Back to index

plt-scheme  4.2.1
WrFFrI.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 *  WrFFrI.c:                                                                  *
00028 *                                                                             *
00029 *  XPM library                                                                *
00030 *  Write an image and possibly its mask to an XPM file                        *
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(WriteFile, int, (FILE *file, XpmImage *image, char *name,
00043                      XpmInfo *info));
00044 
00045 LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors));
00046 
00047 LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height,
00048                       unsigned int cpp, unsigned int *pixels,
00049                       XpmColor *colors));
00050 
00051 LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext,
00052                            unsigned int num));
00053 
00054 LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata));
00055 LFUNC(xpmDataClose, void, (xpmData *mdata));
00056 
00057 int
00058 XpmWriteFileFromImage(display, filename, image, shapeimage, attributes)
00059     Display *display;
00060     char *filename;
00061     XImage *image;
00062     XImage *shapeimage;
00063     XpmAttributes *attributes;
00064 {
00065     XpmImage xpmimage;
00066     XpmInfo info;
00067     int ErrorStatus;
00068 
00069     /* create an XpmImage from the image */
00070     ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
00071                                         &xpmimage, attributes);
00072     if (ErrorStatus != XpmSuccess)
00073        return (ErrorStatus);
00074 
00075     /* write the file from the XpmImage */
00076     if (attributes) {
00077        xpmSetInfo(&info, attributes);
00078        ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info);
00079     } else
00080        ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL);
00081 
00082     /* free the XpmImage */
00083     XpmFreeXpmImage(&xpmimage);
00084 
00085     return (ErrorStatus);
00086 }
00087 
00088 int
00089 XpmWriteFileFromXpmImage(filename, image, info)
00090     char *filename;
00091     XpmImage *image;
00092     XpmInfo *info;
00093 {
00094     xpmData mdata;
00095     char *name, *dot, *s, new_name[BUFSIZ];
00096     int ErrorStatus;
00097 
00098     /* open file to write */
00099     if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
00100        return (ErrorStatus);
00101 
00102     /* figure out a name */
00103     if (filename) {
00104 #ifdef VMS
00105        name = filename;
00106 #else
00107        if (!(name = rindex(filename, '/')))
00108            name = filename;
00109        else
00110            name++;
00111 #endif
00112        /* let's try to make a valid C syntax name */
00113        if (dot = index(name, '.')) {
00114            strcpy(new_name, name);
00115            /* change '.' to '_' */
00116            name = s = new_name;
00117            while (dot = index(s, '.')) {
00118               *dot = '_';
00119               s = dot;
00120            }
00121        }
00122        if (dot = index(name, '-')) {
00123            if (name != new_name) {
00124               strcpy(new_name, name);
00125               name = new_name;
00126            }
00127            /* change '-' to '_' */
00128            s = name;
00129            while (dot = index(s, '-')) {
00130               *dot = '_';
00131               s = dot;
00132            }
00133        }
00134     } else
00135        name = "image_name";
00136 
00137     /* write the XpmData from the XpmImage */
00138     if (ErrorStatus == XpmSuccess)
00139        ErrorStatus = WriteFile(mdata.stream.file, image, name, info);
00140 
00141     xpmDataClose(&mdata);
00142 
00143     return (ErrorStatus);
00144 }
00145 
00146 static int
00147 WriteFile(file, image, name, info)
00148     FILE *file;
00149     XpmImage *image;
00150     char *name;
00151     XpmInfo *info;
00152 {
00153     /* calculation variables */
00154     unsigned int cmts, extensions;
00155     int ErrorStatus;
00156 
00157     cmts = info && (info->valuemask & XpmComments);
00158     extensions = info && (info->valuemask & XpmExtensions)
00159        && info->nextensions;
00160 
00161     /* print the header line */
00162     fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
00163 
00164     /* print the hints line */
00165     if (cmts && info->hints_cmt)
00166        fprintf(file, "/*%s*/\n", info->hints_cmt);
00167 
00168     fprintf(file, "\"%d %d %d %d", image->width, image->height,
00169            image->ncolors, image->cpp);
00170 
00171     if (info && (info->valuemask & XpmHotspot))
00172        fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
00173 
00174     if (extensions)
00175        fprintf(file, " XPMEXT");
00176 
00177     fprintf(file, "\",\n");
00178 
00179     /* print colors */
00180     if (cmts && info->colors_cmt)
00181        fprintf(file, "/*%s*/\n", info->colors_cmt);
00182 
00183     WriteColors(file, image->colorTable, image->ncolors);
00184 
00185     /* print pixels */
00186     if (cmts && info->pixels_cmt)
00187        fprintf(file, "/*%s*/\n", info->pixels_cmt);
00188 
00189     ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
00190                            image->data, image->colorTable);
00191     if (ErrorStatus != XpmSuccess)
00192        return (ErrorStatus);
00193 
00194     /* print extensions */
00195     if (extensions)
00196        WriteExtensions(file, info->extensions, info->nextensions);
00197 
00198     /* close the array */
00199     fprintf(file, "};\n");
00200 
00201     return (XpmSuccess);
00202 }
00203 
00204 static void
00205 WriteColors(file, colors, ncolors)
00206     FILE *file;
00207     XpmColor *colors;
00208     unsigned int ncolors;
00209 {
00210     unsigned int a, key;
00211     char *s;
00212     char **defaults;
00213 
00214     for (a = 0; a < ncolors; a++, colors++) {
00215 
00216        defaults = (char **) colors;
00217        fprintf(file, "\"%s", *defaults++);
00218 
00219        for (key = 1; key <= NKEYS; key++, defaults++) {
00220            if (s = *defaults)
00221               fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
00222        }
00223        fprintf(file, "\",\n");
00224     }
00225 }
00226 
00227 
00228 static int
00229 WritePixels(file, width, height, cpp, pixels, colors)
00230     FILE *file;
00231     unsigned int width;
00232     unsigned int height;
00233     unsigned int cpp;
00234     unsigned int *pixels;
00235     XpmColor *colors;
00236 {
00237     char *s, *p, *buf;
00238     unsigned int x, y, h;
00239 
00240     h = height - 1;
00241     p = buf = (char *) XpmMalloc(width * cpp + 3);
00242     if (!buf)
00243        return (XpmNoMemory);
00244     *buf = '"';
00245     p++;
00246     for (y = 0; y < h; y++) {
00247        s = p;
00248        for (x = 0; x < width; x++, pixels++) {
00249            strncpy(s, colors[*pixels].string, cpp);
00250            s += cpp;
00251        }
00252        *s++ = '"';
00253        *s = '\0';
00254        fprintf(file, "%s,\n", buf);
00255     }
00256     /* duplicate some code to avoid a test in the loop */
00257     s = p;
00258     for (x = 0; x < width; x++, pixels++) {
00259        strncpy(s, colors[*pixels].string, cpp);
00260        s += cpp;
00261     }
00262     *s++ = '"';
00263     *s = '\0';
00264     fprintf(file, "%s", buf);
00265 
00266     XpmFree(buf);
00267     return (XpmSuccess);
00268 }
00269 
00270 static void
00271 WriteExtensions(file, ext, num)
00272     FILE *file;
00273     XpmExtension *ext;
00274     unsigned int num;
00275 {
00276     unsigned int x, y, n;
00277     char **line;
00278 
00279     for (x = 0; x < num; x++, ext++) {
00280        fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
00281        n = ext->nlines;
00282        for (y = 0, line = ext->lines; y < n; y++, line++)
00283            fprintf(file, ",\n\"%s\"", *line);
00284     }
00285     fprintf(file, ",\n\"XPMENDEXT\"");
00286 }
00287 
00288 /*
00289  * open the given file to be written as an xpmData which is returned
00290  */
00291 static int
00292 OpenWriteFile(filename, mdata)
00293     char *filename;
00294     xpmData *mdata;
00295 {
00296 #ifdef ZPIPE
00297     char buf[BUFSIZ];
00298 
00299 #endif
00300 
00301     if (!filename) {
00302        mdata->stream.file = (stdout);
00303        mdata->type = XPMFILE;
00304     } else {
00305 #ifdef ZPIPE
00306        if ((int) strlen(filename) > 2
00307            && !strcmp(".Z", filename + (strlen(filename) - 2))) {
00308            sprintf(buf, "compress > \"%s\"", filename);
00309            if (!(mdata->stream.file = popen(buf, "w")))
00310               return (XpmOpenFailed);
00311 
00312            mdata->type = XPMPIPE;
00313        } else if ((int) strlen(filename) > 3
00314                  && !strcmp(".gz", filename + (strlen(filename) - 3))) {
00315            sprintf(buf, "gzip -q > \"%s\"", filename);
00316            if (!(mdata->stream.file = popen(buf, "w")))
00317               return (XpmOpenFailed);
00318 
00319            mdata->type = XPMPIPE;
00320        } else {
00321 #endif
00322            if (!(mdata->stream.file = fopen(filename, "w")))
00323               return (XpmOpenFailed);
00324 
00325            mdata->type = XPMFILE;
00326 #ifdef ZPIPE
00327        }
00328 #endif
00329     }
00330     return (XpmSuccess);
00331 }
00332 
00333 /*
00334  * close the file related to the xpmData if any
00335  */
00336 static void
00337 xpmDataClose(mdata)
00338     xpmData *mdata;
00339 {
00340     switch (mdata->type) {
00341     case XPMFILE:
00342        if (mdata->stream.file != (stdout))
00343            fclose(mdata->stream.file);
00344        break;
00345 #ifdef ZPIPE
00346     case XPMPIPE:
00347        pclose(mdata->stream.file);
00348        break;
00349 #endif
00350     }
00351 }