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

#include <string.h>

#include "bmp.h"

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

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

//ensure n less than 100

if(n > 100 || n < 1)
{
    fprintf(stderr, "n shouldnt be more than 100");
    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;
}


BITMAPINFOHEADER bi_out;
bi_out=bi;

bi_out.biHeight *= n;
bi_out.biWidth *= n;

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

bi_out.biSizeImage = ((sizeof(RGBTRIPLE) * bi_out.biWidth) + padding2) * abs(bi_out.biHeight);
bf.bfSize = bi_out.biSizeImage + 54; // sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);





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

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




// iterate over infile's scanlines
for (int i = 0; i < abs(bi_out.biHeight); i++)
{
    // iterate over pixels in scanline
    for (int j = 0; j < bi_out.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

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

        for(int k = 0; k < n; ++k)
        {
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
        }

    }


    for (int k = 0; k < padding2; k++)
    {
        fputc(0x00, outptr);
    }

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

}


// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

3
  • Did you figure it out yet? ;-)
    – Cliff B
    Commented Jun 18, 2018 at 6:17
  • @CliffB i rectified the vertical scaling part but i dont understand why "using biWidth and biHeight for the output file to control reading from the input file." is an issue ? or perhaps i dont undertsand what you mean by that ..?
    – user21692
    Commented Jun 21, 2018 at 6:49
  • You modified biWidth and biHeight for the output file header. Then they are used to count the width of the input file reads as well as the number of lines read from the input file. If the output file image is scaled up by 2, that means that the code is going to read 2 rows of pixels when it should read 1 and it'll read twice as many rows vertically as there are in the image. In short, it reads 4 times as much data as it should. It'll work when scale is 1, but not for anything else.
    – Cliff B
    Commented Jun 21, 2018 at 7:02

1 Answer 1

2

There are two major issue. First, the code is using biWidth and biHeight for the output file to control reading from the input file.

Second, there's no actual code to handle vertical scaling.

Perhaps a review of the walkthroughs is in order?

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

You must log in to answer this question.

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