0

The issue that keeps occurring after compiling and running the file, is that the resulting output bmp file changes to an unsupported file format(as stated when clicking on the bmp image file after running the program). I am not sure whether it's a problem with my header or the unsigned char pixels_array I made to save a line of the pixels that has been expanded n times (width). My code reads the input file line by line, and saves each expanded line temporarily (by the growth amount n) into the pixels_array and writes the line n times to the endfile (for height). I really appreciate any help.

// Copies a BMP file

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

#include "bmp.h"

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

    // value to increase by
     int n = atoi(argv[1]);
    if (n <= 0 || n >= 100)
    {
       fprintf(stderr, "Incorrect. enter a proper n value between 1 and 100");
        return 1;
    }

    // remember filenames
    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
    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 outfile_padding = (4- ((bi.biWidth * n) * sizeof(RGBTRIPLE)) % 4) % 4;

    // write outfile's BITMAPFILEHEADER
    BITMAPFILEHEADER outfile_bf;

    fwrite(&outfile_bf, sizeof(outfile_bf), 1, outptr);

    // write outfile's BITMAPINFOHEADER
     BITMAPINFOHEADER outfile_bi;
     outfile_bi.biWidth = bi.biWidth *n;
     outfile_bi.biHeight = bi.biHeight * n;
     outfile_bi.biSizeImage = ((sizeof(RGBTRIPLE) * outfile_bi.biWidth) + outfile_padding) * abs(outfile_bi.biHeight);
    fwrite(&outfile_bi, sizeof(outfile_bi), 1, outptr);


    outfile_bf.bfSize = outfile_bi.biSizeImage + sizeof(outfile_bf) + sizeof(outfile_bi);
    // determine padding for scanlines
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;


     *** edited Edited out code due to CS50 Regulations

2 Answers 2

1

Hmmm.....

After the code creates the output file headers, do you think it would be useful to load/copy the values from the input file headers into the output file headers?

// write outfile's BITMAPFILEHEADER
BITMAPFILEHEADER outfile_bf;

fwrite(&outfile_bf, sizeof(outfile_bf), 1, outptr);

// write outfile's BITMAPINFOHEADER
 BITMAPINFOHEADER outfile_bi;
 outfile_bi.biWidth = bi.biWidth *n;
 outfile_bi.biHeight = bi.biHeight * n;
 outfile_bi.biSizeImage = ((sizeof(RGBTRIPLE) * outfile_bi.biWidth) + outfile_padding) * abs(outfile_bi.biHeight);
fwrite(&outfile_bi, sizeof(outfile_bi), 1, outptr);

Yes, the code modified a couple of fields in the bi header, but all the other fields contain garbage data or no data at all. The output headers were never initialized!

There are more issues, but this answers your current question. ;-)

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

1
  • thank you! yeah I did not save any of the header information from the input file for the output file. thanks!
    – Leah
    Commented Aug 7, 2019 at 1:42
1

You've declared a new header struct, but you never gave it any values

// write outfile's BITMAPFILEHEADER
BITMAPFILEHEADER outfile_bf;

fwrite(&outfile_bf, sizeof(outfile_bf), 1, outptr);

Earlier you read the header from the file into a variable called bf. Perhaps you meant to set out_file bf = bf? Otherwise, you are writing garbage.

1
  • haha! Beat you by 20 seconds!!!! :-P
    – Cliff B
    Commented Aug 7, 2019 at 0:33

You must log in to answer this question.

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