-
-
Save anonymous/8befd9ba16f374c827a311812815f78a to your computer and use it in GitHub Desktop.
resize.c - shared from CS50 IDE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copies a BMP piece by piece, just because. | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include<cs50.h> | |
#include<math.h> | |
#define min(a,b) \ | |
({ typeof (a) _a = (a); \ | |
typeof (b) _b = (b); \ //Min defined | |
_a < _b ? _a : _b; }) | |
#include "bmp.h" | |
int main(int argc, char *argv[]) | |
{ | |
// ensure proper usage | |
if (argc != 4) | |
{ | |
fprintf(stderr, "Usage: ./copy f infile outfile\n"); | |
return 1; | |
} | |
float f=atof(argv[1]); | |
//float f=sscanf(argv[1], " %f", &f); It can also be used | |
//exit if f is invalid | |
if(f > 100.0 || f < 0.0) { | |
fprintf(stderr, "Usage: ./resize f infile outfile\n"); | |
return 1; | |
} | |
// remember filenames | |
char *infile = argv[2]; | |
char *outfile = argv[3]; | |
// 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; | |
BITMAPFILEHEADER bof; | |
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr); | |
bof=bf; | |
// read infile's BITMAPINFOHEADER | |
BITMAPINFOHEADER bi; | |
BITMAPINFOHEADER boi; | |
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr); | |
boi=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 padding for scanlines | |
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; | |
//determining width | |
boi.biWidth=floor(bi.biWidth*f); | |
//determining height by checking top down and bottom up and compliang to top down | |
boi.biHeight=floor(((bi.biHeight>0)?-bi.biHeight:bi.biHeight)*f); | |
//calculating padding for new file | |
int paddingNew = (4 - (boi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; | |
//new size of image excluding headers | |
boi.biSizeImage=(abs(boi.biHeight)*((boi.biWidth* sizeof(RGBTRIPLE))+paddingNew)); | |
//determining new bfsize | |
bof.bfSize=boi.biSizeImage + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); | |
// write outfile's BITMAPFILEHEADER | |
fwrite(&bof, sizeof(BITMAPFILEHEADER), 1, outptr); | |
// write outfile's BITMAPINFOHEADER | |
fwrite(&boi, sizeof(BITMAPINFOHEADER), 1, outptr); | |
//declaring outfile scanline array | |
RGBTRIPLE pixel[abs(bi.biHeight)][bi.biWidth]; | |
if(bi.biHeight<0) | |
{ | |
// iterate over infile's scanlines | |
for (int i = 0; i< abs(bi.biHeight) ; i++) | |
{ | |
// 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); | |
fread(&(pixel[i][j]), sizeof(RGBTRIPLE), 1, inptr); | |
//pixel[i][j]=triple; | |
} | |
// skip over padding, if any | |
fseek(inptr, padding, SEEK_CUR); | |
} | |
} | |
else | |
{ | |
for(int i=bi.biHeight-1; i>=0; i--) | |
{ | |
for (int j = 0; j < bi.biWidth; j++) | |
{ | |
// temporary storage | |
// RGBTRIPLE triple; | |
// read RGB triple from infile | |
// fread(&triple, sizeof(RGBTRIPLE), 1, inptr); | |
fread(&(pixel[i][j]), sizeof(RGBTRIPLE), 1, inptr); | |
//pixel[i][j]=triple; | |
} | |
// skip over padding, if any | |
fseek(inptr, padding, SEEK_CUR); | |
} | |
} | |
RGBTRIPLE outpixel[abs(boi.biHeight)][boi.biWidth]; | |
int row,col; | |
if(f>1) | |
{ | |
for(int i=0; i<abs(bi.biHeight); i++) | |
{ | |
row=floor(i*f); | |
for(int t=row; t<row+floor(f);t++) | |
{ | |
for(int j=0; j<bi.biWidth; j++) | |
{ | |
col=ceil(j*f); //This block of code(Line : 155-171) doesn't work for f<1 #ISSUE | |
for(int k=col; k<col+floor(f);k++) | |
{ outpixel[t][k]=pixel[i][j];} | |
} | |
} | |
} | |
} | |
else | |
{ | |
int r=0,c=0; | |
for(int i=0; i<abs(boi.biHeight);) | |
{ | |
for(int j=0; j<boi.biWidth;) | |
{ | |
outpixel[i][j]=pixel[r][c]; | |
j++; | |
c= min(c+floor(1.0/f), bi.biWidth) ; //Use of function min | |
} | |
r= min(r+floor(1.0/f),abs(bi.biHeight)) ; | |
i++; | |
} | |
} | |
/* | |
int indI, indJ; | |
for(int i = 0; i < abs(bi.biHeight); i++) { | |
indI = floor(i*f); | |
for(int j = 0; j < bi.biWidth; j++) { | |
indJ = ceil(f*j); | |
outpixel[indI][indJ] = pixel[i][j]; | |
for(int k = floor(f) - 1; k > 0; k--) { | |
outpixel[indI][indJ + k] = pixel[i][j]; | |
} | |
} //This block of Code(Line : 172-191) cleared check50 but it doesn't work fine when applied to large.bmp | |
for(int l = floor(f) - 1; l >= 0; l--) { | |
for(int j = 0; j < bi.biWidth; j++) { | |
indJ = ceil(f*j); | |
outpixel[indI + l][indJ] = pixel[i][j]; | |
for(int k = floor(f) - 1; k > 0; k--) { | |
outpixel[indI + l][indJ + k] = pixel[i][j]; | |
} | |
} | |
} | |
} | |
*/ | |
// writing to output file after adding padding | |
for(int i=0; i<abs(boi.biHeight); i++) | |
{ | |
for(int j=0; j<boi.biWidth; j++) | |
{ | |
fwrite(&outpixel[i][j], sizeof(RGBTRIPLE), 1, outptr); | |
} | |
for (int k = 0; k < paddingNew; k++) | |
{ | |
fputc(0x00, outptr); | |
} | |
} | |
// close infile | |
fclose(inptr); | |
// close outfile | |
fclose(outptr); | |
// success | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment