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

#include "bmp.h"

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

    // remember filenames
    int n = atoi(argv[1]);
    char* infile = argv[2];
    char* outfile = argv[3];

    if ( n < 1 || n > 100)
    {
        printf("Error : Integers between 1 to 100 only\n");
        return 5;
    }

    // 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, bfNew;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
    bfNew  = bf;

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

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

    biNew.biHeight = bi.biHeight*n;
    biNew.biWidth = bi.biWidth*n;

    int paddingNew = (4 - (biNew.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    biNew.biSizeImage = abs(biNew.biHeight)*(biNew.biWidth * sizeof(RGBTRIPLE) + paddingNew);
    bfNew.bfSize = bf.bfSize + biNew.biSizeImage - bi.biSizeImage; 

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

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

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

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

       for ( int m = 0; m < n; m++)
       {
            // temporary storage
                RGBTRIPLE triple;
            // iterate over pixels in scanline
            for (int j = 0; j < bi.biWidth; j++)
            {
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

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

            // new padding
            for ( int k = 0; k < paddingNew; k++)
                fputc( 0x00, outptr);

            //back to the beginning of the scan line
            if ( m < n-1)
                fseek( inptr, -bi.biWidth * sizeof(RGBTRIPLE), SEEK_CUR);
       }

        fseek(inptr, padding, SEEK_CUR);

    }


    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
3
  • Couldn't post the entire error message. I hope this specifies something..........runtime error: unsigned integer overflow: 18446744073709551608 * 3 cannot be represented in type 'unsigned long' Oct 9 '16 at 14:52
  • You should post in your question the arguments being used.
    – andy5995
    Oct 9 '16 at 18:47
  • no matter what are the arguments, error is same with identical overflow value mentioned above. Oct 10 '16 at 4:37
2

About the overflow, read this:
Error in my pset4 resize.c code

Apart from that, what's happening is that you're copying the headers to bi and bf, but you're not copying those headers also to bfNew and biNew, so you're left with lots of garbage values, since you only alter some of them in bfNew and biNew and leave the others untouched, thus uninitialized.

If you fseek backwards and copy the headers again to bfNew and biNew (or don't fseek() and copy directly from bi to biNew and bf to bfNew... your choice), it should work.

2
  • I directly initialized biNew to bi and bfNew to bf but still not working. I have updated the code. Oct 10 '16 at 4:34
  • It worked with the same code as above as i declared offset separately as : long offset = bi.biWidth*sizeof(RGBTRIPLE) and then used it in the fseek () function. But I am still confused. Oct 10 '16 at 15:03

You must log in to answer this question.

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