gd_xbm.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Marcus Boerger <helly@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include "gd.h"
  24. #include "gdhelpers.h"
  25. #include "gd_errors.h"
  26. #include "php.h"
  27. #define MAX_XBM_LINE_SIZE 255
  28. /* {{{ gdImagePtr gdImageCreateFromXbm */
  29. gdImagePtr gdImageCreateFromXbm(FILE * fd)
  30. {
  31. char fline[MAX_XBM_LINE_SIZE];
  32. char iname[MAX_XBM_LINE_SIZE];
  33. char *type;
  34. int value;
  35. unsigned int width = 0, height = 0;
  36. int fail = 0;
  37. int max_bit = 0;
  38. gdImagePtr im;
  39. int bytes = 0, i;
  40. int bit, x = 0, y = 0;
  41. int ch;
  42. char h[8];
  43. unsigned int b;
  44. rewind(fd);
  45. while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
  46. fline[MAX_XBM_LINE_SIZE-1] = '\0';
  47. if (strlen(fline) == MAX_XBM_LINE_SIZE-1) {
  48. return 0;
  49. }
  50. if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
  51. if (!(type = strrchr(iname, '_'))) {
  52. type = iname;
  53. } else {
  54. type++;
  55. }
  56. if (!strcmp("width", type)) {
  57. width = (unsigned int) value;
  58. }
  59. if (!strcmp("height", type)) {
  60. height = (unsigned int) value;
  61. }
  62. } else {
  63. if ( sscanf(fline, "static unsigned char %s = {", iname) == 1
  64. || sscanf(fline, "static char %s = {", iname) == 1)
  65. {
  66. max_bit = 128;
  67. } else if (sscanf(fline, "static unsigned short %s = {", iname) == 1
  68. || sscanf(fline, "static short %s = {", iname) == 1)
  69. {
  70. max_bit = 32768;
  71. }
  72. if (max_bit) {
  73. bytes = (width + 7) / 8 * height;
  74. if (!bytes) {
  75. return 0;
  76. }
  77. if (!(type = strrchr(iname, '_'))) {
  78. type = iname;
  79. } else {
  80. type++;
  81. }
  82. if (!strcmp("bits[]", type)) {
  83. break;
  84. }
  85. }
  86. }
  87. }
  88. if (!bytes || !max_bit) {
  89. return 0;
  90. }
  91. if(!(im = gdImageCreate(width, height))) {
  92. return 0;
  93. }
  94. gdImageColorAllocate(im, 255, 255, 255);
  95. gdImageColorAllocate(im, 0, 0, 0);
  96. h[2] = '\0';
  97. h[4] = '\0';
  98. for (i = 0; i < bytes; i++) {
  99. while (1) {
  100. if ((ch=getc(fd)) == EOF) {
  101. fail = 1;
  102. break;
  103. }
  104. if (ch == 'x') {
  105. break;
  106. }
  107. }
  108. if (fail) {
  109. break;
  110. }
  111. /* Get hex value */
  112. if ((ch=getc(fd)) == EOF) {
  113. break;
  114. }
  115. h[0] = ch;
  116. if ((ch=getc(fd)) == EOF) {
  117. break;
  118. }
  119. h[1] = ch;
  120. if (max_bit == 32768) {
  121. if ((ch=getc(fd)) == EOF) {
  122. break;
  123. }
  124. h[2] = ch;
  125. if ((ch=getc(fd)) == EOF) {
  126. break;
  127. }
  128. h[3] = ch;
  129. }
  130. if (sscanf(h, "%x", &b) != 1) {
  131. gd_error("invalid XBM");
  132. gdImageDestroy(im);
  133. return 0;
  134. }
  135. for (bit = 1; bit <= max_bit; bit = bit << 1) {
  136. gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
  137. if (x == im->sx) {
  138. x = 0;
  139. y++;
  140. if (y == im->sy) {
  141. return im;
  142. }
  143. break;
  144. }
  145. }
  146. }
  147. gd_error("EOF before image was complete");
  148. gdImageDestroy(im);
  149. return 0;
  150. }
  151. /* }}} */
  152. /* {{{ gdCtxPrintf */
  153. void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
  154. {
  155. char *buf;
  156. int len;
  157. va_list args;
  158. va_start(args, format);
  159. len = vspprintf(&buf, 0, format, args);
  160. va_end(args);
  161. out->putBuf(out, buf, len);
  162. efree(buf);
  163. }
  164. /* }}} */
  165. /* {{{ gdImageXbmCtx */
  166. void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
  167. {
  168. int x, y, c, b, sx, sy, p;
  169. char *name, *f;
  170. size_t i, l;
  171. name = file_name;
  172. if ((f = strrchr(name, '/')) != NULL) name = f+1;
  173. if ((f = strrchr(name, '\\')) != NULL) name = f+1;
  174. name = estrdup(name);
  175. if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
  176. if ((l = strlen(name)) == 0) {
  177. efree(name);
  178. name = estrdup("image");
  179. } else {
  180. for (i=0; i<l; i++) {
  181. /* only in C-locale isalnum() would work */
  182. if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
  183. name[i] = '_';
  184. }
  185. }
  186. }
  187. gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
  188. gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
  189. gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n ", name);
  190. efree(name);
  191. b = 1;
  192. p = 0;
  193. c = 0;
  194. sx = gdImageSX(image);
  195. sy = gdImageSY(image);
  196. for (y = 0; y < sy; y++) {
  197. for (x = 0; x < sx; x++) {
  198. if (gdImageGetPixel(image, x, y) == fg) {
  199. c |= b;
  200. }
  201. if ((b == 128) || (x == sx - 1)) {
  202. b = 1;
  203. if (p) {
  204. gdCtxPrintf(out, ", ");
  205. if (!(p%12)) {
  206. gdCtxPrintf(out, "\n ");
  207. p = 12;
  208. }
  209. }
  210. p++;
  211. gdCtxPrintf(out, "0x%02X", c);
  212. c = 0;
  213. } else {
  214. b <<= 1;
  215. }
  216. }
  217. }
  218. gdCtxPrintf(out, "};\n");
  219. }
  220. /* }}} */
  221. /*
  222. * Local variables:
  223. * tab-width: 4
  224. * c-basic-offset: 4
  225. * End:
  226. * vim600: sw=4 ts=4 fdm=marker
  227. * vim<600: sw=4 ts=4
  228. */