0

For PSET5 Resize.c, I have tried implementing the following with n being the resize factor inputted by the user. The code compiles but returns an image of an conglumeration of colours (or a corrupted image).... Not sure why even after hours of debugging w GDB as well as looking thr previous posts on stackexchange ... Can anyone point out my mistake please??

UPDATED:

int main(int argc, char* argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        printf("Usage: ./resize n infile outfile\n");
        return 1;
    }

    // remember filenames and resize factor, n. 
    int n = atoi(argv[1]); 
    char* infile = argv[2];
    char* outfile = argv[3];

    if (n < 1) 
    {
        printf("n should be a positive integer greater than 0\n");
        return 5; 
    }

    // open input file 
    FILE* inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE* outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 3;
    }

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

    //Store previous values (for calculating padding later) as tmp. 
    LONG tmpbiWidth = bi.biWidth; 
    LONG tmpbiHeight = bi.biHeight; 

    // determine padding for scanlines for old (input) and new (output) 
    int paddingNEW =  (4 - (n*tmpbiWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int paddingOLD =  (4 - (tmpbiWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    //Alter bi for output. 
    bi.biWidth = n*bi.biWidth; 
    bi.biHeight = n*bi.biHeight; 
    bi.biSizeImage = 3 * abs(bi.biHeight) * bi.biWidth + (paddingNEW * abs(bi.biHeight));
    bf.bfSize = bi.biSizeImage + 54; 

    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
        bi.biBitCount != 24 || bi.biCompression != 0)
    {
        fclose(outptr);
        fclose(inptr);
        fprintf(stderr, "Unsupported file format.\n");
        return 4;
    }

    // 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 (or rows)
    for (int i = 0, biHeight = abs(tmpbiHeight); i < biHeight; i++)
    {
        fseek(inptr,-bi.biWidth*n - paddingNEW,SEEK_CUR); 

        //Resize vertically - copying each row of edited original copy n times. 
        for (int k = 0; k < n; k++) 
        {   
            // iterate over pixels in scanline
            for (int j = 0; j < tmpbiWidth; j++)
            {
                // temporary storage
                RGBTRIPLE triple;

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

                // write RGB triple n times to outfile
                for (int p = 0; p < n; p++)
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

            // skip over padding, if any when reading input (actually this isn't really necessary in this case)
            fseek(inptr, paddingOLD, SEEK_CUR);

            // then add new number of padding 
            for (int k = 0; k < paddingNEW; k++)
            {
                fputc(0x00, outptr);
            }
        }

    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
4
  • Use peek, xxd and diff as asked by the pset specification page!
    – kzidane
    Commented Dec 17, 2014 at 15:16
  • hmm... I tried peek but it returned strange numbers like biHeight = fffffff4 etc.
    – Happytreat
    Commented Dec 17, 2014 at 15:19
  • Hmm used diff and yea there seems to be a difference in bfSize... will try to see what's wrong...
    – Happytreat
    Commented Dec 17, 2014 at 15:21
  • yea updated the bf.bfSize alr, but it's still the same error...
    – Happytreat
    Commented Dec 17, 2014 at 15:24

1 Answer 1

1

Your headers are fine, but you are not handling the position of the cursor in the original file correctly.

Your fseek call:

fseek(inptr,-bi.biWidth*n - paddingNEW,SEEK_CUR); 

This function call needs to go inside your resize vertically loop, and only call when needed, the first time you write a row of pixels you dont need to move back the cursor because already is in the right position. And in the way you wrote the code, bi.biWidth is now the new width of the image and you need the original one. Plus every pixel is 3 bytes and you are multiplying the width by n. Also later in the code you are skipping over the padding on the original file with:

fseek(inptr, paddingOLD, SEEK_CUR);

So you have to move the cursor back the original padding, not the new one.

1
  • Solved! Thanks a lot :))))
    – Happytreat
    Commented Dec 18, 2014 at 2:01

You must log in to answer this question.

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