root/ext/gd/libgd/xbm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gdImageCreateFromXbm
  2. gdCtxPrintf
  3. gdImageXbmCtx

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

/* [<][>][^][v][top][bottom][index][help] */