0

To scale bitmap image 3times bigger, I implemented this code and found holes. I decided to use bilinear Interpolation and these above are the code patching the nearest pixel of which weight are calculated like this code. Output[j*hInfo.biWidth+i] =Image[3/2*j*hInfo.biWidth + 3/1*i].
The logic is simple so I thought It was going to be working properly, I was quite sure, but the result of Image looks like an watermelon like how I feel, please take a look at the code. any comments are welcoming. thanks for reading.

void main() 
{
BITMAPFILEHEADER hf;
BITMAPINFOHEADER hInfo;
RGBQUAD hRGB[256];
FILE *fp;
fp = fopen("input.bmp", "rb");
if(fp == NULL) return;
fread(&hf, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&hInfo, sizeof(BITMAPINFOHEADER), 1, fp);
fread(hRGB, sizeof(RGBQUAD), 256, fp);
hInfo.biWidth *=3;
hInfo.biHeight *=3;
int ImgSize = hInfo.biWidth * hInfo.biHeight;

BYTE *Image = (BYTE *) malloc(ImgSize);
BYTE *Output = (BYTE *)malloc(ImgSize);
fread(Image, sizeof(BYTE), ImgSize, fp);
fclose(fp);
double Sx, Sy;
scanf("%lf", & Sx);// scaling factor x : 3
scanf("%lf", & Sy);// scaling factor y : 3

for(int i= 0 ; i < hInfo.biHeight; i++){
    for(int j=0; j < hInfo.biWidth; j++){
        if(j*Sx < hInfo.biWidth && i*Sy<hInfo.biHeight)

Output[(int)(i*Sy)*hInfo.biWidth+(int)(j*Sx)] = Image[i*hInfo.biWidth + j];
    }
}


// horizontally executed first. 

for(int i= 0 ; i < hInfo.biHeight; i++){
    for(int j=0; j < hInfo.biWidth; j++){
        if( j%3 == 1)
        {
            Output[i*hInfo.biWidth+j] = (int)Image[( (hInfo.biWidth*(1/3) + j+2) + ( hInfo.biWidth* (2/3) + (j-1) ) )]; 
        }
        else if( j%3 == 2 )
        {
            Output[i*hInfo.biWidth+j] = (int)Image[( (hInfo.biWidth*(2/3) + j+1) + ( hInfo.biWidth* (1/3) + (j-2) ) )];
        }
        else if(  j%3 ==1 && j+2 >= hInfo.biWidth)
        {
            Output[i*hInfo.biWidth+j] = Image[i*hInfo.biWidth + (j-2)] ;
        }
        else if(  j%3 ==2 && j+1 >= hInfo.biWidth)
        {
            Output[i*hInfo.biWidth+j] = Image[i*hInfo.biWidth + (j-2)] ;
        }

    }
}


// vertically executed last 
for(int j= 0 ; j < hInfo.biWidth; j++){

    for(int i=0; i < hInfo.biHeight; i++){

        if( j%3 == 1)
        {
            Output[j*hInfo.biWidth+i] = Image[hInfo.biWidth*(1/3) + (i+2) + hInfo.biWidth* (2/3) + (i-1);   
        }
        else if( j%3 == 2 )
        {
            Output[j*hInfo.biWidth+i] = Image[hInfo.biWidth*(2/3) + (i+1) + hInfo.biWidth* (1/3) + (i-2)];
        }
        else if(  j%3 ==1 && j+2>=hInfo.biWidth)
        {
            Output[j*hInfo.biWidth+i] = Image[j*hInfo.biWidth + (i-2)] ;
        }
        else if(  j%3 ==2 && j+1>=hInfo.biWidth)
        {
            Output[j*hInfo.biWidth+i] = Image[j*hInfo.biWidth + (i-2)] ;
        }

    }
}

fp = fopen("output.bmp", "wb");
fwrite(&hf, sizeof(BYTE), sizeof(BITMAPFILEHEADER), fp);
fwrite(&hInfo, sizeof(BYTE), sizeof(BITMAPINFOHEADER), fp);
fwrite(hRGB, sizeof(RGBQUAD), 256, fp);
fwrite(Output, sizeof(BYTE),ImgSize, fp);
fclose(fp);
free(Image);
free(Output);
}
jay
  • 55
  • 1
  • 8
  • `void main` has never been valid C or C++. It makes it harder for readers to copy and paste your code to try it, since only one commonly used compiler accepts it, and it teaches beginners bad habits. Please don't post code with `void main`; corrected. – Cheers and hth. - Alf Jun 07 '16 at 11:05
  • Also, please do format your code with *consistent indentation* before posting it. Free tools like AStyle can do that for you. Also many programmers' editors can do it for you, but the best is to just format the code properly as you write it. I suggest that you now indent the code properly and repost it. Without any other changes. – Cheers and hth. - Alf Jun 07 '16 at 11:06
  • It seems you set `Output[x] = Image[y]`, i.e. the interpolated value is not really interpolated, but another point at another location. Shouldn't it be something like `Output[x] = Image[y]*(1/3) + Image[z]*(2/3)`, i.e. `Image` should appear (at least) twice on the right side? – Karsten Koop Jun 07 '16 at 11:06
  • Beware that e.g. 1/3 if done like integer division is 0. – Erik Alapää Jun 07 '16 at 11:08
  • 1
    also the flow if the four `if`s is `if (j%3==1) ... else if(j%3==1 && ...)`, so the `else if` part can never be true – Karsten Koop Jun 07 '16 at 11:08
  • I have no idea why I put int over there, apologies I ve edited. – jay Jun 07 '16 at 11:11
  • also note that scanlines in BMP is 4-byte padded, see [here](https://en.wikipedia.org/wiki/BMP_file_format) – sp2danny Jun 07 '16 at 11:34

1 Answers1

0

Thanks to you all guys, I finally have done with the code. yes, I don't need the else if ones which is already restricted by a for loop condition.

    for(int i= 0 ; i < hInfo.biHeight; i++){
    for(int j=0; j < hInfo.biWidth; j++){
        if( j%3 == 1)
        {
            Output[i*hInfo.biWidth+j] = (int)Output[i*hInfo.biWidth+j-1]*2/3+(int)Output[i*hInfo.biWidth+j+2]*1/3;
        }
        else if( j%3 == 2 )
        {
            Output[i*hInfo.biWidth+j] = (int)Output[i*hInfo.biWidth+j-1]*1/3 + (int)Output[hInfo.biWidth*i + (j-2)]*2/3;
        }

    }
}
for(int i= 0 ; i < hInfo.biHeight; i++){    
    for(int j= 0; j < hInfo.biWidth; j++){      
        if( j%3 == 1)
        {
            Output[j*hInfo.biWidth+i] = (int)Output[(j-1)*hInfo.biWidth+i]*2/3+(int)Output[(j+2)*hInfo.biWidth+i]*1/3;
        }
        else if( j%3 == 2 )
        {
            Output[j*hInfo.biWidth+i] = (int)Output[(j-1)*hInfo.biWidth+i]*1/3 + (int)Output[hInfo.biWidth*(j-2) + i]*2/3;
        }
    }
}
jay
  • 55
  • 1
  • 8