summaryrefslogtreecommitdiff
path: root/src/CrDatFrI.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/CrDatFrI.c')
-rw-r--r--src/CrDatFrI.c341
1 files changed, 341 insertions, 0 deletions
diff --git a/src/CrDatFrI.c b/src/CrDatFrI.c
new file mode 100644
index 0000000..71fac8b
--- /dev/null
+++ b/src/CrDatFrI.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* CrDataFI.c: *
+* *
+* XPM library *
+* Scan an image and possibly its mask and create an XPM array *
+* *
+* Developed by Arnaud Le Hors *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/CrDatFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */
+
+#include "XpmI.h"
+
+LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
+ XpmColor *colors, unsigned int ncolors,
+ unsigned int cpp));
+
+LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
+ unsigned int height, unsigned int cpp,
+ unsigned int *pixels, XpmColor *colors));
+
+LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
+ unsigned int *ext_size,
+ unsigned int *ext_nlines));
+
+LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
+ XpmExtension *ext, unsigned int num,
+ unsigned int ext_nlines));
+
+int
+XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes)
+ Display *display;
+ char ***data_return;
+ XImage *image;
+ XImage *shapeimage;
+ XpmAttributes *attributes;
+{
+ XpmImage xpmimage;
+ XpmInfo info;
+ int ErrorStatus;
+
+ /* initialize return value */
+ if (data_return)
+ *data_return = NULL;
+
+ /* create an XpmImage from the image */
+ ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
+ &xpmimage, attributes);
+ if (ErrorStatus != XpmSuccess)
+ return (ErrorStatus);
+
+ /* create the data from the XpmImage */
+ if (attributes) {
+ xpmSetInfo(&info, attributes);
+ ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info);
+ } else
+ ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL);
+
+ /* free the XpmImage */
+ XpmFreeXpmImage(&xpmimage);
+
+ return (ErrorStatus);
+}
+
+#undef RETURN
+#define RETURN(status) \
+{ \
+ ErrorStatus = status; \
+ goto exit; \
+}
+
+int
+XpmCreateDataFromXpmImage(data_return, image, info)
+ char ***data_return;
+ XpmImage *image;
+ XpmInfo *info;
+{
+ /* calculation variables */
+ int ErrorStatus;
+ char buf[BUFSIZ];
+ char **header = NULL, **data, **sptr, **sptr2, *s;
+ unsigned int header_size, header_nlines;
+ unsigned int data_size, data_nlines;
+ unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
+ unsigned int offset, l, n;
+
+ *data_return = NULL;
+
+ extensions = info && (info->valuemask & XpmExtensions)
+ && info->nextensions;
+
+ /* compute the number of extensions lines and size */
+ if (extensions)
+ CountExtensions(info->extensions, info->nextensions,
+ &ext_size, &ext_nlines);
+
+ /*
+ * alloc a temporary array of char pointer for the header section which
+ * is the hints line + the color table lines
+ */
+ header_nlines = 1 + image->ncolors;
+ header_size = sizeof(char *) * header_nlines;
+ header = (char **) XpmCalloc(header_size, sizeof(char *));
+ if (!header)
+ return (XpmNoMemory);
+
+ /* print the hints line */
+ s = buf;
+#ifndef VOID_SPRINTF
+ s +=
+#endif
+ sprintf(s, "%d %d %d %d", image->width, image->height,
+ image->ncolors, image->cpp);
+#ifdef VOID_SPRINTF
+ s += strlen(s);
+#endif
+
+ if (info && (info->valuemask & XpmHotspot)) {
+#ifndef VOID_SPRINTF
+ s +=
+#endif
+ sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
+#ifdef VOID_SPRINTF
+ s += strlen(s);
+#endif
+ }
+ if (extensions) {
+ strcpy(s, " XPMEXT");
+ s += 7;
+ }
+ l = s - buf + 1;
+ *header = (char *) XpmMalloc(l);
+ if (!*header)
+ RETURN(XpmNoMemory);
+ header_size += l;
+ strcpy(*header, buf);
+
+ /* print colors */
+ ErrorStatus = CreateColors(header + 1, &header_size,
+ image->colorTable, image->ncolors, image->cpp);
+
+ if (ErrorStatus != XpmSuccess)
+ RETURN(ErrorStatus);
+
+ /* now we know the size needed, alloc the data and copy the header lines */
+ offset = image->width * image->cpp + 1;
+ data_size = header_size + (image->height + ext_nlines) * sizeof(char *)
+ + image->height * offset + ext_size;
+
+ data = (char **) XpmMalloc(data_size);
+ if (!data)
+ RETURN(XpmNoMemory);
+
+ data_nlines = header_nlines + image->height + ext_nlines;
+ *data = (char *) (data + data_nlines);
+ n = image->ncolors;
+ for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) {
+ strcpy(*sptr, *sptr2);
+ *(sptr + 1) = *sptr + strlen(*sptr2) + 1;
+ }
+
+ /* print pixels */
+ data[header_nlines] = (char *) data + header_size
+ + (image->height + ext_nlines) * sizeof(char *);
+
+ CreatePixels(data + header_nlines, image->width, image->height,
+ image->cpp, image->data, image->colorTable);
+
+ /* print extensions */
+ if (extensions)
+ CreateExtensions(data + header_nlines + image->height - 1, offset,
+ info->extensions, info->nextensions,
+ ext_nlines);
+
+ *data_return = data;
+ ErrorStatus = XpmSuccess;
+
+/* exit point, free only locally allocated variables */
+exit:
+ if (header) {
+ for (l = 0; l < header_nlines; l++)
+ if (header[l])
+ XpmFree(header[l]);
+ XpmFree(header);
+ }
+ return(ErrorStatus);
+}
+
+static int
+CreateColors(dataptr, data_size, colors, ncolors, cpp)
+ char **dataptr;
+ unsigned int *data_size;
+ XpmColor *colors;
+ unsigned int ncolors;
+ unsigned int cpp;
+{
+ char buf[BUFSIZ];
+ unsigned int a, key, l;
+ char *s, *s2;
+ char **defaults;
+
+ for (a = 0; a < ncolors; a++, colors++, dataptr++) {
+
+ defaults = (char **) colors;
+ strncpy(buf, *defaults++, cpp);
+ s = buf + cpp;
+
+ for (key = 1; key <= NKEYS; key++, defaults++) {
+ if ((s2 = *defaults)) {
+#ifndef VOID_SPRINTF
+ s +=
+#endif
+ sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
+#ifdef VOID_SPRINTF
+ s += strlen(s);
+#endif
+ }
+ }
+ l = s - buf + 1;
+ s = (char *) XpmMalloc(l);
+ if (!s)
+ return (XpmNoMemory);
+ *data_size += l;
+ *dataptr = strcpy(s, buf);
+ }
+ return (XpmSuccess);
+}
+
+static void
+CreatePixels(dataptr, width, height, cpp, pixels, colors)
+ char **dataptr;
+ unsigned int width;
+ unsigned int height;
+ unsigned int cpp;
+ unsigned int *pixels;
+ XpmColor *colors;
+{
+ char *s;
+ unsigned int x, y, h, offset;
+
+ h = height - 1;
+ offset = width * cpp + 1;
+ for (y = 0; y < h; y++, dataptr++) {
+ s = *dataptr;
+ for (x = 0; x < width; x++, pixels++) {
+ strncpy(s, colors[*pixels].string, cpp);
+ s += cpp;
+ }
+ *s = '\0';
+ *(dataptr + 1) = *dataptr + offset;
+ }
+ /* duplicate some code to avoid a test in the loop */
+ s = *dataptr;
+ for (x = 0; x < width; x++, pixels++) {
+ strncpy(s, colors[*pixels].string, cpp);
+ s += cpp;
+ }
+ *s = '\0';
+}
+
+static void
+CountExtensions(ext, num, ext_size, ext_nlines)
+ XpmExtension *ext;
+ unsigned int num;
+ unsigned int *ext_size;
+ unsigned int *ext_nlines;
+{
+ unsigned int x, y, a, size, nlines;
+ char **line;
+
+ size = 0;
+ nlines = 0;
+ for (x = 0; x < num; x++, ext++) {
+ /* 1 for the name */
+ nlines += ext->nlines + 1;
+ /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
+ size += strlen(ext->name) + 8;
+ a = ext->nlines;
+ for (y = 0, line = ext->lines; y < a; y++, line++)
+ size += strlen(*line) + 1;
+ }
+ /* 10 and 1 are for the ending "XPMENDEXT" */
+ *ext_size = size + 10;
+ *ext_nlines = nlines + 1;
+}
+
+static void
+CreateExtensions(dataptr, offset, ext, num, ext_nlines)
+ char **dataptr;
+ unsigned int offset;
+ XpmExtension *ext;
+ unsigned int num;
+ unsigned int ext_nlines;
+{
+ unsigned int x, y, a, b;
+ char **line;
+
+ *(dataptr + 1) = *dataptr + offset;
+ dataptr++;
+ a = 0;
+ for (x = 0; x < num; x++, ext++) {
+ sprintf(*dataptr, "XPMEXT %s", ext->name);
+ a++;
+ if (a < ext_nlines)
+ *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
+ dataptr++;
+ b = ext->nlines;
+ for (y = 0, line = ext->lines; y < b; y++, line++) {
+ strcpy(*dataptr, *line);
+ a++;
+ if (a < ext_nlines)
+ *(dataptr + 1) = *dataptr + strlen(*line) + 1;
+ dataptr++;
+ }
+ }
+ strcpy(*dataptr, "XPMENDEXT");
+}