0

The resize assignment has had me spinning in circles for the past few weeks. Could someone give me an example of how to use fseek and point out the logic errors in my code?

for (int i = 0, biHeight = abs(original_height); i < biHeight; i++)
{
    for (int l = 0; l < n; l++)
    {
        // iterate over pixels in scanline
        for (int j = 0; j < original_width; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            if (i == 0)
            {
                fseek(inptr, 54, SEEK_SET);
            }
            else
            {
                fseek(inptr, (int)&triple, SEEK_CUR);
            }
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

            // write RGB triple to outfile
            if (i == 0)
            {
                fseek(outptr, 54, SEEK_SET);
            }
            else
            {
                fseek(outptr, (int)&triple * n, SEEK_CUR);
            }
            for (int m = 0; m < n; m++)
            {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        // skip over padding, if any
        fseek(inptr, infile_padding, SEEK_CUR);

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

First, you are nesting too many for loops in your code unnecessarily. Think about what you need to do: You want to read a two dimensional data structure, that is the bitmap of your infile. For that, you need to iterate over the height of the original image (which you did) and then over its width, so to read from top to bottom, left to right. The nested for loop with "l" is not necessary for this first step.

Second, think about not only storing an RGBTRIPLE, but an array of these, like this:

// temporary storage as array of structs
RGBTRIPLE temp_line[bi2.biWidth];

This should be stored before you enter the second for loop (considering we forget about the for loop that uses "l"). When you then enter this second for loop, iterating over the original image's width, you can temporarily store one RGBTRIPLE within that nested for loop, and read it n times into

RGBTRIPLE temp_line[bi2.biWidth]

After having stored every pixel n times (n being the user's input, btw) within this array, you can fwrite() it into the outfile, followed by the padding. This you do n times, so to ensure vertical resizing as well.

Now, to your usage of fseek(): At this stage in your code, you will have already read the BITMAPFILEHEADER and BITMAPINFOHEADER, right?! As long as your programme hasn't stopped executing, the cursor will be stored at the stage of last usage. That is, after having read those header files, you do not need to set your cursor 54 bytes further up, because it is already 54 bytes in your infile (and outfile, because you used fwrite() to write the modified headers). Generally speaking, you ONLY need fseek() to jump over the padding, that's it. Your cursor will be updated automatically.

One more thing: What do you want to do with (int)&triple? Casting the address of your RGBTRIPLE to an int? Better forget about this structure altogether.

To sum up, try to use an array of RGBTRIPLES directly after your first for loop that iterates over the infile's height. Don't use more for loops than you actually need to. And only use the fseek() function when you want the cursor to skip over the padding.

1
  • bi2.biWidth being the width (without padding) of the outfile – pat_krat Sep 7 '14 at 10:59

You must log in to answer this question.

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