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 / CrDatFrI.c < prev    next >
C/C++ Source or Header  |  1994-06-06  |  9KB  |  331 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. *  CrDataFI.c:                                                                *
  28. *                                                                             *
  29. *  XPM library                                                                *
  30. *  Scan an image and possibly its mask and create an XPM array                *
  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(CreateColors, int, (char **dataptr, unsigned int *data_size,
  47.               XpmColor *colors, unsigned int ncolors,
  48.               unsigned int cpp));
  49.  
  50. LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
  51.                unsigned int height, unsigned int cpp,
  52.                unsigned int *pixels, XpmColor *colors));
  53.  
  54. LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
  55.                   unsigned int *ext_size,
  56.                   unsigned int *ext_nlines));
  57.  
  58. LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
  59.                    XpmExtension *ext, unsigned int num,
  60.                    unsigned int ext_nlines));
  61.  
  62. int
  63. XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes)
  64.     Display *display;
  65.     char ***data_return;
  66.     XImage *image;
  67.     XImage *shapeimage;
  68.     XpmAttributes *attributes;
  69. {
  70.     XpmImage xpmimage;
  71.     XpmInfo info;
  72.     int ErrorStatus;
  73.  
  74.     /* initialize return value */
  75.     if (data_return)
  76.     *data_return = NULL;
  77.  
  78.     /* create an XpmImage from the image */
  79.     ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
  80.                          &xpmimage, attributes);
  81.     if (ErrorStatus != XpmSuccess)
  82.     return (ErrorStatus);
  83.  
  84.     /* create the data from the XpmImage */
  85.     if (attributes) {
  86.     xpmSetInfo(&info, attributes);
  87.     ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info);
  88.     } else
  89.     ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL);
  90.  
  91.     /* free the XpmImage */
  92.     XpmFreeXpmImage(&xpmimage);
  93.  
  94.     return (ErrorStatus);
  95. }
  96.  
  97. #undef RETURN
  98. #define RETURN(status) \
  99. { \
  100.     if (header) { \
  101.     for (l = 0; l < header_nlines; l++) \
  102.         if (header[l]) \
  103.         XpmFree(header[l]); \
  104.         XpmFree(header); \
  105.     } \
  106.     return(status); \
  107. }
  108.  
  109. int
  110. XpmCreateDataFromXpmImage(data_return, image, info)
  111.     char ***data_return;
  112.     XpmImage *image;
  113.     XpmInfo *info;
  114. {
  115.     /* calculation variables */
  116.     int ErrorStatus;
  117.     char buf[BUFSIZ];
  118.     char **header = NULL, **data, **sptr, **sptr2, *s;
  119.     unsigned int header_size, header_nlines;
  120.     unsigned int data_size, data_nlines;
  121.     unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
  122.     unsigned int offset, l, n;
  123.  
  124.     *data_return = NULL;
  125.  
  126.     extensions = info && (info->valuemask & XpmExtensions)
  127.     && info->nextensions;
  128.  
  129.     /* compute the number of extensions lines and size */
  130.     if (extensions)
  131.     CountExtensions(info->extensions, info->nextensions,
  132.             &ext_size, &ext_nlines);
  133.  
  134.     /*
  135.      * alloc a temporary array of char pointer for the header section which
  136.      * is the hints line + the color table lines
  137.      */
  138.     header_nlines = 1 + image->ncolors;
  139.     header_size = sizeof(char *) * header_nlines;
  140.     header = (char **) XpmCalloc(header_size, sizeof(char *));
  141.     if (!header)
  142.     return (XpmNoMemory);
  143.  
  144.     /* print the hints line */
  145.     s = buf;
  146.     sprintf(s, "%d %d %d %d", image->width, image->height,
  147.         image->ncolors, image->cpp);
  148.     s += strlen(s);
  149.  
  150.     if (info && (info->valuemask & XpmHotspot)) {
  151.     sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
  152.     s += strlen(s);
  153.     }
  154.     if (extensions)
  155.     sprintf(s, " XPMEXT");
  156.  
  157.     l = strlen(buf) + 1;
  158.     *header = (char *) XpmMalloc(l);
  159.     if (!*header)
  160.     RETURN(XpmNoMemory);
  161.     header_size += l;
  162.     strcpy(*header, buf);
  163.  
  164.     /* print colors */
  165.     ErrorStatus = CreateColors(header + 1, &header_size,
  166.                    image->colorTable, image->ncolors, image->cpp);
  167.  
  168.     if (ErrorStatus != XpmSuccess)
  169.     RETURN(ErrorStatus);
  170.  
  171.     /* now we know the size needed, alloc the data and copy the header lines */
  172.     offset = image->width * image->cpp + 1;
  173.     data_size = header_size + (image->height + ext_nlines) * sizeof(char *)
  174.     + image->height * offset + ext_size;
  175.  
  176.     data = (char **) XpmMalloc(data_size);
  177.     if (!data)
  178.     RETURN(XpmNoMemory);
  179.  
  180.     data_nlines = header_nlines + image->height + ext_nlines;
  181.     *data = (char *) (data + data_nlines);
  182.     n = image->ncolors;
  183.     for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) {
  184.     strcpy(*sptr, *sptr2);
  185.     *(sptr + 1) = *sptr + strlen(*sptr2) + 1;
  186.     }
  187.  
  188.     /* print pixels */
  189.     data[header_nlines] = (char *) data + header_size
  190.     + (image->height + ext_nlines) * sizeof(char *);
  191.  
  192.     CreatePixels(data + header_nlines, image->width, image->height,
  193.          image->cpp, image->data, image->colorTable);
  194.  
  195.     /* print extensions */
  196.     if (extensions)
  197.     CreateExtensions(data + header_nlines + image->height - 1, offset,
  198.              info->extensions, info->nextensions,
  199.              ext_nlines);
  200.  
  201.     *data_return = data;
  202.  
  203.     RETURN(XpmSuccess);
  204. }
  205.  
  206. static int
  207. CreateColors(dataptr, data_size, colors, ncolors, cpp)
  208.     char **dataptr;
  209.     unsigned int *data_size;
  210.     XpmColor *colors;
  211.     unsigned int ncolors;
  212.     unsigned int cpp;
  213. {
  214.     char buf[BUFSIZ];
  215.     unsigned int a, key, l;
  216.     char *s, *s2;
  217.     char **defaults;
  218.  
  219.     for (a = 0; a < ncolors; a++, colors++, dataptr++) {
  220.  
  221.     defaults = (char **) colors;
  222.     strncpy(buf, *defaults++, cpp);
  223.     s = buf + cpp;
  224.  
  225.     for (key = 1; key <= NKEYS; key++, defaults++) {
  226.         if (s2 = *defaults) {
  227.         sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  228.         s += strlen(s);
  229.         }
  230.     }
  231.     l = strlen(buf) + 1;
  232.     s = (char *) XpmMalloc(l);
  233.     if (!s)
  234.         return (XpmNoMemory);
  235.     *data_size += l;
  236.     strcpy(s, buf);
  237.     *dataptr = s;
  238.     }
  239.     return (XpmSuccess);
  240. }
  241.  
  242. static void
  243. CreatePixels(dataptr, width, height, cpp, pixels, colors)
  244.     char **dataptr;
  245.     unsigned int width;
  246.     unsigned int height;
  247.     unsigned int cpp;
  248.     unsigned int *pixels;
  249.     XpmColor *colors;
  250. {
  251.     char *s;
  252.     unsigned int x, y, h, offset;
  253.  
  254.     h = height - 1;
  255.     offset = width * cpp + 1;
  256.     for (y = 0; y < h; y++, dataptr++) {
  257.     s = *dataptr;
  258.     for (x = 0; x < width; x++, pixels++) {
  259.         strncpy(s, colors[*pixels].string, cpp);
  260.         s += cpp;
  261.     }
  262.     *s = '\0';
  263.     *(dataptr + 1) = *dataptr + offset;
  264.     }
  265.     /* duplicate some code to avoid a test in the loop */
  266.     s = *dataptr;
  267.     for (x = 0; x < width; x++, pixels++) {
  268.     strncpy(s, colors[*pixels].string, cpp);
  269.     s += cpp;
  270.     }
  271.     *s = '\0';
  272. }
  273.  
  274. static void
  275. CountExtensions(ext, num, ext_size, ext_nlines)
  276.     XpmExtension *ext;
  277.     unsigned int num;
  278.     unsigned int *ext_size;
  279.     unsigned int *ext_nlines;
  280. {
  281.     unsigned int x, y, a, size, nlines;
  282.     char **line;
  283.  
  284.     size = 0;
  285.     nlines = 0;
  286.     for (x = 0; x < num; x++, ext++) {
  287.     /* 1 for the name */
  288.     nlines += ext->nlines + 1;
  289.     /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
  290.     size += strlen(ext->name) + 8;
  291.     a = ext->nlines;
  292.     for (y = 0, line = ext->lines; y < a; y++, line++)
  293.         size += strlen(*line) + 1;
  294.     }
  295.     /* 10 and 1 are for the ending "XPMENDEXT" */
  296.     *ext_size = size + 10;
  297.     *ext_nlines = nlines + 1;
  298. }
  299.  
  300. static void
  301. CreateExtensions(dataptr, offset, ext, num, ext_nlines)
  302.     char **dataptr;
  303.     unsigned int offset;
  304.     XpmExtension *ext;
  305.     unsigned int num;
  306.     unsigned int ext_nlines;
  307. {
  308.     unsigned int x, y, a, b;
  309.     char **line;
  310.  
  311.     *(dataptr + 1) = *dataptr + offset;
  312.     dataptr++;
  313.     a = 0;
  314.     for (x = 0; x < num; x++, ext++) {
  315.     sprintf(*dataptr, "XPMEXT %s", ext->name);
  316.     a++;
  317.     if (a < ext_nlines)
  318.         *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
  319.     dataptr++;
  320.     b = ext->nlines;
  321.     for (y = 0, line = ext->lines; y < b; y++, line++) {
  322.         strcpy(*dataptr, *line);
  323.         a++;
  324.         if (a < ext_nlines)
  325.         *(dataptr + 1) = *dataptr + strlen(*line) + 1;
  326.         dataptr++;
  327.     }
  328.     }
  329.     strcpy(*dataptr, "XPMENDEXT");
  330. }
  331.