Created
December 14, 2017 04:27
-
-
Save alaingalvan/848e62386f5ae438d9eb9a4501e3d88c to your computer and use it in GitHub Desktop.
This file contains hidden or 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
//----------------------------------------------------------------------------- | |
// Photoshop Trick | |
// Author: Kiran Sudhakara | |
// | |
// Produces an image that most image editors cannot downsize Inspired | |
// by http://www.4p8.com/eric.brasseur/gamma.html | |
//----------------------------------------------------------------------------- | |
#include "windows.h" | |
#include <stdio.h> | |
//----------------------------------------------------------------------------- | |
typedef enum FileDialogType { | |
DIALOG_OPEN, | |
DIALOG_SAVE | |
} FileDialogType; | |
int GetBitmapPath(char *sz_path, int len, FileDialogType dialog_type) | |
{ | |
OPENFILENAME desc; | |
memset(&desc,0,sizeof(desc)); | |
sz_path[0] = '\0'; | |
desc.lStructSize = sizeof(desc); | |
desc.lpstrFile = sz_path; | |
desc.nMaxFile = len; | |
desc.lpstrFilter = "Windows Bitmap File\0*.bmp\0"; | |
if (dialog_type == DIALOG_OPEN) | |
desc.Flags = OFN_FILEMUSTEXIST; | |
else | |
desc.Flags = OFN_OVERWRITEPROMPT; | |
if (dialog_type == DIALOG_OPEN) { | |
if (!GetOpenFileName(&desc)) | |
return 1; | |
} else { | |
if (!GetSaveFileName(&desc)) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
//----------------------------------------------------------------------------- | |
//this only supports 24 bit bitmaps! | |
typedef struct rgb_t { | |
unsigned char b; | |
unsigned char g; | |
unsigned char r; | |
} rgb_t; | |
typedef struct image_t { | |
int w,h; | |
rgb_t *rgb; | |
} image_t; | |
int Image_Init(image_t *img, int w, int h) | |
{ | |
img->w = w; | |
img->h = h; | |
img->rgb = (rgb_t*)malloc(w*h*sizeof(rgb_t)); | |
return 0; | |
} | |
int Image_InitFromBitmap(image_t *img) | |
{ | |
FILE *fp; | |
BITMAPFILEHEADER file_header; | |
BITMAPINFOHEADER info_header; | |
int buf_size; | |
char sz_path[260]; | |
if (GetBitmapPath(sz_path, sizeof(sz_path),DIALOG_OPEN)) | |
return 1; | |
//read file into image | |
fp = fopen(sz_path, "rb"); | |
fread(&file_header, sizeof(file_header), 1, fp); | |
fread(&info_header, sizeof(info_header), 1, fp); | |
fseek(fp, file_header.bfOffBits, SEEK_SET); | |
img->h = info_header.biHeight; | |
img->w = info_header.biWidth; | |
buf_size = img->h * img->w * sizeof(rgb_t); | |
if (info_header.biBitCount != 24) | |
return 1; | |
img->rgb = (rgb_t*)malloc(buf_size); | |
fread(img->rgb, 1, buf_size, fp); | |
fclose(fp); | |
return 0; | |
} | |
void Image_Destroy(image_t *img) | |
{ | |
free(img->rgb); | |
memset(img, 0, sizeof(image_t)); | |
} | |
int Image_WriteToBitmap(image_t *img) | |
{ | |
FILE *fp; | |
BITMAPFILEHEADER file_header; | |
BITMAPINFOHEADER info_header; | |
char sz_path[260]; | |
int img_size; | |
union { | |
unsigned short type; | |
char id[2]; | |
} magic; | |
memset(&file_header, 0, sizeof(file_header)); | |
memset(&info_header, 0, sizeof(info_header)); | |
magic.id[0] = 'B'; | |
magic.id[1] = 'M'; | |
img_size = img->w * img->h * sizeof(rgb_t); | |
file_header.bfType = magic.type; | |
file_header.bfSize = sizeof(file_header) + sizeof(info_header) + img_size; | |
file_header.bfOffBits = sizeof(file_header) + sizeof(info_header); | |
info_header.biSize = sizeof(info_header); | |
info_header.biWidth = img->w; | |
info_header.biHeight = img->h; | |
info_header.biPlanes = 1; | |
info_header.biBitCount = 24; | |
info_header.biCompression = 0; | |
info_header.biSizeImage = img_size; | |
//write to file | |
if (GetBitmapPath(sz_path, sizeof(sz_path), DIALOG_SAVE)) | |
return 1; | |
fp = fopen(sz_path, "wb"); | |
fwrite(&file_header, sizeof(file_header), 1, fp); | |
fwrite(&info_header, sizeof(info_header), 1, fp); | |
fwrite(img->rgb, img_size, 1, fp); | |
fclose(fp); | |
return 0; | |
} | |
void Image_PhotoshopTrick(image_t *out, image_t *in) | |
{ | |
int i,j; | |
int w,h; | |
rgb_t px,px_out; | |
w = in->w; | |
h = in->h; | |
for (j=0; j<h; j+=2) { | |
for (i=0; i<w; i++) { | |
px = in->rgb[j*w + i]; | |
px_out.r = 127 - px.r /2; | |
px_out.g = 127 - px.g /2; | |
px_out.b = 127 - px.b /2; | |
out->rgb[j*w + i] = px_out; | |
px_out.r = 127 + px.r /2; | |
px_out.g = 127 + px.g /2; | |
px_out.b = 127 + px.b /2; | |
out->rgb[(j+1)*w + i] = px_out; | |
} | |
} | |
} | |
//----------------------------------------------------------------------------- | |
int main(int argc, char *argv[]) | |
{ | |
image_t in, out; | |
if (Image_InitFromBitmap(&in)) | |
return 1; | |
Image_Init(&out, in.w, in.h); | |
Image_PhotoshopTrick(&out, &in); | |
Image_WriteToBitmap(&out); | |
Image_Destroy(&in); | |
Image_Destroy(&out); | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment