0

So I thought I finished but the image only half way is written. Not sure what I did wrong but the image scales but only the top half. I tried both ways I could think of for the loop but decided using i%factor was best.

// Copies a BMP file

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

#include "bmp.h"

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

// remember factor
int factor = atoi(argv[1]);
// remember filenames
char *infile = argv[2];
char *outfile = argv[3];
if(factor < 1 || factor > 100)
{
    printf("Please try again");
}
// 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;
}

// Sets new file headers equal to old ones
BITMAPFILEHEADER newbf = bf;
BITMAPINFOHEADER newbi = bi;
// Updates width and height
newbi.biWidth *= factor;
newbi.biHeight *= factor;
// Deals with padding; basically just took the old one and changed width to the new one
int newPadding = (4 - (newbi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// Deals with size of image
newbi.biSizeImage = (newbi.biWidth * sizeof(RGBTRIPLE)+newPadding)*abs(newbi.biHeight);
newbf.bfSize = newbi.biSizeImage + 54;





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

// write outfile's BITMAPINFOHEADER
fwrite(&newbi, 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 q = 0; q < factor; q++)
    //{
        // fscan is nessesary because it resets the scanner to the correct position; basically prints each line factor times
        // iterate over pixels in scanline
        // sets the scanner back a line
        if(i%factor!=0)
        {
            fseek(inptr,-(padding + bi.biWidth * sizeof(RGBTRIPLE)),SEEK_CUR);
        }
        for (int j = 0; j < bi.biWidth; j++)
        {

            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
            // write RGB triple to outfile
            // How to do this? maybe use an %?

            // Scales horizontally by printing each picture a factor times.
            for(int x = 0; x < factor; x++)
            {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

        }

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

        // then add it back (to demonstrate how)
        // OOPS originally forgot to change padding to new.
        for (int k = 0; k < newPadding; k++)
        {
            fputc(0x00, outptr);
        }

//}
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

1 Answer 1

0

The way you do it, your outer loop would have to go over all the output lines, not input lines. So newbi instead of bi on that loop.

You must log in to answer this question.

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