0

Been messing with this code for days, but when I was debugging it the program went from printing a distorted image to simply saying Unsupported File Format in the command line. Not sure where I'm going wrong.

#include <stdio.h>
#include <stdlib.h>
#include "bmp.h"

int main(int argc, char *argv[])
{
    // ensure proper usage
    // I changed to argc eqal to four because it will be accepting
    // the name of the program, the number we want to increase the size by,
    if (argc != 4)
    {
        fprintf(stderr, "Usage: copy infile outfile\n");
        return 1;
    }

    // remember filenames
    int n = atoi(argv[1]);
    char *infile = argv[2];
    char *outfile = argv[3];
    // I'm going to need to change this and add something about what
    // var resize is, as well as convert var resize from
    // an array of characters to an integer

    // 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
    BITMAPFILEHEADER bf;

    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

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

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

    int biWidthOld = bi.biWidth;
    int biHeightOld = abs(bi.biHeight);
    int paddingOld = (4 - (biWidthOld * sizeof(RGBTRIPLE)) % 4) % 4;


    bi.biWidth *= n;
    bi.biHeight *= n;
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    //keep in mind i'll need to change the padding
    //probably best to declare it as a variable earlier

    bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + padding) * abs(bi.biHeight);
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    //int biWidth0 = (bi.biWidth / n);
    //int biHeight0 = (bi.biHeight / n);

    // write outfile's BITMAPFILEHEADER

    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

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

    // determine padding for scanlines
    // I should declare a seperate padding above
    // iterate over infile's scanlines
    // I took out the abs before biHeight0
    for (int i = 0; i < biHeightOld; i++)
    {
        for (int b=0; b < n; b++)
        {
        // iterate over pixels in scanline
            for (int j = 0; j < biWidthOld ; j++)
            {

                // temporary storage
                RGBTRIPLE triple;

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

                    // write RGB triple to outfile
                        for (int c=0; c < n; c++)
                        {
                            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
                        }
                    // that might be my issue is that i'm fwriting the wrong thing
            }
            fseek(inptr, - (sizeof(RGBTRIPLE) * biWidthOld), SEEK_CUR);
        }
        fseek(inptr, paddingOld, SEEK_CUR);
        for (int k = 0; k < padding; k++)
        {
            fputc(0x00, outptr);
        }
    }
    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

1

Wasn't able to duplicate the unsupported file format, so I have no explanation for that. The code posted produces valid output files, just not correct files.

The big underlying problem that I see is this. In the output file, the padding is not being added to the end of each line. Instead, it's being added after the image data line is processed n times. In other words, a line of image data is written n times, but without padding, and then the padding is added once.

Next, the code goes backwards in the input file after every line is processed. At some point, the file pointer needs to be left in place and not moved back to the beginning of the line.

Well, that's not precisely true, but I wanted to emphasize two related problems. Not only should the input file pointer not go back, but it must go forward to skip over the padding. It must do this only when the processing of the current line is done.

The short version of all that is that all the parts are in the code, but they're not in the correct logical order!

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

1
  • It works now, thanks so much!
    – user21860
    Commented Aug 13, 2018 at 17:18

You must log in to answer this question.

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