more jp2k tests

This commit is contained in:
John Cupitt 2021-03-23 17:15:02 +00:00
parent d69512c8b0
commit 40c020ccd2
3 changed files with 86 additions and 51 deletions

View File

@ -367,24 +367,14 @@ vips_foreign_load_jp2k_set_header( VipsForeignLoadJp2k *jp2k, VipsImage *out )
VipsBandFormat format;
VipsInterpretation interpretation;
switch( first->prec ) {
case 8:
/* OpenJPEG only supports up to 31 bpp. Treat it as 32.
*/
if( first->prec <= 8 )
format = first->sgnd ? VIPS_FORMAT_CHAR : VIPS_FORMAT_UCHAR;
break;
case 16:
else if( first->prec <= 16 )
format = first->sgnd ? VIPS_FORMAT_SHORT : VIPS_FORMAT_USHORT;
break;
case 32:
else
format = first->sgnd ? VIPS_FORMAT_INT : VIPS_FORMAT_UINT;
break;
default:
vips_error( class->nickname,
_( "unsupported precision %d" ), first->prec );
return( -1 );
}
switch( jp2k->image->color_space ) {
case OPJ_CLRSPC_SYCC:

View File

@ -38,13 +38,9 @@
/* TODO
*
* - we will have 0.5 pixels if the image width or hight is odd and chroma
* - we will have 0.5 pixels if the image width or height is odd and chroma
* subsampling is on ... this will cause at least read out of bounds.
*
* - add 16 and 32-bit images to tests
*
* - add chroma modes to tests
*
* - could support tiff-like depth parameter
*
* - could support png-like bitdepth parameter
@ -451,6 +447,9 @@ vips_foreign_save_jp2k_unpack( VipsForeignSaveJp2k *jp2k, VipsRect *tile )
static size_t
vips_foreign_save_jp2k_sizeof_tile( VipsForeignSaveJp2k *jp2k, VipsRect *tile )
{
VipsForeignSave *save = (VipsForeignSave *) jp2k;
size_t sizeof_element = VIPS_IMAGE_SIZEOF_ELEMENT( save->ready );
size_t size;
int i;
@ -466,7 +465,7 @@ vips_foreign_save_jp2k_sizeof_tile( VipsForeignSaveJp2k *jp2k, VipsRect *tile )
int output_height = VIPS_ROUND_UINT(
(double) tile->height / comp->dy );;
size += output_width * output_height * (comp->bpp / 8);
size += output_width * output_height * sizeof_element;
}
return( size );
@ -579,6 +578,7 @@ vips_foreign_save_jp2k_build( VipsObject *object )
OPJ_COLOR_SPACE color_space;
int expected_bands;
int bits_per_pixel;
int i;
size_t sizeof_tile;
size_t sizeof_line;
@ -632,6 +632,56 @@ vips_foreign_save_jp2k_build( VipsObject *object )
jp2k->parameters.tcp_mct = FALSE;
}
/* CIELAB etc. do not seem to be well documented.
*/
switch( save->ready->Type ) {
case VIPS_INTERPRETATION_B_W:
case VIPS_INTERPRETATION_GREY16:
color_space = OPJ_CLRSPC_GRAY;
expected_bands = 1;
break;
case VIPS_INTERPRETATION_sRGB:
case VIPS_INTERPRETATION_RGB16:
color_space = jp2k->save_as_ycc ?
OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
expected_bands = 3;
break;
case VIPS_INTERPRETATION_CMYK:
color_space = OPJ_CLRSPC_CMYK;
expected_bands = 4;
break;
default:
color_space = OPJ_CLRSPC_UNSPECIFIED;
expected_bands = save->ready->Bands;
break;
}
switch( save->ready->BandFmt ) {
case VIPS_FORMAT_CHAR:
case VIPS_FORMAT_UCHAR:
bits_per_pixel = 8;
break;
case VIPS_FORMAT_SHORT:
case VIPS_FORMAT_USHORT:
bits_per_pixel = 16;
break;
case VIPS_FORMAT_INT:
case VIPS_FORMAT_UINT:
/* OpenJPEG only supports up to 31.
*/
bits_per_pixel = 31;
break;
default:
g_assert_not_reached();
break;
}
/* Set parameters for compressor.
*/
@ -659,8 +709,8 @@ vips_foreign_save_jp2k_build( VipsObject *object )
jp2k->comps[i].h = save->ready->Ysize;
jp2k->comps[i].x0 = 0;
jp2k->comps[i].y0 = 0;
jp2k->comps[i].prec = jp2k->comps[i].bpp =
8 * vips_format_sizeof( save->ready->BandFmt );
jp2k->comps[i].prec = bits_per_pixel;
jp2k->comps[i].bpp = bits_per_pixel;
jp2k->comps[i].sgnd =
!vips_band_format_isuint( save->ready->BandFmt );
}
@ -685,33 +735,6 @@ vips_foreign_save_jp2k_build( VipsObject *object )
/* Create output image.
*/
/* CIELAB etc. do not seem to be well documented.
*/
switch( save->ready->Type ) {
case VIPS_INTERPRETATION_B_W:
case VIPS_INTERPRETATION_GREY16:
color_space = OPJ_CLRSPC_GRAY;
expected_bands = 1;
break;
case VIPS_INTERPRETATION_sRGB:
case VIPS_INTERPRETATION_RGB16:
color_space = jp2k->save_as_ycc ?
OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB;
expected_bands = 3;
break;
case VIPS_INTERPRETATION_CMYK:
color_space = OPJ_CLRSPC_CMYK;
expected_bands = 4;
break;
default:
color_space = OPJ_CLRSPC_UNSPECIFIED;
expected_bands = save->ready->Bands;
break;
}
jp2k->image = opj_image_create( save->ready->Bands,
jp2k->comps, color_space );
jp2k->image->x1 = save->ready->Xsize;

View File

@ -1155,13 +1155,35 @@ class TestForeign:
buf = self.colour.jp2ksave_buffer(lossless=True)
im2 = pyvips.Image.new_from_buffer(buf, "")
assert self.colour.avg() == im2.avg()
assert (self.colour == im2).min() == 255
# higher Q should mean a bigger buffer
b1 = self.mono.jp2ksave_buffer(Q=10)
b2 = self.mono.jp2ksave_buffer(Q=90)
assert len(b2) > len(b1)
# disabling chroma subsample should mean a bigger buffer
b1 = self.colour.jp2ksave_buffer(subsample_mode="on")
b2 = self.colour.jp2ksave_buffer(subsample_mode="off")
assert len(b2) > len(b1)
# enabling lossless should mean a bigger buffer
b1 = self.colour.jp2ksave_buffer(lossless=False)
b2 = self.colour.jp2ksave_buffer(lossless=True)
assert len(b2) > len(b1)
# 16-bit colour load and save
im = self.colour.colourspace("rgb16")
buf = im.jp2ksave_buffer(lossless=True)
im2 = pyvips.Image.new_from_buffer(buf, "")
assert (im == im2).min() == 255
# openjpeg 32-bit load and save doesn't seem to work, comment out
# im = self.colour.colourspace("rgb16").cast("uint") << 14
# buf = im.jp2ksave_buffer(lossless=True)
# im2 = pyvips.Image.new_from_buffer(buf, "")
# assert (im == im2).min() == 255
if __name__ == '__main__':
pytest.main()