So my small image is resizing vertically but I get all the wrong colors. Can someone take a quick peek at my rewrite method to see where I've gone wrong? I've attached a pic of my large.bmp passing in n=4, my code is below.
// Copies a BMP file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
// TODO: REMOVE - Only for Testing Purposes
for (int i = 0; i < strlen(*argv); i++)
{
printf("this is arg %i - argv[%s]\n", i, argv[i]);
}
fprintf(stderr, "Usage: ./resize n infile outfile\n");
return 1;
}
else
{
// check if first argument is a digit
//char *number = argv[1];
// for each character in the number
for (int i = 0; i < strlen(argv[1]);i++)
{
// if the character is not a digit
if (!isdigit(argv[1][i]))
{
fprintf(stderr, "Usage: ./resize n infile outfile\n");
return 1;;
}
}
}
// get the first argument (digit)
int n = atoi(argv[1]);
//printf("this is n:%i\n", n);
// remember filenames
char *infile = argv[2];
char *outfile = argv[3];
// open input file (inptr now points to infile)
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);
//printf("this is INFILE bf....\n");
//printf("this is bf type: %hu\n", bf.bfType); // will be 'BM' or 19778
//printf("this is bf size: %d\n", bf.bfSize); //size in bytes of the bitmap file (includes: pixels, padding, headers)
//printf("this is size of bf: %lu\n", sizeof(BITMAPFILEHEADER)); // should print 14 bytes
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
//printf("this is INFILE bi....\n");
//printf("this is bi width: %d\n", bi.biWidth); // width of image in pixels, does not include padding
//printf("this is bi height: %d\n", bi.biHeight); // height of image in pixels
//printf("this is bi image size: %d\n", bi.biSizeImage); // total size of image in bytes, includes pixels and padding (negative because it's top down)
//printf("this is biWidth before resize: %i\n", bi.biWidth);
// get the bytes for the small image (width of pixels * 3)
int smallBytes = bi.biWidth * 3;
int paddingOriginal = 0;
// check if smallBytes is divisible by 4, if it's not then calculate the padding
if (smallBytes % 4 != 0)
{
paddingOriginal = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
//printf("this is pading before resize: %i\n", paddingOriginal);
}
// change height and width of the bitmap file (OUTFILE)
bi.biWidth *= n;
bi.biHeight *= n;
// get the padding for the infile
int paddingInfile = 0;
// get the bytes of the small image (width in pixels x 3)
int bytes = bi.biWidth * 3;
// holds the result of padding from below calculation
int padding = 0;
// if bytes are not a multiple of 4 then
if (bytes % 4 != 0)
{
// calculate the padding
padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
//printf("this is padding after Resize: %i\n", padding);
}
//printf("this is padding after Resize: %i\n", padding);
// calcuate the new biSizeImage for Outfile using the formula
bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + padding * abs(bi.biHeight));
//printf("this is new biSizeImage: %i\n", bi.biSizeImage);
// calcuate the new bfSize for Outfile using the formula
bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//printf("this is new bfSize: %i\n", bf.bfSize);
// 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;
}
// change image size of OUTFILE
//printf(">>>this is size of RGBTriple:%lu\n", sizeof(RGBTRIPLE));
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
//printf("this is OUTFILE bf....\n");
//printf("this is bf type: %hu\n", bf.bfType); // will be 'BM' or 19778
//printf("this is bf size: %d\n", bf.bfSize); //size in bytes of the bitmap file (includes: pixels, padding, headers)
//printf("this is size of bf: %lu\n", sizeof(BITMAPFILEHEADER)); // should print 14 bytes
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
//printf("this is OUTFILE bi....\n");
//printf("this is bi width: %d\n", bi.biWidth); // width of image in pixels, does not include padding
//printf("this is bi height: %d\n", bi.biHeight); // height of image in pixels
//printf("this is bi image size: %d\n", bi.biSizeImage); // total size of image in bytes, includes pixels and padding (negative because it's top down)
// determine padding for scanlines
//int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// iterate over infile's scanlines (row or height)
for (int i = 0, biHeight = abs(bi.biHeight)/n; i < biHeight; i++)
{
//printf("this is biWidth in loop: %i\n", bi.biWidth);
// for each row make a copy of array
// declare new struct for vertical resizing, make size equal to biWidth
RGBTRIPLE vertical[bi.biWidth];
//printf("this is i: %i\n", i);
// iterate over infile's pixels in scanline (column or width)
for (int j = 0, biWidth = bi.biWidth/n; j < biWidth; j++)
{
//printf("this is biWidth: %i\n", biWidth);
//printf("this is j: %i\n", j);
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
// Resize Horizontally here
for (int resizeHor = 0; resizeHor < n; resizeHor++)
{
//printf("this is resizeHor: %i\n", resizeHor);
// write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
fread(&vertical, bi.biWidth, 1, inptr);
// Resize Veritcally
for (int writeArray = 0; writeArray < n; writeArray++)
{
printf("this is size of veritcal: %lu\n", sizeof(vertical));
// write RGB triple to outfile
fwrite(&vertical, sizeof(vertical), 1, outptr);
// write outile's padding to end of row
for (int k = 0; k < padding; k++)
{
fputc(0x00, outptr);
}
}
}
// skip over infile's padding, if any, from the current position of the pointer
fseek(inptr, paddingOriginal, SEEK_CUR);
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}