home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / x / x11r6-ch / xpm-3.4 / xpm-3 / xpm-3.4c / lib / CrBufFrI.c < prev    next >
C/C++ Source or Header  |  1994-06-06  |  10KB  |  350 lines

  1. /*
  2.  * Copyright (C) 1989-94 GROUPE BULL
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  5.  * of this software and associated documentation files (the "Software"), to
  6.  * deal in the Software without restriction, including without limitation the
  7.  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8.  * sell copies of the Software, and to permit persons to whom the Software is
  9.  * furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17.  * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  18.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20.  *
  21.  * Except as contained in this notice, the name of GROUPE BULL shall not be
  22.  * used in advertising or otherwise to promote the sale, use or other dealings
  23.  * in this Software without prior written authorization from GROUPE BULL.
  24.  */
  25.  
  26. /*****************************************************************************\
  27. *  CrBufFrI.c:                                                                *
  28. *                                                                             *
  29. *  XPM library                                                                *
  30. *  Scan an image and possibly its mask and create an XPM buffer               *
  31. *                                                                             *
  32. *  Developed by Arnaud Le Hors                                                *
  33. \*****************************************************************************/
  34.  
  35. #include "xpmP.h"
  36. #ifdef VMS
  37. #include "sys$library:string.h"
  38. #else
  39. #if defined(SYSV) || defined(SVR4)
  40. #include <string.h>
  41. #else
  42. #include <strings.h>
  43. #endif
  44. #endif
  45.  
  46. LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
  47.              unsigned int *used_size, XpmColor *colors,
  48.              unsigned int ncolors, unsigned int cpp));
  49.  
  50. LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size,
  51.               unsigned int width, unsigned int height,
  52.               unsigned int cpp, unsigned int *pixels,
  53.               XpmColor *colors));
  54.  
  55. LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
  56.                   XpmExtension *ext, unsigned int num));
  57.  
  58. LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
  59. LFUNC(CommentsSize, int, (XpmInfo *info));
  60.  
  61. int
  62. XpmCreateBufferFromImage(display, buffer_return, image, shapeimage, attributes)
  63.     Display *display;
  64.     char **buffer_return;
  65.     XImage *image;
  66.     XImage *shapeimage;
  67.     XpmAttributes *attributes;
  68. {
  69.     XpmImage xpmimage;
  70.     XpmInfo info;
  71.     int ErrorStatus;
  72.  
  73.     /* initialize return value */
  74.     if (buffer_return)
  75.     *buffer_return = NULL;
  76.  
  77.     /* create an XpmImage from the image */
  78.     ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
  79.                          &xpmimage, attributes);
  80.     if (ErrorStatus != XpmSuccess)
  81.     return (ErrorStatus);
  82.  
  83.     /* create the buffer from the XpmImage */
  84.     if (attributes) {
  85.     xpmSetInfo(&info, attributes);
  86.     ErrorStatus =
  87.         XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info);
  88.     } else
  89.     ErrorStatus =
  90.         XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL);
  91.  
  92.     /* free the XpmImage */
  93.     XpmFreeXpmImage(&xpmimage);
  94.  
  95.     return (ErrorStatus);
  96. }
  97.  
  98.  
  99. #undef RETURN
  100. #define RETURN(status) \
  101. { \
  102.     if (ptr) \
  103.     XpmFree(ptr); \
  104.     return(status); \
  105. }
  106.  
  107. int
  108. XpmCreateBufferFromXpmImage(buffer_return, image, info)
  109.     char **buffer_return;
  110.     XpmImage *image;
  111.     XpmInfo *info;
  112. {
  113.     /* calculation variables */
  114.     int ErrorStatus;
  115.     char buf[BUFSIZ];
  116.     unsigned int cmts, extensions, ext_size = 0;
  117.     unsigned int l, cmt_size = 0;
  118.     char *ptr = NULL, *p;
  119.     unsigned int ptr_size, used_size;
  120.  
  121.     *buffer_return = NULL;
  122.  
  123.     cmts = info && (info->valuemask & XpmComments);
  124.     extensions = info && (info->valuemask & XpmExtensions)
  125.     && info->nextensions;
  126.  
  127.     /* compute the extensions and comments size */
  128.     if (extensions)
  129.     ext_size = ExtensionsSize(info->extensions, info->nextensions);
  130.     if (cmts)
  131.     cmt_size = CommentsSize(info);
  132.  
  133.     /* write the header line */
  134.     sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
  135.     used_size = strlen(buf);
  136.     ptr_size = used_size + ext_size + cmt_size + 1;
  137.     ptr = (char *) XpmMalloc(ptr_size);
  138.     if (!ptr)
  139.     return XpmNoMemory;
  140.     strcpy(ptr, buf);
  141.  
  142.     /* write the values line */
  143.     if (cmts && info->hints_cmt) {
  144.     sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt);
  145.     used_size += strlen(info->hints_cmt) + 5;
  146.     }
  147.     sprintf(buf, "\"%d %d %d %d", image->width, image->height,
  148.         image->ncolors, image->cpp);
  149.     l = strlen(buf);
  150.  
  151.     if (info && (info->valuemask & XpmHotspot)) {
  152.     sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot);
  153.     l = strlen(buf);
  154.     }
  155.     if (extensions) {
  156.     sprintf(buf + l, " XPMEXT");
  157.     l = strlen(buf);
  158.     }
  159.     sprintf(buf + l, "\",\n");
  160.     l = strlen(buf);
  161.     ptr_size += l;
  162.     p = (char *) XpmRealloc(ptr, ptr_size);
  163.     if (!p)
  164.     RETURN(XpmNoMemory);
  165.     ptr = p;
  166.     strcpy(ptr + used_size, buf);
  167.     used_size += l;
  168.  
  169.     /* write colors */
  170.     if (cmts && info->colors_cmt) {
  171.     sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt);
  172.     used_size += strlen(info->colors_cmt) + 5;
  173.     }
  174.     ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
  175.                   image->colorTable, image->ncolors, image->cpp);
  176.  
  177.     if (ErrorStatus != XpmSuccess)
  178.     RETURN(ErrorStatus);
  179.  
  180.     /*
  181.      * now we know the exact size we needed, realloc the data 4 = 1 (for
  182.      * '"') + 3 (for '",\n') 1 = - 2 is because the last line does not end
  183.      * with ',\n' + 3 (for '};\n')
  184.      */
  185.     ptr_size += image->height * (image->width * image->cpp + 4) + 1;
  186.  
  187.     p = (char *) XpmRealloc(ptr, ptr_size);
  188.     if (!p)
  189.     RETURN(XpmNoMemory);
  190.     ptr = p;
  191.  
  192.     /* print pixels */
  193.     if (cmts && info->pixels_cmt) {
  194.     sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
  195.     used_size += strlen(info->pixels_cmt) + 5;
  196.     }
  197.     WritePixels(ptr + used_size, &used_size, image->width, image->height,
  198.         image->cpp, image->data, image->colorTable);
  199.  
  200.     /* print extensions */
  201.     if (extensions)
  202.     WriteExtensions(ptr + used_size, &used_size,
  203.             info->extensions, info->nextensions);
  204.  
  205.     /* close the array */
  206.     sprintf(ptr + used_size, "};\n");
  207.  
  208.     *buffer_return = ptr;
  209.  
  210.     return (XpmSuccess);
  211. }
  212.  
  213. static int
  214. WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp)
  215.     char **dataptr;
  216.     unsigned int *data_size;
  217.     unsigned int *used_size;
  218.     XpmColor *colors;
  219.     unsigned int ncolors;
  220.     unsigned int cpp;
  221. {
  222.     char buf[BUFSIZ];
  223.     unsigned int a, key, l;
  224.     char *s, *s2;
  225.     char **defaults;
  226.  
  227.     *buf = '"';
  228.     for (a = 0; a < ncolors; a++, colors++) {
  229.  
  230.     defaults = (char **) colors;
  231.     s = buf + 1;
  232.     strncpy(s, *defaults++, cpp);
  233.     s += cpp;
  234.  
  235.     for (key = 1; key <= NKEYS; key++, defaults++) {
  236.         if (s2 = *defaults) {
  237.         sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  238.         s += strlen(s);
  239.         }
  240.     }
  241.     strcpy(s, "\",\n");
  242.     l = strlen(buf);
  243.     s = (char *) XpmRealloc(*dataptr, *data_size + l);
  244.     if (!s)
  245.         return (XpmNoMemory);
  246.     *data_size += l;
  247.     strcpy(s + *used_size, buf);
  248.     *used_size += l;
  249.     *dataptr = s;
  250.     }
  251.     return (XpmSuccess);
  252. }
  253.  
  254. static void
  255. WritePixels(dataptr, used_size, width, height, cpp, pixels, colors)
  256.     char *dataptr;
  257.     unsigned int *used_size;
  258.     unsigned int width;
  259.     unsigned int height;
  260.     unsigned int cpp;
  261.     unsigned int *pixels;
  262.     XpmColor *colors;
  263. {
  264.     char *s = dataptr;
  265.     unsigned int x, y, h;
  266.  
  267.     h = height - 1;
  268.     for (y = 0; y < h; y++) {
  269.     *s++ = '"';
  270.     for (x = 0; x < width; x++, pixels++) {
  271.         strncpy(s, colors[*pixels].string, cpp);
  272.         s += cpp;
  273.     }
  274.     strcpy(s, "\",\n");
  275.     s += 3;
  276.     }
  277.     /* duplicate some code to avoid a test in the loop */
  278.     *s++ = '"';
  279.     for (x = 0; x < width; x++, pixels++) {
  280.     strncpy(s, colors[*pixels].string, cpp);
  281.     s += cpp;
  282.     }
  283.     *s++ = '"';
  284.     *used_size += s - dataptr;
  285. }
  286.  
  287. static int
  288. ExtensionsSize(ext, num)
  289.     XpmExtension *ext;
  290.     unsigned int num;
  291. {
  292.     unsigned int x, y, a, size;
  293.     char **line;
  294.  
  295.     size = 0;
  296.     for (x = 0; x < num; x++, ext++) {
  297.     /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
  298.     size += strlen(ext->name) + 11;
  299.     a = ext->nlines;
  300.     for (y = 0, line = ext->lines; y < a; y++, line++)
  301.         /* 4 = 3 (for ',\n"') + 1 (for '"') */
  302.         size += strlen(*line) + 4;
  303.     }
  304.     /* 13 is for ',\n"XPMENDEXT"' */
  305.     return size + 13;
  306. }
  307.  
  308. static void
  309. WriteExtensions(dataptr, used_size, ext, num)
  310.     char *dataptr;
  311.     unsigned int *used_size;
  312.     XpmExtension *ext;
  313.     unsigned int num;
  314. {
  315.     unsigned int x, y, a;
  316.     char **line;
  317.     char *s = dataptr;
  318.  
  319.     for (x = 0; x < num; x++, ext++) {
  320.     sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
  321.     s += strlen(ext->name) + 11;
  322.     a = ext->nlines;
  323.     for (y = 0, line = ext->lines; y < a; y++, line++) {
  324.         sprintf(s, ",\n\"%s\"", *line);
  325.         s += strlen(*line) + 4;
  326.     }
  327.     }
  328.     strcpy(s, ",\n\"XPMENDEXT\"");
  329.     *used_size += s - dataptr + 13;
  330. }
  331.  
  332. static int
  333. CommentsSize(info)
  334.     XpmInfo *info;
  335. {
  336.     int size = 0;
  337.  
  338.     /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
  339.     if (info->hints_cmt)
  340.     size += 5 + strlen(info->hints_cmt);
  341.  
  342.     if (info->colors_cmt)
  343.     size += 5 + strlen(info->colors_cmt);
  344.  
  345.     if (info->pixels_cmt)
  346.     size += 5 + strlen(info->pixels_cmt);
  347.  
  348.     return size;
  349. }
  350.