Darlyn
Darlyn

Reputation: 4938

Converting BMP image into greyScale

I am trying to convert BMP image into greyScale.

I have loaded data ( found and adjusted some functions found here):

struct Info{
    int width;
    int height;
    int offset;
    unsigned char * info;
    unsigned char * data;
    int size;
};

    Info readBMP(char* filename)
    {
        int i;
        std::ifstream is(filename, std::ifstream::binary);
        is.seekg(0, is.end);
        i = is.tellg();
        is.seekg(0);
        unsigned char *info = new unsigned char[i];
        is.read((char *)info,i);

        int width = *(int*)&info[17];
        int height = *(int*)&info[21];
        int offset = *(int*)&info[10];

        unsigned char a[offset];
        unsigned char *b = new unsigned char[i - offset];
        std::copy(info,
                  info + offset,
                  a);

        std::copy(info + offset,
                  info + i,
                  b + 0);

        Info dat;
        dat.width = width;
        dat.height = height;
        dat.offset = offset;
        dat.size = i;
        dat.info = new unsigned char[offset - 1];
        dat.data = new unsigned char[i - offset];

        for( int j = 0; j < offset ; j++ ){
            dat.info[j] = a[j];
        }

        for( int j = 0; j < i - offset; j++ ){
            dat.data[j] = b[j];
        }
        return dat;

    }

( Loadin works as it should, i tried to load and save data and result was same image )

Now if i understand it correctly, the data should be of width * height * 3 length.

I am trying to apply greyScale filter using:

void greyScale( unsigned char * src , int rows, int cols){
    for( int i = 0; i < rows; i++){
        for( int j = 0;  j < cols; j++){
            char r = src[3 * (i * rows + j)];
            char g = src[3 * (i * rows + j) + 1];
            char b = src[3 * (i * rows+ j) + 2];

            char linearIntensity = (char)(0.2126f * r + 0.7512f * g + 0);

            src[3 * (i * rows + j)]= linearIntensity;
            src[3 * (i * rows + j) + 1] = linearIntensity;
            src[3 * (i * rows+ j) + 2] = linearIntensity;
        }
    }
}

usage:

int main() {
    //unsigned char* info = new unsigned char[54];
    Info dat = readBMP("C:\\Users\\Me\\Downloads\\test.bmp");
    greyScale(dat.data,dat.width,dat.height);


    ofstream fout;
    fout.open("out.bmp", ios::binary | ios::out);
    fout.write( reinterpret_cast<char *>(dat.info), dat.offset);
    fout.write( reinterpret_cast<char *>(dat.data), dat.size - dat.offset );
    fout.close();
    return 0;
}

However i recieved segfault at j = 3067 and i = 6, which im confused about, cuz it shouldnt be out of index ( the loops shouldnt access anythin out of index ).

I thought it was some padding problem, but padding is just 0 so it shouldnt be problem.

Why is this happening? Why do i recieve good old segfault? I fail to find the reason.

Thanks for help!

Upvotes: 2

Views: 255

Answers (1)

Gaurav Dhiman
Gaurav Dhiman

Reputation: 1173

I am not sure if its a typo, but you seems to be using rows variable instead of cols variable, try this

void greyScale( unsigned char * src , int rows, int cols){
        for( int i = 0; i < rows; i++){
            for( int j = 0;  j < cols; j++){
                char r = src[3 * (i * cols + j)];
                char g = src[3 * (i * cols + j) + 1];
                char b = src[3 * (i * cols + j) + 2];

                char linearIntensity = (char)(0.2126f * r + 0.7512f * g + 0);

                src[3 * (i * cols + j)] = linearIntensity;
                src[3 * (i * cols + j) + 1] = linearIntensity;
                src[3 * (i * cols + j) + 2] = linearIntensity;
            }
        }
    }

Upvotes: 1

Related Questions