hphp/runtime/ext/imagick/imagick.cpp (3,673 lines of code) (raw):

/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) | | Copyright (c) 1997-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ */ #include "hphp/runtime/ext/imagick/ext_imagick.h" #include "hphp/runtime/base/array-iterator.h" #include "hphp/runtime/ext/std/ext_std_file.h" #include "hphp/runtime/ext/string/ext_string.h" #include "hphp/runtime/vm/native-prop-handler.h" using std::pair; using std::string; using std::vector; namespace HPHP { #define IMAGICK_THROW imagickThrow<ImagickException> // bool Imagick::$imagePending static const StaticString s_imagePending("imagePending"); ALWAYS_INLINE static bool getImagePending(const Object& imagick) { auto var = imagick->o_get(s_imagePending, true, s_Imagick); return var.toBoolean(); } ALWAYS_INLINE static void setImagePending(const Object& imagick, bool imagePending) { imagick->o_set(s_imagePending, imagePending, s_Imagick); } // class ImageGeometry struct ImageGeometry { static const ImageGeometry empty_geometry; ImageGeometry(int64_t width, int64_t height) : m_width(width), m_height(height) { } explicit ImageGeometry(MagickWand* wand) : ImageGeometry(MagickGetImageWidth(wand), MagickGetImageHeight(wand)) { } bool empty() const { return m_width <= 0 || m_height <= 0; } bool operator==(const ImageGeometry& other) const { return m_width == other.m_width && m_height == other.m_height; } bool operator!=(const ImageGeometry& other) const { return m_width != other.m_width || m_height != other.m_height; } int64_t getWidth() const { return m_width; } int64_t getHeight() const { return m_height; } ImageGeometry scale(double ratio) const { static const double kEPS = 1e-8; return ImageGeometry( std::max<int64_t>(1, (int64_t)(m_width * ratio + kEPS)), std::max<int64_t>(1, (int64_t)(m_height * ratio + kEPS))); } ImageGeometry toThumbnail(ImageGeometry hint, bool bestfit) const { if (empty()) { return empty_geometry; } double ratio_w = (double)hint.m_width / (double)m_width; double ratio_h = (double)hint.m_height / (double)m_height; if (bestfit) { if (hint.empty()) { return empty_geometry; } else { return scale(std::min(ratio_w, ratio_h)); } } else { if (!hint.empty()) { return hint; } else if (hint.m_width <= 0 && hint.m_height <= 0) { return empty_geometry; } else { return scale(std::max(ratio_w, ratio_h)); } } } Array toArray() const { return make_dict_array( s_width, m_width, s_height, m_height); } private: int64_t m_width; int64_t m_height; }; const ImageGeometry ImageGeometry::empty_geometry(0, 0); // assertion ALWAYS_INLINE static void ensureImageHasFormat(MagickWand* wand) { String format = convertMagickString(MagickGetImageFormat(wand)); if (format.empty()) { IMAGICK_THROW("Image has no format"); } } ALWAYS_INLINE static void ensurePageIsValid( int64_t x, int64_t y, int64_t width, int64_t height) { if (x < 0 || y < 0) { IMAGICK_THROW("The coordinates must be non-negative"); } if (width <= 0 || height <= 0) { IMAGICK_THROW("The width and height must be greater than zero"); } } ALWAYS_INLINE static void ensureChannelMapIsValid(const String& map) { static const StaticString s_channels("RGBAOCYMKIP"); for (int i = 0; i < map.size(); ++i) { if (s_channels.find(map[i]) == String::npos) { IMAGICK_THROW("The map contains disallowed characters"); } } } // import/export ImagePixels template<StorageType T> struct StorageTypeCPPType; template<> struct StorageTypeCPPType<CharPixel> { using T = unsigned char; }; template<> struct StorageTypeCPPType<LongPixel> { using T = long; }; template<> struct StorageTypeCPPType<DoublePixel> { using T = double; }; ALWAYS_INLINE static StorageType resolveStorageType(StorageType storage) { #define substituteStorageType(from, to) \ do { \ if (storage == from) { \ /* \ raiseDeprecated(s_Imagick.c_str(), #from, \ s_Imagick.c_str(), #to); \ */ \ storage = to; \ } \ } while (false) substituteStorageType(FloatPixel, DoublePixel); substituteStorageType(ShortPixel, LongPixel); substituteStorageType(IntegerPixel, LongPixel); #undef substituteStorageType if (storage != CharPixel && storage != IntegerPixel && storage != DoublePixel) { IMAGICK_THROW("Unknown storage format"); } else { return storage; } } // misc ALWAYS_INLINE static String getImageMimeType(MagickWand* wand) { String format = convertMagickString(MagickGetImageFormat(wand)); if (format.empty()) { return String(); } String mimetype = convertMagickString(MagickToMime(format.c_str())); if (mimetype.empty()) { return String(); } return mimetype; } ////////////////////////////////////////////////////////////////////////////// // Imagick Helper using MagickQueryFunction = char** (*)(const char*, size_t*); Object createImagick(MagickWand* wand) { Object ret = Imagick::allocObject(); setWandResource(s_Imagick, ret, wand); return ret; } ALWAYS_INLINE static Array magickQuery(const char* pattern, MagickQueryFunction query) { size_t num = 0; auto result = query(pattern, &num); return convertMagickArray(num, result); } Array magickQueryFonts(const char* pattern /* = "*" */) { return magickQuery(pattern, MagickQueryFonts); } Array magickQueryFormats(const char* pattern /* = "*" */) { return magickQuery(pattern, MagickQueryFormats); } String magickResolveFont(const String& fontName) { Array fonts = magickQueryFonts(); for (ArrayIter it(fonts); it; ++it) { if (strcasecmp(val(it.secondValPlus()).pstr->data(), fontName.c_str()) == 0) { return fontName; } } auto font = HHVM_FN(realpath)(fontName); if (font.isBoolean() && !font.toBoolean()) { return String(); } else { return font.toString(); } } ////////////////////////////////////////////////////////////////////////////// // class Imagick static bool HHVM_METHOD(Imagick, adaptiveBlurImage, double radius, double sigma, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickAdaptiveBlurImageChannel( wand->getWand(), (ChannelType)channel, radius, sigma); if (status == MagickFalse) { IMAGICK_THROW("Unable to adaptive blur image"); } return true; } static bool HHVM_METHOD(Imagick, adaptiveResizeImage, int64_t columns, int64_t rows, bool bestfit) { auto wand = getMagickWandResource(Object{this_}); auto geometry = ImageGeometry(wand->getWand()).toThumbnail( {columns, rows}, bestfit); if (geometry.empty()) { IMAGICK_THROW("Invalid image geometry"); } auto status = MagickAdaptiveResizeImage( wand->getWand(), geometry.getWidth(), geometry.getHeight()); if (status == MagickFalse) { IMAGICK_THROW("Unable to adaptive resize image"); } return true; } static bool HHVM_METHOD(Imagick, adaptiveSharpenImage, double radius, double sigma, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickAdaptiveSharpenImageChannel( wand->getWand(), (ChannelType)channel, radius, sigma); if (status == MagickFalse) { IMAGICK_THROW("Unable to adaptive sharpen image"); } return true; } static bool HHVM_METHOD(Imagick, adaptiveThresholdImage, int64_t width, int64_t height, int64_t offset) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickAdaptiveThresholdImage( wand->getWand(), width, height, offset); if (status == MagickFalse) { IMAGICK_THROW("Unable to adaptive threshold image"); } return true; } static bool HHVM_METHOD(Imagick, addImage, const Object& source) { auto wand = getMagickWandResource(Object{this_}); auto magick = getMagickWandResource(source); auto status = MagickAddImage(wand->getWand(), magick->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to add image"); } MagickSetLastIterator(wand->getWand()); return true; } static bool HHVM_METHOD(Imagick, addNoiseImage, int64_t noise_type, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickAddNoiseImageChannel( wand->getWand(), (ChannelType)channel, (NoiseType)noise_type); if (status == MagickFalse) { IMAGICK_THROW("Unable to add image noise"); } return true; } static bool HHVM_METHOD(Imagick, affineTransformImage, const Object& matrix) { auto wand = getMagickWandResource(Object{this_}); auto drawing = getDrawingWandResource(matrix); auto status = MagickAffineTransformImage( wand->getWand(), drawing->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to affine transform image"); } return true; } static bool HHVM_METHOD(Imagick, animateImages, const String& x_server) { auto wand = getMagickWandResource(Object{this_}); MagickSetFirstIterator(wand->getWand()); auto status = MagickAnimateImages(wand->getWand(), x_server.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to animate images"); } return true; } static bool HHVM_METHOD(Imagick, annotateImage, const Object& draw_settings, double x, double y, double angle, const String& text) { auto wand = getMagickWandResource(Object{this_}); auto drawing = getDrawingWandResource(draw_settings); auto status = MagickAnnotateImage( wand->getWand(), drawing->getWand(), x, y, angle, text.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to annotate image"); } return true; } static Object HHVM_METHOD(Imagick, appendImages, bool stack) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickAppendImages(wand->getWand(), toMagickBool(stack)); if (magick == nullptr) { IMAGICK_THROW("Unable to append images"); } return createImagick(magick); } static Object HHVM_METHOD(Imagick, averageImages) { raiseDeprecated(s_Imagick.c_str(), "averageImages"); auto wand = getMagickWandResource(Object{this_}); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto magick = MagickAverageImages(wand->getWand()); #pragma GCC diagnostic pop if (magick == nullptr) { IMAGICK_THROW("Averaging images failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, blackThresholdImage, const Variant& threshold) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(threshold); auto status = MagickBlackThresholdImage(wand->getWand(), pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to black threshold image"); } return true; } static bool HHVM_METHOD(Imagick, blurImage, double radius, double sigma, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickBlurImageChannel( wand->getWand(), (ChannelType)channel, radius, sigma); if (status == MagickFalse) { IMAGICK_THROW("Unable to blur image"); } return true; } static bool HHVM_METHOD(Imagick, borderImage, const Variant& bordercolor, int64_t width, int64_t height) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(bordercolor); auto status = MagickBorderImage( wand->getWand(), pixel->getWand(), width, height); if (status == MagickFalse) { IMAGICK_THROW("Unable to border image"); } return true; } static bool HHVM_METHOD(Imagick, charcoalImage, double radius, double sigma) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickCharcoalImage(wand->getWand(), radius, sigma); if (status == MagickFalse) { IMAGICK_THROW("Unable to charcoal image"); } return true; } static bool HHVM_METHOD(Imagick, chopImage, int64_t width, int64_t height, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickChopImage(wand->getWand(), width, height, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to chop image"); } return true; } static bool HHVM_METHOD(Imagick, clear) { auto wand = getWandResource<MagickWand>(s_Imagick, Object{this_}); if (!wand || wand->getWand() == nullptr) { return false; } else { ClearMagickWand(wand->getWand()); setImagePending(Object{this_}, false); return true; } } static bool HHVM_METHOD(Imagick, clipImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickClipImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to clip image"); } return true; } static bool HHVM_METHOD(Imagick, clipPathImage, const String& pathname, bool inside) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickClipImagePath( wand->getWand(), pathname.c_str(), toMagickBool(inside)); if (status == MagickFalse) { IMAGICK_THROW("Unable to clip path image"); } return true; } static void HHVM_METHOD(Imagick, __clone) { auto wand = getMagickWandResource(Object{this_}); auto magick = CloneMagickWand(wand->getWand()); if (magick == nullptr) { IMAGICK_THROW("Cloning Imagick object failed"); } else { setWandResource(s_Imagick, Object{this_}, magick); } } static bool HHVM_METHOD(Imagick, clutImage, const Object& lookup_table, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto magick = getMagickWandResource(lookup_table); auto status = MagickClutImageChannel( wand->getWand(), (ChannelType)channel, magick->getWand()); if (status == MagickFalse) { IMAGICK_THROW( "Unable to replace colors in the image from a color lookup table"); } return true; } static Object HHVM_METHOD(Imagick, coalesceImages) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickCoalesceImages(wand->getWand()); if (magick == nullptr) { IMAGICK_THROW("Coalesce image failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, colorFloodfillImage, const Variant& fill, double fuzz, const Variant& bordercolor, int64_t x, int64_t y) { raiseDeprecated(s_Imagick.c_str(), "colorFloodFillImage"); auto wand = getMagickWandResource(Object{this_}); auto fillPixel = buildColorWand(fill); auto borderPixel = buildColorWand(bordercolor); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickColorFloodfillImage( wand->getWand(), fillPixel->getWand(), fuzz, borderPixel->getWand(), x, y); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to color floodfill image"); } return true; } static bool HHVM_METHOD(Imagick, colorizeImage, const Variant& colorize, const Variant& opacity) { auto wand = getMagickWandResource(Object{this_}); auto colorPixel = buildColorWand(colorize); auto opacityPixel = buildOpacityWand(opacity); auto pixel = req::make<WandResource<PixelWand>>( ClonePixelWand(colorPixel->getWand())); if (pixel->getWand() == nullptr) { IMAGICK_THROW("Failed to allocate"); } else { auto opacityValue = PixelGetOpacity(opacityPixel->getWand()); auto alphaValue = PixelGetAlpha(opacityPixel->getWand()); PixelSetOpacity(pixel->getWand(), opacityValue); PixelSetAlpha(pixel->getWand(), alphaValue); } auto status = MagickColorizeImage( wand->getWand(), pixel->getWand(), pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to colorize image"); } return true; } static Object HHVM_METHOD(Imagick, combineImages, int64_t channelType) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickCombineImages(wand->getWand(), (ChannelType)channelType); if (magick == nullptr) { IMAGICK_THROW("Combine images failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, commentImage, const String& comment) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickCommentImage(wand->getWand(), comment.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to comment image"); } return true; } static Array HHVM_METHOD(Imagick, compareImageChannels, const Object& image, int64_t channelType, int64_t metricType) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(image); double distortion; auto magick = MagickCompareImageChannels( wand->getWand(), wand2->getWand(), (ChannelType)channelType, (MetricType)metricType, &distortion); if (magick == nullptr) { IMAGICK_THROW("Compare image channels failed"); } else { return make_vec_array(createImagick(magick), distortion); } } static Object HHVM_METHOD(Imagick, compareImageLayers, int64_t method) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickCompareImageLayers( wand->getWand(), (ImageLayerMethod)method); if (magick == nullptr) { IMAGICK_THROW("Compare image layers failed"); } return createImagick(magick); } static Array HHVM_METHOD(Imagick, compareImages, const Object& compare, int64_t metric) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(compare); double distortion; auto magick = MagickCompareImages( wand->getWand(), wand2->getWand(), (MetricType)metric, &distortion); if (magick == nullptr) { IMAGICK_THROW("Compare images failed"); } else { return make_vec_array(createImagick(magick), distortion); } } static bool HHVM_METHOD(Imagick, compositeImage, const Object& composite_object, int64_t composite, int64_t x, int64_t y, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(composite_object); MagickCompositeImageChannel( wand->getWand(), (ChannelType)channel, wand2->getWand(), (CompositeOperator)composite, x, y); return true; } static void HHVM_METHOD(Imagick, __construct, const Variant& files) { auto magick = NewMagickWand(); if (magick == nullptr) { IMAGICK_THROW("Failed to create ImagickDraw object"); } else { setWandResource(s_Imagick, Object{this_}, magick); } auto wand = getMagickWandResource(Object{this_}); Array array = files.isString() ? make_vec_array(files) : files.isArray() ? files.toArray() : empty_vec_array(); for (ArrayIter it(array); it; ++it) { imagickReadOp( wand->getWand(), tvCastToString(it.secondValPlus()), MagickReadImage ); } } static bool HHVM_METHOD(Imagick, contrastImage, bool sharpen) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickContrastImage(wand->getWand(), toMagickBool(sharpen)); if (status == MagickFalse) { IMAGICK_THROW("Unable to contrast image"); } return true; } static bool HHVM_METHOD(Imagick, contrastStretchImage, double black_point, double white_point, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickContrastStretchImageChannel( wand->getWand(), (ChannelType)channel, black_point, white_point); if (status == MagickFalse) { IMAGICK_THROW("Unable to contrast strech image"); } return true; } static bool HHVM_METHOD(Imagick, convolveImage, const Array& kernelArray, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto kernel = toDoubleArray(kernelArray); if (kernel.empty()) { IMAGICK_THROW("Unable to read matrix array"); } auto order = (size_t)sqrt(kernel.size()); auto status = MagickConvolveImageChannel( wand->getWand(), (ChannelType)channel, order, kernel.data()); if (status == MagickFalse) { IMAGICK_THROW("Unable to convolve image"); } return true; } static bool HHVM_METHOD(Imagick, cropImage, int64_t width, int64_t height, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickCropImage(wand->getWand(), width, height, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to crop image"); } return true; } static bool HHVM_METHOD(Imagick, cropThumbnailImage, int64_t width, int64_t height) { auto wand = getMagickWandResource(Object{this_}); auto geometry = ImageGeometry(wand->getWand()); ImageGeometry thumbnail(width, height); MagickBooleanType status; if (thumbnail.empty()) { status = MagickFalse; } else if (thumbnail == geometry) { // Already at the size, just strip profiles status = MagickStripImage(wand->getWand()); } else { auto ratio_w = (double)thumbnail.getWidth() / geometry.getWidth(); auto ratio_h = (double)thumbnail.getHeight() / geometry.getHeight(); auto thumbnail = geometry.scale(std::max(ratio_w, ratio_h)); status = MagickThumbnailImage( wand->getWand(), thumbnail.getWidth(), thumbnail.getHeight()); if (status != MagickFalse && thumbnail != ImageGeometry(width, height)) { auto crop_x = (thumbnail.getWidth() - width) / 2; auto crop_y = (thumbnail.getHeight() - height) / 2; status = MagickCropImage( wand->getWand(), width, height, crop_x, crop_y); if (status != MagickFalse) { status = MagickSetImagePage(wand->getWand(), width, height, 0, 0); } } } if (status == MagickFalse) { IMAGICK_THROW("Unable to crop-thumbnail image"); } return true; } static bool HHVM_METHOD(Imagick, cycleColormapImage, int64_t displace) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickCycleColormapImage(wand->getWand(), displace); if (status == MagickFalse) { IMAGICK_THROW("Unable to cycle image colormap"); } return true; } static bool HHVM_METHOD(Imagick, decipherImage, const String& passphrase) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickDecipherImage(wand->getWand(), passphrase.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to decipher image"); } return true; } static Object HHVM_METHOD(Imagick, deconstructImages) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickDeconstructImages(wand->getWand()); if (magick == nullptr) { IMAGICK_THROW("Deconstruct image failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, deleteImageArtifact, const String& artifact) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickDeleteImageArtifact(wand->getWand(), artifact.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to delete image artifact"); } return true; } static bool HHVM_METHOD(Imagick, deskewImage, double threshold) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickDeskewImage(wand->getWand(), threshold); if (status == MagickFalse) { IMAGICK_THROW("Unable to deskew image"); } return true; } static bool HHVM_METHOD(Imagick, despeckleImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickDespeckleImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to despeckle image"); } return true; } static bool HHVM_METHOD(Imagick, destroy) { return HHVM_MN(Imagick, clear)(this_); } static bool HHVM_METHOD(Imagick, displayImage, const String& servername) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickDisplayImage(wand->getWand(), servername.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to display image"); } return true; } static bool HHVM_METHOD(Imagick, displayImages, const String& servername) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickDisplayImages(wand->getWand(), servername.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to display images"); } return true; } static bool HHVM_METHOD(Imagick, distortImage, int64_t method, const Array& arguments, bool bestfit) { auto wand = getMagickWandResource(Object{this_}); auto args = toDoubleArray(arguments); if (args.empty()) { IMAGICK_THROW("Can't read argument array"); } auto status = MagickDistortImage( wand->getWand(), (DistortImageMethod)method, args.size(), args.data(), toMagickBool(bestfit)); if (status == MagickFalse) { IMAGICK_THROW("Unable to distort the image"); } return true; } static bool HHVM_METHOD(Imagick, drawImage, const Object& draw) { auto wand = getMagickWandResource(Object{this_}); auto drawing = getDrawingWandResource(draw); auto status = withMagickLocaleFix([&wand, &drawing](){ return MagickDrawImage(wand->getWand(), drawing->getWand()); }); if (status == MagickFalse) { IMAGICK_THROW("Unable to draw image"); } return true; } static bool HHVM_METHOD(Imagick, edgeImage, double radius) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickEdgeImage(wand->getWand(), radius); if (status == MagickFalse) { IMAGICK_THROW("Unable to edge image"); } return true; } static bool HHVM_METHOD(Imagick, embossImage, double radius, double sigma) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickEmbossImage(wand->getWand(), radius, sigma); if (status == MagickFalse) { IMAGICK_THROW("Unable to emboss image"); } return true; } static bool HHVM_METHOD(Imagick, encipherImage, const String& passphrase) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickEncipherImage(wand->getWand(), passphrase.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to encipher image"); } return true; } static bool HHVM_METHOD(Imagick, enhanceImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickEnhanceImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to enchance image"); } return true; } static bool HHVM_METHOD(Imagick, equalizeImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickEqualizeImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to equalize image"); } return true; } static bool HHVM_METHOD(Imagick, evaluateImage, int64_t op, double constant, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickEvaluateImageChannel(wand->getWand(), (ChannelType)channel, (MagickEvaluateOperator)op, constant); if (status == MagickFalse) { IMAGICK_THROW("Unable to evaluate image"); } return true; } template<StorageType T> ALWAYS_INLINE static vector<typename StorageTypeCPPType<T>::T> exportImagePixels( req::ptr<WandResource<MagickWand>> wand, int64_t x, int64_t y, int64_t width, int64_t height, const String& map) { size_t size = width * height * map.length(); vector<typename StorageTypeCPPType<T>::T> ret(size); auto status = MagickExportImagePixels( wand->getWand(), x, y, width, height, map.c_str(), T, (void*)ret.data()); if (status == MagickFalse) { IMAGICK_THROW("Unable to export image pixels"); } return ret; } static Array HHVM_METHOD(Imagick, exportImagePixels, int64_t x, int64_t y, int64_t width, int64_t height, const String& map, int64_t storage_) { auto wand = getMagickWandResource(Object{this_}); ensurePageIsValid(x, y, width, height); ensureChannelMapIsValid(map); auto storage = resolveStorageType((StorageType)storage_); if (storage == DoublePixel) { auto ret = exportImagePixels<DoublePixel>(wand, x, y, width, height, map); return convertArray(ret.size(), ret.data()); } else { vector<int64_t> ret; if (storage == CharPixel) { auto tmp = exportImagePixels<CharPixel>(wand, x, y, width, height, map); ret.assign(tmp.begin(), tmp.end()); } else { auto tmp = exportImagePixels<LongPixel>(wand, x, y, width, height, map); ret.assign(tmp.begin(), tmp.end()); } return convertArray(ret.size(), ret.data()); } } static bool HHVM_METHOD(Imagick, extentImage, int64_t width, int64_t height, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickExtentImage(wand->getWand(), width, height, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to extent image"); } return true; } static Object HHVM_METHOD(Imagick, flattenImages) { raiseDeprecated(s_Imagick.c_str(), "flattenImages"); auto wand = getMagickWandResource(Object{this_}); MagickSetFirstIterator(wand->getWand()); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto magick = MagickFlattenImages(wand->getWand()); #pragma GCC diagnostic pop if (magick == nullptr) { IMAGICK_THROW("Flatten images failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, flipImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickFlipImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to flip image"); } return true; } static bool HHVM_METHOD(Imagick, floodFillPaintImage, const Variant& fill, double fuzz, const Variant& target, int64_t x, int64_t y, bool invert, int64_t channel /*=Default*/) { auto wand = getMagickWandResource(Object{this_}); auto fillPixel = buildColorWand(fill); auto targetPixel = buildColorWand(target); auto status = MagickFloodfillPaintImage( wand->getWand(), (ChannelType)channel, fillPixel->getWand(), fuzz, targetPixel->getWand(), x, y, toMagickBool(invert)); if (status == MagickFalse) { IMAGICK_THROW("Unable to floodfill paint image"); } return true; } static bool HHVM_METHOD(Imagick, flopImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickFlopImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to flop image"); } return true; } static bool HHVM_METHOD(Imagick, frameImage, const Variant& matte_color, int64_t width, int64_t height, int64_t inner_bevel, int64_t outer_bevel) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(matte_color); auto status = MagickFrameImage( wand->getWand(), pixel->getWand(), width, height, inner_bevel, outer_bevel); if (status == MagickFalse) { IMAGICK_THROW("Unable to frame image"); } return true; } static bool HHVM_METHOD(Imagick, functionImage, int64_t func, const Array& arguments, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto args = toDoubleArray(arguments); if (args.empty()) { IMAGICK_THROW("The arguments array contains disallowed characters"); } auto status = MagickFunctionImageChannel( wand->getWand(), (ChannelType)channel, (MagickFunction)func, args.size(), args.data()); if (status == MagickFalse) { IMAGICK_THROW("Unable to execute function on the image"); } return true; } static Object HHVM_METHOD(Imagick, fxImage, const String& expression, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickFxImageChannel( wand->getWand(), (ChannelType)channel, expression.c_str()); if (magick == nullptr) { IMAGICK_THROW("Fx image failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, gammaImage, double gamma, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickGammaImageChannel( wand->getWand(), (ChannelType)channel, gamma); if (status == MagickFalse) { IMAGICK_THROW("Unable to gamma image"); } return true; } static bool HHVM_METHOD(Imagick, gaussianBlurImage, double radius, double sigma, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickGaussianBlurImageChannel( wand->getWand(), (ChannelType)channel, radius, sigma); if (status == MagickFalse) { IMAGICK_THROW("Unable to gaussian blur image"); } return true; } static int64_t HHVM_METHOD(Imagick, getColorspace) { auto wand = getMagickWandResource(Object{this_}); return MagickGetColorspace(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getCompression) { auto wand = getMagickWandResource(Object{this_}); return MagickGetCompression(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getCompressionQuality) { auto wand = getMagickWandResource(Object{this_}); return MagickGetCompressionQuality(wand->getWand()); } static String HHVM_STATIC_METHOD(Imagick, getCopyright) { return MagickGetCopyright(); } static String HHVM_METHOD(Imagick, getFilename) { auto wand = getMagickWandResource(Object{this_}); return convertMagickString(MagickGetFilename(wand->getWand())); } static String HHVM_METHOD(Imagick, getFont) { auto wand = getMagickWandResource(Object{this_}); return convertMagickString(MagickGetFont(wand->getWand())); } static String HHVM_METHOD(Imagick, getFormat) { auto wand = getMagickWandResource(Object{this_}); return convertMagickString(MagickGetFormat(wand->getWand())); } static int64_t HHVM_METHOD(Imagick, getGravity) { auto wand = getMagickWandResource(Object{this_}); return MagickGetGravity(wand->getWand()); } static String HHVM_STATIC_METHOD(Imagick, getHomeURL) { return convertMagickString(MagickGetHomeURL()); } static Object HHVM_METHOD(Imagick, getImage) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickGetImage(wand->getWand()); if (magick == nullptr) { IMAGICK_THROW("Get image failed"); } return createImagick(magick); } static int64_t HHVM_METHOD(Imagick, getImageAlphaChannel) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageAlphaChannel(wand->getWand()); } static String HHVM_METHOD(Imagick, getImageArtifact, const String& artifact) { auto wand = getMagickWandResource(Object{this_}); return convertMagickString( MagickGetImageArtifact(wand->getWand(), artifact.c_str())); } static Object HHVM_METHOD(Imagick, getImageBackgroundColor) { auto wand = getMagickWandResource(Object{this_}); auto pixel = newPixelWand(); auto status = MagickGetImageBackgroundColor( wand->getWand(), pixel->getWand()); if (pixel->getWand() == nullptr || status == MagickFalse) { IMAGICK_THROW("Unable to get image background color"); } return createImagickPixel(pixel->releaseWand()); } static String HHVM_METHOD(Imagick, getImageBlob) { auto wand = getMagickWandResource(Object{this_}); ensureImageHasFormat(wand->getWand()); size_t size; auto data = MagickGetImageBlob(wand->getWand(), &size); return convertMagickData(size, data); } static Array HHVM_METHOD(Imagick, getImageBluePrimary) { auto wand = getMagickWandResource(Object{this_}); double x, y; auto status = MagickGetImageBluePrimary(wand->getWand(), &x, &y); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image blue primary"); } return make_dict_array(s_x, x, s_y, y); } static Object HHVM_METHOD(Imagick, getImageBorderColor) { auto wand = getMagickWandResource(Object{this_}); auto pixel = newPixelWand(); auto status = MagickGetImageBorderColor(wand->getWand(), pixel->getWand()); if (pixel->getWand() == nullptr || status == MagickFalse) { IMAGICK_THROW("Unable to get image border color"); } return createImagickPixel(pixel->releaseWand()); } static int64_t HHVM_METHOD(Imagick, getImageChannelDepth, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageChannelDepth(wand->getWand(), (ChannelType)channel); } static double HHVM_METHOD(Imagick, getImageChannelDistortion, const Object& reference, int64_t channel, int64_t metric) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(reference); double distortion; auto status = MagickGetImageChannelDistortion( wand->getWand(), wand2->getWand(), (ChannelType)channel, (MetricType)metric, &distortion); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image channel distortion"); } return distortion; } static double HHVM_METHOD(Imagick, getImageChannelDistortions, const Object& reference, int64_t metric, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(reference); double distortion; auto status = MagickGetImageChannelDistortion( wand->getWand(), wand2->getWand(), (ChannelType)channel, (MetricType)metric, &distortion); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image channel distortion metrics"); } return distortion; } static Array HHVM_METHOD(Imagick, getImageChannelExtrema, int64_t channel) { raiseDeprecated(s_Imagick.c_str(), "getImageChannelExtrema"); auto wand = getMagickWandResource(Object{this_}); size_t minima, maxima; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickGetImageChannelExtrema( wand->getWand(), (ChannelType)channel, &minima, &maxima); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to get image channel extrema"); } return make_dict_array( s_minima, (int64_t)minima, s_maxima, (int64_t)maxima); } static Array HHVM_METHOD(Imagick, getImageChannelKurtosis, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); double kurtosis, skewness; auto status = MagickGetImageChannelKurtosis( wand->getWand(), (ChannelType)channel, &kurtosis, &skewness); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image channel kurtosis"); } return make_dict_array( s_kurtosis, kurtosis, s_skewness, skewness); } static Array HHVM_METHOD(Imagick, getImageChannelMean, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); double mean, standardDeviation; auto status = MagickGetImageChannelMean( wand->getWand(), (ChannelType)channel, &mean, &standardDeviation); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image channel mean"); } return make_dict_array( s_mean, mean, s_standardDeviation, standardDeviation); } static Array HHVM_METHOD(Imagick, getImageChannelRange, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); double minima, maxima; auto status = MagickGetImageChannelRange( wand->getWand(), (ChannelType)channel, &minima, &maxima); if (status == MagickFalse) { IMAGICK_THROW("Unable to get channel range"); } return make_dict_array( s_minima, minima, s_maxima, maxima); } static Array HHVM_METHOD(Imagick, getImageChannelStatistics) { static const int channels[] = { UndefinedChannel, RedChannel, CyanChannel, GreenChannel, MagentaChannel, BlueChannel, YellowChannel, OpacityChannel, BlackChannel, MatteChannel }; auto wand = getMagickWandResource(Object{this_}); auto stat = MagickGetImageChannelStatistics(wand->getWand()); DictInit ret(sizeof(channels) / sizeof(channels[0])); for (auto channel : channels) { ret.set(channel, make_dict_array( s_mean, stat[channel].mean, s_minima, stat[channel].minima, s_maxima, stat[channel].maxima, s_standardDeviation, stat[channel].standard_deviation, s_depth, (int64_t)stat[channel].depth)); } freeMagickMemory(stat); return ret.toArray(); } static Object HHVM_METHOD(Imagick, getImageClipMask) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickGetImageClipMask(wand->getWand()); if (magick == nullptr) { IMAGICK_THROW("Unable to get image clip mask"); } return createImagick(magick); } static Object HHVM_METHOD(Imagick, getImageColormapColor, int64_t index) { auto wand = getMagickWandResource(Object{this_}); auto pixel = newPixelWand(); auto status = MagickGetImageColormapColor( wand->getWand(), index , pixel->getWand()); if (pixel->getWand() == nullptr || status == MagickFalse) { IMAGICK_THROW("Unable to get image colormap color"); } return createImagickPixel(pixel->releaseWand()); } static int64_t HHVM_METHOD(Imagick, getImageColors) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageColors(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageColorspace) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageColorspace(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageCompose) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageCompose(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageCompression) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageCompression(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageDelay) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageDelay(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageDepth) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageDepth(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageDispose) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageDispose(wand->getWand()); } static double HHVM_METHOD(Imagick, getImageDistortion, const Object& reference, int64_t metric) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(reference); double distortion; auto status = MagickGetImageDistortion( wand->getWand(), wand2->getWand(), (MetricType)metric, &distortion); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image distortion"); } return distortion; } static Array HHVM_METHOD(Imagick, getImageExtrema) { raiseDeprecated(s_Imagick.c_str(), "getImageExtrema"); auto wand = getMagickWandResource(Object{this_}); size_t min, max; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickGetImageExtrema(wand->getWand(), &min, &max); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to get image extrema"); } return make_dict_array( s_min, (int64_t)min, s_max, (int64_t)max); } static String HHVM_METHOD(Imagick, getImageFilename) { auto wand = getMagickWandResource(Object{this_}); return convertMagickString(MagickGetImageFilename(wand->getWand())); } static String HHVM_METHOD(Imagick, getImageFormat) { auto wand = getMagickWandResource(Object{this_}); ensureImageHasFormat(wand->getWand()); return convertMagickString(MagickGetImageFormat(wand->getWand())); } static double HHVM_METHOD(Imagick, getImageGamma) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageGamma(wand->getWand()); } static Array HHVM_METHOD(Imagick, getImageGeometry) { auto wand = getMagickWandResource(Object{this_}); return ImageGeometry(wand->getWand()).toArray(); } static int64_t HHVM_METHOD(Imagick, getImageGravity) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageGravity(wand->getWand()); } static Array HHVM_METHOD(Imagick, getImageGreenPrimary) { auto wand = getMagickWandResource(Object{this_}); double x, y; auto status = MagickGetImageGreenPrimary(wand->getWand(), &x, &y); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image green primary"); } return make_dict_array(s_x, x, s_y, y); } static int64_t HHVM_METHOD(Imagick, getImageHeight) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageHeight(wand->getWand()); } static Array HHVM_METHOD(Imagick, getImageHistogram) { auto wand = getMagickWandResource(Object{this_}); size_t colors; auto hist = MagickGetImageHistogram(wand->getWand(), &colors); auto ret = createImagickPixelArray(colors, hist); freeMagickMemory(hist); return ret; } static int64_t HHVM_METHOD(Imagick, getImageIndex) { raiseDeprecated(s_Imagick.c_str(), "getImageindex"); auto wand = getMagickWandResource(Object{this_}); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" return MagickGetImageIndex(wand->getWand()); #pragma GCC diagnostic pop } static int64_t HHVM_METHOD(Imagick, getImageInterlaceScheme) { raiseDeprecated(s_Imagick.c_str(), "getImageInterlaceScheme"); auto wand = getMagickWandResource(Object{this_}); return MagickGetImageInterlaceScheme(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageInterpolateMethod) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageInterpolateMethod(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageIterations) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageIterations(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageLength) { auto wand = getMagickWandResource(Object{this_}); MagickSizeType length; auto status = MagickGetImageLength(wand->getWand(), &length); if (status == MagickFalse) { IMAGICK_THROW("Unable to acquire image length"); } return length; } static bool HHVM_METHOD(Imagick, getImageMatte) { raiseDeprecated(s_Imagick.c_str(), "getImageMatte"); auto wand = getMagickWandResource(Object{this_}); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" return MagickGetImageMatte(wand->getWand()) == MagickTrue; #pragma GCC diagnostic pop } static Object HHVM_METHOD(Imagick, getImageMatteColor) { auto wand = getMagickWandResource(Object{this_}); auto pixel = newPixelWand(); auto status = MagickGetImageMatteColor(wand->getWand(), pixel->getWand()); if (pixel->getWand() == nullptr || status == MagickFalse) { IMAGICK_THROW("Unable to get image matte color"); } return createImagickPixel(pixel->releaseWand()); } static String HHVM_METHOD(Imagick, getImageMimeType) { auto wand = getMagickWandResource(Object{this_}); return getImageMimeType(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageOrientation) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageOrientation(wand->getWand()); } static Array HHVM_METHOD(Imagick, getImagePage) { auto wand = getMagickWandResource(Object{this_}); size_t width, height; ssize_t x, y; auto status = MagickGetImagePage(wand->getWand(), &width, &height, &x, &y); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image page"); } return make_dict_array( s_width, (int64_t)width, s_height, (int64_t)height, s_x, (int64_t)x, s_y, (int64_t)y); } static Object HHVM_METHOD(Imagick, getImagePixelColor, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto pixel = newPixelWand(); auto status = MagickGetImagePixelColor( wand->getWand(), x, y , pixel->getWand()); if (pixel->getWand() == nullptr || status == MagickFalse) { IMAGICK_THROW("Unable get image pixel color"); } return createImagickPixel(pixel->releaseWand()); } ALWAYS_INLINE static String magickGetImageProfile(MagickWand* wand, const char* name) { size_t length; auto profile = MagickGetImageProfile(wand, name, &length); if (profile == nullptr) { IMAGICK_THROW("Can not get image profile"); } else { return convertMagickData(length, profile); } } static String HHVM_METHOD(Imagick, getImageProfile, const String& name) { auto wand = getMagickWandResource(Object{this_}); return magickGetImageProfile(wand->getWand(), name.c_str()); } static Variant HHVM_METHOD(Imagick, getImageProfiles, const String& pattern, bool with_values) { auto wand = getMagickWandResource(Object{this_}); size_t count; auto profiles = MagickGetImageProfiles( wand->getWand(), pattern.c_str(), &count); if (profiles == nullptr) { IMAGICK_THROW("Unable to get image profiles"); } if (with_values) { DictInit ret(count); for (size_t i = 0; i < count; ++i) { ret.set( String(profiles[i]), magickGetImageProfile(wand->getWand(), profiles[i])); } freeMagickMemory(profiles); return ret.toArray(); } else { return convertMagickArray(count, profiles); } } ALWAYS_INLINE static String magickGetImageProperty(MagickWand* wand, const char* name) { return convertMagickString(MagickGetImageProperty(wand, name)); } static Variant HHVM_METHOD(Imagick, getImageProperties, const String& pattern, bool with_values) { auto wand = getMagickWandResource(Object{this_}); size_t count; auto properties = MagickGetImageProperties( wand->getWand(), pattern.c_str(), &count); if (properties == nullptr) { IMAGICK_THROW("Unable to get image properties"); } if (with_values) { DictInit ret(count); for (size_t i = 0; i < count; ++i) { ret.set( String(properties[i]), magickGetImageProperty(wand->getWand(), properties[i])); } freeMagickMemory(properties); return ret.toArray(); } else { return convertMagickArray(count, properties); } } static String HHVM_METHOD(Imagick, getImageProperty, const String& name) { auto wand = getMagickWandResource(Object{this_}); return magickGetImageProperty(wand->getWand(), name.c_str()); } static Array HHVM_METHOD(Imagick, getImageRedPrimary) { auto wand = getMagickWandResource(Object{this_}); double x, y; auto status = MagickGetImageRedPrimary(wand->getWand(), &x, &y); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image red primary"); } return make_dict_array(s_x, x, s_y, y); } static Object HHVM_METHOD(Imagick, getImageRegion, int64_t width, int64_t height, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickGetImageRegion(wand->getWand(), width, height, x, y); if (magick == nullptr) { IMAGICK_THROW("Get image region failed"); } return createImagick(magick); } static int64_t HHVM_METHOD(Imagick, getImageRenderingIntent) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageRenderingIntent(wand->getWand()); } static Array HHVM_METHOD(Imagick, getImageResolution) { auto wand = getMagickWandResource(Object{this_}); double x, y; auto status = MagickGetImageResolution(wand->getWand(), &x, &y); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image resolution"); } return make_dict_array(s_x, x, s_y, y); } static String HHVM_METHOD(Imagick, getImagesBlob) { auto wand = getMagickWandResource(Object{this_}); int current = MagickGetIteratorIndex(wand->getWand()); MagickResetIterator(wand->getWand()); while (MagickNextImage(wand->getWand()) != MagickFalse) { ensureImageHasFormat(wand->getWand()); } auto status = MagickSetIteratorIndex(wand->getWand(), current); if (status == MagickFalse) { IMAGICK_THROW("Unable to set the iterator index"); } size_t size; auto data = MagickGetImagesBlob(wand->getWand(), &size); return convertMagickData(size, data); } static int64_t HHVM_METHOD(Imagick, getImageScene) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageScene(wand->getWand()); } static String HHVM_METHOD(Imagick, getImageSignature) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageSignature(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageSize) { raiseDeprecated(s_Imagick.c_str(), "getImageSize", s_Imagick.c_str(), "getImageLength"); auto wand = getMagickWandResource(Object{this_}); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" return MagickGetImageSize(wand->getWand()); #pragma GCC diagnostic pop } static int64_t HHVM_METHOD(Imagick, getImageTicksPerSecond) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageTicksPerSecond(wand->getWand()); } static double HHVM_METHOD(Imagick, getImageTotalInkDensity) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageTotalInkDensity(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageType) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageType(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageUnits) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageUnits(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getImageVirtualPixelMethod) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageVirtualPixelMethod(wand->getWand()); } static Array HHVM_METHOD(Imagick, getImageWhitePoint) { auto wand = getMagickWandResource(Object{this_}); double x, y; auto status = MagickGetImageWhitePoint(wand->getWand(), &x, &y); if (status == MagickFalse) { IMAGICK_THROW("Unable to get image white point"); } return make_dict_array(s_x, x, s_y, y); } static int64_t HHVM_METHOD(Imagick, getImageWidth) { auto wand = getMagickWandResource(Object{this_}); return MagickGetImageWidth(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getInterlaceScheme) { auto wand = getMagickWandResource(Object{this_}); return MagickGetInterlaceScheme(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getIteratorIndex) { auto wand = getMagickWandResource(Object{this_}); return MagickGetIteratorIndex(wand->getWand()); } static int64_t HHVM_METHOD(Imagick, getNumberImages) { auto wand = getMagickWandResource(Object{this_}); return MagickGetNumberImages(wand->getWand()); } static String HHVM_METHOD(Imagick, getOption, const String& key) { auto wand = getMagickWandResource(Object{this_}); return convertMagickString(MagickGetOption(wand->getWand(), key.c_str())); } static String HHVM_STATIC_METHOD(Imagick, getPackageName) { return MagickGetPackageName(); } static Array HHVM_METHOD(Imagick, getPage) { auto wand = getMagickWandResource(Object{this_}); size_t width, height; ssize_t x, y; auto status = MagickGetPage(wand->getWand(), &width, &height, &x, &y); if (status == MagickFalse) { IMAGICK_THROW("Unable to get page"); } return make_dict_array( s_width, (int64_t)width, s_height, (int64_t)height, s_x, (int64_t)x, s_y, (int64_t)y); } static Object HHVM_METHOD(Imagick, getPixelIterator) { return createPixelIterator(Object{this_}); } static Object HHVM_METHOD(Imagick, getPixelRegionIterator, int64_t x, int64_t y, int64_t columns, int64_t rows) { return createPixelRegionIterator(Object{this_}, x, y, columns, rows); } static double HHVM_METHOD(Imagick, getPointSize) { auto wand = getMagickWandResource(Object{this_}); return MagickGetPointsize(wand->getWand()); } static Array HHVM_STATIC_METHOD(Imagick, getQuantumDepth) { size_t depth; const char* quantumDepth = MagickGetQuantumDepth(&depth); return make_dict_array( s_quantumDepthLong, (int64_t)depth, s_quantumDepthString, quantumDepth); } static Array HHVM_STATIC_METHOD(Imagick, getQuantumRange) { size_t range; const char* quantumRange = MagickGetQuantumRange(&range); return make_dict_array( s_quantumRangeLong, (int64_t)range, s_quantumRangeString, quantumRange); } static String HHVM_STATIC_METHOD(Imagick, getReleaseDate) { return MagickGetReleaseDate(); } static int64_t HHVM_STATIC_METHOD(Imagick, getResource, int64_t resource_type) { return MagickGetResource((ResourceType)resource_type); } static int64_t HHVM_STATIC_METHOD(Imagick, getResourceLimit, int64_t resource_type) { return MagickGetResourceLimit((ResourceType)resource_type); } static Array HHVM_METHOD(Imagick, getSamplingFactors) { auto wand = getMagickWandResource(Object{this_}); size_t num; auto arr = MagickGetSamplingFactors(wand->getWand(), &num); return convertMagickArray(num, arr); } static Array HHVM_METHOD(Imagick, getSize) { auto wand = getMagickWandResource(Object{this_}); size_t columns, rows; auto status = MagickGetSize(wand->getWand(), &columns, &rows); if (status == MagickFalse) { IMAGICK_THROW("Unable to get size"); } return make_dict_array( s_columns, (int64_t)columns, s_rows, (int64_t)rows); } static int64_t HHVM_METHOD(Imagick, getSizeOffset) { auto wand = getMagickWandResource(Object{this_}); ssize_t offset; auto status = MagickGetSizeOffset(wand->getWand(), &offset); if (status == MagickFalse) { IMAGICK_THROW("Unable to get size offset"); } return offset; } static Array HHVM_STATIC_METHOD(Imagick, getVersion) { size_t version; const char* versionStr = MagickGetVersion(&version); return make_dict_array( s_versionNumber, (int64_t)version, s_versionString, versionStr); } static bool HHVM_METHOD(Imagick, haldClutImage, const Object& clut, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(clut); auto status = MagickHaldClutImageChannel( wand->getWand(), (ChannelType)channel, wand2->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to hald clut image"); } return true; } static bool HHVM_METHOD(Imagick, hasNextImage) { auto wand = getMagickWandResource(Object{this_}); return MagickHasNextImage(wand->getWand()) != MagickFalse; } static bool HHVM_METHOD(Imagick, hasPreviousImage) { auto wand = getMagickWandResource(Object{this_}); return MagickHasPreviousImage(wand->getWand()) != MagickFalse; } ALWAYS_INLINE static vector<pair<String, String>> parseIdentify(const String& identify) { using Keys = vector<pair<string, StaticString>>; static const Keys keys = { {"Format: ", s_format}, {"Units: ", s_units}, {"Type: ", s_type}, {"Colorspace: ", s_colorSpace}, {"Filesize: ", s_fileSize}, {"Compression: ", s_compression} }; vector<pair<String, String>> ret; Array lines = HHVM_FN(explode)("\r\n", identify).toArray(); ret.reserve(keys.size()); for (ArrayIter it(lines); it; ++it) { String line = HHVM_FN(trim)( tvCastToString(it.secondValPlus()) ); auto key = std::find_if(keys.begin(), keys.end(), [=](Keys::const_reference i) { const string& prefix = i.first; return strncmp(line.c_str(), prefix.c_str(), prefix.length()) == 0; }); if (key != keys.end()) { ret.push_back({key->second, line.substr(key->first.length())}); } } return ret; } static Array HHVM_METHOD(Imagick, identifyImage, bool appendRawOutput) { static const StaticString s_unknown("unknown"); auto wand = getMagickWandResource(Object{this_}); String identify = convertMagickString(MagickIdentifyImage(wand->getWand())); auto parsedIdentify = parseIdentify(identify); DictInit ret(parsedIdentify.size() + 6); ret.set(s_imageName, convertMagickString(MagickGetImageFilename(wand->getWand()))); String mimetype = HHVM_MN(Imagick, getImageMimeType)(this_); ret.set(s_mimetype, mimetype.empty() ? String(s_unknown) : mimetype); for (const auto& i: parsedIdentify) { ret.set(i.first, i.second); } ret.set(s_geometry, ImageGeometry(wand->getWand()).toArray()); double x, y; if (MagickGetImageResolution(wand->getWand(), &x, &y) == MagickTrue) { ret.set(s_resolution, make_dict_array(s_x, x, s_y, y)); } ret.set(s_signature, convertMagickString(MagickGetImageSignature(wand->getWand()))); if (appendRawOutput) { ret.set(s_rawOutput, identify); } return ret.toArray(); } static bool HHVM_METHOD(Imagick, implodeImage, double radius) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickImplodeImage(wand->getWand(), radius); if (status == MagickFalse) { IMAGICK_THROW("Unable to implode image"); } return true; } template<StorageType T> ALWAYS_INLINE static void importImagePixels(req::ptr<WandResource<MagickWand>> wand, int64_t x, int64_t y, int64_t width, int64_t height, const String& map, const vector<double>& array) { vector<typename StorageTypeCPPType<T>::T> data(array.begin(), array.end()); auto status = MagickImportImagePixels(wand->getWand(), x, y, width, height, map.c_str(), T, data.data()); if (status == MagickFalse) { IMAGICK_THROW("Unable to import image pixels"); } } static bool HHVM_METHOD(Imagick, importImagePixels, int64_t x, int64_t y, int64_t width, int64_t height, const String& map, int64_t storage_, const Array& pixels) { auto wand = getMagickWandResource(Object{this_}); ensurePageIsValid(x, y, width, height); ensureChannelMapIsValid(map); if (pixels.size() != width * height * map.size()) { IMAGICK_THROW("The array contains incorrect number of elements"); } auto array = toDoubleArray(pixels); if (array.empty()) { IMAGICK_THROW("The array contains incorrect values"); } auto storage = resolveStorageType((StorageType)storage_); if (storage == CharPixel) { importImagePixels<CharPixel>(wand, x, y, width, height, map, array); } else if (storage == LongPixel) { importImagePixels<LongPixel>(wand, x, y, width, height, map, array); } else if (storage == DoublePixel) { importImagePixels<DoublePixel>(wand, x, y, width, height, map, array); } else { not_reached(); } return true; } static bool HHVM_METHOD(Imagick, labelImage, const String& label) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickLabelImage(wand->getWand(), label.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to label image"); } return true; } static bool HHVM_METHOD(Imagick, levelImage, double blackPoint, double gamma, double whitePoint, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickLevelImageChannel( wand->getWand(), (ChannelType)channel, blackPoint, gamma, whitePoint); if (status == MagickFalse) { IMAGICK_THROW("Unable to level image"); } return true; } static bool HHVM_METHOD(Imagick, linearStretchImage, double blackPoint, double whitePoint) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickLinearStretchImage( wand->getWand(), blackPoint, whitePoint); if (status == MagickFalse) { IMAGICK_THROW("Unable to linear strech image"); } return true; } static bool HHVM_METHOD(Imagick, liquidRescaleImage, int64_t width, int64_t height, double delta_x, double rigidity) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickLiquidRescaleImage( wand->getWand(), width, height, delta_x, rigidity); if (status == MagickFalse) { IMAGICK_THROW("Unable to liquid rescale image"); } return true; } static bool HHVM_METHOD(Imagick, magnifyImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickMagnifyImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to magnify image"); } return true; } static bool HHVM_METHOD(Imagick, mapImage, const Object& map, bool dither) { raiseDeprecated(s_Imagick.c_str(), "mapImage"); auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(map); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickMapImage( wand->getWand(), wand2->getWand(), toMagickBool(dither)); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to map image"); } return true; } static bool HHVM_METHOD(Imagick, matteFloodfillImage, double alpha, double fuzz, const Variant& bordercolor, int64_t x, int64_t y) { raiseDeprecated(s_Imagick.c_str(), "matteFloodfillImage"); auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(bordercolor); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickMatteFloodfillImage( wand->getWand(), alpha, fuzz, pixel->getWand(), x, y); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to matte floodfill image"); } return true; } static bool HHVM_METHOD(Imagick, medianFilterImage, double radius) { raiseDeprecated(s_Imagick.c_str(), "medianFilterImage"); auto wand = getMagickWandResource(Object{this_}); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickMedianFilterImage(wand->getWand(), radius); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to median filter image"); } return true; } static Object HHVM_METHOD(Imagick, mergeImageLayers, int64_t layer_method) { auto wand = getMagickWandResource(Object{this_}); MagickSetFirstIterator(wand->getWand()); auto magick = MagickMergeImageLayers( wand->getWand(), (ImageLayerMethod)layer_method); if (magick == nullptr) { IMAGICK_THROW("Unable to merge image layers"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, minifyImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickMinifyImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to minify image"); } return true; } static bool HHVM_METHOD(Imagick, modulateImage, double brightness, double saturation, double hue) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickModulateImage( wand->getWand(), brightness, saturation, hue); if (status == MagickFalse) { IMAGICK_THROW("Unable to modulate image"); } return true; } static Object HHVM_METHOD(Imagick, montageImage, const Object& draw, const String& tile_geometry, const String& thumbnail_geometry, int64_t montage_mode, const String& frame) { auto wand = getMagickWandResource(Object{this_}); auto drawing = getDrawingWandResource(draw); auto magick = MagickMontageImage( wand->getWand(), drawing->getWand(), tile_geometry.c_str(), thumbnail_geometry.c_str(), (MontageMode)montage_mode, frame.c_str()); if (magick == nullptr) { IMAGICK_THROW("Montage image failed"); } return createImagick(magick); } static Object HHVM_METHOD(Imagick, morphImages, int64_t number_frames) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickMorphImages(wand->getWand(), number_frames); if (magick == nullptr) { IMAGICK_THROW("Morphing images failed"); } return createImagick(magick); } static Object HHVM_METHOD(Imagick, mosaicImages) { raiseDeprecated(s_Imagick.c_str(), "mosaicImages"); auto wand = getMagickWandResource(Object{this_}); MagickSetFirstIterator(wand->getWand()); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto magick = MagickMosaicImages(wand->getWand()); #pragma GCC diagnostic pop if (magick == nullptr) { IMAGICK_THROW("Mosaic image failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, motionBlurImage, double radius, double sigma, double angle, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickMotionBlurImageChannel( wand->getWand(), (ChannelType)channel, radius, sigma, angle); if (status == MagickFalse) { IMAGICK_THROW("Unable to motion blur image"); } return true; } static bool HHVM_METHOD(Imagick, negateImage, bool gray, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickNegateImageChannel( wand->getWand(), (ChannelType)channel, toMagickBool(gray)); if (status == MagickFalse) { IMAGICK_THROW("Unable to negate image"); } return true; } static bool HHVM_METHOD(Imagick, newImage, int64_t cols, int64_t rows, const Variant& background, const String& format) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(background); auto status = MagickNewImage(wand->getWand(), cols, rows, pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to create new image"); } if (!format.empty()) { auto status = MagickSetImageFormat(wand->getWand(), format.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set the image format"); } } return true; } static bool HHVM_METHOD(Imagick, newPseudoImage, int64_t columns, int64_t rows, const String& pseudoString) { auto wand = getMagickWandResource(Object{this_}); if (!isMagickPseudoFormat(pseudoString)) { IMAGICK_THROW("Invalid pseudo format string"); } auto status = MagickSetSize(wand->getWand(), columns, rows); if (status == MagickFalse) { IMAGICK_THROW("Unable to create new pseudo image"); } imagickReadOp(wand->getWand(), pseudoString, MagickReadImage); return true; } static bool HHVM_METHOD(Imagick, nextImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickNextImage(wand->getWand()); setImagePending(Object{this_}, status == MagickFalse); return status != MagickFalse; } static bool HHVM_METHOD(Imagick, normalizeImage, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickNormalizeImageChannel( wand->getWand(), (ChannelType)channel); if (status == MagickFalse) { IMAGICK_THROW("Unable to normalize image"); } return true; } static bool HHVM_METHOD(Imagick, oilPaintImage, double radius) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickOilPaintImage(wand->getWand(), radius); if (status == MagickFalse) { IMAGICK_THROW("Unable to oilpaint image"); } return true; } static bool HHVM_METHOD(Imagick, opaquePaintImage, const Variant& target, const Variant& fill, double fuzz, bool invert, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto fillPixel = buildColorWand(fill); auto targetPixel = buildColorWand(target); auto status = MagickOpaquePaintImageChannel( wand->getWand(), (ChannelType)channel, fillPixel->getWand(), targetPixel->getWand(), fuzz, toMagickBool(invert)); if (status == MagickFalse) { IMAGICK_THROW("Unable to opaque paint image"); } return true; } static Object HHVM_METHOD(Imagick, optimizeImageLayers) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickOptimizeImageLayers(wand->getWand()); if (magick == nullptr) { IMAGICK_THROW("Optimize image layers failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, orderedPosterizeImage, const String& threshold_map, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickOrderedPosterizeImageChannel( wand->getWand(), (ChannelType)channel, threshold_map.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to posterize image"); } return true; } static bool HHVM_METHOD(Imagick, paintFloodfillImage, const Variant& fill, double fuzz, const Variant& bordercolor, int64_t x, int64_t y, int64_t channel) { raiseDeprecated(s_Imagick.c_str(), "paintFloodfillImage"); auto wand = getMagickWandResource(Object{this_}); auto fillPixel = buildColorWand(fill); auto borderPixel = bordercolor.isNull() ? req::make<WandResource<PixelWand>>(nullptr) : buildColorWand(bordercolor); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickPaintFloodfillImage( wand->getWand(), (ChannelType)channel, fillPixel->getWand(), fuzz, borderPixel->getWand(), x, y); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to paint floodfill image"); } return true; } static bool HHVM_METHOD(Imagick, paintOpaqueImage, const Variant& target, const Variant& fill, double fuzz, int64_t channel) { raiseDeprecated(s_Imagick.c_str(), "paintOpaqueImage"); auto wand = getMagickWandResource(Object{this_}); auto fillPixel = buildColorWand(fill); auto targetPixel = buildColorWand(target); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickPaintOpaqueImageChannel( wand->getWand(), (ChannelType)channel, targetPixel->getWand(), fillPixel->getWand(), fuzz); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable paint opaque image"); } return true; } static bool HHVM_METHOD(Imagick, paintTransparentImage, const Variant& target, double alpha, double fuzz) { raiseDeprecated(s_Imagick.c_str(), "paintTransparentImage"); auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(target); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickPaintTransparentImage( wand->getWand(), pixel->getWand(), alpha, fuzz); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to paint transparent image"); } return true; } static bool HHVM_METHOD(Imagick, pingImage, const String& filename) { auto wand = getMagickWandResource(Object{this_}); imagickReadOp(wand->getWand(), filename, MagickPingImage); return true; } static bool HHVM_METHOD(Imagick, pingImageBlob, const String& image) { auto wand = getMagickWandResource(Object{this_}); if (image.empty()) { IMAGICK_THROW("Empty image string passed"); } auto status = MagickPingImageBlob( wand->getWand(), image.c_str(), image.size()); if (status == MagickFalse) { IMAGICK_THROW("Unable to ping image blob"); } return true; } static bool HHVM_METHOD(Imagick, pingImageFile, const Resource& filehandle, const String& /*fileName*/) { auto wand = getMagickWandResource(Object{this_}); imagickReadOp(wand->getWand(), filehandle, MagickPingImageFile); return true; } static bool HHVM_METHOD(Imagick, polaroidImage, const Object& properties, double angle) { auto wand = getMagickWandResource(Object{this_}); auto drawing = getDrawingWandResource(properties); auto status = MagickPolaroidImage( wand->getWand(), drawing->getWand(), angle); if (status == MagickFalse) { IMAGICK_THROW("Unable to polaroid image"); } return true; } static bool HHVM_METHOD(Imagick, posterizeImage, int64_t levels, bool dither) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickPosterizeImage( wand->getWand(), levels, toMagickBool(dither)); if (status == MagickFalse) { IMAGICK_THROW("Unable to posterize image"); } return true; } static Object HHVM_METHOD(Imagick, previewImages, int64_t preview) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickPreviewImages(wand->getWand(), (PreviewType)preview); if (magick == nullptr) { IMAGICK_THROW("Preview images failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, previousImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickPreviousImage(wand->getWand()); setImagePending(Object{this_}, false); return status != MagickFalse; } static bool HHVM_METHOD(Imagick, profileImage, const String& name, const String& profile) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickProfileImage( wand->getWand(), name.c_str(), profile.c_str(), profile.length()); if (status == MagickFalse) { IMAGICK_THROW("Unable to profile image"); } return true; } static bool HHVM_METHOD(Imagick, quantizeImage, int64_t numberColors, int64_t colorspace, int64_t treedepth, bool dither, bool measureError) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickQuantizeImage( wand->getWand(), numberColors, (ColorspaceType)colorspace, treedepth, toMagickBool(dither), toMagickBool(measureError)); if (status == MagickFalse) { IMAGICK_THROW("Unable to quantize image"); } return true; } static bool HHVM_METHOD(Imagick, quantizeImages, int64_t numberColors, int64_t colorspace, int64_t treedepth, bool dither, bool measureError) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickQuantizeImages( wand->getWand(), numberColors, (ColorspaceType)colorspace, treedepth, toMagickBool(dither), toMagickBool(measureError)); if (status == MagickFalse) { IMAGICK_THROW("Unable to quantize images"); } return true; } static Array HHVM_METHOD(Imagick, queryFontMetrics, const Object& properties, const String& text, const Variant& query_multiline) { auto wand = getMagickWandResource(Object{this_}); auto drawing = getDrawingWandResource(properties); // No parameter passed, this means we should autodetect bool multiline = query_multiline.isNull() ? text.find('\n') != String::npos : query_multiline.toBoolean(); // wand is empty, create a 1x1 pixel image to use as a temporary canvas bool removeCanvas; if (MagickGetNumberImages(wand->getWand()) < 1) { auto pixel = newPixelWand(); if (pixel->getWand() == nullptr) { IMAGICK_THROW( "Unable to allocate background color for the temporary canvas"); } auto status = MagickNewImage(wand->getWand(), 1, 1, pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to allocate temporary canvas"); } removeCanvas = true; } else { removeCanvas = false; } // Multiline testing double* metrics; if (multiline) { metrics = MagickQueryMultilineFontMetrics( wand->getWand(), drawing->getWand(), text.c_str()); } else { metrics = MagickQueryFontMetrics( wand->getWand(), drawing->getWand(), text.c_str()); } // Remove the image from the stack if (removeCanvas) { MagickRemoveImage(wand->getWand()); } if (metrics == nullptr) { IMAGICK_THROW("Failed to query the font metrics"); } else { static const StaticString keys[] = { s_characterWidth, s_characterHeight, s_ascender, s_descender, s_textWidth, s_textHeight, s_maxHorizontalAdvance, // s_x1, s_y1, s_x2, s_y2, s_boundingBox, empty_string_ref, empty_string_ref, empty_string_ref, s_originX, s_originY }; static const size_t boundingBoxOffset = 7; static const size_t size = 13; DictInit ret(size - 3); for (size_t i = 0; i < size; ++i) { if (keys[i] == s_boundingBox) { ret.set(s_boundingBox, make_dict_array( s_x1, metrics[boundingBoxOffset + 0], s_y1, metrics[boundingBoxOffset + 1], s_x2, metrics[boundingBoxOffset + 2], s_y2, metrics[boundingBoxOffset + 3])); } else if (!keys[i].empty()) { ret.set(keys[i], metrics[i]); } } freeMagickMemory(metrics); return ret.toArray(); } } static Array HHVM_STATIC_METHOD(Imagick, queryFonts, const String& pattern) { return magickQueryFonts(pattern.c_str()); } static Array HHVM_STATIC_METHOD(Imagick, queryFormats, const String& pattern) { return magickQueryFormats(pattern.c_str()); } static bool HHVM_METHOD(Imagick, radialBlurImage, double angle, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickRadialBlurImageChannel( wand->getWand(), (ChannelType)channel, angle); if (status == MagickFalse) { IMAGICK_THROW("Unable to radial blur image"); } return true; } static bool HHVM_METHOD(Imagick, raiseImage, int64_t width, int64_t height, int64_t x, int64_t y, bool raise) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickRaiseImage( wand->getWand(), width, height, x, y, toMagickBool(raise)); if (status == MagickFalse) { IMAGICK_THROW("Unable to raise image"); } return true; } static bool HHVM_METHOD(Imagick, randomThresholdImage, double low, double high, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickRandomThresholdImageChannel( wand->getWand(), (ChannelType)channel, low, high); if (status == MagickFalse) { IMAGICK_THROW("Unable to random threshold image"); } return true; } static bool HHVM_METHOD(Imagick, readImage, const String& filename) { auto wand = getMagickWandResource(Object{this_}); imagickReadOp(wand->getWand(), filename, MagickReadImage); return true; } static bool HHVM_METHOD(Imagick, readImageBlob, const String& image, const String& filename) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickReadImageBlob( wand->getWand(), image.c_str(), image.size()); if (status == MagickFalse) { IMAGICK_THROW("Unable to read image blob"); } if (!filename.empty()) { MagickSetImageFilename(wand->getWand(), filename.c_str()); } MagickSetLastIterator(wand->getWand()); return true; } static bool HHVM_METHOD(Imagick, readImageFile, const Resource& filehandle, const String& fileName) { auto wand = getMagickWandResource(Object{this_}); imagickReadOp(wand->getWand(), filehandle, MagickReadImageFile); if (!fileName.empty()) { MagickSetImageFilename(wand->getWand(), fileName.c_str()); } MagickSetLastIterator(wand->getWand()); return true; } static bool HHVM_METHOD(Imagick, readImages, const Array& files) { auto wand = getMagickWandResource(Object{this_}); for (ArrayIter it(files); it; ++it) { imagickReadOp( wand->getWand(), tvCastToString(it.secondValPlus()), MagickReadImage ); } return true; } static bool HHVM_METHOD(Imagick, recolorImage, const Array& matrix) { raiseDeprecated(s_Imagick.c_str(), "recolorImage"); auto wand = getMagickWandResource(Object{this_}); auto array = toDoubleArray(matrix); if (array.empty()) { IMAGICK_THROW("The map contains disallowed characters"); } auto order = (size_t)sqrt(array.size()); if (order * order != array.size()) { IMAGICK_THROW("The color matrix must contain a square number of elements"); } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickRecolorImage(wand->getWand(), order, array.data()); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to recolor image"); } return true; } static bool HHVM_METHOD(Imagick, reduceNoiseImage, double radius) { raiseDeprecated(s_Imagick.c_str(), "reduceNoiseImage"); auto wand = getMagickWandResource(Object{this_}); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickReduceNoiseImage(wand->getWand(), radius); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to reduce image noise"); } return true; } static bool HHVM_METHOD(Imagick, remapImage, const Object& replacement, int64_t dither) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(replacement); auto status = MagickRemapImage( wand->getWand(), wand2->getWand(), (DitherMethod)dither); if (status == MagickFalse) { IMAGICK_THROW("Unable to remap image"); } return true; } static bool HHVM_METHOD(Imagick, removeImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickRemoveImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to remove image"); } MagickSetLastIterator(wand->getWand()); setImagePending(Object{this_}, true); return true; } static String HHVM_METHOD(Imagick, removeImageProfile, const String& name) { auto wand = getMagickWandResource(Object{this_}); size_t length; auto profile = MagickRemoveImageProfile( wand->getWand(), name.c_str(), &length); if (profile == nullptr) { IMAGICK_THROW("The image profile does not exist"); } else { return convertMagickData(length, profile); } } static bool HHVM_METHOD(Imagick, resampleImage, double x_resolution, double y_resolution, int64_t filter, double blur) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickResampleImage( wand->getWand(), x_resolution, y_resolution, (FilterTypes)filter, blur); if (status == MagickFalse) { IMAGICK_THROW("Unable to resample image"); } return true; } static bool HHVM_METHOD(Imagick, resetImagePage, const String& page) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickResetImagePage(wand->getWand(), page.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to reset image page"); } return true; } static bool HHVM_METHOD(Imagick, resizeImage, int64_t columns, int64_t rows, int64_t filter, double blur, bool bestfit) { auto wand = getMagickWandResource(Object{this_}); auto geometry = ImageGeometry(wand->getWand()).toThumbnail( {columns, rows}, bestfit); if (geometry.empty()) { IMAGICK_THROW("Invalid image geometry"); } auto status = MagickResizeImage( wand->getWand(), geometry.getWidth(), geometry.getHeight(), (FilterTypes)filter, blur); if (status == MagickFalse) { IMAGICK_THROW("Unable to resize image"); } return true; } static bool HHVM_METHOD(Imagick, rollImage, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickRollImage(wand->getWand(), x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to roll image"); } return true; } static bool HHVM_METHOD(Imagick, rotateImage, const Variant& background, double degrees) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(background); auto status = MagickRotateImage(wand->getWand(), pixel->getWand(), degrees); if (status == MagickFalse) { IMAGICK_THROW("Unable to rotate image"); } return true; } static bool HHVM_METHOD(Imagick, roundCornersImage, double x_rounding, double y_rounding, double stroke_width, double displace, double size_correction) { auto wand = getMagickWandResource(Object{this_}); auto geometry = ImageGeometry(wand->getWand()); if (geometry.empty()) { IMAGICK_THROW("Unable to round corners on empty image"); } if (MagickSetImageMatte(wand->getWand(), MagickTrue) == MagickFalse) { IMAGICK_THROW("Unable to set image matte"); } auto pixel = newPixelWand(); if (pixel->getWand() == nullptr) { IMAGICK_THROW("Failed to allocate PixelWand structure"); } auto drawing = req::make<WandResource<DrawingWand>>(NewDrawingWand()); if (drawing->getWand() == nullptr) { IMAGICK_THROW("Failed to allocate DrawingWand structure"); } auto magick = req::make<WandResource<MagickWand>>(NewMagickWand()); if (magick->getWand() == nullptr) { IMAGICK_THROW("Failed to allocate MagickWand structure"); } if (PixelSetColor(pixel->getWand(), "transparent") == MagickFalse) { IMAGICK_THROW("Unable to set pixel color"); } if (MagickNewImage(magick->getWand(), geometry.getWidth(), geometry.getHeight(), pixel->getWand()) == MagickFalse) { IMAGICK_THROW("Unable to allocate mask image"); } MagickSetImageBackgroundColor(magick->getWand(), pixel->getWand()); if (PixelSetColor(pixel->getWand(), "white") == MagickFalse) { IMAGICK_THROW("Unable to set pixel color"); } DrawSetFillColor(drawing->getWand(), pixel->getWand()); if (PixelSetColor(pixel->getWand(), "black") == MagickFalse) { IMAGICK_THROW("Unable to set pixel color"); } DrawSetStrokeColor(drawing->getWand(), pixel->getWand()); DrawSetStrokeWidth(drawing->getWand(), stroke_width); DrawRoundRectangle(drawing->getWand(), displace, displace, geometry.getWidth() + size_correction, geometry.getHeight() + size_correction, x_rounding, y_rounding); auto status = withMagickLocaleFix([&magick, &drawing](){ return MagickDrawImage(magick->getWand(), drawing->getWand()); }); if (status == MagickFalse) { IMAGICK_THROW("Unable to draw on image"); } if (MagickCompositeImage(wand->getWand(), magick->getWand(), DstInCompositeOp, 0, 0) == MagickFalse) { IMAGICK_THROW("Unable to composite image"); } return true; } static bool HHVM_METHOD(Imagick, roundCorners, double x_rounding, double y_rounding, double stroke_width, double displace, double size_correction) { // raiseDeprecated(s_Imagick.c_str(), "roundCorners", // s_Imagick.c_str(), "roundCornersImage"); return HHVM_MN(Imagick, roundCornersImage)( this_, x_rounding, y_rounding, stroke_width, displace, size_correction); } static bool HHVM_METHOD(Imagick, sampleImage, int64_t columns, int64_t rows) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSampleImage(wand->getWand(), columns, rows); if (status == MagickFalse) { IMAGICK_THROW("Unable to sample image"); } return true; } static bool HHVM_METHOD(Imagick, scaleImage, int64_t cols, int64_t rows, bool bestfit) { auto wand = getMagickWandResource(Object{this_}); auto geometry = ImageGeometry(wand->getWand()).toThumbnail( {cols, rows}, bestfit); if (geometry.empty()) { IMAGICK_THROW("Invalid image geometry"); } auto status = MagickScaleImage( wand->getWand(), geometry.getWidth(), geometry.getHeight()); if (status == MagickFalse) { IMAGICK_THROW("Unable to scale image"); } return true; } static bool HHVM_METHOD(Imagick, segmentImage, int64_t colorspace, double cluster_threshold, double smooth_threshold, bool verbose) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSegmentImage( wand->getWand(), (ColorspaceType)colorspace, toMagickBool(verbose), cluster_threshold, smooth_threshold); if (status == MagickFalse) { IMAGICK_THROW("Unable to segment image"); } return true; } static bool HHVM_METHOD(Imagick, separateImageChannel, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSeparateImageChannel( wand->getWand(), (ChannelType)channel); if (status == MagickFalse) { IMAGICK_THROW("Unable to separate image channel"); } return true; } static bool HHVM_METHOD(Imagick, sepiaToneImage, double threshold) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSepiaToneImage(wand->getWand(), threshold); if (status == MagickFalse) { IMAGICK_THROW("Unable to sepia tone image"); } return true; } static bool HHVM_METHOD(Imagick, setBackgroundColor, const Variant& background) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(background); auto status = MagickSetBackgroundColor(wand->getWand(), pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set background color"); } return true; } static bool HHVM_METHOD(Imagick, setColorspace, int64_t colorspace) { auto wand = getMagickWandResource(Object{this_}); return MagickSetColorspace( wand->getWand(), (ColorspaceType)colorspace) != MagickFalse; } static bool HHVM_METHOD(Imagick, setCompression, int64_t compression) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetCompression( wand->getWand(), (CompressionType)compression); if (status == MagickFalse) { IMAGICK_THROW("Unable to set compression"); } return true; } static bool HHVM_METHOD(Imagick, setCompressionQuality, int64_t quality) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetCompressionQuality(wand->getWand(), quality); if (status == MagickFalse) { IMAGICK_THROW("Unable to set compression quality"); } return true; } static bool HHVM_METHOD(Imagick, setFilename, const String& filename) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetFilename(wand->getWand(), filename.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set filename"); } return true; } static bool HHVM_METHOD(Imagick, setFirstIterator) { auto wand = getMagickWandResource(Object{this_}); MagickSetFirstIterator(wand->getWand()); setImagePending(Object{this_}, false); return true; } static bool HHVM_METHOD(Imagick, setFont, const String& fontName) { auto wand = getMagickWandResource(Object{this_}); auto font = magickResolveFont(fontName); if (font.isNull() || MagickSetFont(wand->getWand(), font.c_str()) == MagickFalse) { IMAGICK_THROW("Unable to set font"); } return true; } static bool HHVM_METHOD(Imagick, setFormat, const String& format) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetFormat(wand->getWand(), format.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set format"); } return true; } static bool HHVM_METHOD(Imagick, setGravity, int64_t gravity) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetGravity(wand->getWand(), (GravityType)gravity); if (status == MagickFalse) { IMAGICK_THROW("Unable to set gravity"); } return true; } static bool HHVM_METHOD(Imagick, setImage, const Object& replace) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(replace); auto status = MagickSetImage(wand->getWand(), wand2->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set the image"); } return true; } static bool HHVM_METHOD(Imagick, setImageAlphaChannel, int64_t mode) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageAlphaChannel( wand->getWand(), (AlphaChannelType)mode); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image alpha channel"); } return true; } static bool HHVM_METHOD(Imagick, setImageArtifact, const String& artifact, const String& value) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageArtifact( wand->getWand(), artifact.c_str(), value.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image artifact"); } return true; } static bool HHVM_METHOD(Imagick, setImageBackgroundColor, const Variant& background) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(background); auto status = MagickSetImageBackgroundColor( wand->getWand(), pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image background color"); } return true; } static bool HHVM_METHOD(Imagick, setImageBias, double bias) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageBias(wand->getWand(), bias); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image bias"); } return true; } static bool HHVM_METHOD(Imagick, setImageBluePrimary, double x, double y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageBluePrimary(wand->getWand(), x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image blue primary"); } return true; } static bool HHVM_METHOD(Imagick, setImageBorderColor, const Variant& border) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(border); auto status = MagickSetImageBorderColor(wand->getWand(), pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image border color"); } return true; } static bool HHVM_METHOD(Imagick, setImageChannelDepth, int64_t channel, int64_t depth) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageChannelDepth( wand->getWand(), (ChannelType)channel, depth); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image channel depth"); } return true; } static bool HHVM_METHOD(Imagick, setImageClipMask, const Object& clip_mask) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(clip_mask); auto status = MagickSetImageClipMask(wand->getWand(), wand2->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image clip mask"); } return true; } static bool HHVM_METHOD(Imagick, setImageColormapColor, int64_t index, const Object& color) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(color); auto status = MagickSetImageColormapColor( wand->getWand(), index, pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image color map color"); } return true; } static bool HHVM_METHOD(Imagick, setImageColorspace, int64_t colorspace) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageColorspace( wand->getWand(), (ColorspaceType)colorspace); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image colorspace"); } return true; } static bool HHVM_METHOD(Imagick, setImageCompose, int64_t compose) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageCompose( wand->getWand(), (CompositeOperator)compose); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image composite operator"); } return true; } static bool HHVM_METHOD(Imagick, setImageCompression, int64_t compression) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageCompression( wand->getWand(), (CompressionType)compression); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image compression"); } return true; } static bool HHVM_METHOD(Imagick, setImageCompressionQuality, int64_t quality) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageCompressionQuality(wand->getWand(), quality); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image compression quality"); } return true; } static bool HHVM_METHOD(Imagick, setImageDelay, int64_t delay) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageDelay(wand->getWand(), delay); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image delay"); } return true; } static bool HHVM_METHOD(Imagick, setImageDepth, int64_t depth) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageDepth(wand->getWand(), depth); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image depth"); } return true; } static bool HHVM_METHOD(Imagick, setImageDispose, int64_t dispose) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageDispose( wand->getWand(), (DisposeType)dispose); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image dispose"); } return true; } static bool HHVM_METHOD(Imagick, setImageExtent, int64_t columns, int64_t rows) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageExtent(wand->getWand(), columns, rows); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image extent"); } return true; } static bool HHVM_METHOD(Imagick, setImageFilename, const String& filename) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageFilename(wand->getWand(), filename.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image filename"); } return true; } static bool HHVM_METHOD(Imagick, setImageFormat, const String& format) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageFormat(wand->getWand(), format.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image format"); } return true; } static bool HHVM_METHOD(Imagick, setImageGamma, double gamma) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageGamma(wand->getWand(), gamma); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image gamma"); } return true; } static bool HHVM_METHOD(Imagick, setImageGravity, int64_t gravity) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageGravity( wand->getWand(), (GravityType)gravity); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image gravity"); } return true; } static bool HHVM_METHOD(Imagick, setImageGreenPrimary, double x, double y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageGreenPrimary(wand->getWand(), x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image green primary"); } return true; } static bool HHVM_METHOD(Imagick, setImageIndex, int64_t index) { raiseDeprecated(s_Imagick.c_str(), "setImageIndex"); auto wand = getMagickWandResource(Object{this_}); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" auto status = MagickSetImageIndex(wand->getWand(), index); #pragma GCC diagnostic pop if (status == MagickFalse) { IMAGICK_THROW("Unable to set image index"); } setImagePending(Object{this_}, false); return true; } static bool HHVM_METHOD(Imagick, setImageInterlaceScheme, int64_t interlace_scheme) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageInterlaceScheme( wand->getWand(), (InterlaceType)interlace_scheme); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image interlace scheme"); } return true; } static bool HHVM_METHOD(Imagick, setImageInterpolateMethod, int64_t method) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageInterpolateMethod( wand->getWand(), (InterpolatePixelMethod)method); if (status == MagickFalse) { IMAGICK_THROW("Unable to set the image interpolate method"); } return true; } static bool HHVM_METHOD(Imagick, setImageIterations, int64_t iterations) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageIterations(wand->getWand(), iterations); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image iterations"); } return true; } static bool HHVM_METHOD(Imagick, setImageMatte, bool matte) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageMatte(wand->getWand(), toMagickBool(matte)); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image matte"); } return true; } static bool HHVM_METHOD(Imagick, setImageMatteColor, const Variant& matte) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(matte); auto status = MagickSetImageMatteColor(wand->getWand(), pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image matte color"); } return true; } static bool HHVM_METHOD(Imagick, setImageOpacity, double opacity) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageOpacity(wand->getWand(), opacity); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image opacity"); } return true; } static bool HHVM_METHOD(Imagick, setImageOrientation, int64_t orientation) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageOrientation( wand->getWand(), (OrientationType)orientation); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image orientation"); } return true; } static bool HHVM_METHOD(Imagick, setImagePage, int64_t width, int64_t height, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImagePage(wand->getWand(), width, height, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image page"); } return true; } static bool HHVM_METHOD(Imagick, setImageProfile, const String& name, const String& profile) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageProfile( wand->getWand(), name.c_str(), profile.c_str(), profile.length()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image profile"); } return true; } static bool HHVM_METHOD(Imagick, setImageProperty, const String& name, const String& value) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageProperty( wand->getWand(), name.c_str(), value.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image property"); } return true; } static bool HHVM_METHOD(Imagick, setImageRedPrimary, double x, double y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageRedPrimary(wand->getWand(), x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image red primary"); } return true; } static bool HHVM_METHOD(Imagick, setImageRenderingIntent, int64_t rendering_intent) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageRenderingIntent( wand->getWand(), (RenderingIntent)rendering_intent); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image rendering intent"); } return true; } static bool HHVM_METHOD(Imagick, setImageResolution, double x_resolution, double y_resolution) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageResolution( wand->getWand(), x_resolution, y_resolution); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image resolution"); } return true; } static bool HHVM_METHOD(Imagick, setImageScene, int64_t scene) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageScene(wand->getWand(), scene); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image scene"); } return true; } static bool HHVM_METHOD(Imagick, setImageTicksPerSecond, int64_t ticks_per_second) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageTicksPerSecond( wand->getWand(), ticks_per_second); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image ticks per second"); } return true; } static bool HHVM_METHOD(Imagick, setImageType, int64_t image_type) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageType( wand->getWand(), (ImageType)image_type); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image type"); } return true; } static bool HHVM_METHOD(Imagick, setImageUnits, int64_t units) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageUnits( wand->getWand(), (ResolutionType)units); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image units"); } return true; } static bool HHVM_METHOD(Imagick, setImageVirtualPixelMethod, int64_t method) { auto wand = getMagickWandResource(Object{this_}); MagickSetImageVirtualPixelMethod( wand->getWand(), (VirtualPixelMethod)method); return true; } static bool HHVM_METHOD(Imagick, setImageWhitePoint, double x, double y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetImageWhitePoint(wand->getWand(), x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to set image white point"); } return true; } static bool HHVM_METHOD(Imagick, setInterlaceScheme, int64_t interlace_scheme) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetInterlaceScheme( wand->getWand(), (InterlaceType)interlace_scheme); if (status == MagickFalse) { IMAGICK_THROW("Unable to set interlace scheme"); } return true; } static bool HHVM_METHOD(Imagick, setIteratorIndex, int64_t index) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetIteratorIndex(wand->getWand(), index); if (status == MagickFalse) { IMAGICK_THROW("Unable to set iterator index"); } setImagePending(Object{this_}, false); return true; } static bool HHVM_METHOD(Imagick, setLastIterator) { auto wand = getMagickWandResource(Object{this_}); MagickSetLastIterator(wand->getWand()); setImagePending(Object{this_}, true); return true; } static bool HHVM_METHOD(Imagick, setOption, const String& key, const String& value) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetOption(wand->getWand(), key.c_str(), value.c_str()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set option"); } return true; } static bool HHVM_METHOD(Imagick, setPage, int64_t width, int64_t height, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetPage(wand->getWand(), width, height, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to set page"); } return true; } static bool HHVM_METHOD(Imagick, setPointSize, double point_size) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetPointsize(wand->getWand(), point_size); if (status == MagickFalse) { IMAGICK_THROW("Unable to set point size"); } return true; } static bool HHVM_METHOD(Imagick, setResolution, double x_resolution, double y_resolution) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetResolution( wand->getWand(), x_resolution, y_resolution); if (status == MagickFalse) { IMAGICK_THROW("Unable to set resolution"); } return true; } static bool HHVM_STATIC_METHOD(Imagick, setResourceLimit, int64_t type, int64_t limit) { auto status = MagickSetResourceLimit((ResourceType)type, limit); if (status == MagickFalse) { IMAGICK_THROW("Unable to set resource limit"); } return true; } static bool HHVM_METHOD(Imagick, setSamplingFactors, const Array& factors) { auto wand = getMagickWandResource(Object{this_}); auto array = toDoubleArray(factors); if (array.empty()) { IMAGICK_THROW("Can't read array"); } auto status = MagickSetSamplingFactors( wand->getWand(), array.size(), array.data()); if (status == MagickFalse) { IMAGICK_THROW("Unable to set sampling factors"); } return true; } static bool HHVM_METHOD(Imagick, setSize, int64_t columns, int64_t rows) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetSize(wand->getWand(), columns, rows); if (status == MagickFalse) { IMAGICK_THROW("Unable to set size"); } return true; } static bool HHVM_METHOD(Imagick, setSizeOffset, int64_t columns, int64_t rows, int64_t offset) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetSizeOffset(wand->getWand(), columns, rows, offset); if (status == MagickFalse) { IMAGICK_THROW("Unable to set size offset"); } return true; } static bool HHVM_METHOD(Imagick, setType, int64_t image_type) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSetType( wand->getWand(), (ImageType)image_type); if (status == MagickFalse) { IMAGICK_THROW("Unable to set type"); } return true; } static bool HHVM_METHOD(Imagick, shadeImage, bool gray, double azimuth, double elevation) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickShadeImage( wand->getWand(), toMagickBool(gray), azimuth, elevation); if (status == MagickFalse) { IMAGICK_THROW("Unable to shade image"); } return true; } static bool HHVM_METHOD(Imagick, shadowImage, double opacity, double sigma, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickShadowImage(wand->getWand(), opacity, sigma, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to shadow image"); } return true; } static bool HHVM_METHOD(Imagick, sharpenImage, double radius, double sigma, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSharpenImageChannel( wand->getWand(), (ChannelType)channel, radius, sigma); if (status == MagickFalse) { IMAGICK_THROW("Unable to sharpen image"); } return true; } static bool HHVM_METHOD(Imagick, shaveImage, int64_t columns, int64_t rows) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickShaveImage(wand->getWand(), columns, rows); if (status == MagickFalse) { IMAGICK_THROW("Unable to shave image"); } return true; } static bool HHVM_METHOD(Imagick, shearImage, const Variant& background, double x_shear, double y_shear) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(background); auto status = MagickShearImage( wand->getWand(), pixel->getWand(), x_shear, y_shear); if (status == MagickFalse) { IMAGICK_THROW("Unable to shear image"); } return true; } static bool HHVM_METHOD(Imagick, sigmoidalContrastImage, bool sharpen, double alpha, double beta, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSigmoidalContrastImageChannel( wand->getWand(), (ChannelType)channel, toMagickBool(sharpen), alpha, beta); if (status == MagickFalse) { IMAGICK_THROW("Unable to sigmoidal contrast image"); } return true; } static bool HHVM_METHOD(Imagick, sketchImage, double radius, double sigma, double angle) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSketchImage(wand->getWand(), radius, sigma, angle); if (status == MagickFalse) { IMAGICK_THROW("Unable to sketch image"); } return true; } static bool HHVM_METHOD(Imagick, solarizeImage, int64_t threshold) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSolarizeImage(wand->getWand(), threshold); if (status == MagickFalse) { IMAGICK_THROW("Unable to solarize image"); } return true; } static bool HHVM_METHOD(Imagick, sparseColorImage, int64_t sparse, const Array& arguments, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto array = toDoubleArray(arguments); if (array.empty()) { IMAGICK_THROW("The map must contain only numeric values"); } auto status = MagickSparseColorImage( wand->getWand(), (ChannelType)channel, (SparseColorMethod)sparse, array.size(), array.data()); if (status == MagickFalse) { IMAGICK_THROW("Unable to sparse color image"); } return true; } static bool HHVM_METHOD(Imagick, spliceImage, int64_t width, int64_t height, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSpliceImage(wand->getWand(), width, height, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to splice image"); } return true; } static bool HHVM_METHOD(Imagick, spreadImage, double radius) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSpreadImage(wand->getWand(), radius); if (status == MagickFalse) { IMAGICK_THROW("Unable to spread image"); } return true; } static Object HHVM_METHOD(Imagick, steganoImage, const Object& watermark_wand, int64_t offset) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(watermark_wand); auto magick = MagickSteganoImage(wand->getWand(), wand2->getWand(), offset); if (magick == nullptr) { IMAGICK_THROW("Stegano image failed"); } return createImagick(magick); } static Object HHVM_METHOD(Imagick, stereoImage, const Object& offset_wand) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(offset_wand); auto magick = MagickStereoImage(wand->getWand(), wand2->getWand()); if (magick == nullptr) { IMAGICK_THROW("Stereo image failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, stripImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickStripImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to strip image"); } return true; } static bool HHVM_METHOD(Imagick, swirlImage, double degrees) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickSwirlImage(wand->getWand(), degrees); if (status == MagickFalse) { IMAGICK_THROW("Unable to swirl image"); } return true; } static Object HHVM_METHOD(Imagick, textureImage, const Object& texture_wand) { auto wand = getMagickWandResource(Object{this_}); auto wand2 = getMagickWandResource(texture_wand); auto magick = MagickTextureImage(wand->getWand(), wand2->getWand()); if (magick == nullptr) { IMAGICK_THROW("Texture image failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, thresholdImage, double threshold, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickThresholdImageChannel( wand->getWand(), (ChannelType)channel, threshold); if (status == MagickFalse) { IMAGICK_THROW("Unable to threshold image"); } return true; } static bool HHVM_METHOD(Imagick, thumbnailImage, int64_t cols, int64_t rows, bool bestfit, bool fill) { auto wand = getMagickWandResource(Object{this_}); auto geometry = ImageGeometry(wand->getWand()).toThumbnail( {cols, rows}, bestfit); if (geometry.empty()) { IMAGICK_THROW("Invalid image geometry"); } // Resize the image to the new size auto status = MagickThumbnailImage( wand->getWand(), geometry.getWidth(), geometry.getHeight()); if (status == MagickFalse) { IMAGICK_THROW("Unable to thumbnail image"); } // If the image does not fill the box completely the box is filled with // image's background color. if (bestfit && fill) { auto extent_x = std::max<ssize_t>(0, (cols - geometry.getWidth()) / 2); auto extent_y = std::max<ssize_t>(0, (rows - geometry.getHeight()) / 2); auto status = MagickExtentImage( wand->getWand(), cols, rows, -extent_x, -extent_y); if (status == MagickFalse) { IMAGICK_THROW("Unable to resize and fill image"); } } return true; } static bool HHVM_METHOD(Imagick, tintImage, const Variant& tint, const Variant& opacity) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(tint); auto opacityPixel = buildOpacityWand(opacity); auto status = MagickTintImage( wand->getWand(), pixel->getWand(), opacityPixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable tint image"); } return true; } static Object HHVM_METHOD(Imagick, transformImage, const String& crop, const String& geometry) { auto wand = getMagickWandResource(Object{this_}); auto magick = MagickTransformImage( wand->getWand(), crop.c_str(), geometry.c_str()); if (!magick) { IMAGICK_THROW("Transforming image failed"); } return createImagick(magick); } static bool HHVM_METHOD(Imagick, transparentPaintImage, const Variant& target, double alpha, double fuzz, bool invert) { auto wand = getMagickWandResource(Object{this_}); auto targetPixel = buildColorWand(target); auto status = MagickTransparentPaintImage( wand->getWand(), targetPixel->getWand(), alpha, fuzz, toMagickBool(invert)); if (status == MagickFalse) { IMAGICK_THROW("Unable to paint transparent image"); } return true; } static bool HHVM_METHOD(Imagick, transposeImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickTransposeImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to transpose image"); } return true; } static bool HHVM_METHOD(Imagick, transverseImage) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickTransverseImage(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to transverse image"); } return true; } static bool HHVM_METHOD(Imagick, trimImage, double fuzz) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickTrimImage(wand->getWand(), fuzz); if (status == MagickFalse) { IMAGICK_THROW("Unable to trim image"); } return true; } static bool HHVM_METHOD(Imagick, uniqueImageColors) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickUniqueImageColors(wand->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to get unique image colors"); } return true; } static bool HHVM_METHOD(Imagick, unsharpMaskImage, double radius, double sigma, double amount, double threshold, int64_t channel) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickUnsharpMaskImageChannel( wand->getWand(), (ChannelType)channel, radius, sigma, amount, threshold); if (status == MagickFalse) { IMAGICK_THROW("Unable to unsharp mask image"); } return true; } static bool HHVM_METHOD(Imagick, vignetteImage, double blackPoint, double whitePoint, int64_t x, int64_t y) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickVignetteImage( wand->getWand(), blackPoint, whitePoint, x, y); if (status == MagickFalse) { IMAGICK_THROW("Unable to apply vignette filter"); } return true; } static bool HHVM_METHOD(Imagick, waveImage, double amplitude, double length) { auto wand = getMagickWandResource(Object{this_}); auto status = MagickWaveImage(wand->getWand(), amplitude, length); if (status == MagickFalse) { IMAGICK_THROW("Unable to wave image"); } return true; } static bool HHVM_METHOD(Imagick, whiteThresholdImage, const Variant& threshold) { auto wand = getMagickWandResource(Object{this_}); auto pixel = buildColorWand(threshold); auto status = MagickWhiteThresholdImage(wand->getWand(), pixel->getWand()); if (status == MagickFalse) { IMAGICK_THROW("Unable to white threshold image"); } return true; } static bool HHVM_METHOD(Imagick, writeImage, const String& filename) { auto wand = getMagickWandResource(Object{this_}); imagickWriteOp(wand->getWand(), filename, MagickWriteImage); return true; } static bool HHVM_METHOD(Imagick, writeImageFile, const Resource& filehandle, const String& format) { auto wand = getMagickWandResource(Object{this_}); imagickWriteOp(wand->getWand(), filehandle, format, MagickWriteImageFile); return true; } static bool HHVM_METHOD(Imagick, writeImages, const String& filename, bool adjoin) { auto wand = getMagickWandResource(Object{this_}); imagickWriteOp(wand->getWand(), filename, [=](MagickWand* magick, const char* path) { return MagickWriteImages(magick, path, toMagickBool(adjoin)); }); return true; } static bool HHVM_METHOD(Imagick, writeImagesFile, const Resource& filehandle, const String& format) { auto wand = getMagickWandResource(Object{this_}); imagickWriteOp(wand->getWand(), filehandle, format, MagickWriteImagesFile); return true; } // Countable interface static int HHVM_METHOD(Imagick, count) { return HHVM_MN(Imagick, getNumberImages)(this_); } // Iterator interface static Object HHVM_METHOD(Imagick, current) { return Object{this_}; } static int HHVM_METHOD(Imagick, key) { return HHVM_MN(Imagick, getIteratorIndex)(this_); } static void HHVM_METHOD(Imagick, next) { HHVM_MN(Imagick, nextImage)(this_); } static void HHVM_METHOD(Imagick, rewind) { HHVM_MN(Imagick, setFirstIterator)(this_); } static bool HHVM_METHOD(Imagick, valid) { return !getImagePending(Object{this_}); } template<size_t (*get)(_MagickWand*)> static Variant get_size(const Object& this_) { return get(getMagickWandResource(Object{this_})->getWand()); } static Variant get_image_format(const Object& this_) { return HHVM_MN(Imagick, getImageFormat)(this_.get()); } static Native::PropAccessor imagick_properties[] = { { "width", get_size<MagickGetImageWidth> }, { "height", get_size<MagickGetImageHeight> }, { "format", get_image_format }, { nullptr } }; Native::PropAccessorMap imagick_properties_map{imagick_properties}; struct ImagickPropHandler : Native::MapPropHandler<ImagickPropHandler> { static constexpr Native::PropAccessorMap& map = imagick_properties_map; }; #undef IMAGICK_THROW void ImagickExtension::loadImagickClass() { HHVM_ME(Imagick, adaptiveBlurImage); HHVM_ME(Imagick, adaptiveResizeImage); HHVM_ME(Imagick, adaptiveSharpenImage); HHVM_ME(Imagick, adaptiveThresholdImage); HHVM_ME(Imagick, addImage); HHVM_ME(Imagick, addNoiseImage); HHVM_ME(Imagick, affineTransformImage); HHVM_ME(Imagick, animateImages); HHVM_ME(Imagick, annotateImage); HHVM_ME(Imagick, appendImages); HHVM_ME(Imagick, averageImages); HHVM_ME(Imagick, blackThresholdImage); HHVM_ME(Imagick, blurImage); HHVM_ME(Imagick, borderImage); HHVM_ME(Imagick, charcoalImage); HHVM_ME(Imagick, chopImage); HHVM_ME(Imagick, clear); HHVM_ME(Imagick, clipImage); HHVM_ME(Imagick, clipPathImage); HHVM_ME(Imagick, __clone); HHVM_ME(Imagick, clutImage); HHVM_ME(Imagick, coalesceImages); HHVM_ME(Imagick, colorFloodfillImage); HHVM_ME(Imagick, colorizeImage); HHVM_ME(Imagick, combineImages); HHVM_ME(Imagick, commentImage); HHVM_ME(Imagick, compareImageChannels); HHVM_ME(Imagick, compareImageLayers); HHVM_ME(Imagick, compareImages); HHVM_ME(Imagick, compositeImage); HHVM_ME(Imagick, __construct); HHVM_ME(Imagick, contrastImage); HHVM_ME(Imagick, contrastStretchImage); HHVM_ME(Imagick, convolveImage); HHVM_ME(Imagick, cropImage); HHVM_ME(Imagick, cropThumbnailImage); HHVM_ME(Imagick, cycleColormapImage); HHVM_ME(Imagick, decipherImage); HHVM_ME(Imagick, deconstructImages); HHVM_ME(Imagick, deleteImageArtifact); HHVM_ME(Imagick, deskewImage); HHVM_ME(Imagick, despeckleImage); HHVM_ME(Imagick, destroy); HHVM_ME(Imagick, displayImage); HHVM_ME(Imagick, displayImages); HHVM_ME(Imagick, distortImage); HHVM_ME(Imagick, drawImage); HHVM_ME(Imagick, edgeImage); HHVM_ME(Imagick, embossImage); HHVM_ME(Imagick, encipherImage); HHVM_ME(Imagick, enhanceImage); HHVM_ME(Imagick, equalizeImage); HHVM_ME(Imagick, evaluateImage); HHVM_ME(Imagick, exportImagePixels); HHVM_ME(Imagick, extentImage); HHVM_ME(Imagick, flattenImages); HHVM_ME(Imagick, flipImage); HHVM_ME(Imagick, floodFillPaintImage); HHVM_ME(Imagick, flopImage); HHVM_ME(Imagick, frameImage); HHVM_ME(Imagick, functionImage); HHVM_ME(Imagick, fxImage); HHVM_ME(Imagick, gammaImage); HHVM_ME(Imagick, gaussianBlurImage); HHVM_ME(Imagick, getColorspace); HHVM_ME(Imagick, getCompression); HHVM_ME(Imagick, getCompressionQuality); HHVM_STATIC_ME(Imagick, getCopyright); HHVM_ME(Imagick, getFilename); HHVM_ME(Imagick, getFont); HHVM_ME(Imagick, getFormat); HHVM_ME(Imagick, getGravity); HHVM_STATIC_ME(Imagick, getHomeURL); HHVM_ME(Imagick, getImage); HHVM_ME(Imagick, getImageAlphaChannel); HHVM_ME(Imagick, getImageArtifact); HHVM_ME(Imagick, getImageBackgroundColor); HHVM_ME(Imagick, getImageBlob); HHVM_ME(Imagick, getImageBluePrimary); HHVM_ME(Imagick, getImageBorderColor); HHVM_ME(Imagick, getImageChannelDepth); HHVM_ME(Imagick, getImageChannelDistortion); HHVM_ME(Imagick, getImageChannelDistortions); HHVM_ME(Imagick, getImageChannelExtrema); HHVM_ME(Imagick, getImageChannelKurtosis); HHVM_ME(Imagick, getImageChannelMean); HHVM_ME(Imagick, getImageChannelRange); HHVM_ME(Imagick, getImageChannelStatistics); HHVM_ME(Imagick, getImageClipMask); HHVM_ME(Imagick, getImageColormapColor); HHVM_ME(Imagick, getImageColors); HHVM_ME(Imagick, getImageColorspace); HHVM_ME(Imagick, getImageCompose); HHVM_ME(Imagick, getImageCompression); HHVM_ME(Imagick, getImageDelay); HHVM_ME(Imagick, getImageDepth); HHVM_ME(Imagick, getImageDispose); HHVM_ME(Imagick, getImageDistortion); HHVM_ME(Imagick, getImageExtrema); HHVM_ME(Imagick, getImageFilename); HHVM_ME(Imagick, getImageFormat); HHVM_ME(Imagick, getImageGamma); HHVM_ME(Imagick, getImageGeometry); HHVM_ME(Imagick, getImageGravity); HHVM_ME(Imagick, getImageGreenPrimary); HHVM_ME(Imagick, getImageHeight); HHVM_ME(Imagick, getImageHistogram); HHVM_ME(Imagick, getImageIndex); HHVM_ME(Imagick, getImageInterlaceScheme); HHVM_ME(Imagick, getImageInterpolateMethod); HHVM_ME(Imagick, getImageIterations); HHVM_ME(Imagick, getImageLength); HHVM_ME(Imagick, getImageMatte); HHVM_ME(Imagick, getImageMatteColor); HHVM_ME(Imagick, getImageMimeType); HHVM_ME(Imagick, getImageOrientation); HHVM_ME(Imagick, getImagePage); HHVM_ME(Imagick, getImagePixelColor); HHVM_ME(Imagick, getImageProfile); HHVM_ME(Imagick, getImageProfiles); HHVM_ME(Imagick, getImageProperties); HHVM_ME(Imagick, getImageProperty); HHVM_ME(Imagick, getImageRedPrimary); HHVM_ME(Imagick, getImageRegion); HHVM_ME(Imagick, getImageRenderingIntent); HHVM_ME(Imagick, getImageResolution); HHVM_ME(Imagick, getImagesBlob); HHVM_ME(Imagick, getImageScene); HHVM_ME(Imagick, getImageSignature); HHVM_ME(Imagick, getImageSize); HHVM_ME(Imagick, getImageTicksPerSecond); HHVM_ME(Imagick, getImageTotalInkDensity); HHVM_ME(Imagick, getImageType); HHVM_ME(Imagick, getImageUnits); HHVM_ME(Imagick, getImageVirtualPixelMethod); HHVM_ME(Imagick, getImageWhitePoint); HHVM_ME(Imagick, getImageWidth); HHVM_ME(Imagick, getInterlaceScheme); HHVM_ME(Imagick, getIteratorIndex); HHVM_ME(Imagick, getNumberImages); HHVM_ME(Imagick, getOption); HHVM_STATIC_ME(Imagick, getPackageName); HHVM_ME(Imagick, getPage); HHVM_ME(Imagick, getPixelIterator); HHVM_ME(Imagick, getPixelRegionIterator); HHVM_ME(Imagick, getPointSize); HHVM_STATIC_ME(Imagick, getQuantumDepth); HHVM_STATIC_ME(Imagick, getQuantumRange); HHVM_STATIC_ME(Imagick, getReleaseDate); HHVM_STATIC_ME(Imagick, getResource); HHVM_STATIC_ME(Imagick, getResourceLimit); HHVM_ME(Imagick, getSamplingFactors); HHVM_ME(Imagick, getSize); HHVM_ME(Imagick, getSizeOffset); HHVM_STATIC_ME(Imagick, getVersion); HHVM_ME(Imagick, haldClutImage); HHVM_ME(Imagick, hasNextImage); HHVM_ME(Imagick, hasPreviousImage); HHVM_ME(Imagick, identifyImage); HHVM_ME(Imagick, implodeImage); HHVM_ME(Imagick, importImagePixels); HHVM_ME(Imagick, labelImage); HHVM_ME(Imagick, levelImage); HHVM_ME(Imagick, linearStretchImage); HHVM_ME(Imagick, liquidRescaleImage); HHVM_ME(Imagick, magnifyImage); HHVM_ME(Imagick, mapImage); HHVM_ME(Imagick, matteFloodfillImage); HHVM_ME(Imagick, medianFilterImage); HHVM_ME(Imagick, mergeImageLayers); HHVM_ME(Imagick, minifyImage); HHVM_ME(Imagick, modulateImage); HHVM_ME(Imagick, montageImage); HHVM_ME(Imagick, morphImages); HHVM_ME(Imagick, mosaicImages); HHVM_ME(Imagick, motionBlurImage); HHVM_ME(Imagick, negateImage); HHVM_ME(Imagick, newImage); HHVM_ME(Imagick, newPseudoImage); HHVM_ME(Imagick, nextImage); HHVM_ME(Imagick, normalizeImage); HHVM_ME(Imagick, oilPaintImage); HHVM_ME(Imagick, opaquePaintImage); HHVM_ME(Imagick, optimizeImageLayers); HHVM_ME(Imagick, orderedPosterizeImage); HHVM_ME(Imagick, paintFloodfillImage); HHVM_ME(Imagick, paintOpaqueImage); HHVM_ME(Imagick, paintTransparentImage); HHVM_ME(Imagick, pingImage); HHVM_ME(Imagick, pingImageBlob); HHVM_ME(Imagick, pingImageFile); HHVM_ME(Imagick, polaroidImage); HHVM_ME(Imagick, posterizeImage); HHVM_ME(Imagick, previewImages); HHVM_ME(Imagick, previousImage); HHVM_ME(Imagick, profileImage); HHVM_ME(Imagick, quantizeImage); HHVM_ME(Imagick, quantizeImages); HHVM_ME(Imagick, queryFontMetrics); HHVM_STATIC_ME(Imagick, queryFonts); HHVM_STATIC_ME(Imagick, queryFormats); HHVM_ME(Imagick, radialBlurImage); HHVM_ME(Imagick, raiseImage); HHVM_ME(Imagick, randomThresholdImage); HHVM_ME(Imagick, readImage); HHVM_ME(Imagick, readImageBlob); HHVM_ME(Imagick, readImageFile); HHVM_ME(Imagick, readImages); HHVM_ME(Imagick, recolorImage); HHVM_ME(Imagick, reduceNoiseImage); HHVM_ME(Imagick, remapImage); HHVM_ME(Imagick, removeImage); HHVM_ME(Imagick, removeImageProfile); HHVM_ME(Imagick, resampleImage); HHVM_ME(Imagick, resetImagePage); HHVM_ME(Imagick, resizeImage); HHVM_ME(Imagick, rollImage); HHVM_ME(Imagick, rotateImage); HHVM_ME(Imagick, roundCorners); HHVM_ME(Imagick, roundCornersImage); HHVM_ME(Imagick, sampleImage); HHVM_ME(Imagick, scaleImage); HHVM_ME(Imagick, segmentImage); HHVM_ME(Imagick, separateImageChannel); HHVM_ME(Imagick, sepiaToneImage); HHVM_ME(Imagick, setBackgroundColor); HHVM_ME(Imagick, setColorspace); HHVM_ME(Imagick, setCompression); HHVM_ME(Imagick, setCompressionQuality); HHVM_ME(Imagick, setFilename); HHVM_ME(Imagick, setFirstIterator); HHVM_ME(Imagick, setFont); HHVM_ME(Imagick, setFormat); HHVM_ME(Imagick, setGravity); HHVM_ME(Imagick, setImage); HHVM_ME(Imagick, setImageAlphaChannel); HHVM_ME(Imagick, setImageArtifact); HHVM_ME(Imagick, setImageBackgroundColor); HHVM_ME(Imagick, setImageBias); HHVM_ME(Imagick, setImageBluePrimary); HHVM_ME(Imagick, setImageBorderColor); HHVM_ME(Imagick, setImageChannelDepth); HHVM_ME(Imagick, setImageClipMask); HHVM_ME(Imagick, setImageColormapColor); HHVM_ME(Imagick, setImageColorspace); HHVM_ME(Imagick, setImageCompose); HHVM_ME(Imagick, setImageCompression); HHVM_ME(Imagick, setImageCompressionQuality); HHVM_ME(Imagick, setImageDelay); HHVM_ME(Imagick, setImageDepth); HHVM_ME(Imagick, setImageDispose); HHVM_ME(Imagick, setImageExtent); HHVM_ME(Imagick, setImageFilename); HHVM_ME(Imagick, setImageFormat); HHVM_ME(Imagick, setImageGamma); HHVM_ME(Imagick, setImageGravity); HHVM_ME(Imagick, setImageGreenPrimary); HHVM_ME(Imagick, setImageIndex); HHVM_ME(Imagick, setImageInterlaceScheme); HHVM_ME(Imagick, setImageInterpolateMethod); HHVM_ME(Imagick, setImageIterations); HHVM_ME(Imagick, setImageMatte); HHVM_ME(Imagick, setImageMatteColor); HHVM_ME(Imagick, setImageOpacity); HHVM_ME(Imagick, setImageOrientation); HHVM_ME(Imagick, setImagePage); HHVM_ME(Imagick, setImageProfile); HHVM_ME(Imagick, setImageProperty); HHVM_ME(Imagick, setImageRedPrimary); HHVM_ME(Imagick, setImageRenderingIntent); HHVM_ME(Imagick, setImageResolution); HHVM_ME(Imagick, setImageScene); HHVM_ME(Imagick, setImageTicksPerSecond); HHVM_ME(Imagick, setImageType); HHVM_ME(Imagick, setImageUnits); HHVM_ME(Imagick, setImageVirtualPixelMethod); HHVM_ME(Imagick, setImageWhitePoint); HHVM_ME(Imagick, setInterlaceScheme); HHVM_ME(Imagick, setIteratorIndex); HHVM_ME(Imagick, setLastIterator); HHVM_ME(Imagick, setOption); HHVM_ME(Imagick, setPage); HHVM_ME(Imagick, setPointSize); HHVM_ME(Imagick, setResolution); HHVM_STATIC_ME(Imagick, setResourceLimit); HHVM_ME(Imagick, setSamplingFactors); HHVM_ME(Imagick, setSize); HHVM_ME(Imagick, setSizeOffset); HHVM_ME(Imagick, setType); HHVM_ME(Imagick, shadeImage); HHVM_ME(Imagick, shadowImage); HHVM_ME(Imagick, sharpenImage); HHVM_ME(Imagick, shaveImage); HHVM_ME(Imagick, shearImage); HHVM_ME(Imagick, sigmoidalContrastImage); HHVM_ME(Imagick, sketchImage); HHVM_ME(Imagick, solarizeImage); HHVM_ME(Imagick, sparseColorImage); HHVM_ME(Imagick, spliceImage); HHVM_ME(Imagick, spreadImage); HHVM_ME(Imagick, steganoImage); HHVM_ME(Imagick, stereoImage); HHVM_ME(Imagick, stripImage); HHVM_ME(Imagick, swirlImage); HHVM_ME(Imagick, textureImage); HHVM_ME(Imagick, thresholdImage); HHVM_ME(Imagick, thumbnailImage); HHVM_ME(Imagick, tintImage); HHVM_ME(Imagick, transformImage); HHVM_ME(Imagick, transparentPaintImage); HHVM_ME(Imagick, transposeImage); HHVM_ME(Imagick, transverseImage); HHVM_ME(Imagick, trimImage); HHVM_ME(Imagick, uniqueImageColors); HHVM_ME(Imagick, unsharpMaskImage); HHVM_ME(Imagick, vignetteImage); HHVM_ME(Imagick, waveImage); HHVM_ME(Imagick, whiteThresholdImage); HHVM_ME(Imagick, writeImage); HHVM_ME(Imagick, writeImageFile); HHVM_ME(Imagick, writeImages); HHVM_ME(Imagick, writeImagesFile); // Countable interface HHVM_ME(Imagick, count); // Iterator interface HHVM_ME(Imagick, current); HHVM_ME(Imagick, key); HHVM_ME(Imagick, next); HHVM_ME(Imagick, rewind); HHVM_ME(Imagick, valid); Native::registerNativePropHandler<ImagickPropHandler>(s_Imagick); } ////////////////////////////////////////////////////////////////////////////// } // namespace HPHP