@@ -626,13 +626,17 @@ vips_thumbnail_build( VipsObject *object )
626
626
int preshrunk_page_height ;
627
627
double hshrink ;
628
628
double vshrink ;
629
- VipsInterpretation interpretation ;
630
629
631
630
/* TRUE if we've done the import of an ICC transform and still need to
632
631
* export.
633
632
*/
634
633
gboolean have_imported ;
635
634
635
+ /* If we shrink in linear space, we need to return to the input
636
+ * colourspace after the shrink.
637
+ */
638
+ VipsInterpretation input_interpretation ;
639
+
636
640
/* TRUE if we've premultiplied and need to unpremultiply.
637
641
*/
638
642
gboolean have_premultiplied ;
@@ -669,7 +673,7 @@ vips_thumbnail_build( VipsObject *object )
669
673
*/
670
674
preshrunk_page_height = vips_image_get_page_height ( in );
671
675
672
- /* RAD needs special unpacking.
676
+ /* Coded forms need special unpacking.
673
677
*/
674
678
if ( in -> Coding == VIPS_CODING_RAD ) {
675
679
g_info ( "unpacking Rad to float" );
@@ -680,62 +684,69 @@ vips_thumbnail_build( VipsObject *object )
680
684
return ( -1 );
681
685
in = t [12 ];
682
686
}
687
+ else if ( in -> Coding == VIPS_CODING_LABQ ) {
688
+ g_info ( "unpacking LABQ to float" );
683
689
684
- /* In linear mode, we import right at the start.
685
- *
686
- * We also have to import the whole image if it's CMYK, since
687
- * vips_colourspace() (see below) doesn't let you specify the fallback
688
- * profile.
690
+ if ( vips_LabQ2Lab ( in , & t [12 ], NULL ) )
691
+ return ( -1 );
692
+ in = t [12 ];
693
+ }
694
+
695
+ /* In linear mode, we need to transform to a linear space before
696
+ * vips_resize().
689
697
*
690
- * This is only going to work for images in device space. If you have
691
- * an image in PCS which also has an attached profile, strange things
692
- * will happen.
698
+ * If we are doing colour management (there's an import profile),
699
+ * then we use XYZ PCS as the resize space.
693
700
*/
694
701
have_imported = FALSE;
695
- if ( thumbnail -> linear &&
696
- in -> Coding == VIPS_CODING_NONE &&
697
- (in -> BandFmt == VIPS_FORMAT_UCHAR ||
698
- in -> BandFmt == VIPS_FORMAT_USHORT ) &&
699
- (vips_image_get_typeof ( in , VIPS_META_ICC_NAME ) ||
700
- thumbnail -> import_profile ) ) {
701
- g_info ( "importing to XYZ PCS" );
702
- if ( thumbnail -> import_profile )
703
- g_info ( "fallback input profile %s" ,
704
- thumbnail -> import_profile );
705
-
706
- if ( vips_icc_import ( in , & t [1 ],
707
- "input_profile" , thumbnail -> import_profile ,
708
- "embedded" , TRUE,
709
- "intent" , thumbnail -> intent ,
710
- "pcs" , VIPS_PCS_XYZ ,
711
- NULL ) )
712
- return ( -1 );
702
+ if ( thumbnail -> linear ) {
703
+ if ( in -> Coding == VIPS_CODING_NONE &&
704
+ (in -> BandFmt == VIPS_FORMAT_UCHAR ||
705
+ in -> BandFmt == VIPS_FORMAT_USHORT ) &&
706
+ (vips_image_get_typeof ( in , VIPS_META_ICC_NAME ) ||
707
+ thumbnail -> import_profile ) ) {
708
+ g_info ( "importing to XYZ PCS" );
709
+ if ( thumbnail -> import_profile )
710
+ g_info ( "fallback input profile %s" ,
711
+ thumbnail -> import_profile );
712
+
713
+ if ( vips_icc_import ( in , & t [1 ],
714
+ "input_profile" , thumbnail -> import_profile ,
715
+ "embedded" , TRUE,
716
+ "intent" , thumbnail -> intent ,
717
+ "pcs" , VIPS_PCS_XYZ ,
718
+ NULL ) )
719
+ return ( -1 );
713
720
714
- in = t [1 ];
721
+ in = t [1 ];
715
722
716
- have_imported = TRUE;
723
+ have_imported = TRUE;
724
+ }
725
+ else {
726
+ /* Otherwise, use scRGB or GREY16 for linear shrink.
727
+ */
728
+ VipsInterpretation interpretation ;
729
+
730
+ /* Note the interpretation we will revert to after
731
+ * linear.
732
+ */
733
+ input_interpretation = in -> Type ;
734
+
735
+ if ( in -> Bands < 3 )
736
+ interpretation = VIPS_INTERPRETATION_GREY16 ;
737
+ else
738
+ interpretation = VIPS_INTERPRETATION_scRGB ;
739
+
740
+ g_info ( "converting to processing space %s" ,
741
+ vips_enum_nick ( VIPS_TYPE_INTERPRETATION ,
742
+ interpretation ) );
743
+ if ( vips_colourspace ( in , & t [2 ], interpretation ,
744
+ NULL ) )
745
+ return ( -1 );
746
+ in = t [2 ];
747
+ }
717
748
}
718
749
719
- /* To the processing colourspace. This will unpack LABQ, import CMYK,
720
- * etc.
721
- *
722
- * If this is a CMYK image, we need to set have_imported since we only
723
- * want to export at the end.
724
- */
725
- if ( in -> Type == VIPS_INTERPRETATION_CMYK )
726
- have_imported = TRUE;
727
- if ( thumbnail -> linear )
728
- interpretation = VIPS_INTERPRETATION_scRGB ;
729
- else if ( in -> Bands < 3 )
730
- interpretation = VIPS_INTERPRETATION_B_W ;
731
- else
732
- interpretation = VIPS_INTERPRETATION_sRGB ;
733
- g_info ( "converting to processing space %s" ,
734
- vips_enum_nick ( VIPS_TYPE_INTERPRETATION , interpretation ) );
735
- if ( vips_colourspace ( in , & t [2 ], interpretation , NULL ) )
736
- return ( -1 );
737
- in = t [2 ];
738
-
739
750
/* Shrink to preshrunk_page_height, so we work for multi-page images.
740
751
*/
741
752
vips_thumbnail_calculate_shrink ( thumbnail ,
@@ -767,7 +778,7 @@ vips_thumbnail_build( VipsObject *object )
767
778
768
779
/* vips_premultiply() makes a float image. When we
769
780
* vips_unpremultiply() below, we need to cast back to the
770
- * pre-premultiply format.
781
+ * pre-premultiplied format.
771
782
*/
772
783
unpremultiplied_format = in -> BandFmt ;
773
784
in = t [3 ];
@@ -779,6 +790,14 @@ vips_thumbnail_build( VipsObject *object )
779
790
return ( -1 );
780
791
in = t [4 ];
781
792
793
+ if ( have_premultiplied ) {
794
+ g_info ( "unpremultiplying alpha" );
795
+ if ( vips_unpremultiply ( in , & t [5 ], NULL ) ||
796
+ vips_cast ( t [5 ], & t [6 ], unpremultiplied_format , NULL ) )
797
+ return ( -1 );
798
+ in = t [6 ];
799
+ }
800
+
782
801
/* Only set page-height if we have more than one page, or this could
783
802
* accidentally turn into an animated image later.
784
803
*/
@@ -794,21 +813,12 @@ vips_thumbnail_build( VipsObject *object )
794
813
VIPS_META_PAGE_HEIGHT , output_page_height );
795
814
}
796
815
797
- if ( have_premultiplied ) {
798
- g_info ( "unpremultiplying alpha" );
799
- if ( vips_unpremultiply ( in , & t [5 ], NULL ) ||
800
- vips_cast ( t [5 ], & t [6 ], unpremultiplied_format , NULL ) )
801
- return ( -1 );
802
- in = t [6 ];
803
- }
804
-
805
816
/* Colour management.
806
- *
807
- * If we've already imported, just export. Otherwise, we're in
808
- * device space and we need a combined import/export to transform to
809
- * the target space.
810
817
*/
811
818
if ( have_imported ) {
819
+ /* We've already imported, just export. Go to sRGB if there's
820
+ * no export profile.
821
+ */
812
822
if ( thumbnail -> export_profile ||
813
823
vips_image_get_typeof ( in , VIPS_META_ICC_NAME ) ) {
814
824
g_info ( "exporting to device space with a profile" );
@@ -827,9 +837,10 @@ vips_thumbnail_build( VipsObject *object )
827
837
in = t [7 ];
828
838
}
829
839
}
830
- else if ( thumbnail -> export_profile &&
831
- (vips_image_get_typeof ( in , VIPS_META_ICC_NAME ) ||
832
- thumbnail -> import_profile ) ) {
840
+ else if ( thumbnail -> export_profile ) {
841
+ /* Not imported, but we are doing colourmanagement. Transform
842
+ * to the output space.
843
+ */
833
844
g_info ( "transforming to %s" , thumbnail -> export_profile );
834
845
if ( thumbnail -> import_profile )
835
846
g_info ( "fallback input profile %s" ,
@@ -844,6 +855,19 @@ vips_thumbnail_build( VipsObject *object )
844
855
return ( -1 );
845
856
in = t [7 ];
846
857
}
858
+ else if ( thumbnail -> linear ) {
859
+ /* Linear mode, no colour management. We went to scRGB for
860
+ * precessing, so we now revert to the input
861
+ * colourspace.
862
+ */
863
+ g_info ( "reverting to input space %s" ,
864
+ vips_enum_nick ( VIPS_TYPE_INTERPRETATION ,
865
+ input_interpretation ) );
866
+ if ( vips_colourspace ( in , & t [7 ],
867
+ input_interpretation , NULL ) )
868
+ return ( -1 );
869
+ in = t [7 ];
870
+ }
847
871
848
872
if ( thumbnail -> auto_rotate &&
849
873
thumbnail -> orientation != 1 ) {
0 commit comments