@@ -81,9 +81,11 @@ typedef struct {
8181 int height ; // size[1];
8282 int bits ; // one of: 8, 10, 12.
8383 int alpha ; // one of: 0, 1.
84- char mode [8 ]; // one of: RGB, RGBA, RGBa, BGR, BGRA, BGRa + Optional[;10/12/16]
84+ char mode [8 ]; // one of: L, RGB, RGBA, RGBa, BGR, BGRA, BGRa + Optional[;10/12/16]
8585 int n_channels ; // 1, 2, 3, 4.
8686 int primary ; // one of: 0, 1.
87+ enum heif_colorspace colorspace ;
88+ enum heif_chroma chroma ;
8789 int hdr_to_8bit ; // private. decode option.
8890 int bgr_mode ; // private. decode option.
8991 int remove_stride ; // private. decode option.
@@ -767,6 +769,8 @@ PyObject* _CtxDepthImage(struct heif_image_handle* main_handle, heif_item_id dep
767769 }
768770 ctx_image -> hdr_to_8bit = 0 ;
769771 ctx_image -> bgr_mode = 0 ;
772+ ctx_image -> colorspace = heif_colorspace_monochrome ;
773+ ctx_image -> chroma = heif_chroma_monochrome ;
770774 ctx_image -> handle = depth_handle ;
771775 ctx_image -> heif_image = NULL ;
772776 ctx_image -> data = NULL ;
@@ -795,7 +799,9 @@ static void _CtxImage_destructor(CtxImageObject* self) {
795799PyObject * _CtxImage (struct heif_image_handle * handle , int hdr_to_8bit ,
796800 int bgr_mode , int remove_stride , int hdr_to_16bit ,
797801 int reload_size , int primary , PyObject * file_bytes ,
798- const char * decoder_id ) {
802+ const char * decoder_id ,
803+ enum heif_colorspace colorspace , enum heif_chroma chroma
804+ ) {
799805 CtxImageObject * ctx_image = PyObject_New (CtxImageObject , & CtxImage_Type );
800806 if (!ctx_image ) {
801807 heif_image_handle_release (handle );
@@ -805,23 +811,41 @@ PyObject* _CtxImage(struct heif_image_handle* handle, int hdr_to_8bit,
805811 ctx_image -> image_type = PhHeifImage ;
806812 ctx_image -> width = heif_image_handle_get_width (handle );
807813 ctx_image -> height = heif_image_handle_get_height (handle );
808- strcpy (ctx_image -> mode , bgr_mode ? "BGR" : "RGB" );
809814 ctx_image -> alpha = heif_image_handle_has_alpha_channel (handle );
810- ctx_image -> n_channels = 3 ;
811- if (ctx_image -> alpha ) {
812- strcat (ctx_image -> mode , heif_image_handle_is_premultiplied_alpha (handle ) ? "a" : "A" );
813- ctx_image -> n_channels = 4 ;
814- }
815815 ctx_image -> bits = heif_image_handle_get_luma_bits_per_pixel (handle );
816- if ((ctx_image -> bits > 8 ) && (!hdr_to_8bit )) {
817- if (hdr_to_16bit ) {
818- strcat (ctx_image -> mode , ";16" );
816+ if ((chroma == heif_chroma_monochrome ) && (colorspace == heif_colorspace_monochrome ) && (!ctx_image -> alpha )) {
817+ strcpy (ctx_image -> mode , "L" );
818+ if (ctx_image -> bits > 8 ) {
819+ if (hdr_to_16bit ) {
820+ strcpy (ctx_image -> mode , "I;16" );
821+ }
822+ else if (ctx_image -> bits == 10 ) {
823+ strcpy (ctx_image -> mode , "I;10" );
824+ }
825+ else {
826+ strcpy (ctx_image -> mode , "I;12" );
827+ }
819828 }
820- else if (ctx_image -> bits == 10 ) {
821- strcat (ctx_image -> mode , ";10" );
829+ ctx_image -> n_channels = 1 ;
830+ bgr_mode = 0 ;
831+ hdr_to_8bit = 0 ;
832+ } else {
833+ strcpy (ctx_image -> mode , bgr_mode ? "BGR" : "RGB" );
834+ ctx_image -> n_channels = 3 ;
835+ if (ctx_image -> alpha ) {
836+ strcat (ctx_image -> mode , heif_image_handle_is_premultiplied_alpha (handle ) ? "a" : "A" );
837+ ctx_image -> n_channels += 1 ;
822838 }
823- else {
824- strcat (ctx_image -> mode , ";12" );
839+ if ((ctx_image -> bits > 8 ) && (!hdr_to_8bit )) {
840+ if (hdr_to_16bit ) {
841+ strcat (ctx_image -> mode , ";16" );
842+ }
843+ else if (ctx_image -> bits == 10 ) {
844+ strcat (ctx_image -> mode , ";10" );
845+ }
846+ else {
847+ strcat (ctx_image -> mode , ";12" );
848+ }
825849 }
826850 }
827851 ctx_image -> hdr_to_8bit = hdr_to_8bit ;
@@ -833,6 +857,8 @@ PyObject* _CtxImage(struct heif_image_handle* handle, int hdr_to_8bit,
833857 ctx_image -> hdr_to_16bit = hdr_to_16bit ;
834858 ctx_image -> reload_size = reload_size ;
835859 ctx_image -> primary = primary ;
860+ ctx_image -> colorspace = colorspace ;
861+ ctx_image -> chroma = chroma ;
836862 ctx_image -> file_bytes = file_bytes ;
837863 ctx_image -> stride = get_stride (ctx_image );
838864 strcpy (ctx_image -> decoder_id , decoder_id );
@@ -852,6 +878,14 @@ static PyObject* _CtxImage_bit_depth(CtxImageObject* self, void* closure) {
852878 return Py_BuildValue ("i" , self -> bits );
853879}
854880
881+ static PyObject * _CtxImage_colorspace (CtxImageObject * self , void * closure ) {
882+ return Py_BuildValue ("i" , self -> colorspace );
883+ }
884+
885+ static PyObject * _CtxImage_chroma (CtxImageObject * self , void * closure ) {
886+ return Py_BuildValue ("i" , self -> chroma );
887+ }
888+
855889static PyObject * _CtxImage_color_profile (CtxImageObject * self , void * closure ) {
856890 enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type (self -> handle );
857891 if (profile_type == heif_color_profile_type_not_present )
@@ -1155,6 +1189,8 @@ static struct PyGetSetDef _CtxImage_getseters[] = {
11551189 {"size_mode" , (getter )_CtxImage_size_mode , NULL , NULL , NULL },
11561190 {"primary" , (getter )_CtxImage_primary , NULL , NULL , NULL },
11571191 {"bit_depth" , (getter )_CtxImage_bit_depth , NULL , NULL , NULL },
1192+ {"colorspace" , (getter )_CtxImage_colorspace , NULL , NULL , NULL },
1193+ {"chroma" , (getter )_CtxImage_chroma , NULL , NULL , NULL },
11581194 {"color_profile" , (getter )_CtxImage_color_profile , NULL , NULL , NULL },
11591195 {"metadata" , (getter )_CtxImage_metadata , NULL , NULL , NULL },
11601196 {"thumbnails" , (getter )_CtxImage_thumbnails , NULL , NULL , NULL },
@@ -1264,6 +1300,8 @@ static PyObject* _load_file(PyObject* self, PyObject* args) {
12641300 return NULL ;
12651301 }
12661302
1303+ enum heif_colorspace colorspace ;
1304+ enum heif_chroma chroma ;
12671305 struct heif_image_handle * handle ;
12681306 struct heif_error error ;
12691307 for (int i = 0 ; i < n_images ; i ++ ) {
@@ -1274,13 +1312,19 @@ static PyObject* _load_file(PyObject* self, PyObject* args) {
12741312 }
12751313 else
12761314 error = heif_context_get_image_handle (heif_ctx , images_ids [i ], & handle );
1277- if (error .code == heif_error_Ok )
1278- PyList_SET_ITEM (images_list ,
1279- i ,
1280- _CtxImage (handle , hdr_to_8bit ,
1315+ if (error .code == heif_error_Ok ) {
1316+ error = heif_image_handle_get_preferred_decoding_colorspace (handle , & colorspace , & chroma );
1317+ if (error .code == heif_error_Ok ) {
1318+ PyList_SET_ITEM (images_list ,
1319+ i ,
1320+ _CtxImage (handle , hdr_to_8bit ,
12811321 bgr_mode , remove_stride , hdr_to_16bit , reload_size , primary , heif_bytes ,
1282- decoder_id ));
1283- else {
1322+ decoder_id , colorspace , chroma ));
1323+ } else {
1324+ heif_image_handle_release (handle );
1325+ }
1326+ }
1327+ if (error .code != heif_error_Ok ) {
12841328 Py_INCREF (Py_None );
12851329 PyList_SET_ITEM (images_list , i , Py_None );
12861330 }
0 commit comments