Back to index

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