0

Here is my code. It seemed to be working but apparantly my image is undefined. I know that I have to catch the if condition at the beginning but can anyone tell me why my image was undefine

/**

* copy.c * * Computer Science 50 * Problem Set 4 * * Copies a BMP piece by piece, just because. */

include

include

include "bmp.h"

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

// remember filenames
int size = atoi(argv[1]);
char* infile = argv[2];
char* outfile = argv[3];

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

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

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

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi_updated;
fread(&bi_updated, sizeof(BITMAPINFOHEADER), 1, inptr);
// determine padding for scanlines


bi_updated.biWidth = bi.biWidth * size;
printf("%d\n", bi.biWidth);
bi_updated.biHeight = bi.biHeight * size;
int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int padding_updated = (4 - (bi_updated.biWidth * sizeof(RGBTRIPLE) * size) % 4) % 4;
printf("%d\n",padding_updated);
bi_updated.biSizeImage = abs(bi_updated.biHeight) * (sizeof(RGBTRIPLE) * bi_updated.biWidth  + padding_updated);
bf_updated.bfSize = bi_updated.biSizeImage + bf.bfOffBits;
 // write outfile's BITMAPFILEHEADER
fwrite(&bf_updated, sizeof(BITMAPFILEHEADER), 1, outptr);
printf("%d\n",padding);

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

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++) {
    fseek(inptr, 54 + ((bi.biWidth * sizeof(RGBTRIPLE) + padding) * i) , SEEK_SET);

    for (int a = 0; a < size; a++) {
        // 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);
            for (int b = 0; b < size; b++) {
            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        // skip over padding, if any

        // then add it back (to demonstrate how)
        for (int k = 0; k < padding_updated; k++)
        {
            fputc(0x00, outptr);
        }
        fseek(inptr, -((bi.biWidth) * sizeof(RGBTRIPLE)) , SEEK_CUR);

    }
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;

}

1 Answer 1

0

The problem is that the code isn't reading the headers into the updated header structures. The code reads the headers into the original header structures and then reads data into the new header structures. Unfortunately, it doesn't reset the file pointer to the beginning of the file, so it is actually reading image data into the headers.

This can be fixed by either resetting the pointer to the beginning of the file between the two sets of reads, or by simply copying the original structures to the new ones.

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

You must log in to answer this question.

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