1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
#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;
}
//factor to resize by
const int FACTOR = atoi(argv[1]);
if (FACTOR < 1 || FACTOR > 100)
{
printf("Factor must be between 1 annd 100\n");
return 2;
}
// remember filenames
char* infile = argv[2];
char* outfile = argv[3];
// open input file
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
printf("Could not open %s.\n", infile);
return 3;
}
// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 4;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
//old width
int oldWidth = bi.biWidth;
int oldHeight = bi.biHeight;
int old_padding = ((4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4);
//resize image header <--- This is correct
bi.biWidth *= FACTOR;
bi.biHeight *= FACTOR;
//buffer to store old scanline in
RGBTRIPLE scanline[oldWidth];
// determine padding for scanlines
int padding = ((4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4);
// size of new scanline
int sizeOfScanline = (bi.biWidth * sizeof(RGBTRIPLE));
bi.biSizeImage = sizeOfScanline * (abs(bi.biHeight));
bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;
// 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 5;
}
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// iterate over infile's scanlines
for (int i = 0, height = abs(oldHeight); i < height; i++)
{
// iterate over pixels in scanline
for (int j = 0; j < oldWidth; j++)
{
// read RGB triple from infile
fread(&scanline[j], sizeof(RGBTRIPLE), 1, inptr);
}
fseek(inptr, old_padding, SEEK_CUR);
//write FACTOR number of scanlines
for (int s = 0; s < FACTOR; s++)
{
//write a scanline
for (int l = 0; l < bi.biWidth; l++)
{
//write a pixel
for (int m = 0; m < FACTOR; m++)
{
// write RGB triple to outfile
fwrite(&scanline[l], sizeof(RGBTRIPLE), 1, outptr);
}
}
//padding
for (int n = 0; n < padding; n++)
{
fputc(0x00, outptr);
}
//reset file position indicator WHY ??
fseek(outptr, -(sizeOfScanline * (FACTOR -1)), SEEK_CUR);
}
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
return 0;
}
|