26 #if defined (HAVE_CONFIG_H)
41 #if defined (HAVE_MAGICK)
42 # include <Magick++.h>
48 using Magick::Quantum;
53 #if defined (HAVE_MAGICK)
87 bool indexed = (img.classType () == Magick::PseudoClass);
92 const std::string fmt = img.magick ();
97 else if (fmt ==
"PNG")
106 const std::string color_type
107 =
const_cast<Magick::Image&
> (img).attribute (
"PNG:IHDR.color-type-orig");
108 if (! color_type.empty () && color_type !=
"3")
135 && img.channelDepth (Magick::RedChannel) == 1
136 && img.channelDepth (Magick::GreenChannel) == 1
137 && img.channelDepth (Magick::BlueChannel) == 1
138 && img.channelDepth (Magick::CyanChannel) == 1
139 && img.channelDepth (Magick::MagentaChannel) == 1
140 && img.channelDepth (Magick::YellowChannel) == 1
141 && img.channelDepth (Magick::BlackChannel) == 1
142 && img.channelDepth (Magick::OpacityChannel) == 1
143 && img.channelDepth (Magick::GrayChannel) == 1)
156 range<double> output;
163 output = range<double> (value, value);
168 double base = array(0);
169 double limit = array(array.
numel () - 1);
170 double incr = array(1) - base;
171 output = range<double> (base, incr, limit);
174 error (
"__magick_read__: unknown datatype for Region option");
196 m_row_start = rows.base () - 1;
197 m_col_start = cols.base () - 1;
198 m_row_end = rows.max () - 1;
199 m_col_end = cols.max () - 1;
201 m_row_cache = m_row_end - m_row_start + 1;
202 m_col_cache = m_col_end - m_col_start + 1;
204 m_row_shift = m_col_cache * rows.increment ();
205 m_col_shift = m_col_cache * (m_row_cache + rows.increment () - 1) - cols.increment ();
207 m_row_out = rows.numel ();
208 m_col_out = cols.numel ();
275 const Magick::ColorRGB c = img.colorMap (i);
276 cmap(i, 0) = c.red ();
277 cmap(i, 1) = c.green ();
278 cmap(i, 2) = c.blue ();
279 amap(i) = c.alpha ();
287 template <
typename T>
294 typedef typename T::element_type P;
309 T img = T (
dim_vector (nRows, nCols, 1, nFrames));
310 P *img_fvec = img.fortran_vec ();
327 imvec[frameidx(frame)].getConstPixels (col_start, row_start,
328 col_cache, row_cache);
330 const Magick::IndexPacket *pix
331 = imvec[frameidx(frame)].getConstIndexes ();
337 img_fvec[idx++] =
static_cast<P
> (*pix);
354 =
read_maps (
const_cast<Magick::Image&
> (imvec[frameidx(def_elem)]));
359 if (imvec[def_elem].matte () && nargout >= 3)
361 const Matrix amap = maps(1).matrix_value ();
362 const double *amap_fvec = amap.
data ();
371 alpha_fvec[pix] = 1 - amap_fvec[
static_cast<int> (img_fvec[3])];
384 template <
typename T>
391 typedef typename T::element_type P;
433 if (imvec[def_elem].depth () == 32)
436 divisor = MaxRGB / ((uint64_t (1) << imvec[def_elem].depth ()) - 1);
445 Magick::ImageType type = imvec[def_elem].type ();
446 if (type == Magick::BilevelType && imvec[def_elem].matte ())
447 type = Magick::GrayscaleMatteType;
456 if (imvec[0].magick () ==
"PNG")
466 const std::string type_str
467 = imvec[0].attribute (
"PNG:IHDR.color-type-orig");
470 type = Magick::GrayscaleType;
471 else if (type_str ==
"2")
472 type = Magick::TrueColorType;
473 else if (type_str ==
"6")
474 type = Magick::TrueColorMatteType;
475 else if (type_str ==
"4")
476 type = Magick::GrayscaleMatteType;
482 if (imvec[0].matte ())
484 if (type == Magick::GrayscaleType)
485 type = Magick::GrayscaleMatteType;
486 else if (type == Magick::TrueColorType)
487 type = Magick::TrueColorMatteType;
497 case Magick::GrayscaleMatteType:
498 type = Magick::GrayscaleType;
501 case Magick::PaletteMatteType:
502 type = Magick::PaletteType;
505 case Magick::TrueColorMatteType:
506 type = Magick::TrueColorType;
509 case Magick::ColorSeparationMatteType:
510 type = Magick::ColorSeparationType;
523 case Magick::BilevelType:
524 case Magick::GrayscaleType:
526 img = T (
dim_vector (nRows, nCols, 1, nFrames));
527 P *img_fvec = img.fortran_vec ();
534 const Magick::PixelPacket *pix
535 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
536 col_cache, row_cache);
542 img_fvec[idx++] = pix->red / divisor;
551 case Magick::GrayscaleMatteType:
553 img = T (
dim_vector (nRows, nCols, 1, nFrames));
554 T alpha (
dim_vector (nRows, nCols, 1, nFrames));
555 P *img_fvec = img.fortran_vec ();
556 P *a_fvec = alpha.fortran_vec ();
563 const Magick::PixelPacket *pix
564 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
565 col_cache, row_cache);
571 img_fvec[idx] = pix->red / divisor;
572 a_fvec[idx] = (MaxRGB - pix->opacity) / divisor;
583 case Magick::PaletteType:
584 case Magick::TrueColorType:
586 img = T (
dim_vector (nRows, nCols, 3, nFrames));
587 P *img_fvec = img.fortran_vec ();
594 const Magick::PixelPacket *pix
595 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
596 col_cache, row_cache);
600 P *gbuf = img_fvec + color_stride;
601 P *bbuf = img_fvec + color_stride * 2;
607 rbuf[idx] = pix->red / divisor;
608 gbuf[idx] = pix->green / divisor;
609 bbuf[idx] = pix->blue / divisor;
615 img_fvec += frame_stride;
620 case Magick::PaletteMatteType:
621 case Magick::TrueColorMatteType:
623 img = T (
dim_vector (nRows, nCols, 3, nFrames));
624 T alpha (
dim_vector (nRows, nCols, 1, nFrames));
625 P *img_fvec = img.fortran_vec ();
626 P *a_fvec = alpha.fortran_vec ();
637 const Magick::PixelPacket *pix
638 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
639 col_cache, row_cache);
643 P *gbuf = img_fvec + color_stride;
644 P *bbuf = img_fvec + color_stride * 2;
650 rbuf[idx] = pix->red / divisor;
651 gbuf[idx] = pix->green / divisor;
652 bbuf[idx] = pix->blue / divisor;
653 a_fvec[a_idx++] = (MaxRGB - pix->opacity) / divisor;
659 img_fvec += frame_stride;
665 case Magick::ColorSeparationType:
667 img = T (
dim_vector (nRows, nCols, 4, nFrames));
668 P *img_fvec = img.fortran_vec ();
675 const Magick::PixelPacket *pix
676 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
677 col_cache, row_cache);
681 P *mbuf = img_fvec + color_stride;
682 P *ybuf = img_fvec + color_stride * 2;
683 P *kbuf = img_fvec + color_stride * 3;
689 cbuf[idx] = pix->red / divisor;
690 mbuf[idx] = pix->green / divisor;
691 ybuf[idx] = pix->blue / divisor;
692 kbuf[idx] = pix->opacity / divisor;
698 img_fvec += frame_stride;
704 case Magick::ColorSeparationMatteType:
706 img = T (
dim_vector (nRows, nCols, 4, nFrames));
707 T alpha (
dim_vector (nRows, nCols, 1, nFrames));
708 P *img_fvec = img.fortran_vec ();
709 P *a_fvec = alpha.fortran_vec ();
720 const Magick::PixelPacket *pix
721 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
722 col_cache, row_cache);
725 const Magick::IndexPacket *apix
726 = imvec[frameidx(frame)].getConstIndexes ();
730 P *mbuf = img_fvec + color_stride;
731 P *ybuf = img_fvec + color_stride * 2;
732 P *kbuf = img_fvec + color_stride * 3;
738 cbuf[idx] = pix->red / divisor;
739 mbuf[idx] = pix->green / divisor;
740 ybuf[idx] = pix->blue / divisor;
741 kbuf[idx] = pix->opacity / divisor;
742 a_fvec[a_idx++] = (MaxRGB - *apix) / divisor;
748 img_fvec += frame_stride;
755 error (
"__magick_read__: unknown Magick++ image type");
765 read_file (
const std::string& filename, std::vector<Magick::Image>& imvec)
775 Magick::readImages (&imvec, ascii_fname);
777 catch (
const Magick::Warning&
w)
779 warning (
"Magick++ warning: %s",
w.what ());
781 catch (
const Magick::Exception& e)
783 error (
"Magick++ exception: %s", e.what ());
790 static bool initialized =
false;
796 const char *static_locale = setlocale (LC_ALL,
nullptr);
797 const std::string locale = (static_locale ? static_locale :
"");
799 const std::string program_name
800 = sys::env::get_program_invocation_name ();
801 Magick::InitializeMagick (program_name.c_str ());
804 setlocale (LC_ALL, locale.c_str ());
825 if (QuantumDepth < 16)
827 "your version of %s limits images to %d bits per pixel\n",
828 MagickPackageName, QuantumDepth);
836 DEFUN (__magick_read__, args, nargout,
847 #if defined (HAVE_MAGICK)
849 if (args.length () != 2 || ! args(0).is_string ())
855 = args(1).xscalar_map_value (
"__magick_read__: OPTIONS must be a struct");
859 std::vector<Magick::Image> imvec;
860 read_file (args(0).string_value (), imvec);
874 frameidx = indexes.
xint_vector_value (
"__magick_read__: invalid value for Index/Frame");
882 if (frameidx(i) < 0 || frameidx(i) > nFrames - 1)
887 error (
"imread: index/frames specified are outside the number of images");
897 const unsigned int nRows = imvec[frameidx(0)].rows ();
898 const unsigned int nCols = imvec[frameidx(0)].columns ();
902 if (nRows != imvec[frameidx(frame)].rows ()
903 || nCols != imvec[frameidx(frame)].columns ())
905 error (
"imread: all frames must have the same size but frame "
906 "%" OCTAVE_IDX_TYPE_FORMAT
" is different",
916 output = read_indexed_images<boolNDArray> (imvec, frameidx,
919 output = read_indexed_images<uint8NDArray> (imvec, frameidx,
921 else if (depth <= 16)
922 output = read_indexed_images<uint16NDArray> (imvec, frameidx,
925 error (
"imread: indexed images with depths greater than 16-bit are not supported");
931 output = read_images<boolNDArray> (imvec, frameidx, nargout, options);
933 output = read_images<uint8NDArray> (imvec, frameidx, nargout, options);
934 else if (depth <= 16)
935 output = read_images<uint16NDArray> (imvec, frameidx, nargout, options);
936 else if (depth <= 32)
937 output = read_images<FloatNDArray> (imvec, frameidx, nargout, options);
939 error (
"imread: reading of images with %" OCTAVE_IDX_TYPE_FORMAT
940 "-bit depth is not supported", depth);
947 octave_unused_parameter (args);
948 octave_unused_parameter (nargout);
960 #if defined (HAVE_MAGICK)
962 template <
typename T>
966 typedef typename T::element_type P;
970 const P *img_fvec = img.data ();
975 out_fvec[idx] = img_fvec[idx] *
max;
982 template <
typename T>
986 typedef typename T::element_type P;
988 =
sizeof (P) * std::numeric_limits<unsigned char>::digits;
995 const Magick::ImageType& type,
996 const Magick::ClassType& klass)
998 Magick::Image img (Magick::Geometry (nCols, nRows),
"black");
1002 img.classType (klass);
1006 img.depth (bitdepth);
1009 case Magick::GrayscaleMatteType:
1010 case Magick::TrueColorMatteType:
1011 case Magick::ColorSeparationMatteType:
1012 case Magick::PaletteMatteType:
1023 template <
typename T>
1029 typedef typename T::element_type P;
1030 const octave_idx_type nFrames = (img.ndims () < 4 ? 1 : img.dims ()(3));
1038 std::vector<Magick::ColorRGB> colormap;
1040 const double *cmap_fvec = cmap.
data ();
1044 colormap.push_back (Magick::ColorRGB (cmap_fvec[map_idx],
1045 cmap_fvec[map_idx + G_offset],
1046 cmap_fvec[map_idx + B_offset]));
1054 Magick::PaletteType,
1055 Magick::PseudoClass);
1058 m_img.colorMapSize (cmap_size);
1060 m_img.colorMap (map_idx, colormap[map_idx]);
1071 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1072 Magick::IndexPacket *ind = m_img.getIndexes ();
1073 const P *img_fvec = img.data ();
1080 ind[GM_idx] = double (*img_fvec);
1081 pix[GM_idx] = m_img.colorMap (
double (*img_fvec));
1085 GM_idx -= nCols * nRows - 1;
1089 m_img.syncPixels ();
1090 imvec.push_back (m_img);
1102 const Magick::Color white (
"white");
1104 const bool *img_fvec = img.
data ();
1115 Magick::GrayscaleType,
1116 Magick::DirectClass);
1118 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1124 if (img_fvec[img_idx])
1125 pix[GM_idx] = white;
1130 GM_idx -= nCols * nRows - 1;
1133 m_img.syncPixels ();
1136 m_img.type (Magick::BilevelType);
1137 imvec.push_back (m_img);
1141 template <
typename T>
1144 const T& img,
const T& alpha)
1146 typedef typename T::element_type P;
1147 const octave_idx_type channels = (img.ndims () < 3 ? 1 : img.dims ()(2));
1148 const octave_idx_type nFrames = (img.ndims () < 4 ? 1 : img.dims ()(3));
1153 Magick::ImageType type;
1154 const bool has_alpha = ! alpha.isempty ();
1159 type = Magick::GrayscaleMatteType;
1161 type = Magick::GrayscaleType;
1166 type = Magick::TrueColorMatteType;
1168 type = Magick::TrueColorType;
1173 type = Magick::ColorSeparationMatteType;
1175 type = Magick::ColorSeparationType;
1180 error (
"__magick_write__: wrong size on 3rd dimension");
1190 const double divisor =
static_cast<double> ((uint64_t (1) << bitdepth) - 1)
1193 const P *img_fvec = img.data ();
1194 const P *a_fvec = alpha.data ();
1197 case Magick::GrayscaleType:
1205 Magick::DirectClass);
1207 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1213 const double grey =
math::round (
double (*img_fvec) / divisor);
1214 Magick::Color c (grey, grey, grey);
1219 GM_idx -= nCols * nRows - 1;
1222 m_img.syncPixels ();
1223 imvec.push_back (m_img);
1228 case Magick::GrayscaleMatteType:
1236 Magick::DirectClass);
1238 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1244 double grey =
math::round (
double (*img_fvec) / divisor);
1245 Magick::Color c (grey, grey, grey,
1246 MaxRGB -
math::round (
double (*a_fvec) / divisor));
1252 GM_idx -= nCols * nRows - 1;
1255 m_img.syncPixels ();
1256 imvec.push_back (m_img);
1261 case Magick::TrueColorType:
1272 Magick::DirectClass);
1274 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1280 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1281 math::round (
double (img_fvec[G_offset]) / divisor),
1282 math::round (
double (img_fvec[B_offset]) / divisor));
1287 GM_idx -= nCols * nRows - 1;
1290 m_img.syncPixels ();
1291 imvec.push_back (m_img);
1292 img_fvec += B_offset;
1297 case Magick::TrueColorMatteType:
1308 Magick::DirectClass);
1310 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1316 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1317 math::round (
double (img_fvec[G_offset]) / divisor),
1318 math::round (
double (img_fvec[B_offset]) / divisor),
1319 MaxRGB -
math::round (
double (*a_fvec) / divisor));
1325 GM_idx -= nCols * nRows - 1;
1328 m_img.syncPixels ();
1329 imvec.push_back (m_img);
1330 img_fvec += B_offset;
1335 case Magick::ColorSeparationType:
1347 Magick::DirectClass);
1349 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1355 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1356 math::round (
double (img_fvec[M_offset]) / divisor),
1357 math::round (
double (img_fvec[Y_offset]) / divisor),
1358 math::round (
double (img_fvec[K_offset]) / divisor));
1363 GM_idx -= nCols * nRows - 1;
1366 m_img.syncPixels ();
1367 imvec.push_back (m_img);
1368 img_fvec += K_offset;
1373 case Magick::ColorSeparationMatteType:
1385 Magick::DirectClass);
1387 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1388 Magick::IndexPacket *ind = m_img.getIndexes ();
1394 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1395 math::round (
double (img_fvec[M_offset]) / divisor),
1396 math::round (
double (img_fvec[Y_offset]) / divisor),
1397 math::round (
double (img_fvec[K_offset]) / divisor));
1399 ind[GM_idx] = MaxRGB -
math::round (
double (*a_fvec) / divisor);
1404 GM_idx -= nCols * nRows - 1;
1407 m_img.syncPixels ();
1408 imvec.push_back (m_img);
1409 img_fvec += K_offset;
1415 error (
"__magick_write__: unrecognized Magick::ImageType");
1422 static std::map<octave_idx_type, std::string>
1440 static std::map<octave_idx_type, std::string> methods;
1441 if (methods.empty ())
1443 methods[0] =
"doNotSpecify";
1444 methods[1] =
"leaveInPlace";
1445 methods[2] =
"restoreBG";
1446 methods[3] =
"restorePrevious";
1450 static std::map<std::string, octave_idx_type>
1453 static std::map<std::string, octave_idx_type> methods;
1454 if (methods.empty ())
1456 methods[
"donotspecify"] = 0;
1457 methods[
"leaveinplace"] = 1;
1458 methods[
"restorebg"] = 2;
1459 methods[
"restoreprevious"] = 3;
1466 const std::string& ext,
1467 std::vector<Magick::Image>& imvec)
1471 Magick::writeImages (imvec.begin (), imvec.end (), ext +
':' + filename);
1473 catch (
const Magick::Warning&
w)
1475 warning (
"Magick++ warning: %s",
w.what ());
1477 catch (
const Magick::ErrorCoder& e)
1479 warning (
"Magick++ coder error: %s", e.what ());
1481 catch (
const Magick::Exception& e)
1483 error (
"Magick++ exception: %s", e.what ());
1489 DEFUN (__magick_write__, args, ,
1500 #if defined (HAVE_MAGICK)
1502 if (args.length () != 5 || ! args(0).is_string () || ! args(1).is_string ())
1507 const std::string filename = args(0).string_value ();
1508 const std::string ext = args(1).string_value ();
1511 = args(4).xscalar_map_value (
"__magick_write__: OPTIONS must be a struct");
1514 const Matrix cmap = args(3).xmatrix_value (
"__magick_write__: invalid MAP");
1516 std::vector<Magick::Image> imvec;
1543 clip_img = img_float2uint<FloatNDArray>
1545 clip_alpha = img_float2uint<FloatNDArray>
1550 clip_img = img_float2uint<NDArray> (img.
array_value ());
1551 clip_alpha = img_float2uint<NDArray> (alpha.
array_value ());
1553 encode_uint_image<uint32NDArray> (imvec, clip_img, clip_alpha);
1556 error (
"__magick_write__: image type not supported");
1570 error (
"__magick_write__: indexed image must be uint8, uint16 or float");
1572 static std::map<std::string, octave_idx_type> disposal_methods
1584 imvec[i].quality (quality);
1585 imvec[i].animationDelay (delaytime(i));
1586 imvec[i].gifDisposeMethod (disposal_methods[disposalmethod(i)]);
1592 if (writemode ==
"append" && sys::file_stat (filename).exists ())
1594 std::vector<Magick::Image> ini_imvec;
1597 if (ini_imvec.size () > 0)
1599 ini_imvec.insert (ini_imvec.end (), imvec.begin (), imvec.end ());
1600 ini_imvec.swap (imvec);
1630 const std::string compression
1633 #define COMPRESS_MAGICK_IMAGE_VECTOR(GM_TYPE) \
1634 for (std::vector<Magick::Image>::size_type i = 0; i < imvec.size (); i++) \
1635 imvec[i].compressType (GM_TYPE)
1637 if (compression ==
"none")
1639 else if (compression ==
"bzip")
1641 else if (compression ==
"fax3")
1643 else if (compression ==
"fax4")
1645 else if (compression ==
"jpeg")
1647 else if (compression ==
"lzw")
1649 else if (compression ==
"rle")
1651 else if (compression ==
"deflate")
1654 #undef COMPRESS_MAGICK_IMAGE_VECTOR
1662 octave_unused_parameter (args);
1678 DEFUN (__magick_ping__, args, ,
1688 #if defined (HAVE_MAGICK)
1690 if (args.length () < 1 || ! args(0).is_string ())
1695 const std::string filename = args(0).string_value ();
1698 if (args.length () > 1)
1699 idx = args(1).int_value () -1;
1715 img.ping (ascii_fname);
1717 catch (
const Magick::Warning&
w)
1719 warning (
"Magick++ warning: %s",
w.what ());
1721 catch (
const Magick::Exception& e)
1723 error (
"Magick++ exception: %s", e.what ());
1726 static const char *fields[] = {
"rows",
"columns",
"format",
nullptr};
1736 octave_unused_parameter (args);
1743 #if defined (HAVE_MAGICK)
1750 case Magick::NoCompression:
1752 case Magick::BZipCompression:
1754 case Magick::FaxCompression:
1756 case Magick::Group4Compression:
1758 case Magick::JPEGCompression:
1760 case Magick::LZWCompression:
1762 case Magick::RLECompression:
1766 case Magick::ZipCompression:
1794 case Magick::LSBEndian:
1796 case Magick::MSBEndian:
1809 case Magick::TopLeftOrientation:
1811 case Magick::TopRightOrientation:
1813 case Magick::BottomRightOrientation:
1815 case Magick::BottomLeftOrientation:
1817 case Magick::LeftTopOrientation:
1819 case Magick::RightTopOrientation:
1821 case Magick::RightBottomOrientation:
1823 case Magick::LeftBottomOrientation:
1835 case Magick::PixelsPerInchResolution:
1837 case Magick::PixelsPerCentimeterResolution:
1849 return (! val.empty () && val !=
"unknown");
1854 const std::string& key)
1856 const std::string attr = img.attribute (
"EXIF:" + key);
1864 const std::string& key)
1866 const std::string attr = img.attribute (
"EXIF:" + key);
1871 ColumnVector values (std::count (attr.begin (), attr.end (),
',') +1);
1873 std::istringstream sstream (attr);
1875 while (std::getline (sstream, sub,
char (
',')))
1877 sscanf (sub.c_str (),
"%f", &number);
1878 values(
n++) = number;
1887 const std::string& key)
1889 const std::string attr = img.attribute (
"EXIF:" + key);
1895 ColumnVector values (std::count (attr.begin (), attr.end (),
',') +1);
1897 std::istringstream sstream (attr);
1899 while (std::getline (sstream, sub,
','))
1901 sscanf (sub.c_str (),
"%i/%i", &numerator, &denominator);
1902 values(
n++) = double (numerator) / double (denominator);
1911 DEFUN (__magick_finfo__, args, ,
1922 #if defined (HAVE_MAGICK)
1924 if (args.length () < 1 || ! args(0).is_string ())
1929 const std::string filename = args(0).string_value ();
1931 std::vector<Magick::Image> imvec;
1935 const std::string
format = imvec[0].magick ();
1955 static const char *fields[] =
2018 const sys::file_stat fs (filename);
2020 error (
"imfinfo: error reading '%s': %s", filename.c_str (),
2021 fs.error ().c_str ());
2023 const sys::localtime mtime (fs.mtime ());
2024 const std::string filetime = mtime.strftime (
"%e-%b-%Y %H:%M:%S");
2034 const Magick::Image img = imvec[frame];
2044 std::string color_type;
2048 color_type =
"indexed";
2049 cmap =
read_maps (
const_cast<Magick::Image&
> (img))(0).matrix_value ();
2053 switch (img.type ())
2055 case Magick::BilevelType:
2056 case Magick::GrayscaleType:
2057 case Magick::GrayscaleMatteType:
2058 color_type =
"grayscale";
2061 case Magick::TrueColorType:
2062 case Magick::TrueColorMatteType:
2063 color_type =
"truecolor";
2066 case Magick::PaletteType:
2067 case Magick::PaletteMatteType:
2069 color_type =
"indexed";
2072 case Magick::ColorSeparationType:
2073 case Magick::ColorSeparationMatteType:
2074 color_type =
"CMYK";
2078 color_type =
"undefined";
2090 double *chroma_fvec = chromaticities.
fortran_vec ();
2091 img.chromaWhitePoint (&chroma_fvec[0], &chroma_fvec[1]);
2092 img.chromaRedPrimary (&chroma_fvec[2], &chroma_fvec[3]);
2093 img.chromaGreenPrimary (&chroma_fvec[4], &chroma_fvec[5]);
2094 img.chromaBluePrimary (&chroma_fvec[6], &chroma_fvec[7]);
2095 if (chromaticities.
nnz () == 0)
2109 info_frame.
setfield (
"Compression",
2111 info_frame.
setfield (
"Orientation",
2113 info_frame.
setfield (
"ResolutionUnit",
2122 Magick::Image& cimg =
const_cast<Magick::Image&
> (img);
2131 static const char *base_exif_str_fields[] =
2142 static const string_vector base_exif_str (base_exif_str_fields);
2146 info_frame.
setfield (base_exif_str[field],
2148 fill_exif (info_frame, cimg, base_exif_str[field]);
2153 if (! cimg.attribute (
"EXIF:ExifVersion").empty ())
2159 static const char *exif_str_fields[] =
2163 "DateTimeDigitized",
2166 "SubSecTimeOriginal",
2167 "SubSecTimeDigitized",
2174 "SpectralSensitivity",
2184 fill_exif (camera, cimg, exif_str[field]);
2187 static const char *exif_int_fields[] =
2192 "PhotographicSensitivity",
2193 "StandardOutputSensitivity",
2194 "RecommendedExposureIndex",
2196 "ISOSpeedLatitudeyyy",
2197 "ISOSpeedLatitudezzz",
2198 "FocalPlaneResolutionUnit",
2199 "FocalLengthIn35mmFilm",
2222 "SubjectDistanceRange",
2231 static const char *exif_float_fields[] =
2234 "CompressedBitsPerPixel",
2237 "ShutterSpeedValue",
2240 "ExposureBiasValue",
2245 "FocalPlaneXResolution",
2246 "FocalPlaneYResolution",
2250 "LensSpecification",
2261 if (cimg.attribute (
"EXIF:GPSInfo") !=
"unknown")
2267 static const char *gps_str_fields[] =
2277 "GPSImgDirectionRef",
2279 "GPSDestLatitudeRef",
2280 "GPSDestLongitudeRef",
2281 "GPSDestBearingRef",
2282 "GPSDestDistanceRef",
2291 static const char *gps_int_fields[] =
2301 static const char *gps_float_fields[] =
2310 "GPSHPositioningError",
2335 static std::map<octave_idx_type, std::string> disposal_methods
2339 methods[frame] = disposal_methods[imvec[frame].gifDisposeMethod ()];
2350 octave_unused_parameter (args);
2362 DEFUN (__magick_formats__, args, ,
2370 if (args.length () != 1 || ! args(0).isstruct ())
2375 #if defined (HAVE_MAGICK)
2387 fmt.
setfield (
"multipage", coder.isMultiFrame () ?
true :
false);
2390 if (! coder.isReadable ())
2392 if (! coder.isWritable ())
2396 catch (
const Magick::Exception&)
2411 return ovl (formats);
#define COMPRESS_MAGICK_IMAGE_VECTOR(GM_TYPE)
static void write_file(const std::string &filename, const std::string &ext, std::vector< Magick::Image > &imvec)
static bool is_indexed(const Magick::Image &img)
static octave_idx_type get_depth(Magick::Image &img)
octave_value_list read_images(std::vector< Magick::Image > &imvec, const Array< octave_idx_type > &frameidx, const octave_idx_type &nargout, const octave_scalar_map &options)
static void encode_indexed_images(std::vector< Magick::Image > &imvec, const T &img, const Matrix &cmap)
static void encode_uint_image(std::vector< Magick::Image > &imvec, const T &img, const T &alpha)
static octave_value magick_to_octave_value(const Magick::CompressionType &magick)
static octave_value_list read_indexed_images(const std::vector< Magick::Image > &imvec, const Array< octave_idx_type > &frameidx, const octave_idx_type &nargout, const octave_scalar_map &options)
static bool is_valid_exif(const std::string &val)
static uint32NDArray img_float2uint(const T &img)
static void fill_exif_ints(octave_scalar_map &map, Magick::Image &img, const std::string &key)
static octave_idx_type bitdepth_from_class()
static void read_file(const std::string &filename, std::vector< Magick::Image > &imvec)
static void maybe_initialize_magick(void)
static void fill_exif(octave_scalar_map &map, Magick::Image &img, const std::string &key)
static std::map< octave_idx_type, std::string > init_disposal_methods()
static range< double > get_region_range(const octave_value ®ion)
static std::map< std::string, octave_idx_type > init_reverse_disposal_methods()
static Magick::Image init_enconde_image(const octave_idx_type &nCols, const octave_idx_type &nRows, const octave_idx_type &bitdepth, const Magick::ImageType &type, const Magick::ClassType &klass)
static void encode_bool_image(std::vector< Magick::Image > &imvec, const boolNDArray &img)
static void fill_exif_floats(octave_scalar_map &map, Magick::Image &img, const std::string &key)
static octave_value_list read_maps(Magick::Image &img)
charNDArray max(char d, const charNDArray &m)
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type columns(void) const
OCTARRAY_OVERRIDABLE_FUNC_API const T * data(void) const
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API bool isempty(void) const
Size of the specified dimension.
OCTARRAY_API octave_idx_type nnz(void) const
Count nonzero elements.
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type numel(void) const
Number of elements in the array.
OCTARRAY_OVERRIDABLE_FUNC_API const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
OCTARRAY_API void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type rows(void) const
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
OCTARRAY_OVERRIDABLE_FUNC_API int ndims(void) const
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
octave_idx_type row_end(void) const
octave_idx_type col_end(void) const
octave_idx_type m_col_shift
octave_idx_type m_row_cache
octave_idx_type col_out(void) const
octave_idx_type col_cache(void) const
octave_idx_type row_out(void) const
octave_idx_type m_row_shift
octave_idx_type m_row_start
octave_idx_type col_shift(void) const
octave_idx_type m_row_out
octave_idx_type m_col_start
image_region(image_region &&)=default
octave_idx_type m_col_out
octave_idx_type row_cache(void) const
octave_idx_type col_start(void) const
~image_region(void)=default
octave_idx_type m_col_cache
image_region(const image_region &)=default
octave_idx_type m_row_end
octave_idx_type row_start(void) const
octave_idx_type row_shift(void) const
octave_idx_type m_col_end
image_region(const octave_scalar_map &options)
static octave_int< T > max(void)
octave_scalar_map checkelem(octave_idx_type n) const
void delete_elements(const octave::idx_vector &i)
void setfield(const std::string &key, const Cell &val)
octave_idx_type numel(void) const
string_vector fieldnames(void) const
bool fast_elem_insert(octave_idx_type n, const octave_scalar_map &rhs)
void setfield(const std::string &key, const octave_value &val)
octave_value getfield(const std::string &key) const
octave::range< double > range_value(void) const
boolNDArray bool_array_value(bool warn=false) const
uint16NDArray uint16_array_value(void) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
bool is_uint16_type(void) const
bool is_scalar_type(void) const
bool is_string(void) const
Cell cell_value(void) const
bool is_uint32_type(void) const
OCTINTERP_API ColumnVector column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
uint8NDArray uint8_array_value(void) const
double scalar_value(bool frc_str_conv=false) const
std::string string_value(bool force=false) const
bool is_matrix_type(void) const
bool is_range(void) const
NDArray array_value(bool frc_str_conv=false) const
bool is_single_type(void) const
uint32NDArray uint32_array_value(void) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
Array< std::string > cellstr_value(void) const
bool is_uint8_type(void) const
OCTINTERP_API Array< int > xint_vector_value(const char *fmt,...) const
unsigned int uint_value(bool req_int=false, bool frc_str_conv=false) const
bool islogical(void) const
octave_idx_type numel(void) const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
OCTINTERP_API void print_usage(void)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
std::string get_ASCII_filename(const std::string &orig_file_name, const bool allow_locale)
class OCTAVE_API RowVector
class OCTAVE_API ColumnVector
std::complex< double > w(std::complex< double > z, double relerr=0)
T::size_type numel(const T &str)
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
std::size_t format(std::ostream &os, const char *fmt,...)