"Fossies" - the Fresh Open Source Software Archive

Member "libgd-2.3.2/src/gd_xbm.c" (3 Mar 2021, 6429 Bytes) of package /linux/www/libgd-2.3.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gd_xbm.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.1_vs_2.3.2.

    1 /**
    2  * File: XBM IO
    3  *
    4  * Read and write XBM images.
    5  */
    6 
    7 #ifdef HAVE_CONFIG_H
    8 #   include "config.h"
    9 #endif
   10 
   11 #include <ctype.h>
   12 #include <stdio.h>
   13 #include <math.h>
   14 #include <string.h>
   15 #include <stdlib.h>
   16 #include <stdarg.h>
   17 #include "gd.h"
   18 #include "gd_errors.h"
   19 #include "gdhelpers.h"
   20 
   21 #define MAX_XBM_LINE_SIZE 255
   22 
   23 
   24 /*
   25   Function: gdImageCreateFromXbm
   26 
   27     <gdImageCreateFromXbm> is called to load images from X bitmap
   28     format files. Invoke <gdImageCreateFromXbm> with an already opened
   29     pointer to a file containing the desired
   30     image. <gdImageCreateFromXbm> returns a <gdImagePtr> to the new
   31     image, or NULL if unable to load the image (most often because the
   32     file is corrupt or does not contain an X bitmap format
   33     image). <gdImageCreateFromXbm> does not close the file.
   34 
   35     You can inspect the sx and sy members of the image to determine
   36     its size. The image must eventually be destroyed using
   37     <gdImageDestroy>.
   38 
   39     X11 X bitmaps (which define a char[]) as well as X10 X bitmaps (which define
   40     a short[]) are supported.
   41 
   42   Parameters:
   43 
   44     fd - The input FILE pointer
   45 
   46   Returns:
   47 
   48     A pointer to the new image or NULL if an error occurred.
   49 
   50   Example:
   51     (start code)
   52 
   53     gdImagePtr im;
   54     FILE *in;
   55     in = fopen("myxbm.xbm", "rb");
   56     im = gdImageCreateFromXbm(in);
   57     fclose(in);
   58     // ... Use the image ...
   59     gdImageDestroy(im);
   60 
   61     (end code)
   62 */
   63 BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm(FILE * fd)
   64 {
   65     char fline[MAX_XBM_LINE_SIZE];
   66     char iname[MAX_XBM_LINE_SIZE];
   67     char *type;
   68     int value;
   69     unsigned int width = 0, height = 0;
   70     int fail = 0;
   71     int max_bit = 0;
   72 
   73     gdImagePtr im;
   74     int bytes = 0, i;
   75     int bit, x = 0, y = 0;
   76     int ch;
   77     char h[8];
   78     unsigned int b;
   79 
   80     rewind(fd);
   81     while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
   82         fline[MAX_XBM_LINE_SIZE-1] = '\0';
   83         if (strlen(fline) == MAX_XBM_LINE_SIZE-1) {
   84             return 0;
   85         }
   86         if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
   87             if (!(type = strrchr(iname, '_'))) {
   88                 type = iname;
   89             } else {
   90                 type++;
   91             }
   92 
   93             if (!strcmp("width", type)) {
   94                 width = (unsigned int) value;
   95             }
   96             if (!strcmp("height", type)) {
   97                 height = (unsigned int) value;
   98             }
   99         } else {
  100             if ( sscanf(fline, "static unsigned char %s = {", iname) == 1
  101               || sscanf(fline, "static char %s = {", iname) == 1)
  102             {
  103                 max_bit = 128;
  104             } else if (sscanf(fline, "static unsigned short %s = {", iname) == 1
  105                     || sscanf(fline, "static short %s = {", iname) == 1)
  106             {
  107                 max_bit = 32768;
  108             }
  109             if (max_bit) {
  110                 bytes = (width + 7) / 8 * height;
  111                 if (!bytes) {
  112                     return 0;
  113                 }
  114                 if (!(type = strrchr(iname, '_'))) {
  115                     type = iname;
  116                 } else {
  117                     type++;
  118                 }
  119                 if (!strcmp("bits[]", type)) {
  120                     break;
  121                 }
  122             }
  123         }
  124     }
  125     if (!bytes || !max_bit) {
  126         return 0;
  127     }
  128 
  129     if(!(im = gdImageCreate(width, height))) {
  130         return 0;
  131     }
  132     gdImageColorAllocate(im, 255, 255, 255);
  133     gdImageColorAllocate(im, 0, 0, 0);
  134     h[2] = '\0';
  135     h[4] = '\0';
  136     for (i = 0; i < bytes; i++) {
  137         while (1) {
  138             if ((ch=getc(fd)) == EOF) {
  139                 fail = 1;
  140                 break;
  141             }
  142             if (ch == 'x') {
  143                 break;
  144             }
  145         }
  146         if (fail) {
  147             break;
  148         }
  149         /* Get hex value */
  150         if ((ch=getc(fd)) == EOF) {
  151             break;
  152         }
  153         h[0] = ch;
  154         if ((ch=getc(fd)) == EOF) {
  155             break;
  156         }
  157         h[1] = ch;
  158         if (max_bit == 32768) {
  159             if ((ch=getc(fd)) == EOF) {
  160                 break;
  161             }
  162             h[2] = ch;
  163             if ((ch=getc(fd)) == EOF) {
  164                 break;
  165             }
  166             h[3] = ch;
  167         }
  168         if (sscanf(h, "%x", &b) != 1) {
  169             gd_error("invalid XBM");
  170             gdImageDestroy(im);
  171             return 0;
  172         }
  173         for (bit = 1; bit <= max_bit; bit = bit << 1) {
  174             gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
  175             if (x == im->sx) {
  176                 x = 0;
  177                 y++;
  178                 if (y == im->sy) {
  179                     return im;
  180                 }
  181                 break;
  182             }
  183         }
  184     }
  185 
  186     gd_error("EOF before image was complete");
  187     gdImageDestroy(im);
  188     return 0;
  189 }
  190 
  191 
  192 /* {{{ gdCtxPrintf */
  193 static void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
  194 {
  195     char buf[1024];
  196     int len;
  197     va_list args;
  198 
  199     va_start(args, format);
  200     len = vsnprintf(buf, sizeof(buf)-1, format, args);
  201     va_end(args);
  202     out->putBuf(out, buf, len);
  203 }
  204 /* }}} */
  205 
  206 /* The compiler will optimize strlen(constant) to a constant number. */
  207 #define gdCtxPuts(out, s) out->putBuf(out, s, strlen(s))
  208 
  209 
  210 /**
  211  * Function: gdImageXbmCtx
  212  *
  213  *  Writes an image to an IO context in X11 bitmap format.
  214  *
  215  * Parameters:
  216  *
  217  *  image     - The <gdImagePtr> to write.
  218  *  file_name - The prefix of the XBM's identifiers. Illegal characters are
  219  *              automatically stripped.
  220  *  gd        - Which color to use as forground color. All pixels with another
  221  *              color are unset.
  222  *  out       - The <gdIOCtx> to write the image file to.
  223  *
  224  */
  225 BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
  226 {
  227     int x, y, c, b, sx, sy, p;
  228     char *name, *f;
  229     size_t i, l;
  230 
  231     name = file_name;
  232     if ((f = strrchr(name, '/')) != NULL) name = f+1;
  233     if ((f = strrchr(name, '\\')) != NULL) name = f+1;
  234     name = strdup(name);
  235     if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
  236     if ((l = strlen(name)) == 0) {
  237         free(name);
  238         name = strdup("image");
  239     } else {
  240         for (i=0; i<l; i++) {
  241             /* only in C-locale isalnum() would work */
  242             if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
  243                 name[i] = '_';
  244             }
  245         }
  246     }
  247 
  248     /* Since "name" comes from the user, run it through a direct puts.
  249      * Trying to printf it into a local buffer means we'd need a large
  250      * or dynamic buffer to hold it all. */
  251 
  252     /* #define <name>_width 1234 */
  253     gdCtxPuts(out, "#define ");
  254     gdCtxPuts(out, name);
  255     gdCtxPuts(out, "_width ");
  256     gdCtxPrintf(out, "%d\n", gdImageSX(image));
  257 
  258     /* #define <name>_height 1234 */
  259     gdCtxPuts(out, "#define ");
  260     gdCtxPuts(out, name);
  261     gdCtxPuts(out, "_height ");
  262     gdCtxPrintf(out, "%d\n", gdImageSY(image));
  263 
  264     /* static unsigned char <name>_bits[] = {\n */
  265     gdCtxPuts(out, "static unsigned char ");
  266     gdCtxPuts(out, name);
  267     gdCtxPuts(out, "_bits[] = {\n  ");
  268 
  269     free(name);
  270 
  271     b = 1;
  272     p = 0;
  273     c = 0;
  274     sx = gdImageSX(image);
  275     sy = gdImageSY(image);
  276     for (y = 0; y < sy; y++) {
  277         for (x = 0; x < sx; x++) {
  278             if (gdImageGetPixel(image, x, y) == fg) {
  279                 c |= b;
  280             }
  281             if ((b == 128) || (x == sx - 1)) {
  282                 b = 1;
  283                 if (p) {
  284                     gdCtxPuts(out, ", ");
  285                     if (!(p%12)) {
  286                         gdCtxPuts(out, "\n  ");
  287                         p = 12;
  288                     }
  289                 }
  290                 p++;
  291                 gdCtxPrintf(out, "0x%02X", c);
  292                 c = 0;
  293             } else {
  294                 b <<= 1;
  295             }
  296         }
  297     }
  298     gdCtxPuts(out, "};\n");
  299 }