0

I thought I got it, but still stuck. any help appreciated

/** * resizes bmp piece by piece */

include

include

include "bmp.h"

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

// make sure resize facotr is valid
int factor = atoi(argv[2]);
if (factor < 0 || factor >100)
{
    printf("factor must be positive integer less or equal to 100.\n");
    return 2;
}




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

// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 4;
}

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

// construct bitmap headers for the outfile
BITMAPFILEHEADER out_bf;
BITMAPINFOHEADER out_bi;

out_bf = bf;
out_bi = bi;

out_bi.biWidth = bi.biWidth*factor;
out_bi.biHeight = bi.biHeight*factor;

// work out padding for scanlines
int in_padding = (4 - (bi.biWidth*sizeof(RGBTRIPLE))%4)%4;
int out_padding = (4 - (out_bi.biWidth*sizeof(RGBTRIPLE))%4)%4;

// work out change of image size
out_bi.biSizeImage = ((sizeof(RGBTRIPLE)*out_bi.biWidth) + out_padding)*abs(out_bi.biHeight);

//work out change of file size
out_bf.bfSize = out_bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);



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

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


// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    // ensure each line is written factor times
    for (int n = 0; n < factor; n++)
    {
        // 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);

            // ensure repeated factor times
            for (int m = 0; m < factor; m++)
            {
            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }
        // skip over padding, if any
        fseek(inptr,in_padding, SEEK_CUR);

        // write padding to outffile
        for (int k = 0; k < out_padding; k++)
        {
            fputc(0x00, outptr);
        }
        // return cursor
        fseek(inptr, -(bi.biWidth*sizeof(RGBTRIPLE)+ in_padding), SEEK_CUR);
    }
    //return cursor again I dont know why
    fseek(inptr, (bi.biWidth*sizeof(RGBTRIPLE)+ in_padding), SEEK_CUR);
}
// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

2
  • Can we get a clue what you're having trouble with? What's it doing? What isn't it doing? What is it doing wrong? – Cliff B Dec 31 '17 at 6:39
  • When I use check50, it states that it complies correctly. It states that it does not resize a 3x3 pixel BMP correctly when factor equals 1. It states that it does not resize a 3x3 pixel BMP correctly when factor equals to 2. Surprisingly It states that it resizes a 3x3 pixel BMP to 9x9 when factor equals 3. I think my problem is I just dont understand f(seek). I am putting f(seek) in places hoping that it is correct. Thanks. – stephen Ong Dec 31 '17 at 18:19
1

You have to check your command line arguments. You take the third argument as the resize factor and as the infile name.

2
  • Thank you. It works now after checking my command line arguments. Can you tell me why I have to put in the last f(seek) line towards the end?? I put the last f(seek) line by trial and error but I dont understand why.. i.e.: //return cursor again I dont know why fseek(inptr, (bi.biWidth*sizeof(RGBTRIPLE)+ in_padding), SEEK_CUR); – stephen Ong Jan 1 '18 at 17:49
  • You do try to iterate over the infile's lines but you set multiplied bi.height by your factor. The same with your width. You have to store the old height and width and iterate oldHeight and oldWidth times. – Noah Haasis Jan 2 '18 at 4:46

You must log in to answer this question.

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