Mercurial > octave-libtiff
diff libinterp/corefcn/__tiff__.cc @ 31198:93eb0d6e7f62
__tiff_imwrite__: converted to private octave function
* libinterp/corefcn/__tiff__.cc: removed internal function __tiff_imwrite__.
* scripts/image/private/__tiff_imwrite__.m: added private function
__tiff_imwrite__.
* scripts/image/module.mk: added entry for __tiff_imwrite__.m.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Fri, 02 Sep 2022 03:06:29 +0200 |
parents | 1604c8812b67 |
children | 30b28458bb06 |
line wrap: on
line diff
--- a/libinterp/corefcn/__tiff__.cc Thu Sep 01 01:56:20 2022 +0200 +++ b/libinterp/corefcn/__tiff__.cc Fri Sep 02 03:06:29 2022 +0200 @@ -128,13 +128,6 @@ } } - bool - is_colormap (octave_value ov) - { - return ov.isnumeric () && ov.isreal () && ov.isfloat () - && ov.ndims () == 2 && ov.columns () == 3; - } - // A map of tag names supported by matlab, there are some differences // than LibTIFF's names (e.g. Photometric vs PhotometricInterpretation) static const std::map<std::string, ttag_t> tag_name_map = { @@ -3584,261 +3577,6 @@ #endif } - DEFUN (__tiff_imwrite__, args, , - "Handler for imwrite that uses Tiff interface") - { -#if defined (HAVE_TIFF) - int nargin = args.length (); - - if (nargin < 2) - error ("imwrite: Wrong number of arguments"); - - if (! (args(0).isnumeric () || args(0).is_bool_matrix () - || args(0).is_bool_scalar ())) - error ("imwrite: Expected image matrix as first argument"); - - // The argument checks here are very similar to the ones found in - // __imwrite__.m and imwrite_filename.m, the code is duplicated here since - // the original code is tailored to the generic library graphicsmagick - // so it is not suitable to be used directly for this case - uint16_t offset = 1; - std::string filename; - octave_value cmap = octave_value (NDArray ()); - if (args(1).is_string ()) - { - filename = args(1).string_value (); - offset++; - } - else if (nargin > 2 && is_colormap (args(1)) && args(2).is_string ()) - { - filename = args(2).string_value (); - cmap = args(1); - offset += 2; - } - else - error ("imwrite: no FILENAME specified"); - - filename = sys::file_ops::tilde_expand (filename); - - if (nargin > offset && (nargin - offset) % 2 != 0 - && args(offset).is_string ()) - offset++; - - if ((nargin - offset) % 2 != 0) - error ("imwrite: no pair for all arguments (odd number left)"); - - // Setting the default value for the rest of the parameters - bool append = false; - uint16_t compression = COMPRESSION_NONE; - uint32_t rows_per_strip = UINT32_MAX; - float x_res = 72, y_res = 72; - std::string description = ""; - - // Extract the values for the paramters provided - for (uint16_t arg_idx = offset; arg_idx < nargin; arg_idx+=2) - { - if (! args(arg_idx).is_string ()) - error ("imwrite: PARAM in PARAM/VALUE pair must be string"); - - const char *param_cstr = args(arg_idx).string_value ().c_str (); - if (strcasecmp (param_cstr, "colorspace") == 0) - { - // Matlab specifies three colorspaces: RGB, CIELAB and ICCLAB. - // Of the three, only RGB is currently supported so this tag - // can be ignored. - } - else if (strcasecmp (param_cstr, "compression") == 0) - { - if (! args(arg_idx + 1).is_string ()) - error ("imwrite: value for %s option must be a string", - param_cstr); - std::string comp = args(arg_idx + 1).string_value (); - if (comp == "packbits") - compression = COMPRESSION_PACKBITS; - else if (comp == "lzw") - compression = COMPRESSION_LZW; - else if (comp == "deflate") - compression = COMPRESSION_DEFLATE; - else if (comp == "jpeg") - compression = COMPRESSION_JPEG; - else if (comp == "ccitt") - compression = COMPRESSION_CCITTRLE; - else if (comp == "fax3") - compression = COMPRESSION_CCITTFAX3; - else if (comp == "fax4") - compression = COMPRESSION_CCITTFAX4; - else - error ("imwrite: invalid compression '%s'", comp.c_str ()); - } - else if (strcasecmp (param_cstr, "Description") == 0) - { - if (! args(arg_idx + 1).is_string ()) - error ("imwrite: value for %s option must be a string", - param_cstr); - description = args(arg_idx + 1).string_value (); - } - else if (strcasecmp (param_cstr, "resolution") == 0) - { - if (! args(arg_idx + 1).isnumeric ()) - error ("imwrite: value for %s option must be numeric", - param_cstr); - NDArray res = args(arg_idx + 1).array_value (); - if (res.numel () == 1) - { - x_res = res(0); - y_res = res(0); - } - else if (res.numel () == 2) - { - x_res = res(0); - y_res = res(1); - } - else - error ("imwrite: value for %s option must be either a scalar value or a two-element vector", - param_cstr); - } - else if (strcasecmp (param_cstr, "RowsPerStrip") == 0) - { - if (! args(arg_idx + 1).isnumeric () - || ! args(arg_idx + 1).is_scalar_type ()) - error ("imwrite: value for %s option must be a scalar value", - param_cstr); - rows_per_strip = args(arg_idx + 1).uint32_scalar_value (); - } - else if (strcasecmp (param_cstr, "WriteMode") == 0) - { - if (! args(arg_idx + 1).is_string ()) - error ("imwrite: value for %s option must be a string", - param_cstr); - std::string wmode = args(arg_idx + 1).string_value (); - if (wmode == "overwrite") - append = false; - else if (wmode == "append") - append = true; - else - error ("imwrite: value for %s option must be either 'overwrite' or 'append'", - param_cstr); - } - else - error ("imread: invalid PARAMETER '%s'", param_cstr); - } - - // Matlab specifies that JPEG compression must also specify RowsPerStrip - // and must be a value divisible by 8 - if (compression == COMPRESSION_JPEG - && (rows_per_strip == UINT32_MAX || rows_per_strip % 8 != 0)) - error ("imwrite: RowsPerStrip option must be specified for jpeg compression and must be divisible by 8"); - - // These compression schemes are only available for binary images - if (! (args(0).is_bool_matrix () || args(0).is_bool_scalar ()) - && (compression == COMPRESSION_CCITTRLE - || compression == COMPRESSION_CCITTFAX3 - || compression == COMPRESSION_CCITTFAX4)) - error ("imwrite: the specified compression scheme is for binary images only"); - - // Matlab rejects 4D data for TIFF images - dim_vector img_dims = args(0).dims (); - if (args(0).ndims () != 2 && args(0).ndims () != 3) - error ("imwrite: expected 2-dimensional or 3-dimensional image matrix"); - - if (args(0).ndims () > 2 && img_dims(2) > 1 && cmap.numel () > 0) - error ("imwrite: palette images must be 1 channel only"); - - TIFF *tif; - if (append) - tif = TIFFOpen (filename.c_str (), "a"); - else - tif = TIFFOpen (filename.c_str (), "w"); - - if (! tif) - error ("Failed to open file %s", filename.c_str ()); - - // A simple way to make sure the file will be closed when the function - // returns or when an error occurs as the destructor will always be called - octave_tiff_handle tiff_handle (tif); - - // Set all necessary tags - if (! TIFFSetField (tif, TIFFTAG_IMAGELENGTH, - static_cast<uint32_t>(img_dims(0))) - || ! TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, - static_cast<uint32_t>(img_dims(1)))) - error ("Failed to set image dimensions"); - - if (img_dims.ndims () > 2) - if (! TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, img_dims(2))) - error ("Failed to set the number of samples"); - - if (! TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) - error ("Failed to set the planar configuration"); - - if (! TIFFSetField (tif, TIFFTAG_COMPRESSION, compression)) - error ("Failed to set the compressoin tag"); - - if (! TIFFSetField (tif, TIFFTAG_XRESOLUTION, x_res) - || ! TIFFSetField (tif, TIFFTAG_YRESOLUTION, y_res)) - error ("Failed to set resolution tag"); - - if (! TIFFSetField (tif, TIFFTAG_IMAGEDESCRIPTION, description.c_str ())) - error ("Failed to set description tag"); - - if (rows_per_strip == UINT32_MAX) - rows_per_strip = TIFFDefaultStripSize (tif, 0); - - if (! TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, rows_per_strip)) - error ("Failed to set the RowsPerStrip tag"); - - uint16_t bits_per_sample; - if (args(0).is_bool_matrix () || args(0).is_bool_scalar ()) - bits_per_sample = 1; - else if (args(0).is_uint8_type ()) - bits_per_sample = 8; - else if (args(0).is_uint16_type ()) - bits_per_sample = 16; - else if (args(0).is_uint32_type () || args(0).is_single_type ()) - bits_per_sample = 32; - else if (args(0).is_double_type ()) - bits_per_sample = 64; - else - error ("imwrite: unsupported image data type"); - - if (! TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample)) - error ("Failed to set BitsPerSample tag"); - - // Infer the photometric interpretation of the image from the color map - // and the number of channels of the input - uint16_t photometric = PHOTOMETRIC_MINISBLACK; - if (cmap.numel () > 0) - { - photometric = PHOTOMETRIC_PALETTE; - set_field_data (tif, TIFFFieldWithTag (tif, TIFFTAG_COLORMAP), - cmap); - } - else if (img_dims(2) == 3) - photometric = PHOTOMETRIC_RGB; - else if (img_dims(2) == 4) - photometric = PHOTOMETRIC_SEPARATED; - - if (! TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, photometric)) - error ("Failed to set the photometric tag"); - - tiff_image_data image_data (tif); - if (args(0).is_bool_scalar () || args(0).is_bool_matrix () - || args(0).is_uint8_type () || args(0).is_uint16_type () - || args(0).is_uint32_type ()) - write_unsigned_image (tif, args(0), &image_data); - else - { - if (!TIFFSetField (tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP)) - error ("Failed to set SampleFormat tag"); - write_float_image (tif, args(0).as_double (), &image_data); - } - - return octave_value_list (); -#else - err_disabled_feature ("imwrite", "Tiff"); -#endif - } - DEFUN (__tiff_imfinfo__, args, , "Handler for imfinfo that uses Tiff interface") {