Skip to content

Instantly share code, notes, and snippets.

@flibitijibibo
Last active July 29, 2020 01:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flibitijibibo/a6af323524347781a18a72f2b5b4de02 to your computer and use it in GitHub Desktop.
Save flibitijibibo/a6af323524347781a18a72f2b5b4de02 to your computer and use it in GitHub Desktop.
Basic image comparison tool. http://www.flibitijibibo.com/adobesucks.zip
/* 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