Skip to content

Commit

Permalink
add error handling for vips2tiff jpeg tile write
Browse files Browse the repository at this point in the history
  • Loading branch information
jcupitt committed Sep 24, 2023
1 parent e47408d commit 9da89f8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 14 deletions.
2 changes: 2 additions & 0 deletions libvips/foreign/dzsave.c
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,8 @@ strip_save(Level *level)

image_strip_init(&strip, level);

vips_image_set_int(strip.image, "vips-no-minimise", 1);

if (vips_threadpool_run(strip.image,
vips_thread_state_new,
image_strip_allocate,
Expand Down
21 changes: 19 additions & 2 deletions libvips/foreign/vips2jpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@
#endif /*HAVE_CONFIG_H*/
#include <glib/gi18n-lib.h>

#ifdef HAVE_JPEG

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -152,6 +150,8 @@

#include "pforeign.h"

#ifdef HAVE_JPEG

#include "jpeg.h"

#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
Expand Down Expand Up @@ -1037,4 +1037,21 @@ vips__jpeg_region_write_target(VipsRegion *region, VipsRect *rect,
return 0;
}

#else /*!HAVE_JPEG*/

int
vips__jpeg_region_write_target(VipsRegion *region, VipsRect *rect,
VipsTarget *target,
int Q, const char *profile,
gboolean optimize_coding, gboolean progressive,
gboolean strip, gboolean trellis_quant,
gboolean overshoot_deringing, gboolean optimize_scans,
int quant_table, VipsForeignSubsample subsample_mode,
int restart_interval)
{
vips_error("jp2k",
"%s", _("libvips built without JPEG support"));
return -1;
}

#endif /*HAVE_JPEG*/
38 changes: 26 additions & 12 deletions libvips/foreign/vips2tiff.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,11 @@ static int
wtiff_compress_jpeg(Wtiff *wtiff,
VipsRegion *strip, VipsRect *tile, VipsTarget *target)
{
size_t sizeof_pel = VIPS_REGION_SIZEOF_PEL(strip);

struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
ErrorManager eman;
VipsPel *line;

#ifdef DEBUG
printf("wtiff_compress_jpeg: left = %d, top = %d, "
Expand All @@ -708,13 +711,31 @@ wtiff_compress_jpeg(Wtiff *wtiff,
#endif /*DEBUG*/

// we could have one of these per thread and reuse it for a small speedup
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
cinfo.err = jpeg_std_error(&eman.pub);
cinfo.dest = NULL;
eman.pub.error_exit = vips__new_error_exit;
eman.pub.output_message = vips__new_output_message;
eman.fp = NULL;

/// we need a line buffer to pad edge tiles
line = VIPS_MALLOC(NULL, wtiff->tilew * sizeof_pel);

/* Error handling. The error message will have ben set by our handlers.
*/
if (setjmp(eman.jmp)) {
jpeg_destroy_compress(&cinfo);
VIPS_FREE(line);
return -1;
}

/* Attach output.
*/
vips__jpeg_target_dest(&cinfo, target);

/* Make jpeg compression object.
*/
jpeg_create_compress(&cinfo);

wtiff_compress_jpeg_header(wtiff, &cinfo, strip->im);

// don't output tables, just coefficients
Expand All @@ -725,12 +746,7 @@ wtiff_compress_jpeg(Wtiff *wtiff,

if (tile->width < wtiff->tilew ||
tile->height < wtiff->tileh) {
size_t sizeof_pel = VIPS_REGION_SIZEOF_PEL(strip);
VipsPel *line = VIPS_MALLOC(NULL, wtiff->tilew * sizeof_pel);

JSAMPROW row_pointer[1];

row_pointer[0] = line;
JSAMPROW row_pointer[1] = { line };

for (int y = 0; y < tile->height; y++) {
memcpy(line, VIPS_REGION_ADDR(strip, tile->left, tile->top + y),
Expand All @@ -742,8 +758,6 @@ wtiff_compress_jpeg(Wtiff *wtiff,
for (int y = tile->height; y < wtiff->tileh; y++) {
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}

g_free(row_pointer[0]);
}
else {
for (int y = 0; y < tile->height; y++) {
Expand All @@ -752,8 +766,8 @@ wtiff_compress_jpeg(Wtiff *wtiff,
row_pointer[0] = VIPS_REGION_ADDR(strip, tile->left, tile->top + y);
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}

}

jpeg_finish_compress(&cinfo);

jpeg_destroy_compress(&cinfo);
Expand Down

0 comments on commit 9da89f8

Please sign in to comment.