gd_xbm.c 5.1 KB

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