@@ -78,6 +78,8 @@ struct j2k_decode_unpacker {
7878 const char * mode ;
7979 OPJ_COLOR_SPACE color_space ;
8080 unsigned components ;
81+ /* bool indicating if unpacker supports subsampling */
82+ int subsampling ;
8183 j2k_unpacker_t unpacker ;
8284};
8385
@@ -332,6 +334,7 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
332334 unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
333335
334336 int shifts [3 ], offsets [3 ], csiz [3 ];
337+ unsigned dx [3 ], dy [3 ];
335338 const UINT8 * cdata [3 ];
336339 const UINT8 * cptr = tiledata ;
337340 unsigned n , x , y ;
@@ -341,6 +344,8 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
341344 shifts [n ] = 8 - in -> comps [n ].prec ;
342345 offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
343346 csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
347+ dx [n ] = (in -> comps [n ].dx );
348+ dy [n ] = (in -> comps [n ].dy );
344349
345350 if (csiz [n ] == 3 ) {
346351 csiz [n ] = 4 ;
@@ -350,24 +355,24 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
350355 offsets [n ] += 1 << (- shifts [n ] - 1 );
351356 }
352357
353- cptr += csiz [n ] * w * h ;
358+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
354359 }
355360
356361 for (y = 0 ; y < h ; ++ y ) {
357362 const UINT8 * data [3 ];
358363 UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
359364 for (n = 0 ; n < 3 ; ++ n ) {
360- data [n ] = & cdata [n ][csiz [n ] * y * w ];
365+ data [n ] = & cdata [n ][csiz [n ] * ( y / dy [ n ]) * ( w / dx [ n ]) ];
361366 }
362367
363368 for (x = 0 ; x < w ; ++ x ) {
364369 for (n = 0 ; n < 3 ; ++ n ) {
365370 UINT32 word = 0 ;
366371
367372 switch (csiz [n ]) {
368- case 1 : word = * data [n ]++ ; break ;
369- case 2 : word = * ( const UINT16 * )data [n ]; data [n ] += 2 ; break ;
370- case 4 : word = * ( const UINT32 * )data [n ]; data [n ] += 4 ; break ;
373+ case 1 : word = data [n ][ x / dx [ n ]] ; break ;
374+ case 2 : word = (( const UINT16 * )data [n ])[ x / dx [n ]] ; break ;
375+ case 4 : word = (( const UINT32 * )data [n ])[ x / dx [n ]] ; break ;
371376 }
372377
373378 row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -387,6 +392,7 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
387392 unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
388393
389394 int shifts [3 ], offsets [3 ], csiz [3 ];
395+ unsigned dx [3 ], dy [3 ];
390396 const UINT8 * cdata [3 ];
391397 const UINT8 * cptr = tiledata ;
392398 unsigned n , x , y ;
@@ -396,6 +402,8 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
396402 shifts [n ] = 8 - in -> comps [n ].prec ;
397403 offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
398404 csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
405+ dx [n ] = (in -> comps [n ].dx );
406+ dy [n ] = (in -> comps [n ].dy );
399407
400408 if (csiz [n ] == 3 ) {
401409 csiz [n ] = 4 ;
@@ -405,25 +413,25 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
405413 offsets [n ] += 1 << (- shifts [n ] - 1 );
406414 }
407415
408- cptr += csiz [n ] * w * h ;
416+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
409417 }
410418
411419 for (y = 0 ; y < h ; ++ y ) {
412420 const UINT8 * data [3 ];
413421 UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
414422 UINT8 * row_start = row ;
415423 for (n = 0 ; n < 3 ; ++ n ) {
416- data [n ] = & cdata [n ][csiz [n ] * y * w ];
424+ data [n ] = & cdata [n ][csiz [n ] * ( y / dy [ n ]) * ( w / dx [ n ]) ];
417425 }
418426
419427 for (x = 0 ; x < w ; ++ x ) {
420428 for (n = 0 ; n < 3 ; ++ n ) {
421429 UINT32 word = 0 ;
422430
423431 switch (csiz [n ]) {
424- case 1 : word = * data [n ]++ ; break ;
425- case 2 : word = * ( const UINT16 * )data [n ]; data [n ] += 2 ; break ;
426- case 4 : word = * ( const UINT32 * )data [n ]; data [n ] += 4 ; break ;
432+ case 1 : word = data [n ][ x / dx [ n ]] ; break ;
433+ case 2 : word = (( const UINT16 * )data [n ])[ x / dx [n ]] ; break ;
434+ case 4 : word = (( const UINT32 * )data [n ])[ x / dx [n ]] ; break ;
427435 }
428436
429437 row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -445,6 +453,7 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
445453 unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
446454
447455 int shifts [4 ], offsets [4 ], csiz [4 ];
456+ unsigned dx [4 ], dy [4 ];
448457 const UINT8 * cdata [4 ];
449458 const UINT8 * cptr = tiledata ;
450459 unsigned n , x , y ;
@@ -454,6 +463,8 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
454463 shifts [n ] = 8 - in -> comps [n ].prec ;
455464 offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
456465 csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
466+ dx [n ] = (in -> comps [n ].dx );
467+ dy [n ] = (in -> comps [n ].dy );
457468
458469 if (csiz [n ] == 3 ) {
459470 csiz [n ] = 4 ;
@@ -463,24 +474,24 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
463474 offsets [n ] += 1 << (- shifts [n ] - 1 );
464475 }
465476
466- cptr += csiz [n ] * w * h ;
477+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
467478 }
468479
469480 for (y = 0 ; y < h ; ++ y ) {
470481 const UINT8 * data [4 ];
471482 UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
472483 for (n = 0 ; n < 4 ; ++ n ) {
473- data [n ] = & cdata [n ][csiz [n ] * y * w ];
484+ data [n ] = & cdata [n ][csiz [n ] * ( y / dy [ n ]) * ( w / dx [ n ]) ];
474485 }
475486
476487 for (x = 0 ; x < w ; ++ x ) {
477488 for (n = 0 ; n < 4 ; ++ n ) {
478489 UINT32 word = 0 ;
479490
480491 switch (csiz [n ]) {
481- case 1 : word = * data [n ]++ ; break ;
482- case 2 : word = * ( const UINT16 * )data [n ]; data [n ] += 2 ; break ;
483- case 4 : word = * ( const UINT32 * )data [n ]; data [n ] += 4 ; break ;
492+ case 1 : word = data [n ][ x / dx [ n ]] ; break ;
493+ case 2 : word = (( const UINT16 * )data [n ])[ x / dx [n ]] ; break ;
494+ case 4 : word = (( const UINT32 * )data [n ])[ x / dx [n ]] ; break ;
484495 }
485496
486497 row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -499,6 +510,7 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
499510 unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
500511
501512 int shifts [4 ], offsets [4 ], csiz [4 ];
513+ unsigned dx [4 ], dy [4 ];
502514 const UINT8 * cdata [4 ];
503515 const UINT8 * cptr = tiledata ;
504516 unsigned n , x , y ;
@@ -508,6 +520,8 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
508520 shifts [n ] = 8 - in -> comps [n ].prec ;
509521 offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
510522 csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
523+ dx [n ] = (in -> comps [n ].dx );
524+ dy [n ] = (in -> comps [n ].dy );
511525
512526 if (csiz [n ] == 3 ) {
513527 csiz [n ] = 4 ;
@@ -517,25 +531,25 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
517531 offsets [n ] += 1 << (- shifts [n ] - 1 );
518532 }
519533
520- cptr += csiz [n ] * w * h ;
534+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
521535 }
522536
523537 for (y = 0 ; y < h ; ++ y ) {
524538 const UINT8 * data [4 ];
525539 UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
526540 UINT8 * row_start = row ;
527541 for (n = 0 ; n < 4 ; ++ n ) {
528- data [n ] = & cdata [n ][csiz [n ] * y * w ];
542+ data [n ] = & cdata [n ][csiz [n ] * ( y / dy [ n ]) * ( w / dx [ n ]) ];
529543 }
530544
531545 for (x = 0 ; x < w ; ++ x ) {
532546 for (n = 0 ; n < 4 ; ++ n ) {
533547 UINT32 word = 0 ;
534548
535549 switch (csiz [n ]) {
536- case 1 : word = * data [n ]++ ; break ;
537- case 2 : word = * ( const UINT16 * )data [n ]; data [n ] += 2 ; break ;
538- case 4 : word = * ( const UINT32 * )data [n ]; data [n ] += 4 ; break ;
550+ case 1 : word = data [n ][ x / dx [ n ]] ; break ;
551+ case 2 : word = (( const UINT16 * )data [n ])[ x / dx [n ]] ; break ;
552+ case 4 : word = (( const UINT32 * )data [n ])[ x / dx [n ]] ; break ;
539553 }
540554
541555 row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -548,22 +562,22 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
548562}
549563
550564static const struct j2k_decode_unpacker j2k_unpackers [] = {
551- { "L" , OPJ_CLRSPC_GRAY , 1 , j2ku_gray_l },
552- { "I;16" , OPJ_CLRSPC_GRAY , 1 , j2ku_gray_i },
553- { "I;16B" , OPJ_CLRSPC_GRAY , 1 , j2ku_gray_i },
554- { "LA" , OPJ_CLRSPC_GRAY , 2 , j2ku_graya_la },
555- { "RGB" , OPJ_CLRSPC_GRAY , 1 , j2ku_gray_rgb },
556- { "RGB" , OPJ_CLRSPC_GRAY , 2 , j2ku_gray_rgb },
557- { "RGB" , OPJ_CLRSPC_SRGB , 3 , j2ku_srgb_rgb },
558- { "RGB" , OPJ_CLRSPC_SYCC , 3 , j2ku_sycc_rgb },
559- { "RGB" , OPJ_CLRSPC_SRGB , 4 , j2ku_srgb_rgb },
560- { "RGB" , OPJ_CLRSPC_SYCC , 4 , j2ku_sycc_rgb },
561- { "RGBA" , OPJ_CLRSPC_GRAY , 1 , j2ku_gray_rgb },
562- { "RGBA" , OPJ_CLRSPC_GRAY , 2 , j2ku_graya_la },
563- { "RGBA" , OPJ_CLRSPC_SRGB , 3 , j2ku_srgb_rgb },
564- { "RGBA" , OPJ_CLRSPC_SYCC , 3 , j2ku_sycc_rgb },
565- { "RGBA" , OPJ_CLRSPC_SRGB , 4 , j2ku_srgba_rgba },
566- { "RGBA" , OPJ_CLRSPC_SYCC , 4 , j2ku_sycca_rgba },
565+ { "L" , OPJ_CLRSPC_GRAY , 1 , 0 , j2ku_gray_l },
566+ { "I;16" , OPJ_CLRSPC_GRAY , 1 , 0 , j2ku_gray_i },
567+ { "I;16B" , OPJ_CLRSPC_GRAY , 1 , 0 , j2ku_gray_i },
568+ { "LA" , OPJ_CLRSPC_GRAY , 2 , 0 , j2ku_graya_la },
569+ { "RGB" , OPJ_CLRSPC_GRAY , 1 , 0 , j2ku_gray_rgb },
570+ { "RGB" , OPJ_CLRSPC_GRAY , 2 , 0 , j2ku_gray_rgb },
571+ { "RGB" , OPJ_CLRSPC_SRGB , 3 , 1 , j2ku_srgb_rgb },
572+ { "RGB" , OPJ_CLRSPC_SYCC , 3 , 1 , j2ku_sycc_rgb },
573+ { "RGB" , OPJ_CLRSPC_SRGB , 4 , 1 , j2ku_srgb_rgb },
574+ { "RGB" , OPJ_CLRSPC_SYCC , 4 , 1 , j2ku_sycc_rgb },
575+ { "RGBA" , OPJ_CLRSPC_GRAY , 1 , 0 , j2ku_gray_rgb },
576+ { "RGBA" , OPJ_CLRSPC_GRAY , 2 , 0 , j2ku_graya_la },
577+ { "RGBA" , OPJ_CLRSPC_SRGB , 3 , 1 , j2ku_srgb_rgb },
578+ { "RGBA" , OPJ_CLRSPC_SYCC , 3 , 1 , j2ku_sycc_rgb },
579+ { "RGBA" , OPJ_CLRSPC_SRGB , 4 , 1 , j2ku_srgba_rgba },
580+ { "RGBA" , OPJ_CLRSPC_SYCC , 4 , 1 , j2ku_sycca_rgba },
567581};
568582
569583/* -------------------------------------------------------------------- */
@@ -589,7 +603,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
589603 j2k_unpacker_t unpack = NULL ;
590604 size_t buffer_size = 0 , tile_bytes = 0 ;
591605 unsigned n , tile_height , tile_width ;
592- int components ;
606+ int components , subsampling ;
593607
594608
595609 stream = opj_stream_create (BUFFER_SIZE , OPJ_TRUE );
@@ -652,11 +666,16 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
652666 goto quick_exit ;
653667 }
654668
655- for (n = 1 ; n < image -> numcomps ; ++ n ) {
669+ /*
670+ * Find first component with subsampling.
671+ *
672+ * This is a heuristic to determine the colorspace if unspecified.
673+ */
674+ subsampling = -1 ;
675+ for (n = 0 ; n < image -> numcomps ; ++ n ) {
656676 if (image -> comps [n ].dx != 1 || image -> comps [n ].dy != 1 ) {
657- state -> errcode = IMAGING_CODEC_BROKEN ;
658- state -> state = J2K_STATE_FAILED ;
659- goto quick_exit ;
677+ subsampling = n ;
678+ break ;
660679 }
661680 }
662681
@@ -672,12 +691,14 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
672691
673692 If colorspace is unspecified, we assume:
674693
675- Number of components Colorspace
676- -----------------------------------------
677- 1 gray
678- 2 gray (+ alpha)
679- 3 sRGB
680- 4 sRGB (+ alpha)
694+ Number of components Subsampling Colorspace
695+ -------------------------------------------------------
696+ 1 Any gray
697+ 2 Any gray (+ alpha)
698+ 3 -1, 0 sRGB
699+ 3 1, 2 YCbCr
700+ 4 -1, 0, 3 sRGB (+ alpha)
701+ 4 1, 2 YCbCr (+ alpha)
681702
682703 */
683704
@@ -686,14 +707,23 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
686707
687708 if (color_space == OPJ_CLRSPC_UNSPECIFIED ) {
688709 switch (image -> numcomps ) {
689- case 1 : case 2 : color_space = OPJ_CLRSPC_GRAY ; break ;
690- case 3 : case 4 : color_space = OPJ_CLRSPC_SRGB ; break ;
710+ case 1 : case 2 :
711+ color_space = OPJ_CLRSPC_GRAY ; break ;
712+ case 3 : case 4 :
713+ switch (subsampling ) {
714+ case -1 : case 0 : case 3 :
715+ color_space = OPJ_CLRSPC_SRGB ; break ;
716+ case 1 : case 2 :
717+ color_space = OPJ_CLRSPC_SYCC ; break ;
718+ }
719+ break ;
691720 }
692721 }
693722
694723 for (n = 0 ; n < sizeof (j2k_unpackers ) / sizeof (j2k_unpackers [0 ]); ++ n ) {
695724 if (color_space == j2k_unpackers [n ].color_space
696725 && image -> numcomps == j2k_unpackers [n ].components
726+ && (j2k_unpackers [n ].subsampling || (subsampling == -1 ))
697727 && strcmp (im -> mode , j2k_unpackers [n ].mode ) == 0 ) {
698728 unpack = j2k_unpackers [n ].unpacker ;
699729 break ;
0 commit comments