# HG changeset patch # User magedrifaat # Date 1660255477 -7200 # Node ID 48d46f7a640bf77cc7826c241d44f0f8bcf30f6e # Parent 3155aa74c62efaed32cfeb2d7109be64b1cfe7df Tiff setTag: handled scalar tags with the correct data type. diff -r 3155aa74c62e -r 48d46f7a640b libinterp/corefcn/__tiff__.cc --- a/libinterp/corefcn/__tiff__.cc Wed Aug 10 23:55:33 2022 +0200 +++ b/libinterp/corefcn/__tiff__.cc Fri Aug 12 00:04:37 2022 +0200 @@ -854,6 +854,8 @@ } case TIFF_RATIONAL: { + // TODO(maged): This is incorrect, LibTIFF already handles + // rationals and converts them to floats NDArray arr (arr_dims); for (uint32_t i = 0; i < count; i+=2) { @@ -1178,10 +1180,193 @@ } void + set_scalar_field_data (TIFF *tif, const TIFFField *fip, octave_value tag_ov) + { + uint32_t tag_id = TIFFFieldTag (fip); + + // Since scalar tags are the last to be handled, any tag that + // require a count to be passed is an unsupported tag. + if (TIFFFieldPassCount (fip)) + error ("Unsupported tag"); + + TIFFDataType tag_datatype = TIFFFieldDataType (fip); + switch (tag_datatype) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + // TODO(maged): check if matlab errors for long data type/range + TIFFSetField (tif, tag_id, tag_ov.uint8_scalar_value ()); + break; + case TIFF_SHORT: + TIFFSetField (tif, tag_id, tag_ov.uint16_scalar_value ()); + break; + case TIFF_LONG: + TIFFSetField (tif, tag_id, tag_ov.uint32_scalar_value ()); + break; + case TIFF_LONG8: + TIFFSetField (tif, tag_id, tag_ov.uint64_scalar_value ()); + break; + case TIFF_RATIONAL: + TIFFSetField (tif, tag_id, tag_ov.float_scalar_value ()); + break; + case TIFF_SBYTE: + TIFFSetField (tif, tag_id, tag_ov.int8_scalar_value ()); + break; + case TIFF_SSHORT: + TIFFSetField (tif, tag_id, tag_ov.int16_scalar_value ()); + break; + case TIFF_SLONG: + TIFFSetField (tif, tag_id, tag_ov.int32_scalar_value ()); + break; + case TIFF_SLONG8: + TIFFSetField (tif, tag_id, tag_ov.int64_scalar_value ()); + break; + case TIFF_FLOAT: + TIFFSetField (tif, tag_id, tag_ov.float_scalar_value ()); + break; + case TIFF_DOUBLE: + TIFFSetField (tif, tag_id, tag_ov.double_value ()); + break; + case TIFF_SRATIONAL: + TIFFSetField (tif, tag_id, tag_ov.float_scalar_value ()); + break; + case TIFF_IFD: + case TIFF_IFD8: + error ("Unimplemented IFFD data type"); + break; + default: + error ("Unsupported tag data type"); + } + } + + void + set_array_field_data (TIFF *tif, const TIFFField *fip, + octave_value tag_ov, uint32_t count) + { + } + + void set_field_data (TIFF *tif, const TIFFField *fip, octave_value tag_ov) { // TODO(maged): complete the implementation of this function uint32_t tag_id = TIFFFieldTag (fip); + + // TODO(maged): find/create images to test the special tags + switch (tag_id) + { + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_STRIPOFFSETS: + set_array_field_data (tif, fip, tag_ov, TIFFNumberOfStrips (tif)); + break; + case TIFFTAG_TILEBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + set_array_field_data (tif, fip, tag_ov, TIFFNumberOfTiles (tif)); + break; + case TIFFTAG_YCBCRCOEFFICIENTS: + set_array_field_data (tif, fip, tag_ov, 3); + break; + case TIFFTAG_REFERENCEBLACKWHITE: + set_array_field_data (tif, fip, tag_ov, 6); + break; + case TIFFTAG_GRAYRESPONSECURVE: + { + uint16_t bits_per_sample; + if (! TIFFGetFieldDefaulted (tif, TIFFTAG_BITSPERSAMPLE, + &bits_per_sample)) + error ("Failed to obtain the bit depth"); + + set_array_field_data (tif, fip, tag_ov, 1< 16) + error ("Too high bit depth for a palette image"); + + uint32_t count = 1 << bits_per_sample; + // uint16_t *red, *green, *blue; + // validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, + // &red, &green, &blue)); + break; + } + case TIFFTAG_TRANSFERFUNCTION: + { + uint16_t samples_per_pixel; + if (! TIFFGetFieldDefaulted (tif, TIFFTAG_SAMPLESPERPIXEL, + &samples_per_pixel)) + error ("Failed to obtain the number of samples per pixel"); + + uint16_t bits_per_sample; + if (! TIFFGetFieldDefaulted (tif, TIFFTAG_BITSPERSAMPLE, + &bits_per_sample)) + error ("Failed to obtain the number of samples per pixel"); + + uint32_t count = 1 << bits_per_sample; + uint16_t *ch1, *ch2, *ch3; + if (samples_per_pixel == 1) + { + // validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, &ch1)); + } + else + { + // validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, + // &ch1, &ch2, &ch3)); + } + break; + } + case TIFFTAG_PAGENUMBER: + case TIFFTAG_HALFTONEHINTS: + case TIFFTAG_DOTRANGE: + case TIFFTAG_YCBCRSUBSAMPLING: + { + uint16_t tag_part1, tag_part2; + // validate_tiff_get_field (TIFFGetField (tif, tag_id, + // &tag_part1, &tag_part2)); + break; + } + case TIFFTAG_SUBIFD: + { + uint16_t count; + uint64_t *offsets; + // validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &offsets)); + break; + } + case TIFFTAG_EXTRASAMPLES: + { + uint16_t count; + uint16_t *types; + // validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &types)); + break; + } + // TODO(maged): These tags are more complex to implement + // will be implemented and tested later. + case TIFFTAG_XMLPACKET: + case TIFFTAG_RICHTIFFIPTC: + case TIFFTAG_PHOTOSHOP: + case TIFFTAG_ICCPROFILE: + { + error ("Complex Tags not implemented"); + break; + } + // These tags are not mentioned in the LibTIFF documentation + // but are handled correctly by the library + case TIFFTAG_ZIPQUALITY: + case TIFFTAG_SGILOGDATAFMT: + case TIFFTAG_GRAYRESPONSEUNIT: + { + set_scalar_field_data (tif, fip, tag_ov); + break; + } + default: + set_scalar_field_data (tif, fip, tag_ov); + } uint32_t tag_data = tag_ov.double_value (); if (! TIFFSetField(tif, tag_id, tag_data))