OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [engine/] [devimage.c] - Diff between revs 27 and 174

Only display areas with differences | Details | Blame | View Log

Rev 27 Rev 174
#define FASTJPEG        1       /* =1 for temp quick jpeg 8bpp display */
#define FASTJPEG        1       /* =1 for temp quick jpeg 8bpp display */
#ifdef __ECOS
#ifdef __ECOS
// Why isn't this handled in the global config file?
// Why isn't this handled in the global config file?
#undef HAVE_MMAP
#undef HAVE_MMAP
#else
#else
#define HAVE_MMAP       1       /* =1 to use mmap if available         */
#define HAVE_MMAP       1       /* =1 to use mmap if available         */
#endif
#endif
 
 
#if defined(HAVE_FILEIO)        /* temp for entire file*/
#if defined(HAVE_FILEIO)        /* temp for entire file*/
 
 
/*
/*
 * Copyright (c) 2000, 2001 Greg Haerr <greg@censoft.com>
 * Copyright (c) 2000, 2001 Greg Haerr <greg@censoft.com>
 * Portions Copyright (c) 2000 Martin Jolicoeur <martinj@visuaide.com>
 * Portions Copyright (c) 2000 Martin Jolicoeur <martinj@visuaide.com>
 * Portions Copyright (c) 2000 Alex Holden <alex@linuxhacker.org>
 * Portions Copyright (c) 2000 Alex Holden <alex@linuxhacker.org>
 * Portions Copyright (c) Independant JPEG group (ijg)
 * Portions Copyright (c) Independant JPEG group (ijg)
 *
 *
 * Image load/cache/resize/display routines
 * Image load/cache/resize/display routines
 *
 *
 * GIF, BMP, JPEG, PPM, PGM, PBM, PNG, and XPM formats are supported.
 * GIF, BMP, JPEG, PPM, PGM, PBM, PNG, and XPM formats are supported.
 * JHC:  Instead of working with a file, we work with a buffer
 * JHC:  Instead of working with a file, we work with a buffer
 *       (either provided by the user or through mmap).  This
 *       (either provided by the user or through mmap).  This
 *       improves speed, and provides a mechanism by which the
 *       improves speed, and provides a mechanism by which the
 *       client can send image data directly to the engine
 *       client can send image data directly to the engine
 */
 */
 
 
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
#include <fcntl.h>
#include <fcntl.h>
#include <ctype.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
 
 
#ifdef HAVE_MMAP
#ifdef HAVE_MMAP
#include <sys/mman.h>
#include <sys/mman.h>
#endif
#endif
 
 
#include "device.h"
#include "device.h"
#include "swap.h"
#include "swap.h"
 
 
/* cached image list*/
/* cached image list*/
typedef struct {
typedef struct {
        MWLIST          link;           /* link list*/
        MWLIST          link;           /* link list*/
        int             id;             /* image id*/
        int             id;             /* image id*/
        PMWIMAGEHDR     pimage;         /* image data*/
        PMWIMAGEHDR     pimage;         /* image data*/
        PSD             psd;            /* FIXME shouldn't need this*/
        PSD             psd;            /* FIXME shouldn't need this*/
} IMAGEITEM, *PIMAGEITEM;
} IMAGEITEM, *PIMAGEITEM;
 
 
static MWLISTHEAD imagehead;            /* global image list*/
static MWLISTHEAD imagehead;            /* global image list*/
static int nextimageid = 1;
static int nextimageid = 1;
 
 
typedef struct {  /* structure for reading images from buffer   */
typedef struct {  /* structure for reading images from buffer   */
  void *start;    /* The pointer to the beginning of the buffer */
  void *start;    /* The pointer to the beginning of the buffer */
  int offset;     /* The current offset within the buffer       */
  int offset;     /* The current offset within the buffer       */
  int size;       /* The total size of the buffer               */
  int size;       /* The total size of the buffer               */
} buffer_t;
} buffer_t;
 
 
 
 
static void ComputePitch(int bpp, int width, int *pitch, int *bytesperpixel);
static void ComputePitch(int bpp, int width, int *pitch, int *bytesperpixel);
#if defined(HAVE_BMP_SUPPORT)
#if defined(HAVE_BMP_SUPPORT)
static int  LoadBMP(buffer_t *src, PMWIMAGEHDR pimage);
static int  LoadBMP(buffer_t *src, PMWIMAGEHDR pimage);
#endif
#endif
#if defined(HAVE_JPEG_SUPPORT)
#if defined(HAVE_JPEG_SUPPORT)
static int  LoadJPEG(buffer_t *src, PMWIMAGEHDR pimage, PSD psd,
static int  LoadJPEG(buffer_t *src, PMWIMAGEHDR pimage, PSD psd,
                MWBOOL fast_grayscale);
                MWBOOL fast_grayscale);
#endif
#endif
#if defined(HAVE_PNG_SUPPORT)
#if defined(HAVE_PNG_SUPPORT)
static int  LoadPNG(buffer_t *src, PMWIMAGEHDR pimage);
static int  LoadPNG(buffer_t *src, PMWIMAGEHDR pimage);
#endif
#endif
#if defined(HAVE_GIF_SUPPORT)
#if defined(HAVE_GIF_SUPPORT)
static int  LoadGIF(buffer_t *src, PMWIMAGEHDR pimage);
static int  LoadGIF(buffer_t *src, PMWIMAGEHDR pimage);
#endif
#endif
#if defined(HAVE_PNM_SUPPORT)
#if defined(HAVE_PNM_SUPPORT)
static int LoadPNM(buffer_t *src, PMWIMAGEHDR pimage);
static int LoadPNM(buffer_t *src, PMWIMAGEHDR pimage);
#endif
#endif
#if defined(HAVE_XPM_SUPPORT)
#if defined(HAVE_XPM_SUPPORT)
static int LoadXPM(buffer_t *src, PMWIMAGEHDR pimage, PSD psd) ;
static int LoadXPM(buffer_t *src, PMWIMAGEHDR pimage, PSD psd) ;
#endif
#endif
 
 
/*
/*
 * Buffered input functions to replace stdio functions
 * Buffered input functions to replace stdio functions
 */
 */
static void
static void
binit(void *in, int size, buffer_t *dest)
binit(void *in, int size, buffer_t *dest)
{
{
        dest->start = in;
        dest->start = in;
        dest->offset = 0;
        dest->offset = 0;
        dest->size = size;
        dest->size = size;
}
}
 
 
static int
static int
bseek(buffer_t *buffer, int offset, int whence)
bseek(buffer_t *buffer, int offset, int whence)
{
{
        int new;
        int new;
 
 
        switch(whence) {
        switch(whence) {
        case SEEK_SET:
        case SEEK_SET:
                if (offset >= buffer->size || offset < 0)
                if (offset >= buffer->size || offset < 0)
                        return(-1);
                        return(-1);
                buffer->offset = offset;
                buffer->offset = offset;
                return(0);
                return(0);
 
 
        case SEEK_CUR:
        case SEEK_CUR:
                new = buffer->offset + offset;
                new = buffer->offset + offset;
                if (new >= buffer->size || new < 0)
                if (new >= buffer->size || new < 0)
                        return(-1);
                        return(-1);
                buffer->offset = new;
                buffer->offset = new;
                return(0);
                return(0);
 
 
        case SEEK_END:
        case SEEK_END:
                if (offset >= buffer->size || offset > 0)
                if (offset >= buffer->size || offset > 0)
                        return(-1);
                        return(-1);
                buffer->offset = (buffer->size - 1) - offset;
                buffer->offset = (buffer->size - 1) - offset;
                return(0);
                return(0);
 
 
        default:
        default:
                return(-1);
                return(-1);
        }
        }
}
}
 
 
static int
static int
bread(buffer_t *buffer, void *dest, int size)
bread(buffer_t *buffer, void *dest, int size)
{
{
        int copysize = size;
        int copysize = size;
 
 
        if (buffer->offset == buffer->size)
        if (buffer->offset == buffer->size)
                return(0);
                return(0);
 
 
        if (buffer->offset + size > buffer->size)
        if (buffer->offset + size > buffer->size)
                copysize = (buffer->size - buffer->offset);
                copysize = (buffer->size - buffer->offset);
 
 
        memcpy((void *)dest, (void *)(buffer->start + buffer->offset),copysize);
        memcpy((void *)dest, (void *)(buffer->start + buffer->offset),copysize);
 
 
        buffer->offset += copysize;
        buffer->offset += copysize;
        return(copysize);
        return(copysize);
}
}
 
 
static int
static int
bgetc(buffer_t *buffer)
bgetc(buffer_t *buffer)
{
{
        int ch;
        int ch;
 
 
        if (buffer->offset == buffer->size)
        if (buffer->offset == buffer->size)
                return(EOF);
                return(EOF);
 
 
        ch = *((unsigned char *) (buffer->start + buffer->offset));
        ch = *((unsigned char *) (buffer->start + buffer->offset));
        buffer->offset++;
        buffer->offset++;
        return(ch);
        return(ch);
}
}
 
 
static char *
static char *
bgets(buffer_t *buffer, char *dest, int size)
bgets(buffer_t *buffer, char *dest, int size)
{
{
        int i,o;
        int i,o;
        int copysize = size - 1;
        int copysize = size - 1;
 
 
        if (buffer->offset == buffer->size)
        if (buffer->offset == buffer->size)
                return(0);
                return(0);
 
 
        if (buffer->offset + copysize > buffer->size)
        if (buffer->offset + copysize > buffer->size)
                copysize = buffer->size - buffer->offset;
                copysize = buffer->size - buffer->offset;
 
 
        for(o=0, i=buffer->offset; i < buffer->offset + copysize; i++, o++) {
        for(o=0, i=buffer->offset; i < buffer->offset + copysize; i++, o++) {
                dest[o] = *((char *) (buffer->start + i));
                dest[o] = *((char *) (buffer->start + i));
                if (dest[o] == '\n')
                if (dest[o] == '\n')
                        break;
                        break;
        }
        }
 
 
        buffer->offset = i + 1;
        buffer->offset = i + 1;
        dest[o + 1] = 0;
        dest[o + 1] = 0;
 
 
        return(dest);
        return(dest);
}
}
 
 
static int
static int
beof(buffer_t *buffer)
beof(buffer_t *buffer)
{
{
        return (buffer->offset == buffer->size);
        return (buffer->offset == buffer->size);
}
}
 
 
/*
/*
 * Image decoding and display
 * Image decoding and display
 * NOTE: This routine and APIs will change in subsequent releases.
 * NOTE: This routine and APIs will change in subsequent releases.
 *
 *
 * Decodes and loads a graphics file, then resizes to width/height,
 * Decodes and loads a graphics file, then resizes to width/height,
 * then displays image at x, y
 * then displays image at x, y
 * If width/height == -1, don't resize, use image size.
 * If width/height == -1, don't resize, use image size.
 * Clipping is not currently supported, just stretch/shrink to fit.
 * Clipping is not currently supported, just stretch/shrink to fit.
 *
 *
 */
 */
 
 
static int GdDecodeImage(PSD psd, buffer_t *src, int flags);
static int GdDecodeImage(PSD psd, buffer_t *src, int flags);
 
 
int
int
GdLoadImageFromBuffer(PSD psd, void *buffer, int size, int flags)
GdLoadImageFromBuffer(PSD psd, void *buffer, int size, int flags)
{
{
        buffer_t src;
        buffer_t src;
        binit(buffer, size, &src);
        binit(buffer, size, &src);
 
 
        return(GdDecodeImage(psd, &src, flags));
        return(GdDecodeImage(psd, &src, flags));
}
}
 
 
void
void
GdDrawImageFromBuffer(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width,
GdDrawImageFromBuffer(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width,
        MWCOORD height, void *buffer, int size, int flags)
        MWCOORD height, void *buffer, int size, int flags)
{
{
        int id;
        int id;
        buffer_t src;
        buffer_t src;
 
 
        binit(buffer, size, &src);
        binit(buffer, size, &src);
        id = GdDecodeImage(psd, &src, flags);
        id = GdDecodeImage(psd, &src, flags);
 
 
        if (id) {
        if (id) {
                GdDrawImageToFit(psd, x, y, width, height, id);
                GdDrawImageToFit(psd, x, y, width, height, id);
                GdFreeImage(id);
                GdFreeImage(id);
        }
        }
}
}
 
 
void
void
GdDrawImageFromFile(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width,
GdDrawImageFromFile(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width,
        MWCOORD height, char *path, int flags)
        MWCOORD height, char *path, int flags)
{
{
        int     id;
        int     id;
 
 
        id = GdLoadImageFromFile(psd, path, flags);
        id = GdLoadImageFromFile(psd, path, flags);
        if (id) {
        if (id) {
                GdDrawImageToFit(psd, x, y, width, height, id);
                GdDrawImageToFit(psd, x, y, width, height, id);
                GdFreeImage(id);
                GdFreeImage(id);
        }
        }
}
}
 
 
int
int
GdLoadImageFromFile(PSD psd, char *path, int flags)
GdLoadImageFromFile(PSD psd, char *path, int flags)
{
{
  int fd, id;
  int fd, id;
  struct stat s;
  struct stat s;
  void *buffer = 0;
  void *buffer = 0;
  buffer_t src;
  buffer_t src;
 
 
  fd = open(path, O_RDONLY);
  fd = open(path, O_RDONLY);
  if (fd <= 0) {
  if (fd <= 0) {
    EPRINTF("GdLoadImageFromFile: can't open image: %s\n", path);
    EPRINTF("GdLoadImageFromFile: can't open image: %s\n", path);
    return(0);
    return(0);
  }
  }
 
 
  fstat(fd, &s);
  fstat(fd, &s);
 
 
#ifdef HAVE_MMAP
#ifdef HAVE_MMAP
  buffer = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  buffer = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
 
 
  if (!buffer) {
  if (!buffer) {
    EPRINTF("GdLoadImageFromFile:  Couldn't map image %s\n", path);
    EPRINTF("GdLoadImageFromFile:  Couldn't map image %s\n", path);
    close(fd);
    close(fd);
    return(0);
    return(0);
  }
  }
#else
#else
  buffer = malloc(s.st_size);
  buffer = malloc(s.st_size);
  if (!buffer) {
  if (!buffer) {
     EPRINTF("GdLoadImageFromFile:  Couldn't load image %s\n", path);
     EPRINTF("GdLoadImageFromFile:  Couldn't load image %s\n", path);
     close(fd);
     close(fd);
     return(0);
     return(0);
  }
  }
 
 
  if (read(fd, buffer, s.st_size) != s.st_size) {
  if (read(fd, buffer, s.st_size) != s.st_size) {
    EPRINTF("GdLoadImageFromFile:  Couldn't load image %s\n", path);
    EPRINTF("GdLoadImageFromFile:  Couldn't load image %s\n", path);
    close(fd);
    close(fd);
    return(0);
    return(0);
  }
  }
#endif
#endif
 
 
  binit(buffer, s.st_size, &src);
  binit(buffer, s.st_size, &src);
  id = GdDecodeImage(psd, &src, flags);
  id = GdDecodeImage(psd, &src, flags);
 
 
#ifdef HAVE_MMAP
#ifdef HAVE_MMAP
  munmap(buffer, s.st_size);
  munmap(buffer, s.st_size);
#else
#else
  free(buffer);
  free(buffer);
#endif
#endif
 
 
  close(fd);
  close(fd);
  return(id);
  return(id);
}
}
 
 
static int
static int
GdDecodeImage(PSD psd, buffer_t * src, int flags)
GdDecodeImage(PSD psd, buffer_t * src, int flags)
{
{
        int         loadOK = 0;
        int         loadOK = 0;
        PMWIMAGEHDR pimage;
        PMWIMAGEHDR pimage;
        PIMAGEITEM  pItem;
        PIMAGEITEM  pItem;
 
 
        /* allocate image struct*/
        /* allocate image struct*/
        pimage = (PMWIMAGEHDR)malloc(sizeof(MWIMAGEHDR));
        pimage = (PMWIMAGEHDR)malloc(sizeof(MWIMAGEHDR));
        if(!pimage) {
        if(!pimage) {
                return 0;
                return 0;
        }
        }
        pimage->imagebits = NULL;
        pimage->imagebits = NULL;
        pimage->palette = NULL;
        pimage->palette = NULL;
        pimage->transcolor = -1L;
        pimage->transcolor = -1L;
 
 
#if defined(HAVE_BMP_SUPPORT)
#if defined(HAVE_BMP_SUPPORT)
        if (loadOK == 0)
        if (loadOK == 0)
                loadOK = LoadBMP(src, pimage);
                loadOK = LoadBMP(src, pimage);
#endif
#endif
#if defined(HAVE_GIF_SUPPORT)
#if defined(HAVE_GIF_SUPPORT)
        if (loadOK == 0)
        if (loadOK == 0)
                loadOK = LoadGIF(src, pimage);
                loadOK = LoadGIF(src, pimage);
#endif
#endif
#if defined(HAVE_JPEG_SUPPORT)
#if defined(HAVE_JPEG_SUPPORT)
        if (loadOK == 0)
        if (loadOK == 0)
                loadOK = LoadJPEG(src, pimage, psd, flags);
                loadOK = LoadJPEG(src, pimage, psd, flags);
#endif
#endif
#if defined(HAVE_PNG_SUPPORT)
#if defined(HAVE_PNG_SUPPORT)
        if (loadOK == 0)
        if (loadOK == 0)
                loadOK = LoadPNG(src, pimage);
                loadOK = LoadPNG(src, pimage);
#endif
#endif
#if defined(HAVE_PNM_SUPPORT)
#if defined(HAVE_PNM_SUPPORT)
        if(loadOK == 0)
        if(loadOK == 0)
                loadOK = LoadPNM(src, pimage);
                loadOK = LoadPNM(src, pimage);
#endif
#endif
#if defined(HAVE_XPM_SUPPORT)
#if defined(HAVE_XPM_SUPPORT)
        if (loadOK == 0)
        if (loadOK == 0)
                loadOK = LoadXPM(src, pimage, psd);
                loadOK = LoadXPM(src, pimage, psd);
#endif
#endif
 
 
        if (loadOK == 0) {
        if (loadOK == 0) {
                EPRINTF("GdLoadImageFromFile: unknown image type:\n");
                EPRINTF("GdLoadImageFromFile: unknown image type:\n");
          //            EPRINTF("GdLoadImageFromFile: unknown image type: \n", path);
          //            EPRINTF("GdLoadImageFromFile: unknown image type: \n", path);
                goto err;               /* image loading error*/
                goto err;               /* image loading error*/
        }
        }
        if (loadOK != 1)
        if (loadOK != 1)
                goto err;               /* image loading error*/
                goto err;               /* image loading error*/
 
 
        /* allocate id*/
        /* allocate id*/
        pItem = GdItemNew(IMAGEITEM);
        pItem = GdItemNew(IMAGEITEM);
        if (!pItem)
        if (!pItem)
                goto err;
                goto err;
        pItem->id = nextimageid++;
        pItem->id = nextimageid++;
        pItem->pimage = pimage;
        pItem->pimage = pimage;
        pItem->psd = psd;
        pItem->psd = psd;
        GdListAdd(&imagehead, &pItem->link);
        GdListAdd(&imagehead, &pItem->link);
 
 
        return pItem->id;
        return pItem->id;
 
 
err:
err:
        free(pimage);
        free(pimage);
        return 0;                        /* image loading error*/
        return 0;                        /* image loading error*/
}
}
 
 
static PIMAGEITEM
static PIMAGEITEM
findimage(int id)
findimage(int id)
{
{
        PMWLIST         p;
        PMWLIST         p;
        PIMAGEITEM      pimagelist;
        PIMAGEITEM      pimagelist;
 
 
        for (p=imagehead.head; p; p=p->next) {
        for (p=imagehead.head; p; p=p->next) {
                pimagelist = GdItemAddr(p, IMAGEITEM, link);
                pimagelist = GdItemAddr(p, IMAGEITEM, link);
                if (pimagelist->id == id)
                if (pimagelist->id == id)
                        return pimagelist;
                        return pimagelist;
        }
        }
        return NULL;
        return NULL;
}
}
 
 
void
void
GdDrawImageToFit(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,
GdDrawImageToFit(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,
        int id)
        int id)
{
{
        PIMAGEITEM      pItem;
        PIMAGEITEM      pItem;
        PMWIMAGEHDR     pimage;
        PMWIMAGEHDR     pimage;
 
 
        pItem = findimage(id);
        pItem = findimage(id);
        if (!pItem)
        if (!pItem)
                return;
                return;
        pimage = pItem->pimage;
        pimage = pItem->pimage;
 
 
        /*
        /*
         * Display image, possibly stretch/shrink to resize
         * Display image, possibly stretch/shrink to resize
         */
         */
        if (height < 0)
        if (height < 0)
                height = pimage->height;
                height = pimage->height;
        if (width < 0)
        if (width < 0)
                width = pimage->width;
                width = pimage->width;
 
 
        if (height != pimage->height || width != pimage->width) {
        if (height != pimage->height || width != pimage->width) {
                MWCLIPRECT      rcDst;
                MWCLIPRECT      rcDst;
                MWIMAGEHDR      image2;
                MWIMAGEHDR      image2;
 
 
                /* create similar image, different width/height*/
                /* create similar image, different width/height*/
 
 
                image2.width = width;
                image2.width = width;
                image2.height = height;
                image2.height = height;
                image2.planes = pimage->planes;
                image2.planes = pimage->planes;
                image2.bpp = pimage->bpp;
                image2.bpp = pimage->bpp;
                ComputePitch(pimage->bpp, width, &image2.pitch,
                ComputePitch(pimage->bpp, width, &image2.pitch,
                        &image2.bytesperpixel);
                        &image2.bytesperpixel);
                image2.compression = pimage->compression;
                image2.compression = pimage->compression;
                image2.palsize = pimage->palsize;
                image2.palsize = pimage->palsize;
                image2.palette = pimage->palette;       /* already allocated*/
                image2.palette = pimage->palette;       /* already allocated*/
                image2.transcolor = pimage->transcolor;
                image2.transcolor = pimage->transcolor;
                if( (image2.imagebits = malloc(image2.pitch*height)) == NULL) {
                if( (image2.imagebits = malloc(image2.pitch*height)) == NULL) {
                        EPRINTF("GdDrawImageToFit: no memory\n");
                        EPRINTF("GdDrawImageToFit: no memory\n");
                        return;
                        return;
                }
                }
 
 
                rcDst.x = 0;
                rcDst.x = 0;
                rcDst.y = 0;
                rcDst.y = 0;
                rcDst.width = width;
                rcDst.width = width;
                rcDst.height = height;
                rcDst.height = height;
 
 
                /* Stretch full soruce to destination rectangle*/
                /* Stretch full soruce to destination rectangle*/
                GdStretchImage(pimage, NULL, &image2, &rcDst);
                GdStretchImage(pimage, NULL, &image2, &rcDst);
                GdDrawImage(psd, x, y, &image2);
                GdDrawImage(psd, x, y, &image2);
                free(image2.imagebits);
                free(image2.imagebits);
        } else
        } else
                GdDrawImage(psd, x, y, pimage);
                GdDrawImage(psd, x, y, pimage);
}
}
 
 
void
void
GdFreeImage(int id)
GdFreeImage(int id)
{
{
        PIMAGEITEM      pItem;
        PIMAGEITEM      pItem;
        PMWIMAGEHDR     pimage;
        PMWIMAGEHDR     pimage;
 
 
        pItem = findimage(id);
        pItem = findimage(id);
        if (pItem) {
        if (pItem) {
                GdListRemove(&imagehead, &pItem->link);
                GdListRemove(&imagehead, &pItem->link);
                pimage = pItem->pimage;
                pimage = pItem->pimage;
 
 
                /* delete image bits*/
                /* delete image bits*/
                if(pimage->imagebits)
                if(pimage->imagebits)
                        free(pimage->imagebits);
                        free(pimage->imagebits);
                if(pimage->palette)
                if(pimage->palette)
                        free(pimage->palette);
                        free(pimage->palette);
 
 
                free(pimage);
                free(pimage);
                GdItemFree(pItem);
                GdItemFree(pItem);
        }
        }
}
}
 
 
MWBOOL
MWBOOL
GdGetImageInfo(int id, PMWIMAGEINFO pii)
GdGetImageInfo(int id, PMWIMAGEINFO pii)
{
{
        PMWIMAGEHDR     pimage;
        PMWIMAGEHDR     pimage;
        PIMAGEITEM      pItem;
        PIMAGEITEM      pItem;
        int             i;
        int             i;
 
 
        pItem = findimage(id);
        pItem = findimage(id);
        if (!pItem) {
        if (!pItem) {
                memset(pii, 0, sizeof(*pii));
                memset(pii, 0, sizeof(*pii));
                return FALSE;
                return FALSE;
        }
        }
        pimage = pItem->pimage;
        pimage = pItem->pimage;
        pii->id = id;
        pii->id = id;
        pii->width = pimage->width;
        pii->width = pimage->width;
        pii->height = pimage->height;
        pii->height = pimage->height;
        pii->planes = pimage->planes;
        pii->planes = pimage->planes;
        pii->bpp = pimage->bpp;
        pii->bpp = pimage->bpp;
        pii->pitch = pimage->pitch;
        pii->pitch = pimage->pitch;
        pii->bytesperpixel = pimage->bytesperpixel;
        pii->bytesperpixel = pimage->bytesperpixel;
        pii->compression = pimage->compression;
        pii->compression = pimage->compression;
        pii->palsize = pimage->palsize;
        pii->palsize = pimage->palsize;
        if (pimage->palsize) {
        if (pimage->palsize) {
                if (pimage->palette) {
                if (pimage->palette) {
                        for (i=0; i<pimage->palsize; ++i)
                        for (i=0; i<pimage->palsize; ++i)
                                pii->palette[i] = pimage->palette[i];
                                pii->palette[i] = pimage->palette[i];
                } else {
                } else {
                        /* FIXME handle jpeg's without palette*/
                        /* FIXME handle jpeg's without palette*/
                        GdGetPalette(pItem->psd, 0, pimage->palsize,
                        GdGetPalette(pItem->psd, 0, pimage->palsize,
                                pii->palette);
                                pii->palette);
                }
                }
        }
        }
        return TRUE;
        return TRUE;
}
}
 
 
#define PIX2BYTES(n)    (((n)+7)/8)
#define PIX2BYTES(n)    (((n)+7)/8)
/*
/*
 * compute image line size and bytes per pixel
 * compute image line size and bytes per pixel
 * from bits per pixel and width
 * from bits per pixel and width
 */
 */
static void
static void
ComputePitch(int bpp, int width, int *pitch, int *bytesperpixel)
ComputePitch(int bpp, int width, int *pitch, int *bytesperpixel)
{
{
        int     linesize;
        int     linesize;
        int     bytespp = 1;
        int     bytespp = 1;
 
 
        if(bpp == 1)
        if(bpp == 1)
                linesize = PIX2BYTES(width);
                linesize = PIX2BYTES(width);
        else if(bpp <= 4)
        else if(bpp <= 4)
                linesize = PIX2BYTES(width<<2);
                linesize = PIX2BYTES(width<<2);
        else if(bpp <= 8)
        else if(bpp <= 8)
                linesize = width;
                linesize = width;
        else if(bpp <= 16) {
        else if(bpp <= 16) {
                linesize = width * 2;
                linesize = width * 2;
                bytespp = 2;
                bytespp = 2;
        } else if(bpp <= 24) {
        } else if(bpp <= 24) {
                linesize = width * 3;
                linesize = width * 3;
                bytespp = 3;
                bytespp = 3;
        } else {
        } else {
                linesize = width * 4;
                linesize = width * 4;
                bytespp = 4;
                bytespp = 4;
        }
        }
 
 
        /* rows are DWORD right aligned*/
        /* rows are DWORD right aligned*/
        *pitch = (linesize + 3) & ~3;
        *pitch = (linesize + 3) & ~3;
        *bytesperpixel = bytespp;
        *bytesperpixel = bytespp;
}
}
 
 
/*
/*
 * StretchImage - Resize an image
 * StretchImage - Resize an image
 *
 *
 * Major portions from SDL Simple DirectMedia Layer by Sam Lantinga
 * Major portions from SDL Simple DirectMedia Layer by Sam Lantinga
 * Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga <slouken@devolution.com>
 * Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga <slouken@devolution.com>
 * This a stretch blit implementation based on ideas given to me by
 * This a stretch blit implementation based on ideas given to me by
 *  Tomasz Cejner - thanks! :)
 *  Tomasz Cejner - thanks! :)
 */
 */
/*
/*
    This library is free software; you can redistribute it and/or
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
    version 2 of the License, or (at your option) any later version.
 
 
    This library is distributed in the hope that it will be useful,
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
    Library General Public License for more details.
 
 
    You should have received a copy of the GNU Library General Public
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
*/
 
 
#define DEFINE_COPY_ROW(name, type)                                     \
#define DEFINE_COPY_ROW(name, type)                                     \
static void name(type *src, int src_w, type *dst, int dst_w)            \
static void name(type *src, int src_w, type *dst, int dst_w)            \
{                                                                       \
{                                                                       \
        int i;                                                          \
        int i;                                                          \
        int pos, inc;                                                   \
        int pos, inc;                                                   \
        type pixel = 0;                                                  \
        type pixel = 0;                                                  \
                                                                        \
                                                                        \
        pos = 0x10000;                                                  \
        pos = 0x10000;                                                  \
        inc = (src_w << 16) / dst_w;                                    \
        inc = (src_w << 16) / dst_w;                                    \
        for ( i=dst_w; i>0; --i ) {                                      \
        for ( i=dst_w; i>0; --i ) {                                      \
                while ( pos >= 0x10000L ) {                             \
                while ( pos >= 0x10000L ) {                             \
                        pixel = *src++;                                 \
                        pixel = *src++;                                 \
                        pos -= 0x10000L;                                \
                        pos -= 0x10000L;                                \
                }                                                       \
                }                                                       \
                *dst++ = pixel;                                         \
                *dst++ = pixel;                                         \
                pos += inc;                                             \
                pos += inc;                                             \
        }                                                               \
        }                                                               \
}
}
 
 
DEFINE_COPY_ROW(copy_row1, unsigned char)
DEFINE_COPY_ROW(copy_row1, unsigned char)
DEFINE_COPY_ROW(copy_row2, unsigned short)
DEFINE_COPY_ROW(copy_row2, unsigned short)
DEFINE_COPY_ROW(copy_row4, unsigned long)
DEFINE_COPY_ROW(copy_row4, unsigned long)
 
 
static void copy_row3(unsigned char *src, int src_w, unsigned char *dst,
static void copy_row3(unsigned char *src, int src_w, unsigned char *dst,
        int dst_w)
        int dst_w)
{
{
        int i;
        int i;
        int pos, inc;
        int pos, inc;
        unsigned char r = 0;
        unsigned char r = 0;
        unsigned char g = 0;
        unsigned char g = 0;
        unsigned char b = 0;
        unsigned char b = 0;
 
 
        pos = 0x10000;
        pos = 0x10000;
        inc = (src_w << 16) / dst_w;
        inc = (src_w << 16) / dst_w;
        for ( i=dst_w; i>0; --i ) {
        for ( i=dst_w; i>0; --i ) {
                while ( pos >= 0x10000L ) {
                while ( pos >= 0x10000L ) {
                        b = *src++;
                        b = *src++;
                        g = *src++;
                        g = *src++;
                        r = *src++;
                        r = *src++;
                        pos -= 0x10000L;
                        pos -= 0x10000L;
                }
                }
                *dst++ = b;
                *dst++ = b;
                *dst++ = g;
                *dst++ = g;
                *dst++ = r;
                *dst++ = r;
                pos += inc;
                pos += inc;
        }
        }
}
}
 
 
/* Perform a stretch blit between two image structs of the same format.*/
/* Perform a stretch blit between two image structs of the same format.*/
void
void
GdStretchImage(PMWIMAGEHDR src, MWCLIPRECT *srcrect, PMWIMAGEHDR dst,
GdStretchImage(PMWIMAGEHDR src, MWCLIPRECT *srcrect, PMWIMAGEHDR dst,
        MWCLIPRECT *dstrect)
        MWCLIPRECT *dstrect)
{
{
        int pos, inc;
        int pos, inc;
        int bytesperpixel;
        int bytesperpixel;
        int dst_maxrow;
        int dst_maxrow;
        int src_row, dst_row;
        int src_row, dst_row;
        MWUCHAR *srcp = 0;
        MWUCHAR *srcp = 0;
        MWUCHAR *dstp;
        MWUCHAR *dstp;
        MWCLIPRECT full_src;
        MWCLIPRECT full_src;
        MWCLIPRECT full_dst;
        MWCLIPRECT full_dst;
 
 
        if ( src->bytesperpixel != dst->bytesperpixel ) {
        if ( src->bytesperpixel != dst->bytesperpixel ) {
                EPRINTF("GdStretchImage: bytesperpixel mismatch\n");
                EPRINTF("GdStretchImage: bytesperpixel mismatch\n");
                return;
                return;
        }
        }
 
 
        /* Verify the blit rectangles */
        /* Verify the blit rectangles */
        if ( srcrect ) {
        if ( srcrect ) {
                if ( (srcrect->x < 0) || (srcrect->y < 0) ||
                if ( (srcrect->x < 0) || (srcrect->y < 0) ||
                     ((srcrect->x+srcrect->width) > src->width) ||
                     ((srcrect->x+srcrect->width) > src->width) ||
                     ((srcrect->y+srcrect->height) > src->height) ) {
                     ((srcrect->y+srcrect->height) > src->height) ) {
                        EPRINTF("GdStretchImage: invalid source rect\n");
                        EPRINTF("GdStretchImage: invalid source rect\n");
                        return;
                        return;
                }
                }
        } else {
        } else {
                full_src.x = 0;
                full_src.x = 0;
                full_src.y = 0;
                full_src.y = 0;
                full_src.width = src->width;
                full_src.width = src->width;
                full_src.height = src->height;
                full_src.height = src->height;
                srcrect = &full_src;
                srcrect = &full_src;
        }
        }
        if ( dstrect ) {
        if ( dstrect ) {
                /* if stretching to nothing, return*/
                /* if stretching to nothing, return*/
                if (!dstrect->width || !dstrect->height)
                if (!dstrect->width || !dstrect->height)
                        return;
                        return;
                if ( (dstrect->x < 0) || (dstrect->y < 0) ||
                if ( (dstrect->x < 0) || (dstrect->y < 0) ||
                     ((dstrect->x+dstrect->width) > dst->width) ||
                     ((dstrect->x+dstrect->width) > dst->width) ||
                     ((dstrect->y+dstrect->height) > dst->height) ) {
                     ((dstrect->y+dstrect->height) > dst->height) ) {
                        EPRINTF("GdStretchImage: invalid dest rect\n");
                        EPRINTF("GdStretchImage: invalid dest rect\n");
                        return;
                        return;
                }
                }
        } else {
        } else {
                full_dst.x = 0;
                full_dst.x = 0;
                full_dst.y = 0;
                full_dst.y = 0;
                full_dst.width = dst->width;
                full_dst.width = dst->width;
                full_dst.height = dst->height;
                full_dst.height = dst->height;
                dstrect = &full_dst;
                dstrect = &full_dst;
        }
        }
 
 
        /* Set up the data... */
        /* Set up the data... */
        pos = 0x10000;
        pos = 0x10000;
        inc = (srcrect->height << 16) / dstrect->height;
        inc = (srcrect->height << 16) / dstrect->height;
        src_row = srcrect->y;
        src_row = srcrect->y;
        dst_row = dstrect->y;
        dst_row = dstrect->y;
        bytesperpixel = dst->bytesperpixel;
        bytesperpixel = dst->bytesperpixel;
 
 
        /* Perform the stretch blit */
        /* Perform the stretch blit */
        for ( dst_maxrow = dst_row+dstrect->height; dst_row<dst_maxrow;
        for ( dst_maxrow = dst_row+dstrect->height; dst_row<dst_maxrow;
                                                                ++dst_row ) {
                                                                ++dst_row ) {
                dstp = (MWUCHAR *)dst->imagebits + (dst_row*dst->pitch)
                dstp = (MWUCHAR *)dst->imagebits + (dst_row*dst->pitch)
                                    + (dstrect->x*bytesperpixel);
                                    + (dstrect->x*bytesperpixel);
                while ( pos >= 0x10000L ) {
                while ( pos >= 0x10000L ) {
                        srcp = (MWUCHAR *)src->imagebits + (src_row*src->pitch)
                        srcp = (MWUCHAR *)src->imagebits + (src_row*src->pitch)
                                    + (srcrect->x*bytesperpixel);
                                    + (srcrect->x*bytesperpixel);
                        ++src_row;
                        ++src_row;
                        pos -= 0x10000L;
                        pos -= 0x10000L;
                }
                }
 
 
                switch (bytesperpixel) {
                switch (bytesperpixel) {
                case 1:
                case 1:
                        copy_row1(srcp, srcrect->width, dstp, dstrect->width);
                        copy_row1(srcp, srcrect->width, dstp, dstrect->width);
                        break;
                        break;
                case 2:
                case 2:
                        copy_row2((unsigned short *)srcp, srcrect->width,
                        copy_row2((unsigned short *)srcp, srcrect->width,
                                (unsigned short *)dstp, dstrect->width);
                                (unsigned short *)dstp, dstrect->width);
                        break;
                        break;
                case 3:
                case 3:
                        copy_row3(srcp, srcrect->width, dstp, dstrect->width);
                        copy_row3(srcp, srcrect->width, dstp, dstrect->width);
                        break;
                        break;
                case 4:
                case 4:
                        copy_row4((unsigned long *)srcp, srcrect->width,
                        copy_row4((unsigned long *)srcp, srcrect->width,
                                (unsigned long *)dstp, dstrect->width);
                                (unsigned long *)dstp, dstrect->width);
                        break;
                        break;
                }
                }
 
 
                pos += inc;
                pos += inc;
        }
        }
}
}
 
 
#if defined(HAVE_FILEIO) && defined(HAVE_JPEG_SUPPORT)
#if defined(HAVE_FILEIO) && defined(HAVE_JPEG_SUPPORT)
#include "jpeglib.h"
#include "jpeglib.h"
/*
/*
 * JPEG decompression routine
 * JPEG decompression routine
 *
 *
 * JPEG support must be enabled (see README.txt in contrib/jpeg)
 * JPEG support must be enabled (see README.txt in contrib/jpeg)
 *
 *
 * SOME FINE POINTS: (from libjpeg)
 * SOME FINE POINTS: (from libjpeg)
 * In the below code, we ignored the return value of jpeg_read_scanlines,
 * In the below code, we ignored the return value of jpeg_read_scanlines,
 * which is the number of scanlines actually read.  We could get away with
 * which is the number of scanlines actually read.  We could get away with
 * this because we asked for only one line at a time and we weren't using
 * this because we asked for only one line at a time and we weren't using
 * a suspending data source.  See libjpeg.doc for more info.
 * a suspending data source.  See libjpeg.doc for more info.
 *
 *
 * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
 * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
 * we should have done it beforehand to ensure that the space would be
 * we should have done it beforehand to ensure that the space would be
 * counted against the JPEG max_memory setting.  In some systems the above
 * counted against the JPEG max_memory setting.  In some systems the above
 * code would risk an out-of-memory error.  However, in general we don't
 * code would risk an out-of-memory error.  However, in general we don't
 * know the output image dimensions before jpeg_start_decompress(), unless we
 * know the output image dimensions before jpeg_start_decompress(), unless we
 * call jpeg_calc_output_dimensions().  See libjpeg.doc for more about this.
 * call jpeg_calc_output_dimensions().  See libjpeg.doc for more about this.
 *
 *
 * Scanlines are returned in the same order as they appear in the JPEG file,
 * Scanlines are returned in the same order as they appear in the JPEG file,
 * which is standardly top-to-bottom.  If you must emit data bottom-to-top,
 * which is standardly top-to-bottom.  If you must emit data bottom-to-top,
 * you can use one of the virtual arrays provided by the JPEG memory manager
 * you can use one of the virtual arrays provided by the JPEG memory manager
 * to invert the data.  See wrbmp.c for an example.
 * to invert the data.  See wrbmp.c for an example.
 *
 *
 * As with compression, some operating modes may require temporary files.
 * As with compression, some operating modes may require temporary files.
 * On some systems you may need to set up a signal handler to ensure that
 * On some systems you may need to set up a signal handler to ensure that
 * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
 * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
 */
 */
static int
static int
LoadJPEG(buffer_t *src, PMWIMAGEHDR pimage, PSD psd, MWBOOL fast_grayscale)
LoadJPEG(buffer_t *src, PMWIMAGEHDR pimage, PSD psd, MWBOOL fast_grayscale)
{
{
  int   i;
  int   i;
  int   ret = 2;        /* image load error*/
  int   ret = 2;        /* image load error*/
  unsigned char magic[4];
  unsigned char magic[4];
 
 
#if FASTJPEG
#if FASTJPEG
  extern MWPALENTRY mwstdpal8[256];
  extern MWPALENTRY mwstdpal8[256];
#else
#else
  MWPALENTRY palette[256];
  MWPALENTRY palette[256];
#endif
#endif
 
 
  struct jpeg_source_mgr smgr;
  struct jpeg_source_mgr smgr;
  struct jpeg_decompress_struct cinfo;
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  struct jpeg_error_mgr jerr;
 
 
  static void init_source(j_compress_ptr dinfo) {
  static void init_source(j_compress_ptr dinfo) {
    smgr.next_input_byte = src->start;
    smgr.next_input_byte = src->start;
    smgr.bytes_in_buffer = src->size;
    smgr.bytes_in_buffer = src->size;
  }
  }
 
 
  static void fill_input_buffer(j_compress_ptr dinfo) {
  static void fill_input_buffer(j_compress_ptr dinfo) {
    return;
    return;
  }
  }
 
 
  static void skip_input_data(j_compress_ptr dinfo, int num_bytes) {
  static void skip_input_data(j_compress_ptr dinfo, int num_bytes) {
    if (num_bytes >= src->size) return;
    if (num_bytes >= src->size) return;
    smgr.next_input_byte += num_bytes;
    smgr.next_input_byte += num_bytes;
    smgr.bytes_in_buffer -= num_bytes;
    smgr.bytes_in_buffer -= num_bytes;
  }
  }
 
 
  static int resync_to_restart(j_compress_ptr dinfo, int desired ) {
  static int resync_to_restart(j_compress_ptr dinfo, int desired ) {
    return(jpeg_resync_to_restart(dinfo, desired));
    return(jpeg_resync_to_restart(dinfo, desired));
  }
  }
 
 
  static void term_source(j_compress_ptr dinfo) {
  static void term_source(j_compress_ptr dinfo) {
    return;
    return;
  }
  }
 
 
  /* first determine if JPEG file since decoder will error if not*/
  /* first determine if JPEG file since decoder will error if not*/
  bseek(src, 0, SEEK_SET);
  bseek(src, 0, SEEK_SET);
 
 
  if (!bread(src, magic, 2))
  if (!bread(src, magic, 2))
    return(0);
    return(0);
 
 
  if (magic[0] != 0xFF || magic[1] != 0xD8)
  if (magic[0] != 0xFF || magic[1] != 0xD8)
    return(0);           /* not JPEG image*/
    return(0);           /* not JPEG image*/
 
 
 
 
  bread(src, magic, 4);
  bread(src, magic, 4);
  bread(src, magic, 4);
  bread(src, magic, 4);
 
 
  if (strncmp(magic, "JFIF", 4) != 0)
  if (strncmp(magic, "JFIF", 4) != 0)
    return(0);           /* not JPEG image*/
    return(0);           /* not JPEG image*/
 
 
  bread(src, 0, SEEK_SET);
  bread(src, 0, SEEK_SET);
  pimage->imagebits = NULL;
  pimage->imagebits = NULL;
  pimage->palette = NULL;
  pimage->palette = NULL;
 
 
  /* Step 1: allocate and initialize JPEG decompression object */
  /* Step 1: allocate and initialize JPEG decompression object */
 
 
  /* We set up the normal JPEG error routines. */
  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr);
  cinfo.err = jpeg_std_error (&jerr);
 
 
  /* Now we can initialize the JPEG decompression object. */
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);
  jpeg_create_decompress (&cinfo);
 
 
 
 
  /* Step 2:  Setup the source manager */
  /* Step 2:  Setup the source manager */
 
 
  smgr.init_source = init_source;
  smgr.init_source = init_source;
  smgr.fill_input_buffer = fill_input_buffer;
  smgr.fill_input_buffer = fill_input_buffer;
  smgr.skip_input_data = skip_input_data;
  smgr.skip_input_data = skip_input_data;
  smgr.resync_to_restart = resync_to_restart;
  smgr.resync_to_restart = resync_to_restart;
  smgr.term_source = term_source;
  smgr.term_source = term_source;
 
 
  cinfo.src = &smgr;
  cinfo.src = &smgr;
 
 
  /* Step 2: specify data source (eg, a file) */
  /* Step 2: specify data source (eg, a file) */
  /* jpeg_stdio_src (&cinfo, fp); */
  /* jpeg_stdio_src (&cinfo, fp); */
 
 
  /* Step 3: read file parameters with jpeg_read_header() */
  /* Step 3: read file parameters with jpeg_read_header() */
  jpeg_read_header (&cinfo, TRUE);
  jpeg_read_header (&cinfo, TRUE);
 
 
        /* Step 4: set parameters for decompression */
        /* Step 4: set parameters for decompression */
        cinfo.out_color_space = fast_grayscale? JCS_GRAYSCALE: JCS_RGB;
        cinfo.out_color_space = fast_grayscale? JCS_GRAYSCALE: JCS_RGB;
        cinfo.quantize_colors = FALSE;
        cinfo.quantize_colors = FALSE;
 
 
#if FASTJPEG
#if FASTJPEG
        goto fastjpeg;
        goto fastjpeg;
#endif
#endif
        if (!fast_grayscale)
        if (!fast_grayscale)
        {
        {
                if (psd->pixtype == MWPF_PALETTE)
                if (psd->pixtype == MWPF_PALETTE)
                {
                {
fastjpeg:
fastjpeg:
                        cinfo.quantize_colors = TRUE;
                        cinfo.quantize_colors = TRUE;
 
 
#if FASTJPEG
#if FASTJPEG
                        cinfo.actual_number_of_colors = 256;
                        cinfo.actual_number_of_colors = 256;
#else
#else
                        /* Get system palette */
                        /* Get system palette */
                        cinfo.actual_number_of_colors =
                        cinfo.actual_number_of_colors =
                                GdGetPalette(psd, 0, psd->ncolors, palette);
                                GdGetPalette(psd, 0, psd->ncolors, palette);
#endif
#endif
 
 
                        /* Allocate jpeg colormap space */
                        /* Allocate jpeg colormap space */
                        cinfo.colormap = (*cinfo.mem->alloc_sarray)
                        cinfo.colormap = (*cinfo.mem->alloc_sarray)
                                ((j_common_ptr) &cinfo, JPOOL_IMAGE,
                                ((j_common_ptr) &cinfo, JPOOL_IMAGE,
                                (JDIMENSION)cinfo.actual_number_of_colors,
                                (JDIMENSION)cinfo.actual_number_of_colors,
                                (JDIMENSION)3);
                                (JDIMENSION)3);
 
 
                        /* Set colormap from system palette */
                        /* Set colormap from system palette */
                        for(i = 0; i < cinfo.actual_number_of_colors; ++i)
                        for(i = 0; i < cinfo.actual_number_of_colors; ++i)
                        {
                        {
#if FASTJPEG
#if FASTJPEG
                                cinfo.colormap[0][i] = mwstdpal8[i].r;
                                cinfo.colormap[0][i] = mwstdpal8[i].r;
                                cinfo.colormap[1][i] = mwstdpal8[i].g;
                                cinfo.colormap[1][i] = mwstdpal8[i].g;
                                cinfo.colormap[2][i] = mwstdpal8[i].b;
                                cinfo.colormap[2][i] = mwstdpal8[i].b;
#else
#else
                                cinfo.colormap[0][i] = palette[i].r;
                                cinfo.colormap[0][i] = palette[i].r;
                                cinfo.colormap[1][i] = palette[i].g;
                                cinfo.colormap[1][i] = palette[i].g;
                                cinfo.colormap[2][i] = palette[i].b;
                                cinfo.colormap[2][i] = palette[i].b;
#endif
#endif
                        }
                        }
                }
                }
        }
        }
        else
        else
        {
        {
                /* Grayscale output asked */
                /* Grayscale output asked */
                cinfo.quantize_colors = TRUE;
                cinfo.quantize_colors = TRUE;
                cinfo.out_color_space = JCS_GRAYSCALE;
                cinfo.out_color_space = JCS_GRAYSCALE;
                cinfo.desired_number_of_colors = psd->ncolors;
                cinfo.desired_number_of_colors = psd->ncolors;
        }
        }
        jpeg_calc_output_dimensions(&cinfo);
        jpeg_calc_output_dimensions(&cinfo);
 
 
        pimage->width = cinfo.output_width;
        pimage->width = cinfo.output_width;
        pimage->height = cinfo.output_height;
        pimage->height = cinfo.output_height;
        pimage->planes = 1;
        pimage->planes = 1;
#if FASTJPEG
#if FASTJPEG
        pimage->bpp = 8;
        pimage->bpp = 8;
#else
#else
        pimage->bpp = (fast_grayscale || psd->pixtype == MWPF_PALETTE)?
        pimage->bpp = (fast_grayscale || psd->pixtype == MWPF_PALETTE)?
                8: cinfo.output_components*8;
                8: cinfo.output_components*8;
#endif
#endif
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
                &pimage->bytesperpixel);
                &pimage->bytesperpixel);
        pimage->compression = MWIMAGE_RGB;      /* RGB not BGR order*/
        pimage->compression = MWIMAGE_RGB;      /* RGB not BGR order*/
        pimage->palsize = (pimage->bpp == 8)? 256: 0;
        pimage->palsize = (pimage->bpp == 8)? 256: 0;
        pimage->imagebits = malloc(pimage->pitch * pimage->height);
        pimage->imagebits = malloc(pimage->pitch * pimage->height);
        if(!pimage->imagebits)
        if(!pimage->imagebits)
                goto err;
                goto err;
        pimage->palette = NULL;
        pimage->palette = NULL;
#if FASTJPEG
#if FASTJPEG
        if(pimage->bpp == 8) {
        if(pimage->bpp == 8) {
                pimage->palette = malloc(256*sizeof(MWPALENTRY));
                pimage->palette = malloc(256*sizeof(MWPALENTRY));
                if(!pimage->palette)
                if(!pimage->palette)
                        goto err;
                        goto err;
                for (i=0; i<256; ++i)
                for (i=0; i<256; ++i)
                        pimage->palette[i] = mwstdpal8[i];
                        pimage->palette[i] = mwstdpal8[i];
        }
        }
#endif
#endif
 
 
        /* Step 5: Start decompressor */
        /* Step 5: Start decompressor */
        jpeg_start_decompress (&cinfo);
        jpeg_start_decompress (&cinfo);
 
 
        /* Step 6: while (scan lines remain to be read) */
        /* Step 6: while (scan lines remain to be read) */
        while(cinfo.output_scanline < cinfo.output_height) {
        while(cinfo.output_scanline < cinfo.output_height) {
                JSAMPROW rowptr[1];
                JSAMPROW rowptr[1];
                rowptr[0] = (JSAMPROW)(pimage->imagebits +
                rowptr[0] = (JSAMPROW)(pimage->imagebits +
                        cinfo.output_scanline * pimage->pitch);
                        cinfo.output_scanline * pimage->pitch);
                jpeg_read_scanlines (&cinfo, rowptr, 1);
                jpeg_read_scanlines (&cinfo, rowptr, 1);
        }
        }
        ret = 1;
        ret = 1;
 
 
err:
err:
        /* Step 7: Finish decompression */
        /* Step 7: Finish decompression */
        jpeg_finish_decompress (&cinfo);
        jpeg_finish_decompress (&cinfo);
 
 
        /* Step 8: Release JPEG decompression object */
        /* Step 8: Release JPEG decompression object */
        jpeg_destroy_decompress (&cinfo);
        jpeg_destroy_decompress (&cinfo);
 
 
        /* May want to check to see whether any corrupt-data
        /* May want to check to see whether any corrupt-data
         * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
         * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
         */
         */
        return ret;
        return ret;
}
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_JPEG_SUPPORT)*/
#endif /* defined(HAVE_FILEIO) && defined(HAVE_JPEG_SUPPORT)*/
 
 
#if defined(HAVE_FILEIO) && defined(HAVE_PNG_SUPPORT)
#if defined(HAVE_FILEIO) && defined(HAVE_PNG_SUPPORT)
#include "png.h"
#include "png.h"
/* png_jmpbuf() macro is not defined prior to libpng-1.0.6*/
/* png_jmpbuf() macro is not defined prior to libpng-1.0.6*/
#ifndef png_jmpbuf
#ifndef png_jmpbuf
#define png_jmpbuf(png_ptr)     ((png_ptr)->jmpbuf)
#define png_jmpbuf(png_ptr)     ((png_ptr)->jmpbuf)
#endif
#endif
/*
/*
 * Load a PNG file.
 * Load a PNG file.
 * Currently for simplicity we get the PNG library to convert the file to
 * Currently for simplicity we get the PNG library to convert the file to
 * 24 bit RGB format with no alpha channel information even if we could
 * 24 bit RGB format with no alpha channel information even if we could
 * potentially store the image more efficiently by taking note of the image
 * potentially store the image more efficiently by taking note of the image
 * type and depth and acting accordingly. Similarly, > 8 bits per channel,
 * type and depth and acting accordingly. Similarly, > 8 bits per channel,
 * gamma correction, etc. are not supported.
 * gamma correction, etc. are not supported.
 */
 */
static int
static int
LoadPNG(buffer_t * src, PMWIMAGEHDR pimage)
LoadPNG(buffer_t * src, PMWIMAGEHDR pimage)
{
{
        unsigned char hdr[8], **rows;
        unsigned char hdr[8], **rows;
        png_structp state;
        png_structp state;
        png_infop pnginfo;
        png_infop pnginfo;
        png_uint_32 width, height;
        png_uint_32 width, height;
        int bit_depth, colourtype, i;
        int bit_depth, colourtype, i;
 
 
        bseek(src, 0L, 0);
        bseek(src, 0L, 0);
 
 
        if(bread(src, hdr, 8) != 8) return 0;
        if(bread(src, hdr, 8) != 8) return 0;
 
 
        if(png_sig_cmp(hdr, 0, 8)) return 0;
        if(png_sig_cmp(hdr, 0, 8)) return 0;
 
 
        if(!(state = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
        if(!(state = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
                                                NULL, NULL))) goto nomem;
                                                NULL, NULL))) goto nomem;
 
 
        if(!(pnginfo = png_create_info_struct(state))) {
        if(!(pnginfo = png_create_info_struct(state))) {
                png_destroy_read_struct(&state, NULL, NULL);
                png_destroy_read_struct(&state, NULL, NULL);
                goto nomem;
                goto nomem;
        }
        }
 
 
        if(setjmp(png_jmpbuf(state))) {
        if(setjmp(png_jmpbuf(state))) {
                png_destroy_read_struct(&state, &pnginfo, NULL);
                png_destroy_read_struct(&state, &pnginfo, NULL);
                return 2;
                return 2;
        }
        }
 
 
        png_init_io(state, fp);
        png_init_io(state, fp);
        png_set_sig_bytes(state, 8);
        png_set_sig_bytes(state, 8);
        png_read_info(state, pnginfo);
        png_read_info(state, pnginfo);
        png_get_IHDR(state, pnginfo, &width, &height, &bit_depth, &colourtype,
        png_get_IHDR(state, pnginfo, &width, &height, &bit_depth, &colourtype,
                                                        NULL, NULL, NULL);
                                                        NULL, NULL, NULL);
 
 
        pimage->width = width;
        pimage->width = width;
        pimage->height = height;
        pimage->height = height;
        pimage->bpp = 24;
        pimage->bpp = 24;
        pimage->planes = 1;
        pimage->planes = 1;
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
                                                &pimage->bytesperpixel);
                                                &pimage->bytesperpixel);
        pimage->compression = MWIMAGE_RGB;
        pimage->compression = MWIMAGE_RGB;
        if(!(pimage->imagebits = malloc(pimage->pitch * pimage->height))) {
        if(!(pimage->imagebits = malloc(pimage->pitch * pimage->height))) {
                png_destroy_read_struct(&state, &pnginfo, NULL);
                png_destroy_read_struct(&state, &pnginfo, NULL);
                goto nomem;
                goto nomem;
        }
        }
        if(!(rows = malloc(pimage->height * sizeof(unsigned char *)))) {
        if(!(rows = malloc(pimage->height * sizeof(unsigned char *)))) {
                png_destroy_read_struct(&state, &pnginfo, NULL);
                png_destroy_read_struct(&state, &pnginfo, NULL);
                goto nomem;
                goto nomem;
        }
        }
        for(i = 0; i < pimage->height; i++)
        for(i = 0; i < pimage->height; i++)
                rows[i] = pimage->imagebits + (i * pimage->pitch);
                rows[i] = pimage->imagebits + (i * pimage->pitch);
 
 
        png_set_expand(state);
        png_set_expand(state);
        if(bit_depth == 16)
        if(bit_depth == 16)
                png_set_strip_16(state);
                png_set_strip_16(state);
        if(colourtype & PNG_COLOR_MASK_ALPHA)
        if(colourtype & PNG_COLOR_MASK_ALPHA)
                png_set_strip_alpha(state);
                png_set_strip_alpha(state);
        if(colourtype == PNG_COLOR_TYPE_GRAY ||
        if(colourtype == PNG_COLOR_TYPE_GRAY ||
                        colourtype == PNG_COLOR_TYPE_GRAY_ALPHA)
                        colourtype == PNG_COLOR_TYPE_GRAY_ALPHA)
                png_set_gray_to_rgb(state);
                png_set_gray_to_rgb(state);
 
 
        png_read_image(state, rows);
        png_read_image(state, rows);
 
 
        png_read_end(state, NULL);
        png_read_end(state, NULL);
        free(rows);
        free(rows);
        png_destroy_read_struct(&state, &pnginfo, NULL);
        png_destroy_read_struct(&state, &pnginfo, NULL);
 
 
        return 1;
        return 1;
 
 
nomem:
nomem:
        EPRINTF("LoadPNG: Out of memory\n");
        EPRINTF("LoadPNG: Out of memory\n");
        return 2;
        return 2;
}
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_PNG_SUPPORT)*/
#endif /* defined(HAVE_FILEIO) && defined(HAVE_PNG_SUPPORT)*/
 
 
#if defined(HAVE_FILEIO) && defined(HAVE_BMP_SUPPORT)
#if defined(HAVE_FILEIO) && defined(HAVE_BMP_SUPPORT)
/* BMP stuff*/
/* BMP stuff*/
#define BI_RGB          0L
#define BI_RGB          0L
#define BI_RLE8         1L
#define BI_RLE8         1L
#define BI_RLE4         2L
#define BI_RLE4         2L
#define BI_BITFIELDS    3L
#define BI_BITFIELDS    3L
 
 
typedef unsigned char   BYTE;
typedef unsigned char   BYTE;
typedef unsigned short  WORD;
typedef unsigned short  WORD;
typedef unsigned long   DWORD;
typedef unsigned long   DWORD;
typedef long            LONG;
typedef long            LONG;
 
 
typedef struct {
typedef struct {
        /* BITMAPFILEHEADER*/
        /* BITMAPFILEHEADER*/
        BYTE    bfType[2];
        BYTE    bfType[2];
        DWORD   bfSize;
        DWORD   bfSize;
        WORD    bfReserved1;
        WORD    bfReserved1;
        WORD    bfReserved2;
        WORD    bfReserved2;
        DWORD   bfOffBits;
        DWORD   bfOffBits;
} BMPFILEHEAD;
} BMPFILEHEAD;
 
 
#define FILEHEADSIZE 14
#define FILEHEADSIZE 14
 
 
/* windows style*/
/* windows style*/
typedef struct {
typedef struct {
        /* BITMAPINFOHEADER*/
        /* BITMAPINFOHEADER*/
        DWORD   BiSize;
        DWORD   BiSize;
        DWORD   BiWidth;
        DWORD   BiWidth;
        DWORD   BiHeight;
        DWORD   BiHeight;
        WORD    BiPlanes;
        WORD    BiPlanes;
        WORD    BiBitCount;
        WORD    BiBitCount;
        DWORD   BiCompression;
        DWORD   BiCompression;
        DWORD   BiSizeImage;
        DWORD   BiSizeImage;
        DWORD   BiXpelsPerMeter;
        DWORD   BiXpelsPerMeter;
        DWORD   BiYpelsPerMeter;
        DWORD   BiYpelsPerMeter;
        DWORD   BiClrUsed;
        DWORD   BiClrUsed;
        DWORD   BiClrImportant;
        DWORD   BiClrImportant;
} BMPINFOHEAD;
} BMPINFOHEAD;
 
 
#define INFOHEADSIZE 40
#define INFOHEADSIZE 40
 
 
/* os/2 style*/
/* os/2 style*/
typedef struct {
typedef struct {
        /* BITMAPCOREHEADER*/
        /* BITMAPCOREHEADER*/
        DWORD   bcSize;
        DWORD   bcSize;
        WORD    bcWidth;
        WORD    bcWidth;
        WORD    bcHeight;
        WORD    bcHeight;
        WORD    bcPlanes;
        WORD    bcPlanes;
        WORD    bcBitCount;
        WORD    bcBitCount;
} BMPCOREHEAD;
} BMPCOREHEAD;
 
 
#define COREHEADSIZE 12
#define COREHEADSIZE 12
 
 
static int      DecodeRLE8(MWUCHAR *buf, buffer_t *src);
static int      DecodeRLE8(MWUCHAR *buf, buffer_t *src);
static int      DecodeRLE4(MWUCHAR *buf, buffer_t *src);
static int      DecodeRLE4(MWUCHAR *buf, buffer_t *src);
static void     put4(int b);
static void     put4(int b);
 
 
/*
/*
 * BMP decoding routine
 * BMP decoding routine
 */
 */
 
 
/* Changed by JHC to allow a buffer instead of a filename */
/* Changed by JHC to allow a buffer instead of a filename */
 
 
static int
static int
LoadBMP(buffer_t *src, PMWIMAGEHDR pimage)
LoadBMP(buffer_t *src, PMWIMAGEHDR pimage)
{
{
        int             h, i, compression;
        int             h, i, compression;
        int             headsize;
        int             headsize;
        MWUCHAR         *imagebits;
        MWUCHAR         *imagebits;
        BMPFILEHEAD     bmpf;
        BMPFILEHEAD     bmpf;
        BMPINFOHEAD     bmpi;
        BMPINFOHEAD     bmpi;
        BMPCOREHEAD     bmpc;
        BMPCOREHEAD     bmpc;
        MWUCHAR         headbuffer[INFOHEADSIZE];
        MWUCHAR         headbuffer[INFOHEADSIZE];
 
 
        bseek(src, 0, SEEK_SET);
        bseek(src, 0, SEEK_SET);
 
 
        pimage->imagebits = NULL;
        pimage->imagebits = NULL;
        pimage->palette = NULL;
        pimage->palette = NULL;
 
 
        /* read BMP file header*/
        /* read BMP file header*/
        if (bread(src, &headbuffer, FILEHEADSIZE) != FILEHEADSIZE)
        if (bread(src, &headbuffer, FILEHEADSIZE) != FILEHEADSIZE)
          return(0);
          return(0);
 
 
        bmpf.bfType[0] = headbuffer[0];
        bmpf.bfType[0] = headbuffer[0];
        bmpf.bfType[1] = headbuffer[1];
        bmpf.bfType[1] = headbuffer[1];
 
 
        /* Is it really a bmp file ? */
        /* Is it really a bmp file ? */
        if (*(WORD*)&bmpf.bfType[0] != wswap(0x4D42)) /* 'BM' */
        if (*(WORD*)&bmpf.bfType[0] != wswap(0x4D42)) /* 'BM' */
                return 0;        /* not bmp image*/
                return 0;        /* not bmp image*/
 
 
        /*bmpf.bfSize = dwswap(dwread(&headbuffer[2]));*/
        /*bmpf.bfSize = dwswap(dwread(&headbuffer[2]));*/
        bmpf.bfOffBits = dwswap(dwread(&headbuffer[10]));
        bmpf.bfOffBits = dwswap(dwread(&headbuffer[10]));
 
 
        /* Read remaining header size */
        /* Read remaining header size */
        if (bread(src,&headsize,sizeof(DWORD)) != sizeof(DWORD))
        if (bread(src,&headsize,sizeof(DWORD)) != sizeof(DWORD))
                return 0;        /* not bmp image*/
                return 0;        /* not bmp image*/
        headsize = dwswap(headsize);
        headsize = dwswap(headsize);
 
 
        /* might be windows or os/2 header */
        /* might be windows or os/2 header */
        if(headsize == COREHEADSIZE) {
        if(headsize == COREHEADSIZE) {
 
 
                /* read os/2 header */
                /* read os/2 header */
                if(bread(src, &headbuffer, COREHEADSIZE-sizeof(DWORD)) !=
                if(bread(src, &headbuffer, COREHEADSIZE-sizeof(DWORD)) !=
                        COREHEADSIZE-sizeof(DWORD))
                        COREHEADSIZE-sizeof(DWORD))
                                return 0;        /* not bmp image*/
                                return 0;        /* not bmp image*/
 
 
                /* Get data */
                /* Get data */
                bmpc.bcWidth = wswap(*(WORD*)&headbuffer[0]);
                bmpc.bcWidth = wswap(*(WORD*)&headbuffer[0]);
                bmpc.bcHeight = wswap(*(WORD*)&headbuffer[2]);
                bmpc.bcHeight = wswap(*(WORD*)&headbuffer[2]);
                bmpc.bcPlanes = wswap(*(WORD*)&headbuffer[4]);
                bmpc.bcPlanes = wswap(*(WORD*)&headbuffer[4]);
                bmpc.bcBitCount = wswap(*(WORD*)&headbuffer[6]);
                bmpc.bcBitCount = wswap(*(WORD*)&headbuffer[6]);
 
 
                pimage->width = (int)bmpc.bcWidth;
                pimage->width = (int)bmpc.bcWidth;
                pimage->height = (int)bmpc.bcHeight;
                pimage->height = (int)bmpc.bcHeight;
                pimage->bpp = bmpc.bcBitCount;
                pimage->bpp = bmpc.bcBitCount;
                if (pimage->bpp <= 8)
                if (pimage->bpp <= 8)
                        pimage->palsize = 1 << pimage->bpp;
                        pimage->palsize = 1 << pimage->bpp;
                else pimage->palsize = 0;
                else pimage->palsize = 0;
                compression = BI_RGB;
                compression = BI_RGB;
        } else {
        } else {
                /* read windows header */
                /* read windows header */
                if(bread(src, &headbuffer, INFOHEADSIZE-sizeof(DWORD)) !=
                if(bread(src, &headbuffer, INFOHEADSIZE-sizeof(DWORD)) !=
                        INFOHEADSIZE-sizeof(DWORD))
                        INFOHEADSIZE-sizeof(DWORD))
                                return 0;        /* not bmp image*/
                                return 0;        /* not bmp image*/
 
 
                /* Get data */
                /* Get data */
                bmpi.BiWidth = dwswap(*(DWORD*)&headbuffer[0]);
                bmpi.BiWidth = dwswap(*(DWORD*)&headbuffer[0]);
                bmpi.BiHeight = dwswap(*(DWORD*)&headbuffer[4]);
                bmpi.BiHeight = dwswap(*(DWORD*)&headbuffer[4]);
                bmpi.BiPlanes = wswap(*(WORD*)&headbuffer[8]);
                bmpi.BiPlanes = wswap(*(WORD*)&headbuffer[8]);
                bmpi.BiBitCount = wswap(*(WORD*)&headbuffer[10]);
                bmpi.BiBitCount = wswap(*(WORD*)&headbuffer[10]);
                bmpi.BiCompression = dwswap(*(DWORD*)&headbuffer[12]);
                bmpi.BiCompression = dwswap(*(DWORD*)&headbuffer[12]);
                bmpi.BiSizeImage = dwswap(*(DWORD*)&headbuffer[16]);
                bmpi.BiSizeImage = dwswap(*(DWORD*)&headbuffer[16]);
                bmpi.BiXpelsPerMeter = dwswap(*(DWORD*)&headbuffer[20]);
                bmpi.BiXpelsPerMeter = dwswap(*(DWORD*)&headbuffer[20]);
                bmpi.BiYpelsPerMeter = dwswap(*(DWORD*)&headbuffer[24]);
                bmpi.BiYpelsPerMeter = dwswap(*(DWORD*)&headbuffer[24]);
                bmpi.BiClrUsed = dwswap(*(DWORD*)&headbuffer[28]);
                bmpi.BiClrUsed = dwswap(*(DWORD*)&headbuffer[28]);
                bmpi.BiClrImportant = dwswap(*(DWORD*)&headbuffer[32]);
                bmpi.BiClrImportant = dwswap(*(DWORD*)&headbuffer[32]);
 
 
                pimage->width = (int)bmpi.BiWidth;
                pimage->width = (int)bmpi.BiWidth;
                pimage->height = (int)bmpi.BiHeight;
                pimage->height = (int)bmpi.BiHeight;
                pimage->bpp = bmpi.BiBitCount;
                pimage->bpp = bmpi.BiBitCount;
                pimage->palsize = (int)bmpi.BiClrUsed;
                pimage->palsize = (int)bmpi.BiClrUsed;
                if (pimage->palsize > 256)
                if (pimage->palsize > 256)
                        pimage->palsize = 0;
                        pimage->palsize = 0;
                else if(pimage->palsize == 0 && pimage->bpp <= 8)
                else if(pimage->palsize == 0 && pimage->bpp <= 8)
                        pimage->palsize = 1 << pimage->bpp;
                        pimage->palsize = 1 << pimage->bpp;
                compression = bmpi.BiCompression;
                compression = bmpi.BiCompression;
        }
        }
        pimage->compression = MWIMAGE_BGR;      /* right side up, BGR order*/
        pimage->compression = MWIMAGE_BGR;      /* right side up, BGR order*/
        pimage->planes = 1;
        pimage->planes = 1;
 
 
        /* currently only 1, 4, 8 and 24 bpp bitmaps*/
        /* currently only 1, 4, 8 and 24 bpp bitmaps*/
        if(pimage->bpp > 8 && pimage->bpp != 24) {
        if(pimage->bpp > 8 && pimage->bpp != 24) {
                EPRINTF("LoadBMP: image bpp not 1, 4, 8 or 24\n");
                EPRINTF("LoadBMP: image bpp not 1, 4, 8 or 24\n");
                return 2;       /* image loading error*/
                return 2;       /* image loading error*/
        }
        }
 
 
        /* compute byte line size and bytes per pixel*/
        /* compute byte line size and bytes per pixel*/
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
                &pimage->bytesperpixel);
                &pimage->bytesperpixel);
 
 
        /* Allocate image */
        /* Allocate image */
        if( (pimage->imagebits = malloc(pimage->pitch*pimage->height)) == NULL)
        if( (pimage->imagebits = malloc(pimage->pitch*pimage->height)) == NULL)
                goto err;
                goto err;
        if( (pimage->palette = malloc(256*sizeof(MWPALENTRY))) == NULL)
        if( (pimage->palette = malloc(256*sizeof(MWPALENTRY))) == NULL)
                goto err;
                goto err;
 
 
        /* get colormap*/
        /* get colormap*/
        if(pimage->bpp <= 8) {
        if(pimage->bpp <= 8) {
                for(i=0; i<pimage->palsize; i++) {
                for(i=0; i<pimage->palsize; i++) {
                        pimage->palette[i].b = bgetc(src);
                        pimage->palette[i].b = bgetc(src);
                        pimage->palette[i].g = bgetc(src);
                        pimage->palette[i].g = bgetc(src);
                        pimage->palette[i].r = bgetc(src);
                        pimage->palette[i].r = bgetc(src);
                        if(headsize != COREHEADSIZE)
                        if(headsize != COREHEADSIZE)
                                bgetc(src);
                                bgetc(src);
                }
                }
        }
        }
 
 
        /* decode image data*/
        /* decode image data*/
        bseek(src, bmpf.bfOffBits, SEEK_SET);
        bseek(src, bmpf.bfOffBits, SEEK_SET);
 
 
        h = pimage->height;
        h = pimage->height;
        /* For every row ... */
        /* For every row ... */
        while (--h >= 0) {
        while (--h >= 0) {
                /* turn image rightside up*/
                /* turn image rightside up*/
                imagebits = pimage->imagebits + h*pimage->pitch;
                imagebits = pimage->imagebits + h*pimage->pitch;
 
 
                /* Get row data from file */
                /* Get row data from file */
                if(compression == BI_RLE8) {
                if(compression == BI_RLE8) {
                        if(!DecodeRLE8(imagebits, src))
                        if(!DecodeRLE8(imagebits, src))
                                break;
                                break;
                } else if(compression == BI_RLE4) {
                } else if(compression == BI_RLE4) {
                        if(!DecodeRLE4(imagebits, src))
                        if(!DecodeRLE4(imagebits, src))
                                break;
                                break;
                } else {
                } else {
                        if(bread(src, imagebits, pimage->pitch) !=
                        if(bread(src, imagebits, pimage->pitch) !=
                                pimage->pitch)
                                pimage->pitch)
                                        goto err;
                                        goto err;
                }
                }
        }
        }
        return 1;               /* bmp image ok*/
        return 1;               /* bmp image ok*/
 
 
err:
err:
        EPRINTF("LoadBMP: image loading error\n");
        EPRINTF("LoadBMP: image loading error\n");
        if(pimage->imagebits)
        if(pimage->imagebits)
                free(pimage->imagebits);
                free(pimage->imagebits);
        if(pimage->palette)
        if(pimage->palette)
                free(pimage->palette);
                free(pimage->palette);
        return 2;               /* bmp image error*/
        return 2;               /* bmp image error*/
}
}
 
 
/*
/*
 * Decode one line of RLE8, return 0 when done with all bitmap data
 * Decode one line of RLE8, return 0 when done with all bitmap data
 */
 */
static int
static int
DecodeRLE8(MWUCHAR *buf, buffer_t *src)
DecodeRLE8(MWUCHAR *buf, buffer_t *src)
{
{
        int             c, n;
        int             c, n;
        MWUCHAR *       p = buf;
        MWUCHAR *       p = buf;
 
 
        for( ;;) {
        for( ;;) {
          switch( n = bgetc(src)) {
          switch( n = bgetc(src)) {
          case EOF:
          case EOF:
            return( 0);
            return( 0);
          case 0:                        /* 0 = escape*/
          case 0:                        /* 0 = escape*/
            switch( n = bgetc(src)) {
            switch( n = bgetc(src)) {
            case 0:      /* 0 0 = end of current scan line*/
            case 0:      /* 0 0 = end of current scan line*/
              return( 1);
              return( 1);
            case 1:             /* 0 1 = end of data*/
            case 1:             /* 0 1 = end of data*/
              return( 1);
              return( 1);
            case 2:             /* 0 2 xx yy delta mode NOT SUPPORTED*/
            case 2:             /* 0 2 xx yy delta mode NOT SUPPORTED*/
              (void)bgetc(src);
              (void)bgetc(src);
              (void)bgetc(src);
              (void)bgetc(src);
              continue;
              continue;
            default:    /* 0 3..255 xx nn uncompressed data*/
            default:    /* 0 3..255 xx nn uncompressed data*/
              for( c=0; c<n; c++)
              for( c=0; c<n; c++)
                *p++ = bgetc(src);
                *p++ = bgetc(src);
              if( n & 1)
              if( n & 1)
                (void)bgetc(src);
                (void)bgetc(src);
              continue;
              continue;
            }
            }
          default:
          default:
            c = bgetc(src);
            c = bgetc(src);
            while( n--)
            while( n--)
              *p++ = c;
              *p++ = c;
            continue;
            continue;
          }
          }
        }
        }
}
}
 
 
/*
/*
 * Decode one line of RLE4, return 0 when done with all bitmap data
 * Decode one line of RLE4, return 0 when done with all bitmap data
 */
 */
static MWUCHAR *p;
static MWUCHAR *p;
static int      once;
static int      once;
 
 
static void
static void
put4(int b)
put4(int b)
{
{
        static int      last;
        static int      last;
 
 
        last = (last << 4) | b;
        last = (last << 4) | b;
        if( ++once == 2) {
        if( ++once == 2) {
                *p++ = last;
                *p++ = last;
                once = 0;
                once = 0;
        }
        }
}
}
 
 
static int
static int
DecodeRLE4(MWUCHAR *buf, buffer_t *src)
DecodeRLE4(MWUCHAR *buf, buffer_t *src)
{
{
        int             c, n, c1, c2;
        int             c, n, c1, c2;
 
 
        p = buf;
        p = buf;
        once = 0;
        once = 0;
        c1 = 0;
        c1 = 0;
 
 
        for( ;;) {
        for( ;;) {
          switch( n = bgetc(src)) {
          switch( n = bgetc(src)) {
          case EOF:
          case EOF:
            return( 0);
            return( 0);
          case 0:                        /* 0 = escape*/
          case 0:                        /* 0 = escape*/
            switch( n = bgetc(src)) {
            switch( n = bgetc(src)) {
            case 0:      /* 0 0 = end of current scan line*/
            case 0:      /* 0 0 = end of current scan line*/
              if( once)
              if( once)
                put4( 0);
                put4( 0);
              return( 1);
              return( 1);
            case 1:             /* 0 1 = end of data*/
            case 1:             /* 0 1 = end of data*/
              if( once)
              if( once)
                put4( 0);
                put4( 0);
              return( 1);
              return( 1);
            case 2:             /* 0 2 xx yy delta mode NOT SUPPORTED*/
            case 2:             /* 0 2 xx yy delta mode NOT SUPPORTED*/
              (void)bgetc(src);
              (void)bgetc(src);
              (void)bgetc(src);
              (void)bgetc(src);
              continue;
              continue;
            default:    /* 0 3..255 xx nn uncompressed data*/
            default:    /* 0 3..255 xx nn uncompressed data*/
              c2 = (n+3) & ~3;
              c2 = (n+3) & ~3;
              for( c=0; c<c2; c++) {
              for( c=0; c<c2; c++) {
                if( (c & 1) == 0)
                if( (c & 1) == 0)
                  c1 = bgetc(src);
                  c1 = bgetc(src);
                if( c < n)
                if( c < n)
                  put4( (c1 >> 4) & 0x0f);
                  put4( (c1 >> 4) & 0x0f);
                c1 <<= 4;
                c1 <<= 4;
              }
              }
              continue;
              continue;
            }
            }
          default:
          default:
            c = bgetc(src);
            c = bgetc(src);
            c1 = (c >> 4) & 0x0f;
            c1 = (c >> 4) & 0x0f;
            c2 = c & 0x0f;
            c2 = c & 0x0f;
            for( c=0; c<n; c++)
            for( c=0; c<n; c++)
              put4( (c&1)? c2: c1);
              put4( (c&1)? c2: c1);
            continue;
            continue;
          }
          }
        }
        }
}
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_BMP_SUPPORT)*/
#endif /* defined(HAVE_FILEIO) && defined(HAVE_BMP_SUPPORT)*/
 
 
#if 0
#if 0
void print_image(PMWIMAGEHDR image)
void print_image(PMWIMAGEHDR image)
{
{
        int i;
        int i;
 
 
        DPRINTF("Image:\n\n");
        DPRINTF("Image:\n\n");
        DPRINTF("height: %d\n", image->height);
        DPRINTF("height: %d\n", image->height);
        DPRINTF("width: %d\n", image->width);
        DPRINTF("width: %d\n", image->width);
        DPRINTF("planes: %d\n", image->planes);
        DPRINTF("planes: %d\n", image->planes);
        DPRINTF("bpp: %d\n", image->bpp);
        DPRINTF("bpp: %d\n", image->bpp);
        DPRINTF("compression: %d\n", image->compression);
        DPRINTF("compression: %d\n", image->compression);
        DPRINTF("palsize: %d\n", image->palsize);
        DPRINTF("palsize: %d\n", image->palsize);
 
 
        for (i=0;i<image->palsize;i++)
        for (i=0;i<image->palsize;i++)
                DPRINTF("palette: %d, %d, %d\n", image->palette[i].r,
                DPRINTF("palette: %d, %d, %d\n", image->palette[i].r,
                        image->palette[i].g, image->palette[i].b);
                        image->palette[i].g, image->palette[i].b);
 
 
        for(i=0;i<(image->width*image->height);i++)
        for(i=0;i<(image->width*image->height);i++)
                DPRINTF("imagebits: %d\n", image->imagebits[i]);
                DPRINTF("imagebits: %d\n", image->imagebits[i]);
}
}
#endif
#endif
 
 
#if defined(HAVE_FILEIO) && defined(HAVE_GIF_SUPPORT)
#if defined(HAVE_FILEIO) && defined(HAVE_GIF_SUPPORT)
/* Code for GIF decoding has been adapted from XPaint:                   */
/* Code for GIF decoding has been adapted from XPaint:                   */
/* +-------------------------------------------------------------------+ */
/* +-------------------------------------------------------------------+ */
/* | Copyright 1990, 1991, 1993 David Koblas.                          | */
/* | Copyright 1990, 1991, 1993 David Koblas.                          | */
/* | Copyright 1996 Torsten Martinsen.                                 | */
/* | Copyright 1996 Torsten Martinsen.                                 | */
/* |   Permission to use, copy, modify, and distribute this software   | */
/* |   Permission to use, copy, modify, and distribute this software   | */
/* |   and its documentation for any purpose and without fee is hereby | */
/* |   and its documentation for any purpose and without fee is hereby | */
/* |   granted, provided that the above copyright notice appear in all | */
/* |   granted, provided that the above copyright notice appear in all | */
/* |   copies and that both that copyright notice and this permission  | */
/* |   copies and that both that copyright notice and this permission  | */
/* |   notice appear in supporting documentation.  This software is    | */
/* |   notice appear in supporting documentation.  This software is    | */
/* |   provided "as is" without express or implied warranty.           | */
/* |   provided "as is" without express or implied warranty.           | */
/* +-------------------------------------------------------------------+ */
/* +-------------------------------------------------------------------+ */
/* Portions Copyright (C) 1999  Sam Lantinga*/
/* Portions Copyright (C) 1999  Sam Lantinga*/
/* Adapted for use in SDL by Sam Lantinga -- 7/20/98 */
/* Adapted for use in SDL by Sam Lantinga -- 7/20/98 */
/*
/*
    This library is free software; you can redistribute it and/or
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
    version 2 of the License, or (at your option) any later version.
 
 
    This library is distributed in the hope that it will be useful,
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
    Library General Public License for more details.
 
 
    You should have received a copy of the GNU Library General Public
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
*/
/* GIF stuff*/
/* GIF stuff*/
/*
/*
 * GIF decoding routine
 * GIF decoding routine
 */
 */
#define MAXCOLORMAPSIZE         256
#define MAXCOLORMAPSIZE         256
#define MAX_LWZ_BITS            12
#define MAX_LWZ_BITS            12
#define INTERLACE               0x40
#define INTERLACE               0x40
#define LOCALCOLORMAP           0x80
#define LOCALCOLORMAP           0x80
 
 
#define CM_RED          0
#define CM_RED          0
#define CM_GREEN        1
#define CM_GREEN        1
#define CM_BLUE         2
#define CM_BLUE         2
 
 
#define BitSet(byte, bit)       (((byte) & (bit)) == (bit))
#define BitSet(byte, bit)       (((byte) & (bit)) == (bit))
#define ReadOK(src,buffer,len)  bread(src, buffer, len)
#define ReadOK(src,buffer,len)  bread(src, buffer, len)
#define LM_to_uint(a,b)         (((b)<<8)|(a))
#define LM_to_uint(a,b)         (((b)<<8)|(a))
 
 
struct {
struct {
    unsigned int Width;
    unsigned int Width;
    unsigned int Height;
    unsigned int Height;
    unsigned char ColorMap[3][MAXCOLORMAPSIZE];
    unsigned char ColorMap[3][MAXCOLORMAPSIZE];
    unsigned int BitPixel;
    unsigned int BitPixel;
    unsigned int ColorResolution;
    unsigned int ColorResolution;
    unsigned int Background;
    unsigned int Background;
    unsigned int AspectRatio;
    unsigned int AspectRatio;
    int GrayScale;
    int GrayScale;
} GifScreen;
} GifScreen;
 
 
static struct {
static struct {
    int transparent;
    int transparent;
    int delayTime;
    int delayTime;
    int inputFlag;
    int inputFlag;
    int disposal;
    int disposal;
} Gif89;
} Gif89;
 
 
static int ReadColorMap(buffer_t *src, int number,
static int ReadColorMap(buffer_t *src, int number,
                unsigned char buffer[3][MAXCOLORMAPSIZE], int *flag);
                unsigned char buffer[3][MAXCOLORMAPSIZE], int *flag);
static int DoExtension(buffer_t *src, int label);
static int DoExtension(buffer_t *src, int label);
static int GetDataBlock(buffer_t *src, unsigned char *buf);
static int GetDataBlock(buffer_t *src, unsigned char *buf);
static int GetCode(buffer_t *src, int code_size, int flag);
static int GetCode(buffer_t *src, int code_size, int flag);
static int LWZReadByte(buffer_t *src, int flag, int input_code_size);
static int LWZReadByte(buffer_t *src, int flag, int input_code_size);
static int ReadImage(buffer_t *src, PMWIMAGEHDR pimage, int len, int height, int,
static int ReadImage(buffer_t *src, PMWIMAGEHDR pimage, int len, int height, int,
                unsigned char cmap[3][MAXCOLORMAPSIZE],
                unsigned char cmap[3][MAXCOLORMAPSIZE],
                int gray, int interlace, int ignore);
                int gray, int interlace, int ignore);
 
 
static int
static int
LoadGIF(buffer_t *src, PMWIMAGEHDR pimage)
LoadGIF(buffer_t *src, PMWIMAGEHDR pimage)
{
{
    unsigned char buf[16];
    unsigned char buf[16];
    unsigned char c;
    unsigned char c;
    unsigned char localColorMap[3][MAXCOLORMAPSIZE];
    unsigned char localColorMap[3][MAXCOLORMAPSIZE];
    int grayScale;
    int grayScale;
    int useGlobalColormap;
    int useGlobalColormap;
    int bitPixel;
    int bitPixel;
    int imageCount = 0;
    int imageCount = 0;
    char version[4];
    char version[4];
    int imageNumber = 1;
    int imageNumber = 1;
    int ok = 0;
    int ok = 0;
 
 
    bseek(src, 0, SEEK_SET);
    bseek(src, 0, SEEK_SET);
 
 
    pimage->imagebits = NULL;
    pimage->imagebits = NULL;
    pimage->palette = NULL;
    pimage->palette = NULL;
 
 
    if (!ReadOK(src, buf, 6))
    if (!ReadOK(src, buf, 6))
        return 0;                /* not gif image*/
        return 0;                /* not gif image*/
    if (strncmp((char *) buf, "GIF", 3) != 0)
    if (strncmp((char *) buf, "GIF", 3) != 0)
        return 0;
        return 0;
    strncpy(version, (char *) buf + 3, 3);
    strncpy(version, (char *) buf + 3, 3);
    version[3] = '\0';
    version[3] = '\0';
 
 
    if (strcmp(version, "87a") != 0 && strcmp(version, "89a") != 0) {
    if (strcmp(version, "87a") != 0 && strcmp(version, "89a") != 0) {
        EPRINTF("LoadGIF: GIF version number not 87a or 89a\n");
        EPRINTF("LoadGIF: GIF version number not 87a or 89a\n");
        return 2;               /* image loading error*/
        return 2;               /* image loading error*/
    }
    }
    Gif89.transparent = -1;
    Gif89.transparent = -1;
    Gif89.delayTime = -1;
    Gif89.delayTime = -1;
    Gif89.inputFlag = -1;
    Gif89.inputFlag = -1;
    Gif89.disposal = 0;
    Gif89.disposal = 0;
 
 
    if (!ReadOK(src, buf, 7)) {
    if (!ReadOK(src, buf, 7)) {
        EPRINTF("LoadGIF: bad screen descriptor\n");
        EPRINTF("LoadGIF: bad screen descriptor\n");
        return 2;               /* image loading error*/
        return 2;               /* image loading error*/
    }
    }
    GifScreen.Width = LM_to_uint(buf[0], buf[1]);
    GifScreen.Width = LM_to_uint(buf[0], buf[1]);
    GifScreen.Height = LM_to_uint(buf[2], buf[3]);
    GifScreen.Height = LM_to_uint(buf[2], buf[3]);
    GifScreen.BitPixel = 2 << (buf[4] & 0x07);
    GifScreen.BitPixel = 2 << (buf[4] & 0x07);
    GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
    GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
    GifScreen.Background = buf[5];
    GifScreen.Background = buf[5];
    GifScreen.AspectRatio = buf[6];
    GifScreen.AspectRatio = buf[6];
 
 
    if (BitSet(buf[4], LOCALCOLORMAP)) {        /* Global Colormap */
    if (BitSet(buf[4], LOCALCOLORMAP)) {        /* Global Colormap */
        if (ReadColorMap(src, GifScreen.BitPixel, GifScreen.ColorMap,
        if (ReadColorMap(src, GifScreen.BitPixel, GifScreen.ColorMap,
                         &GifScreen.GrayScale)) {
                         &GifScreen.GrayScale)) {
            EPRINTF("LoadGIF: bad global colormap\n");
            EPRINTF("LoadGIF: bad global colormap\n");
            return 2;           /* image loading error*/
            return 2;           /* image loading error*/
        }
        }
    }
    }
 
 
    do {
    do {
        if (!ReadOK(src, &c, 1)) {
        if (!ReadOK(src, &c, 1)) {
            EPRINTF("LoadGIF: EOF on image data\n");
            EPRINTF("LoadGIF: EOF on image data\n");
            goto done;
            goto done;
        }
        }
        if (c == ';') {         /* GIF terminator */
        if (c == ';') {         /* GIF terminator */
            if (imageCount < imageNumber) {
            if (imageCount < imageNumber) {
                EPRINTF("LoadGIF: no image %d of %d\n", imageNumber,imageCount);
                EPRINTF("LoadGIF: no image %d of %d\n", imageNumber,imageCount);
                goto done;
                goto done;
            }
            }
        }
        }
        if (c == '!') {         /* Extension */
        if (c == '!') {         /* Extension */
            if (!ReadOK(src, &c, 1)) {
            if (!ReadOK(src, &c, 1)) {
                EPRINTF("LoadGIF: EOF on extension function code\n");
                EPRINTF("LoadGIF: EOF on extension function code\n");
                goto done;
                goto done;
            }
            }
            DoExtension(src, c);
            DoExtension(src, c);
            continue;
            continue;
        }
        }
        if (c != ',') {         /* Not a valid start character */
        if (c != ',') {         /* Not a valid start character */
            continue;
            continue;
        }
        }
        ++imageCount;
        ++imageCount;
 
 
        if (!ReadOK(src, buf, 9)) {
        if (!ReadOK(src, buf, 9)) {
            EPRINTF("LoadGIF: bad image size\n");
            EPRINTF("LoadGIF: bad image size\n");
            goto done;
            goto done;
        }
        }
        useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);
        useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);
 
 
        bitPixel = 1 << ((buf[8] & 0x07) + 1);
        bitPixel = 1 << ((buf[8] & 0x07) + 1);
 
 
        if (!useGlobalColormap) {
        if (!useGlobalColormap) {
            if (ReadColorMap(src, bitPixel, localColorMap, &grayScale)) {
            if (ReadColorMap(src, bitPixel, localColorMap, &grayScale)) {
                EPRINTF("LoadGIF: bad local colormap\n");
                EPRINTF("LoadGIF: bad local colormap\n");
                goto done;
                goto done;
            }
            }
            ok = ReadImage(src, pimage, LM_to_uint(buf[4], buf[5]),
            ok = ReadImage(src, pimage, LM_to_uint(buf[4], buf[5]),
                              LM_to_uint(buf[6], buf[7]),
                              LM_to_uint(buf[6], buf[7]),
                              bitPixel, localColorMap, grayScale,
                              bitPixel, localColorMap, grayScale,
                              BitSet(buf[8], INTERLACE),
                              BitSet(buf[8], INTERLACE),
                              imageCount != imageNumber);
                              imageCount != imageNumber);
        } else {
        } else {
            ok = ReadImage(src, pimage, LM_to_uint(buf[4], buf[5]),
            ok = ReadImage(src, pimage, LM_to_uint(buf[4], buf[5]),
                              LM_to_uint(buf[6], buf[7]),
                              LM_to_uint(buf[6], buf[7]),
                              GifScreen.BitPixel, GifScreen.ColorMap,
                              GifScreen.BitPixel, GifScreen.ColorMap,
                              GifScreen.GrayScale, BitSet(buf[8], INTERLACE),
                              GifScreen.GrayScale, BitSet(buf[8], INTERLACE),
                              imageCount != imageNumber);
                              imageCount != imageNumber);
        }
        }
    } while (ok == 0);
    } while (ok == 0);
 
 
    /* set transparent color, if any*/
    /* set transparent color, if any*/
    pimage->transcolor = Gif89.transparent;
    pimage->transcolor = Gif89.transparent;
 
 
    if (ok)
    if (ok)
            return 1;           /* image load ok*/
            return 1;           /* image load ok*/
 
 
done:
done:
    if (pimage->imagebits)
    if (pimage->imagebits)
            free(pimage->imagebits);
            free(pimage->imagebits);
    if (pimage->palette)
    if (pimage->palette)
            free(pimage->palette);
            free(pimage->palette);
    return 2;                   /* image load error*/
    return 2;                   /* image load error*/
}
}
 
 
static int
static int
ReadColorMap(buffer_t *src, int number, unsigned char buffer[3][MAXCOLORMAPSIZE],
ReadColorMap(buffer_t *src, int number, unsigned char buffer[3][MAXCOLORMAPSIZE],
    int *gray)
    int *gray)
{
{
    int i;
    int i;
    unsigned char rgb[3];
    unsigned char rgb[3];
    int flag;
    int flag;
 
 
    flag = TRUE;
    flag = TRUE;
 
 
    for (i = 0; i < number; ++i) {
    for (i = 0; i < number; ++i) {
        if (!ReadOK(src, rgb, sizeof(rgb)))
        if (!ReadOK(src, rgb, sizeof(rgb)))
            return 1;
            return 1;
        buffer[CM_RED][i] = rgb[0];
        buffer[CM_RED][i] = rgb[0];
        buffer[CM_GREEN][i] = rgb[1];
        buffer[CM_GREEN][i] = rgb[1];
        buffer[CM_BLUE][i] = rgb[2];
        buffer[CM_BLUE][i] = rgb[2];
        flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]);
        flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]);
    }
    }
 
 
#if 0
#if 0
    if (flag)
    if (flag)
        *gray = (number == 2) ? PBM_TYPE : PGM_TYPE;
        *gray = (number == 2) ? PBM_TYPE : PGM_TYPE;
    else
    else
        *gray = PPM_TYPE;
        *gray = PPM_TYPE;
#else
#else
    *gray = 0;
    *gray = 0;
#endif
#endif
 
 
    return FALSE;
    return FALSE;
}
}
 
 
static int
static int
DoExtension(buffer_t *src, int label)
DoExtension(buffer_t *src, int label)
{
{
    static unsigned char buf[256];
    static unsigned char buf[256];
 
 
    switch (label) {
    switch (label) {
    case 0x01:                  /* Plain Text Extension */
    case 0x01:                  /* Plain Text Extension */
        break;
        break;
    case 0xff:                  /* Application Extension */
    case 0xff:                  /* Application Extension */
        break;
        break;
    case 0xfe:                  /* Comment Extension */
    case 0xfe:                  /* Comment Extension */
        while (GetDataBlock(src, (unsigned char *) buf) != 0);
        while (GetDataBlock(src, (unsigned char *) buf) != 0);
        return FALSE;
        return FALSE;
    case 0xf9:                  /* Graphic Control Extension */
    case 0xf9:                  /* Graphic Control Extension */
        GetDataBlock(src, (unsigned char *) buf);
        GetDataBlock(src, (unsigned char *) buf);
        Gif89.disposal = (buf[0] >> 2) & 0x7;
        Gif89.disposal = (buf[0] >> 2) & 0x7;
        Gif89.inputFlag = (buf[0] >> 1) & 0x1;
        Gif89.inputFlag = (buf[0] >> 1) & 0x1;
        Gif89.delayTime = LM_to_uint(buf[1], buf[2]);
        Gif89.delayTime = LM_to_uint(buf[1], buf[2]);
        if ((buf[0] & 0x1) != 0)
        if ((buf[0] & 0x1) != 0)
            Gif89.transparent = buf[3];
            Gif89.transparent = buf[3];
 
 
        while (GetDataBlock(src, (unsigned char *) buf) != 0);
        while (GetDataBlock(src, (unsigned char *) buf) != 0);
        return FALSE;
        return FALSE;
    default:
    default:
        break;
        break;
    }
    }
 
 
    while (GetDataBlock(src, (unsigned char *) buf) != 0);
    while (GetDataBlock(src, (unsigned char *) buf) != 0);
 
 
    return FALSE;
    return FALSE;
}
}
 
 
static int ZeroDataBlock = FALSE;
static int ZeroDataBlock = FALSE;
 
 
static int
static int
GetDataBlock(buffer_t *src, unsigned char *buf)
GetDataBlock(buffer_t *src, unsigned char *buf)
{
{
    unsigned char count;
    unsigned char count;
 
 
    if (!ReadOK(src, &count, 1))
    if (!ReadOK(src, &count, 1))
        return -1;
        return -1;
    ZeroDataBlock = count == 0;
    ZeroDataBlock = count == 0;
 
 
    if ((count != 0) && (!ReadOK(src, buf, count)))
    if ((count != 0) && (!ReadOK(src, buf, count)))
        return -1;
        return -1;
    return count;
    return count;
}
}
 
 
static int
static int
GetCode(buffer_t *src, int code_size, int flag)
GetCode(buffer_t *src, int code_size, int flag)
{
{
    static unsigned char buf[280];
    static unsigned char buf[280];
    static int curbit, lastbit, done, last_byte;
    static int curbit, lastbit, done, last_byte;
    int i, j, ret;
    int i, j, ret;
    unsigned char count;
    unsigned char count;
 
 
    if (flag) {
    if (flag) {
        curbit = 0;
        curbit = 0;
        lastbit = 0;
        lastbit = 0;
        done = FALSE;
        done = FALSE;
        return 0;
        return 0;
    }
    }
    if ((curbit + code_size) >= lastbit) {
    if ((curbit + code_size) >= lastbit) {
        if (done) {
        if (done) {
            if (curbit >= lastbit)
            if (curbit >= lastbit)
                EPRINTF("LoadGIF: bad decode\n");
                EPRINTF("LoadGIF: bad decode\n");
            return -1;
            return -1;
        }
        }
        buf[0] = buf[last_byte - 2];
        buf[0] = buf[last_byte - 2];
        buf[1] = buf[last_byte - 1];
        buf[1] = buf[last_byte - 1];
 
 
        if ((count = GetDataBlock(src, &buf[2])) == 0)
        if ((count = GetDataBlock(src, &buf[2])) == 0)
            done = TRUE;
            done = TRUE;
 
 
        last_byte = 2 + count;
        last_byte = 2 + count;
        curbit = (curbit - lastbit) + 16;
        curbit = (curbit - lastbit) + 16;
        lastbit = (2 + count) * 8;
        lastbit = (2 + count) * 8;
    }
    }
    ret = 0;
    ret = 0;
    for (i = curbit, j = 0; j < code_size; ++i, ++j)
    for (i = curbit, j = 0; j < code_size; ++i, ++j)
        ret |= ((buf[i / 8] & (1 << (i % 8))) != 0) << j;
        ret |= ((buf[i / 8] & (1 << (i % 8))) != 0) << j;
 
 
    curbit += code_size;
    curbit += code_size;
 
 
    return ret;
    return ret;
}
}
 
 
static int
static int
LWZReadByte(buffer_t *src, int flag, int input_code_size)
LWZReadByte(buffer_t *src, int flag, int input_code_size)
{
{
    int code, incode;
    int code, incode;
    register int i;
    register int i;
    static int fresh = FALSE;
    static int fresh = FALSE;
    static int code_size, set_code_size;
    static int code_size, set_code_size;
    static int max_code, max_code_size;
    static int max_code, max_code_size;
    static int firstcode, oldcode;
    static int firstcode, oldcode;
    static int clear_code, end_code;
    static int clear_code, end_code;
    static int table[2][(1 << MAX_LWZ_BITS)];
    static int table[2][(1 << MAX_LWZ_BITS)];
    static int stack[(1 << (MAX_LWZ_BITS)) * 2], *sp;
    static int stack[(1 << (MAX_LWZ_BITS)) * 2], *sp;
 
 
    if (flag) {
    if (flag) {
        set_code_size = input_code_size;
        set_code_size = input_code_size;
        code_size = set_code_size + 1;
        code_size = set_code_size + 1;
        clear_code = 1 << set_code_size;
        clear_code = 1 << set_code_size;
        end_code = clear_code + 1;
        end_code = clear_code + 1;
        max_code_size = 2 * clear_code;
        max_code_size = 2 * clear_code;
        max_code = clear_code + 2;
        max_code = clear_code + 2;
 
 
        GetCode(src, 0, TRUE);
        GetCode(src, 0, TRUE);
 
 
        fresh = TRUE;
        fresh = TRUE;
 
 
        for (i = 0; i < clear_code; ++i) {
        for (i = 0; i < clear_code; ++i) {
            table[0][i] = 0;
            table[0][i] = 0;
            table[1][i] = i;
            table[1][i] = i;
        }
        }
        for (; i < (1 << MAX_LWZ_BITS); ++i)
        for (; i < (1 << MAX_LWZ_BITS); ++i)
            table[0][i] = table[1][0] = 0;
            table[0][i] = table[1][0] = 0;
 
 
        sp = stack;
        sp = stack;
 
 
        return 0;
        return 0;
    } else if (fresh) {
    } else if (fresh) {
        fresh = FALSE;
        fresh = FALSE;
        do {
        do {
            firstcode = oldcode = GetCode(src, code_size, FALSE);
            firstcode = oldcode = GetCode(src, code_size, FALSE);
        } while (firstcode == clear_code);
        } while (firstcode == clear_code);
        return firstcode;
        return firstcode;
    }
    }
    if (sp > stack)
    if (sp > stack)
        return *--sp;
        return *--sp;
 
 
    while ((code = GetCode(src, code_size, FALSE)) >= 0) {
    while ((code = GetCode(src, code_size, FALSE)) >= 0) {
        if (code == clear_code) {
        if (code == clear_code) {
            for (i = 0; i < clear_code; ++i) {
            for (i = 0; i < clear_code; ++i) {
                table[0][i] = 0;
                table[0][i] = 0;
                table[1][i] = i;
                table[1][i] = i;
            }
            }
            for (; i < (1 << MAX_LWZ_BITS); ++i)
            for (; i < (1 << MAX_LWZ_BITS); ++i)
                table[0][i] = table[1][i] = 0;
                table[0][i] = table[1][i] = 0;
            code_size = set_code_size + 1;
            code_size = set_code_size + 1;
            max_code_size = 2 * clear_code;
            max_code_size = 2 * clear_code;
            max_code = clear_code + 2;
            max_code = clear_code + 2;
            sp = stack;
            sp = stack;
            firstcode = oldcode = GetCode(src, code_size, FALSE);
            firstcode = oldcode = GetCode(src, code_size, FALSE);
            return firstcode;
            return firstcode;
        } else if (code == end_code) {
        } else if (code == end_code) {
            int count;
            int count;
            unsigned char buf[260];
            unsigned char buf[260];
 
 
            if (ZeroDataBlock)
            if (ZeroDataBlock)
                return -2;
                return -2;
 
 
            while ((count = GetDataBlock(src, buf)) > 0);
            while ((count = GetDataBlock(src, buf)) > 0);
 
 
            if (count != 0) {
            if (count != 0) {
                /*
                /*
                 * EPRINTF("missing EOD in data stream (common occurence)");
                 * EPRINTF("missing EOD in data stream (common occurence)");
                 */
                 */
            }
            }
            return -2;
            return -2;
        }
        }
        incode = code;
        incode = code;
 
 
        if (code >= max_code) {
        if (code >= max_code) {
            *sp++ = firstcode;
            *sp++ = firstcode;
            code = oldcode;
            code = oldcode;
        }
        }
        while (code >= clear_code) {
        while (code >= clear_code) {
            *sp++ = table[1][code];
            *sp++ = table[1][code];
            if (code == table[0][code])
            if (code == table[0][code])
                EPRINTF("LoadGIF: circular table entry\n");
                EPRINTF("LoadGIF: circular table entry\n");
            code = table[0][code];
            code = table[0][code];
        }
        }
 
 
        *sp++ = firstcode = table[1][code];
        *sp++ = firstcode = table[1][code];
 
 
        if ((code = max_code) < (1 << MAX_LWZ_BITS)) {
        if ((code = max_code) < (1 << MAX_LWZ_BITS)) {
            table[0][code] = oldcode;
            table[0][code] = oldcode;
            table[1][code] = firstcode;
            table[1][code] = firstcode;
            ++max_code;
            ++max_code;
            if ((max_code >= max_code_size) &&
            if ((max_code >= max_code_size) &&
                (max_code_size < (1 << MAX_LWZ_BITS))) {
                (max_code_size < (1 << MAX_LWZ_BITS))) {
                max_code_size *= 2;
                max_code_size *= 2;
                ++code_size;
                ++code_size;
            }
            }
        }
        }
        oldcode = incode;
        oldcode = incode;
 
 
        if (sp > stack)
        if (sp > stack)
            return *--sp;
            return *--sp;
    }
    }
    return code;
    return code;
}
}
 
 
static int
static int
ReadImage(buffer_t* src, PMWIMAGEHDR pimage, int len, int height, int cmapSize,
ReadImage(buffer_t* src, PMWIMAGEHDR pimage, int len, int height, int cmapSize,
          unsigned char cmap[3][MAXCOLORMAPSIZE],
          unsigned char cmap[3][MAXCOLORMAPSIZE],
          int gray, int interlace, int ignore)
          int gray, int interlace, int ignore)
{
{
    unsigned char c;
    unsigned char c;
    int i, v;
    int i, v;
    int xpos = 0, ypos = 0, pass = 0;
    int xpos = 0, ypos = 0, pass = 0;
 
 
    /*
    /*
     *  Initialize the compression routines
     *  Initialize the compression routines
     */
     */
    if (!ReadOK(src, &c, 1)) {
    if (!ReadOK(src, &c, 1)) {
        EPRINTF("LoadGIF: EOF on image data\n");
        EPRINTF("LoadGIF: EOF on image data\n");
        return 0;
        return 0;
    }
    }
    if (LWZReadByte(src, TRUE, c) < 0) {
    if (LWZReadByte(src, TRUE, c) < 0) {
        EPRINTF("LoadGIF: error reading image\n");
        EPRINTF("LoadGIF: error reading image\n");
        return 0;
        return 0;
    }
    }
 
 
    /*
    /*
     *  If this is an "uninteresting picture" ignore it.
     *  If this is an "uninteresting picture" ignore it.
     */
     */
    if (ignore) {
    if (ignore) {
        while (LWZReadByte(src, FALSE, c) >= 0);
        while (LWZReadByte(src, FALSE, c) >= 0);
        return 0;
        return 0;
    }
    }
    /*image = ImageNewCmap(len, height, cmapSize);*/
    /*image = ImageNewCmap(len, height, cmapSize);*/
    pimage->width = len;
    pimage->width = len;
    pimage->height = height;
    pimage->height = height;
    pimage->planes = 1;
    pimage->planes = 1;
    pimage->bpp = 8;
    pimage->bpp = 8;
    ComputePitch(8, len, &pimage->pitch, &pimage->bytesperpixel);
    ComputePitch(8, len, &pimage->pitch, &pimage->bytesperpixel);
    pimage->compression = 0;
    pimage->compression = 0;
    pimage->palsize = cmapSize;
    pimage->palsize = cmapSize;
    pimage->palette = malloc(256*sizeof(MWPALENTRY));
    pimage->palette = malloc(256*sizeof(MWPALENTRY));
    pimage->imagebits = malloc(height*pimage->pitch);
    pimage->imagebits = malloc(height*pimage->pitch);
    if(!pimage->imagebits || !pimage->palette)
    if(!pimage->imagebits || !pimage->palette)
            return 0;
            return 0;
 
 
    for (i = 0; i < cmapSize; i++) {
    for (i = 0; i < cmapSize; i++) {
        /*ImageSetCmap(image, i, cmap[CM_RED][i],
        /*ImageSetCmap(image, i, cmap[CM_RED][i],
                     cmap[CM_GREEN][i], cmap[CM_BLUE][i]);*/
                     cmap[CM_GREEN][i], cmap[CM_BLUE][i]);*/
        pimage->palette[i].r = cmap[CM_RED][i];
        pimage->palette[i].r = cmap[CM_RED][i];
        pimage->palette[i].g = cmap[CM_GREEN][i];
        pimage->palette[i].g = cmap[CM_GREEN][i];
        pimage->palette[i].b = cmap[CM_BLUE][i];
        pimage->palette[i].b = cmap[CM_BLUE][i];
    }
    }
 
 
    while ((v = LWZReadByte(src, FALSE, c)) >= 0) {
    while ((v = LWZReadByte(src, FALSE, c)) >= 0) {
        pimage->imagebits[ypos * pimage->pitch + xpos] = v;
        pimage->imagebits[ypos * pimage->pitch + xpos] = v;
 
 
        ++xpos;
        ++xpos;
        if (xpos == len) {
        if (xpos == len) {
            xpos = 0;
            xpos = 0;
            if (interlace) {
            if (interlace) {
                switch (pass) {
                switch (pass) {
                case 0:
                case 0:
                case 1:
                case 1:
                    ypos += 8;
                    ypos += 8;
                    break;
                    break;
                case 2:
                case 2:
                    ypos += 4;
                    ypos += 4;
                    break;
                    break;
                case 3:
                case 3:
                    ypos += 2;
                    ypos += 2;
                    break;
                    break;
                }
                }
 
 
                if (ypos >= height) {
                if (ypos >= height) {
                    ++pass;
                    ++pass;
                    switch (pass) {
                    switch (pass) {
                    case 1:
                    case 1:
                        ypos = 4;
                        ypos = 4;
                        break;
                        break;
                    case 2:
                    case 2:
                        ypos = 2;
                        ypos = 2;
                        break;
                        break;
                    case 3:
                    case 3:
                        ypos = 1;
                        ypos = 1;
                        break;
                        break;
                    default:
                    default:
                        goto fini;
                        goto fini;
                    }
                    }
                }
                }
            } else {
            } else {
                ++ypos;
                ++ypos;
            }
            }
        }
        }
        if (ypos >= height)
        if (ypos >= height)
            break;
            break;
    }
    }
 
 
fini:
fini:
    return 1;
    return 1;
}
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_GIF_SUPPORT)*/
#endif /* defined(HAVE_FILEIO) && defined(HAVE_GIF_SUPPORT)*/
 
 
#if defined(HAVE_FILEIO) && defined(HAVE_PNM_SUPPORT)
#if defined(HAVE_FILEIO) && defined(HAVE_PNM_SUPPORT)
enum {
enum {
        PNM_TYPE_NOTPNM,
        PNM_TYPE_NOTPNM,
        PNM_TYPE_PBM,
        PNM_TYPE_PBM,
        PNM_TYPE_PGM,
        PNM_TYPE_PGM,
        PNM_TYPE_PPM
        PNM_TYPE_PPM
};
};
static int LoadPNM(buffer_t *src, PMWIMAGEHDR pimage)
static int LoadPNM(buffer_t *src, PMWIMAGEHDR pimage)
{
{
        char buf[256], *p;
        char buf[256], *p;
        int type = PNM_TYPE_NOTPNM, binary = 0, gothdrs = 0, scale = 0;
        int type = PNM_TYPE_NOTPNM, binary = 0, gothdrs = 0, scale = 0;
        int ch, x = 0, y = 0, i, n, mask, col1, col2, col3;
        int ch, x = 0, y = 0, i, n, mask, col1, col2, col3;
 
 
        bseek(src, 0L, 0);
        bseek(src, 0L, 0);
 
 
        if(!bgets(src,buf, 4)) return 0;
        if(!bgets(src,buf, 4)) return 0;
 
 
        if(!strcmp("P1\n", buf)) type = PNM_TYPE_PBM;
        if(!strcmp("P1\n", buf)) type = PNM_TYPE_PBM;
        else if(!strcmp("P2\n", buf)) type = PNM_TYPE_PGM;
        else if(!strcmp("P2\n", buf)) type = PNM_TYPE_PGM;
        else if(!strcmp("P3\n", buf)) type = PNM_TYPE_PPM;
        else if(!strcmp("P3\n", buf)) type = PNM_TYPE_PPM;
        else if(!strcmp("P4\n", buf)) {
        else if(!strcmp("P4\n", buf)) {
                type = PNM_TYPE_PBM;
                type = PNM_TYPE_PBM;
                binary = 1;
                binary = 1;
        }
        }
        else if(!strcmp("P5\n", buf)) {
        else if(!strcmp("P5\n", buf)) {
                type = PNM_TYPE_PGM;
                type = PNM_TYPE_PGM;
                binary = 1;
                binary = 1;
        }
        }
        else if(!strcmp("P6\n", buf)) {
        else if(!strcmp("P6\n", buf)) {
                type = PNM_TYPE_PPM;
                type = PNM_TYPE_PPM;
                binary = 1;
                binary = 1;
        }
        }
 
 
        if(type == PNM_TYPE_NOTPNM) return 0;
        if(type == PNM_TYPE_NOTPNM) return 0;
 
 
        n = 0;
        n = 0;
        while((p = bgets(src, buf, 256))) {
        while((p = bgets(src, buf, 256))) {
                if(*buf == '#') continue;
                if(*buf == '#') continue;
                if(type == PNM_TYPE_PBM) {
                if(type == PNM_TYPE_PBM) {
                        if(sscanf(buf, "%i %i", &pimage->width,
                        if(sscanf(buf, "%i %i", &pimage->width,
                                        &pimage->height) == 2) {
                                        &pimage->height) == 2) {
                                pimage->bpp = 1;
                                pimage->bpp = 1;
                                gothdrs = 1;
                                gothdrs = 1;
                                if(!(pimage->palette = malloc(
                                if(!(pimage->palette = malloc(
                                                sizeof(MWPALENTRY) * 2))) {
                                                sizeof(MWPALENTRY) * 2))) {
                                        EPRINTF("Out of memory\n");
                                        EPRINTF("Out of memory\n");
                                        return 2;
                                        return 2;
                                }
                                }
                                pimage->palsize = 2;
                                pimage->palsize = 2;
                                pimage->palette[0].r = 0xff;
                                pimage->palette[0].r = 0xff;
                                pimage->palette[0].g = 0xff;
                                pimage->palette[0].g = 0xff;
                                pimage->palette[0].b = 0xff;
                                pimage->palette[0].b = 0xff;
                                pimage->palette[1].r = 0;
                                pimage->palette[1].r = 0;
                                pimage->palette[1].g = 0;
                                pimage->palette[1].g = 0;
                                pimage->palette[1].b = 0;
                                pimage->palette[1].b = 0;
                        }
                        }
                        break;
                        break;
                }
                }
                if((type == PNM_TYPE_PGM) || (type == PNM_TYPE_PPM)) {
                if((type == PNM_TYPE_PGM) || (type == PNM_TYPE_PPM)) {
                        if(!n++) {
                        if(!n++) {
                                if(sscanf(buf, "%i %i", &pimage->width,
                                if(sscanf(buf, "%i %i", &pimage->width,
                                        &pimage->height) != 2) break;
                                        &pimage->height) != 2) break;
                        } else {
                        } else {
                                if(sscanf(buf, "%i", &i) != 1) break;
                                if(sscanf(buf, "%i", &i) != 1) break;
                                pimage->bpp = 24;
                                pimage->bpp = 24;
                                if(i > 255) {
                                if(i > 255) {
                                        EPRINTF("LoadPNM: PPM files must be "
                                        EPRINTF("LoadPNM: PPM files must be "
                                                "24bpp\n");
                                                "24bpp\n");
                                        return 2;
                                        return 2;
                                }
                                }
                                for(scale = 7, n = 2; scale; scale--, n *= 2)
                                for(scale = 7, n = 2; scale; scale--, n *= 2)
                                        if(i < n) break;
                                        if(i < n) break;
                                gothdrs = 1;
                                gothdrs = 1;
                                break;
                                break;
                        }
                        }
                }
                }
        }
        }
 
 
        if(!gothdrs) {
        if(!gothdrs) {
                EPRINTF("LoadPNM: bad image headers\n");
                EPRINTF("LoadPNM: bad image headers\n");
                if(pimage->palette) free(pimage->palette);
                if(pimage->palette) free(pimage->palette);
                return 2;
                return 2;
        }
        }
 
 
        pimage->planes = 1;
        pimage->planes = 1;
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
        ComputePitch(pimage->bpp, pimage->width, &pimage->pitch,
                                                &pimage->bytesperpixel);
                                                &pimage->bytesperpixel);
        pimage->compression = MWIMAGE_RGB;
        pimage->compression = MWIMAGE_RGB;
        if(!(pimage->imagebits = malloc(pimage->pitch * pimage->height))) {
        if(!(pimage->imagebits = malloc(pimage->pitch * pimage->height))) {
                EPRINTF("LoadPNM: couldn't allocate memory for image\n");
                EPRINTF("LoadPNM: couldn't allocate memory for image\n");
                if(pimage->palette) free(pimage->palette);
                if(pimage->palette) free(pimage->palette);
                return 2;
                return 2;
        }
        }
 
 
        p = pimage->imagebits;
        p = pimage->imagebits;
 
 
        if(type == PNM_TYPE_PBM) {
        if(type == PNM_TYPE_PBM) {
                if(binary) {
                if(binary) {
                        x = 0;
                        x = 0;
                        y = 0;
                        y = 0;
                        while((ch = bgetc(src)) != EOF) {
                        while((ch = bgetc(src)) != EOF) {
                                for(i = 0; i < 8; i++) {
                                for(i = 0; i < 8; i++) {
                                        mask = 0x80 >> i;
                                        mask = 0x80 >> i;
                                        if(ch & mask) *p |= mask;
                                        if(ch & mask) *p |= mask;
                                        else *p &= ~mask;
                                        else *p &= ~mask;
                                        if(++x == pimage->width) {
                                        if(++x == pimage->width) {
                                                if(++y == pimage->height)
                                                if(++y == pimage->height)
                                                        return 1;
                                                        return 1;
                                                p = pimage->imagebits - 1 +
                                                p = pimage->imagebits - 1 +
                                                        (y * pimage->pitch);
                                                        (y * pimage->pitch);
                                                x = 0;
                                                x = 0;
                                                break;
                                                break;
                                        }
                                        }
                                }
                                }
                                p++;
                                p++;
                        }
                        }
                } else {
                } else {
                        n = 0;
                        n = 0;
                        while((ch = bgetc(src)) != EOF) {
                        while((ch = bgetc(src)) != EOF) {
                                if(isspace(ch)) continue;
                                if(isspace(ch)) continue;
                                mask = 0x80 >> n;
                                mask = 0x80 >> n;
                                if(ch == '1') *p |= mask;
                                if(ch == '1') *p |= mask;
                                else if(ch == '0') *p &= ~mask;
                                else if(ch == '0') *p &= ~mask;
                                else goto baddata;
                                else goto baddata;
                                if(++n == 8) {
                                if(++n == 8) {
                                        n = 0;
                                        n = 0;
                                        p++;
                                        p++;
                                }
                                }
                                if(++x == pimage->width) {
                                if(++x == pimage->width) {
                                        if(++y == pimage->height)
                                        if(++y == pimage->height)
                                                return 1;
                                                return 1;
                                        p = pimage->imagebits +
                                        p = pimage->imagebits +
                                                (y * pimage->pitch);
                                                (y * pimage->pitch);
                                        n = 0;
                                        n = 0;
                                        x = 0;
                                        x = 0;
                                }
                                }
                        }
                        }
                }
                }
        } else {
        } else {
                while(1) {
                while(1) {
                        if(type == PNM_TYPE_PGM) {
                        if(type == PNM_TYPE_PGM) {
                                if(binary) {
                                if(binary) {
                                        if((ch = bgetc(src)) == EOF)
                                        if((ch = bgetc(src)) == EOF)
                                                goto baddata;
                                                goto baddata;
                                } else {
                                } else {
                                  //                                    if(fscanf(fp, "%i", &ch) != 1)
                                  //                                    if(fscanf(fp, "%i", &ch) != 1)
                                                goto baddata;
                                                goto baddata;
                                }
                                }
                                *p++ = ch << scale;
                                *p++ = ch << scale;
                                *p++ = ch << scale;
                                *p++ = ch << scale;
                                *p++ = ch << scale;
                                *p++ = ch << scale;
                        } else {
                        } else {
                                if(binary) {
                                if(binary) {
                                        if(((col1 = bgetc(src)) == EOF) ||
                                        if(((col1 = bgetc(src)) == EOF) ||
                                                ((col2 = bgetc(src)) == EOF) ||
                                                ((col2 = bgetc(src)) == EOF) ||
                                                ((col3 = bgetc(src)) == EOF))
                                                ((col3 = bgetc(src)) == EOF))
                                                goto baddata;
                                                goto baddata;
                                } else {
                                } else {
                                  //                                    if(fscanf(fp, "%i %i %i", &col1, &col2,
                                  //                                    if(fscanf(fp, "%i %i %i", &col1, &col2,
                                  //                                                            &col3) != 3)
                                  //                                                            &col3) != 3)
                                                goto baddata;
                                                goto baddata;
                                }
                                }
                                *p++ = col1 << scale;
                                *p++ = col1 << scale;
                                *p++ = col2 << scale;
                                *p++ = col2 << scale;
                                *p++ = col3 << scale;
                                *p++ = col3 << scale;
                        }
                        }
                        if(++x == pimage->width) {
                        if(++x == pimage->width) {
                                if(++y == pimage->height) return 1;
                                if(++y == pimage->height) return 1;
                                p = pimage->imagebits + (y * pimage->pitch);
                                p = pimage->imagebits + (y * pimage->pitch);
                                x = 0;
                                x = 0;
                        }
                        }
                }
                }
        }
        }
 
 
baddata:
baddata:
        EPRINTF("LoadPNM: bad image data\n");
        EPRINTF("LoadPNM: bad image data\n");
        free(pimage->imagebits);
        free(pimage->imagebits);
        if(pimage->palette) free(pimage->palette);
        if(pimage->palette) free(pimage->palette);
        return 2;
        return 2;
}
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_PNM_SUPPORT) */
#endif /* defined(HAVE_FILEIO) && defined(HAVE_PNM_SUPPORT) */
 
 
#if defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)
#if defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)
struct xpm_cmap {
struct xpm_cmap {
  char mapstr[3];
  char mapstr[3];
  long palette_entry;
  long palette_entry;
  long color;
  long color;
  struct xpm_cmap *next;
  struct xpm_cmap *next;
};
};
 
 
 
 
static long XPM_parse_color(char *color)
static long XPM_parse_color(char *color)
{
{
  /* This will parse the string into a color value of some sort */
  /* This will parse the string into a color value of some sort */
 
 
  if (color[0] != '#')
  if (color[0] != '#')
    {
    {
      if (!strcmp(color, "None"))
      if (!strcmp(color, "None"))
        return(-1); /* Transparent */
        return(-1); /* Transparent */
      else
      else
        return(0); /* If its an X color, then we bail */
        return(0); /* If its an X color, then we bail */
    }
    }
  else
  else
    {
    {
      /* This is ugly! */
      /* This is ugly! */
 
 
      char *sptr = color + 1;
      char *sptr = color + 1;
      char rstr[5], gstr[5], bstr[5];
      char rstr[5], gstr[5], bstr[5];
      long r,g,b;
      long r,g,b;
 
 
      switch(strlen(sptr))
      switch(strlen(sptr))
        {
        {
        case 6:
        case 6:
          return(strtol(sptr, NULL, 16));
          return(strtol(sptr, NULL, 16));
 
 
        case 9: /* RRRGGGBBB */
        case 9: /* RRRGGGBBB */
          strncpy(rstr, sptr, 3);
          strncpy(rstr, sptr, 3);
          strncpy(gstr, sptr + 3, 3);
          strncpy(gstr, sptr + 3, 3);
          strncpy(bstr, sptr + 6, 3);
          strncpy(bstr, sptr + 6, 3);
 
 
          rstr[3] = 0;
          rstr[3] = 0;
          gstr[3] = 0;
          gstr[3] = 0;
          bstr[3] = 0;
          bstr[3] = 0;
 
 
          r = strtol(rstr, NULL, 16) >> 4;
          r = strtol(rstr, NULL, 16) >> 4;
          g = strtol(gstr, NULL, 16) >> 4;
          g = strtol(gstr, NULL, 16) >> 4;
          b = strtol(bstr, NULL, 16) >> 4;
          b = strtol(bstr, NULL, 16) >> 4;
 
 
          return( (long) ( r << 16 | g << 8 | b));
          return( (long) ( r << 16 | g << 8 | b));
 
 
        case 12:
        case 12:
          strncpy(rstr, sptr, 4);
          strncpy(rstr, sptr, 4);
          strncpy(gstr, sptr + 4, 4);
          strncpy(gstr, sptr + 4, 4);
          strncpy(bstr, sptr + 8, 4);
          strncpy(bstr, sptr + 8, 4);
 
 
          rstr[4] = 0;
          rstr[4] = 0;
          gstr[4] = 0;
          gstr[4] = 0;
          bstr[4] = 0;
          bstr[4] = 0;
 
 
          r = strtol(rstr, NULL, 16) >> 8;
          r = strtol(rstr, NULL, 16) >> 8;
          g = strtol(gstr, NULL, 16) >> 8;
          g = strtol(gstr, NULL, 16) >> 8;
          b = strtol(bstr, NULL, 16) >> 8;
          b = strtol(bstr, NULL, 16) >> 8;
 
 
          return( (long) ( (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)));
          return( (long) ( (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF)));
        }
        }
    }
    }
 
 
  return(0);
  return(0);
}
}
 
 
/* A series of status indicators that let us know whats going on */
/* A series of status indicators that let us know whats going on */
/* It could be an enum if you want */
/* It could be an enum if you want */
 
 
#define LOAD_HEADER 1
#define LOAD_HEADER 1
#define LOAD_COLORS 2
#define LOAD_COLORS 2
#define LOAD_PALETTE 3
#define LOAD_PALETTE 3
#define LOAD_PIXELS 4
#define LOAD_PIXELS 4
#define LOAD_DONE 5
#define LOAD_DONE 5
 
 
/* The magic that "should" indicate an XPM (does it really?) */
/* The magic that "should" indicate an XPM (does it really?) */
#define XPM_MAGIC "/* XPM */"
#define XPM_MAGIC "/* XPM */"
#define XPM_TRANSCOLOR 0x01000000
#define XPM_TRANSCOLOR 0x01000000
 
 
static int LoadXPM(buffer_t *src, PMWIMAGEHDR pimage, PSD psd)
static int LoadXPM(buffer_t *src, PMWIMAGEHDR pimage, PSD psd)
{
{
  struct xpm_cmap *colorheap = 0;  /* A "heap" of color structs */
  struct xpm_cmap *colorheap = 0;  /* A "heap" of color structs */
  struct xpm_cmap *colormap[256];  /* A quick hash of 256 spots for colors */
  struct xpm_cmap *colormap[256];  /* A quick hash of 256 spots for colors */
 
 
  unsigned char *imageptr = 0;
  unsigned char *imageptr = 0;
 
 
  MWSCREENINFO sinfo;
  MWSCREENINFO sinfo;
 
 
  char xline[300];
  char xline[300];
  char dline[300];
  char dline[300];
 
 
  char *c;
  char *c;
  int a;
  int a;
 
 
  int col, row, colors, cpp;
  int col, row, colors, cpp;
  int in_color = 0;
  int in_color = 0;
  int read_xline = 0;
  int read_xline = 0;
 
 
  int status = LOAD_HEADER;
  int status = LOAD_HEADER;
 
 
  /* Very first thing, get the screen info */
  /* Very first thing, get the screen info */
  GdGetScreenInfo(psd, &sinfo);
  GdGetScreenInfo(psd, &sinfo);
 
 
  for(a = 0; a < 256; a++)
  for(a = 0; a < 256; a++)
    colormap[a] = 0;
    colormap[a] = 0;
 
 
  pimage->imagebits = NULL;
  pimage->imagebits = NULL;
  pimage->palette = NULL;
  pimage->palette = NULL;
 
 
  /* Start over at the beginning with the file */
  /* Start over at the beginning with the file */
  bseek(src, 0, SEEK_SET);
  bseek(src, 0, SEEK_SET);
 
 
  bgets(src, xline, 300);
  bgets(src, xline, 300);
 
 
  /* Chop the EOL */
  /* Chop the EOL */
  xline[strlen(xline) - 1] = 0;
  xline[strlen(xline) - 1] = 0;
 
 
  /* Check the magic */
  /* Check the magic */
  if (strncmp(xline, XPM_MAGIC, sizeof(XPM_MAGIC))) return(0);
  if (strncmp(xline, XPM_MAGIC, sizeof(XPM_MAGIC))) return(0);
 
 
  while(!beof(src))
  while(!beof(src))
    {
    {
      /* Get the next line from the file */
      /* Get the next line from the file */
      bgets(src,xline, 300);
      bgets(src,xline, 300);
      xline[strlen(xline) - 1] = 0;
      xline[strlen(xline) - 1] = 0;
 
 
      /* Check it out */
      /* Check it out */
      if (xline[0] == '/' && xline[1] == '*') /* Comment */
      if (xline[0] == '/' && xline[1] == '*') /* Comment */
        continue;
        continue;
 
 
      if (xline[0] != '\"')
      if (xline[0] != '\"')
        continue;
        continue;
 
 
      /* remove the quotes from the line */
      /* remove the quotes from the line */
      for(c = xline + 1, a = 0; *c != '\"' && *c != 0; c++, a++)
      for(c = xline + 1, a = 0; *c != '\"' && *c != 0; c++, a++)
        dline[a] = *c;
        dline[a] = *c;
 
 
      dline[a] = 0;
      dline[a] = 0;
 
 
      /* Is it the header? */
      /* Is it the header? */
      if (status == LOAD_HEADER)
      if (status == LOAD_HEADER)
        {
        {
          sscanf(dline, "%i %i %i %i", &col, &row, &colors, &cpp);
          sscanf(dline, "%i %i %i %i", &col, &row, &colors, &cpp);
 
 
          pimage->width = col;
          pimage->width = col;
          pimage->height = row;
          pimage->height = row;
          pimage->planes = 1;
          pimage->planes = 1;
 
 
          if (sinfo.bpp <= 8)
          if (sinfo.bpp <= 8)
            {
            {
              pimage->bpp = sinfo.bpp;
              pimage->bpp = sinfo.bpp;
              pimage->compression = 0;
              pimage->compression = 0;
              pimage->transcolor = -1;
              pimage->transcolor = -1;
            }
            }
          else
          else
            {
            {
              pimage->bpp = 32;
              pimage->bpp = 32;
              pimage->transcolor = XPM_TRANSCOLOR;
              pimage->transcolor = XPM_TRANSCOLOR;
              pimage->compression = MWIMAGE_BGR;
              pimage->compression = MWIMAGE_BGR;
            }
            }
 
 
          pimage->palsize = colors;
          pimage->palsize = colors;
 
 
          ComputePitch(pimage->bpp, col, &pimage->pitch, &pimage->bytesperpixel);
          ComputePitch(pimage->bpp, col, &pimage->pitch, &pimage->bytesperpixel);
 
 
          pimage->imagebits = malloc(pimage->pitch * pimage->height);
          pimage->imagebits = malloc(pimage->pitch * pimage->height);
          imageptr = (unsigned char *) pimage->imagebits;
          imageptr = (unsigned char *) pimage->imagebits;
 
 
          /* Allocate enough room for all the colors */
          /* Allocate enough room for all the colors */
          colorheap = (struct xpm_cmap *) malloc(colors * sizeof(struct xpm_cmap));
          colorheap = (struct xpm_cmap *) malloc(colors * sizeof(struct xpm_cmap));
 
 
          /* Allocate the palette space (if required) */
          /* Allocate the palette space (if required) */
 
 
          if (sinfo.bpp <= 8)
          if (sinfo.bpp <= 8)
              pimage->palette = malloc(256*sizeof(MWPALENTRY));
              pimage->palette = malloc(256*sizeof(MWPALENTRY));
 
 
          if (!colorheap)
          if (!colorheap)
            {
            {
              EPRINTF("Couldn't allocate any memory for the colors\n");
              EPRINTF("Couldn't allocate any memory for the colors\n");
              return(0);
              return(0);
            }
            }
 
 
          status = LOAD_COLORS;
          status = LOAD_COLORS;
          in_color = 0;
          in_color = 0;
          continue;
          continue;
        }
        }
 
 
      /* Are we in load colors? */
      /* Are we in load colors? */
      if (status == LOAD_COLORS)
      if (status == LOAD_COLORS)
        {
        {
          struct xpm_cmap *n;
          struct xpm_cmap *n;
 
 
          char tstr[5];
          char tstr[5];
          char cstr[256];
          char cstr[256];
 
 
          unsigned char m;
          unsigned char m;
 
 
          c = dline;
          c = dline;
 
 
          /* Go at at least 1 charater, and then count until we have
          /* Go at at least 1 charater, and then count until we have
             two spaces in a row */
             two spaces in a row */
 
 
          strncpy(tstr, c, cpp);
          strncpy(tstr, c, cpp);
 
 
          c += cpp;
          c += cpp;
          for(; *c == '\t' || *c == ' '; c++); /* Skip over whitespace */
          for(; *c == '\t' || *c == ' '; c++); /* Skip over whitespace */
 
 
          /* FIXME: We assume that a 'c' follows.  What if it doesn't? */
          /* FIXME: We assume that a 'c' follows.  What if it doesn't? */
          c +=2;
          c +=2;
 
 
          tstr[cpp] = 0;
          tstr[cpp] = 0;
 
 
          /* Now we put it into the array for easy lookup   */
          /* Now we put it into the array for easy lookup   */
          /* We base it off the first charater, even though */
          /* We base it off the first charater, even though */
          /* there may be up to 4                           */
          /* there may be up to 4                           */
 
 
          m = tstr[0];
          m = tstr[0];
 
 
          if (colormap[m])
          if (colormap[m])
            {
            {
              n = colormap[m];
              n = colormap[m];
 
 
              while(n->next) n = n->next;
              while(n->next) n = n->next;
              n->next = &colorheap[in_color];
              n->next = &colorheap[in_color];
              n = n->next;
              n = n->next;
            }
            }
          else
          else
            {
            {
              colormap[m] = &colorheap[in_color];
              colormap[m] = &colorheap[in_color];
              n = colormap[m];
              n = colormap[m];
            }
            }
 
 
          n->next = 0;
          n->next = 0;
 
 
          /* Record the string */
          /* Record the string */
          strncpy(n->mapstr, tstr, cpp);
          strncpy(n->mapstr, tstr, cpp);
          n->mapstr[cpp] = 0;
          n->mapstr[cpp] = 0;
 
 
          /* Now record the palette entry */
          /* Now record the palette entry */
          n->palette_entry = (long) in_color;
          n->palette_entry = (long) in_color;
 
 
          /* This is the color */
          /* This is the color */
          sscanf(c, "%65535s", cstr);
          sscanf(c, "%65535s", cstr);
 
 
          /* Turn it into a real value */
          /* Turn it into a real value */
          n->color = XPM_parse_color(cstr);
          n->color = XPM_parse_color(cstr);
 
 
          /* If we are in palette mode, then we need to */
          /* If we are in palette mode, then we need to */
          /* load the palette (duh..) */
          /* load the palette (duh..) */
 
 
          if (sinfo.bpp <= 8)
          if (sinfo.bpp <= 8)
            {
            {
              if (n->color == -1)
              if (n->color == -1)
                {
                {
                  pimage->transcolor = in_color;
                  pimage->transcolor = in_color;
                  n->color = -1;
                  n->color = -1;
                }
                }
 
 
              pimage->palette[in_color].r = (n->color >> 16) & 0xFF;
              pimage->palette[in_color].r = (n->color >> 16) & 0xFF;
              pimage->palette[in_color].g = (n->color >> 8) & 0xFF;
              pimage->palette[in_color].g = (n->color >> 8) & 0xFF;
              pimage->palette[in_color].b = n->color & 0xFF;
              pimage->palette[in_color].b = n->color & 0xFF;
            }
            }
          else
          else
            {
            {
              if (n->color == -1)
              if (n->color == -1)
                n->color = XPM_TRANSCOLOR;
                n->color = XPM_TRANSCOLOR;
            }
            }
 
 
          if (++in_color == colors)
          if (++in_color == colors)
            {
            {
              read_xline = 0;
              read_xline = 0;
              status = LOAD_PIXELS;
              status = LOAD_PIXELS;
            }
            }
 
 
          continue;
          continue;
        }
        }
 
 
      if (status == LOAD_PIXELS)
      if (status == LOAD_PIXELS)
      {
      {
        int bytecount = 0;
        int bytecount = 0;
        int bitcount = 0;
        int bitcount = 0;
        long dwordcolor = 0;
        long dwordcolor = 0;
        int i;
        int i;
        char pxlstr[3];
        char pxlstr[3];
 
 
        c = dline;
        c = dline;
 
 
        while(*c)
        while(*c)
          {
          {
            unsigned char z = 0;
            unsigned char z = 0;
 
 
            if (cpp == 1)
            if (cpp == 1)
              {
              {
                z = *c;
                z = *c;
 
 
                if (!colormap[z])
                if (!colormap[z])
                  {
                  {
                    EPRINTF("No color entry for (%c)\n", z);
                    EPRINTF("No color entry for (%c)\n", z);
                    return(0);
                    return(0);
                  }
                  }
 
 
                if (sinfo.bpp <= 8)
                if (sinfo.bpp <= 8)
                  dwordcolor = (long) colormap[z]->palette_entry;
                  dwordcolor = (long) colormap[z]->palette_entry;
                else
                else
                  dwordcolor = colormap[z]->color;
                  dwordcolor = colormap[z]->color;
 
 
                c++;
                c++;
              }
              }
            else
            else
              {
              {
                struct xpm_cmap *n;
                struct xpm_cmap *n;
 
 
                /* We grab the largest possible, and then compare */
                /* We grab the largest possible, and then compare */
 
 
                strncpy(pxlstr, c, cpp);
                strncpy(pxlstr, c, cpp);
                z = pxlstr[0];
                z = pxlstr[0];
 
 
                if (!colormap[z])
                if (!colormap[z])
                  {
                  {
                    EPRINTF("No color entry for (%s)\n", pxlstr);
                    EPRINTF("No color entry for (%s)\n", pxlstr);
                    return(0);
                    return(0);
                  }
                  }
 
 
                n = colormap[z];
                n = colormap[z];
 
 
                while(n)
                while(n)
                  {
                  {
                    if (!strncmp(n->mapstr, pxlstr, cpp))
                    if (!strncmp(n->mapstr, pxlstr, cpp))
                      break;
                      break;
 
 
                    n = n->next;
                    n = n->next;
                  }
                  }
 
 
                if (!n)
                if (!n)
                  {
                  {
                    EPRINTF("No color found for (%s)\n", pxlstr);
                    EPRINTF("No color found for (%s)\n", pxlstr);
                    return(0);
                    return(0);
                  }
                  }
 
 
                if (sinfo.bpp <= 8)
                if (sinfo.bpp <= 8)
                  dwordcolor = (long) n->palette_entry;
                  dwordcolor = (long) n->palette_entry;
                else
                else
                  dwordcolor = n->color;
                  dwordcolor = n->color;
 
 
                c += cpp;
                c += cpp;
              }
              }
 
 
            /*
            /*
             * This ugly thing is needed to ensure that we
             * This ugly thing is needed to ensure that we
             * work well in all modes.
             * work well in all modes.
             */
             */
            switch(sinfo.bpp)
            switch(sinfo.bpp)
              {
              {
              case 2:
              case 2:
                if (bitcount == 0)
                if (bitcount == 0)
                  imageptr[0] = 0;
                  imageptr[0] = 0;
 
 
                imageptr[0] |= (dwordcolor & 0x3) << (4 - bitcount);
                imageptr[0] |= (dwordcolor & 0x3) << (4 - bitcount);
                bitcount++;
                bitcount++;
 
 
                if (bitcount == 4)
                if (bitcount == 4)
                  {
                  {
                    imageptr++;
                    imageptr++;
                    bytecount += pimage->bytesperpixel;
                    bytecount += pimage->bytesperpixel;
                    bitcount = 0;
                    bitcount = 0;
                  }
                  }
 
 
                break;
                break;
 
 
              case 4:
              case 4:
                if (bitcount == 0)
                if (bitcount == 0)
                  imageptr[0] = 0;
                  imageptr[0] = 0;
 
 
                imageptr[0] |= (dwordcolor & 0xF) << (2 - bitcount);
                imageptr[0] |= (dwordcolor & 0xF) << (2 - bitcount);
                bitcount++;
                bitcount++;
 
 
                if (bitcount == 2)
                if (bitcount == 2)
                  {
                  {
                    imageptr++;
                    imageptr++;
                    bytecount += pimage->bytesperpixel;
                    bytecount += pimage->bytesperpixel;
                    bitcount = 0;
                    bitcount = 0;
                  }
                  }
 
 
                break;
                break;
 
 
              case 8:
              case 8:
              case 16:
              case 16:
              case 24:
              case 24:
              case 32:
              case 32:
 
 
                for(i = 0; i < pimage->bytesperpixel; i++)
                for(i = 0; i < pimage->bytesperpixel; i++)
                  imageptr[i] = (dwordcolor >> (8 * i)) & 0xFF;
                  imageptr[i] = (dwordcolor >> (8 * i)) & 0xFF;
 
 
                imageptr += pimage->bytesperpixel;
                imageptr += pimage->bytesperpixel;
                bytecount += pimage->bytesperpixel;
                bytecount += pimage->bytesperpixel;
                break;
                break;
 
 
#ifdef NOTUSED
#ifdef NOTUSED
              case 8:
              case 8:
                imageptr[0] = (unsigned char) (dwordcolor & 0xFF);
                imageptr[0] = (unsigned char) (dwordcolor & 0xFF);
                imageptr += pimage->bytesperpixel;
                imageptr += pimage->bytesperpixel;
                bytecount += pimage->bytesperpixel;
                bytecount += pimage->bytesperpixel;
                break;
                break;
 
 
              case 16:
              case 16:
              case 24:
              case 24:
              case 32:
              case 32:
                imageptr[0] = (unsigned char) (dwordcolor >> 24) & 0xFF;
                imageptr[0] = (unsigned char) (dwordcolor >> 24) & 0xFF;
                imageptr[1] = (unsigned char) (dwordcolor >> 16) & 0xFF;
                imageptr[1] = (unsigned char) (dwordcolor >> 16) & 0xFF;
                imageptr[2] = (unsigned char) (dwordcolor >> 8) & 0xFF;
                imageptr[2] = (unsigned char) (dwordcolor >> 8) & 0xFF;
                imageptr[3] = (unsigned char) (dwordcolor & 0xFF);
                imageptr[3] = (unsigned char) (dwordcolor & 0xFF);
                imageptr += pimage->bytesperpixel;
                imageptr += pimage->bytesperpixel;
                bytecount += pimage->bytesperpixel;
                bytecount += pimage->bytesperpixel;
                break;
                break;
#endif
#endif
              }
              }
          }
          }
 
 
        /* Pad to the end of the line */
        /* Pad to the end of the line */
        if (bytecount < pimage->pitch)
        if (bytecount < pimage->pitch)
          for(i = 0; i < (pimage->pitch - bytecount); i++)
          for(i = 0; i < (pimage->pitch - bytecount); i++)
            *imageptr++ = 0x00;
            *imageptr++ = 0x00;
 
 
        read_xline++;
        read_xline++;
 
 
        if (read_xline == row)
        if (read_xline == row)
          status = LOAD_DONE;
          status = LOAD_DONE;
 
 
        continue;
        continue;
      }
      }
    }
    }
 
 
  free(colorheap);
  free(colorheap);
 
 
  if (status != LOAD_DONE)
  if (status != LOAD_DONE)
    return(-1);
    return(-1);
  return(1);
  return(1);
}
}
#endif /* defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)*/
#endif /* defined(HAVE_FILEIO) && defined(HAVE_XPM_SUPPORT)*/
 
 
#endif /* defined(HAVE_FILEIO)*/
#endif /* defined(HAVE_FILEIO)*/
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.