Back to index

php5  5.3.10
xbm.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2010 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Marcus Boerger <helly@php.net>                               |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: xbm.c 293036 2010-01-03 09:23:27Z sebastian $ */
00020 
00021 #include <stdio.h>
00022 #include <math.h>
00023 #include <string.h>
00024 #include <stdlib.h>
00025 #include "gd.h"
00026 #include "gdhelpers.h"
00027 
00028 #include "php.h"
00029 
00030 #define MAX_XBM_LINE_SIZE 255
00031 
00032 /* {{{ gdImagePtr gdImageCreateFromXbm */
00033 gdImagePtr gdImageCreateFromXbm(FILE * fd)
00034 {
00035        char fline[MAX_XBM_LINE_SIZE];
00036        char iname[MAX_XBM_LINE_SIZE];
00037        char *type;
00038        int value;
00039        unsigned int width = 0, height = 0;
00040        int fail = 0;
00041        int max_bit = 0;
00042 
00043        gdImagePtr im;
00044        int bytes = 0, i;
00045        int bit, x = 0, y = 0;
00046        int ch;
00047        char h[8];
00048        unsigned int b;
00049 
00050        rewind(fd);
00051        while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
00052               fline[MAX_XBM_LINE_SIZE-1] = '\0';
00053               if (strlen(fline) == MAX_XBM_LINE_SIZE-1) {
00054                      return 0;
00055               }
00056               if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
00057                      if (!(type = strrchr(iname, '_'))) {
00058                             type = iname;
00059                      } else {
00060                             type++;
00061                      }
00062 
00063                      if (!strcmp("width", type)) {
00064                             width = (unsigned int) value;
00065                      }
00066                      if (!strcmp("height", type)) {
00067                             height = (unsigned int) value;
00068                      }
00069               } else {
00070                      if ( sscanf(fline, "static unsigned char %s = {", iname) == 1
00071                        || sscanf(fline, "static char %s = {", iname) == 1)
00072                      {
00073                             max_bit = 128;
00074                      } else if (sscanf(fline, "static unsigned short %s = {", iname) == 1
00075                                    || sscanf(fline, "static short %s = {", iname) == 1)
00076                      {
00077                             max_bit = 32768;
00078                      }
00079                      if (max_bit) {
00080                             bytes = (width * height / 8) + 1;
00081                             if (!bytes) {
00082                                    return 0;
00083                             }
00084                             if (!(type = strrchr(iname, '_'))) {
00085                                    type = iname;
00086                             } else {
00087                                    type++;
00088                             }
00089                             if (!strcmp("bits[]", type)) {
00090                                    break;
00091                             }
00092                      }
00093               }
00094        }
00095        if (!bytes || !max_bit) {
00096               return 0;
00097        }
00098 
00099        if(!(im = gdImageCreate(width, height))) {
00100               return 0;
00101        }
00102        gdImageColorAllocate(im, 255, 255, 255);
00103        gdImageColorAllocate(im, 0, 0, 0);
00104        h[2] = '\0';
00105        h[4] = '\0';
00106        for (i = 0; i < bytes; i++) {
00107               while (1) {
00108                      if ((ch=getc(fd)) == EOF) {
00109                             fail = 1;
00110                             break;
00111                      }
00112                      if (ch == 'x') {
00113                             break;
00114                      }
00115               }
00116               if (fail) {
00117                      break;
00118               }
00119               /* Get hex value */
00120               if ((ch=getc(fd)) == EOF) {
00121                      break;
00122               }
00123               h[0] = ch;
00124               if ((ch=getc(fd)) == EOF) {
00125                      break;
00126               }
00127               h[1] = ch;
00128               if (max_bit == 32768) {
00129                      if ((ch=getc(fd)) == EOF) {
00130                             break;
00131                      }
00132                      h[2] = ch;
00133                      if ((ch=getc(fd)) == EOF) {
00134                             break;
00135                      }
00136                      h[3] = ch;
00137               }
00138               sscanf(h, "%x", &b);
00139               for (bit = 1; bit <= max_bit; bit = bit << 1) {
00140                      gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
00141                      if (x == im->sx) {
00142                             x = 0;
00143                             y++;
00144                             if (y == im->sy) {
00145                                    return im;
00146                             }
00147                             break;
00148                      }
00149               }
00150        }
00151 
00152        php_gd_error("EOF before image was complete");
00153        gdImageDestroy(im);
00154        return 0;
00155 }
00156 /* }}} */
00157 
00158 /* {{{ gdCtxPrintf */
00159 void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
00160 {
00161        char *buf;
00162        int len;
00163        va_list args;
00164 
00165        va_start(args, format);
00166        len = vspprintf(&buf, 0, format, args);
00167        va_end(args);
00168        out->putBuf(out, buf, len);
00169        efree(buf);
00170 }
00171 /* }}} */
00172 
00173 /* {{{ gdImageXbmCtx */
00174 void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
00175 {
00176        int x, y, c, b, sx, sy, p;
00177        char *name, *f;
00178        size_t i, l;
00179 
00180        name = file_name;
00181        if ((f = strrchr(name, '/')) != NULL) name = f+1;
00182        if ((f = strrchr(name, '\\')) != NULL) name = f+1;
00183        name = estrdup(name);
00184        if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
00185        if ((l = strlen(name)) == 0) {
00186               efree(name);
00187               name = estrdup("image");
00188        } else {
00189               for (i=0; i<l; i++) {
00190                      /* only in C-locale isalnum() would work */
00191                      if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
00192                             name[i] = '_';
00193                      }
00194               }
00195        }
00196 
00197        gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
00198        gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
00199        gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n  ", name);
00200 
00201        efree(name);
00202 
00203        b = 1;
00204        p = 0;
00205        c = 0;
00206        sx = gdImageSX(image);
00207        sy = gdImageSY(image);
00208        for (y = 0; y < sy; y++) {
00209               for (x = 0; x < sx; x++) {
00210                      if (gdImageGetPixel(image, x, y) == fg) {
00211                             c |= b;
00212                      }
00213                      if ((b == 128) || (x == sx && y == sy)) {
00214                             b = 1;
00215                             if (p) {
00216                                    gdCtxPrintf(out, ", ");
00217                                    if (!(p%12)) {
00218                                           gdCtxPrintf(out, "\n  ");
00219                                           p = 12;
00220                                    }
00221                             }
00222                             p++;
00223                             gdCtxPrintf(out, "0x%02X", c);
00224                             c = 0;
00225                      } else {
00226                             b <<= 1;
00227                      }
00228               }
00229        }
00230        gdCtxPrintf(out, "};\n");
00231 }
00232 /* }}} */
00233 
00234 /*
00235  * Local variables:
00236  * tab-width: 4
00237  * c-basic-offset: 4
00238  * End:
00239  * vim600: sw=4 ts=4 fdm=marker
00240  * vim<600: sw=4 ts=4
00241  */