Last active
July 29, 2020 01:07
-
-
Save flibitijibibo/a6af323524347781a18a72f2b5b4de02 to your computer and use it in GitHub Desktop.
Basic image comparison tool. http://www.flibitijibibo.com/adobesucks.zip
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
/* Adobe Sucks - Image Comparison Program for Checking Creative Suite Fuckups | |
* Written by Ethan "flibitijibibo" Lee | |
* http://www.flibitijibibo.com/ | |
* | |
* Released under public domain. | |
* No warranty implied; use at your own risk. | |
* | |
* How to Build: | |
* cc adobesucks.c `sdl2-config --cflags --libs` -lSDL2_image | |
*/ | |
#include <SDL.h> | |
#include <SDL_image.h> | |
#define SOLID_COLOR 0 | |
static SDL_Surface* LoadImage( | |
SDL_Renderer *renderer, | |
SDL_Texture *texture, | |
char *imgPath | |
) { | |
SDL_Surface *surface; | |
SDL_Event evt; | |
Uint8 free = 0; | |
while (imgPath == NULL) | |
{ | |
while (SDL_PollEvent(&evt) > 0) | |
{ | |
if (evt.type == SDL_QUIT) | |
{ | |
return NULL; | |
} | |
if (evt.type == SDL_DROPFILE) | |
{ | |
imgPath = evt.drop.file; | |
free = 1; | |
} | |
} | |
SDL_RenderClear(renderer); | |
if (texture != NULL) | |
{ | |
SDL_RenderCopy( | |
renderer, | |
texture, | |
NULL, | |
NULL | |
); | |
} | |
SDL_RenderPresent(renderer); | |
} | |
surface = IMG_Load(imgPath); | |
if (free) | |
{ | |
SDL_free(imgPath); | |
} | |
if (!surface) | |
{ | |
SDL_ShowSimpleMessageBox( | |
SDL_MESSAGEBOX_ERROR, | |
"Image load failed!", | |
IMG_GetError(), | |
NULL | |
); | |
} | |
return surface; | |
} | |
int main(int argc, char **argv) | |
{ | |
SDL_Window *window; | |
SDL_Renderer *renderer; | |
SDL_Texture *texture; | |
SDL_Surface *src, *dst, *tmp; | |
char *imgPath; | |
char *diff, *srcpx, *dstpx; | |
int pitch, wi, hi; | |
SDL_Event evt; | |
Uint8 run = 1; | |
SDL_Init(SDL_INIT_VIDEO); | |
SDL_CreateWindowAndRenderer( | |
256, | |
256, | |
SDL_WINDOW_SHOWN, | |
&window, | |
&renderer | |
); | |
SDL_SetWindowTitle(window, "Drag original image here..."); | |
/* Source image is either first arg or the first dragged image */ | |
imgPath = (argc > 1) ? argv[1] : NULL; | |
src = LoadImage(renderer, NULL, imgPath); | |
if (!src) | |
{ | |
return 0; | |
} | |
/* Create the texture, show it as the source because we can */ | |
texture = SDL_CreateTexture( | |
renderer, | |
src->format->format, | |
SDL_TEXTUREACCESS_STREAMING, | |
src->w, | |
src->h | |
); | |
SDL_UpdateTexture(texture, NULL, src->pixels, src->pitch); | |
SDL_SetWindowSize(window, src->w, src->h); | |
SDL_SetWindowTitle(window, "Drag new image here..."); | |
/* Comparison image is either second arg or the second dragged image */ | |
imgPath = (argc > 2) ? argv[2] : NULL; | |
dst = LoadImage(renderer, texture, imgPath); | |
if (!dst) | |
{ | |
SDL_FreeSurface(src); | |
return 0; | |
} | |
SDL_SetWindowTitle(window, NULL); | |
while (run) | |
{ | |
while (SDL_PollEvent(&evt) > 0) | |
{ | |
if (evt.type == SDL_QUIT) | |
{ | |
run = 0; | |
} | |
if (evt.type == SDL_DROPFILE) | |
{ | |
/* Dragged files replace the comparison image */ | |
tmp = IMG_Load(evt.drop.file); | |
if (!tmp) | |
{ | |
SDL_ShowSimpleMessageBox( | |
SDL_MESSAGEBOX_ERROR, | |
"New image load failed!", | |
IMG_GetError(), | |
NULL | |
); | |
} | |
SDL_FreeSurface(dst); | |
dst = tmp; | |
} | |
} | |
/* Images aren't related? Bail. */ | |
if ( (src->w != dst->w) || | |
(src->h != dst->h) || | |
(src->format->format != dst->format->format) ) | |
{ | |
SDL_ShowSimpleMessageBox( | |
SDL_MESSAGEBOX_ERROR, | |
"Image mismatch!", | |
"Source and Destination must be the same size/format!", | |
NULL | |
); | |
break; | |
} | |
/* Compare each pixel, write unique pixels to texture */ | |
SDL_LockTexture( | |
texture, | |
NULL, | |
(void**) &diff, | |
&pitch | |
); | |
srcpx = (char*) src->pixels; | |
dstpx = (char*) dst->pixels; | |
for (hi = 0; hi < src->h; hi += 1) | |
for (wi = 0; wi < src->w; wi += 1) | |
{ | |
const int offset = ( | |
(hi * pitch) + | |
(wi * src->format->BytesPerPixel) | |
); | |
if (SDL_memcmp( | |
&srcpx[offset], | |
&dstpx[offset], | |
src->format->BytesPerPixel | |
) != 0) { | |
#if SOLID_COLOR | |
SDL_memset( | |
&diff[offset], | |
'\0', | |
src->format->BytesPerPixel | |
); | |
diff[offset] = 0xFF; | |
if (src->format->BytesPerPixel == 4) | |
{ | |
diff[offset + 3] = 0xFF; | |
} | |
#else | |
SDL_memcpy( | |
&diff[offset], | |
&dstpx[offset], | |
src->format->BytesPerPixel | |
); | |
#endif | |
} | |
else | |
{ | |
SDL_memset( | |
&diff[offset], | |
'\0', | |
src->format->BytesPerPixel | |
); | |
} | |
} | |
SDL_UnlockTexture(texture); | |
/* Draw the result! */ | |
SDL_RenderClear(renderer); | |
SDL_RenderCopy( | |
renderer, | |
texture, | |
NULL, | |
NULL | |
); | |
SDL_RenderPresent(renderer); | |
} | |
SDL_FreeSurface(src); | |
SDL_FreeSurface(dst); | |
SDL_DestroyTexture(texture); | |
SDL_DestroyRenderer(renderer); | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment