Skip to content

Instantly share code, notes, and snippets.

@Melraidin
Created April 21, 2015 02:10
Show Gist options
  • Save Melraidin/5a9a3e23a91f4e490b2a to your computer and use it in GitHub Desktop.
Save Melraidin/5a9a3e23a91f4e490b2a to your computer and use it in GitHub Desktop.
libvips crash when saving JPEGs
#include <stdio.h>
#include <math.h>
#include <vips/vips.h>
#include <stdlib.h>
#include <glib-object.h>
gboolean use_copy_hack = FALSE;
gboolean save_original = FALSE;
void process(VipsImage* src);
int main(int argc, char **argv) {
if (argc != 3) {
printf(
"Demonstrates crash when saving a particular JPEG with libvips:\n"
" %s <save original> <use copy>\n"
"\n"
" <save original>: + to save the original, - to skip\n"
" <use copy>: + to use vips_copy(), - to use vips_extract_area()\n"
"\n"
"These cases crash:\n"
" %s - +\n"
" %s + +\n"
" %s + -\n", argv[0], argv[0], argv[0], argv[0]);
return 1;
}
if (argv[1][0] == '+') {
printf("Will save original.\n");
save_original = TRUE;
} else {
printf("Skipping saving original.\n");
}
if (argv[2][0] == '-') {
printf("Using vips_extract_area() in place of vips_copy().\n");
use_copy_hack = TRUE;
} else {
printf("Using vips_copy().\n");
}
FILE *f = fopen("source.jpg", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
char *buffer = malloc(fsize + 1);
fread(buffer, fsize, 1, f);
fclose(f);
VipsImage *img;
if (!(img = vips_image_new_from_buffer(buffer, fsize, NULL, NULL))) {
printf("Failed to load file: %s\n", vips_error_buffer());
vips_error_clear();
}
if (save_original) {
printf("Saving source image.\n");
vips_jpegsave(img, "tmp.jpg", NULL);
}
for (int i = 0; i < 8; i++) {
printf("Starting conversion %d\n", i);
process(img);
}
vips_thread_shutdown();
return 0;
}
void process(VipsImage* src) {
VipsImage *dupe = NULL;
if (use_copy_hack) {
if (vips_extract_area(src, &dupe, 0, 0, src->Xsize, src->Ysize, NULL) != 0) {
printf("Failed to use hack to copy image: %s\n", vips_error_buffer());
return;
}
} else {
if (vips_copy(src, &dupe, NULL) != 0) {
printf("Failed to copy image: %s\n", vips_error_buffer());
return;
}
}
size_t length = 0;
void *buffer = NULL;
int result = vips_jpegsave_buffer(dupe, &buffer, &length, NULL);
if (result != 0) {
printf("Failed to write JPEG: %s\n", vips_error_buffer());
return;
}
g_free(buffer);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment