0

I've got resize working to the point where it resizes horizontally, but not vertically. Here is the code:

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(old_biHeight); i < biHeight; i++)
{   
    //LONG cur_pos = ftell(inptr);
    for (int x = 0; x < nFactor; x++)
    {
        // iterate over pixels in scanline
        for (int j = 0; j < old_biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

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

            for (int v = 0; v < nFactor; v++)
            {
                // write RGB triple to outfile 
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

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

            // add the new padding
            for (int k = 0; k < new_padding; k++)
            {
                fputc(0x00, outptr);
            }     
        }
        //fseek(inptr, cur_pos, SEEK_CUR);
    }
}

I've gone over this about half a dozen times on paper and in GDB, but I can't see what's wrong. I thought that the 2nd for loop (x < nFactor) would take care of repeating the line as long as I fseek() back to the beginning at the end of that loop, but apparently I'm wrong. The image just comes out wrong when I un-comment both the ftell() and fseek() lines - its the right size, but the pixels are all messed up.

Any advice on how to tackle this?

2 Answers 2

1

You need to tell it to fseek back (use a negative number to move the cursor back) IF it's not the first time through a vertical copy.

If you imagine a picture comprising 4 pixels, 2x2 and we want to double the size

xo
ox

doubles to

xxoo
xxoo
ooxx
ooxx

now think about the exact steps needed to do this.

  1. read first line
  2. write first line, doubling horizontally
  3. since we're doubling, we need to copy the first line again vertically, so now we need to fseek back to the start of the line
  4. read first line again
  5. write first line again, doubling horizontally
  6. read second line
  7. repeat steps 2-5 for second line

So to do this, you have to read over the first line (xo) one time, and then FSEEK back, so it can be read and copied again a 2nd time. The same is true of the second line. The real magic comes in when the program has to determine "is this the first time I'm copying this line? If so, then I don't need to fseek back, if not, seek back so I can read the line again"

I hope that helps you somewhat. This seems to be the same place that most students are getting stuck. The horizontal resize is easy, it's the vertical looping that gets tricky.

just think, if int j=0 you know it's the first pass through the line. If j>0 you know you need to fseek back. To make it go back, simply add a -1 multiplier in front of the sizeof(RGBtriple).

1
  • Wait, use sizeof(RGBTtriple) to get the offset? I thought we could use ftell() at the beginning of the line (of course taking care to store the result), ftell() again at the end, and then fseek() the difference between the two to get back to the start of the line? (I think this might be the problem, as that's what I'm doing) Commented Nov 18, 2014 at 1:34
0

Are you sure about your placement of the following lines:

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

        // add the new padding
        for (int k = 0; k < new_padding; k++)
        {
            fputc(0x00, outptr);
        } 

It looks to me like they might be included inside the loop that is commented // iterate over pixels in scanline. If this is true, when and how often are these lines being executed?

In case you are unsure of how the padding works, there is some great information in the spec http://cdn.cs50.net/2015/x/psets/4/pset4/pset4.pdf , an excerpt of which is pasted here for you:

And so the scanline is "padded" with as many zeroes as it takes to extend the scanline’s length to a multiple of 4. In other words, between 0 and 3 bytes of padding are needed for each scanline in a 24-bit BMP.

Depending on where you put your code for handling padding (i.e. which loops it is inside) you might be removing and adding padding too frequently, or not frequently enough.

I think this should be enough information to help you find the answer on your own, but if you find it confusing, let me know, and I'll be more explicit. I might be wrong, after all.

HTH


If this answers your question please accept it by clicking the gray check-mark to the left, so that it becomes green. You can also vote it up by pressing the up arrow above the check-mark.

You must log in to answer this question.

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