earlybrowserreborn - Rev 1

Subversion Repositories:
Rev:
/* Copyright 1990,91 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/*****************************************************************************\
* XpmWrFFrI.c:                                                                *
*                                                                             *
*  XPM library                                                                *
*  Write an image and possibly its mask to an XPM file                        *
*                                                                             *
*  Developed by Arnaud Le Hors                                                *
\*****************************************************************************/


#include "xpmP.h"
#ifdef VMS
#include "sys$library:string.h"
#else
#ifdef SYSV
#include <string.h>
#else
#include <strings.h>
#endif
#endif

LFUNC(WriteData, int, (xpmData * mdata,
                    xpmInternAttrib * attrib, XpmAttributes * attributes));

int
XpmWriteFileFromImage(display, filename, image, shapeimage, attributes)
    Display *display;
    char *filename;
    XImage *image;
    XImage *shapeimage;
    XpmAttributes *attributes;
{
    xpmData mdata;
    char *name, *end_name, *begin_name = NULL;
    int ErrorStatus;
    xpmInternAttrib attrib;

    if ((ErrorStatus = xpmWriteFile(filename, &mdata)) != XpmSuccess)
        return (ErrorStatus);

    if (filename) {
#ifdef VMS
        name = filename;
#else
        if (!(name = strchr(filename, '/')))
            name = filename;
        else
            name++;
#endif
        if (end_name = strchr(name, '.')) {
            begin_name = name;
            name = (char *) malloc((unsigned int) (end_name - begin_name) + 1);
            if (!name) {
                begin_name = NULL;
                name = "image_name";
            } else {
                strncpy(name, begin_name,
                        (unsigned int) (end_name - begin_name));
                name[(unsigned int) (end_name - begin_name)] = '\0';
            }
        }
    } else
        name = "image_name";

    xpmInitInternAttrib(&attrib);

    /*
     * Scan image then write it out
     */

    ErrorStatus = xpmScanImage(display, image, shapeimage,
                               attributes, &attrib);

    if (ErrorStatus == XpmSuccess) {
        attrib.name = name;
        ErrorStatus = WriteData(&mdata, &attrib, attributes);
    }
    xpmFreeInternAttrib(&attrib);
    XpmDataClose(&mdata);
    if (begin_name)
        free(name);

    return (ErrorStatus);
}


static int
WriteData(mdata, attrib, attributes)
    xpmData *mdata;
    xpmInternAttrib *attrib;
    XpmAttributes *attributes;
{
    /* calculation variables */
    xpmRgbName rgbn[MAX_RGBNAMES];
    int rgbn_max = 0;
    char *colorname;
    unsigned int *iptr;
    unsigned int a, b, c, x, y, n = 0, key, d, e;


    /*
     * read the rgb file if any was specified
     */

    if (attributes && (attributes->valuemask & XpmRgbFilename))
        rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);

    /* force output type to the C syntax */
    n = 1;

    /*
     * print the header line
     */

    fprintf(mdata->stream.file, "%s XPM %s\n", xpmDataTypes[n].Bcmt,
            xpmDataTypes[n].Ecmt);
    if (n != 0)                         /* print the assignment line */
        fprintf(mdata->stream.file, "%s %s %s",
                xpmDataTypes[n].Dec, attrib->name, xpmDataTypes[n].Boa);

    /*
     * print the hints line
     */

    if (attributes && (attributes->valuemask & XpmInfos)
        && attributes->hints_cmt)
        /* print hints comment line */
        fprintf(mdata->stream.file, "%s%s%s\n",
        xpmDataTypes[n].Bcmt, attributes->hints_cmt, xpmDataTypes[n].Ecmt);

    if (xpmDataTypes[n].Bos)
        fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Bos);

    fprintf(mdata->stream.file, "%d %d %d %d",
            attrib->width, attrib->height, attrib->ncolors, attrib->cpp);

    if (attributes && (attributes->valuemask & XpmHotspot))
        fprintf(mdata->stream.file, " %d %d",
                attributes->x_hotspot, attributes->y_hotspot);

    if (xpmDataTypes[n].Eos)
        fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Eos);

    fprintf(mdata->stream.file, xpmDataTypes[n].Strs);

    /*
     * print colors
     */

    if (attributes && (attributes->valuemask & XpmInfos)
        && attributes->colors_cmt)
        /* print colors comment line */
        fprintf(mdata->stream.file, "%s%s%s\n",
        xpmDataTypes[n].Bcmt, attributes->colors_cmt, xpmDataTypes[n].Ecmt);

    if (attrib->mask_pixel != UNDEF_PIXEL) {    /* transparent pixel */
        if (xpmDataTypes[n].Bos)
            fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Bos);

        for (b = 0; b < attrib->cpp; b++)
            fprintf(mdata->stream.file, "%c", attrib->colorStrings[0][b]);

        if (attributes && (attributes->valuemask & XpmInfos)
            && attributes->mask_pixel != UNDEF_PIXEL) {
            for (key = 1; key < NKEYS + 1; key++) {
                if (attributes->colorTable[attributes->mask_pixel][key])
                    fprintf(mdata->stream.file, "\t%s %s",
                            xpmColorKeys[key - 1],
                        attributes->colorTable[attributes->mask_pixel][key]
                        );
            }
        } else
            fprintf(mdata->stream.file, "\tc %s", TRANSPARENT_COLOR);

        if (xpmDataTypes[n].Eos)
            fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Eos);

        fprintf(mdata->stream.file, xpmDataTypes[n].Strs);
        d = 1;
    } else
        d = 0;

    for (a = d; a < attrib->ncolors; a++) {     /* other colors */
        if (xpmDataTypes[n].Bos)
            fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Bos);

        for (b = 0; b < attrib->cpp; b++)
            fprintf(mdata->stream.file, "%c", attrib->colorStrings[a][b]);

        c = 1;
        if (attributes && (attributes->valuemask & XpmInfos)) {
            e = 0;
            for (b = 0; b < attributes->ncolors; b++) {
                if (b == attributes->mask_pixel) {
                    e = 1;
                    continue;
                }
                if (attributes->pixels[b - e] == attrib->xcolors[a].pixel)
                    break;
            }
            if (b != attributes->ncolors) {
                c = 0;
                for (key = 1; key < NKEYS + 1; key++) {
                    if (attributes->colorTable[b][key])
                        fprintf(mdata->stream.file, "\t%s %s",
                                xpmColorKeys[key - 1],
                                attributes->colorTable[b][key]);
                }
            }
        }
        if (c) {
            colorname = NULL;
            if (rgbn_max)
                colorname = xpmGetRgbName(rgbn, rgbn_max,
                                          attrib->xcolors[a].red,
                                          attrib->xcolors[a].green,
                                          attrib->xcolors[a].blue);
            if (colorname)
                fprintf(mdata->stream.file, "\tc %s", colorname);
            else
                fprintf(mdata->stream.file, "\tc #%04X%04X%04X",
                        attrib->xcolors[a].red,
                        attrib->xcolors[a].green,
                        attrib->xcolors[a].blue);
        }
        if (xpmDataTypes[n].Eos)
            fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Eos);

        fprintf(mdata->stream.file, xpmDataTypes[n].Strs);
    }

    /*
     * print pixels
     */

    if (attributes && (attributes->valuemask & XpmInfos)
        && attributes->pixels_cmt)
        /* print pixels comment line */
        fprintf(mdata->stream.file, "%s%s%s\n",
        xpmDataTypes[n].Bcmt, attributes->pixels_cmt, xpmDataTypes[n].Ecmt);

    iptr = attrib->pixelindex;

    for (y = 0; y < attrib->height; y++) {

        if (xpmDataTypes[n].Bos)
            fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Bos);

        for (x = 0; x < attrib->width; x++, iptr++)
            for (b = 0; b < attrib->cpp; b++)
                fprintf(mdata->stream.file, "%c",
                        attrib->colorStrings[*iptr][b]);

        if (xpmDataTypes[n].Eos)
            fprintf(mdata->stream.file, "%c", xpmDataTypes[n].Eos);

        if (y < attrib->height - 1)
            fprintf(mdata->stream.file, xpmDataTypes[n].Strs);
    }

    fprintf(mdata->stream.file, xpmDataTypes[n].Eoa);

    xpmFreeRgbNames(rgbn, rgbn_max);

    return (XpmSuccess);
}