home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / src / xpm / XpmCrDataFI.c < prev    next >
C/C++ Source or Header  |  2000-07-29  |  11KB  |  418 lines

  1. /* Copyright 1990-92 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * XpmCrDataFI.c:                                                              *
  4. *                                                                             *
  5. *  XPM library                                                                *
  6. *  Scan an image and possibly its mask and create an XPM array                *
  7. *                                                                             *
  8. *  Developed by Arnaud Le Hors                                                *
  9. \*****************************************************************************/
  10.  
  11. #include "xpmP.h"
  12. #ifdef VMS
  13. #include "sys$library:string.h"
  14. #else
  15. #if defined(SYSV) || defined(SVR4)
  16. #include <string.h>
  17. #else
  18. #include <strings.h>
  19. #endif
  20. #endif
  21.  
  22. LFUNC(CreateTransparentColor, int, (char **dataptr, unsigned int *data_size,
  23.                     char **colors, unsigned int cpp,
  24.                     unsigned int mask_pixel,
  25.                     char ***colorTable));
  26.  
  27. LFUNC(CreateOtherColors, int, (char **dataptr, unsigned int *data_size,
  28.                    char **colors, XColor *xcolors,
  29.                    unsigned int ncolors, unsigned int cpp,
  30.                    unsigned int mask_pixel, char ***colorTable,
  31.                    unsigned int ncolors2, Pixel *pixels,
  32.                    char *rgb_fname));
  33.  
  34. LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
  35.                unsigned int height, unsigned int cpp,
  36.                unsigned int *pixels, char **colors));
  37.  
  38. LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
  39.                   unsigned int *ext_size,
  40.                   unsigned int *ext_nlines));
  41.  
  42. LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
  43.                    XpmExtension *ext, unsigned int num,
  44.                    unsigned int ext_nlines));
  45.  
  46. int
  47. XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes)
  48.     Display *display;
  49.     char ***data_return;
  50.     XImage *image;
  51.     XImage *shapeimage;
  52.     XpmAttributes *attributes;
  53. {
  54.     int ErrorStatus;
  55.     xpmInternAttrib attrib;
  56.  
  57.     /*
  58.      * initialize return values 
  59.      */
  60.     if (data_return)
  61.     *data_return = NULL;
  62.  
  63.     xpmInitInternAttrib(&attrib);
  64.  
  65.     /*
  66.      * Scan image then create data 
  67.      */
  68.     ErrorStatus = xpmScanImage(display, image, shapeimage,
  69.                    attributes, &attrib);
  70.  
  71.     if (ErrorStatus == XpmSuccess)
  72.     ErrorStatus = xpmCreateData(data_return, &attrib, attributes);
  73.  
  74.     xpmFreeInternAttrib(&attrib);
  75.  
  76.     return (ErrorStatus);
  77. }
  78.  
  79.  
  80. #undef RETURN
  81. #define RETURN(status) \
  82.   { if (header) { \
  83.         for (l = 0; l < header_nlines; l++) \
  84.         if (header[l]) \
  85.         free(header[l]); \
  86.     free(header); \
  87.     } \
  88.     return(status); }
  89.  
  90. int
  91. xpmCreateData(data_return, attrib, attributes)
  92.     char ***data_return;
  93.     xpmInternAttrib *attrib;
  94.     XpmAttributes *attributes;
  95. {
  96.     /* calculation variables */
  97.     int ErrorStatus;
  98.     char buf[BUFSIZ];
  99.     char **header = NULL, **data, **sptr, **sptr2, *s;
  100.     unsigned int header_size, header_nlines;
  101.     unsigned int data_size, data_nlines;
  102.     unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
  103.     unsigned int infos = 0, offset, l, n;
  104.  
  105.     *data_return = NULL;
  106.  
  107.     infos = attributes && (attributes->valuemask & XpmInfos);
  108.     extensions = attributes && (attributes->valuemask & XpmExtensions)
  109.     && attributes->nextensions;
  110.  
  111.     /* compute the number of extensions lines and size */
  112.     if (extensions)
  113.     CountExtensions(attributes->extensions, attributes->nextensions,
  114.             &ext_size, &ext_nlines);
  115.  
  116.     /*
  117.      * alloc a temporary array of char pointer for the header section which
  118.      * is the hints line + the color table lines 
  119.      */
  120.     header_nlines = 1 + attrib->ncolors;
  121.     header_size = sizeof(char *) * header_nlines;
  122.     header = (char **) calloc(header_size, sizeof(char *));
  123.     if (!header)
  124.     RETURN(XpmNoMemory);
  125.  
  126.     /*
  127.      * print the hints line 
  128.      */
  129.     s = buf;
  130.     sprintf(s, "%d %d %d %d", attrib->width, attrib->height,
  131.         attrib->ncolors, attrib->cpp);
  132.     s += strlen(s);
  133.  
  134.     if (attributes && (attributes->valuemask & XpmHotspot)) {
  135.     sprintf(s, " %d %d", attributes->x_hotspot, attributes->y_hotspot);
  136.     s += strlen(s);
  137.     }
  138.  
  139.     if (extensions)
  140.     sprintf(s, " XPMEXT");
  141.  
  142.     l = strlen(buf) + 1;
  143.     *header = (char *) malloc(l);
  144.     if (!*header)
  145.     RETURN(XpmNoMemory);
  146.     header_size += l;
  147.     strcpy(*header, buf);
  148.  
  149.     /*
  150.      * print colors 
  151.      */
  152.  
  153.     /* transparent color */
  154.     if (attrib->mask_pixel != UNDEF_PIXEL) {
  155.     ErrorStatus =
  156.         CreateTransparentColor(header + 1, &header_size,
  157.                    attrib->colorStrings, attrib->cpp,
  158.                    (infos ? attributes->mask_pixel : 0),
  159.                    (infos ? attributes->colorTable : NULL));
  160.     if (ErrorStatus != XpmSuccess)
  161.         RETURN(ErrorStatus);
  162.  
  163.     offset = 1;
  164.     } else
  165.     offset = 0;
  166.  
  167.     /* other colors */
  168.     ErrorStatus =
  169.     CreateOtherColors(header + 1 + offset, &header_size,
  170.               attrib->colorStrings + offset,
  171.               attrib->xcolors + offset, attrib->ncolors - offset,
  172.               attrib->cpp, (infos ? attributes->mask_pixel : 0),
  173.               (infos ? attributes->colorTable : NULL),
  174.               (infos ? attributes->ncolors : 0),
  175.               (infos ? attributes->pixels : NULL),
  176.               (attributes &&
  177.                (attributes->valuemask & XpmRgbFilename) ?
  178.                attributes->rgb_fname : NULL));
  179.     if (ErrorStatus != XpmSuccess)
  180.     RETURN(ErrorStatus);
  181.  
  182.     /*
  183.      * now we know the size needed, alloc the data and copy the header lines 
  184.      */
  185.     offset = attrib->width * attrib->cpp + 1;
  186.     data_size = header_size + (attrib->height + ext_nlines) * sizeof(char *)
  187.     + attrib->height * offset + ext_size;
  188.  
  189.     data = (char **) malloc(data_size);
  190.     if (!data)
  191.     RETURN(XpmNoMemory);
  192.  
  193.     data_nlines = header_nlines + attrib->height + ext_nlines;
  194.     *data = (char *) (data + data_nlines);
  195.     n = attrib->ncolors;
  196.     for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) {
  197.     strcpy(*sptr, *sptr2);
  198.     *(sptr + 1) = *sptr + strlen(*sptr2) + 1;
  199.     }
  200.  
  201.     /*
  202.      * print pixels 
  203.      */
  204.     data[header_nlines] = (char *) data + header_size +
  205.     (attrib->height + ext_nlines) * sizeof(char *);
  206.  
  207.     CreatePixels(data + header_nlines, attrib->width, attrib->height,
  208.          attrib->cpp, attrib->pixelindex, attrib->colorStrings);
  209.  
  210.     /*
  211.      * print extensions
  212.      */
  213.     if (extensions)
  214.     CreateExtensions(data + header_nlines + attrib->height - 1, offset,
  215.              attributes->extensions, attributes->nextensions,
  216.              ext_nlines);
  217.  
  218.     *data_return = data;
  219.  
  220.     RETURN(XpmSuccess);
  221. }
  222.  
  223.  
  224. static int
  225. CreateTransparentColor(dataptr, data_size, colors, cpp, mask_pixel, colorTable)
  226. char **dataptr;
  227. unsigned int *data_size;
  228. char **colors;
  229. unsigned int cpp;
  230. unsigned int mask_pixel;
  231. char ***colorTable;
  232. {
  233.     char buf[BUFSIZ];
  234.     unsigned int key, l;
  235.     char *s, *s2;
  236.  
  237.     strncpy(buf, *colors, cpp);
  238.     s = buf + cpp;
  239.  
  240.     if (colorTable && mask_pixel != UNDEF_PIXEL) {
  241.     for (key = 1; key <= NKEYS; key++) {
  242.         if (s2 = colorTable[mask_pixel][key]) {
  243.         sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  244.         s += strlen(s);
  245.         }
  246.     }
  247.     } else
  248.     sprintf(s, "\tc %s", TRANSPARENT_COLOR);
  249.  
  250.     l = strlen(buf) + 1;
  251.     s = (char *) malloc(l);
  252.     if (!s)
  253.     return(XpmNoMemory);
  254.     *data_size += l;
  255.     strcpy(s, buf);
  256.     *dataptr = s;
  257.     return(XpmSuccess);
  258. }
  259.  
  260. static int
  261. CreateOtherColors(dataptr, data_size, colors, xcolors, ncolors, cpp,
  262.           mask_pixel, colorTable, ncolors2, pixels, rgb_fname)
  263. char **dataptr;
  264. unsigned int *data_size;
  265. char **colors;
  266. XColor *xcolors;
  267. unsigned int ncolors;
  268. unsigned int cpp;
  269. unsigned int mask_pixel;
  270. char ***colorTable;
  271. unsigned int ncolors2;
  272. Pixel *pixels;
  273. char *rgb_fname;
  274. {
  275.     char buf[BUFSIZ];
  276.     unsigned int a, b, c, d, key, l;
  277.     char *s, *s2, *colorname;
  278.     xpmRgbName rgbn[MAX_RGBNAMES];
  279.     int rgbn_max = 0;
  280.  
  281.     /* read the rgb file if any was specified */
  282.     if (rgb_fname)
  283.     rgbn_max = xpmReadRgbNames(rgb_fname, rgbn);
  284.  
  285.     for (a = 0; a < ncolors; a++, colors++, xcolors++, dataptr++) {
  286.  
  287.     strncpy(buf, *colors, cpp);
  288.     s = buf + cpp;
  289.  
  290.     c = 1;
  291.     if (colorTable) {
  292.         d = 0;
  293.         for (b = 0; b < ncolors2; b++) {
  294.         if (b == mask_pixel) {
  295.             d = 1;
  296.             continue;
  297.         }
  298.         if (pixels[b - d] == xcolors->pixel)
  299.             break;
  300.         }
  301.         if (b != ncolors2) {
  302.         c = 0;
  303.         for (key = 1; key <= NKEYS; key++) {
  304.             if (s2 = colorTable[b][key]) {
  305.             sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  306.             s += strlen(s);
  307.             }
  308.         }
  309.         }
  310.     }
  311.     if (c) {
  312.         colorname = NULL;
  313.         if (rgbn_max)
  314.         colorname = xpmGetRgbName(rgbn, rgbn_max, xcolors->red,
  315.                       xcolors->green, xcolors->blue);
  316.         if (colorname)
  317.         sprintf(s, "\tc %s", colorname);
  318.         else
  319.         sprintf(s, "\tc #%04X%04X%04X",
  320.             xcolors->red, xcolors->green, xcolors->blue);
  321.         s += strlen(s);
  322.     }
  323.     l = strlen(buf) + 1;
  324.     s = (char *) malloc(l);
  325.     if (!s)
  326.         return(XpmNoMemory);
  327.     *data_size += l;
  328.     strcpy(s, buf);
  329.     *dataptr = s;
  330.     }
  331.     xpmFreeRgbNames(rgbn, rgbn_max);
  332.     return(XpmSuccess);
  333. }
  334.  
  335. static void
  336. CreatePixels(dataptr, width, height, cpp, pixels, colors)
  337. char **dataptr;
  338. unsigned int width;
  339. unsigned int height;
  340. unsigned int cpp;
  341. unsigned int *pixels;
  342. char **colors;
  343. {
  344.     char *s;
  345.     unsigned int x, y, h, offset;
  346.  
  347.     h = height - 1;
  348.     offset = width * cpp + 1;
  349.     for (y = 0; /* test is inside loop */ ; y++, dataptr++) {
  350.     s = *dataptr;
  351.     for (x = 0; x < width; x++, pixels++) {
  352.         strncpy(s, colors[*pixels], cpp);
  353.         s += cpp;
  354.     }
  355.     *s = '\0';
  356.     if (y >= h)
  357.         break;        /* LEAVE LOOP */
  358.     *(dataptr + 1) = *dataptr + offset;
  359.     }
  360. }
  361.  
  362. static void
  363. CountExtensions(ext, num, ext_size, ext_nlines)
  364. XpmExtension *ext;
  365. unsigned int num;
  366. unsigned int *ext_size;
  367. unsigned int *ext_nlines;
  368. {
  369.     unsigned int x, y, a, size, nlines;
  370.     char **lines;
  371.  
  372.     size = 0;
  373.     nlines = 0;
  374.     for (x = 0; x < num; x++, ext++) {
  375.     /* "+ 2" is for the name and the ending 0 */
  376.     nlines += ext->nlines + 2;
  377.     /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
  378.     size += strlen(ext->name) + 8;
  379.     a = ext->nlines;
  380.     for (y = 0, lines = ext->lines; y < a; y++, lines++)
  381.         size += strlen(*lines) + 1;
  382.     }
  383.     *ext_size = size;
  384.     *ext_nlines = nlines;
  385. }
  386.  
  387. static void
  388. CreateExtensions(dataptr, offset, ext, num, ext_nlines)
  389. char **dataptr;
  390. unsigned int offset;
  391. XpmExtension *ext;
  392. unsigned int num;
  393. unsigned int ext_nlines;
  394. {
  395.     unsigned int x, y, a, b;
  396.     char **sptr;
  397.  
  398.     *(dataptr + 1) = *dataptr + offset;
  399.     dataptr++;
  400.     a = 0;
  401.     for (x = 0; x < num; x++, ext++) {
  402.     sprintf(*dataptr, "XPMEXT %s", ext->name);
  403.     a++;
  404.     if (a < ext_nlines)
  405.         *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
  406.     dataptr++;
  407.     b = ext->nlines;
  408.     for (y = 0, sptr = ext->lines; y < b; y++, sptr++) {
  409.         strcpy(*dataptr, *sptr);
  410.         a++;
  411.         if (a < ext_nlines)
  412.         *(dataptr + 1) = *dataptr + strlen(*sptr) + 1;
  413.         dataptr++;
  414.     }
  415.     }
  416.     *dataptr = 0;
  417. }
  418.