26 #if defined (HAVE_CONFIG_H)
41 #if defined (HAVE_MAGICK)
42 # include <Magick++.h>
48 using Magick::Quantum;
53 #if defined (HAVE_MAGICK)
85 is_indexed (
const Magick::Image& img)
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")
131 get_depth (Magick::Image& img)
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)
168 double base = array(0);
169 double limit = array(array.
numel () - 1);
170 double incr = array(1) - base;
174 error (
"__magick_read__: unknown datatype for Region option");
184 image_region () =
delete;
195 const range<double> rows = get_region_range (pixel_region (0));
196 const range<double> cols = get_region_range (pixel_region (1));
198 m_row_start = rows.base () - 1;
199 m_col_start = cols.base () - 1;
200 m_row_end = rows.max () - 1;
201 m_col_end = cols.max () - 1;
203 m_row_cache = m_row_end - m_row_start + 1;
204 m_col_cache = m_col_end - m_col_start + 1;
206 m_row_shift = m_col_cache * rows.increment ();
207 m_col_shift = m_col_cache * (m_row_cache + rows.increment () - 1) - cols.increment ();
209 m_row_out = rows.numel ();
210 m_col_out = cols.numel ();
213 OCTAVE_DEFAULT_COPY_MOVE_DELETE (image_region)
261 read_maps (Magick::Image& img)
269 const Magick::ColorRGB c = img.colorMap (i);
270 cmap(i, 0) = c.red ();
271 cmap(i, 1) = c.green ();
272 cmap(i, 2) = c.blue ();
273 amap(i) = c.alpha ();
281 template <
typename T>
283 read_indexed_images (
const std::vector<Magick::Image>& imvec,
288 typedef typename T::element_type P;
292 image_region region (options);
303 T img = T (
dim_vector (nRows, nCols, 1, nFrames));
304 P *img_fvec = img.fortran_vec ();
321 imvec[frameidx(frame)].getConstPixels (col_start, row_start,
322 col_cache, row_cache);
324 const Magick::IndexPacket *pix
325 = imvec[frameidx(frame)].getConstIndexes ();
331 img_fvec[idx++] =
static_cast<P
> (*pix);
348 = read_maps (
const_cast<Magick::Image&
> (imvec[frameidx(def_elem)]));
355 if (imvec[def_elem].matte ())
358 const Matrix amap = maps(1).matrix_value ();
359 const double *amap_fvec = amap.
data ();
362 double *alpha_fvec = alpha.fortran_vec ();
368 alpha_fvec[pix] = 1 - amap_fvec[
static_cast<int> (img_fvec[3])];
387 template <
typename T>
394 typedef typename T::element_type P;
398 image_region region (options);
436 if (imvec[def_elem].depth () == 32)
439 divisor = MaxRGB / ((uint64_t (1) << imvec[def_elem].depth ()) - 1);
448 Magick::ImageType type = imvec[def_elem].type ();
449 if (type == Magick::BilevelType && imvec[def_elem].matte ())
450 type = Magick::GrayscaleMatteType;
459 if (imvec[0].magick () ==
"PNG")
469 const std::string type_str
470 = imvec[0].attribute (
"PNG:IHDR.color-type-orig");
473 type = Magick::GrayscaleType;
474 else if (type_str ==
"2")
475 type = Magick::TrueColorType;
476 else if (type_str ==
"6")
477 type = Magick::TrueColorMatteType;
478 else if (type_str ==
"4")
479 type = Magick::GrayscaleMatteType;
485 if (imvec[0].matte ())
487 if (type == Magick::GrayscaleType)
488 type = Magick::GrayscaleMatteType;
489 else if (type == Magick::TrueColorType)
490 type = Magick::TrueColorMatteType;
500 case Magick::GrayscaleMatteType:
501 type = Magick::GrayscaleType;
504 case Magick::PaletteMatteType:
505 type = Magick::PaletteType;
508 case Magick::TrueColorMatteType:
509 type = Magick::TrueColorType;
512 case Magick::ColorSeparationMatteType:
513 type = Magick::ColorSeparationType;
526 case Magick::BilevelType:
527 case Magick::GrayscaleType:
529 img = T (
dim_vector (nRows, nCols, 1, nFrames));
530 P *img_fvec = img.fortran_vec ();
537 const Magick::PixelPacket *pix
538 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
539 col_cache, row_cache);
545 img_fvec[idx++] = pix->red / divisor;
554 case Magick::GrayscaleMatteType:
556 img = T (
dim_vector (nRows, nCols, 1, nFrames));
557 T alpha (
dim_vector (nRows, nCols, 1, nFrames));
558 P *img_fvec = img.fortran_vec ();
559 P *a_fvec = alpha.fortran_vec ();
566 const Magick::PixelPacket *pix
567 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
568 col_cache, row_cache);
574 img_fvec[idx] = pix->red / divisor;
575 a_fvec[idx] = (MaxRGB - pix->opacity) / divisor;
586 case Magick::PaletteType:
587 case Magick::TrueColorType:
589 img = T (
dim_vector (nRows, nCols, 3, nFrames));
590 P *img_fvec = img.fortran_vec ();
597 const Magick::PixelPacket *pix
598 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
599 col_cache, row_cache);
603 P *gbuf = img_fvec + color_stride;
604 P *bbuf = img_fvec + color_stride * 2;
610 rbuf[idx] = pix->red / divisor;
611 gbuf[idx] = pix->green / divisor;
612 bbuf[idx] = pix->blue / divisor;
618 img_fvec += frame_stride;
623 case Magick::PaletteMatteType:
624 case Magick::TrueColorMatteType:
626 img = T (
dim_vector (nRows, nCols, 3, nFrames));
627 T alpha (
dim_vector (nRows, nCols, 1, nFrames));
628 P *img_fvec = img.fortran_vec ();
629 P *a_fvec = alpha.fortran_vec ();
640 const Magick::PixelPacket *pix
641 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
642 col_cache, row_cache);
646 P *gbuf = img_fvec + color_stride;
647 P *bbuf = img_fvec + color_stride * 2;
653 rbuf[idx] = pix->red / divisor;
654 gbuf[idx] = pix->green / divisor;
655 bbuf[idx] = pix->blue / divisor;
656 a_fvec[a_idx++] = (MaxRGB - pix->opacity) / divisor;
662 img_fvec += frame_stride;
668 case Magick::ColorSeparationType:
670 img = T (
dim_vector (nRows, nCols, 4, nFrames));
671 P *img_fvec = img.fortran_vec ();
678 const Magick::PixelPacket *pix
679 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
680 col_cache, row_cache);
684 P *mbuf = img_fvec + color_stride;
685 P *ybuf = img_fvec + color_stride * 2;
686 P *kbuf = img_fvec + color_stride * 3;
692 cbuf[idx] = pix->red / divisor;
693 mbuf[idx] = pix->green / divisor;
694 ybuf[idx] = pix->blue / divisor;
695 kbuf[idx] = pix->opacity / divisor;
701 img_fvec += frame_stride;
707 case Magick::ColorSeparationMatteType:
709 img = T (
dim_vector (nRows, nCols, 4, nFrames));
710 T alpha (
dim_vector (nRows, nCols, 1, nFrames));
711 P *img_fvec = img.fortran_vec ();
712 P *a_fvec = alpha.fortran_vec ();
723 const Magick::PixelPacket *pix
724 = imvec[frameidx(frame)].getConstPixels (col_start, row_start,
725 col_cache, row_cache);
728 const Magick::IndexPacket *apix
729 = imvec[frameidx(frame)].getConstIndexes ();
733 P *mbuf = img_fvec + color_stride;
734 P *ybuf = img_fvec + color_stride * 2;
735 P *kbuf = img_fvec + color_stride * 3;
741 cbuf[idx] = pix->red / divisor;
742 mbuf[idx] = pix->green / divisor;
743 ybuf[idx] = pix->blue / divisor;
744 kbuf[idx] = pix->opacity / divisor;
745 a_fvec[a_idx++] = (MaxRGB - *apix) / divisor;
751 img_fvec += frame_stride;
758 error (
"__magick_read__: unknown Magick++ image type");
768 read_file (
const std::string& filename, std::vector<Magick::Image>& imvec)
778 Magick::readImages (&imvec, ascii_fname);
780 catch (
const Magick::Warning&
w)
782 warning (
"Magick++ warning: %s",
w.what ());
784 catch (
const Magick::Exception& e)
786 error (
"Magick++ exception: %s", e.what ());
791 maybe_initialize_magick ()
793 static bool initialized =
false;
799 const char *static_locale = setlocale (LC_ALL,
nullptr);
800 const std::string locale = (static_locale ? static_locale :
"");
802 const std::string program_name
803 = sys::env::get_program_invocation_name ();
804 Magick::InitializeMagick (program_name.c_str ());
807 setlocale (LC_ALL, locale.c_str ());
828 if (QuantumDepth < 16)
830 "your version of %s limits images to %d bits per pixel\n",
831 MagickPackageName, QuantumDepth);
839 DEFUN (__magick_read__, args, nargout,
850 #if defined (HAVE_MAGICK)
852 if (args.length () != 2 || ! args(0).is_string ())
855 maybe_initialize_magick ();
858 = args(1).xscalar_map_value (
"__magick_read__: OPTIONS must be a struct");
862 std::vector<Magick::Image> imvec;
863 read_file (args(0).string_value (), imvec);
877 frameidx = indexes.
xint_vector_value (
"__magick_read__: invalid value for Index/Frame");
885 if (frameidx(i) < 0 || frameidx(i) > nFrames - 1)
890 error (
"imread: index/frames specified are outside the number of images");
900 const unsigned int nRows = imvec[frameidx(0)].rows ();
901 const unsigned int nCols = imvec[frameidx(0)].columns ();
905 if (nRows != imvec[frameidx(frame)].rows ()
906 || nCols != imvec[frameidx(frame)].columns ())
908 error (
"imread: all frames must have the same size but frame "
909 "%" OCTAVE_IDX_TYPE_FORMAT
" is different",
916 if (is_indexed (imvec[frameidx(0)]))
919 output = read_indexed_images<boolNDArray> (imvec, frameidx,
922 output = read_indexed_images<uint8NDArray> (imvec, frameidx,
924 else if (depth <= 16)
925 output = read_indexed_images<uint16NDArray> (imvec, frameidx,
928 error (
"imread: indexed images with depths greater than 16-bit are not supported");
934 output = read_images<boolNDArray> (imvec, frameidx, nargout, options);
936 output = read_images<uint8NDArray> (imvec, frameidx, nargout, options);
937 else if (depth <= 16)
938 output = read_images<uint16NDArray> (imvec, frameidx, nargout, options);
939 else if (depth <= 32)
940 output = read_images<FloatNDArray> (imvec, frameidx, nargout, options);
942 error (
"imread: reading of images with %" OCTAVE_IDX_TYPE_FORMAT
943 "-bit depth is not supported", depth);
950 octave_unused_parameter (args);
951 octave_unused_parameter (nargout);
963 #if defined (HAVE_MAGICK)
965 template <
typename T>
967 img_float2uint (
const T& img)
969 typedef typename T::element_type P;
973 const P *img_fvec = img.data ();
978 out_fvec[idx] = img_fvec[idx] *
max;
985 template <
typename T>
987 bitdepth_from_class ()
989 typedef typename T::element_type P;
991 =
sizeof (P) * std::numeric_limits<unsigned char>::digits;
998 const Magick::ImageType& type,
999 const Magick::ClassType& klass)
1001 Magick::Image img (Magick::Geometry (nCols, nRows),
"black");
1005 img.classType (klass);
1009 img.depth (bitdepth);
1012 case Magick::GrayscaleMatteType:
1013 case Magick::TrueColorMatteType:
1014 case Magick::ColorSeparationMatteType:
1015 case Magick::PaletteMatteType:
1026 template <
typename T>
1028 encode_indexed_images (std::vector<Magick::Image>& imvec,
1032 typedef typename T::element_type P;
1033 const octave_idx_type nFrames = (img.ndims () < 4 ? 1 : img.dims ()(3));
1041 std::vector<Magick::ColorRGB> colormap;
1043 const double *cmap_fvec = cmap.
data ();
1047 colormap.push_back (Magick::ColorRGB (cmap_fvec[map_idx],
1048 cmap_fvec[map_idx + G_offset],
1049 cmap_fvec[map_idx + B_offset]));
1056 Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
1057 Magick::PaletteType,
1058 Magick::PseudoClass);
1061 m_img.colorMapSize (cmap_size);
1063 m_img.colorMap (map_idx, colormap[map_idx]);
1074 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1075 Magick::IndexPacket *ind = m_img.getIndexes ();
1076 const P *img_fvec = img.data ();
1083 ind[GM_idx] = double (*img_fvec);
1084 pix[GM_idx] = m_img.colorMap (
double (*img_fvec));
1088 GM_idx -= nCols * nRows - 1;
1092 m_img.syncPixels ();
1093 imvec.push_back (m_img);
1098 encode_bool_image (std::vector<Magick::Image>& imvec,
const boolNDArray& img)
1105 const Magick::Color white (
"white");
1107 const bool *img_fvec = img.
data ();
1117 Magick::Image m_img = init_enconde_image (nCols, nRows, 1,
1118 Magick::GrayscaleType,
1119 Magick::DirectClass);
1121 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1127 if (img_fvec[img_idx])
1128 pix[GM_idx] = white;
1133 GM_idx -= nCols * nRows - 1;
1136 m_img.syncPixels ();
1139 m_img.type (Magick::BilevelType);
1140 imvec.push_back (m_img);
1144 template <
typename T>
1146 encode_uint_image (std::vector<Magick::Image>& imvec,
1147 const T& img,
const T& alpha)
1149 typedef typename T::element_type P;
1150 const octave_idx_type channels = (img.ndims () < 3 ? 1 : img.dims ()(2));
1151 const octave_idx_type nFrames = (img.ndims () < 4 ? 1 : img.dims ()(3));
1156 Magick::ImageType type;
1157 const bool has_alpha = ! alpha.isempty ();
1162 type = Magick::GrayscaleMatteType;
1164 type = Magick::GrayscaleType;
1169 type = Magick::TrueColorMatteType;
1171 type = Magick::TrueColorType;
1176 type = Magick::ColorSeparationMatteType;
1178 type = Magick::ColorSeparationType;
1183 error (
"__magick_write__: wrong size on 3rd dimension");
1193 const double divisor =
static_cast<double> ((uint64_t (1) << bitdepth) - 1)
1196 const P *img_fvec = img.data ();
1197 const P *a_fvec = alpha.data ();
1200 case Magick::GrayscaleType:
1206 Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
1208 Magick::DirectClass);
1210 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1216 const double grey =
math::round (
double (*img_fvec) / divisor);
1217 Magick::Color c (grey, grey, grey);
1222 GM_idx -= nCols * nRows - 1;
1225 m_img.syncPixels ();
1226 imvec.push_back (m_img);
1231 case Magick::GrayscaleMatteType:
1237 Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
1239 Magick::DirectClass);
1241 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1247 double grey =
math::round (
double (*img_fvec) / divisor);
1248 Magick::Color c (grey, grey, grey,
1249 MaxRGB -
math::round (
double (*a_fvec) / divisor));
1255 GM_idx -= nCols * nRows - 1;
1258 m_img.syncPixels ();
1259 imvec.push_back (m_img);
1264 case Magick::TrueColorType:
1273 Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
1275 Magick::DirectClass);
1277 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1283 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1284 math::round (
double (img_fvec[G_offset]) / divisor),
1285 math::round (
double (img_fvec[B_offset]) / divisor));
1290 GM_idx -= nCols * nRows - 1;
1293 m_img.syncPixels ();
1294 imvec.push_back (m_img);
1295 img_fvec += B_offset;
1300 case Magick::TrueColorMatteType:
1309 Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
1311 Magick::DirectClass);
1313 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1319 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1320 math::round (
double (img_fvec[G_offset]) / divisor),
1321 math::round (
double (img_fvec[B_offset]) / divisor),
1322 MaxRGB -
math::round (
double (*a_fvec) / divisor));
1328 GM_idx -= nCols * nRows - 1;
1331 m_img.syncPixels ();
1332 imvec.push_back (m_img);
1333 img_fvec += B_offset;
1338 case Magick::ColorSeparationType:
1348 Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
1350 Magick::DirectClass);
1352 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1358 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1359 math::round (
double (img_fvec[M_offset]) / divisor),
1360 math::round (
double (img_fvec[Y_offset]) / divisor),
1361 math::round (
double (img_fvec[K_offset]) / divisor));
1366 GM_idx -= nCols * nRows - 1;
1369 m_img.syncPixels ();
1370 imvec.push_back (m_img);
1371 img_fvec += K_offset;
1376 case Magick::ColorSeparationMatteType:
1386 Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
1388 Magick::DirectClass);
1390 Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
1391 Magick::IndexPacket *ind = m_img.getIndexes ();
1397 Magick::Color c (
math::round (
double (*img_fvec) / divisor),
1398 math::round (
double (img_fvec[M_offset]) / divisor),
1399 math::round (
double (img_fvec[Y_offset]) / divisor),
1400 math::round (
double (img_fvec[K_offset]) / divisor));
1402 ind[GM_idx] = MaxRGB -
math::round (
double (*a_fvec) / divisor);
1407 GM_idx -= nCols * nRows - 1;
1410 m_img.syncPixels ();
1411 imvec.push_back (m_img);
1412 img_fvec += K_offset;
1418 error (
"__magick_write__: unrecognized Magick::ImageType");
1425 static std::map<octave_idx_type, std::string>
1426 init_disposal_methods ()
1443 static std::map<octave_idx_type, std::string> methods;
1444 if (methods.empty ())
1446 methods[0] =
"doNotSpecify";
1447 methods[1] =
"leaveInPlace";
1448 methods[2] =
"restoreBG";
1449 methods[3] =
"restorePrevious";
1453 static std::map<std::string, octave_idx_type>
1454 init_reverse_disposal_methods ()
1456 static std::map<std::string, octave_idx_type> methods;
1457 if (methods.empty ())
1459 methods[
"donotspecify"] = 0;
1460 methods[
"leaveinplace"] = 1;
1461 methods[
"restorebg"] = 2;
1462 methods[
"restoreprevious"] = 3;
1468 write_file (
const std::string& filename,
1469 const std::string& ext,
1470 std::vector<Magick::Image>& imvec)
1474 Magick::writeImages (imvec.begin (), imvec.end (), ext +
':' + filename);
1476 catch (
const Magick::Warning&
w)
1478 warning (
"Magick++ warning: %s",
w.what ());
1480 catch (
const Magick::ErrorCoder& e)
1482 warning (
"Magick++ coder error: %s", e.what ());
1484 catch (
const Magick::Exception& e)
1486 error (
"Magick++ exception: %s", e.what ());
1492 DEFUN (__magick_write__, args, ,
1503 #if defined (HAVE_MAGICK)
1505 if (args.length () != 5 || ! args(0).is_string () || ! args(1).is_string ())
1508 maybe_initialize_magick ();
1510 const std::string filename = args(0).string_value ();
1511 const std::string ext = args(1).string_value ();
1514 = args(4).xscalar_map_value (
"__magick_write__: OPTIONS must be a struct");
1517 const Matrix cmap = args(3).xmatrix_value (
"__magick_write__: invalid MAP");
1519 std::vector<Magick::Image> imvec;
1546 clip_img = img_float2uint<FloatNDArray>
1548 clip_alpha = img_float2uint<FloatNDArray>
1553 clip_img = img_float2uint<NDArray> (img.
array_value ());
1554 clip_alpha = img_float2uint<NDArray> (alpha.
array_value ());
1556 encode_uint_image<uint32NDArray> (imvec, clip_img, clip_alpha);
1559 error (
"__magick_write__: image type not supported");
1573 error (
"__magick_write__: indexed image must be uint8, uint16 or float");
1575 static std::map<std::string, octave_idx_type> disposal_methods
1576 = init_reverse_disposal_methods ();
1587 imvec[i].quality (quality);
1588 imvec[i].animationDelay (delaytime(i));
1589 imvec[i].gifDisposeMethod (disposal_methods[disposalmethod(i)]);
1597 std::vector<Magick::Image> ini_imvec;
1598 read_file (filename, ini_imvec);
1600 if (ini_imvec.size () > 0)
1602 ini_imvec.insert (ini_imvec.end (), imvec.begin (), imvec.end ());
1603 ini_imvec.swap (imvec);
1633 const std::string compression
1636 #define COMPRESS_MAGICK_IMAGE_VECTOR(GM_TYPE) \
1637 for (std::vector<Magick::Image>::size_type i = 0; i < imvec.size (); i++) \
1638 imvec[i].compressType (GM_TYPE)
1640 if (compression ==
"none")
1642 else if (compression ==
"bzip")
1644 else if (compression ==
"fax3")
1646 else if (compression ==
"fax4")
1648 else if (compression ==
"jpeg")
1650 else if (compression ==
"lzw")
1652 else if (compression ==
"rle")
1654 else if (compression ==
"deflate")
1657 #undef COMPRESS_MAGICK_IMAGE_VECTOR
1659 write_file (filename, ext, imvec);
1665 octave_unused_parameter (args);
1681 DEFUN (__magick_ping__, args, ,
1691 #if defined (HAVE_MAGICK)
1693 if (args.length () < 1 || ! args(0).is_string ())
1696 maybe_initialize_magick ();
1698 const std::string filename = args(0).string_value ();
1701 if (args.length () > 1)
1702 idx = args(1).int_value () -1;
1718 img.ping (ascii_fname);
1720 catch (
const Magick::Warning&
w)
1722 warning (
"Magick++ warning: %s",
w.what ());
1724 catch (
const Magick::Exception& e)
1726 error (
"Magick++ exception: %s", e.what ());
1729 static const char *fields[] = {
"rows",
"columns",
"format",
nullptr};
1739 octave_unused_parameter (args);
1746 #if defined (HAVE_MAGICK)
1749 magick_to_octave_value (
const Magick::CompressionType& magick)
1753 case Magick::NoCompression:
1755 case Magick::BZipCompression:
1757 case Magick::FaxCompression:
1759 case Magick::Group4Compression:
1761 case Magick::JPEGCompression:
1763 case Magick::LZWCompression:
1765 case Magick::RLECompression:
1769 case Magick::ZipCompression:
1793 magick_to_octave_value (
const Magick::EndianType& magick)
1797 case Magick::LSBEndian:
1799 case Magick::MSBEndian:
1807 magick_to_octave_value (
const Magick::OrientationType& magick)
1812 case Magick::TopLeftOrientation:
1814 case Magick::TopRightOrientation:
1816 case Magick::BottomRightOrientation:
1818 case Magick::BottomLeftOrientation:
1820 case Magick::LeftTopOrientation:
1822 case Magick::RightTopOrientation:
1824 case Magick::RightBottomOrientation:
1826 case Magick::LeftBottomOrientation:
1834 magick_to_octave_value (
const Magick::ResolutionType& magick)
1838 case Magick::PixelsPerInchResolution:
1840 case Magick::PixelsPerCentimeterResolution:
1848 is_valid_exif (
const std::string& val)
1852 return (! val.empty () && val !=
"unknown");
1857 const std::string& key)
1859 const std::string attr = img.attribute (
"EXIF:" + key);
1860 if (is_valid_exif (attr))
1867 const std::string& key)
1869 const std::string attr = img.attribute (
"EXIF:" + key);
1870 if (is_valid_exif (attr))
1874 ColumnVector values (std::count (attr.begin (), attr.end (),
',') +1);
1876 std::istringstream sstream (attr);
1878 while (std::getline (sstream, sub,
char (
',')))
1880 sscanf (sub.c_str (),
"%f", &number);
1881 values(
n++) = number;
1890 const std::string& key)
1892 const std::string attr = img.attribute (
"EXIF:" + key);
1893 if (is_valid_exif (attr))
1898 ColumnVector values (std::count (attr.begin (), attr.end (),
',') +1);
1900 std::istringstream sstream (attr);
1902 while (std::getline (sstream, sub,
','))
1904 sscanf (sub.c_str (),
"%i/%i", &numerator, &denominator);
1905 values(
n++) = double (numerator) / double (denominator);
1914 DEFUN (__magick_finfo__, args, ,
1925 #if defined (HAVE_MAGICK)
1927 if (args.length () < 1 || ! args(0).is_string ())
1930 maybe_initialize_magick ();
1932 const std::string filename = args(0).string_value ();
1934 std::vector<Magick::Image> imvec;
1935 read_file (filename, imvec);
1938 const std::string
format = imvec[0].magick ();
1958 static const char *fields[] =
2021 const sys::file_stat fs (filename);
2023 error (
"imfinfo: error reading '%s': %s", filename.c_str (),
2024 fs.error ().c_str ());
2026 const sys::localtime mtime (fs.mtime ());
2027 const std::string filetime = mtime.strftime (
"%e-%b-%Y %H:%M:%S");
2037 const Magick::Image img = imvec[frame];
2042 octave_value (get_depth (
const_cast<Magick::Image&
> (img))));
2047 std::string color_type;
2049 if (is_indexed (img))
2051 color_type =
"indexed";
2052 cmap = read_maps (
const_cast<Magick::Image&
> (img))(0).matrix_value ();
2056 switch (img.type ())
2058 case Magick::BilevelType:
2059 case Magick::GrayscaleType:
2060 case Magick::GrayscaleMatteType:
2061 color_type =
"grayscale";
2064 case Magick::TrueColorType:
2065 case Magick::TrueColorMatteType:
2066 color_type =
"truecolor";
2069 case Magick::PaletteType:
2070 case Magick::PaletteMatteType:
2072 color_type =
"indexed";
2075 case Magick::ColorSeparationType:
2076 case Magick::ColorSeparationMatteType:
2077 color_type =
"CMYK";
2081 color_type =
"undefined";
2093 double *chroma_fvec = chromaticities.
fortran_vec ();
2094 img.chromaWhitePoint (&chroma_fvec[0], &chroma_fvec[1]);
2095 img.chromaRedPrimary (&chroma_fvec[2], &chroma_fvec[3]);
2096 img.chromaGreenPrimary (&chroma_fvec[4], &chroma_fvec[5]);
2097 img.chromaBluePrimary (&chroma_fvec[6], &chroma_fvec[7]);
2098 if (chromaticities.
nnz () == 0)
2112 info_frame.
setfield (
"Compression",
2113 magick_to_octave_value (img.compressType ()));
2114 info_frame.
setfield (
"Orientation",
2115 magick_to_octave_value (img.orientation ()));
2116 info_frame.
setfield (
"ResolutionUnit",
2117 magick_to_octave_value (img.resolutionUnits ()));
2119 magick_to_octave_value (img.endian ()));
2125 Magick::Image& cimg =
const_cast<Magick::Image&
> (img);
2134 static const char *base_exif_str_fields[] =
2145 static const string_vector base_exif_str (base_exif_str_fields);
2149 info_frame.
setfield (base_exif_str[field],
2151 fill_exif (info_frame, cimg, base_exif_str[field]);
2156 if (! cimg.attribute (
"EXIF:ExifVersion").empty ())
2162 static const char *exif_str_fields[] =
2166 "DateTimeDigitized",
2169 "SubSecTimeOriginal",
2170 "SubSecTimeDigitized",
2177 "SpectralSensitivity",
2187 fill_exif (camera, cimg, exif_str[field]);
2190 static const char *exif_int_fields[] =
2195 "PhotographicSensitivity",
2196 "StandardOutputSensitivity",
2197 "RecommendedExposureIndex",
2199 "ISOSpeedLatitudeyyy",
2200 "ISOSpeedLatitudezzz",
2201 "FocalPlaneResolutionUnit",
2202 "FocalLengthIn35mmFilm",
2225 "SubjectDistanceRange",
2231 fill_exif_ints (camera, cimg, exif_int[field]);
2234 static const char *exif_float_fields[] =
2237 "CompressedBitsPerPixel",
2240 "ShutterSpeedValue",
2243 "ExposureBiasValue",
2248 "FocalPlaneXResolution",
2249 "FocalPlaneYResolution",
2253 "LensSpecification",
2259 fill_exif_floats (camera, cimg, exif_float[field]);
2264 if (cimg.attribute (
"EXIF:GPSInfo") !=
"unknown")
2270 static const char *gps_str_fields[] =
2280 "GPSImgDirectionRef",
2282 "GPSDestLatitudeRef",
2283 "GPSDestLongitudeRef",
2284 "GPSDestBearingRef",
2285 "GPSDestDistanceRef",
2292 fill_exif (gps, cimg, gps_str[field]);
2294 static const char *gps_int_fields[] =
2302 fill_exif_ints (gps, cimg, gps_int[field]);
2304 static const char *gps_float_fields[] =
2313 "GPSHPositioningError",
2325 fill_exif_floats (gps, cimg, gps_float[field]);
2338 static std::map<octave_idx_type, std::string> disposal_methods
2339 = init_disposal_methods ();
2342 methods[frame] = disposal_methods[imvec[frame].gifDisposeMethod ()];
2353 octave_unused_parameter (args);
2365 DEFUN (__magick_formats__, args, ,
2373 if (args.length () != 1 || ! args(0).isstruct ())
2378 #if defined (HAVE_MAGICK)
2380 maybe_initialize_magick ();
2390 fmt.
setfield (
"multipage", coder.isMultiFrame () ?
true :
false);
2393 if (! coder.isReadable ())
2395 if (! coder.isWritable ())
2399 catch (
const Magick::Exception&)
2414 return ovl (formats);
2422 OCTAVE_END_NAMESPACE(
octave)
#define COMPRESS_MAGICK_IMAGE_VECTOR(GM_TYPE)
charNDArray max(char d, const charNDArray &m)
T * fortran_vec()
Size of the specified dimension.
int ndims() const
Size of the specified dimension.
octave_idx_type nnz() const
Count nonzero elements.
octave_idx_type rows() const
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
const T * data() const
Size of the specified dimension.
octave_idx_type columns() const
bool isempty() const
Size of the specified dimension.
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
octave_idx_type numel() const
Number of elements in the array.
Vector representing the dimensions (size) of an Array.
static octave_int< T > max()
octave_scalar_map checkelem(octave_idx_type n) const
string_vector fieldnames() const
void delete_elements(const octave::idx_vector &i)
void setfield(const std::string &key, const Cell &val)
octave_idx_type numel() 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
bool is_uint32_type() const
boolNDArray bool_array_value(bool warn=false) const
uint16NDArray uint16_array_value() const
int int_value(bool req_int=false, bool frc_str_conv=false) const
bool is_scalar_type() const
octave::range< double > range_value() const
Array< int > xint_vector_value(const char *fmt,...) const
bool is_single_type() const
bool is_uint8_type() const
bool is_uint16_type() const
double scalar_value(bool frc_str_conv=false) const
std::string string_value(bool force=false) const
bool is_matrix_type() const
NDArray array_value(bool frc_str_conv=false) const
uint8NDArray uint8_array_value() const
ColumnVector column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
uint32NDArray uint32_array_value() const
unsigned int uint_value(bool req_int=false, bool frc_str_conv=false) const
Array< std::string > cellstr_value() const
octave_idx_type numel() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#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)
bool file_exists(const std::string &filename, bool is_dir)
std::complex< double > w(std::complex< double > z, double relerr=0)
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)
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,...)