1 /* load jpeg2000
2  *
3  * 18/3/20
4  * 	- from heifload.c
5  * 4/11/21
6  * 	- add untiled load
7  */
8 
9 /*
10 
11     This file is part of VIPS.
12 
13     VIPS is free software; you can redistribute it and/or modify
14     it under the terms of the GNU Lesser General Public License as published by
15     the Free Software Foundation; either version 2 of the License, or
16     (at your option) any later version.
17 
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU Lesser General Public License for more details.
22 
23     You should have received a copy of the GNU Lesser General Public License
24     along with this program; if not, write to the Free Software
25     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26     02110-1301  USA
27 
28  */
29 
30 /*
31 
32     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
33 
34  */
35 
36 /*
37 #define DEBUG_VERBOSE
38 #define DEBUG
39  */
40 
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif /*HAVE_CONFIG_H*/
44 #include <vips/intl.h>
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 
50 #include <vips/vips.h>
51 #include <vips/debug.h>
52 #include <vips/internal.h>
53 
54 #ifdef HAVE_LIBOPENJP2
55 
56 #include <openjpeg.h>
57 
58 #include "pforeign.h"
59 
60 /* Surely enough ... does anyone do multispectral imaging with jp2k?
61  */
62 #define MAX_BANDS (100)
63 
64 typedef struct _VipsForeignLoadJp2k {
65 	VipsForeignLoad parent_object;
66 
67 	/* Source to load from (set by subclasses).
68 	 */
69 	VipsSource *source;
70 
71 	/* Page set by user, then we translate that into shrink factor.
72 	 */
73 	int page;
74 	int shrink;
75 
76 	/* Decompress state.
77 	 */
78         opj_stream_t *stream;		/* Source as an opj stream */
79 	OPJ_CODEC_FORMAT format;	/* libopenjp2 format */
80         opj_codec_t *codec;		/* Decompress codec */
81 	opj_dparameters_t parameters;	/* Core decompress params */
82 	opj_image_t *image;		/* Read image to here */
83 	opj_codestream_info_v2_t *info;	/* Tile geometry */
84 
85 	/* Number of errors reported during load -- use this to block load of
86 	 * corrupted images.
87 	 */
88 	int n_errors;
89 
90 	/* If we need to upsample tiles read from opj.
91 	 */
92 	gboolean upsample;
93 
94 	/* If we need to do ycc->rgb conversion on load.
95 	 */
96 	gboolean ycc_to_rgb;
97 } VipsForeignLoadJp2k;
98 
99 typedef VipsForeignLoadClass VipsForeignLoadJp2kClass;
100 
101 G_DEFINE_ABSTRACT_TYPE( VipsForeignLoadJp2k, vips_foreign_load_jp2k,
102 	VIPS_TYPE_FOREIGN_LOAD );
103 
104 static void
vips_foreign_load_jp2k_dispose(GObject * gobject)105 vips_foreign_load_jp2k_dispose( GObject *gobject )
106 {
107 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) gobject;
108 
109 #ifdef DEBUG
110 	printf( "vips_foreign_load_jp2k_dispose:\n" );
111 #endif /*DEBUG*/
112 
113 	/*
114 	 * FIXME ... do we need this? seems to just cause warnings
115 	 *
116 	if( jp2k->codec &&
117 		jp2k->stream )
118 		opj_end_decompress( jp2k->codec, jp2k->stream );
119 	 *
120 	 */
121 
122 	if( jp2k->info )
123 		opj_destroy_cstr_info( &jp2k->info );
124 	VIPS_FREEF( opj_destroy_codec, jp2k->codec );
125 	VIPS_FREEF( opj_stream_destroy, jp2k->stream );
126 	VIPS_FREEF( opj_image_destroy, jp2k->image );
127 	VIPS_UNREF( jp2k->source );
128 
129 	G_OBJECT_CLASS( vips_foreign_load_jp2k_parent_class )->
130 		dispose( gobject );
131 }
132 
133 static OPJ_SIZE_T
vips_foreign_load_jp2k_read_source(void * buffer,size_t length,void * client)134 vips_foreign_load_jp2k_read_source( void *buffer, size_t length, void *client )
135 {
136 	VipsSource *source = VIPS_SOURCE( client );
137 	gint64 bytes_read = vips_source_read( source, buffer, length );
138 
139 	/* openjpeg read uses -1 for both EOF and error return.
140 	 */
141 	return( bytes_read == 0 ? -1 : bytes_read );
142 }
143 
144 static OPJ_OFF_T
vips_foreign_load_jp2k_skip_source(OPJ_OFF_T n_bytes,void * client)145 vips_foreign_load_jp2k_skip_source( OPJ_OFF_T n_bytes, void *client )
146 {
147 	VipsSource *source = VIPS_SOURCE( client );
148 
149 	if( vips_source_seek( source, n_bytes, SEEK_CUR ) == -1 )
150 		/* openjpeg skip uses -1 for both end of stream and error.
151 		 */
152 		return( -1 );
153 
154 	return( n_bytes );
155 }
156 
157 static OPJ_BOOL
vips_foreign_load_jp2k_seek_source(OPJ_OFF_T position,void * client)158 vips_foreign_load_jp2k_seek_source( OPJ_OFF_T position, void *client )
159 {
160 	VipsSource *source = VIPS_SOURCE( client );
161 
162 	if( vips_source_seek( source, position, SEEK_SET ) == -1 )
163 		/* openjpeg seek uses FALSE for both end of stream and error.
164 		 */
165 		return( OPJ_FALSE );
166 
167 	return( OPJ_TRUE );
168 }
169 
170 /* Make a libopenjp2 stream that wraps a VipsSource.
171  */
172 static opj_stream_t *
vips_foreign_load_jp2k_stream(VipsSource * source)173 vips_foreign_load_jp2k_stream( VipsSource *source )
174 {
175 	opj_stream_t *stream;
176 
177 	/* TRUE means a read stream.
178 	 */
179 	if( !(stream = opj_stream_create( OPJ_J2K_STREAM_CHUNK_SIZE, TRUE )) )
180 		return( NULL );
181 
182 	opj_stream_set_user_data( stream, source, NULL );
183 	/* Unfortunately, jp2k requires the length, so pipe sources will have
184 	 * to buffer in memory.
185 	 */
186 	opj_stream_set_user_data_length( stream,
187 		vips_source_length( source ) );
188 	opj_stream_set_read_function( stream,
189 		vips_foreign_load_jp2k_read_source );
190 	opj_stream_set_skip_function( stream,
191 		vips_foreign_load_jp2k_skip_source );
192 	opj_stream_set_seek_function( stream,
193 		vips_foreign_load_jp2k_seek_source );
194 
195 	return( stream );
196 }
197 
198 static int
vips_foreign_load_jp2k_build(VipsObject * object)199 vips_foreign_load_jp2k_build( VipsObject *object )
200 {
201 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
202 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) object;
203 
204 #ifdef DEBUG
205 	printf( "vips_foreign_load_jp2k_build:\n" );
206 #endif /*DEBUG*/
207 
208 	/* Default parameters.
209 	 */
210         jp2k->parameters.decod_format = -1;
211         jp2k->parameters.cod_format = -1;
212         opj_set_default_decoder_parameters( &jp2k->parameters );
213 
214 	/* Link the openjpeg stream to our VipsSource.
215 	 */
216 	if( jp2k->source ) {
217 		jp2k->stream = vips_foreign_load_jp2k_stream( jp2k->source );
218 		if( !jp2k->stream ) {
219 			vips_error( class->nickname,
220 				"%s", _( "unable to create jp2k stream" ) );
221 			return( -1 );
222 		}
223 	}
224 
225 	if( VIPS_OBJECT_CLASS( vips_foreign_load_jp2k_parent_class )->
226 		build( object ) )
227 		return( -1 );
228 
229 	return( 0 );
230 }
231 
232 #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
233 #define JP2_MAGIC "\x0d\x0a\x87\x0a"
234 /* position 45: "\xff\x52" */
235 #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
236 
237 /* Return the image format. OpenJPEG supports several different image types.
238  */
239 static OPJ_CODEC_FORMAT
vips_foreign_load_jp2k_get_format(VipsSource * source)240 vips_foreign_load_jp2k_get_format( VipsSource *source )
241 {
242 	unsigned char *data;
243 
244 	if( vips_source_sniff_at_most( source, &data, 12 ) < 12 )
245 		return( -1 );
246 
247 	/* There's also OPJ_CODEC_JPT for xxx.jpt files, but we don't support
248 	 * that.
249 	 */
250 	if( memcmp( data, JP2_RFC3745_MAGIC, 12) == 0 ||
251 		memcmp( data, JP2_MAGIC, 4 ) == 0 )
252 		return( OPJ_CODEC_JP2 );
253 	else if( memcmp( data, J2K_CODESTREAM_MAGIC, 4 ) == 0 )
254 		return( OPJ_CODEC_J2K );
255 	else
256 		return( -1 );
257 }
258 
259 static gboolean
vips_foreign_load_jp2k_is_a_source(VipsSource * source)260 vips_foreign_load_jp2k_is_a_source( VipsSource *source )
261 {
262 	return( vips_foreign_load_jp2k_get_format( source ) != -1 );
263 }
264 
265 static VipsForeignFlags
vips_foreign_load_jp2k_get_flags(VipsForeignLoad * load)266 vips_foreign_load_jp2k_get_flags( VipsForeignLoad *load )
267 {
268 	return( VIPS_FOREIGN_PARTIAL );
269 }
270 
271 static void
vips_foreign_load_jp2k_error_callback(const char * msg,void * client)272 vips_foreign_load_jp2k_error_callback( const char *msg, void *client )
273 {
274 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) client;
275 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( jp2k );
276 
277 	vips_error( class->nickname, "%s", msg );
278 	jp2k->n_errors += 1;
279 }
280 
281 /* The openjpeg info and warning callbacks are incredibly chatty.
282  */
283 static void
vips_foreign_load_jp2k_warning_callback(const char * msg,void * client)284 vips_foreign_load_jp2k_warning_callback( const char *msg, void *client )
285 {
286 #ifdef DEBUG
287 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( client );
288 
289 	g_warning( "%s: %s",  class->nickname, msg );
290 #endif /*DEBUG*/
291 }
292 
293 /* The openjpeg info and warning callbacks are incredibly chatty.
294  */
295 static void
vips_foreign_load_jp2k_info_callback(const char * msg,void * client)296 vips_foreign_load_jp2k_info_callback( const char *msg, void *client )
297 {
298 #ifdef DEBUG
299 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( client );
300 
301 	g_info( "%s: %s",  class->nickname, msg );
302 #endif /*DEBUG*/
303 }
304 
305 static void
vips_foreign_load_jp2k_attach_handlers(VipsForeignLoadJp2k * jp2k,opj_codec_t * codec)306 vips_foreign_load_jp2k_attach_handlers( VipsForeignLoadJp2k *jp2k,
307 	opj_codec_t *codec )
308 {
309 	opj_set_info_handler( codec,
310 		vips_foreign_load_jp2k_info_callback, jp2k );
311 	opj_set_warning_handler( codec,
312 		vips_foreign_load_jp2k_warning_callback, jp2k );
313 	opj_set_error_handler( codec,
314 		vips_foreign_load_jp2k_error_callback, jp2k );
315 }
316 
317 #ifdef DEBUG
318 static void
vips_foreign_load_jp2k_print_image(opj_image_t * image)319 vips_foreign_load_jp2k_print_image( opj_image_t *image )
320 {
321 	printf( "image:\n" );
322 	printf( "x0 = %u, y0 = %u, x1 = %u, y1 = %u, numcomps = %u, "
323 		"color_space = %u\n",
324 		image->x0, image->y0, image->x1, image->y1,
325 		image->numcomps, image->color_space );
326 	printf( "icc_profile_buf = %p, icc_profile_len = %x\n",
327 		image->icc_profile_buf, image->icc_profile_len );
328 }
329 
330 static void
vips_foreign_load_jp2k_print(VipsForeignLoadJp2k * jp2k)331 vips_foreign_load_jp2k_print( VipsForeignLoadJp2k *jp2k )
332 {
333 	int i;
334 
335 	vips_foreign_load_jp2k_print_image( jp2k->image );
336 
337 	printf( "components:\n" );
338 	for( i = 0; i < jp2k->image->numcomps; i++ ) {
339 		opj_image_comp_t *this = &jp2k->image->comps[i];
340 
341 		printf( "%i) dx = %u, dy = %u, w = %u, h = %u, "
342 			"x0 = %u, y0 = %u\n",
343 			i, this->dx, this->dy, this->w, this->h,
344 			this->x0, this->y0 );
345 		printf( "    prec = %x, bpp = %x, sgnd = %x, "
346 			"resno_decoded = %u, factor = %u\n",
347 			this->prec, this->bpp, this->sgnd,
348 			this->resno_decoded, this->factor );
349 		printf( "    data = %p, alpha = %u\n",
350 			this->data, this->alpha );
351 	}
352 
353 	printf( "info:\n" );
354 	printf( "tx0 = %u, ty0 = %d, tdx = %u, tdy = %u, tw = %u, th = %u\n",
355 		jp2k->info->tx0, jp2k->info->ty0,
356 		jp2k->info->tdx, jp2k->info->tdy,
357 		jp2k->info->tw, jp2k->info->th );
358 	printf( "nbcomps = %u, tile_info = %p\n",
359 		jp2k->info->nbcomps, jp2k->info->tile_info );
360 	if( jp2k->info->tw == 1 &&
361 		jp2k->info->th == 1 )
362 		printf( "untiled\n" );
363 }
364 #endif /*DEBUG*/
365 
366 static int
vips_foreign_load_jp2k_set_header(VipsForeignLoadJp2k * jp2k,VipsImage * out)367 vips_foreign_load_jp2k_set_header( VipsForeignLoadJp2k *jp2k, VipsImage *out )
368 {
369 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( jp2k );
370 	opj_image_comp_t *first = &jp2k->image->comps[0];
371 
372 	VipsBandFormat format;
373 	VipsInterpretation interpretation;
374 
375 	/* OpenJPEG only supports up to 31 bpp. Treat it as 32.
376 	 */
377 	if( first->prec <= 8 )
378 		format = first->sgnd ? VIPS_FORMAT_CHAR : VIPS_FORMAT_UCHAR;
379 	else if( first->prec <= 16 )
380 		format = first->sgnd ? VIPS_FORMAT_SHORT : VIPS_FORMAT_USHORT;
381 	else
382 		format = first->sgnd ? VIPS_FORMAT_INT : VIPS_FORMAT_UINT;
383 
384 	switch( jp2k->image->color_space ) {
385 	case OPJ_CLRSPC_SYCC:
386 	case OPJ_CLRSPC_EYCC:
387 		/* Map these to RGB.
388 		 */
389 		interpretation = vips_format_sizeof( format ) == 1 ?
390 			VIPS_INTERPRETATION_sRGB :
391 			VIPS_INTERPRETATION_RGB16;
392 		jp2k->ycc_to_rgb = TRUE;
393 		break;
394 
395 	case OPJ_CLRSPC_GRAY:
396 		interpretation = vips_format_sizeof( format ) == 1 ?
397 			VIPS_INTERPRETATION_B_W :
398 			VIPS_INTERPRETATION_GREY16;
399 		break;
400 
401 	case OPJ_CLRSPC_SRGB:
402 		interpretation = vips_format_sizeof( format ) == 1 ?
403 			VIPS_INTERPRETATION_sRGB :
404 			VIPS_INTERPRETATION_RGB16;
405 		break;
406 
407 	case OPJ_CLRSPC_CMYK:
408 		interpretation = VIPS_INTERPRETATION_CMYK;
409 		break;
410 
411 	case OPJ_CLRSPC_UNSPECIFIED:
412 		/* Try to guess something sensible.
413 		 */
414 		if( jp2k->image->numcomps < 3 )
415 			interpretation = vips_format_sizeof( format ) == 1 ?
416 				VIPS_INTERPRETATION_B_W :
417 				VIPS_INTERPRETATION_GREY16;
418 		else
419 			interpretation = vips_format_sizeof( format ) == 1 ?
420 				VIPS_INTERPRETATION_sRGB :
421 				VIPS_INTERPRETATION_RGB16;
422 
423 		/* Unspecified with three bands and subsampling on bands 2 and
424 		 * 3 is usually YCC.
425 		 */
426 		if( jp2k->image->numcomps == 3 &&
427 			jp2k->image->comps[0].dx == 1 &&
428 			jp2k->image->comps[0].dy == 1 &&
429 			jp2k->image->comps[1].dx > 1 &&
430 			jp2k->image->comps[1].dy > 1 &&
431 			jp2k->image->comps[2].dx > 1 &&
432 			jp2k->image->comps[2].dy > 1)
433 			jp2k->ycc_to_rgb = TRUE;
434 
435 		break;
436 
437 	default:
438 		vips_error( class->nickname,
439 			_( "unsupported colourspace %d" ),
440 			jp2k->image->color_space );
441 		return( -1 );
442 	}
443 
444 	/* Even though this is a tiled reader, we hint thinstrip since with
445 	 * the cache we are quite happy serving that if anything downstream
446 	 * would like it.
447 	 */
448         if( vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL ) )
449 		return( -1 );
450 
451 	vips_image_init_fields( out,
452 		first->w, first->h, jp2k->image->numcomps, format,
453 		VIPS_CODING_NONE, interpretation, 1.0, 1.0 );
454 
455 	/* openjpeg allows left and top of the coordinate grid to be
456 	 * non-zero. These are always in unshrunk coordinates.
457 	 */
458 	out->Xoffset =
459 		-VIPS_ROUND_INT( (double) jp2k->image->x0 / jp2k->shrink );
460 	out->Yoffset =
461 		-VIPS_ROUND_INT( (double) jp2k->image->y0 / jp2k->shrink );
462 
463 	if( jp2k->image->icc_profile_buf &&
464 		jp2k->image->icc_profile_len > 0 )
465 		vips_image_set_blob_copy( out, VIPS_META_ICC_NAME,
466 			jp2k->image->icc_profile_buf,
467 			jp2k->image->icc_profile_len );
468 
469 	/* Map number of layers in image to pages.
470 	 */
471 	if( jp2k->info &&
472 		jp2k->info->m_default_tile_info.tccp_info )
473 		vips_image_set_int( out, VIPS_META_N_PAGES,
474 			jp2k->info->m_default_tile_info.tccp_info->
475 				numresolutions );
476 
477 	return( 0 );
478 }
479 
480 static int
vips_foreign_load_jp2k_header(VipsForeignLoad * load)481 vips_foreign_load_jp2k_header( VipsForeignLoad *load )
482 {
483 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( load );
484 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) load;
485 
486 	opj_image_comp_t *first;
487 	int i;
488 
489 #ifdef DEBUG
490 	printf( "vips_foreign_load_jp2k_header:\n" );
491 #endif /*DEBUG*/
492 
493 	jp2k->format = vips_foreign_load_jp2k_get_format( jp2k->source );
494 	vips_source_rewind( jp2k->source );
495 	if( !(jp2k->codec = opj_create_decompress( jp2k->format )) )
496 		return( -1 );
497 
498 	vips_foreign_load_jp2k_attach_handlers( jp2k, jp2k->codec );
499 
500 	jp2k->shrink = 1 << jp2k->page;
501 	jp2k->parameters.cp_reduce = jp2k->page;
502 	if( !opj_setup_decoder( jp2k->codec, &jp2k->parameters ) )
503 		return( -1 );
504 
505 	opj_codec_set_threads( jp2k->codec, vips_concurrency_get() );
506 
507 	if( !opj_read_header( jp2k->stream, jp2k->codec, &jp2k->image ) )
508 		return( -1 );
509 	if( !(jp2k->info = opj_get_cstr_info( jp2k->codec )) )
510 		return( -1 );
511 
512 #ifdef DEBUG
513 	vips_foreign_load_jp2k_print( jp2k );
514 #endif /*DEBUG*/
515 
516 	/* We only allow images where all components have the same format.
517 	 */
518 	if( jp2k->image->numcomps > MAX_BANDS ) {
519 		vips_error( class->nickname,
520 			"%s", _( "too many image bands" ) );
521 		return( -1 );
522 	}
523 	if( jp2k->image->numcomps == 0 ) {
524 		vips_error( class->nickname,
525 			"%s", _( "no image components" ) );
526 		return( -1 );
527 	}
528 	first = &jp2k->image->comps[0];
529 	for( i = 1; i < jp2k->image->numcomps; i++ ) {
530 		opj_image_comp_t *this = &jp2k->image->comps[i];
531 
532 		if( this->x0 != first->x0 ||
533 			this->y0 != first->y0 ||
534 			this->w * this->dx != first->w * first->dx ||
535 			this->h * this->dy != first->h * first->dy ||
536 			this->resno_decoded != first->resno_decoded ||
537 			this->factor != first->factor ) {
538 			vips_error( class->nickname,
539 				"%s", _( "components differ in geometry" ) );
540 			return( -1 );
541 		}
542 
543 		if( this->prec != first->prec ||
544 			this->bpp != first->bpp ||
545 			this->sgnd != first->sgnd ) {
546 			vips_error( class->nickname,
547 				"%s", _( "components differ in precision" ) );
548 			return( -1 );
549 		}
550 
551 		/* If dx/dy are not 1, we'll need to upsample components during
552 		 * tile packing.
553 		 */
554 		if( this->dx != first->dx ||
555 			this->dy != first->dy ||
556 			first->dx != 1 ||
557 			first->dy != 1 )
558 			jp2k->upsample = TRUE;
559 	}
560 
561 	if( vips_foreign_load_jp2k_set_header( jp2k, load->out ) )
562 		return( -1 );
563 
564 	VIPS_SETSTR( load->out->filename,
565 		vips_connection_filename( VIPS_CONNECTION( jp2k->source ) ) );
566 
567 	return( 0 );
568 }
569 
570 #define PACK( TYPE ) { \
571 	TYPE *tq = (TYPE *) q; \
572 	\
573 	for( x = 0; x < length; x++ ) { \
574 		for( i = 0; i < b; i++ ) \
575 			tq[i] = planes[i][x]; \
576 		\
577 		tq += b; \
578 	} \
579 }
580 
581 #define PACK_UPSAMPLE( TYPE ) { \
582 	TYPE *tq = (TYPE *) q; \
583 	\
584 	for( x = 0; x < length; x++ ) { \
585 		for( i = 0; i < b; i++ ) { \
586 			int dx = image->comps[i].dx; \
587 			int pixel = planes[i][x / dx]; \
588 			\
589 			tq[i] = pixel; \
590 		} \
591 		\
592 		tq += b; \
593 	} \
594 }
595 
596 /* Pack a line of openjpeg pixels into libvips format. left/top are the
597  * offsets into the opj image in pixel coordinates where we should start
598  * reading.
599  *
600  * Set upsample if any opj component is subsampled.
601  */
602 static void
vips_foreign_load_jp2k_pack(gboolean upsample,opj_image_t * image,VipsImage * im,VipsPel * q,int left,int top,int length)603 vips_foreign_load_jp2k_pack( gboolean upsample,
604 	opj_image_t *image, VipsImage *im,
605 	VipsPel *q, int left, int top, int length )
606 {
607 	int *planes[MAX_BANDS];
608 	int b = image->numcomps;
609 
610 	int x, i;
611 
612 #ifdef DEBUG_VERBOSE
613 	printf( "vips_foreign_load_jp2k_pack: "
614 		"upsample = %d, left = %d, top = %d, length = %d\n",
615 		upsample, left, top, length );
616 #endif /*DEBUG_VERBOSE*/
617 
618 	for( i = 0; i < b; i++ ) {
619 		opj_image_comp_t *comp = &image->comps[i];
620 
621 		planes[i] = comp->data + (top / comp->dy) * comp->w +
622 			(left / comp->dx);
623 	}
624 
625 	if( upsample )
626 		switch( im->BandFmt ) {
627 		case VIPS_FORMAT_CHAR:
628 		case VIPS_FORMAT_UCHAR:
629 			PACK_UPSAMPLE( unsigned char );
630 			break;
631 
632 		case VIPS_FORMAT_SHORT:
633 		case VIPS_FORMAT_USHORT:
634 			PACK_UPSAMPLE( unsigned short );
635 			break;
636 
637 		case VIPS_FORMAT_INT:
638 		case VIPS_FORMAT_UINT:
639 			PACK_UPSAMPLE( unsigned int );
640 			break;
641 
642 		default:
643 			g_assert_not_reached();
644 			break;
645 		}
646 	else
647 		/* Fast no-upsample path.
648 		 */
649 		switch( im->BandFmt ) {
650 		case VIPS_FORMAT_CHAR:
651 		case VIPS_FORMAT_UCHAR:
652 			PACK( unsigned char );
653 			break;
654 
655 		case VIPS_FORMAT_SHORT:
656 		case VIPS_FORMAT_USHORT:
657 			PACK( unsigned short );
658 			break;
659 
660 		case VIPS_FORMAT_INT:
661 		case VIPS_FORMAT_UINT:
662 			PACK( unsigned int );
663 			break;
664 
665 		default:
666 			g_assert_not_reached();
667 			break;
668 		}
669 }
670 
671 /* ycc->rgb coversion adapted from openjpeg src/bin/common/color.c
672  *
673  * See also https://en.wikipedia.org/wiki/YCbCr#JPEG_conversion
674  */
675 #define YCC_TO_RGB( TYPE ) { \
676 	TYPE *tq = (TYPE *) q; \
677 	\
678 	for( x = 0; x < length; x++ ) { \
679 		int y = tq[0]; \
680 		int cb = tq[1] - offset; \
681 		int cr = tq[2] - offset; \
682 		\
683 		int r, g, b; \
684 		\
685 		r = y + (int)(1.402 * (float)cr); \
686 		tq[0] = VIPS_CLIP( 0, r, upb ); \
687 		\
688 		g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr); \
689 		tq[1] = VIPS_CLIP( 0, g, upb ); \
690 		\
691 		b = y + (int)(1.772 * (float)cb); \
692 		tq[2] = VIPS_CLIP( 0, b, upb ); \
693 		\
694 		tq += 3; \
695 	} \
696 }
697 
698 /* YCC->RGB for a line of pels.
699  */
700 static void
vips_foreign_load_jp2k_ycc_to_rgb(opj_image_t * image,VipsImage * im,VipsPel * q,int length)701 vips_foreign_load_jp2k_ycc_to_rgb( opj_image_t *image, VipsImage *im,
702 	VipsPel *q, int length )
703 {
704 	int prec = image->comps[0].prec;
705 	int offset = 1 << (prec - 1);
706 	int upb = (1 << prec) - 1;
707 
708 	int x;
709 
710 	switch( im->BandFmt ) {
711 	case VIPS_FORMAT_CHAR:
712 	case VIPS_FORMAT_UCHAR:
713 		YCC_TO_RGB( unsigned char );
714 		break;
715 
716 	case VIPS_FORMAT_SHORT:
717 	case VIPS_FORMAT_USHORT:
718 		YCC_TO_RGB( unsigned short );
719 		break;
720 
721 	case VIPS_FORMAT_INT:
722 	case VIPS_FORMAT_UINT:
723 		YCC_TO_RGB( unsigned int );
724 		break;
725 
726 	default:
727 		g_assert_not_reached();
728 		break;
729 	}
730 }
731 
732 /* Read a tile from an untiled jp2k file.
733  */
734 static int
vips_foreign_load_jp2k_generate_untiled(VipsRegion * out,void * seq,void * a,void * b,gboolean * stop)735 vips_foreign_load_jp2k_generate_untiled( VipsRegion *out,
736 	void *seq, void *a, void *b, gboolean *stop )
737 {
738 	VipsForeignLoad *load = (VipsForeignLoad *) a;
739 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) load;
740 	VipsRect *r = &out->valid;
741 
742 	VipsRect opj;
743 	VipsRect image;
744 	int y;
745 
746 #ifdef DEBUG_VERBOSE
747 	printf( "vips_foreign_load_jp2k_generate_untiled: "
748 		"left = %d, top = %d, width = %d, height = %d\n",
749 		r->left, r->top, r->width, r->height );
750 #endif /*DEBUG_VERBOSE*/
751 
752 	/* If openjpeg has flagged an error, the library is not in a known
753 	 * state and it's not safe to call again.
754 	 */
755 	if( jp2k->n_errors )
756 		return( 0 );
757 
758 	/* Coordinates are always in the highest res level.
759 	 */
760 	opj.left = r->left * jp2k->shrink;
761 	opj.top = r->top * jp2k->shrink;
762 	opj.width = r->width * jp2k->shrink;
763 	opj.height = r->height * jp2k->shrink;
764 
765 	/* And must be clipped against the image size.
766 	 */
767 	image.left = 0;
768 	image.top = 0;
769 	image.width = jp2k->info->tdx;
770 	image.height = jp2k->info->tdy;
771 	vips_rect_intersectrect( &opj, &image, &opj );
772 
773 	if( !opj_set_decode_area( jp2k->codec, jp2k->image,
774 		opj.left, opj.top,
775 		VIPS_RECT_RIGHT( &opj ), VIPS_RECT_BOTTOM( &opj ) ) )
776 		return( -1 );
777 
778 	if( !opj_decode( jp2k->codec, jp2k->stream, jp2k->image ) )
779 		return( -1 );
780 
781 	/* Unpack decoded pixels to buffer in vips layout.
782 	 */
783 	for( y = 0; y < r->height; y++ ) {
784 		VipsPel *q = VIPS_REGION_ADDR( out, r->left, r->top + y );
785 
786 		vips_foreign_load_jp2k_pack( jp2k->upsample,
787 			jp2k->image, out->im, q, 0, y, r->width );
788 
789 		if( jp2k->ycc_to_rgb )
790 			vips_foreign_load_jp2k_ycc_to_rgb( jp2k->image,
791 				out->im, q, r->width );
792 	}
793 
794 	/* jp2k files can't be truncated (they fail to open), so all we can
795 	 * spot is errors.
796 	 */
797 	if( load->fail_on >= VIPS_FAIL_ON_ERROR &&
798 		jp2k->n_errors > 0 )
799 		return( -1 );
800 
801 	return( 0 );
802 }
803 
804 /* Read a tile from the file. libvips tiles can be much larger or smaller than
805  * openjpeg tiles, so we must loop over the output region, painting in
806  * tiles from the file.
807  */
808 static int
vips_foreign_load_jp2k_generate_tiled(VipsRegion * out,void * seq,void * a,void * b,gboolean * stop)809 vips_foreign_load_jp2k_generate_tiled( VipsRegion *out,
810 	void *seq, void *a, void *b, gboolean *stop )
811 {
812 	VipsForeignLoad *load = (VipsForeignLoad *) a;
813 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) load;
814 	VipsRect *r = &out->valid;
815 
816 	/* jp2k get smaller with the layer size.
817 	 */
818 	int tile_width = VIPS_ROUND_UINT(
819 		(double) jp2k->info->tdx / jp2k->shrink );
820 	int tile_height = VIPS_ROUND_UINT(
821 		(double) jp2k->info->tdy / jp2k->shrink );
822 
823 	/* ... so tiles_across is always the same.
824 	 */
825 	int tiles_across = jp2k->info->tw;
826 
827 	int x, y, z;
828 
829 #ifdef DEBUG_VERBOSE
830 	printf( "vips_foreign_load_jp2k_generate: "
831 		"left = %d, top = %d, width = %d, height = %d\n",
832 		r->left, r->top, r->width, r->height );
833 #endif /*DEBUG_VERBOSE*/
834 
835 	/* If openjpeg has flagged an error, the library is not in a known
836 	 * state and it's not safe to call again.
837 	 */
838 	if( jp2k->n_errors )
839 		return( 0 );
840 
841 	y = 0;
842 	while( y < r->height ) {
843 		VipsRect tile, hit;
844 
845 		/* Not necessary, but it stops static analyzers complaining
846 		 * about a used-before-set.
847 		 */
848 		hit.height = 0;
849 
850 		x = 0;
851 		while( x < r->width ) {
852 			/* Tile the xy falls in, in tile numbers.
853 			 */
854 			int tx = (r->left + x) / tile_width;
855 			int ty = (r->top + y) / tile_height;
856 
857 			/* Pixel coordinates of the tile that xy falls in.
858 			 */
859 			int xs = tx * tile_width;
860 			int ys = ty * tile_height;
861 
862 			int tile_index = ty * tiles_across + tx;
863 
864 			/* Fetch the tile.
865 			 */
866 #ifdef DEBUG_VERBOSE
867 			printf( "   fetch tile %d\n", tile_index );
868 #endif /*DEBUG_VERBOSE*/
869 			if( !opj_get_decoded_tile( jp2k->codec,
870 				jp2k->stream, jp2k->image, tile_index ) )
871 				return( -1 );
872 
873 			/* Intersect tile with request to get pixels we need
874 			 * to copy out.
875 			 */
876 			tile.left = xs;
877 			tile.top = ys;
878 			tile.width = tile_width;
879 			tile.height = tile_height;
880 			vips_rect_intersectrect( &tile, r, &hit );
881 
882 			/* Unpack hit pixels to buffer in vips layout.
883 			 */
884 			for( z = 0; z < hit.height; z++ ) {
885 				VipsPel *q = VIPS_REGION_ADDR( out,
886 					hit.left, hit.top + z );
887 
888 				vips_foreign_load_jp2k_pack( jp2k->upsample,
889 					jp2k->image, out->im, q,
890 					hit.left - tile.left,
891 					hit.top - tile.top + z,
892 					hit.width );
893 
894 				if( jp2k->ycc_to_rgb )
895 					vips_foreign_load_jp2k_ycc_to_rgb(
896 						jp2k->image, out->im, q,
897 						hit.width );
898 			}
899 
900 			x += hit.width;
901 		}
902 
903 		/* This will be the same for all tiles in the row we've just
904 		 * done.
905 		 */
906 		y += hit.height;
907 	}
908 
909 	/* jp2k files can't be truncated (they fail to open), so all we can
910 	 * spot is errors.
911 	 */
912 	if( load->fail_on >= VIPS_FAIL_ON_ERROR &&
913 		jp2k->n_errors > 0 )
914 		return( -1 );
915 
916 	return( 0 );
917 }
918 
919 static int
vips_foreign_load_jp2k_load(VipsForeignLoad * load)920 vips_foreign_load_jp2k_load( VipsForeignLoad *load )
921 {
922 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) load;
923 	VipsImage **t = (VipsImage **)
924 		vips_object_local_array( VIPS_OBJECT( load ), 3 );
925 
926 	int vips_tile_width;
927 	int vips_tile_height;
928 	int vips_tiles_across;
929 
930 #ifdef DEBUG
931 	printf( "vips_foreign_load_jp2k_load:\n" );
932 #endif /*DEBUG*/
933 
934 	t[0] = vips_image_new();
935 	if( vips_foreign_load_jp2k_set_header( jp2k, t[0] ) )
936 		return( -1 );
937 
938 	/* Untiled jp2k images need a different read API.
939 	 */
940 	if( jp2k->info->tw == 1 &&
941 		jp2k->info->th == 1 ) {
942 		vips_tile_width = 512;
943 		vips_tile_height = 512;
944 		vips_tiles_across =
945 			VIPS_ROUND_UP( t[0]->Xsize, vips_tile_width ) /
946 			vips_tile_width;
947 
948 		if( vips_image_generate( t[0],
949 			NULL, vips_foreign_load_jp2k_generate_untiled, NULL,
950 			jp2k, NULL ) )
951 			return( -1 );
952 	}
953 	else {
954 		vips_tile_width = jp2k->info->tdx;
955 		vips_tile_height = jp2k->info->tdy;
956 		vips_tiles_across =  jp2k->info->tw;
957 
958 		if( vips_image_generate( t[0],
959 			NULL, vips_foreign_load_jp2k_generate_tiled, NULL,
960 			jp2k, NULL ) )
961 			return( -1 );
962 	}
963 
964 	/* Copy to out, adding a cache. Enough tiles for two complete
965 	 * rows, plus 50%.
966 	 */
967 	if( vips_tilecache( t[0], &t[1],
968 		"tile_width", vips_tile_width,
969 		"tile_height", vips_tile_height,
970 		"max_tiles", 3 * vips_tiles_across,
971 		NULL ) )
972 		return( -1 );
973 
974 	if( vips_image_write( t[1], load->real ) )
975 		return( -1 );
976 
977 	return( 0 );
978 }
979 
980 static void
vips_foreign_load_jp2k_class_init(VipsForeignLoadJp2kClass * class)981 vips_foreign_load_jp2k_class_init( VipsForeignLoadJp2kClass *class )
982 {
983 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
984 	VipsObjectClass *object_class = (VipsObjectClass *) class;
985 	VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
986 
987 	gobject_class->dispose = vips_foreign_load_jp2k_dispose;
988 	gobject_class->set_property = vips_object_set_property;
989 	gobject_class->get_property = vips_object_get_property;
990 
991 	object_class->nickname = "jp2kload_base";
992 	object_class->description = _( "load JPEG2000 image" );
993 	object_class->build = vips_foreign_load_jp2k_build;
994 
995 	load_class->get_flags = vips_foreign_load_jp2k_get_flags;
996 	load_class->header = vips_foreign_load_jp2k_header;
997 	load_class->load = vips_foreign_load_jp2k_load;
998 
999 	VIPS_ARG_INT( class, "page", 20,
1000 		_( "Page" ),
1001 		_( "Load this page from the image" ),
1002 		VIPS_ARGUMENT_OPTIONAL_INPUT,
1003 		G_STRUCT_OFFSET( VipsForeignLoadJp2k, page ),
1004 		0, 100000, 0 );
1005 
1006 }
1007 
1008 static void
vips_foreign_load_jp2k_init(VipsForeignLoadJp2k * jp2k)1009 vips_foreign_load_jp2k_init( VipsForeignLoadJp2k *jp2k )
1010 {
1011 }
1012 
1013 typedef struct _VipsForeignLoadJp2kFile {
1014 	VipsForeignLoadJp2k parent_object;
1015 
1016 	/* Filename for load.
1017 	 */
1018 	char *filename;
1019 
1020 } VipsForeignLoadJp2kFile;
1021 
1022 typedef VipsForeignLoadJp2kClass VipsForeignLoadJp2kFileClass;
1023 
1024 G_DEFINE_TYPE( VipsForeignLoadJp2kFile, vips_foreign_load_jp2k_file,
1025 	vips_foreign_load_jp2k_get_type() );
1026 
1027 static int
vips_foreign_load_jp2k_file_build(VipsObject * object)1028 vips_foreign_load_jp2k_file_build( VipsObject *object )
1029 {
1030 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) object;
1031 	VipsForeignLoadJp2kFile *file = (VipsForeignLoadJp2kFile *) object;
1032 
1033 	if( file->filename &&
1034 		!(jp2k->source = vips_source_new_from_file( file->filename )) )
1035 		return( -1 );
1036 
1037 	if( VIPS_OBJECT_CLASS( vips_foreign_load_jp2k_file_parent_class )->
1038 		build( object ) )
1039 		return( -1 );
1040 
1041 	return( 0 );
1042 }
1043 
1044 const char *vips__jp2k_suffs[] =
1045 	{ ".j2k", ".jp2", ".jpt", ".j2c", ".jpc", NULL };
1046 
1047 static int
vips_foreign_load_jp2k_is_a(const char * filename)1048 vips_foreign_load_jp2k_is_a( const char *filename )
1049 {
1050 	VipsSource *source;
1051 	gboolean result;
1052 
1053 	if( !(source = vips_source_new_from_file( filename )) )
1054 		return( FALSE );
1055 	result = vips_foreign_load_jp2k_is_a_source( source );
1056 	VIPS_UNREF( source );
1057 
1058 	return( result );
1059 }
1060 
1061 static void
vips_foreign_load_jp2k_file_class_init(VipsForeignLoadJp2kFileClass * class)1062 vips_foreign_load_jp2k_file_class_init(
1063 	VipsForeignLoadJp2kFileClass *class )
1064 {
1065 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
1066 	VipsObjectClass *object_class = (VipsObjectClass *) class;
1067 	VipsForeignClass *foreign_class = (VipsForeignClass *) class;
1068 	VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
1069 
1070 	gobject_class->set_property = vips_object_set_property;
1071 	gobject_class->get_property = vips_object_get_property;
1072 
1073 	object_class->nickname = "jp2kload";
1074 	object_class->build = vips_foreign_load_jp2k_file_build;
1075 
1076 	foreign_class->suffs = vips__jp2k_suffs;
1077 
1078 	load_class->is_a = vips_foreign_load_jp2k_is_a;
1079 
1080 	VIPS_ARG_STRING( class, "filename", 1,
1081 		_( "Filename" ),
1082 		_( "Filename to load from" ),
1083 		VIPS_ARGUMENT_REQUIRED_INPUT,
1084 		G_STRUCT_OFFSET( VipsForeignLoadJp2kFile, filename ),
1085 		NULL );
1086 
1087 }
1088 
1089 static void
vips_foreign_load_jp2k_file_init(VipsForeignLoadJp2kFile * jp2k)1090 vips_foreign_load_jp2k_file_init( VipsForeignLoadJp2kFile *jp2k )
1091 {
1092 }
1093 
1094 typedef struct _VipsForeignLoadJp2kBuffer {
1095 	VipsForeignLoadJp2k parent_object;
1096 
1097 	/* Load from a buffer.
1098 	 */
1099 	VipsArea *buf;
1100 
1101 } VipsForeignLoadJp2kBuffer;
1102 
1103 typedef VipsForeignLoadJp2kClass VipsForeignLoadJp2kBufferClass;
1104 
1105 G_DEFINE_TYPE( VipsForeignLoadJp2kBuffer, vips_foreign_load_jp2k_buffer,
1106 	vips_foreign_load_jp2k_get_type() );
1107 
1108 static int
vips_foreign_load_jp2k_buffer_build(VipsObject * object)1109 vips_foreign_load_jp2k_buffer_build( VipsObject *object )
1110 {
1111 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) object;
1112 	VipsForeignLoadJp2kBuffer *buffer =
1113 		(VipsForeignLoadJp2kBuffer *) object;
1114 
1115 	if( buffer->buf )
1116 		if( !(jp2k->source = vips_source_new_from_memory(
1117 			VIPS_AREA( buffer->buf )->data,
1118 			VIPS_AREA( buffer->buf )->length )) )
1119 			return( -1 );
1120 
1121 	if( VIPS_OBJECT_CLASS( vips_foreign_load_jp2k_file_parent_class )->
1122 		build( object ) )
1123 		return( -1 );
1124 
1125 	return( 0 );
1126 }
1127 
1128 static gboolean
vips_foreign_load_jp2k_buffer_is_a(const void * buf,size_t len)1129 vips_foreign_load_jp2k_buffer_is_a( const void *buf, size_t len )
1130 {
1131 	VipsSource *source;
1132 	gboolean result;
1133 
1134 	if( !(source = vips_source_new_from_memory( buf, len )) )
1135 		return( FALSE );
1136 	result = vips_foreign_load_jp2k_is_a_source( source );
1137 	VIPS_UNREF( source );
1138 
1139 	return( result );
1140 }
1141 
1142 static void
vips_foreign_load_jp2k_buffer_class_init(VipsForeignLoadJp2kBufferClass * class)1143 vips_foreign_load_jp2k_buffer_class_init(
1144 	VipsForeignLoadJp2kBufferClass *class )
1145 {
1146 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
1147 	VipsObjectClass *object_class = (VipsObjectClass *) class;
1148 	VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
1149 
1150 	gobject_class->set_property = vips_object_set_property;
1151 	gobject_class->get_property = vips_object_get_property;
1152 
1153 	object_class->nickname = "jp2kload_buffer";
1154 	object_class->build = vips_foreign_load_jp2k_buffer_build;
1155 
1156 	load_class->is_a_buffer = vips_foreign_load_jp2k_buffer_is_a;
1157 
1158 	VIPS_ARG_BOXED( class, "buffer", 1,
1159 		_( "Buffer" ),
1160 		_( "Buffer to load from" ),
1161 		VIPS_ARGUMENT_REQUIRED_INPUT,
1162 		G_STRUCT_OFFSET( VipsForeignLoadJp2kBuffer, buf ),
1163 		VIPS_TYPE_BLOB );
1164 
1165 }
1166 
1167 static void
vips_foreign_load_jp2k_buffer_init(VipsForeignLoadJp2kBuffer * buffer)1168 vips_foreign_load_jp2k_buffer_init( VipsForeignLoadJp2kBuffer *buffer )
1169 {
1170 }
1171 
1172 typedef struct _VipsForeignLoadJp2kSource {
1173 	VipsForeignLoadJp2k parent_object;
1174 
1175 	/* Load from a source.
1176 	 */
1177 	VipsSource *source;
1178 
1179 } VipsForeignLoadJp2kSource;
1180 
1181 typedef VipsForeignLoadJp2kClass VipsForeignLoadJp2kSourceClass;
1182 
1183 G_DEFINE_TYPE( VipsForeignLoadJp2kSource, vips_foreign_load_jp2k_source,
1184 	vips_foreign_load_jp2k_get_type() );
1185 
1186 static int
vips_foreign_load_jp2k_source_build(VipsObject * object)1187 vips_foreign_load_jp2k_source_build( VipsObject *object )
1188 {
1189 	VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) object;
1190 	VipsForeignLoadJp2kSource *source =
1191 		(VipsForeignLoadJp2kSource *) object;
1192 
1193 	if( source->source ) {
1194 		jp2k->source = source->source;
1195 		g_object_ref( jp2k->source );
1196 	}
1197 
1198 	if( VIPS_OBJECT_CLASS(
1199 		vips_foreign_load_jp2k_source_parent_class )->
1200 			build( object ) )
1201 		return( -1 );
1202 
1203 	return( 0 );
1204 }
1205 
1206 static void
vips_foreign_load_jp2k_source_class_init(VipsForeignLoadJp2kSourceClass * class)1207 vips_foreign_load_jp2k_source_class_init(
1208 	VipsForeignLoadJp2kSourceClass *class )
1209 {
1210 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
1211 	VipsObjectClass *object_class = (VipsObjectClass *) class;
1212 	VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
1213 	VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
1214 
1215 	gobject_class->set_property = vips_object_set_property;
1216 	gobject_class->get_property = vips_object_get_property;
1217 
1218 	object_class->nickname = "jp2kload_source";
1219 	object_class->build = vips_foreign_load_jp2k_source_build;
1220 
1221 	operation_class->flags = VIPS_OPERATION_NOCACHE;
1222 
1223 	load_class->is_a_source = vips_foreign_load_jp2k_is_a_source;
1224 
1225 	VIPS_ARG_OBJECT( class, "source", 1,
1226 		_( "Source" ),
1227 		_( "Source to load from" ),
1228 		VIPS_ARGUMENT_REQUIRED_INPUT,
1229 		G_STRUCT_OFFSET( VipsForeignLoadJp2kSource, source ),
1230 		VIPS_TYPE_SOURCE );
1231 
1232 }
1233 
1234 static void
vips_foreign_load_jp2k_source_init(VipsForeignLoadJp2kSource * jp2k)1235 vips_foreign_load_jp2k_source_init(
1236 	VipsForeignLoadJp2kSource *jp2k )
1237 {
1238 }
1239 
1240 static void
warning_callback(const char * msg G_GNUC_UNUSED,void * data G_GNUC_UNUSED)1241 warning_callback( const char *msg G_GNUC_UNUSED, void *data G_GNUC_UNUSED )
1242 {
1243 	/* There are a lot of warnings ...
1244 	 */
1245 }
1246 
1247 static void
error_callback(const char * msg,void * data)1248 error_callback( const char *msg, void *data )
1249 {
1250 	printf( "OpenJPEG: %s", msg );
1251 	vips_error( "OpenJPEG", "%s", msg );
1252 }
1253 
1254 typedef struct _TileDecompress {
1255 	VipsSource *source;
1256         opj_stream_t *stream;
1257         opj_codec_t *codec;
1258 	opj_image_t *image;
1259 } TileDecompress;
1260 
1261 static void
vips__foreign_load_jp2k_decompress_free(TileDecompress * decompress)1262 vips__foreign_load_jp2k_decompress_free( TileDecompress *decompress )
1263 {
1264 	VIPS_FREEF( opj_destroy_codec, decompress->codec );
1265 	VIPS_FREEF( opj_image_destroy, decompress->image );
1266 	VIPS_FREEF( opj_stream_destroy, decompress->stream );
1267 	VIPS_UNREF( decompress->source );
1268 }
1269 
1270 /* Called from tiff2vips to decode a jp2k-compressed tile.
1271  *
1272  * width/height is the tile size. If this is an edge tile, and smaller than
1273  * this, we still write a full-size tile and our caller will clip.
1274  */
1275 int
vips__foreign_load_jp2k_decompress(VipsImage * out,int width,int height,gboolean ycc_to_rgb,void * from,size_t from_length,void * to,size_t to_length)1276 vips__foreign_load_jp2k_decompress( VipsImage *out,
1277 	int width, int height, gboolean ycc_to_rgb,
1278 	void *from, size_t from_length,
1279 	void *to, size_t to_length )
1280 {
1281 	size_t pel_size = VIPS_IMAGE_SIZEOF_PEL( out );
1282 	size_t line_size = pel_size * width;
1283 
1284 	TileDecompress decompress = { 0 };
1285 	opj_dparameters_t parameters;
1286 	int i;
1287 	gboolean upsample;
1288 	VipsPel *q;
1289 	int y;
1290 
1291 #ifdef DEBUG
1292 	printf( "vips__foreign_load_jp2k_decompress: width = %d, height = %d, "
1293 		"ycc_to_rgb = %d, from_length = %zd, to_length = %zd\n",
1294 		width, height, ycc_to_rgb, from_length, to_length );
1295 #endif /*DEBUG*/
1296 
1297 	/* Our ycc->rgb only works for exactly 3 bands.
1298 	 */
1299 	ycc_to_rgb = ycc_to_rgb && out->Bands == 3;
1300 
1301 	decompress.codec = opj_create_decompress( OPJ_CODEC_J2K );
1302 	opj_set_default_decoder_parameters( &parameters );
1303 	opj_setup_decoder( decompress.codec, &parameters );
1304 	opj_set_warning_handler( decompress.codec, warning_callback, NULL );
1305 	opj_set_error_handler( decompress.codec, error_callback, NULL );
1306 
1307 	decompress.source = vips_source_new_from_memory( from, from_length );
1308 	decompress.stream = vips_foreign_load_jp2k_stream( decompress.source );
1309 	if( !opj_read_header( decompress.stream,
1310 		decompress.codec, &decompress.image ) ) {
1311 		vips_error( "jp2kload", "%s", ( "header error" ) );
1312 		vips__foreign_load_jp2k_decompress_free( &decompress );
1313 		return( -1 );
1314 	}
1315 
1316 	if( decompress.image->x1 > width ||
1317 		decompress.image->y1 > height ||
1318 		line_size * height > to_length ) {
1319 		vips_error( "jp2kload", "%s", ( "bad dimensions" ) );
1320 		vips__foreign_load_jp2k_decompress_free( &decompress );
1321     		return( -1 );
1322 	}
1323 
1324 	if( !opj_decode( decompress.codec,
1325 		decompress.stream, decompress.image ) ) {
1326 		vips_error( "jp2kload", "%s", ( "decode error" ) );
1327 		vips__foreign_load_jp2k_decompress_free( &decompress );
1328 		return( -1 );
1329 	}
1330 
1331 	/* Do any components need upsampling?
1332 	 */
1333 	upsample = FALSE;
1334 	for( i = 0; i < decompress.image->numcomps; i++ ) {
1335 		opj_image_comp_t *this = &decompress.image->comps[i];
1336 
1337 		if( this->dx > 1 ||
1338 			this->dy > 1 )
1339 			upsample = TRUE;
1340 	}
1341 
1342 	/* Unpack hit pixels to buffer in vips layout.
1343 	 */
1344 	q = to;
1345 	for( y = 0; y < height; y++ ) {
1346 		vips_foreign_load_jp2k_pack( upsample,
1347 			decompress.image, out, q,
1348 			0, y, width );
1349 
1350 		if( ycc_to_rgb )
1351 			vips_foreign_load_jp2k_ycc_to_rgb(
1352 				decompress.image, out, q,
1353 				width );
1354 
1355 		q += line_size;
1356 	}
1357 
1358 	vips__foreign_load_jp2k_decompress_free( &decompress );
1359 
1360 	return( 0 );
1361 }
1362 
1363 #else /*!HAVE_LIBOPENJP2*/
1364 
1365 int
vips__foreign_load_jp2k_decompress(VipsImage * out,int width,int height,gboolean ycc_to_rgb,void * from,size_t from_length,void * to,size_t to_length)1366 vips__foreign_load_jp2k_decompress( VipsImage *out,
1367 	int width, int height, gboolean ycc_to_rgb,
1368 	void *from, size_t from_length,
1369 	void *to, size_t to_length )
1370 {
1371 	vips_error( "jp2k",
1372 		"%s", _( "libvips built without JPEG2000 support" ) );
1373 	return( -1 );
1374 }
1375 
1376 #endif /*HAVE_LIBOPENJP2*/
1377 
1378 /**
1379  * vips_jp2kload:
1380  * @filename: file to load
1381  * @out: (out): decompressed image
1382  * @...: %NULL-terminated list of optional named arguments
1383  *
1384  * Optional arguments:
1385  *
1386  * * @page: %gint, load this page
1387  * * @fail_on: #VipsFailOn, types of read error to fail on
1388  *
1389  * Read a JPEG2000 image. The loader supports 8, 16 and 32-bit int pixel
1390  * values, signed and unsigned. It supports greyscale, RGB, YCC, CMYK and
1391  * multispectral colour spaces. It will read any ICC profile on the image.
1392  *
1393  * It will only load images where all channels have the same format.
1394  *
1395  * Use @page to set the page to load, where page 0 is the base resolution
1396  * image and higher-numbered pages are x2 reductions. Use the metadata item
1397  * "n-pages" to find the number of pyramid layers.
1398  *
1399  * Use @fail_on to set the type of error that will cause load to fail. By
1400  * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE.
1401  *
1402  * See also: vips_image_new_from_file().
1403  *
1404  * Returns: 0 on success, -1 on error.
1405  */
1406 int
vips_jp2kload(const char * filename,VipsImage ** out,...)1407 vips_jp2kload( const char *filename, VipsImage **out, ... )
1408 {
1409 	va_list ap;
1410 	int result;
1411 
1412 	va_start( ap, out );
1413 	result = vips_call_split( "jp2kload", ap, filename, out );
1414 	va_end( ap );
1415 
1416 	return( result );
1417 }
1418 
1419 /**
1420  * vips_jp2kload_buffer:
1421  * @buf: (array length=len) (element-type guint8): memory area to load
1422  * @len: (type gsize): size of memory area
1423  * @out: (out): image to write
1424  * @...: %NULL-terminated list of optional named arguments
1425  *
1426  * Optional arguments:
1427  *
1428  * * @page: %gint, load this page
1429  * * @fail_on: #VipsFailOn, types of read error to fail on
1430  *
1431  * Exactly as vips_jp2kload(), but read from a buffer.
1432  *
1433  * You must not free the buffer while @out is active. The
1434  * #VipsObject::postclose signal on @out is a good place to free.
1435  *
1436  * Returns: 0 on success, -1 on error.
1437  */
1438 int
vips_jp2kload_buffer(void * buf,size_t len,VipsImage ** out,...)1439 vips_jp2kload_buffer( void *buf, size_t len, VipsImage **out, ... )
1440 {
1441 	va_list ap;
1442 	VipsBlob *blob;
1443 	int result;
1444 
1445 	/* We don't take a copy of the data or free it.
1446 	 */
1447 	blob = vips_blob_new( NULL, buf, len );
1448 
1449 	va_start( ap, out );
1450 	result = vips_call_split( "jp2kload_buffer", ap, blob, out );
1451 	va_end( ap );
1452 
1453 	vips_area_unref( VIPS_AREA( blob ) );
1454 
1455 	return( result );
1456 }
1457 
1458 /**
1459  * vips_jp2kload_source:
1460  * @source: source to load from
1461  * @out: (out): decompressed image
1462  * @...: %NULL-terminated list of optional named arguments
1463  *
1464  * Optional arguments:
1465  *
1466  * * @page: %gint, load this page
1467  * * @fail_on: #VipsFailOn, types of read error to fail on
1468  *
1469  * Exactly as vips_jp2kload(), but read from a source.
1470  *
1471  * Returns: 0 on success, -1 on error.
1472  */
1473 int
vips_jp2kload_source(VipsSource * source,VipsImage ** out,...)1474 vips_jp2kload_source( VipsSource *source, VipsImage **out, ... )
1475 {
1476 	va_list ap;
1477 	int result;
1478 
1479 	va_start( ap, out );
1480 	result = vips_call_split( "jp2kload_source", ap, source, out );
1481 	va_end( ap );
1482 
1483 	return( result );
1484 }
1485