fix some small bugs

- disable chroma subsample for jp2k-in-tiff ... it didn't work due to opj bugs
- revise numresolutions setting
- require opj 2.4 or later
This commit is contained in:
John Cupitt 2021-04-30 10:42:32 +01:00
parent edcdf8af70
commit 7603c4b6ab
4 changed files with 54 additions and 45 deletions

View File

@ -836,10 +836,11 @@ AC_ARG_WITH([libopenjp2],
AS_HELP_STRING([--without-libopenjp2],
[build without libopenjp2 (default: test)]))
# 2.4 is the first one to have working threading and tiling
if test x"$with_libopenjp2" != x"no"; then
PKG_CHECK_MODULES(LIBOPENJP2, libopenjp2 >= 2.3,
PKG_CHECK_MODULES(LIBOPENJP2, libopenjp2 >= 2.4,
[AC_DEFINE(HAVE_LIBOPENJP2,1,
[define if you have libopenjp2 >=2.2 installed.])
[define if you have libopenjp2 >=2.4 installed.])
with_libopenjp2=yes
PACKAGES_USED="$PACKAGES_USED libopenjp2"
],
@ -847,14 +848,6 @@ if test x"$with_libopenjp2" != x"no"; then
with_libopenjp2=no
]
)
# 2.3 and earlier have threading problems
PKG_CHECK_MODULES(LIBOPENJP2_THREADING, libopenjp2 >= 2.4,
[AC_DEFINE(HAVE_LIBOPENJP2_THREADING,1,[define if your libopenjp2 threading works.])
],
[:
]
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $LIBOPENJP2_CFLAGS"
@ -1555,7 +1548,7 @@ EXIF metadata support with libexif: $with_libexif
JPEG load/save with libjpeg: $with_jpeg
JXL load/save with libjxl: $with_libjxl
JPEG2000 load/save with libopenjp2: $with_libopenjp2
(requires libopenjp2 2.2 or later)
(requires libopenjp2 2.4 or later)
PNG load with libspng: $with_libspng
(requires libspng-0.6 or later)
PNG load/save with libpng: $with_png
@ -1574,8 +1567,6 @@ PDF load with poppler-glib: $with_poppler (dynamic module: $with_pop
SVG load with librsvg-2.0: $with_rsvg
(requires librsvg-2.0 2.34.0 or later)
EXR load with OpenEXR: $with_OpenEXR
JPEG2000 load/save with libopenjp2: $with_libopenjp2
(requires libopenjp2 2.2 or later)
slide load with OpenSlide: $with_openslide (dynamic module: $with_openslide_module)
(requires openslide-3.3.0 or later)
Matlab load with matio: $with_matio

View File

@ -496,12 +496,7 @@ vips_foreign_load_jp2k_header( VipsForeignLoad *load )
if( !opj_setup_decoder( jp2k->codec, &jp2k->parameters ) )
return( -1 );
#ifdef HAVE_LIBOPENJP2_THREADING
/* Use eg. VIPS_CONCURRENCY etc. to set n-cpus, if this openjpeg has
* stable support.
*/
opj_codec_set_threads( jp2k->codec, vips_concurrency_get() );
#endif /*HAVE_LIBOPENJP2_THREADING*/
if( !opj_read_header( jp2k->stream, jp2k->codec, &jp2k->image ) )
return( -1 );
@ -608,6 +603,12 @@ vips_foreign_load_jp2k_pack( gboolean upsample,
int x, i;
#ifdef DEBUG_VERBOSE
printf( "vips_foreign_load_jp2k_pack: "
"upsample = %d, left = %d, top = %d, length = %d\n",
upsample, left, top, length );
#endif /*DEBUG_VERBOSE*/
for( i = 0; i < b; i++ ) {
opj_image_comp_t *comp = &image->comps[i];
@ -1152,7 +1153,7 @@ typedef struct _TileDecompress {
opj_image_t *image;
} TileDecompress;
void
static void
vips__foreign_load_jp2k_decompress_free( TileDecompress *decompress )
{
VIPS_FREEF( opj_destroy_codec, decompress->codec );
@ -1182,6 +1183,12 @@ vips__foreign_load_jp2k_decompress( VipsImage *out,
VipsPel *q;
int y;
#ifdef DEBUG
printf( "vips__foreign_load_jp2k_decompress: width = %d, height = %d, "
"ycc_to_rgb = %d, from_length = %zd, to_length = %zd\n",
width, height, ycc_to_rgb, from_length, to_length );
#endif /*DEBUG*/
/* Our ycc->rgb only works for exactly 3 bands.
*/
ycc_to_rgb = ycc_to_rgb && out->Bands == 3;

View File

@ -737,11 +737,13 @@ vips_foreign_save_jp2k_set_profile( opj_cparameters_t *parameters,
* -I -p RPCL -n 7 \
* -c[256,256],[256,256],[256,256],[256,256],[256,256],[256,256],[256,256] \
* -b 64,64
*
* except we don't set numresolution -- our caller does that,
* depending on the image size and compression requirements.
*/
parameters->irreversible = TRUE;
parameters->prog_order = OPJ_RPCL;
parameters->numresolution = 7;
parameters->cblockw_init = 64;
parameters->cblockh_init = 64;
parameters->cp_disto_alloc = 1;
@ -817,12 +819,21 @@ vips_foreign_save_jp2k_build( VipsObject *object )
*/
opj_set_default_encoder_parameters( &jp2k->parameters );
/* Set compression profile.
*/
vips_foreign_save_jp2k_set_profile( &jp2k->parameters,
jp2k->lossless, jp2k->Q );
/* Always tile.
*/
jp2k->parameters.tile_size_on = OPJ_TRUE;
jp2k->parameters.cp_tdx = jp2k->tile_width;
jp2k->parameters.cp_tdy = jp2k->tile_height;
/* Makes three band images smaller, somehow.
*/
jp2k->parameters.tcp_mct = save->ready->Bands >= 3 ? 1 : 0;
/* Number of layers to write. Smallest layer is c. 2^5 on the smallest
* axis.
*/
@ -834,15 +845,6 @@ vips_foreign_save_jp2k_build( VipsObject *object )
jp2k->parameters.numresolution );
#endif /*DEBUG*/
/* Makes three band images smaller, somehow.
*/
jp2k->parameters.tcp_mct = save->ready->Bands >= 3 ? 1 : 0;
/* Set compression profile.
*/
vips_foreign_save_jp2k_set_profile( &jp2k->parameters,
jp2k->lossless, jp2k->Q );
/* Set up compressor.
*/
@ -858,12 +860,7 @@ vips_foreign_save_jp2k_build( VipsObject *object )
if( !opj_setup_encoder( jp2k->codec, &jp2k->parameters, jp2k->image ) )
return( -1 );
#ifdef HAVE_LIBOPENJP2_THREADING
/* Use eg. VIPS_CONCURRENCY etc. to set n-cpus, if this openjpeg has
* stable support.
*/
opj_codec_set_threads( jp2k->codec, vips_concurrency_get() );
#endif /*HAVE_LIBOPENJP2_THREADING*/
if( !(jp2k->stream = vips_foreign_save_jp2k_target( jp2k->target )) )
return( -1 );
@ -1315,16 +1312,19 @@ vips__foreign_load_jp2k_compress( VipsRegion *region,
/* Set compression params.
*/
opj_set_default_encoder_parameters( &parameters );
parameters.numresolution = 1;
/* Makes three band images smaller, somehow.
*/
parameters.tcp_mct = (region->im->Bands >= 3 && !subsample) ? 1 : 0;
/* Set compression profile.
*/
vips_foreign_save_jp2k_set_profile( &parameters, lossless, Q );
/* Makes three band images smaller, somehow.
*/
parameters.tcp_mct = region->im->Bands >= 3 ? 1 : 0;
/* Only one pyramid level.
*/
parameters.numresolution = 1;
/* Create output image. TRUE means we alloc memory for the image
* planes.
*/
@ -1351,12 +1351,7 @@ vips__foreign_load_jp2k_compress( VipsRegion *region,
return( -1 );
}
#ifdef HAVE_LIBOPENJP2_THREADING
/* Use eg. VIPS_CONCURRENCY etc. to set n-cpus, if this openjpeg has
* stable support.
*/
opj_codec_set_threads( compress.codec, vips_concurrency_get() );
#endif /*HAVE_LIBOPENJP2_THREADING*/
if( save_as_ycc )
vips_foreign_save_jp2k_rgb_to_ycc( region,

View File

@ -1558,11 +1558,27 @@ wtiff_layer_write_tiles( Wtiff *wtiff, Layer *layer, VipsRegion *strip )
switch( wtiff->compression ) {
case JP2K_LOSSY:
/* Sadly chroma subsample seems not to work
* for edge tiles in tiff with jp2k
* compression, so we always pass FALSE
* instead of:
*
* !wtiff->rgbjpeg && wtiff->Q < 90,
*
* I've verified that the libvips jp2k
* encode and decode subsample operations fill
* the comps[i].data arrays correctly, so it
* seems to be a openjpeg bug.
*
* FIXME ... try again with openjpeg 2.5,
* when that comes.
*/
result = vips__foreign_load_jp2k_compress(
strip, &tile, target,
wtiff->tilew, wtiff->tileh,
!wtiff->rgbjpeg,
!wtiff->rgbjpeg && wtiff->Q < 90,
// !wtiff->rgbjpeg && wtiff->Q < 90,
FALSE,
wtiff->lossless,
wtiff->Q );
break;