0

So I am working on resize, and I thought I had gotten it to work; it correctly resizes smiley.bmp and large.bmp. However, it can't seem to resize small.bmp to save its life, even when the specs matched up by checking peek cs50. I've spent an ungodly amount of time on this and I genuinely don't understand what's not working. ANY help would be appreciated.

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

#include "bmp.h"

int main(int argc, char *argv[])
{
int n = atoi(argv[1]);
//define a line


// ensure proper usage
if (argc != 4)
{
    fprintf(stderr, "Usage: ./resize n infile outfile\n");
    return 1;
}

// remember filenames
char *infile = argv[2];
char *outfile = argv[3];

//check n

if (n <= 0 || n > 100)
{
    fprintf(stderr, "Error: n not within specified range.\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;
}

int outputpadding = (4 - (bi.biWidth * n * sizeof(RGBTRIPLE)) % 4) % 4;

bi.biSizeImage = n * n * bi.biWidth * abs(bi.biHeight) * 3 + outputpadding*abs(bi.biHeight);
bi.biWidth = bi.biWidth * n;
bi.biHeight = bi.biHeight * n;
bf.bfSize = bi.biSizeImage + 54;


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

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



bi.biHeight = bi.biHeight / n;
bi.biWidth = bi.biWidth / n;


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

    fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBTRIPLE)*i*bi.biWidth, SEEK_SET);

    // iterate over pixels in scanline, i.e. "resize horizontally"
    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 q = 0; q<n; q++)
        {
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
        }
    }




    //output padding
    for (int k = 0; k < outputpadding; k++)
    {
        fputc(0x00, outptr);
    }


}
//skip over old padding
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    fseek(inptr, padding, SEEK_CUR);
}





// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

1 Answer 1

1

The symptoms immediately point you the problem: you resize files with zero padding as large.bmp and smyley.bmp and do not resize small.bmp with padding 3.

Values for old and new padding are calculated correctly. But what about time to skip old and put new? I stop here and let you to correct the code.

Also, why do you calculate old padding inside your loop? You spend resources to get the same value again and again. Wouldn't it be better to make it in the beginning.

2
  • I have the same problem as above. Can you please be more specific please?
    – Sam Devo
    Jul 13, 2017 at 21:22
  • It's quite common problem but specifics differ. Show you code, describe symptoms in details and I (or smbdy else) help
    – obesman
    Jul 14, 2017 at 3:52

You must log in to answer this question.

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