PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/gd/libgd/xbm.c

https://github.com/gmphp/PHP
C | 241 lines | 189 code | 18 blank | 34 comment | 76 complexity | fc50aa06239a533749f41dacaa0b0064 MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2010 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: xbm.c 293036 2010-01-03 09:23:27Z sebastian $ */
  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 "php.h"
  26. #define MAX_XBM_LINE_SIZE 255
  27. /* {{{ gdImagePtr gdImageCreateFromXbm */
  28. gdImagePtr gdImageCreateFromXbm(FILE * fd)
  29. {
  30. char fline[MAX_XBM_LINE_SIZE];
  31. char iname[MAX_XBM_LINE_SIZE];
  32. char *type;
  33. int value;
  34. unsigned int width = 0, height = 0;
  35. int fail = 0;
  36. int max_bit = 0;
  37. gdImagePtr im;
  38. int bytes = 0, i;
  39. int bit, x = 0, y = 0;
  40. int ch;
  41. char h[8];
  42. unsigned int b;
  43. rewind(fd);
  44. while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
  45. fline[MAX_XBM_LINE_SIZE-1] = '\0';
  46. if (strlen(fline) == MAX_XBM_LINE_SIZE-1) {
  47. return 0;
  48. }
  49. if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
  50. if (!(type = strrchr(iname, '_'))) {
  51. type = iname;
  52. } else {
  53. type++;
  54. }
  55. if (!strcmp("width", type)) {
  56. width = (unsigned int) value;
  57. }
  58. if (!strcmp("height", type)) {
  59. height = (unsigned int) value;
  60. }
  61. } else {
  62. if ( sscanf(fline, "static unsigned char %s = {", iname) == 1
  63. || sscanf(fline, "static char %s = {", iname) == 1)
  64. {
  65. max_bit = 128;
  66. } else if (sscanf(fline, "static unsigned short %s = {", iname) == 1
  67. || sscanf(fline, "static short %s = {", iname) == 1)
  68. {
  69. max_bit = 32768;
  70. }
  71. if (max_bit) {
  72. bytes = (width * height / 8) + 1;
  73. if (!bytes) {
  74. return 0;
  75. }
  76. if (!(type = strrchr(iname, '_'))) {
  77. type = iname;
  78. } else {
  79. type++;
  80. }
  81. if (!strcmp("bits[]", type)) {
  82. break;
  83. }
  84. }
  85. }
  86. }
  87. if (!bytes || !max_bit) {
  88. return 0;
  89. }
  90. if(!(im = gdImageCreate(width, height))) {
  91. return 0;
  92. }
  93. gdImageColorAllocate(im, 255, 255, 255);
  94. gdImageColorAllocate(im, 0, 0, 0);
  95. h[2] = '\0';
  96. h[4] = '\0';
  97. for (i = 0; i < bytes; i++) {
  98. while (1) {
  99. if ((ch=getc(fd)) == EOF) {
  100. fail = 1;
  101. break;
  102. }
  103. if (ch == 'x') {
  104. break;
  105. }
  106. }
  107. if (fail) {
  108. break;
  109. }
  110. /* Get hex value */
  111. if ((ch=getc(fd)) == EOF) {
  112. break;
  113. }
  114. h[0] = ch;
  115. if ((ch=getc(fd)) == EOF) {
  116. break;
  117. }
  118. h[1] = ch;
  119. if (max_bit == 32768) {
  120. if ((ch=getc(fd)) == EOF) {
  121. break;
  122. }
  123. h[2] = ch;
  124. if ((ch=getc(fd)) == EOF) {
  125. break;
  126. }
  127. h[3] = ch;
  128. }
  129. sscanf(h, "%x", &b);
  130. for (bit = 1; bit <= max_bit; bit = bit << 1) {
  131. gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
  132. if (x == im->sx) {
  133. x = 0;
  134. y++;
  135. if (y == im->sy) {
  136. return im;
  137. }
  138. break;
  139. }
  140. }
  141. }
  142. php_gd_error("EOF before image was complete");
  143. gdImageDestroy(im);
  144. return 0;
  145. }
  146. /* }}} */
  147. /* {{{ gdCtxPrintf */
  148. void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
  149. {
  150. char *buf;
  151. int len;
  152. va_list args;
  153. va_start(args, format);
  154. len = vspprintf(&buf, 0, format, args);
  155. va_end(args);
  156. out->putBuf(out, buf, len);
  157. efree(buf);
  158. }
  159. /* }}} */
  160. /* {{{ gdImageXbmCtx */
  161. void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
  162. {
  163. int x, y, c, b, sx, sy, p;
  164. char *name, *f;
  165. size_t i, l;
  166. name = file_name;
  167. if ((f = strrchr(name, '/')) != NULL) name = f+1;
  168. if ((f = strrchr(name, '\\')) != NULL) name = f+1;
  169. name = estrdup(name);
  170. if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
  171. if ((l = strlen(name)) == 0) {
  172. efree(name);
  173. name = estrdup("image");
  174. } else {
  175. for (i=0; i<l; i++) {
  176. /* only in C-locale isalnum() would work */
  177. if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
  178. name[i] = '_';
  179. }
  180. }
  181. }
  182. gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
  183. gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
  184. gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n ", name);
  185. efree(name);
  186. b = 1;
  187. p = 0;
  188. c = 0;
  189. sx = gdImageSX(image);
  190. sy = gdImageSY(image);
  191. for (y = 0; y < sy; y++) {
  192. for (x = 0; x < sx; x++) {
  193. if (gdImageGetPixel(image, x, y) == fg) {
  194. c |= b;
  195. }
  196. if ((b == 128) || (x == sx && y == sy)) {
  197. b = 1;
  198. if (p) {
  199. gdCtxPrintf(out, ", ");
  200. if (!(p%12)) {
  201. gdCtxPrintf(out, "\n ");
  202. p = 12;
  203. }
  204. }
  205. p++;
  206. gdCtxPrintf(out, "0x%02X", c);
  207. c = 0;
  208. } else {
  209. b <<= 1;
  210. }
  211. }
  212. }
  213. gdCtxPrintf(out, "};\n");
  214. }
  215. /* }}} */
  216. /*
  217. * Local variables:
  218. * tab-width: 4
  219. * c-basic-offset: 4
  220. * End:
  221. * vim600: sw=4 ts=4 fdm=marker
  222. * vim<600: sw=4 ts=4
  223. */