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

// remember filenames int n = atoi(argv[1]); 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 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; } //changed fields BITMAPFILEHEADER bfnew = bf; BITMAPINFOHEADER binew = bi; binew.biWidth *= n; binew.biHeight *= n; // determine padding for scanlines int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; int newpadding = (4 - (binew.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; binew.biSizeImage = ((sizeof(RGBTRIPLE) * binew.biWidth) + newpadding) * abs(binew.biHeight); bfnew.bfSize = binew.biSizeImage + 54; // write outfile's BITMAPFILEHEADER fwrite(&bfnew, sizeof(BITMAPFILEHEADER), 1, outptr); // write outfile's BITMAPINFOHEADER fwrite(&binew, sizeof(BITMAPINFOHEADER), 1, outptr); // iterate over infile's scanlines for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++) { // 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); // scale width n times for (int p = 0; p < n; p++) { // write RGB triple to outfile fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr); } } // skip over padding, if any fseek(inptr, padding, SEEK_CUR); // then add it back (to demonstrate how) for (int k = 0; k < newpadding; k++) { fputc(0x00, outptr); } } // close infile fclose(inptr); // close outfile fclose(outptr); // success return 0;


Have a good day I know this question asked many times but I really did'nt understand logic of padding and vertical scaling .What padding means exactly and what is it doing , I saw my problem solution many times but I want to understand logic behind it there is no sense just copy paste can somebody explain me solution of my problem line by line.Thanks (btw english not my mother tongue sorry for misunderstanding)


About you first question: What is padding?

In this type of bmp file, every pixel takes up 3 bytes (that's one of the checks you did on the inputfile: biBitcount = 24 bits = 3 bytes).

However, every line of pixels should be using a multiple of 4 bytes in the file. Therefore, you might have to add 1, 2 or 3 bytes to the end of each pixel line.

Those extra bytes are the padding. You handled in your formula for newpadding (plus the loop in which you use newpadding).

About your second question: How does vertical scaling work?

For the horizontal scaling, you made sure that every pixel (represented by a RGBTRIPLE) from the input file was written n times to the output file.

So for the vertical scaling, you should make sure that every (horizontally scaled) pixel line should be written n times to the output file ...

There are several ways to do that, for instance:

  • You might try to read every input line n times. Might be difficult to jump back correctly ...
  • You might try to collect the output pixel line in some buffer first, before writing it n times to the output file. Might be difficult to prevent memory leaks ...

Try to find some way to do this which looks natural to you.

You must log in to answer this question.

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