I've tried to do this by going back to the beginning of each scanline n times. I'm fairly sure that my problem lies in where I've tried to reposition to the beginning of the scanline, but I've changed that around to many different values and can't seem to get it right.
#include <stdio.h>
#include <stdlib.h>
#include "bmp.h"
int main(int argc, char* argv[])
{
// ensure proper usage
if (argc != 4)
{
printf("Usage: ./resize n infile outfile\n");
return 1;
}
// remember filenames
char* infile = argv[2];
char* outfile = argv[3];
// remember size
int n = atoi(argv[1]);
//ensure size is inbetween 1 and 100
if (n < 1 || n > 100)
{
printf("please enter a n between 1 and 100\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, bf_new;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
bf_new = bf;
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi, bi_new;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
bi_new = 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;
}
// determine new dimensions
bi_new.biHeight = bi.biHeight * n;
bi_new.biWidth = bi.biWidth * n;
// calculate padding
int new_padding = (4 - (bi_new.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// calculate further dimensions
bi_new.biSizeImage = abs(bi_new.biHeight) * (bi_new.biWidth * sizeof(RGBTRIPLE) + new_padding);
bf_new.bfSize = bi_new.biSizeImage + 54;
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi_new, sizeof(BITMAPINFOHEADER), 1, outptr);
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
// iterate over scanline n times
for (int y = 0; y < n; y++)
{
// 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);
// write RGB triple to outfile n times
for (int x = 0; x < n; x++)
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 < new_padding; k++)
{
fputc(0x00, outptr);
}
// return to beginning of scanline
fseek(inptr, -(bi.biWidth + padding), SEEK_CUR);
}
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// that's all folks
return 0;
}