/* * Copyright (C) 1989-94 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. */ /* * Warning: * This module is part of the Thot library, which was originally * developed in French. That's why some comments are still in * French, but their translation is in progress and the full module * will be available in English in the next release. * */ /*****************************************************************************\ * XpmCrBufFrI.c: * * * * XPM library * * Scan an image and possibly its PicMask and create an XPM buffer * * * * Developed by Arnaud Le Hors * \*****************************************************************************/ #include "thot_gui.h" #include "thot_sys.h" #include "xpmP.h" LFUNC (WriteColors, int, (char **dataptr, unsigned int *data_size, unsigned int *used_size, XpmColor * colors, unsigned int ncolors, unsigned int cpp)); LFUNC (WritePixels, void, (char *dataptr, unsigned int *used_size, unsigned int width, unsigned int height, unsigned int cpp, unsigned int *pixels, XpmColor * colors)); LFUNC (WriteExtensions, void, (char *dataptr, unsigned int *used_size, XpmExtension * ext, unsigned int num)); LFUNC (ExtensionsSize, int, (XpmExtension * ext, unsigned int num)); LFUNC (CommentsSize, int, (XpmInfo * info)); #ifdef __STDC__ int XpmCreateBufferFromImage (Display * display, char **buffer_return, XImage * image, XImage * shapeimage, XpmAttributes * attributes) #else /* __STDC__ */ int XpmCreateBufferFromImage (display, buffer_return, image, shapeimage, attributes) Display *display; char **buffer_return; XImage *image; XImage *shapeimage; XpmAttributes *attributes; #endif /* __STDC__ */ { XpmImage xpmimage; XpmInfo info; int ErrorStatus; /* initialize return value */ if (buffer_return) *buffer_return = NULL; /* create an XpmImage from the image */ ErrorStatus = XpmCreateXpmImageFromImage (display, image, shapeimage, &xpmimage, attributes); if (ErrorStatus != XpmSuccess) return (ErrorStatus); /* create the buffer from the XpmImage */ if (attributes) { xpmSetInfo (&info, attributes); ErrorStatus = XpmCreateBufferFromXpmImage (buffer_return, &xpmimage, &info); } else ErrorStatus = XpmCreateBufferFromXpmImage (buffer_return, &xpmimage, NULL); /* free the XpmImage */ XpmFreeXpmImage (&xpmimage); return (ErrorStatus); } #undef RETURN #define RETURN(status) \ { \ if (ptr) \ XpmFree(ptr); \ return(status); \ } #ifdef __STDC__ int XpmCreateBufferFromXpmImage (char **buffer_return, XpmImage * image, XpmInfo * info) #else /* __STDC__ */ int XpmCreateBufferFromXpmImage (buffer_return, image, info) char **buffer_return; XpmImage *image; XpmInfo *info; #endif /* __STDC__ */ { /* calculation variables */ int ErrorStatus; char buf[BUFSIZ]; unsigned int cmts, extensions, ext_size = 0; unsigned int l, cmt_size = 0; char *ptr = NULL, *p; unsigned int ptr_size, used_size; *buffer_return = NULL; cmts = info && (info->valuemask & XpmComments); extensions = info && (info->valuemask & XpmExtensions) && info->nextensions; /* compute the extensions and comments size */ if (extensions) ext_size = ExtensionsSize (info->extensions, info->nextensions); if (cmts) cmt_size = CommentsSize (info); /* write the header line */ sprintf (buf, "/* XPM */\nstatic char * image_name[] = {\n"); used_size = strlen (buf); ptr_size = used_size + ext_size + cmt_size + 1; ptr = (char *) XpmMalloc (ptr_size); if (!ptr) return XpmNoMemory; strcpy (ptr, buf); /* write the values line */ if (cmts && info->hints_cmt) { sprintf (ptr + used_size, "/*%s*/\n", info->hints_cmt); used_size += strlen (info->hints_cmt) + 5; } sprintf (buf, "\"%d %d %d %d", image->width, image->height, image->ncolors, image->cpp); l = strlen (buf); if (info && (info->valuemask & XpmHotspot)) { sprintf (buf + l, " %d %d", info->x_hotspot, info->y_hotspot); l = strlen (buf); } if (extensions) { sprintf (buf + l, " XPMEXT"); l = strlen (buf); } sprintf (buf + l, "\",\n"); l = strlen (buf); ptr_size += l; p = (char *) XpmRealloc (ptr, ptr_size); if (!p) RETURN (XpmNoMemory); ptr = p; strcpy (ptr + used_size, buf); used_size += l; /* write colors */ if (cmts && info->colors_cmt) { sprintf (ptr + used_size, "/*%s*/\n", info->colors_cmt); used_size += strlen (info->colors_cmt) + 5; } ErrorStatus = WriteColors (&ptr, &ptr_size, &used_size, image->colorTable, image->ncolors, image->cpp); if (ErrorStatus != XpmSuccess) RETURN (ErrorStatus); /* * now we know the exact size we needed, realloc the data 4 = 1 (for * '"') + 3 (for '",\n') 1 = - 2 is because the last line does not end * with ',\n' + 3 (for '};\n') */ ptr_size += image->height * (image->width * image->cpp + 4) + 1; p = (char *) XpmRealloc (ptr, ptr_size); if (!p) RETURN (XpmNoMemory); ptr = p; /* print pixels */ if (cmts && info->pixels_cmt) { sprintf (ptr + used_size, "/*%s*/\n", info->pixels_cmt); used_size += strlen (info->pixels_cmt) + 5; } WritePixels (ptr + used_size, &used_size, image->width, image->height, image->cpp, image->data, image->colorTable); /* print extensions */ if (extensions) WriteExtensions (ptr + used_size, &used_size, info->extensions, info->nextensions); /* close the array */ sprintf (ptr + used_size, "};\n"); *buffer_return = ptr; return (XpmSuccess); } #ifdef __STDC__ static int WriteColors (char **dataptr, unsigned int *data_size, unsigned int *used_size, XpmColor * colors, unsigned int ncolors, unsigned int cpp) #else /* __STDC__ */ static int WriteColors (dataptr, data_size, used_size, colors, ncolors, cpp) char **dataptr; unsigned int *data_size; unsigned int *used_size; XpmColor *colors; unsigned int ncolors; unsigned int cpp; #endif /* __STDC__ */ { char buf[BUFSIZ]; unsigned int a, key, l; char *s, *s2; char **defaults; *buf = '"'; for (a = 0; a < ncolors; a++, colors++) { defaults = (char **) colors; s = buf + 1; strncpy (s, *defaults++, cpp); s += cpp; for (key = 1; key <= NKEYS; key++, defaults++) { if ((s2 = *defaults)) { sprintf (s, "\t%s %s", xpmColorKeys[key - 1], s2); s += strlen (s); } } strcpy (s, "\",\n"); l = strlen (buf); s = (char *) XpmRealloc (*dataptr, *data_size + l); if (!s) return (XpmNoMemory); *data_size += l; strcpy (s + *used_size, buf); *used_size += l; *dataptr = s; } return (XpmSuccess); } #ifdef __STDC__ static void WritePixels (char *dataptr, unsigned int *used_size, unsigned int width, unsigned int height, unsigned int cpp, unsigned int *pixels, XpmColor * colors) #else /* __STDC__ */ static void WritePixels (dataptr, used_size, width, height, cpp, pixels, colors) char *dataptr; unsigned int *used_size; unsigned int width; unsigned int height; unsigned int cpp; unsigned int *pixels; XpmColor *colors; #endif /* __STDC__ */ { char *s = dataptr; unsigned int x, y, h; h = height - 1; for (y = 0; y < h; y++) { *s++ = '"'; for (x = 0; x < width; x++, pixels++) { strncpy (s, colors[*pixels].string, cpp); s += cpp; } strcpy (s, "\",\n"); s += 3; } /* duplicate some code to avoid a test in the loop */ *s++ = '"'; for (x = 0; x < width; x++, pixels++) { strncpy (s, colors[*pixels].string, cpp); s += cpp; } *s++ = '"'; *used_size += s - dataptr; } #ifdef __STDC__ static int ExtensionsSize (XpmExtension * ext, unsigned int num) #else /* __STDC__ */ static int ExtensionsSize (ext, num) XpmExtension *ext; unsigned int num; #endif /* __STDC__ */ { unsigned int x, y, a, size; char **line; size = 0; for (x = 0; x < num; x++, ext++) { /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */ size += strlen (ext->name) + 11; a = ext->nlines; for (y = 0, line = ext->lines; y < a; y++, line++) /* 4 = 3 (for ',\n"') + 1 (for '"') */ size += strlen (*line) + 4; } /* 13 is for ',\n"XPMENDEXT"' */ return size + 13; } #ifdef __STDC__ static void WriteExtensions (char *dataptr, unsigned int *used_size, XpmExtension * ext, unsigned int num) #else /* __STDC__ */ static void WriteExtensions (dataptr, used_size, ext, num) char *dataptr; unsigned int *used_size; XpmExtension *ext; unsigned int num; #endif /* __STDC__ */ { unsigned int x, y, a; char **line; char *s = dataptr; for (x = 0; x < num; x++, ext++) { sprintf (s, ",\n\"XPMEXT %s\"", ext->name); s += strlen (ext->name) + 11; a = ext->nlines; for (y = 0, line = ext->lines; y < a; y++, line++) { sprintf (s, ",\n\"%s\"", *line); s += strlen (*line) + 4; } } strcpy (s, ",\n\"XPMENDEXT\""); *used_size += s - dataptr + 13; } #ifdef __STDC__ static int CommentsSize (XpmInfo * info) #else /* __STDC__ */ static int CommentsSize (info) XpmInfo *info; #endif /* __STDC__ */ { int size = 0; /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */ if (info->hints_cmt) size += 5 + strlen (info->hints_cmt); if (info->colors_cmt) size += 5 + strlen (info->colors_cmt); if (info->pixels_cmt) size += 5 + strlen (info->pixels_cmt); return size; }