0

i'm facing problem with header file, every time i check50 my solution i get this error message:
Header field bfType doesn't match. Expected 0x4d42, not 0x28
despite i used printf after copying data from bf to new_bf, and another check after finishing the whole program and before closing both files, and i find that my bfType is 4d42, so why this error message appear ?
here is my code:

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

#include "bmp.h"

int main(int argc, char *argv[])
{
    //converting the number of times from string into integer
    int32_t nTimes = atoi(argv[1]);

    // ensure proper usage
    if (argc != 4)
    {
        fprintf(stderr, "Usage: copy infile outfile\n");
        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;
    }

    //check that the size (n) is positive integer number
    if (nTimes < 0 || nTimes > 100)
    {
        fprintf(stderr, "number you entered is not valid number");
        return 5;
    }

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

    //copying data inside bf & bi to the new bf & bi to be able to change them and not store garbage values
    BITMAPFILEHEADER bf_new = bf;
    BITMAPINFOHEADER bi_new = bi;

    // changing value of width & height &size to a new value after enlarges image
    bi_new.biWidth *= nTimes;
    bi_new.biHeight *= nTimes;
    // determine padding for scanlines
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) %4) % 4;
    int padding_new = (4 - (bi_new.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    bi_new.biSizeImage = ((sizeof(RGBTRIPLE) * bi_new.biWidth) + padding_new) * abs(bi_new.biHeight);

    // changing bfsize before writing info header
    bf_new.bfSize = bi_new.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

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

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

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

        //repeat it vertically
        for (int repeat = 0; repeat < nTimes ; repeat++)
        {
            // iterate over pixels in scanline
            for (int j = 0; j < bi_new.biWidth; j++)
            {
                // temporary storage
                RGBTRIPLE triple;

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

                // writing each RGB triple twice to enlarge image
                for (int k = 0; k < nTimes; k++)
                {
                    // 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 < padding; k++)
            {
                fputc(0x00, outptr);
            }

            if (repeat < nTimes-1)
            {
                //rewind current scanline n-1 times because we already scan one time above & *3 because RGB 3 bytes
                fseek(inptr, -(bi.biWidth * 3 + padding), SEEK_CUR);
            }
        }
    }
    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}
4

The headers are read in this order from the file:

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

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

Which is the correct order. You're writing them in this order:

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

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

Remember that fwrite will write from the very first byte of the file.

You must log in to answer this question.

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