PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/hphp/runtime/ext/imagick/ext_imagick.h

https://github.com/tstarling/hiphop-php
C Header | 372 lines | 267 code | 70 blank | 35 comment | 22 complexity | 3ad1cb62fb1605cf67c75f3c1c53a5db MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
  6. | Copyright (c) 1997-2010 The PHP Group |
  7. +----------------------------------------------------------------------+
  8. | This source file is subject to version 3.01 of the PHP license, |
  9. | that is bundled with this package in the file LICENSE, and is |
  10. | available through the world-wide-web at the following url: |
  11. | http://www.php.net/license/3_01.txt |
  12. | If you did not receive a copy of the PHP license and are unable to |
  13. | obtain it through the world-wide-web, please send a note to |
  14. | license@php.net so we can mail you a copy immediately. |
  15. +----------------------------------------------------------------------+
  16. */
  17. #ifndef incl_HPHP_EXT_IMAGICK_H_
  18. #define incl_HPHP_EXT_IMAGICK_H_
  19. #include <vector>
  20. #include <wand/MagickWand.h>
  21. #include "hphp/runtime/base/base-includes.h"
  22. #include "hphp/runtime/ext/imagick/constants.h"
  23. #include "hphp/util/string-vsnprintf.h"
  24. namespace HPHP {
  25. //////////////////////////////////////////////////////////////////////////////
  26. // ImagickExtension
  27. class ImagickExtension : public Extension {
  28. public:
  29. ImagickExtension();
  30. virtual void moduleInit();
  31. virtual void threadInit();
  32. static bool hasLocaleFix();
  33. static bool hasProgressMonitor();
  34. private:
  35. struct ImagickIniSetting {
  36. bool m_locale_fix;
  37. bool m_progress_monitor;
  38. };
  39. static DECLARE_THREAD_LOCAL(ImagickIniSetting, s_ini_setting);
  40. };
  41. //////////////////////////////////////////////////////////////////////////////
  42. // PHP Exceptions and Classes
  43. #define IMAGICK_DEFINE_CLASS(CLS) \
  44. class CLS { \
  45. public: \
  46. static Object allocObject() { \
  47. if (cls == nullptr) { \
  48. initClass(); \
  49. } \
  50. return ObjectData::newInstance(cls); \
  51. } \
  52. \
  53. static Object allocObject(const Variant& arg) { \
  54. Object ret = allocObject(); \
  55. TypedValue dummy; \
  56. g_context->invokeFunc(&dummy, \
  57. cls->getCtor(), \
  58. make_packed_array(arg), \
  59. ret.get()); \
  60. return ret; \
  61. } \
  62. \
  63. private: \
  64. static void initClass() { \
  65. cls = Unit::lookupClass(StringData::Make(#CLS)); \
  66. } \
  67. \
  68. static HPHP::Class* cls; \
  69. };
  70. IMAGICK_DEFINE_CLASS(ImagickException)
  71. IMAGICK_DEFINE_CLASS(ImagickDrawException)
  72. IMAGICK_DEFINE_CLASS(ImagickPixelException)
  73. IMAGICK_DEFINE_CLASS(ImagickPixelIteratorException)
  74. IMAGICK_DEFINE_CLASS(Imagick)
  75. IMAGICK_DEFINE_CLASS(ImagickDraw)
  76. IMAGICK_DEFINE_CLASS(ImagickPixel)
  77. IMAGICK_DEFINE_CLASS(ImagickPixelIterator)
  78. #undef IMAGICK_DEFINE_CLASS
  79. template<typename T>
  80. void imagickThrow(const char* fmt, ...)
  81. ATTRIBUTE_PRINTF(1, 2) ATTRIBUTE_NORETURN;
  82. template<typename T>
  83. void imagickThrow(const char* fmt, ...) {
  84. va_list ap;
  85. std::string msg;
  86. va_start(ap, fmt);
  87. string_vsnprintf(msg, fmt, ap);
  88. va_end(ap);
  89. throw T::allocObject(msg);
  90. }
  91. //////////////////////////////////////////////////////////////////////////////
  92. // WandResource
  93. template<typename Wand>
  94. class WandResource : public SweepableResourceData {
  95. DECLARE_RESOURCE_ALLOCATION(WandResource<Wand>);
  96. public:
  97. explicit WandResource(Wand* wand, bool owner) :
  98. m_wand(wand), m_owner(owner) {
  99. }
  100. WandResource(WandResource<Wand> &&res) :
  101. m_wand(res.m_wand), m_owner(res.m_owner) {
  102. res.releaseWand();
  103. }
  104. ~WandResource() {
  105. clear();
  106. }
  107. void clear() {
  108. if (m_wand != nullptr) {
  109. if (m_owner) {
  110. destoryWand();
  111. }
  112. m_wand = nullptr;
  113. }
  114. }
  115. void destoryWand();
  116. Wand* getWand() {
  117. return m_wand;
  118. }
  119. Wand* releaseWand() {
  120. m_owner = false;
  121. return m_wand;
  122. }
  123. private:
  124. Wand* m_wand;
  125. bool m_owner;
  126. };
  127. template<typename Wand>
  128. ALWAYS_INLINE
  129. void WandResource<Wand>::sweep() {
  130. clear();
  131. }
  132. template<>
  133. ALWAYS_INLINE
  134. void WandResource<MagickWand>::destoryWand() {
  135. DestroyMagickWand(m_wand);
  136. }
  137. template<>
  138. ALWAYS_INLINE
  139. void WandResource<DrawingWand>::destoryWand() {
  140. DestroyDrawingWand(m_wand);
  141. }
  142. template<>
  143. ALWAYS_INLINE
  144. void WandResource<PixelWand>::destoryWand() {
  145. DestroyPixelWand(m_wand);
  146. }
  147. template<>
  148. ALWAYS_INLINE
  149. void WandResource<PixelIterator>::destoryWand() {
  150. DestroyPixelIterator(m_wand);
  151. }
  152. template<typename Wand>
  153. ALWAYS_INLINE
  154. void setWandResource(const StaticString& className,
  155. const Object& obj,
  156. Wand* wand,
  157. bool destroy = true) {
  158. auto res = Resource(NEWOBJ(WandResource<Wand>(wand, destroy)));
  159. obj->o_set("wand", res, className.get());
  160. }
  161. template<typename Wand>
  162. ALWAYS_INLINE
  163. WandResource<Wand>* getWandResource(const StaticString& className,
  164. const Object& obj) {
  165. if (!obj.instanceof(className)) {
  166. return nullptr;
  167. }
  168. auto var = obj->o_get("wand", true, className.get());
  169. if (var.isNull()) {
  170. return nullptr;
  171. } else {
  172. return var.asCResRef().getTyped<WandResource<Wand>>();
  173. }
  174. }
  175. template<typename Wand, typename T>
  176. ALWAYS_INLINE
  177. WandResource<Wand>* getWandResource(const StaticString& className,
  178. const Object& obj,
  179. const std::string& msg) {
  180. auto ret = getWandResource<Wand>(className, obj);
  181. if (ret == nullptr || ret->getWand() == nullptr) {
  182. throw T::allocObject(msg);
  183. } else {
  184. return ret;
  185. }
  186. }
  187. ALWAYS_INLINE
  188. WandResource<MagickWand>* getMagickWandResource(const Object& obj) {
  189. return getWandResource<MagickWand, ImagickException>(
  190. s_Imagick, obj,
  191. "Can not process invalid Imagick object");
  192. }
  193. ALWAYS_INLINE
  194. WandResource<DrawingWand>* getDrawingWandResource(const Object& obj) {
  195. return getWandResource<DrawingWand, ImagickDrawException>(
  196. s_ImagickDraw, obj,
  197. "Can not process invalid ImagickDraw object");
  198. }
  199. ALWAYS_INLINE
  200. WandResource<PixelWand>* getPixelWandResource(const Object& obj) {
  201. auto ret = getWandResource<PixelWand>(s_ImagickPixel, obj);
  202. assert(ret != nullptr && ret->getWand() != nullptr);
  203. return ret;
  204. }
  205. ALWAYS_INLINE
  206. WandResource<PixelIterator>* getPixelIteratorResource(const Object& obj) {
  207. return getWandResource<PixelIterator, ImagickPixelIteratorException>(
  208. s_ImagickPixelIterator, obj,
  209. "ImagickPixelIterator is not initialized correctly");
  210. }
  211. //////////////////////////////////////////////////////////////////////////////
  212. // IO
  213. bool isMagickPseudoFormat(const String& path, char mode = '*');
  214. using ImagickFileOp =
  215. std::function<MagickBooleanType(MagickWand*, const char*)>;
  216. using ImagickHandleOp =
  217. std::function<MagickBooleanType(MagickWand*, FILE*)>;
  218. void imagickReadOp(MagickWand* wand,
  219. const String& path,
  220. const ImagickFileOp& op);
  221. void imagickWriteOp(MagickWand* wand,
  222. const String& path,
  223. const ImagickFileOp& op);
  224. void imagickReadOp(MagickWand* wand,
  225. const Resource& res,
  226. const ImagickHandleOp& op);
  227. void imagickWriteOp(MagickWand* wand,
  228. const Resource& res,
  229. const String& format,
  230. const ImagickHandleOp& op);
  231. //////////////////////////////////////////////////////////////////////////////
  232. // Common Helper
  233. void raiseDeprecated(const char* className, const char* methodName);
  234. void raiseDeprecated(const char* className,
  235. const char* methodName,
  236. const char* newClass,
  237. const char* newMethod);
  238. template<typename T>
  239. ALWAYS_INLINE
  240. void freeMagickMemory(T* &resource) {
  241. if (resource != nullptr) {
  242. MagickRelinquishMemory(resource);
  243. resource = nullptr;
  244. }
  245. }
  246. String convertMagickString(char* &&str);
  247. String convertMagickData(size_t size, unsigned char* &data);
  248. template<typename T>
  249. ALWAYS_INLINE
  250. Array convertArray(size_t num, const T* arr) {
  251. PackedArrayInit ret(num);
  252. for (size_t i = 0; i < num; ++i) {
  253. ret.appendWithRef(arr[i]);
  254. }
  255. return ret.create();
  256. }
  257. template<typename T>
  258. ALWAYS_INLINE
  259. Array convertMagickArray(size_t num, T* &arr) {
  260. if (arr == nullptr) {
  261. return null_array;
  262. } else {
  263. Array ret = convertArray(num, arr);
  264. freeMagickMemory(arr);
  265. return ret;
  266. }
  267. }
  268. ALWAYS_INLINE
  269. MagickBooleanType toMagickBool(bool value) {
  270. return value ? MagickTrue : MagickFalse;
  271. }
  272. MagickBooleanType withMagickLocaleFix(
  273. const std::function<MagickBooleanType()>& lambda);
  274. std::vector<double> toDoubleArray(const Array& array);
  275. std::vector<PointInfo> toPointInfoArray(const Array& coordinates);
  276. //////////////////////////////////////////////////////////////////////////////
  277. // Imagick Helper
  278. Object createImagick(MagickWand* wand, bool owner);
  279. Array magickQueryFonts(const char* pattern = "*");
  280. Array magickQueryFormats(const char* pattern = "*");
  281. String magickResolveFont(const String& fontName);
  282. //////////////////////////////////////////////////////////////////////////////
  283. // ImagickPixel Helper
  284. Object createImagickPixel(PixelWand* wand, bool owner);
  285. Array createImagickPixelArray(size_t num, PixelWand* wands[], bool owner);
  286. WandResource<PixelWand> newPixelWand();
  287. WandResource<PixelWand> buildColorWand(const Variant& color);
  288. WandResource<PixelWand> buildOpacityWand(const Variant& opacity);
  289. //////////////////////////////////////////////////////////////////////////////
  290. // ImagickPixel Helper
  291. Object createPixelIterator(const Object& magick);
  292. Object createPixelRegionIterator(const Object& magick,
  293. int64_t x, int64_t y, int64_t columns, int64_t rows);
  294. //////////////////////////////////////////////////////////////////////////////
  295. // Init Module
  296. void loadImagickClass();
  297. void loadImagickDrawClass();
  298. void loadImagickPixelClass();
  299. void loadImagickPixelIteratorClass();
  300. //////////////////////////////////////////////////////////////////////////////
  301. } // namespace HPHP
  302. #endif // incl_HPHP_EXT_IMAGICK_H_