Skip to content

Commit 1131b7d

Browse files
authored
Move tiff JPEG compression outside the lock and thread it (libvips#3679)
1 parent b32cb5e commit 1131b7d

File tree

8 files changed

+543
-154
lines changed

8 files changed

+543
-154
lines changed

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
- add direct mode to dzsave [jcupitt]
2828
- require C++11 as a minimum standard [kleisauke]
2929
- add support for SIMD via Highway [kleisauke]
30+
- threaded write in tiffsave for tiled JPEG and JPEG2000 [jcupitt]
3031

3132
18/9/23 8.14.5
3233

libvips/foreign/dzsave.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,8 @@ strip_save(Level *level)
15991599

16001600
image_strip_init(&strip, level);
16011601

1602+
vips_image_set_int(strip.image, "vips-no-minimise", 1);
1603+
16021604
if (vips_threadpool_run(strip.image,
16031605
vips_thread_state_new,
16041606
image_strip_allocate,

libvips/foreign/jp2ksave.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,8 +1309,8 @@ vips_foreign_save_jp2k_unpack_image(VipsRegion *region, VipsRect *tile,
13091309
}
13101310
}
13111311

1312-
void
1313-
vips__foreign_load_jp2k_compress_free(TileCompress *compress)
1312+
static void
1313+
vips__foreign_save_jp2k_compress_free(TileCompress *compress)
13141314
{
13151315
VIPS_FREEF(opj_destroy_codec, compress->codec);
13161316
VIPS_FREEF(opj_image_destroy, compress->image);
@@ -1326,7 +1326,7 @@ vips__foreign_load_jp2k_compress_free(TileCompress *compress)
13261326
* nope, openjpeg does not allow that.
13271327
*/
13281328
int
1329-
vips__foreign_load_jp2k_compress(VipsRegion *region,
1329+
vips__foreign_save_jp2k_compress(VipsRegion *region,
13301330
VipsRect *tile, VipsTarget *target,
13311331
int tile_width, int tile_height,
13321332
gboolean save_as_ycc, gboolean subsample, gboolean lossless, int Q)
@@ -1357,7 +1357,7 @@ vips__foreign_load_jp2k_compress(VipsRegion *region,
13571357
*/
13581358
if (!(compress.image = vips_foreign_save_jp2k_new_image(region->im,
13591359
tile_width, tile_height, subsample, save_as_ycc, TRUE))) {
1360-
vips__foreign_load_jp2k_compress_free(&compress);
1360+
vips__foreign_save_jp2k_compress_free(&compress);
13611361
return -1;
13621362
}
13631363

@@ -1366,7 +1366,7 @@ vips__foreign_load_jp2k_compress(VipsRegion *region,
13661366
sizeof_line = sizeof(gint64) * tile->width;
13671367
if (!(compress.accumulate =
13681368
VIPS_ARRAY(NULL, sizeof_line, VipsPel))) {
1369-
vips__foreign_load_jp2k_compress_free(&compress);
1369+
vips__foreign_save_jp2k_compress_free(&compress);
13701370
return -1;
13711371
}
13721372

@@ -1376,7 +1376,7 @@ vips__foreign_load_jp2k_compress(VipsRegion *region,
13761376
vips_foreign_save_jp2k_attach_handlers(compress.codec);
13771377
if (!opj_setup_encoder(compress.codec,
13781378
&parameters, compress.image)) {
1379-
vips__foreign_load_jp2k_compress_free(&compress);
1379+
vips__foreign_save_jp2k_compress_free(&compress);
13801380
return -1;
13811381
}
13821382

@@ -1397,32 +1397,32 @@ vips__foreign_load_jp2k_compress(VipsRegion *region,
13971397
tile, compress.image);
13981398

13991399
if (!(compress.stream = vips_foreign_save_jp2k_target(target))) {
1400-
vips__foreign_load_jp2k_compress_free(&compress);
1400+
vips__foreign_save_jp2k_compress_free(&compress);
14011401
return -1;
14021402
}
14031403

14041404
if (!opj_start_compress(compress.codec,
14051405
compress.image, compress.stream)) {
1406-
vips__foreign_load_jp2k_compress_free(&compress);
1406+
vips__foreign_save_jp2k_compress_free(&compress);
14071407
return -1;
14081408
}
14091409

14101410
if (!opj_encode(compress.codec, compress.stream)) {
1411-
vips__foreign_load_jp2k_compress_free(&compress);
1411+
vips__foreign_save_jp2k_compress_free(&compress);
14121412
return -1;
14131413
}
14141414

14151415
opj_end_compress(compress.codec, compress.stream);
14161416

1417-
vips__foreign_load_jp2k_compress_free(&compress);
1417+
vips__foreign_save_jp2k_compress_free(&compress);
14181418

14191419
return 0;
14201420
}
14211421

14221422
#else /*!HAVE_LIBOPENJP2*/
14231423

14241424
int
1425-
vips__foreign_load_jp2k_compress(VipsRegion *region,
1425+
vips__foreign_save_jp2k_compress(VipsRegion *region,
14261426
VipsRect *tile, VipsTarget *target,
14271427
int tile_width, int tile_height,
14281428
gboolean save_as_ycc, gboolean subsample, gboolean lossless, int Q)

libvips/foreign/pforeign.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ int vips__foreign_load_jp2k_decompress(VipsImage *out,
213213
int width, int height, gboolean ycc_to_rgb,
214214
void *from, size_t from_length,
215215
void *to, size_t to_length);
216-
int vips__foreign_load_jp2k_compress(VipsRegion *region,
216+
int vips__foreign_save_jp2k_compress(VipsRegion *region,
217217
VipsRect *tile, VipsTarget *target,
218218
int tile_width, int tile_height,
219219
gboolean save_as_ycc, gboolean subsample, gboolean lossless, int Q);

libvips/foreign/tiff2vips.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,9 @@
208208
* 30/9/21
209209
* - fix tiled + packed formats
210210
* 31/7/22
211-
* - move jp2k decompress outside the lock
212-
* - move jpeg decode outside the lock
213-
* - fix demand hinting
211+
* - move jp2k decompress outside the lock
212+
* - move jpeg decode outside the lock
213+
* - fix demand hinting
214214
* 3/2/23 MathemanFlo
215215
* - add bits per sample metadata
216216
*/

libvips/foreign/vips2jpeg.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,6 @@
139139
#endif /*HAVE_CONFIG_H*/
140140
#include <glib/gi18n-lib.h>
141141

142-
#ifdef HAVE_JPEG
143-
144142
#include <stdio.h>
145143
#include <stdlib.h>
146144
#include <string.h>
@@ -152,6 +150,8 @@
152150

153151
#include "pforeign.h"
154152

153+
#ifdef HAVE_JPEG
154+
155155
#include "jpeg.h"
156156

157157
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
@@ -856,15 +856,12 @@ term_destination(j_compress_ptr cinfo)
856856
if (vips_target_write(dest->target,
857857
dest->buf, TARGET_BUFFER_SIZE - dest->pub.free_in_buffer))
858858
ERREXIT(cinfo, JERR_FILE_WRITE);
859-
860-
if (vips_target_end(dest->target))
861-
ERREXIT(cinfo, JERR_FILE_WRITE);
862859
}
863860

864861
/* Set dest to one of our objects.
865862
*/
866-
static void
867-
target_dest(j_compress_ptr cinfo, VipsTarget *target)
863+
void
864+
vips__jpeg_target_dest(j_compress_ptr cinfo, VipsTarget *target)
868865
{
869866
Dest *dest;
870867

@@ -909,7 +906,7 @@ vips__jpeg_write_target(VipsImage *in, VipsTarget *target,
909906

910907
/* Attach output.
911908
*/
912-
target_dest(&write->cinfo, target);
909+
vips__jpeg_target_dest(&write->cinfo, target);
913910

914911
/* Convert! Write errors come back here as an error return.
915912
*/
@@ -922,6 +919,9 @@ vips__jpeg_write_target(VipsImage *in, VipsTarget *target,
922919
}
923920
write_destroy(write);
924921

922+
if (vips_target_end(target))
923+
return -1;
924+
925925
return 0;
926926
}
927927

@@ -1018,7 +1018,7 @@ vips__jpeg_region_write_target(VipsRegion *region, VipsRect *rect,
10181018

10191019
/* Attach output.
10201020
*/
1021-
target_dest(&write->cinfo, target);
1021+
vips__jpeg_target_dest(&write->cinfo, target);
10221022

10231023
/* Convert! Write errors come back here as an error return.
10241024
*/
@@ -1031,7 +1031,27 @@ vips__jpeg_region_write_target(VipsRegion *region, VipsRect *rect,
10311031
}
10321032
write_destroy(write);
10331033

1034+
if (vips_target_end(target))
1035+
return -1;
1036+
10341037
return 0;
10351038
}
10361039

1040+
#else /*!HAVE_JPEG*/
1041+
1042+
int
1043+
vips__jpeg_region_write_target(VipsRegion *region, VipsRect *rect,
1044+
VipsTarget *target,
1045+
int Q, const char *profile,
1046+
gboolean optimize_coding, gboolean progressive,
1047+
gboolean strip, gboolean trellis_quant,
1048+
gboolean overshoot_deringing, gboolean optimize_scans,
1049+
int quant_table, VipsForeignSubsample subsample_mode,
1050+
int restart_interval)
1051+
{
1052+
vips_error("vips2jpeg",
1053+
"%s", _("libvips built without JPEG support"));
1054+
return -1;
1055+
}
1056+
10371057
#endif /*HAVE_JPEG*/

0 commit comments

Comments
 (0)