PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/2.0/Source/ExtSupport/PHP4/Images.cpp

#
C++ | 241 lines | 182 code | 31 blank | 28 comment | 60 complexity | 18d320c06ca5527fd7268be21836d943 MD5 | raw file
Possible License(s): CPL-1.0, GPL-2.0, CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, Apache-2.0
  1. //
  2. // ExtSupport.PHP4 - substitute for php4ts.dll
  3. //
  4. // Images.cpp
  5. // - contains definitions of image related functions
  6. //
  7. #include "stdafx.h"
  8. #include "Images.h"
  9. #include "Streams.h"
  10. #include "Errors.h"
  11. #include "Memory.h"
  12. #include <stdio.h>
  13. #pragma unmanaged
  14. ZEND_API char php_sig_gif[3] = {'G', 'I', 'F'};
  15. ZEND_API char php_sig_psd[4] = {'8', 'B', 'P', 'S'};
  16. ZEND_API char php_sig_bmp[2] = {'B', 'M'};
  17. ZEND_API char php_sig_swf[3] = {'F', 'W', 'S'};
  18. ZEND_API char php_sig_swc[3] = {'C', 'W', 'S'};
  19. ZEND_API char php_sig_jpg[3] = {(char) 0xff, (char) 0xd8, (char) 0xff};
  20. ZEND_API char php_sig_png[8] = {(char) 0x89, (char) 0x50, (char) 0x4e, (char) 0x47,
  21. (char) 0x0d, (char) 0x0a, (char) 0x1a, (char) 0x0a};
  22. ZEND_API char php_sig_tif_ii[4] = {'I','I', (char)0x2A, (char)0x00};
  23. ZEND_API char php_sig_tif_mm[4] = {'M','M', (char)0x00, (char)0x2A};
  24. ZEND_API char php_sig_jpc[3] = {(char)0xff, (char)0x4f, (char)0xff};
  25. ZEND_API char php_sig_jp2[12] = {(char)0x00, (char)0x00, (char)0x00, (char)0x0c,
  26. (char)0x6a, (char)0x50, (char)0x20, (char)0x20,
  27. (char)0x0d, (char)0x0a, (char)0x87, (char)0x0a};
  28. ZEND_API char php_sig_iff[4] = {'F','O','R','M'};
  29. ZEND_API int php_tiff_bytes_per_format[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
  30. struct gfxinfo {
  31. unsigned int width;
  32. unsigned int height;
  33. unsigned int bits;
  34. unsigned int channels;
  35. };
  36. // copied from image.c and beautified
  37. /* {{{ php_get_wbmp
  38. * int WBMP file format type
  39. * byte Header Type
  40. * byte Extended Header
  41. * byte Header Data (type 00 = multibyte)
  42. * byte Header Data (type 11 = name/pairs)
  43. * int Number of columns
  44. * int Number of rows
  45. */
  46. static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check TSRMLS_DC)
  47. {
  48. int i, width = 0, height = 0;
  49. if (php_stream_rewind(stream)) return 0;
  50. /* get type */
  51. if (php_stream_getc(stream) != 0) return 0;
  52. /* skip header */
  53. do
  54. {
  55. i = php_stream_getc(stream);
  56. if (i < 0) return 0;
  57. }
  58. while (i & 0x80);
  59. /* get width */
  60. do
  61. {
  62. i = php_stream_getc(stream);
  63. if (i < 0) return 0;
  64. width = (width << 7) | (i & 0x7f);
  65. }
  66. while (i & 0x80);
  67. /* get height */
  68. do
  69. {
  70. i = php_stream_getc(stream);
  71. if (i < 0) return 0;
  72. height = (height << 7) | (i & 0x7f);
  73. }
  74. while (i & 0x80);
  75. if (!check)
  76. {
  77. (*result)->width = width;
  78. (*result)->height = height;
  79. }
  80. return IMAGE_FILETYPE_WBMP;
  81. }
  82. // copied from image.c and beautified
  83. static int php_get_xbm(php_stream *stream, struct gfxinfo **result TSRMLS_DC)
  84. {
  85. char *fline;
  86. char *iname;
  87. char *type;
  88. int value;
  89. unsigned int width = 0, height = 0;
  90. if (result) *result = NULL;
  91. if (php_stream_rewind(stream)) return 0;
  92. while ((fline = php_stream_gets(stream, NULL, 0)) != NULL)
  93. {
  94. iname = estrdup(fline); /* simple way to get necessary buffer of required size */
  95. if (sscanf(fline, "#define %s %d", iname, &value) == 2)
  96. {
  97. if (!(type = strrchr(iname, '_'))) type = iname;
  98. else type++;
  99. if (!strcmp("width", type))
  100. {
  101. width = (unsigned int)value;
  102. if (height)
  103. {
  104. efree(iname);
  105. break;
  106. }
  107. }
  108. if (!strcmp("height", type))
  109. {
  110. height = (unsigned int)value;
  111. if (width)
  112. {
  113. efree(iname);
  114. break;
  115. }
  116. }
  117. }
  118. efree(fline);
  119. efree(iname);
  120. }
  121. if (fline) efree(fline);
  122. if (width && height)\
  123. {
  124. if (result)
  125. {
  126. *result = (struct gfxinfo *)ecalloc(1, sizeof(struct gfxinfo));
  127. (*result)->width = width;
  128. (*result)->height = height;
  129. }
  130. return IMAGE_FILETYPE_XBM;
  131. }
  132. return 0;
  133. }
  134. // copied from image.c and beautified
  135. ZEND_API const char *php_image_type_to_mime_type(int image_type)
  136. {
  137. switch (image_type)
  138. {
  139. case IMAGE_FILETYPE_GIF: return "image/gif";
  140. case IMAGE_FILETYPE_JPEG: return "image/jpeg";
  141. case IMAGE_FILETYPE_PNG: return "image/png";
  142. case IMAGE_FILETYPE_SWF:
  143. case IMAGE_FILETYPE_SWC: return "application/x-shockwave-flash";
  144. case IMAGE_FILETYPE_PSD: return "image/psd";
  145. case IMAGE_FILETYPE_BMP: return "image/bmp";
  146. case IMAGE_FILETYPE_TIFF_II:
  147. case IMAGE_FILETYPE_TIFF_MM: return "image/tiff";
  148. case IMAGE_FILETYPE_IFF: return "image/iff";
  149. case IMAGE_FILETYPE_WBMP: return "image/vnd.wap.wbmp";
  150. case IMAGE_FILETYPE_JPC: return "application/octet-stream";
  151. case IMAGE_FILETYPE_JP2: return "image/jp2";
  152. case IMAGE_FILETYPE_XBM: return "image/xbm";
  153. default:
  154. case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */
  155. }
  156. }
  157. /* detect filetype from first bytes */
  158. // copied from image.c and beautified
  159. ZEND_API int php_getimagetype(php_stream *stream, char *filetype TSRMLS_DC)
  160. {
  161. char tmp[12];
  162. if (!filetype) filetype = tmp;
  163. if ((php_stream_read(stream, filetype, 3)) != 3)
  164. {
  165. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!");
  166. return IMAGE_FILETYPE_UNKNOWN;
  167. }
  168. /* BYTES READ: 3 */
  169. if (!memcmp(filetype, php_sig_gif, 3)) return IMAGE_FILETYPE_GIF;
  170. else if (!memcmp(filetype, php_sig_jpg, 3)) return IMAGE_FILETYPE_JPEG;
  171. else if (!memcmp(filetype, php_sig_png, 3))
  172. {
  173. if (php_stream_read(stream, filetype + 3, 5) != 5)
  174. {
  175. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!");
  176. return IMAGE_FILETYPE_UNKNOWN;
  177. }
  178. if (!memcmp(filetype, php_sig_png, 8)) return IMAGE_FILETYPE_PNG;
  179. else
  180. {
  181. php_error_docref(NULL TSRMLS_CC, E_WARNING, "PNG file corrupted by ASCII conversion");
  182. return IMAGE_FILETYPE_UNKNOWN;
  183. }
  184. }
  185. else if (!memcmp(filetype, php_sig_swf, 3)) return IMAGE_FILETYPE_SWF;
  186. else if (!memcmp(filetype, php_sig_swc, 3)) return IMAGE_FILETYPE_SWC;
  187. else if (!memcmp(filetype, php_sig_psd, 3)) return IMAGE_FILETYPE_PSD;
  188. else if (!memcmp(filetype, php_sig_bmp, 2)) return IMAGE_FILETYPE_BMP;
  189. else if (!memcmp(filetype, php_sig_jpc, 3)) return IMAGE_FILETYPE_JPC;
  190. if (php_stream_read(stream, filetype + 3, 1) != 1)
  191. {
  192. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!");
  193. return IMAGE_FILETYPE_UNKNOWN;
  194. }
  195. /* BYTES READ: 4 */
  196. if (!memcmp(filetype, php_sig_tif_ii, 4)) return IMAGE_FILETYPE_TIFF_II;
  197. else if (!memcmp(filetype, php_sig_tif_mm, 4)) return IMAGE_FILETYPE_TIFF_MM;
  198. else if (!memcmp(filetype, php_sig_iff, 4)) return IMAGE_FILETYPE_IFF;
  199. if (php_stream_read(stream, filetype + 4, 8) != 8)
  200. {
  201. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!");
  202. return IMAGE_FILETYPE_UNKNOWN;
  203. }
  204. /* BYTES READ: 12 */
  205. if (!memcmp(filetype, php_sig_jp2, 12)) return IMAGE_FILETYPE_JP2;
  206. /* AFTER ALL ABOVE FAILED */
  207. if (php_get_wbmp(stream, NULL, 1 TSRMLS_CC)) return IMAGE_FILETYPE_WBMP;
  208. if (php_get_xbm(stream, NULL TSRMLS_CC)) return IMAGE_FILETYPE_XBM;
  209. return IMAGE_FILETYPE_UNKNOWN;
  210. }