Back to index

plt-scheme  4.2.1
CrBufFrI.c
Go to the documentation of this file.
00001 
00002 
00003 
00004 /*
00005  * Copyright (C) 1989-95 GROUPE BULL
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a copy
00008  * of this software and associated documentation files (the "Software"), to
00009  * deal in the Software without restriction, including without limitation the
00010  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00011  * sell copies of the Software, and to permit persons to whom the Software is
00012  * furnished to do so, subject to the following conditions:
00013  *
00014  * The above copyright notice and this permission notice shall be included in
00015  * all copies or substantial portions of the Software.
00016  *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020  * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  *
00024  * Except as contained in this notice, the name of GROUPE BULL shall not be
00025  * used in advertising or otherwise to promote the sale, use or other dealings
00026  * in this Software without prior written authorization from GROUPE BULL.
00027  */
00028 
00029 /*****************************************************************************\
00030 *  CrBufFrI.c:                                                                *
00031 *                                                                             *
00032 *  XPM library                                                                *
00033 *  Scan an image and possibly its mask and create an XPM buffer               *
00034 *                                                                             *
00035 *  Developed by Arnaud Le Hors                                                *
00036 \*****************************************************************************/
00037 
00038 #include "xpmP.h"
00039 #if defined(SYSV) || defined(SVR4) || defined(VMS) || defined(__GNUC__)
00040 #include <string.h>
00041 #else
00042 #include <strings.h>
00043 #endif
00044 
00045 LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
00046                       unsigned int *used_size, XpmColor *colors,
00047                       unsigned int ncolors, unsigned int cpp));
00048 
00049 LFUNC(WritePixels, void, (char *dataptr, unsigned int *used_size,
00050                        unsigned int width, unsigned int height,
00051                        unsigned int cpp, unsigned int *pixels,
00052                        XpmColor *colors));
00053 
00054 LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
00055                            XpmExtension *ext, unsigned int num));
00056 
00057 LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
00058 LFUNC(CommentsSize, int, (XpmInfo *info));
00059 
00060 int
00061 XpmCreateBufferFromImage(display, buffer_return, image, shapeimage, attributes)
00062     Display *display;
00063     char **buffer_return;
00064     XImage *image;
00065     XImage *shapeimage;
00066     XpmAttributes *attributes;
00067 {
00068     XpmImage xpmimage;
00069     XpmInfo info;
00070     int ErrorStatus;
00071 
00072     /* initialize return value */
00073     if (buffer_return)
00074        *buffer_return = NULL;
00075 
00076     /* create an XpmImage from the image */
00077     ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
00078                                         &xpmimage, attributes);
00079     if (ErrorStatus != XpmSuccess)
00080        return (ErrorStatus);
00081 
00082     /* create the buffer from the XpmImage */
00083     if (attributes) {
00084        xpmSetInfo(&info, attributes);
00085        ErrorStatus =
00086            XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info);
00087     } else
00088        ErrorStatus =
00089            XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL);
00090 
00091     /* free the XpmImage */
00092     XpmFreeXpmImage(&xpmimage);
00093 
00094     return (ErrorStatus);
00095 }
00096 
00097 
00098 #undef RETURN
00099 #define RETURN(status) \
00100 { \
00101     if (ptr) \
00102        XpmFree(ptr); \
00103     return(status); \
00104 }
00105 
00106 int
00107 XpmCreateBufferFromXpmImage(buffer_return, image, info)
00108     char **buffer_return;
00109     XpmImage *image;
00110     XpmInfo *info;
00111 {
00112     /* calculation variables */
00113     int ErrorStatus;
00114     char buf[BUFSIZ];
00115     unsigned int cmts, extensions, ext_size = 0;
00116     unsigned int l, cmt_size = 0;
00117     char *ptr = NULL, *p;
00118     unsigned int ptr_size, used_size;
00119 
00120     *buffer_return = NULL;
00121 
00122     cmts = info && (info->valuemask & XpmComments);
00123     extensions = info && (info->valuemask & XpmExtensions)
00124        && info->nextensions;
00125 
00126     /* compute the extensions and comments size */
00127     if (extensions)
00128        ext_size = ExtensionsSize(info->extensions, info->nextensions);
00129     if (cmts)
00130        cmt_size = CommentsSize(info);
00131 
00132     /* write the header line */
00133     sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
00134     used_size = strlen(buf);
00135     ptr_size = used_size + ext_size + cmt_size + 1;
00136     ptr = (char *) XpmMalloc(ptr_size);
00137     if (!ptr)
00138        return XpmNoMemory;
00139     strcpy(ptr, buf);
00140 
00141     /* write the values line */
00142     if (cmts && info->hints_cmt) {
00143        sprintf(ptr + used_size, "/*%s*/\n", info->hints_cmt);
00144        used_size += strlen(info->hints_cmt) + 5;
00145     }
00146     sprintf(buf, "\"%d %d %d %d", image->width, image->height,
00147            image->ncolors, image->cpp);
00148     l = strlen(buf);
00149 
00150     if (info && (info->valuemask & XpmHotspot)) {
00151        sprintf(buf + l, " %d %d", info->x_hotspot, info->y_hotspot);
00152        l = strlen(buf);
00153     }
00154     if (extensions) {
00155        sprintf(buf + l, " XPMEXT");
00156        l = strlen(buf);
00157     }
00158     sprintf(buf + l, "\",\n");
00159     l = strlen(buf);
00160     ptr_size += l;
00161     p = (char *) XpmRealloc(ptr, ptr_size);
00162     if (!p)
00163        RETURN(XpmNoMemory);
00164     ptr = p;
00165     strcpy(ptr + used_size, buf);
00166     used_size += l;
00167 
00168     /* write colors */
00169     if (cmts && info->colors_cmt) {
00170        sprintf(ptr + used_size, "/*%s*/\n", info->colors_cmt);
00171        used_size += strlen(info->colors_cmt) + 5;
00172     }
00173     ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
00174                            image->colorTable, image->ncolors, image->cpp);
00175  
00176     if (ErrorStatus != XpmSuccess)
00177        RETURN(ErrorStatus);
00178 
00179     /*
00180      * now we know the exact size we need, realloc the data
00181      * 4 = 1 (for '"') + 3 (for '",\n')
00182      * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n')
00183      */
00184     ptr_size += image->height * (image->width * image->cpp + 4) + 1;
00185 
00186     p = (char *) XpmRealloc(ptr, ptr_size);
00187     if (!p)
00188        RETURN(XpmNoMemory);
00189     ptr = p;
00190 
00191     /* print pixels */
00192     if (cmts && info->pixels_cmt) {
00193        sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
00194        used_size += strlen(info->pixels_cmt) + 5;
00195     }
00196     WritePixels(ptr + used_size, &used_size, image->width, image->height,
00197               image->cpp, image->data, image->colorTable);
00198 
00199     /* print extensions */
00200     if (extensions)
00201        WriteExtensions(ptr + used_size, &used_size,
00202                      info->extensions, info->nextensions);
00203 
00204     /* close the array */
00205     sprintf(ptr + used_size, "};\n");
00206 
00207     *buffer_return = ptr;
00208 
00209     return (XpmSuccess);
00210 }
00211 
00212 static int
00213 WriteColors(dataptr, data_size, used_size, colors, ncolors, cpp)
00214     char **dataptr;
00215     unsigned int *data_size;
00216     unsigned int *used_size;
00217     XpmColor *colors;
00218     unsigned int ncolors;
00219     unsigned int cpp;
00220 {
00221     char buf[BUFSIZ];
00222     unsigned int a, key, l;
00223     char *s, *s2;
00224     char **defaults;
00225 
00226     *buf = '"';
00227     for (a = 0; a < ncolors; a++, colors++) {
00228 
00229        defaults = (char **) colors;
00230        s = buf + 1;
00231        strncpy(s, *defaults++, cpp);
00232        s += cpp;
00233 
00234        for (key = 1; key <= NKEYS; key++, defaults++) {
00235            if (s2 = *defaults) {
00236               sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
00237               s += strlen(s);
00238            }
00239        }
00240        strcpy(s, "\",\n");
00241        l = strlen(buf);
00242        s = (char *) XpmRealloc(*dataptr, *data_size + l);
00243        if (!s)
00244            return (XpmNoMemory);
00245        *data_size += l;
00246        strcpy(s + *used_size, buf);
00247        *used_size += l;
00248        *dataptr = s;
00249     }
00250     return (XpmSuccess);
00251 }
00252 
00253 static void
00254 WritePixels(dataptr, used_size, width, height, cpp, pixels, colors)
00255     char *dataptr;
00256     unsigned int *used_size;
00257     unsigned int width;
00258     unsigned int height;
00259     unsigned int cpp;
00260     unsigned int *pixels;
00261     XpmColor *colors;
00262 {
00263     char *s = dataptr;
00264     unsigned int x, y, h;
00265 
00266     h = height - 1;
00267     for (y = 0; y < h; y++) {
00268        *s++ = '"';
00269        for (x = 0; x < width; x++, pixels++) {
00270            strncpy(s, colors[*pixels].string, cpp);
00271            s += cpp;
00272        }
00273        strcpy(s, "\",\n");
00274        s += 3;
00275     }
00276     /* duplicate some code to avoid a test in the loop */
00277     *s++ = '"';
00278     for (x = 0; x < width; x++, pixels++) {
00279        strncpy(s, colors[*pixels].string, cpp);
00280        s += cpp;
00281     }
00282     *s++ = '"';
00283     *used_size += s - dataptr;
00284 }
00285 
00286 static int
00287 ExtensionsSize(ext, num)
00288     XpmExtension *ext;
00289     unsigned int num;
00290 {
00291     unsigned int x, y, a, size;
00292     char **line;
00293 
00294     size = 0;
00295     for (x = 0; x < num; x++, ext++) {
00296        /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
00297        size += strlen(ext->name) + 11;
00298        a = ext->nlines;
00299        for (y = 0, line = ext->lines; y < a; y++, line++)
00300            /* 4 = 3 (for ',\n"') + 1 (for '"') */
00301            size += strlen(*line) + 4;
00302     }
00303     /* 13 is for ',\n"XPMENDEXT"' */
00304     return size + 13;
00305 }
00306 
00307 static void
00308 WriteExtensions(dataptr, used_size, ext, num)
00309     char *dataptr;
00310     unsigned int *used_size;
00311     XpmExtension *ext;
00312     unsigned int num;
00313 {
00314     unsigned int x, y, a;
00315     char **line;
00316     char *s = dataptr;
00317 
00318     for (x = 0; x < num; x++, ext++) {
00319        sprintf(s, ",\n\"XPMEXT %s\"", ext->name);
00320        s += strlen(ext->name) + 11;
00321        a = ext->nlines;
00322        for (y = 0, line = ext->lines; y < a; y++, line++) {
00323            sprintf(s, ",\n\"%s\"", *line);
00324            s += strlen(*line) + 4;
00325        }
00326     }
00327     strcpy(s, ",\n\"XPMENDEXT\"");
00328     *used_size += s - dataptr + 13;
00329 }
00330 
00331 static int
00332 CommentsSize(info)
00333     XpmInfo *info;
00334 {
00335     int size = 0;
00336 
00337     /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
00338     if (info->hints_cmt)
00339        size += 5 + strlen(info->hints_cmt);
00340 
00341     if (info->colors_cmt)
00342        size += 5 + strlen(info->colors_cmt);
00343 
00344     if (info->pixels_cmt)
00345        size += 5 + strlen(info->pixels_cmt);
00346 
00347     return size;
00348 }