2

I'm on the verge of giving up. I've been stuck on this problem for weeks. I managed the headers, and I think I set up the loops right to write the pixels correctly. I just can't wrap my head around fseek however. I read the man page, and read stack exchange, but I just don't get it.

Can anyone help me, why my code is failing to resize, and what direction should I progress? I'm super frustrated with it.

// Saving original width and height
int oriwidth = bi.biWidth;
int oriheight = bi.biHeight;

// Modifying to new width and height
bi.biWidth = bi.biWidth * n;
bi.biHeight = bi.biHeight * n;

// determine padding for scanlines
int oripadding = (4 - (oriwidth * sizeof(RGBTRIPLE)) % 4) % 4;
int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// Modifying sizes
bi.biSizeImage = ((bi.biWidth * abs(bi.biHeight)) * sizeof(RGBTRIPLE)) + (padding * abs(bi.biHeight));
bf.bfSize = bi.biSizeImage + 54;

// write outfile's BITMAPFILEHEADER     
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);


// iterate over infile's scanlines
for (int i = 0; i < abs(oriheight); i++)
{   

    // temporary storage
    RGBTRIPLE triple; 

    for (int s = 0; s < n; s++)
    {

    fseek(inptr, 54 + ((i + 1) * oriwidth * (sizeof(triple) + oripadding)), SEEK_SET);

        // iterate over pixels in scanline
        for (int j = 0; j < oriwidth; j++)
        {

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

            // write RGB triple to outfile
            for (int k = 0; k < n; k++)
            {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }
    }    
    // skip over padding, if any
    fseek(inptr, padding, SEEK_CUR);

    // then add it back (to demonstrate how)
    for (int k = 0; k < padding; k++)
    {
        fputc(0x00, outptr);
    }
}

1 Answer 1

7

Your approach is correct, but you have three errors to deal with, one of which is irrelevant.

First, as you guessed, your calculation for fseek is in error. In simple terms, you've placed parentheses incorrectly. Hint: padding only exists once on each line of pixels. Look carefully at how you laid out the line and you should be able to resolve it.

fseek(inptr, 54 + ((i + 1) * oriwidth * (sizeof(triple) + oripadding)), SEEK_SET);

I like your approach. Most people, myself included, use relative positioning for the fseek based on the previous position, but you encoded an absolute position based on the start of the file. I think in the long run, it's more elegant.

The second problem is the addition of padding to each output line. You misplaced the code to doing that outside the for loop that generated each line. In essence, you are outputting n lines of pixels and then adding the padding once after multiple lines. Instead, the 'add padding' code should be inside the appropriate for loop so that padding is appended to every line.

Finally, the irrelevant error. The line of code that skips over the padding at the end of each line in the input file used the output padding var instead of the input padding var. It is irrelevant though, because of how you calculate the fseek above! By fseeking relative to the beginning of the file, it rendered this fseek totally unnecessary. The error has no impact and that line of code could be completely removed. Nice.

That should get you going. Try to fix the fseek on your own now, and if you can't, leave a message and I'll give you another push. ;-)

If this answers your question, please click the check mark to accept. Let's keep up on forum maintenance. ;-)

4
  • 1
    Awesome! As soon as I get home, I'll try to implement it, checking this from work atm :)
    – Bubi
    Nov 2, 2015 at 9:50
  • Hm, something still seems to be off. I have removed the parentheses that you have suggested, and then somewhat rewrote the fseek line. It looks like this atm: fseek(inptr, 54 + (i * oriwidth * sizeof(triple)) + oripadding * i, SEEK_SET); In my interpretation, this should: Skip over headers -> skip over i * lines (0 in the beginning) and skip over i* padding (0 in the beginning). I also relocated the for loop with the fputc in it, but somehting is still off. The image is at least the right color now, but it looks somewhat scrambled.
    – Bubi
    Nov 3, 2015 at 22:11
  • Update: It seems to do the image scaling correctly (I can't tell you how happy I was when I saw it) if I set the multiplier to 4, 8, 12 ... etc.. So only the paddig is out of place somehow. I'm so close, I can feel it in my bones!
    – Bubi
    Nov 4, 2015 at 19:21
  • 1
    Cliff B, I salute you! Thanks for helping me out, finally it works. And not only does it work, but what more important is, I also understand why it works! Fantastic, thanks again for the help!
    – Bubi
    Nov 4, 2015 at 19:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .