-
-
Save sameekapdi/7552bb3b9e4eb885b039003ccd7fd7de to your computer and use it in GitHub Desktop.
Resize
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
/** | |
* BMP-related data types based on Microsoft's own. | |
*/ | |
#include <stdint.h> | |
/** | |
* Common Data Types | |
* | |
* The data types in this section are essentially aliases for C/C++ | |
* primitive data types. | |
* | |
* Adapted from https://msdn.microsoft.com/en-us/library/cc230309.aspx. | |
* See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h. | |
*/ | |
typedef uint8_t BYTE; | |
typedef uint32_t DWORD; | |
typedef int32_t LONG; | |
typedef uint16_t WORD; | |
/** | |
* BITMAPFILEHEADER | |
* | |
* The BITMAPFILEHEADER structure contains information about the type, size, | |
* and layout of a file that contains a DIB [device-independent bitmap]. | |
* | |
* Adapted from https://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx. | |
*/ | |
typedef struct | |
{ | |
WORD bfType; | |
DWORD bfSize; | |
WORD bfReserved1; | |
WORD bfReserved2; | |
DWORD bfOffBits; | |
} __attribute__((__packed__)) | |
BITMAPFILEHEADER; | |
/** | |
* BITMAPINFOHEADER | |
* | |
* The BITMAPINFOHEADER structure contains information about the | |
* dimensions and color format of a DIB [device-independent bitmap]. | |
* | |
* Adapted from https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx. | |
*/ | |
typedef struct | |
{ | |
DWORD biSize; | |
LONG biWidth; | |
LONG biHeight; | |
WORD biPlanes; | |
WORD biBitCount; | |
DWORD biCompression; | |
DWORD biSizeImage; | |
LONG biXPelsPerMeter; | |
LONG biYPelsPerMeter; | |
DWORD biClrUsed; | |
DWORD biClrImportant; | |
} __attribute__((__packed__)) | |
BITMAPINFOHEADER; | |
/** | |
* RGBTRIPLE | |
* | |
* This structure describes a color consisting of relative intensities of | |
* red, green, and blue. | |
* | |
* Adapted from https://msdn.microsoft.com/en-us/library/dd162939(v=vs.85).aspx. | |
*/ | |
typedef struct | |
{ | |
BYTE rgbtBlue; | |
BYTE rgbtGreen; | |
BYTE rgbtRed; | |
} __attribute__((__packed__)) | |
RGBTRIPLE; |
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 "bmp.h" | |
int main(int argc, char *argv[]) | |
{ | |
// ensure proper usage | |
if (argc != 4) | |
{ | |
fprintf(stderr, "Usage: ./copy n infile outfile\n"); | |
return 1; | |
} | |
//get float value | |
float scale = atof(argv[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; | |
} | |
// create and read infile's BITMAPFILEHEADER | |
BITMAPFILEHEADER bf_in; | |
fread(&bf_in, sizeof(BITMAPFILEHEADER), 1, inptr); | |
// create and read infile's BITMAPINFOHEADER | |
BITMAPINFOHEADER bi_in; | |
fread(&bi_in, sizeof(BITMAPINFOHEADER), 1, inptr); | |
// ensure infile is (likely) a 24-bit uncompressed BMP 4.0 | |
if (bf_in.bfType != 0x4d42 || bf_in.bfOffBits != 54 || bi_in.biSize != 40 || | |
bi_in.biBitCount != 24 || bi_in.biCompression != 0) | |
{ | |
fclose(outptr); | |
fclose(inptr); | |
fprintf(stderr, "Unsupported file format.\n"); | |
return 4; | |
} | |
// determine padding for scanlines for the infile | |
int in_padding = (4 - (bi_in.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; | |
//an array to store our input image. | |
RGBTRIPLE image[bi_in.biWidth][abs(bi_in.biHeight)]; | |
// iterate over infile's scanlines | |
for (int i = 0, biHeight = abs(bi_in.biHeight); i < biHeight; i++) | |
{ | |
// iterate over pixels in scanline | |
for (int j = 0; j < bi_in.biWidth; j++) | |
{ | |
// temporary storage | |
RGBTRIPLE triple; | |
// read RGB triple from infile | |
fread(&triple, sizeof(RGBTRIPLE), 1, inptr); | |
// store the image in an array | |
image[j][i] = triple; | |
} | |
// skip over padding, if any | |
fseek(inptr, in_padding, SEEK_CUR); | |
} | |
// create the outfile's BITMAPFILEHEADER | |
BITMAPFILEHEADER bf_out; | |
bf_out = bf_in; | |
// create the outfile's BITMAPINFOHEADER | |
BITMAPINFOHEADER bi_out; | |
bi_out = bi_in; | |
//calculate the new width and height; | |
bi_out.biWidth = bi_in.biWidth * scale; | |
bi_out.biHeight = bi_in.biHeight * scale; | |
// determine padding for scanlines for the infile | |
int out_padding = (4 - (bi_out.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; | |
//change the image size | |
bi_out.biSizeImage = ((sizeof(RGBTRIPLE) * bi_out.biWidth) + out_padding) * abs(bi_out.biHeight); | |
//change the file size | |
bf_out.bfSize = bi_out.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); | |
// write outfile's BITMAPFILEHEADER | |
fwrite(&bf_out, sizeof(BITMAPFILEHEADER), 1, outptr); | |
// write outfile's BITMAPINFOHEADER | |
fwrite(&bi_out, sizeof(BITMAPINFOHEADER), 1, outptr); | |
// iterate over outfile's scanlines | |
for (int i = 0, biHeight = abs(bi_out.biHeight); i < biHeight; i++) | |
{ | |
// iterate over pixels in scanline | |
for (int j = 0; j < bi_out.biWidth; j++) | |
{ | |
// temporary storage | |
RGBTRIPLE triple; | |
//determine which pixel to use for the outfile | |
triple = image[(int) (j / scale)][(int) (i / scale)]; | |
// write RGB triple to outfile | |
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr); | |
} | |
// then add it back (to demonstrate how) | |
for (int k = 0; k < out_padding; 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