0

I have similar question as there was asked, but can't find answer.

Here is my code:

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

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

#include "bmp.h"

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

// remember filenames
int sf = atoi(argv[1]); // size factor for resizing
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;
}

// create structs that will be written in output file
BITMAPFILEHEADER bf_out;
bf_out = bf;

BITMAPINFOHEADER bi_out;
bi_out = bi;

bi_out.biWidth = bi.biWidth * sf;
bi_out.biHeight = bi.biHeight * sf;

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

// determine padding for scanlines for input file
int padding_inp =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

/**
* See http://cs50.stackexchange.com/questions/14016/pset4-resize-c-bfsize-bisizeimage-formulas for understand of values in BITMAPINFOHEADER
* */

bi_out.biSizeImage = bi_out.biWidth * abs(bi_out.biHeight) * sizeof(RGBTRIPLE) + bi_out.biHeight * padding * sizeof(BYTE);

bf_out.bfSize =  bi_out.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);



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

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


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

    //iterate sf times through scanlines
    for (int r = 0; r < sf; r++ )
    {
        // 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);

            // iterate sf times through pixels

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

        }

        // skip over padding, if any
        fseek(inptr, -( bi.biWidth * sizeof(RGBTRIPLE)  + padding_inp) , SEEK_CUR);

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


}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}

As a result of this programm I get improper img enter image description here and error:

resize.c:124:26: runtime error: negation of 12 cannot be represented in type 'unsigned long'

Could someone help me, since I don't have any idea what to do next.

1

You could use

fseek(inptr, -bi.biWidth * sizeof(RGBTRIPLE), SEEK_CUR);

(no padding, as you never read some) to go back to the start of the line where you fseek at the moment, and after that loop, use

fseek(inptr, bi.biWidth * sizeof(RGBTRIPLE)  + padding_inp, SEEK_CUR);

to jump to the next line.

3
  • Thank you very much for your time and for your answer. It almost works properly !!))))) Now it is giving me an arror which related with type of value resize.c:124:38: runtime error: unsigned integer overflow: 18446744073709551613 * 3 cannot be represented in type 'unsigned long' Could you please explaine me where is a misatake? Note: result image is great and exactly as i need – Илья Шулика Oct 12 '16 at 12:54
  • The error says you are "overflowing" an integer, as in your variable can't hold the number requested. You must then change the data type to something like unsigned long long. But that is really big (16 bytes). The number it was requested to store is so large (18446744073709551613 * 3) that your code is very likely doing something wrong. If you need more details you're welcome to post another question :) – kluvin Oct 12 '16 at 14:57
  • I took the code, changed/added the two fseeks to what I wrote above, fixed bi_out.biSizeImage (height should always be with abs, you could write that once and use parentheses to group the line with plus padding), and it passes. So cannot reproduce the problem :/ – Blauelf Oct 13 '16 at 23:40

You must log in to answer this question.

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