0

Could anyone help? I have been working on resize for days but there must be a bug somewhere because it still does not work. Just an idea, but it is probably fseek(). Any help is appreciated.

int main(int argc, char* argv[])
{

// ensure proper usage
int factor = atoi(argv[1]);
if (argc != 4 || factor < 1 || factor > 100)
{
    printf("Usage: './copy n infile outfile' where n is an integer that is not less than 1 but not more than 100\n");
    return 1;
}

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

// determine original padding for scanlines    
BITMAPINFOHEADER bi;
int inpadding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// determine new padding for scanlines
int outpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE) * factor) % 4) % 4;

// Copy of original data
long originalbiWidth = bi.biWidth;
long originalbiHeight = bi.biHeight;

// read infile's BITMAPINFOHEADER
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;
}

// rewrite some data in header
bi.biWidth = bi.biWidth * factor;
bi.biHeight = bi.biHeight * factor;
bi.biSizeImage = (bi.biWidth + outpadding) * abs(bi.biHeight) * sizeof(RGBTRIPLE);
bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

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

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

// iterate over infile's scanlines
for (int i = 0, l = abs(originalbiHeight); i < l; i++)
{
    // write rows 'factor' times to outfile
    for (int m = 0; m < factor; m++)
    {
        if (m != 0)
        {
        // return the cursor to the beginning of the scanline
            fseek(inptr, - (originalbiWidth * sizeof(RGBTRIPLE) + inpadding), SEEK_CUR);
        }
        // iterate over pixels in scanline
        for (int j = 0; j < originalbiWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

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


            // write RGB triple 'factor' times to outfile
            for (int n = 0; n < factor; n++)
            {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

            // skip over padding, if any
            fseek(inptr, inpadding, SEEK_CUR);

            // then add it back (to demonstrate how)
            for (int k = 0; k < outpadding; k++)
            {
                fputc(0x00, outptr);
            }

    }
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}

1 Answer 1

0

The most basic mistake I can see you have, is that you first create the struct for the BITMAPINFOHEADER, then you use its biWidth attribute and then you read the actual BITMAPINFOHEADER from the file. There might be more problems.

// determine original padding for scanlines    
BITMAPINFOHEADER bi;
int inpadding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// determine new padding for scanlines
int outpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE) * factor) % 4) % 4;

// Copy of original data
long originalbiWidth = bi.biWidth;
long originalbiHeight = bi.biHeight;

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

If this answers your question please accept it by clicking the gray check-mark to the left, so that it becomes green. You can also vote it up by pressing the up arrow above the check-mark. And don't forget to keep coding!

5
  • Thank you for your help! Now it works fine according to my visual check, however, the program that checks its correctness still gives some unidentifiable errors. For now thank you for your hint, I will submit it and we will see. I might return to you in the future.
    – Ervin
    Commented Aug 28, 2015 at 21:07
  • I'll be here waiting to help again if needed! Keep trying. You are almost done!
    – ChrisG
    Commented Aug 28, 2015 at 23:58
  • Okay, so probably there must be something else since I got zero point. However, according to my visual check there is no mistake. I assume it has something to do with padding because either headers and copy are fine. May I ask for your hint?
    – Ervin
    Commented Sep 7, 2015 at 19:52
  • Could you ask a new question, including the revised code you submitted? It will be difficult to help you from the comment section.
    – ChrisG
    Commented Sep 7, 2015 at 21:46
  • cs50.stackexchange.com/questions/13881/… Thanks!
    – Ervin
    Commented Sep 13, 2015 at 23:57

You must log in to answer this question.

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