0

I feel like I'm close, since this code will resize small.bmp when the larger file's lines require no padding (for instance, n = 4), but fails with a resize factor that does require padding (1, 3, 7). I've checked headers with the peek function and they've matched up so far. I've been stuck on this for quite a while and realize that this could even be a misplaced curly brace situation. Any hint or clue is very appreciated. My code follows:

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

// remember the integer value of 'n' and the filenames
int n = atoi(argv[1]);
char *infile = argv[2];
char *outfile = argv[3];

// check to ensure n is between 1 and 100, per spec.  else return a reminder of usage.
if (n < 1 || n > 100)
{
    fprintf(stderr, "Usage ./resize n infile outfile\n");
    return 1;
}

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

// create new file header and info header
BITMAPFILEHEADER outbf = bf;
BITMAPINFOHEADER outbi = bi;

// Update height and width
outbi.biHeight = bi.biHeight * n;
outbi.biWidth = bi.biWidth * n;

// determine padding for scanlines in infile
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// Update padding for new lines in outfile
int outpadding = (4 - (outbi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// Update outfile's image size
outbi.biSizeImage = (((sizeof(RGBTRIPLE)) * outbi.biWidth) + outpadding) * abs(outbi.biHeight);

// Update outfile's file size
outbf.bfSize = outbi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

// original write outfile's BITMAPFILEHEADER
fwrite(&outbf, sizeof(BITMAPFILEHEADER), 1, outptr);
// original write outfile's BITMAPINFOHEADER
fwrite(&outbi, sizeof(BITMAPINFOHEADER), 1, outptr);



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

    //iterate over the line n-1 times, adding padding and returning to the... 
    //...beginning of the scanline in infile each time
    for (int c = 0; c < (n - 1); c++)
    {
        // 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);

            // write the triple n times 
            for (int a = 0; a < n; a++)
            {
                // write RGB triple to outfile once for each of n times
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        // add outpadding to end of each new line in outfile
        for (int b = 0; b < outpadding; b++)
        {
            fputc(0x00, outptr);
        }

        // send infile cursor back to the beginning of the current line in infile
        fseek(inptr, (bi.biWidth * (int)sizeof(RGBTRIPLE)) * -1, SEEK_CUR);
    }

    // iterate over the scanline one more time (the n-th time)
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

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

        // write the triple n times 
        for (int a = 0; a < n; a++)
        {
            // write RGB triple to outfile once for each of n times
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
        }
        // add outpadding to end of the new line in outfile
        for (int b = 0; b < outpadding; b++)
        {
            fputc(0x00, outptr);
        }
    }

    // skip over padding in scanline, if any
    fseek(inptr, padding, SEEK_CUR);
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

0

1 Answer 1

0

Thanks for looking (if anyone picked this up), but I've found my error.

I see that in my n-th loop the padding was being added after each pixel in the infile, rather than at the end of the line of pixels.

So many loops... :)

Onward and upward.

2
  • Accept your answer so that your question can be marked as answered!
    – ChrisG
    Commented Jul 18, 2017 at 21:04
  • Will do. Stackexchage tells me that I can accept my own answer in two days. I'll keep a reminder open until I get the check checked! Thanks for being there... I suspect I won't always figure out my own bugs. Commented Jul 19, 2017 at 0:38

You must log in to answer this question.

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