/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * Copyright by the Board of Trustees of the University of Illinois.         *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the COPYING file, which can be found at the root of the source code       *
 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*
 *  Title:       GIF.H
 *  Purpose:     GIF Header file
 */
#ifndef GIF_H_
#define GIF_H_   1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "hdf5.h"

#define MAX_PAL 768

/* typedef H5T_NATIVE_UINT8  GIFBYTE; */
typedef unsigned char GIFBYTE;

/* typedef H5T_NATIVE_UINT16  GIFWORD; */
typedef unsigned long GIFWORD;

typedef char GIFCHAR;

#ifndef boolean
typedef unsigned char boolean;
#endif

#ifndef false
#define false       0
#endif
#ifndef true
#define true        1
#endif

/* Set the EndianOrder.
** The GIF Reader file should do this.
** Set EndianOrder = 0 if machine is little endian
**     EndianOrder = 1 if machine is big endian.
*/
extern int  EndianOrder;

/*
**  The GIF header format.
**
**  This structure actually contains the header, logical screen
**  descriptor, and the global color table for the GIF image.
*/
typedef struct _GifHeader { /* Offset   Description                         */
    GIFBYTE PackedField;       /*  0Ah     Color Information                   */
    GIFWORD TableSize;
    GIFBYTE ImageCount;        /* Keep a count of the number of images         */
    GIFBYTE CommentCount;
    GIFBYTE ApplicationCount;
    GIFBYTE PlainTextCount;
    GIFBYTE HDFPalette[256][3];
    GIFBYTE HeaderDump[6];     /* GIFBYTE array to dump header contents           */
    GIFBYTE LSDDump[7];        /* Logical Screen Descriptor dump               */
} GIFHEAD;


/*
**  The GIF Image Descriptor.
*/
typedef struct _GifImageDescriptor {
    GIFWORD ImageWidth;            /* Width of the image in pixels             */
    GIFWORD ImageHeight;           /* Height of the image in pixels            */
    GIFBYTE PackedField;           /* Image and Color Table Data Information   */
    GIFWORD TableSize;
    GIFWORD CodeSize;              /* Minimum LZW CodeSize for image data      */
    GIFBYTE HDFPalette[256][3];
    GIFBYTE GIDDump[9];            /* GifImageDescriptor dump                  */

    GIFBYTE *Image;                /* Decompressed Raster Image                */
    GIFBYTE *GIFImage;
} GIFIMAGEDESC;

/*
**  GIF 89a Graphic Control Extension Block
*/
typedef struct _GifGraphicControlExtension {
    GIFBYTE GCEDump[5];            /* Graphic Control Extension Dump           */
} GIFGRAPHICCONTROL;

/*
**  GIF 89a Plain Text Extension Block
*/
typedef struct _GifPlainTextExtension {
    GIFBYTE PTEDump[15];           /* Plain Text Extension Dump                */
    GIFBYTE *PlainTextData;        /* Plain Text data sub-blocks               */
    GIFWORD DataSize;
} GIFPLAINTEXT;


/*
**  GIF 89a Application Extension Block
*/
typedef struct _GifApplicationExtension {
    GIFBYTE AEDump[14];            /* Application Extension Dump               */
    GIFBYTE *ApplicationData;      /* Application data sub-blocks              */
    GIFWORD DataSize;
} GIFAPPLICATION;

/*
**  GIF 89a Comment Extension Block
*/
typedef struct _GifCommentExtension {
    GIFBYTE CEDump[2];             /* Comment Extension Dump                   */
    GIFBYTE *CommentData;          /* Comment data sub-blocks                  */
    GIFWORD DataSize;
    GIFBYTE Terminator;            /* Block Terminator (always 0)              */
} GIFCOMMENT;

/*
** GIF to HDF Memory Struct
** Purpose : The gif to hdf structure is used to pass all the
**           gif data to the memory, which gets caught by the hdf driver
**           Its the drivers job to put the data in the appropriate places
**           in the HDF file.
**           I have assumed that the ImageDescriptors and GraphicControls follow
**           one another, ie. I have not associated them with each other. The driver
**           must assume a 1-1 correspondance. The same discussion with plain text
**           extension.
*/
typedef struct _GifToMem {
    GIFHEAD            *GifHeader;
    GIFIMAGEDESC      **GifImageDesc;
    GIFGRAPHICCONTROL **GifGraphicControlExtension;
    GIFPLAINTEXT      **GifPlainTextExtension;
    GIFAPPLICATION    **GifApplicationExtension;
    GIFCOMMENT        **GifCommentExtension;
} GIFTOMEM;

/*
**  Function Prototypes
*/

/* GIF2MEM.C */
int Gif2Mem(GIFBYTE *, GIFTOMEM *);

/* GIFREAD.C */
int ReadGifHeader(GIFHEAD *, GIFBYTE **);
int ReadGifImageDesc(GIFIMAGEDESC *, GIFBYTE **);
int ReadGifGraphicControl(GIFGRAPHICCONTROL *, GIFBYTE **);
int ReadGifPlainText(GIFPLAINTEXT *, GIFBYTE **);
int ReadGifApplication(GIFAPPLICATION *, GIFBYTE **);
int ReadGifComment(GIFCOMMENT *, GIFBYTE **);

/* HDFGIFWR.C */
int hdfWriteGIF(FILE *fp, GIFBYTE *pic, int ptype, int w, int h, GIFBYTE *rmap,
                GIFBYTE *gmap, GIFBYTE *bmap, GIFBYTE *pc2ncmap, int numcols,
                int colorstyle, int BitsPerPixel);

/* WRITEHDF.C */
int WriteHDF(GIFTOMEM , GIFCHAR * );

/* Function:    ReadHDF
** Return:      0 on completion without error, -1 on error
** Input:       GIFCHAR *h5_file - HDF file name
**              GIFCHAR *dset_name - Name of the HDF Image dataset
**              GIFCHAR *pal_name - Name of the HDF palette
** Output:      GIFBYTE* data - the HDF Image to be converted
**              GIFBYTE  palette[256][3] - the corresponding palette
**              hsize_t* image_size - the size of each dimension of the image
*/
int ReadHDF(GIFBYTE** data, GIFBYTE palette[256][3], hsize_t *image_size,
            GIFCHAR *h5_file, GIFCHAR *dset_name, GIFCHAR *pal_name);

GIFBYTE *Decompress(GIFIMAGEDESC *, GIFHEAD *);
GIFBYTE GetByte(GIFBYTE *);
GIFWORD GetWord(GIFBYTE *);

void cleanup(GIFBYTE*);

#endif  /* GIF_H_ */
