@@ -78,6 +78,8 @@ struct j2k_decode_unpacker {
78
78
const char * mode ;
79
79
OPJ_COLOR_SPACE color_space ;
80
80
unsigned components ;
81
+ /* bool indicating if unpacker supports subsampling */
82
+ int subsampling ;
81
83
j2k_unpacker_t unpacker ;
82
84
};
83
85
@@ -332,6 +334,7 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
332
334
unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
333
335
334
336
int shifts [3 ], offsets [3 ], csiz [3 ];
337
+ unsigned dx [3 ], dy [3 ];
335
338
const UINT8 * cdata [3 ];
336
339
const UINT8 * cptr = tiledata ;
337
340
unsigned n , x , y ;
@@ -341,6 +344,8 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
341
344
shifts [n ] = 8 - in -> comps [n ].prec ;
342
345
offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
343
346
csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
347
+ dx [n ] = (in -> comps [n ].dx );
348
+ dy [n ] = (in -> comps [n ].dy );
344
349
345
350
if (csiz [n ] == 3 ) {
346
351
csiz [n ] = 4 ;
@@ -350,24 +355,24 @@ j2ku_srgb_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
350
355
offsets [n ] += 1 << (- shifts [n ] - 1 );
351
356
}
352
357
353
- cptr += csiz [n ] * w * h ;
358
+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
354
359
}
355
360
356
361
for (y = 0 ; y < h ; ++ y ) {
357
362
const UINT8 * data [3 ];
358
363
UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
359
364
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 ]) ];
361
366
}
362
367
363
368
for (x = 0 ; x < w ; ++ x ) {
364
369
for (n = 0 ; n < 3 ; ++ n ) {
365
370
UINT32 word = 0 ;
366
371
367
372
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 ;
371
376
}
372
377
373
378
row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -387,6 +392,7 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
387
392
unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
388
393
389
394
int shifts [3 ], offsets [3 ], csiz [3 ];
395
+ unsigned dx [3 ], dy [3 ];
390
396
const UINT8 * cdata [3 ];
391
397
const UINT8 * cptr = tiledata ;
392
398
unsigned n , x , y ;
@@ -396,6 +402,8 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
396
402
shifts [n ] = 8 - in -> comps [n ].prec ;
397
403
offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
398
404
csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
405
+ dx [n ] = (in -> comps [n ].dx );
406
+ dy [n ] = (in -> comps [n ].dy );
399
407
400
408
if (csiz [n ] == 3 ) {
401
409
csiz [n ] = 4 ;
@@ -405,25 +413,25 @@ j2ku_sycc_rgb(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
405
413
offsets [n ] += 1 << (- shifts [n ] - 1 );
406
414
}
407
415
408
- cptr += csiz [n ] * w * h ;
416
+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
409
417
}
410
418
411
419
for (y = 0 ; y < h ; ++ y ) {
412
420
const UINT8 * data [3 ];
413
421
UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
414
422
UINT8 * row_start = row ;
415
423
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 ]) ];
417
425
}
418
426
419
427
for (x = 0 ; x < w ; ++ x ) {
420
428
for (n = 0 ; n < 3 ; ++ n ) {
421
429
UINT32 word = 0 ;
422
430
423
431
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 ;
427
435
}
428
436
429
437
row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -445,6 +453,7 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
445
453
unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
446
454
447
455
int shifts [4 ], offsets [4 ], csiz [4 ];
456
+ unsigned dx [4 ], dy [4 ];
448
457
const UINT8 * cdata [4 ];
449
458
const UINT8 * cptr = tiledata ;
450
459
unsigned n , x , y ;
@@ -454,6 +463,8 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
454
463
shifts [n ] = 8 - in -> comps [n ].prec ;
455
464
offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
456
465
csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
466
+ dx [n ] = (in -> comps [n ].dx );
467
+ dy [n ] = (in -> comps [n ].dy );
457
468
458
469
if (csiz [n ] == 3 ) {
459
470
csiz [n ] = 4 ;
@@ -463,24 +474,24 @@ j2ku_srgba_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
463
474
offsets [n ] += 1 << (- shifts [n ] - 1 );
464
475
}
465
476
466
- cptr += csiz [n ] * w * h ;
477
+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
467
478
}
468
479
469
480
for (y = 0 ; y < h ; ++ y ) {
470
481
const UINT8 * data [4 ];
471
482
UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
472
483
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 ]) ];
474
485
}
475
486
476
487
for (x = 0 ; x < w ; ++ x ) {
477
488
for (n = 0 ; n < 4 ; ++ n ) {
478
489
UINT32 word = 0 ;
479
490
480
491
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 ;
484
495
}
485
496
486
497
row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -499,6 +510,7 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
499
510
unsigned h = tileinfo -> y1 - tileinfo -> y0 ;
500
511
501
512
int shifts [4 ], offsets [4 ], csiz [4 ];
513
+ unsigned dx [4 ], dy [4 ];
502
514
const UINT8 * cdata [4 ];
503
515
const UINT8 * cptr = tiledata ;
504
516
unsigned n , x , y ;
@@ -508,6 +520,8 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
508
520
shifts [n ] = 8 - in -> comps [n ].prec ;
509
521
offsets [n ] = in -> comps [n ].sgnd ? 1 << (in -> comps [n ].prec - 1 ) : 0 ;
510
522
csiz [n ] = (in -> comps [n ].prec + 7 ) >> 3 ;
523
+ dx [n ] = (in -> comps [n ].dx );
524
+ dy [n ] = (in -> comps [n ].dy );
511
525
512
526
if (csiz [n ] == 3 ) {
513
527
csiz [n ] = 4 ;
@@ -517,25 +531,25 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
517
531
offsets [n ] += 1 << (- shifts [n ] - 1 );
518
532
}
519
533
520
- cptr += csiz [n ] * w * h ;
534
+ cptr += csiz [n ] * ( w / dx [ n ]) * ( h / dy [ n ]) ;
521
535
}
522
536
523
537
for (y = 0 ; y < h ; ++ y ) {
524
538
const UINT8 * data [4 ];
525
539
UINT8 * row = (UINT8 * )im -> image [y0 + y ] + x0 * 4 ;
526
540
UINT8 * row_start = row ;
527
541
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 ]) ];
529
543
}
530
544
531
545
for (x = 0 ; x < w ; ++ x ) {
532
546
for (n = 0 ; n < 4 ; ++ n ) {
533
547
UINT32 word = 0 ;
534
548
535
549
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 ;
539
553
}
540
554
541
555
row [n ] = j2ku_shift (offsets [n ] + word , shifts [n ]);
@@ -548,22 +562,22 @@ j2ku_sycca_rgba(opj_image_t *in, const JPEG2KTILEINFO *tileinfo,
548
562
}
549
563
550
564
static 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 },
567
581
};
568
582
569
583
/* -------------------------------------------------------------------- */
@@ -589,7 +603,7 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
589
603
j2k_unpacker_t unpack = NULL ;
590
604
size_t buffer_size = 0 , tile_bytes = 0 ;
591
605
unsigned n , tile_height , tile_width ;
592
- int components ;
606
+ int components , subsampling ;
593
607
594
608
595
609
stream = opj_stream_create (BUFFER_SIZE , OPJ_TRUE );
@@ -652,11 +666,16 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
652
666
goto quick_exit ;
653
667
}
654
668
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 ) {
656
676
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 ;
660
679
}
661
680
}
662
681
@@ -672,12 +691,14 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
672
691
673
692
If colorspace is unspecified, we assume:
674
693
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)
681
702
682
703
*/
683
704
@@ -686,14 +707,23 @@ j2k_decode_entry(Imaging im, ImagingCodecState state)
686
707
687
708
if (color_space == OPJ_CLRSPC_UNSPECIFIED ) {
688
709
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 ;
691
720
}
692
721
}
693
722
694
723
for (n = 0 ; n < sizeof (j2k_unpackers ) / sizeof (j2k_unpackers [0 ]); ++ n ) {
695
724
if (color_space == j2k_unpackers [n ].color_space
696
725
&& image -> numcomps == j2k_unpackers [n ].components
726
+ && (j2k_unpackers [n ].subsampling || (subsampling == -1 ))
697
727
&& strcmp (im -> mode , j2k_unpackers [n ].mode ) == 0 ) {
698
728
unpack = j2k_unpackers [n ].unpacker ;
699
729
break ;
0 commit comments