0

Good afternoon and a happy New year to you all.

I am currently having issues with resize.c My resized file is made but will not open in the CS50 IDE. I get an error saying that it is an unsupported file format.

I have only got as far as the horizontal resize but I fear I am getting too much padding. I initially thought it may be the headers that were incorrect but I have used ~cs50/pset4/peek to compare my resized file with the original and all is good. Having looked at the files with xxd it appears that the resized file has more ...'s at the end which I am guessing is the padding?

My code so far is:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bmp.h"

int main(int argc, char *argv[])
{
    // ensure proper usage. 4 arguments must be given
    if (argc != 4)
    {
        fprintf(stderr, "Usage: ./copy infile outfile\n");
        return 1;
    }

    // remember filenames
    //atof converts string to double. Reminder.
    float f = atof(argv[1]);

    //Need to add the if statement that limits f to between 0.0 and 100

    char *infile = argv[2];
    char *outfile = argv[3];

    // open input file
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "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
    //Creates two structs of type BITMAPFILEHEADER, one called bf for the original file, one called bf_new for the new file
    BITMAPFILEHEADER bf;
    BITMAPFILEHEADER bf_new;
    //Reads the input file and stores the data in the struct bf
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    //Assigns the values of bf to bf_new
    bf_new = bf;

    // read infile's BITMAPINFOHEADER
    //Creates two structs of type BITMAPINFOHEADER, one called bi for the original file, one called bi_new for the new file
    BITMAPINFOHEADER bi;
    BITMAPINFOHEADER bi_new;
    //Reads the input file and stores the data in the struct bi
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

    //Assigns the values of bi to bi_new
    bi_new = bi;

    // 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;
    }


    //Multiplies the width of the input file by the value of f and stores in struct bi_new
    bi_new.biWidth = bi.biWidth * f;
    //Multiplies the height of the input file by the value of f  and stores in struct bi_new
    bi_new.biHeight = bi.biHeight * f;

    // determine padding for scanlines. Both old and new files
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int padding_new = (4 - (bi_new.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    //Sets the total image size, including pixels and padding
    bi_new.biSizeImage = ((sizeof(RGBTRIPLE) * bi_new.biWidth) + padding_new) * abs(bi_new.biHeight);

    //Sets the total image size in bytes. Includes pixels, padding and headers
    bf_new.bfSize = bi_new.biSizeImage + 54;

    // write outfile's BITMAPFILEHEADER using new data
    fwrite(&bf_new, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER using new data
    fwrite(&bi_new, sizeof(BITMAPINFOHEADER), 1, outptr);


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

        // 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);

            //Writes the RGB triple value to the output file n times. Horizontal resize
            for (int k = 0; k < f; k++)
            {
                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

        }

        // Add new padding
        for (int m = 0; m < padding_new; m++)
        {
            fputc(0x00, outptr);
        }

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

        // set pointer to beginning of input file scanline
        fseek(inptr, 54 + (bi.biWidth * 3 + padding_new) * i, SEEK_SET);

    }

        // close infile
        fclose(inptr);

        // close outfile
        fclose(outptr);

        // success
        return 0;

}

1 Answer 1

0

I ran your code and it does open the output file, although it's really small. ;-) Did you remember to resave and remake your executable file?

Once that's done, the code has issues repositioning at the beginning of the correct line in the file after processing each line. It looks to me that it's not an issue of padding, but instead is an issue of placement at the beginning of the correct line. Using xxd, take a look at the patterns in the output file when the scaling factor is 1, and then look at the output file when the scaling factor is 2.

Another clue is file size. When scale = 2, the output file is 114 bytes when it should be 386 bytes.

Remember, sometimes it needs to go back to the beginning of the line just processed, other times it needs to go to the beginning of the next line in the output file.

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

5
  • Thanks for the help.
    – Ben Rogers
    Commented Jan 1, 2018 at 16:38
  • I haven't managed to get the output file to open still. I wonder what could be different. It opens when the scale factor is 1, but not when it is 2. I think the output file size may be wrong as I am only scaling the horizontal axis at the moment. I haven't tried to add the vertical.
    – Ben Rogers
    Commented Jan 1, 2018 at 16:39
  • Right I finally figured it out. You were right it was all in the placement at the start of the line. Thanks
    – Ben Rogers
    Commented Jan 1, 2018 at 18:30
  • And don't you feel like you learned more with a minimum push in the right direction and figuring it out yourself than being shown the solution? ;-)
    – Cliff B
    Commented Jan 1, 2018 at 18:36
  • Indeed I do. Thanks again
    – Ben Rogers
    Commented Jan 2, 2018 at 20:09

You must log in to answer this question.

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