Edit

IABSD.fr/xenocara/lib/libXpm/src/WrFFrI.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2007-09-30 08:38:09
    Hash : 3fa7de0f
    Message : libXpm 3.5.7

  • lib/libXpm/src/WrFFrI.c
  • /*
     * 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.
     */
    
    /*****************************************************************************\
    *  WrFFrI.c:                                                                  *
    *                                                                             *
    *  XPM library                                                                *
    *  Write an image and possibly its mask to an XPM file                        *
    *                                                                             *
    *  Developed by Arnaud Le Hors                                                *
    \*****************************************************************************/
    /* $XFree86$ */
    
    /*
     * The code related to AMIGA has been added by
     * Lorens Younes (d93-hyo@nada.kth.se) 4/96
     */
    
    #ifdef HAVE_CONFIG_H
    #include <config.h>
    #endif
    #include "XpmI.h"
    
    #ifndef NO_ZPIPE
    #include "sys/wait.h"
    #include "sys/types.h"
    #include "fcntl.h"
    #include "unistd.h"
    #include "errno.h"
    #endif
    
    /* MS Windows define a function called WriteFile @#%#&!!! */
    LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, char *name,
    			  XpmInfo *info));
    
    LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors));
    
    LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height,
    			 unsigned int cpp, unsigned int *pixels,
    			 XpmColor *colors));
    
    LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext,
    			      unsigned int num));
    
    LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata));
    LFUNC(xpmDataClose, void, (xpmData *mdata));
    
    int
    XpmWriteFileFromImage(display, filename, image, shapeimage, attributes)
        Display *display;
        char *filename;
        XImage *image;
        XImage *shapeimage;
        XpmAttributes *attributes;
    {
        XpmImage xpmimage;
        XpmInfo info;
        int ErrorStatus;
    
        /* create an XpmImage from the image */
        ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
    					     &xpmimage, attributes);
        if (ErrorStatus != XpmSuccess)
    	return (ErrorStatus);
    
        /* write the file from the XpmImage */
        if (attributes) {
    	xpmSetInfo(&info, attributes);
    	ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info);
        } else
    	ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL);
    
        /* free the XpmImage */
        XpmFreeXpmImage(&xpmimage);
    
        return (ErrorStatus);
    }
    
    int
    XpmWriteFileFromXpmImage(filename, image, info)
        char *filename;
        XpmImage *image;
        XpmInfo *info;
    {
        xpmData mdata;
        char *name, *dot, *s, new_name[BUFSIZ] = {0};
        int ErrorStatus;
    
        /* open file to write */
        if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
    	return (ErrorStatus);
    
        /* figure out a name */
        if (filename) {
    #ifdef VMS
    	name = filename;
    #else
    	if (!(name = strrchr(filename, '/'))
    #ifdef AMIGA
    	    && !(name = strrchr(filename, ':'))
    #endif
         )
    	    name = filename;
    	else
    	    name++;
    #endif
    	/* let's try to make a valid C syntax name */
    	if (strchr(name, '.')) {
    	    strncpy(new_name, name, sizeof(new_name));
    	    new_name[sizeof(new_name)-1] = '\0';
    	    /* change '.' to '_' */
    	    name = s = new_name;
    	    while ((dot = strchr(s, '.'))) {
    		*dot = '_';
    		s = dot;
    	    }
    	}
    	if (strchr(name, '-')) {
    	    if (name != new_name) {
    		strncpy(new_name, name, sizeof(new_name));
    		new_name[sizeof(new_name)-1] = '\0';
    		name = new_name;
    	    }
    	    /* change '-' to '_' */
    	    s = name;
    	    while ((dot = strchr(s, '-'))) {
    		*dot = '_';
    		s = dot;
    	    }
    	}
        } else
    	name = "image_name";
    
        /* write the XpmData from the XpmImage */
        if (ErrorStatus == XpmSuccess)
    	ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info);
    
        xpmDataClose(&mdata);
    
        return (ErrorStatus);
    }
    
    static int
    xpmWriteFile(file, image, name, info)
        FILE *file;
        XpmImage *image;
        char *name;
        XpmInfo *info;
    {
        /* calculation variables */
        unsigned int cmts, extensions;
        int ErrorStatus;
    
        cmts = info && (info->valuemask & XpmComments);
        extensions = info && (info->valuemask & XpmExtensions)
    	&& info->nextensions;
    
        /* print the header line */
        fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
    
        /* print the hints line */
        if (cmts && info->hints_cmt)
    	fprintf(file, "/*%s*/\n", info->hints_cmt);
    
        fprintf(file, "\"%d %d %d %d", image->width, image->height,
    	    image->ncolors, image->cpp);
    
        if (info && (info->valuemask & XpmHotspot))
    	fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
    
        if (extensions)
    	fprintf(file, " XPMEXT");
    
        fprintf(file, "\",\n");
    
        /* print colors */
        if (cmts && info->colors_cmt)
    	fprintf(file, "/*%s*/\n", info->colors_cmt);
    
        WriteColors(file, image->colorTable, image->ncolors);
    
        /* print pixels */
        if (cmts && info->pixels_cmt)
    	fprintf(file, "/*%s*/\n", info->pixels_cmt);
    
        ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
    			      image->data, image->colorTable);
        if (ErrorStatus != XpmSuccess)
    	return (ErrorStatus);
    
        /* print extensions */
        if (extensions)
    	WriteExtensions(file, info->extensions, info->nextensions);
    
        /* close the array */
        fprintf(file, "};\n");
    
        return (XpmSuccess);
    }
    
    static void
    WriteColors(file, colors, ncolors)
        FILE *file;
        XpmColor *colors;
        unsigned int ncolors;
    {
        unsigned int a, key;
        char *s;
        char **defaults;
    
        for (a = 0; a < ncolors; a++, colors++) {
    
    	defaults = (char **) colors;
    	fprintf(file, "\"%s", *defaults++);
    
    	for (key = 1; key <= NKEYS; key++, defaults++) {
    	    if ((s = *defaults))
    		fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
    	}
    	fprintf(file, "\",\n");
        }
    }
    
    
    static int
    WritePixels(file, width, height, cpp, pixels, colors)
        FILE *file;
        unsigned int width;
        unsigned int height;
        unsigned int cpp;
        unsigned int *pixels;
        XpmColor *colors;
    {
        char *s, *p, *buf;
        unsigned int x, y, h;
    
        h = height - 1;
        if (cpp != 0 && width >= (UINT_MAX - 3)/cpp) 
    	return XpmNoMemory;    
        p = buf = (char *) XpmMalloc(width * cpp + 3);
        if (!buf)
    	return (XpmNoMemory);
        *buf = '"';
        p++;
        for (y = 0; y < h; y++) {
    	s = p;
    	for (x = 0; x < width; x++, pixels++) {
    	    strncpy(s, colors[*pixels].string, cpp);
    	    s += cpp;
    	}
    	*s++ = '"';
    	*s = '\0';
    	fprintf(file, "%s,\n", buf);
        }
        /* duplicate some code to avoid a test in the loop */
        s = p;
        for (x = 0; x < width; x++, pixels++) {
    	strncpy(s, colors[*pixels].string, cpp);
    	s += cpp;
        }
        *s++ = '"';
        *s = '\0';
        fprintf(file, "%s", buf);
    
        XpmFree(buf);
        return (XpmSuccess);
    }
    
    static void
    WriteExtensions(file, ext, num)
        FILE *file;
        XpmExtension *ext;
        unsigned int num;
    {
        unsigned int x, y, n;
        char **line;
    
        for (x = 0; x < num; x++, ext++) {
    	fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
    	n = ext->nlines;
    	for (y = 0, line = ext->lines; y < n; y++, line++)
    	    fprintf(file, ",\n\"%s\"", *line);
        }
        fprintf(file, ",\n\"XPMENDEXT\"");
    }
    
    
    #ifndef NO_ZPIPE
    FUNC(xpmPipeThrough, FILE*, (int fd,
    			     const char* cmd,
    			     const char* arg1,
    			     const char* mode));
    #endif
    
    /*
     * open the given file to be written as an xpmData which is returned
     */
    static int
    OpenWriteFile(filename, mdata)
        char *filename;
        xpmData *mdata;
    {
        if (!filename) {
    	mdata->stream.file = (stdout);
    	mdata->type = XPMFILE;
        } else {
    #ifndef NO_ZPIPE
    	size_t len;
    #endif
    	int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
    	if ( fd < 0 )
    	    return(XpmOpenFailed);
    #ifndef NO_ZPIPE
    	len = strlen(filename);
    	if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
    	    mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
    	    mdata->type = XPMPIPE;
    	} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
    	    mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
    	    mdata->type = XPMPIPE;
    	} else
    #endif
    	{
    	    mdata->stream.file = fdopen(fd, "w");
    	    mdata->type = XPMFILE;
    	}
    	if (!mdata->stream.file)
    	    return (XpmOpenFailed);
        }
        return (XpmSuccess);
    }
    
    /*
     * close the file related to the xpmData if any
     */
    static void
    xpmDataClose(mdata)
        xpmData *mdata;
    {
        if (mdata->stream.file != (stdout))
    	fclose(mdata->stream.file);
    }