-1

I'm with the pset5 and my code doesn't work and I don't know why. Can somebody help me? Here is my code:

//resize headers
BITMAPFILEHEADER bfNew;
BITMAPINFOHEADER biNew;

biNew.biWidth = bi.biWidth * n;
biNew.biHeight = bi.biHeight * n;
int paddingNew= (4 - (biNew.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

biNew.biSizeImage = biNew.biWidth * sizeof(RGBTRIPLE) * abs(biNew.biHeight) + paddingNew * abs(biNew.biHeight);
bfNew.bfSize = biNew.biSizeImage + 54;

fpos_t pos;

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

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

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

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{

    //get the current position
    fgetpos(outptr,&pos);

    // iterate over pixels in scanline
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
        for(int counter=0; counter<n;counter++){           

        // write RGB triple to outfile
        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 < paddingNew; k++)
    {
        fputc(0x00, outptr);
    }

    //resize vertically
    if(n!=1){

        //move pointer to start of scanline of outptr
        fsetpos( outptr, &pos );

        //an array of RGBTRIPLE to store one scanline
        RGBTRIPLE tripleLine[biNew.biWidth]; 

        //reading the already written first line from outptr    
        fread(&tripleLine, biNew.biWidth * sizeof(RGBTRIPLE), 1 , outptr); 


        for(int counter=1; counter<n;counter++){           

            // write RGB triple to outfile
            fwrite(&tripleLine, biNew.biWidth * sizeof(RGBTRIPLE), 1, outptr);
        }

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

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

Thank you

  • 2
    This question appears to be off-topic because it is a request for individual code review and does not identify a specific problem. – Air Oct 30 '14 at 18:25
1
  1. I am assuming you've opened outptr for "rw" (it's not in the code you've posted).

  2. You need to get the current position in the outptr and store it in pos (using fgetpos) before you "iterate over pixels in scanline." Otherwise, you are calling fsetpos with garbage value.

  3. Second to the last for() loop, where you are "reading the already written first line from outptr" can be replaced with a single fread. Check out the nmemb parameter in man fread.

  4. The last for() loop, where you "write RGB triple to outfile" is incorrect. You are basically writing elements 1 through n-1 of the tripleLine array. Whereas, you have to write the entire array n-1 times into the file. Again, just use the nmemb parameter to fwrite to write the whole array at once. And don't forget to write the padding after each fwrite.

==========

Looking better! Few more things to fix:

  1. You need to initialize the remaining fields of the structure in bfNew and biNew. Since they are the same as bf and bi, you can just copy them from bf and bi. You can just assign the whole struct, eg: bfNew = bf.

  2. Now, let's follow the code in your program: You save the current file pos in your outptr. Then you write out 1 scanline + padding into outptr. Then, you set the pos back to before the scanline and read the whole scanline in one shot. So now your pos is at the end of the scanline. That's where the next fwrite will write to... But what did you forget?... That's right, you forgot to skip over the padding. So before you start writing the additional scanlines, you need to do something like:

    fseek(outptr, paddingNew, SEEK_CUR);

  3. Lastly, when you write your duplicate scanlines to the file, you need to write padding after each one. So, you last for() loop should be inside the 2nd to the last for() loop.

Otherwise, you are golden.

PS: Following are optional things:

  1. This line:

fread(&tripleLine, biNew.biWidth * sizeof(RGBTRIPLE), 1 , outptr);

could be written like this:

fread(&tripleLine, sizeof(RGBTRIPLE), biNew.biWidth, outptr);

Same for the fwrite line where you write the whole line.

Nothing wrong with the way you wrote it, but the second version is more betterer. :)

  1. Since tripleLine is an array, you don't need to put & before its name in fread and fwrite.
  • Thank you for the answer. I did the changes but it doesn't work. I have edited my old code for the new.I opened de outptr with w+ because with rw the check saids: :( resizes 1x1-pixel BMP to 3x3 correctly when n is 3 \ expected an exit code of 0, not standard error of "Could not create outfile.bmp.\n" – Laura Alonso Arroyo Oct 28 '14 at 11:21
  • Great answer. I helped with markdown for your code (pending approval). using accent marks around your line of code will format it as code. Example (accent here)code code code(accent here). To format blocks of code, every line indented (with the usual 4 spaces) is considered a line of code and will be formatted as such. For more formatting tricks, visit the Help page on formatting. BTW, good to see you out of the fog. – CaptJak Oct 28 '14 at 17:16
  • Thanks capt. :) – Hedgehog Oct 28 '14 at 17:34
  • Thank you CaptJak ! Now it is perfect:D – Laura Alonso Arroyo Oct 29 '14 at 0:16
  • You meant, thank you Hedgehog, right? Cuz this was my answer... :( designer-daily.com/wp-content/uploads/2008/01/hedgehog.jpg – Hedgehog Oct 29 '14 at 0:19

You must log in to answer this question.

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