diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gifconv/decompress.c | 497 | ||||
-rw-r--r-- | tools/gifconv/gif.h | 138 | ||||
-rw-r--r-- | tools/gifconv/gif2hdf.c | 213 | ||||
-rw-r--r-- | tools/gifconv/gif2mem.c | 572 | ||||
-rw-r--r-- | tools/gifconv/gifread.c | 126 | ||||
-rw-r--r-- | tools/gifconv/hdf2gif.c | 705 | ||||
-rw-r--r-- | tools/gifconv/hdfgifwr.c | 528 | ||||
-rw-r--r-- | tools/gifconv/readhdf.c | 308 | ||||
-rw-r--r-- | tools/gifconv/writehdf.c | 781 |
9 files changed, 1951 insertions, 1917 deletions
diff --git a/tools/gifconv/decompress.c b/tools/gifconv/decompress.c index abccb7f..a2682e5 100644 --- a/tools/gifconv/decompress.c +++ b/tools/gifconv/decompress.c @@ -1,38 +1,43 @@ +/* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + */ #include <stdio.h> #include <stdlib.h> + #include "gif.h" -#define NEXTBYTE (*ptr++) -#define IMAGESEP 0x2c -#define INTERLACEMASK 0x40 -#define COLORMAPMASK 0x80 -#define False 0 -#define True 1 +#define NEXTBYTE (*ptr++) + +#define IMAGESEP 0x2c +#define INTERLACEMASK 0x40 +#define COLORMAPMASK 0x80 -WORD iWIDE,iHIGH,eWIDE,eHIGH,expand,numcols,strip,nostrip; +WORD iWIDE, iHIGH, eWIDE, eHIGH, expand, numcols, strip, nostrip; unsigned long cols[256]; -char *cmd; +char *cmd; FILE *fp; -static int BitOffset = 0, /* Bit Offset of next code */ -XC = 0, YC = 0, /* Output X and Y coords of current pixel */ -Pass = 0, /* Used by output routine if WORDerlaced pic */ -OutCount = 0, /* Decompressor output 'stack count' */ -IWidth, IHeight, /* image dimensions */ -BytesPerScanline, /* Bytes per scanline in output raster */ -CodeSize, /* Code size, read from GIF header */ -InitCodeSize, /* Starting code size, used during Clear */ -Code, /* Value returned by ReadCode */ -MaxCode, /* limiting value for current code size */ -ClearCode, /* GIF clear code */ -EOFCode, /* GIF end-of-information code */ -CurCode, OldCode, InCode, /* Decompressor variables */ -FirstFree, /* First free code, generated per GIF spec */ -FreeCode, /* Decompressor, next free slot in hash table */ -FinChar, /* Decompressor variable */ -DataMask, /* AND mask for data size */ -ReadMask; /* Code AND mask for current code size */ +static int + BitOffset = 0, /* Bit Offset of next code */ + XC = 0, YC = 0, /* Output X and Y coords of current pixel */ + Pass = 0, /* Used by output routine if WORDerlaced pic */ + OutCount = 0, /* Decompressor output 'stack count' */ + IWidth, IHeight, /* image dimensions */ + BytesPerScanline, /* Bytes per scanline in output raster */ + CodeSize, /* Code size, read from GIF header */ + InitCodeSize, /* Starting code size, used during Clear */ + Code, /* Value returned by ReadCode */ + MaxCode, /* limiting value for current code size */ + ClearCode, /* GIF clear code */ + EOFCode, /* GIF end-of-information code */ + CurCode, OldCode, InCode, /* Decompressor variables */ + FirstFree, /* First free code, generated per GIF spec */ + FreeCode, /* Decompressor, next free slot in hash table */ + FinChar, /* Decompressor variable */ + DataMask, /* AND mask for data size */ + ReadMask; /* Code AND mask for current code size */ /*MODIFICATIONS*/ BYTE tempbyte[10]; @@ -43,10 +48,9 @@ WORD ImageCount = 0; boolean Interlace, HasColormap; - -BYTE *Image; /* The result array */ -BYTE *RawGIF; /* The heap array to hold it, raw */ -BYTE *Raster; /* The raster data stream, unblocked */ +BYTE *Image; /* The result array */ +BYTE *RawGIF; /* The heap array to hold it, raw */ +BYTE *Raster; /* The raster data stream, unblocked */ /* The hash table used by the decompressor */ @@ -61,233 +65,246 @@ int OutCode[1025]; int numused; -/* Fetch the next code from the raster data stream. The codes can be -* any length from 3 to 12 bits, packed WORDo 8-bit BYTEs, so we have to -* maWORDain our location in the Raster array as a BIT Offset. We compute -* the BYTE Offset WORDo the raster array by dividing this by 8, pick up -* three BYTEs, compute the bit Offset WORDo our 24-bit chunk, shift to -* bring the desired code to the bottom, then mask it off and return it. -*/ -static int ReadCode(void) +/* + * Fetch the next code from the raster data stream. The codes can be any + * length from 3 to 12 bits, packed WORDo 8-bit BYTEs, so we have to maWORDain + * our location in the Raster array as a BIT Offset. We compute the BYTE + * Offset WORDo the raster array by dividing this by 8, pick up three BYTEs, + * compute the bit Offset WORDo our 24-bit chunk, shift to bring the desired + * code to the bottom, then mask it off and return it. + */ +static int +ReadCode(void) { - int RawCode, ByteOffset; - + int RawCode, ByteOffset; + ByteOffset = BitOffset / 8; RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]); + if (CodeSize >= 8) - RawCode += (0x10000 * Raster[ByteOffset + 2]); + RawCode += (0x10000 * Raster[ByteOffset + 2]); + RawCode >>= (BitOffset % 8); BitOffset += CodeSize; - return(RawCode & ReadMask); + return (RawCode & ReadMask); } - -static void AddToPixel(BYTE Index) +static void +AddToPixel(BYTE Index) { if (YC<IHeight) - *(Image + YC * BytesPerScanline + XC) = Index; - + *(Image + YC * BytesPerScanline + XC) = Index; - - /* Update the X-coordinate, and if it overflows, update the Y-coordinate */ + + + /* Update the X-coordinate, and if it overflows, update the + * Y-coordinate */ if (++XC == IWidth) { - - /* If a non-WORDerlaced picture, just increment YC to the next scan line. - * If it's WORDerlaced, deal with the WORDerlace as described in the GIF - * spec. Put the decoded scan line out to the screen if we haven't gone - * past the bottom of it. - */ - - XC = 0; - if (!Interlace) YC++; - else { - switch (Pass) { - case 0: - YC += 8; - if (YC >= IHeight) { - Pass++; - YC = 4; - } - break; - case 1: - YC += 8; - if (YC >= IHeight) { - Pass++; - YC = 2; - } - break; - - case 2: - YC += 4; - if (YC >= IHeight) { - Pass++; - YC = 1; - } - break; - case 3: - YC += 2; - break; - default: - break; - } - } + /* + * If a non-WORDerlaced picture, just increment YC to the next scan + * line. If it's WORDerlaced, deal with the WORDerlace as described + * in the GIF spec. Put the decoded scan line out to the screen if we + * haven't gone past the bottom of it. + */ + XC = 0; + + if (!Interlace) { + YC++; + } else { + switch (Pass) { + case 0: + YC += 8; + + if (YC >= IHeight) { + Pass++; + YC = 4; + } + + break; + case 1: + YC += 8; + + if (YC >= IHeight) { + Pass++; + YC = 2; + } + + break; + case 2: + YC += 4; + + if (YC >= IHeight) { + Pass++; + YC = 1; + } + + break; + case 3: + YC += 2; + break; + default: + break; + } + } } } /* Main routine. Convert a GIF image to an HDF image */ -BYTE* Decompress(GifImageDesc , GifHead) -GIFIMAGEDESC *GifImageDesc; -GIFHEAD *GifHead; +BYTE * +Decompress(GIFIMAGEDESC *GifImageDesc, GIFHEAD *GifHead) { - int i; - - XC = 0; - YC = 0; - Pass = 0; - OutCount = 0; - BitOffset = 0; - - DataMask = (WORD)((1L << ((GifHead->PackedField & 0x07) +1)) -1); - Raster = GifImageDesc->GIFImage; - - - /* Check for image seperator */ - - /* Now read in values from the image descriptor */ - IWidth = GifImageDesc->ImageWidth; - IHeight = GifImageDesc->ImageHeight; - Interlace = GifImageDesc->PackedField & 0x40; - - /* Note that I ignore the possible existence of a local color map. - * I'm told there aren't many files around that use them, and the spec - * says it's defined for future use. This could lead to an error - * reading some files. - */ - - /* Start reading the raster data. First we get the WORDial code size - * and compute decompressor constant values, based on this code size. - */ - - CodeSize = GifImageDesc->CodeSize; - ClearCode = (1 << CodeSize); - EOFCode = ClearCode + 1; - FreeCode = FirstFree = ClearCode + 2; - - /* The GIF spec has it that the code size is the code size used to - * compute the above values is the code size given in the file, but the - * code size used in compression/decompression is the code size given in - * the file plus one. (thus the ++). - */ - - CodeSize++; - InitCodeSize = CodeSize; - MaxCode = (1 << CodeSize); - ReadMask = MaxCode - 1; - - /* Read the raster data. Here we just transpose it from the GIF array - * to the Raster array, turning it from a series of blocks WORDo one long - * data stream, which makes life much easier for ReadCode(). - */ - - - - /* free(RawGIF); We're not done just yet - change made */ - - /* Allocate the Image */ - - if (!(Image = (BYTE *)malloc((size_t)IWidth*(size_t)IHeight))) { - printf("Out of memory"); - exit(-1); - } - - BytesPerScanline = IWidth; - - /* Decompress the file, continuing until you see the GIF EOF code. - * One obvious enhancement is to add checking for corrupt files here. - */ - - Code = ReadCode(); - while (Code != EOFCode) { - - /* Clear code sets everything back to its initial value, then reads the - * immediately subsequent code as uncompressed data. - */ - - if (Code == ClearCode) { - CodeSize = InitCodeSize; - MaxCode = (1 << CodeSize); - ReadMask = MaxCode - 1; - FreeCode = FirstFree; - CurCode = OldCode = Code = ReadCode(); - FinChar = CurCode & DataMask; - AddToPixel(FinChar); - } - else { - - /* If not a clear code, then must be data: save same as CurCode and InCode */ - - CurCode = InCode = Code; - - /* If greater or equal to FreeCode, not in the hash table yet; - * repeat the last character decoded - */ - - if (CurCode >= FreeCode) { - CurCode = OldCode; - OutCode[OutCount++] = FinChar; - } - - /* Unless this code is raw data, pursue the chain poWORDed to by CurCode - * through the hash table to its end; each code in the chain puts its - * associated output code on the output queue. - */ - - while (CurCode > DataMask) { - if (OutCount > 1024) { - /*return error message*/ - } - OutCode[OutCount++] = Suffix[CurCode]; - CurCode = Prefix[CurCode]; - } - - /* The last code in the chain is treated as raw data. */ - - FinChar = CurCode & DataMask; - OutCode[OutCount++] = FinChar; - - /* Now we put the data out to the Output routine. - * It's been stacked LIFO, so deal with it that way... - */ - - for (i = OutCount - 1; i >= 0; i--) - AddToPixel(OutCode[i]); - OutCount = 0; - - /* Build the hash table on-the-fly. No table is stored in the file. */ - - Prefix[FreeCode] = OldCode; - Suffix[FreeCode] = FinChar; - OldCode = InCode; - - /* PoWORD to the next slot in the table. If we exceed the current - * MaxCode value, increment the code size unless it's already 12. If it - * is, do nothing: the next code decompressed better be CLEAR - */ - - FreeCode++; - if (FreeCode >= MaxCode) { - if (CodeSize < 12) { - CodeSize++; - MaxCode *= 2; - ReadMask = (1 << CodeSize) - 1; - } - } - } - Code = ReadCode(); - } - - return Image; -} + int i; + + XC = 0; + YC = 0; + Pass = 0; + OutCount = 0; + BitOffset = 0; + + DataMask = (WORD)((1L << ((GifHead->PackedField & 0x07) +1)) -1); + Raster = GifImageDesc->GIFImage; + + /* Check for image seperator */ + + /* Now read in values from the image descriptor */ + IWidth = GifImageDesc->ImageWidth; + IHeight = GifImageDesc->ImageHeight; + Interlace = GifImageDesc->PackedField & 0x40; + + /* + * Note that I ignore the possible existence of a local color map. I'm + * told there aren't many files around that use them, and the spec says + * it's defined for future use. This could lead to an error reading some + * files. + */ + + /* + * Start reading the raster data. First we get the WORDial code size and + * compute decompressor constant values, based on this code size. + */ + + CodeSize = GifImageDesc->CodeSize; + ClearCode = (1 << CodeSize); + EOFCode = ClearCode + 1; + FreeCode = FirstFree = ClearCode + 2; + + /* + * The GIF spec has it that the code size is the code size used to compute + * the above values is the code size given in the file, but the code size + * used in compression/decompression is the code size given in the file + * plus one. (thus the ++). + */ + + CodeSize++; + InitCodeSize = CodeSize; + MaxCode = (1 << CodeSize); + ReadMask = MaxCode - 1; + + /* + * Read the raster data. Here we just transpose it from the GIF array to + * the Raster array, turning it from a series of blocks WORDo one long + * data stream, which makes life much easier for ReadCode(). + */ + + /* Allocate the Image */ + + if (!(Image = (BYTE *)malloc((size_t)IWidth*(size_t)IHeight))) { + printf("Out of memory"); + exit(-1); + } + + BytesPerScanline = IWidth; + + /* + * Decompress the file, continuing until you see the GIF EOF code. One + * obvious enhancement is to add checking for corrupt files here. + */ + + Code = ReadCode(); + + while (Code != EOFCode) { + /* + * Clear code sets everything back to its initial value, then reads + * the immediately subsequent code as uncompressed data. + */ + if (Code == ClearCode) { + CodeSize = InitCodeSize; + MaxCode = (1 << CodeSize); + ReadMask = MaxCode - 1; + FreeCode = FirstFree; + CurCode = OldCode = Code = ReadCode(); + FinChar = CurCode & DataMask; + AddToPixel(FinChar); + } else { + /* + * If not a clear code, then must be data: save same as CurCode + * and InCode + */ + CurCode = InCode = Code; + /* + * If greater or equal to FreeCode, not in the hash table yet; + * repeat the last character decoded + */ + if (CurCode >= FreeCode) { + CurCode = OldCode; + OutCode[OutCount++] = FinChar; + } + /* + * Unless this code is raw data, pursue the chain poWORDed to by + * CurCode through the hash table to its end; each code in the + * chain puts its associated output code on the output queue. + */ + while (CurCode > DataMask) { + if (OutCount > 1024) { + /*return error message*/ + } + + OutCode[OutCount++] = Suffix[CurCode]; + CurCode = Prefix[CurCode]; + } + + /* The last code in the chain is treated as raw data. */ + FinChar = CurCode & DataMask; + OutCode[OutCount++] = FinChar; + + /* + * Now we put the data out to the Output routine. It's been + * stacked LIFO, so deal with it that way... + */ + for (i = OutCount - 1; i >= 0; i--) + AddToPixel(OutCode[i]); + + OutCount = 0; + + /* + * Build the hash table on-the-fly. No table is stored in the + * file. + */ + Prefix[FreeCode] = OldCode; + Suffix[FreeCode] = FinChar; + OldCode = InCode; + + /* + * PoWORD to the next slot in the table. If we exceed the current + * MaxCode value, increment the code size unless it's already 12. + * If it is, do nothing: the next code decompressed better be + * CLEAR + */ + FreeCode++; + + if (FreeCode >= MaxCode) + if (CodeSize < 12) { + CodeSize++; + MaxCode *= 2; + ReadMask = (1 << CodeSize) - 1; + } + } + + Code = ReadCode(); + } + + return Image; +} diff --git a/tools/gifconv/gif.h b/tools/gifconv/gif.h index 3f2a8da..21ce502 100644 --- a/tools/gifconv/gif.h +++ b/tools/gifconv/gif.h @@ -1,22 +1,21 @@ -/****************************************************************************\ -** Title: GIF.H ** -** Purpose: GIF Header file ** -\****************************************************************************/ - -#ifndef GIF_H -#define GIF_H 1 - -#include <hdf5.h> +/* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + * + * 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 -/*#include "datatype.h" Data type definitions */ - /* set the name length restriction to 64 charachters */ #define VSNAMELENMAX 64 /* this is a carryover from HDF4 */ @@ -26,11 +25,11 @@ typedef unsigned char BYTE; /* typedef H5T_NATIVE_UINT16 WORD; */ typedef unsigned long WORD; -typedef char CHAR; -typedef unsigned char boolean; +typedef char CHAR; +typedef unsigned char boolean; -#define false 0; -#define true 1; +#define false 0 +#define true 1 /* Set the EndianOrder. ** The GIF Reader file should do this. @@ -45,77 +44,69 @@ extern int EndianOrder; ** This structure actually contains the header, logical screen ** descriptor, and the global color table for the GIF image. */ -typedef struct _GifHeader /* Offset Description */ -{ - BYTE PackedField; /* 0Ah Color Information */ - WORD TableSize; - BYTE ImageCount; /* Keep a count of the number of images */ - BYTE CommentCount; - BYTE ApplicationCount; - BYTE PlainTextCount; - BYTE HDFPalette[256][3]; - BYTE HeaderDump[6]; /* BYTE array to dump header contents */ - BYTE LSDDump[7]; /* Logical Screen Descriptor dump */ +typedef struct _GifHeader { /* Offset Description */ + BYTE PackedField; /* 0Ah Color Information */ + WORD TableSize; + BYTE ImageCount; /* Keep a count of the number of images */ + BYTE CommentCount; + BYTE ApplicationCount; + BYTE PlainTextCount; + BYTE HDFPalette[256][3]; + BYTE HeaderDump[6]; /* BYTE array to dump header contents */ + BYTE LSDDump[7]; /* Logical Screen Descriptor dump */ } GIFHEAD; /* ** The GIF Image Descriptor. */ -typedef struct _GifImageDescriptor -{ - WORD ImageWidth; /* Width of the image in pixels */ - WORD ImageHeight; /* Height of the image in pixels */ - BYTE PackedField; /* Image and Color Table Data Information */ - WORD TableSize; - WORD CodeSize; /* Minimum LZW CodeSize for image data */ - BYTE HDFPalette[256][3]; - BYTE GIDDump[9]; /* GifImageDescriptor dump */ - - BYTE *Image; /* Decompressed Raster Image */ - BYTE *GIFImage; +typedef struct _GifImageDescriptor { + WORD ImageWidth; /* Width of the image in pixels */ + WORD ImageHeight; /* Height of the image in pixels */ + BYTE PackedField; /* Image and Color Table Data Information */ + WORD TableSize; + WORD CodeSize; /* Minimum LZW CodeSize for image data */ + BYTE HDFPalette[256][3]; + BYTE GIDDump[9]; /* GifImageDescriptor dump */ + + BYTE *Image; /* Decompressed Raster Image */ + BYTE *GIFImage; } GIFIMAGEDESC; - /* ** GIF 89a Graphic Control Extension Block */ -typedef struct _GifGraphicControlExtension -{ - BYTE GCEDump[5]; /* Graphic Control Extension Dump */ +typedef struct _GifGraphicControlExtension { + BYTE GCEDump[5]; /* Graphic Control Extension Dump */ } GIFGRAPHICCONTROL; - /* ** GIF 89a Plain Text Extension Block */ -typedef struct _GifPlainTextExtension -{ - BYTE PTEDump[15]; /* Plain Text Extension Dump */ - BYTE *PlainTextData; /* Plain Text data sub-blocks */ - WORD DataSize; +typedef struct _GifPlainTextExtension { + BYTE PTEDump[15]; /* Plain Text Extension Dump */ + BYTE *PlainTextData; /* Plain Text data sub-blocks */ + WORD DataSize; } GIFPLAINTEXT; /* ** GIF 89a Application Extension Block */ -typedef struct _GifApplicationExtension -{ - BYTE AEDump[14]; /* Application Extension Dump */ - BYTE *ApplicationData; /* Application data sub-blocks */ - WORD DataSize; +typedef struct _GifApplicationExtension { + BYTE AEDump[14]; /* Application Extension Dump */ + BYTE *ApplicationData; /* Application data sub-blocks */ + WORD DataSize; } GIFAPPLICATION; /* ** GIF 89a Comment Extension Block */ -typedef struct _GifCommentExtension -{ - BYTE CEDump[2]; /* Comment Extension Dump */ - BYTE *CommentData; /* Comment data sub-blocks */ - WORD DataSize; - BYTE Terminator; /* Block Terminator (always 0) */ +typedef struct _GifCommentExtension { + BYTE CEDump[2]; /* Comment Extension Dump */ + BYTE *CommentData; /* Comment data sub-blocks */ + WORD DataSize; + BYTE Terminator; /* Block Terminator (always 0) */ } GIFCOMMENT; /* @@ -129,8 +120,7 @@ typedef struct _GifCommentExtension ** must assume a 1-1 correspondance. The same discussion with plain text ** extension. */ -typedef struct _GifToMem -{ +typedef struct _GifToMem { GIFHEAD *GifHeader; GIFIMAGEDESC **GifImageDesc; GIFGRAPHICCONTROL **GifGraphicControlExtension; @@ -139,10 +129,10 @@ typedef struct _GifToMem GIFCOMMENT **GifCommentExtension; } GIFTOMEM; - /* ** Function Prototypes */ + /* GIF2MEM.C */ GIFTOMEM Gif2Mem(BYTE *); @@ -157,22 +147,22 @@ int ReadGifComment(GIFCOMMENT *, BYTE **); /* WRITEHDF.C */ int WriteHDF(GIFTOMEM , CHAR * , CHAR *); -/* Function : ReadHDF -** Return: 0 on completion without error, -1 on error -** Input: CHAR *h5_file - HDF file name -** CHAR *dset_name - Name of the HDF Image dataset -** CHAR *pal_name - Name of the HDF palette -** Output : BYTE* data - the HDF Image to be converted -** BYTE palette[256][3] - the corresponding palette -** hsize_t* image_size - the size of each dimension of the image -** +/* Function: ReadHDF +** Return: 0 on completion without error, -1 on error +** Input: CHAR *h5_file - HDF file name +** CHAR *dset_name - Name of the HDF Image dataset +** CHAR *pal_name - Name of the HDF palette +** Output: BYTE* data - the HDF Image to be converted +** BYTE palette[256][3] - the corresponding palette +** hsize_t* image_size - the size of each dimension of the image */ -int ReadHDF(BYTE** data , BYTE palette[256][3] , hsize_t *image_size , CHAR *h5_file , CHAR *dset_name , CHAR *pal_name); +int ReadHDF(BYTE** data, BYTE palette[256][3], hsize_t *image_size, + CHAR *h5_file, CHAR *dset_name, CHAR *pal_name); -BYTE *Decompress (GIFIMAGEDESC * , GIFHEAD *); +BYTE *Decompress(GIFIMAGEDESC *, GIFHEAD *); BYTE GetByte(BYTE *); WORD GetWord(BYTE *); void cleanup(BYTE*); -#endif /* GIF_H */ +#endif /* GIF_H_ */ diff --git a/tools/gifconv/gif2hdf.c b/tools/gifconv/gif2hdf.c index 6b4ae2b..89edb5f 100644 --- a/tools/gifconv/gif2hdf.c +++ b/tools/gifconv/gif2hdf.c @@ -1,113 +1,116 @@ -/* #include <hdf.h> */ -#include "gif.h" +/* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + */ #include <string.h> #include <stdio.h> #include <stdlib.h> +#include "gif.h" + int main(int argv , char *argc[]) { - - GIFTOMEM GifMemoryStruct; - GIFIMAGEDESC gifImageDesc; - - FILE *fpGif; - - /* replacing int32 with long */ - long i,ImageCount; - long filesize; - - BYTE *MemGif; - BYTE *StartPos; - - /* VSNAMELENMAX is a carryover from HDF4 and is #defined to 256 in gif.h */ - char GIFFileName[VSNAMELENMAX]; - char HDFFileName[VSNAMELENMAX]; - - /* Initialize all GifMemoryStruct pointers to null - ** to prevent hassles later on - */ - GifMemoryStruct.GifHeader = NULL; - GifMemoryStruct.GifImageDesc = NULL; - GifMemoryStruct.GifGraphicControlExtension = NULL; - GifMemoryStruct.GifPlainTextExtension = NULL; - GifMemoryStruct.GifApplicationExtension = NULL; - GifMemoryStruct.GifCommentExtension = NULL; - - - if (argv<3) - { - printf("\n\nWrong Usage. Use:\ngif2hdf <GIFFILE> <HDFFILE>\n\n"); - return(-1); - } - - - - strncpy(GIFFileName , argc[1] , VSNAMELENMAX - 1); - strncpy(HDFFileName , argc[2] , VSNAMELENMAX - 1); - GIFFileName[VSNAMELENMAX - 1] = '\0'; - HDFFileName[VSNAMELENMAX - 1] = '\0'; - - if (!(fpGif = fopen(GIFFileName,"rb"))) { - printf("Unable to open GIF file for reading.\n"); - printf("Filename (including path) must be less than %d charachters in length\n",VSNAMELENMAX); - exit(-1); - } - - /* Get the whole file into memory. Mem's much faster than I/O */ - fseek(fpGif, 0L , 2); - filesize = ftell(fpGif); - fseek(fpGif, 0L , 0); - if (filesize == 0) printf("File Size Zero"); - if (!(MemGif = StartPos = (BYTE *)malloc((size_t)filesize))) { - printf("Out of memory"); - exit (-1); - } - if (fread(MemGif,(size_t)filesize,1,fpGif) != 1) { - printf("Corrupted Input File"); - exit(-1); - } - - fseek(fpGif,0L,0); - - /* - ** Call Gif2Mem and break the whole file into parts. - ** Gif2Mem also calls decompresses the images so we don't - ** have to worry about that - */ - GifMemoryStruct = Gif2Mem(MemGif); - if (ferror(fpGif)) { - printf("File Stream Error\n\n"); - exit(-1); - } - fclose(fpGif); - - /* Call WriteHDF from here. Go ahead and change WriteHDF to write - ** whatever format you want - */ - if (WriteHDF(GifMemoryStruct , argc[2] , argc[1])) - printf("HDF Write Error\n\n"); - - /* Free all buffers */ - /* replacing int32 with long */ - ImageCount = (long)((GifMemoryStruct.GifHeader)->ImageCount); - - for(i = 0 ; i < ImageCount ; i++) - { - gifImageDesc = *(GifMemoryStruct.GifImageDesc[i]); - if (gifImageDesc.Image != NULL) - free(gifImageDesc.Image); - - if (GifMemoryStruct.GifGraphicControlExtension[i] != NULL) - free(GifMemoryStruct.GifGraphicControlExtension[i]); - - } - free(StartPos); - - free (GifMemoryStruct.GifHeader); - - if (GifMemoryStruct.GifApplicationExtension != NULL) - free (GifMemoryStruct.GifApplicationExtension); - - return (0); + GIFTOMEM GifMemoryStruct; + GIFIMAGEDESC gifImageDesc; + + FILE *fpGif; + + /* replacing int32 with long */ + long i, ImageCount; + long filesize; + + BYTE *MemGif; + BYTE *StartPos; + + /* VSNAMELENMAX is a carryover from HDF4 and is #defined to 256 in gif.h */ + char GIFFileName[VSNAMELENMAX]; + char HDFFileName[VSNAMELENMAX]; + + /* + * Initialize all GifMemoryStruct pointers to null to prevent hassles + * later on + */ + GifMemoryStruct.GifHeader = NULL; + GifMemoryStruct.GifImageDesc = NULL; + GifMemoryStruct.GifGraphicControlExtension = NULL; + GifMemoryStruct.GifPlainTextExtension = NULL; + GifMemoryStruct.GifApplicationExtension = NULL; + GifMemoryStruct.GifCommentExtension = NULL; + + if (argv < 3) { + printf("\n\nWrong Usage. Use:\ngif2hdf <GIFFILE> <HDFFILE>\n\n"); + return(-1); + } + + strncpy(GIFFileName , argc[1] , VSNAMELENMAX - 1); + strncpy(HDFFileName , argc[2] , VSNAMELENMAX - 1); + GIFFileName[VSNAMELENMAX - 1] = '\0'; + HDFFileName[VSNAMELENMAX - 1] = '\0'; + + if (!(fpGif = fopen(GIFFileName,"rb"))) { + printf("Unable to open GIF file for reading.\n"); + printf("Filename (including path) must be less than %d charachters in length\n", + VSNAMELENMAX); + exit(-1); + } + + /* Get the whole file into memory. Mem's much faster than I/O */ + fseek(fpGif, 0L , 2); + filesize = ftell(fpGif); + fseek(fpGif, 0L , 0); + + if (filesize == 0) + printf("File Size Zero"); + + if (!(MemGif = StartPos = (BYTE *)malloc((size_t)filesize))) { + printf("Out of memory"); + exit (-1); + } + + if (fread(MemGif,(size_t)filesize,1,fpGif) != 1) { + printf("Corrupted Input File"); + exit(-1); + } + + fseek(fpGif,0L,0); + + /* + * Call Gif2Mem and break the whole file into parts. Gif2Mem also calls + * decompresses the images so we don't have to worry about that + */ + GifMemoryStruct = Gif2Mem(MemGif); + + if (ferror(fpGif)) { + printf("File Stream Error\n\n"); + exit(-1); + } + + fclose(fpGif); + + /* + * Call WriteHDF from here. Go ahead and change WriteHDF to write whatever + * format you want + */ + if (WriteHDF(GifMemoryStruct , argc[2] , argc[1])) + printf("HDF Write Error\n\n"); + + /* Free all buffers */ + /* replacing int32 with long */ + ImageCount = (long)((GifMemoryStruct.GifHeader)->ImageCount); + + for(i = 0; i < ImageCount ; i++) { + gifImageDesc = *(GifMemoryStruct.GifImageDesc[i]); + + if (gifImageDesc.Image != NULL) + free(gifImageDesc.Image); + + if (GifMemoryStruct.GifGraphicControlExtension[i] != NULL) + free(GifMemoryStruct.GifGraphicControlExtension[i]); + } + + free(StartPos); + free(GifMemoryStruct.GifHeader); + free(GifMemoryStruct.GifApplicationExtension); + return 0; } diff --git a/tools/gifconv/gif2mem.c b/tools/gifconv/gif2mem.c index 830eba7..dd103c4 100644 --- a/tools/gifconv/gif2mem.c +++ b/tools/gifconv/gif2mem.c @@ -1,10 +1,11 @@ /* -** This file contains snippets of code from James Murray's original file -** to display the GIF header information, but most of it has been modified to -** suit gif2hdf -*/ - - + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + * + * This file contains snippets of code from James Murray's original file to + * display the GIF header information, but most of it has been modified to + * suit gif2hdf + */ /****************************************************************************\ ** Title: GIFHEAD.C ** @@ -21,20 +22,18 @@ ** Copyright (C) 1991-92 by Graphics Software Labs. All rights reserved. ** \****************************************************************************/ #include <stdio.h> + #include "gif.h" -/* #include <hdf.h> */ #define VERSION "1.00" GIFTOMEM -Gif2Mem(MemGif) -BYTE *MemGif; +Gif2Mem(BYTE *MemGif) { - /* - ** The gif structure outline for passing data to memory - ** is given in gif.h - ** These pointers are redunant, should take them out in ver. 2 - */ + /* + * The gif structure outline for passing data to memory is given in gif.h. + * These pointers are redunant, should take them out in ver. 2 + */ GIFHEAD *gifHead; /* GIF Header structure */ GIFIMAGEDESC **gifImageDesc; /* Logical Image Descriptor struct */ GIFPLAINTEXT **gifPlainText; /* Plain Text Extension structure */ @@ -42,302 +41,293 @@ BYTE *MemGif; GIFCOMMENT **gifComment; /* Comment Extension structure */ GIFGRAPHICCONTROL **gifGraphicControl; /* Graphic Control Extension strct */ - GIFTOMEM GifMemoryStruct; - - + GIFTOMEM GifMemoryStruct; register WORD i; /* Loop counter */ BYTE Identifier; /* Extension block identifier holder */ BYTE Label; /* Extension block label holder */ BYTE ImageCount; /* Count of the number of images in the file */ - BYTE ImageArray; /* Keep the size of the array to store Images */ - BYTE CommentCount; - BYTE CommentArray; - BYTE ApplicationCount; - BYTE ApplicationArray; - BYTE PlainTextCount; - BYTE PlainTextArray; - BYTE GCEflag; - BYTE aTemp; - BYTE j; - - BYTE w; /* Two more variables needed only while testing */ - BYTE *b; /* Endian Ordering */ - - /* Allocate memory for the GIF structures */ - /* Plug the structs into GifMemoryStruct at the end */ - /****************************************************/ - if (!(gifHead = (GIFHEAD *)malloc(sizeof(GIFHEAD)))) - { - printf("Could not allocate memory for gifHead\n"); - exit(-1); - } - - /* - ** The next three have to grow dynamically so we leave them - ** for now and let realloc handle it later on. - */ - gifImageDesc = NULL; - gifPlainText = NULL; - gifGraphicControl = NULL; - gifComment = NULL; - gifApplication = NULL; - - /******************************/ - /* Memory allocation complete */ - - - /* Carry out Endian Testing and set Endian Order */ - w = 0x0001; - b = (BYTE *) &w; - EndianOrder = (b[0] ? 1 : 0); + BYTE ImageArray; /* Keep the size of the array to store Images */ + BYTE CommentCount; + BYTE CommentArray; + BYTE ApplicationCount; + BYTE ApplicationArray; + BYTE PlainTextCount; + BYTE PlainTextArray; + BYTE GCEflag; + BYTE aTemp; + BYTE j; + BYTE w; /* Two more variables needed only while testing */ + BYTE *b; /* Endian Ordering */ + + /* Allocate memory for the GIF structures */ + /* Plug the structs into GifMemoryStruct at the end */ + /****************************************************/ + if (!(gifHead = (GIFHEAD *)malloc(sizeof(GIFHEAD)))) { + printf("Could not allocate memory for gifHead\n"); + exit(-1); + } + + /* + * The next three have to grow dynamically so we leave them for now and + * let realloc handle it later on. + */ + gifImageDesc = NULL; + gifPlainText = NULL; + gifGraphicControl = NULL; + gifComment = NULL; + gifApplication = NULL; + + /******************************/ + /* Memory allocation complete */ + /******************************/ + + /* Carry out Endian Testing and set Endian Order */ + w = 0x0001; + b = (BYTE *) &w; + EndianOrder = (b[0] ? 1 : 0); /* Read the GIF image file header information */ ReadGifHeader(gifHead, &MemGif); /* Check for FILE stream error */ - /* +#if 0 if (ferror(fpGif)) { fputs("GIFHEAD: Error reading header information!\n", stderr); exit(-3); } - */ +#endif /* 0 */ /* - ** Identify, read, and display block information. - */ - ImageCount = ImageArray = 0; - CommentCount = CommentArray = 0; - ApplicationCount = ApplicationArray = 0; - PlainTextCount = PlainTextArray = 0; - GCEflag = 0; - - for (;;) - { + * Identify, read, and display block information. + */ + ImageCount = ImageArray = 0; + CommentCount = CommentArray = 0; + ApplicationCount = ApplicationArray = 0; + PlainTextCount = PlainTextArray = 0; + GCEflag = 0; + + for (;;) { Identifier = *MemGif++; - switch (Identifier) - { - case 0x3B: /* Trailer */ - /* The counts are stored to make it easier while - ** putting stuff into the HDF file and then - ** deallocating space. - */ - gifHead->ImageCount = ImageCount; - gifHead->CommentCount = CommentCount; - gifHead->ApplicationCount = ApplicationCount; - gifHead->PlainTextCount = PlainTextCount; - - /* putting stuff into the gif2mem structure */ - GifMemoryStruct.GifHeader = gifHead; - GifMemoryStruct.GifImageDesc = gifImageDesc; - GifMemoryStruct.GifPlainTextExtension = gifPlainText; - GifMemoryStruct.GifApplicationExtension = gifApplication; - GifMemoryStruct.GifCommentExtension = gifComment; - GifMemoryStruct.GifGraphicControlExtension = gifGraphicControl; - - /* return the struct */ - return GifMemoryStruct; - - - - case 0x2C: /* Image Descriptor */ - /* If there was no image descriptor before this increase image count. - ** If an imagedescriptor was present, reset GCEflag - */ - if (GCEflag == 0) - ImageCount++; - else - GCEflag = 0; - - if (ImageCount > ImageArray) { - aTemp = ImageArray; - ImageArray = (ImageArray << 1) + 1; - if (!(gifImageDesc = (GIFIMAGEDESC **)realloc(gifImageDesc , sizeof(GIFIMAGEDESC *) * ImageArray))) - { - printf("Out of memory!"); - exit(-1); - } - if (!(gifGraphicControl = (GIFGRAPHICCONTROL **)realloc(gifGraphicControl , sizeof(GIFGRAPHICCONTROL *) * ImageArray))) - { - printf("Out of memory!"); - exit(-1); - } - - for (j = aTemp ; j < ImageArray ; j++) { - gifGraphicControl[j] = NULL; - gifImageDesc[j] = NULL; - } - } - - if(!(gifImageDesc[ImageCount-1] = (GIFIMAGEDESC*)malloc(sizeof(GIFIMAGEDESC)))) - { - printf("Out of memory!"); - exit(-1); - } - - - if (ReadGifImageDesc(gifImageDesc[ImageCount-1], &MemGif) == -1) - fputs("Error reading Image Descriptor information\n", stderr); - - /* - ** Decompress the Image - */ - gifImageDesc[ImageCount-1]->Image = Decompress(gifImageDesc[ImageCount-1] , gifHead); - free(gifImageDesc[ImageCount-1]->GIFImage); - - /* - ** Convert the local palette into an HDF compatible palette - ** In case the local color table is present, it is written out as the HDFPalette - ** If it is absent the global table is written as the HDFPalette. - */ - if (!((gifImageDesc[ImageCount-1]->PackedField) & 0x80)) - { - /* Check to see if the global color table exists.... */ - if (gifHead->PackedField & 0x80) { - for (i=0 ; i<gifHead->TableSize ; i++) - { - gifImageDesc[ImageCount-1]->HDFPalette[i][0] = gifHead->HDFPalette[i][0]; - gifImageDesc[ImageCount-1]->HDFPalette[i][1] = gifHead->HDFPalette[i][1]; - gifImageDesc[ImageCount-1]->HDFPalette[i][2] = gifHead->HDFPalette[i][2]; - } - } - gifImageDesc[ImageCount-1]->TableSize = gifHead->TableSize; - } - - break; - - case 0x21: /* Extension Block */ - Label = *MemGif++; - switch (Label) - { - case 0x01: /* Plain Text Extension */ - puts("Plain Text Extension\n"); - - PlainTextCount++; - if (PlainTextCount > PlainTextArray) - PlainTextArray = (PlainTextArray << 1) + 1; - - if (!(gifPlainText = (GIFPLAINTEXT **)realloc(gifPlainText , sizeof(GIFPLAINTEXT *) * PlainTextArray))) - { - printf("Out of memory!"); - exit(-1); - } - - if(!(gifPlainText[PlainTextCount - 1] = (GIFPLAINTEXT*)malloc(sizeof(GIFPLAINTEXT)))) - { - printf("Out of memory!"); - exit(-1); - } - - - - if (ReadGifPlainText(gifPlainText[PlainTextCount - 1], &MemGif)) - fprintf(stderr, - "Error reading Plain Text Extension information.\n"); - - break; - - case 0xFE: /* Comment Extension */ - CommentCount++; - if (CommentCount > CommentArray) - CommentArray = (CommentArray << 1) + 1; - - if (!(gifComment = (GIFCOMMENT **)realloc(gifComment , sizeof(GIFCOMMENT *) * CommentArray))) - { - printf("Out of memory!"); - exit(-1); - } - - if(!(gifComment[CommentCount - 1] = (GIFCOMMENT *)malloc(sizeof(GIFCOMMENT)))) - { - printf("Out of memory!"); - exit(-1); - } - - - if (ReadGifComment(gifComment[CommentCount - 1], &MemGif)) - fprintf(stderr, - "Error reading Comment Extension information\n"); - break; - - case 0xF9: /* Graphic Control Extension */ - if (GCEflag == 0 ) - ImageCount++; - - GCEflag = 1; - - if (ImageCount > ImageArray) { - aTemp = ImageArray; - ImageArray = (ImageArray << 1) + 1; - if (!(gifGraphicControl = (GIFGRAPHICCONTROL **)realloc(gifGraphicControl , sizeof(GIFGRAPHICCONTROL *) * ImageArray))) - { - printf("Out of memory!"); - exit(-1); - } - if (!(gifImageDesc = (GIFIMAGEDESC **)realloc(gifImageDesc , sizeof(GIFIMAGEDESC *) * ImageArray))) - { - printf("Out of memory!"); - exit(-1); - } - for (j = aTemp ; j < ImageArray ; j++) { - gifGraphicControl[j] = NULL; - gifImageDesc[j] = NULL; - } - } - - if(!(gifGraphicControl[ImageCount-1] = (GIFGRAPHICCONTROL*)malloc(sizeof(GIFGRAPHICCONTROL)))) - { - printf("Out of memory!"); - exit(-1); - } - - - if (ReadGifGraphicControl(gifGraphicControl[ImageCount-1], &MemGif)) - fprintf(stderr, - "Error reading Graphic Control Extension information\n"); - - if (!*MemGif++ == 0) - fprintf(stderr, - "Error reading Graphic Control Extension\n"); - - break; - - case 0xFF: /* Application Extension */ - ApplicationCount++; - if (ApplicationCount > ApplicationArray) - ApplicationArray = (ApplicationArray << 1) + 1; - - if (!(gifApplication = (GIFAPPLICATION **)realloc(gifApplication , sizeof(GIFAPPLICATION *) * ApplicationArray))) - { - printf("Out of memory!"); - exit(-1); - } - - if(!(gifApplication[ApplicationCount - 1] = (GIFAPPLICATION *)malloc(sizeof(GIFAPPLICATION)))) - { - printf("Out of memory!"); - exit(-1); - } - - - if (ReadGifApplication(gifApplication[ApplicationCount - 1], &MemGif)) - fprintf(stderr, - "Error reading Application Extension information\n"); - break; - - default: - - printf("Unknown Extension Label: 0x%02x\n", Label); - break; - } - break; + switch (Identifier) { + case 0x3B: /* Trailer */ + /* + * The counts are stored to make it easier while putting stuff + * into the HDF file and then deallocating space. + */ + gifHead->ImageCount = ImageCount; + gifHead->CommentCount = CommentCount; + gifHead->ApplicationCount = ApplicationCount; + gifHead->PlainTextCount = PlainTextCount; + + /* putting stuff into the gif2mem structure */ + GifMemoryStruct.GifHeader = gifHead; + GifMemoryStruct.GifImageDesc = gifImageDesc; + GifMemoryStruct.GifPlainTextExtension = gifPlainText; + GifMemoryStruct.GifApplicationExtension = gifApplication; + GifMemoryStruct.GifCommentExtension = gifComment; + GifMemoryStruct.GifGraphicControlExtension = gifGraphicControl; + + /* return the struct */ + return GifMemoryStruct; + + case 0x2C: /* Image Descriptor */ + /* + * If there was no image descriptor before this increase image + * count. If an imagedescriptor was present, reset GCEflag + */ + if (GCEflag == 0) + ImageCount++; + else + GCEflag = 0; + + if (ImageCount > ImageArray) { + aTemp = ImageArray; + ImageArray = (ImageArray << 1) + 1; + if (!(gifImageDesc = (GIFIMAGEDESC **)realloc(gifImageDesc, + sizeof(GIFIMAGEDESC *) * ImageArray))) { + printf("Out of memory!"); + exit(-1); + } + + if (!(gifGraphicControl = (GIFGRAPHICCONTROL **)realloc( + gifGraphicControl, + sizeof(GIFGRAPHICCONTROL *) * ImageArray))) { + printf("Out of memory!"); + exit(-1); + } + + for (j = aTemp ; j < ImageArray ; j++) { + gifGraphicControl[j] = NULL; + gifImageDesc[j] = NULL; + } + } + + if(!(gifImageDesc[ImageCount-1] = (GIFIMAGEDESC*)malloc(sizeof(GIFIMAGEDESC)))) { + printf("Out of memory!"); + exit(-1); + } + + + if (ReadGifImageDesc(gifImageDesc[ImageCount-1], &MemGif) == -1) + fputs("Error reading Image Descriptor information\n", stderr); + + /* Decompress the Image */ + gifImageDesc[ImageCount-1]->Image = Decompress(gifImageDesc[ImageCount-1], + gifHead); + free(gifImageDesc[ImageCount-1]->GIFImage); + + /* + * Convert the local palette into an HDF compatible palette In + * case the local color table is present, it is written out as + * the HDFPalette If it is absent the global table is written + * as the HDFPalette. + */ + if (!((gifImageDesc[ImageCount-1]->PackedField) & 0x80)) { + /* Check to see if the global color table exists.... */ + if (gifHead->PackedField & 0x80) { + for (i=0 ; i<gifHead->TableSize ; i++) { + gifImageDesc[ImageCount-1]->HDFPalette[i][0] = + gifHead->HDFPalette[i][0]; + gifImageDesc[ImageCount-1]->HDFPalette[i][1] = + gifHead->HDFPalette[i][1]; + gifImageDesc[ImageCount-1]->HDFPalette[i][2] = + gifHead->HDFPalette[i][2]; + } + } + + gifImageDesc[ImageCount-1]->TableSize = gifHead->TableSize; + } + + break; + + case 0x21: /* Extension Block */ + Label = *MemGif++; + + switch (Label) { + case 0x01: /* Plain Text Extension */ + puts("Plain Text Extension\n"); + PlainTextCount++; + + if (PlainTextCount > PlainTextArray) + PlainTextArray = (PlainTextArray << 1) + 1; + + if (!(gifPlainText = (GIFPLAINTEXT **)realloc(gifPlainText , sizeof(GIFPLAINTEXT *) * PlainTextArray))) { + printf("Out of memory!"); + exit(-1); + } + + if(!(gifPlainText[PlainTextCount - 1] = (GIFPLAINTEXT*)malloc(sizeof(GIFPLAINTEXT)))) { + printf("Out of memory!"); + exit(-1); + } + + if (ReadGifPlainText(gifPlainText[PlainTextCount - 1], &MemGif)) + fprintf(stderr, + "Error reading Plain Text Extension information.\n"); + + break; + + case 0xFE: /* Comment Extension */ + CommentCount++; + + if (CommentCount > CommentArray) + CommentArray = (CommentArray << 1) + 1; + + if (!(gifComment = (GIFCOMMENT **)realloc(gifComment , sizeof(GIFCOMMENT *) * CommentArray))) { + printf("Out of memory!"); + exit(-1); + } + + if(!(gifComment[CommentCount - 1] = (GIFCOMMENT *)malloc(sizeof(GIFCOMMENT)))) { + printf("Out of memory!"); + exit(-1); + } + + + if (ReadGifComment(gifComment[CommentCount - 1], &MemGif)) + fprintf(stderr, + "Error reading Comment Extension information\n"); + + break; + + case 0xF9: /* Graphic Control Extension */ + if (GCEflag == 0 ) + ImageCount++; + + GCEflag = 1; + + if (ImageCount > ImageArray) { + aTemp = ImageArray; + ImageArray = (ImageArray << 1) + 1; + + if (!(gifGraphicControl = (GIFGRAPHICCONTROL **)realloc(gifGraphicControl , sizeof(GIFGRAPHICCONTROL *) * ImageArray))) { + printf("Out of memory!"); + exit(-1); + } + + if (!(gifImageDesc = (GIFIMAGEDESC **)realloc(gifImageDesc , sizeof(GIFIMAGEDESC *) * ImageArray))) { + printf("Out of memory!"); + exit(-1); + } + + for (j = aTemp ; j < ImageArray ; j++) { + gifGraphicControl[j] = NULL; + gifImageDesc[j] = NULL; + } + } + + if(!(gifGraphicControl[ImageCount-1] = (GIFGRAPHICCONTROL*)malloc(sizeof(GIFGRAPHICCONTROL)))) { + printf("Out of memory!"); + exit(-1); + } + + + if (ReadGifGraphicControl(gifGraphicControl[ImageCount-1], &MemGif)) + fprintf(stderr, + "Error reading Graphic Control Extension information\n"); + + if (!*MemGif++ == 0) + fprintf(stderr, + "Error reading Graphic Control Extension\n"); + + break; + + case 0xFF: /* Application Extension */ + ApplicationCount++; + + if (ApplicationCount > ApplicationArray) + ApplicationArray = (ApplicationArray << 1) + 1; + + if (!(gifApplication = (GIFAPPLICATION **)realloc(gifApplication , sizeof(GIFAPPLICATION *) * ApplicationArray))) { + printf("Out of memory!"); + exit(-1); + } + + if(!(gifApplication[ApplicationCount - 1] = (GIFAPPLICATION *)malloc(sizeof(GIFAPPLICATION)))) { + printf("Out of memory!"); + exit(-1); + } + + + if (ReadGifApplication(gifApplication[ApplicationCount - 1], &MemGif)) + fprintf(stderr, + "Error reading Application Extension information\n"); + + break; + + default: + printf("Unknown Extension Label: 0x%02x\n", Label); + break; + } + + break; + default: - fprintf(stderr, "Unknown Block Separator Character: 0x%02x\n", - Identifier); + fprintf(stderr, + "Unknown Block Separator Character: 0x%02x\n", Identifier); } - } - - + } } diff --git a/tools/gifconv/gifread.c b/tools/gifconv/gifread.c index cb033d9..39043f3 100644 --- a/tools/gifconv/gifread.c +++ b/tools/gifconv/gifread.c @@ -1,85 +1,87 @@ +/* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + */ #include <stdio.h> #include <stdlib.h> + #include "gif.h" int EndianOrder; -static BYTE * ReadDataSubBlocks(BYTE **MemGif2, WORD *DSize); +static BYTE *ReadDataSubBlocks(BYTE **MemGif2, WORD *DSize); WORD -GetWord (MemGif) -BYTE *MemGif; +GetWord(BYTE *MemGif) { - WORD w; - if (EndianOrder == 1) /* LittleEndian */ - { - w = (WORD) (*MemGif++ & 0xFF); - w |= (WORD) ((*MemGif++ & 0xFF) << 0x08); - } - else - { - w = (WORD) (*MemGif++ & 0xFF); - w = ((WORD) (*MemGif++ & 0xFF)) | (w << 0x08); - } - return w; + WORD w; + + if (EndianOrder == 1) { + /* LittleEndian */ + w = (WORD) (*MemGif++ & 0xFF); + w |= (WORD) ((*MemGif++ & 0xFF) << 0x08); + } else { + w = (WORD) (*MemGif++ & 0xFF); + w = ((WORD) (*MemGif++ & 0xFF)) | (w << 0x08); + } + + return w; } BYTE -GetByte (MemGif) -BYTE *MemGif; +GetByte(BYTE *MemGif) { - return *MemGif; + return *MemGif; } /* -** Read a GIF image BYTE Header. -** -** This function reads the Header, Logical Screen Descriptor, and -** Global Color Table (if any) from a GIF image file. The information -** is stored in a GIFHEAD structure. -** -** Returns: -1 if a FILE stream error occured during the read, -** otherwise 0 if no error occured. -*/ + * Read a GIF image BYTE Header. + * + * This function reads the Header, Logical Screen Descriptor, and + * Global Color Table (if any) from a GIF image file. The information + * is stored in a GIFHEAD structure. + * + * Returns: -1 if a FILE stream error occured during the read, + * otherwise 0 if no error occured. + */ int -ReadGifHeader(GifHead, MemGif2) -GIFHEAD *GifHead; /* Pointer to GIF header structure */ -BYTE **MemGif2; /* GIF image file input FILE stream */ +ReadGifHeader(GIFHEAD *GifHead, /* Pointer to GIF header structure */ + BYTE **MemGif2) /* GIF image file input FILE stream */ { - WORD i; /* Loop counter */ + WORD i; /* Loop counter */ WORD tableSize; /* Number of entires in the Global Color Table */ - - GifHead->TableSize = 0; - for (i = 0 ; i < 6 ; i++) { - GifHead->HeaderDump[i] = *(*MemGif2)++; - } - if (strncmp((const char *)GifHead->HeaderDump , "GIF" , 3)) { - printf("The file does not appear to be a valid GIF file.\n"); - exit(-1); - } - - for (i = 0 ; i < 7 ; i++) { - GifHead->LSDDump[i] = *(*MemGif2)++; - } - GifHead->PackedField = GifHead->LSDDump[4]; - /* Check if a Global Color Table is present */ - if (GifHead->PackedField & 0x80) - { + GifHead->TableSize = 0; + for (i = 0 ; i < 6 ; i++) { + GifHead->HeaderDump[i] = *(*MemGif2)++; + } + + if (strncmp((const char *)GifHead->HeaderDump , "GIF" , 3)) { + printf("The file does not appear to be a valid GIF file.\n"); + exit(-1); + } + + for (i = 0 ; i < 7 ; i++) { + GifHead->LSDDump[i] = *(*MemGif2)++; + } + + GifHead->PackedField = GifHead->LSDDump[4]; + + /* Check if a Global Color Table is present */ + if (GifHead->PackedField & 0x80) { /* Read number of color table entries */ tableSize = (WORD) (1L << ((GifHead->PackedField & 0x07) + 1)); - GifHead->TableSize = tableSize; + GifHead->TableSize = tableSize; + /* Read the Global Color Table */ - /* - ** There are some changes made here apart from just - ** reading in the global color table as would - ** seem intuitively obvious. - ** The colors are stored in the bottom part of the - ** palette as opposed to the top - */ - for (i = 0; i < tableSize; i++) - { + /* + * There are some changes made here apart from just reading in the + * global color table as would seem intuitively obvious. The colors + * are stored in the bottom part of the palette as opposed to the top + */ + + for (i = 0; i < tableSize; i++) { GifHead->HDFPalette[i][0] = *(*MemGif2)++; GifHead->HDFPalette[i][1] = *(*MemGif2)++; GifHead->HDFPalette[i][2] = *(*MemGif2)++; @@ -87,12 +89,12 @@ BYTE **MemGif2; /* GIF image file input FILE stream */ } /* Check for a FILE stream error */ - /* +#if 0 if (ferror(FpGif)) - return(-1); - */ + return -1; +#endif /* 0 */ - return(0); /* No FILE stream error occured */ + return 0; /* No FILE stream error occured */ } diff --git a/tools/gifconv/hdf2gif.c b/tools/gifconv/hdf2gif.c index 39c75d1..2d6b339 100644 --- a/tools/gifconv/hdf2gif.c +++ b/tools/gifconv/hdf2gif.c @@ -1,355 +1,388 @@ -/* NOTES: -** 04/01 - 04/10: been working on it a lot. I think it does gif89 images just fine with -** palettes. So that's cool. Putting in multiple images and animation support right now -** 03/29: For some reason I can write .GIF files which IE will open and see but -** kodak imaging does not like. I'm sure its a problem with the GIF file, -** I can't figure out what. -** 03/17: Explicitely deallocate the GIFTOMEM* struct in the main loop. -** Check for both success and failure conditions -*/ +/* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + */ + +/* + * NOTES: + * 04/01 - 04/10: been working on it a lot. I think it does gif89 images just + * fine with palettes. So that's cool. Putting in multiple + * images and animation support right now + * 03/29: For some reason I can write .GIF files which IE will open and see + * but kodak imaging does not like. I'm sure its a problem with the GIF + * file, I can't figure out what. + * 03/17: Explicitely deallocate the GIFTOMEM* struct in the main loop. + * Check for both success and failure conditions + */ -#include "gif.h" #include <stdio.h> -#define MAX_FILE_LEN 256 -#define MAX_NUMBER_IMAGES 50 +#include "gif.h" -extern int hdfWriteGIF(FILE *fp, BYTE *pic, int ptype, int w, int h, BYTE *rmap, - BYTE *gmap, BYTE *bmap, BYTE *pc2ncmap, int numcols, int colorstyle, int BitsPerPixel); +#define MAX_FILE_LEN 256 +#define MAX_NUMBER_IMAGES 50 +extern int hdfWriteGIF(FILE *fp, BYTE *pic, int ptype, int w, int h, + BYTE *rmap, BYTE *gmap, BYTE *bmap, BYTE *pc2ncmap, + int numcols, int colorstyle, int BitsPerPixel); int EndianOrder; #ifdef NOT_USED -static void PutByte(BYTE b , FILE *fpGif) +static void +PutByte(BYTE b , FILE *fpGif) { - if (fputc(b , fpGif) == EOF) { - printf("File Writing Error, cannot continue"); - exit(-1); - } + if (fputc(b , fpGif) == EOF) { + printf("File Writing Error, cannot continue"); + exit(-1); + } } #endif /* NOT_USED */ - -static void putword(int w, FILE *fp) +static void +putword(int w, FILE *fp) { - /* writes a 16-bit integer in GIF order (LSB first) */ - - fputc(w &0xff, fp); - - fputc((w>>8)&0xff,fp); + /* writes a 16-bit integer in GIF order (LSB first) */ + fputc(w &0xff, fp); + fputc((w>>8)&0xff,fp); } -static void usage(void ) +static void +usage(void) { - printf("Usage: h52gif <h5_file> <gif_file> -i <h5_image> [-p <h5_palette>]\n"); - printf("h52gif expects *at least* one h5_image. You may repeat -i <h5_image> [-p <h5_palette>] at most 50 times (maximum of 50 images).\n"); + printf("Usage: h52gif <h5_file> <gif_file> -i <h5_image> [-p <h5_palette>]\n"); + printf("h52gif expects *at least* one h5_image.\n"); + printf("You may repeat -i <h5_image> [-p <h5_palette>] at most 50 times\n"); + printf("(maximum of 50 images).\n"); } -int main(int argc , char **argv) { - - FILE *fpGif; - - hsize_t dim_sizes[2]; - - BYTE *Image; - /* compression structs */ - - CHAR *HDFName = NULL; - CHAR *GIFName = NULL; - /* reference variables */ - - int has_local_palette; /* treated as a flag */ - int loop_times; /* number of times to loop, i'm going to treat it as a yes or no */ - - BYTE* b; - - BYTE GlobalPalette[256][3]; - BYTE Red[256]; - BYTE Green[256]; - BYTE Blue[256]; - - int RWidth, RHeight; - int LeftOfs, TopOfs; - int ColorMapSize, InitCodeSize, Background, BitsPerPixel; - int j,nc; - int w,h,i; - int numcols = 256; - int CountDown; - int curx , cury; - int time_out = 0; /* time between two images in the animation */ - int n_images , idx; - - BYTE pc2nc[256] , r1[256] , g1[256] , b1[256]; - - /* initial stuff */ - int number_of_images = 0; - int arg_index = 2; - int bool_is_image = 0; /* 0 = false , 1 = true */ - int bool_is_palette = 0; - CHAR* image_name_arr[MAX_NUMBER_IMAGES]; - CHAR* pal_name_arr[MAX_NUMBER_IMAGES]; - - if (argc < 5) { - /* they didn't supply at least one image -- bail */ - usage(); - return 0; - } - - memset(image_name_arr , NULL , MAX_NUMBER_IMAGES); - memset(pal_name_arr , NULL , MAX_NUMBER_IMAGES); - - HDFName = (CHAR*) malloc (strlen(argv[1]) + 1); - GIFName = (CHAR*) malloc (strlen(argv[2]) + 1); - - if (strlen(argv[1] + 1) > MAX_FILE_LEN || strlen(argv[2] + 1) > MAX_FILE_LEN) { - /* supplied file names are too long. bail. */ - usage(); - printf("Supplied filenames exceed maximum length of 256 bytes\n"); - } - - strcpy(HDFName , argv[1]); - strcpy(GIFName , argv[2]); - - /* get the options */ - while (arg_index++ < argc - 1 && number_of_images < MAX_NUMBER_IMAGES) { - if (!strcmp(argv[arg_index] , "-i")) { - bool_is_image = 1; - continue; - } - if (!strcmp(argv[arg_index] , "-p")) { - bool_is_palette = 1; - continue; - } - if (!strcmp(argv[arg_index] , "-a")) { - time_out = 10; - continue; - } - if (bool_is_image) { - /* this is an image */ - /* allocate space to store the image name */ - image_name_arr[number_of_images] = (CHAR*) malloc(strlen(argv[arg_index] + 1)); - strcpy(image_name_arr[number_of_images] , argv[arg_index]); - /* make the palette array for this NULL */ - pal_name_arr[number_of_images] = NULL; - number_of_images++; - bool_is_image = 0; - continue; - } - if (bool_is_palette) { - /* this is a palette */ - /* allocate space to store the pal name */ - /* the palette was probably allocated for a previous image */ - pal_name_arr[number_of_images-1] = (CHAR*) malloc(strlen(argv[arg_index] + 1)); - strcpy(pal_name_arr[number_of_images - 1] , argv[arg_index]); - bool_is_palette = 0; - continue; - } - /* oops. This was not meant to happen */ - usage(); - /* - while (number_of_images--) { - cleanup(image_name_arr[number_of_images]); - cleanup(pal_name_arr[number_of_images]); - } - */ - return -1; - - } - - /* we shall always have a palette - read hdf will see to that */ - has_local_palette = true; - - /* Do Endian Order testing and set Endian Order */ - w = 0x0001; - b = (BYTE *) &w; - EndianOrder = (b[0] ? 1:0); - - if (!(fpGif = fopen(GIFName , "wb"))) { - printf("Error opening gif file for output. Aborting.\n"); - return -1; - } - - /* hardwire n_images to 1 for now. */ - n_images = number_of_images; - - Background = 0; - for (idx = 0 ; idx < n_images ; idx++) { - - /* try to read the image and the palette */ - /* Lots of funky stuff to support multiple images has been taken off. - ** Just in case you're extending code, here's what you need to do in short: - ** figure out if there is a global palette or not, if there is one store that one - ** only. - ** If they are all local or a combination of local and global palettes, you will have - ** to write the global palette out and then independantly write the smaller local - ** palettes - */ - if (ReadHDF(&Image , GlobalPalette , dim_sizes , HDFName , image_name_arr[idx] , pal_name_arr[idx]) < 0) { - fprintf(stderr , "Unable to read HDF file\n"); - return -1; - } - - w = dim_sizes[1]; - h = dim_sizes[0]; - - RWidth = dim_sizes[1]; - RHeight = dim_sizes[0]; - LeftOfs = TopOfs = 0; - - - /* If the first image does not have a palette, I make my own global color table - ** Obviously this is not the best thing to do, better steps would be: - ** 1. Check for either a global palette or a global attribute called palette - ** 2. Check for palettes in any of the other images. - */ - if (!has_local_palette) { - for (i = 0 ; i < 256 ; i++) { - Red[i] = 255 - i; - Green[i] = 255 - i; - Blue[i] = 255 - i; - } - } - else { - for (i = 0 ; i < 256 ; i++){ - Red[i] = GlobalPalette[i][0]; - Green[i] = GlobalPalette[i][1]; - Blue[i] = GlobalPalette[i][2]; - } - } - - for (i=0; i<256; i++) { pc2nc[i] = r1[i] = g1[i] = b1[i] = 0; } - /* compute number of unique colors */ - nc = 0; - for (i=0; i<numcols; i++) { - /* see if color #i is already used */ - for (j=0; j<i; j++) { - if (Red[i] == Red[j] && Green[i] == Green[j] && - Blue[i] == Blue[j]) break; - } - if (j==i) { /* wasn't found */ - pc2nc[i] = nc; - r1[nc] = Red[i]; - g1[nc] = Green[i]; - b1[nc] = Blue[i]; - nc++; - } - else pc2nc[i] = pc2nc[j]; - } - /* figure out 'BitsPerPixel' */ - for (i=1; i<8; i++) { - if ( (1<<i) >= nc) break; - } - BitsPerPixel = i; - ColorMapSize = 1 << BitsPerPixel; - - - CountDown = w * h; /* # of pixels we'll be doing */ - - if (BitsPerPixel <= 1) InitCodeSize = 2; - else InitCodeSize = BitsPerPixel; - - curx = cury = 0; - - if (!fpGif) { - fprintf(stderr, "WriteGIF: file not open for writing\n" ); - return (1); - } - - /* If it is the first image we do all the header stuff that isn't required for the - ** rest of the images. - */ - if (idx == 0) { - /* Write out the GIF header and logical screen descriptor */ - if (n_images > 1) { - fwrite("GIF89a", 1, 6, fpGif); /* the GIF magic number */ - loop_times = 0; - } - else { - fwrite("GIF87a", 1, 6, fpGif); /* the GIF magic number */ - loop_times = 1; - } - - putword(RWidth, fpGif); /* screen descriptor */ - putword(RHeight, fpGif); - - i = 0x00; /* No, there is no color map */ - i |= (8-1)<<4; /* OR in the color resolution (hardwired 8) */ - i |= (BitsPerPixel - 1); /* OR in the # of bits per pixel */ - fputc(i,fpGif); - - fputc(Background,fpGif); /* background color */ - - fputc(0, fpGif); /* future expansion byte */ - - - /* If loop_times is 0 , put in the application extension to make the gif anime loop - ** indefinitely - */ - if (time_out > 0) { - fputc(0x21 , fpGif); - fputc(0xFF , fpGif); - fputc(11 , fpGif); - fwrite("NETSCAPE2.0" , 1 , 11 , fpGif); - fputc(3 , fpGif); - fputc(1 , fpGif); - fputc(0 , fpGif); - fputc(0 , fpGif); - fputc(0 , fpGif); - - } - - - } - - if (n_images > 1) { - /* write a graphic control block */ - fputc(0x21 , fpGif); - fputc(0xF9 , fpGif); - fputc(4 , fpGif); - fputc(4 , fpGif); - putword(time_out , fpGif); - fputc(255, fpGif); - fputc(0 , fpGif); - } - - /* Put Image Descriptor - ** Hardwiring Left Offset and Top Offset to 0x00 - */ - - fputc (0x2c , fpGif); - putword (0x00 , fpGif); - putword (0x00 , fpGif); - putword (RWidth , fpGif); - putword (RHeight , fpGif); - - /* since we always have a local color palette ... */ - fputc ((0x80 | (BitsPerPixel - 1)) , fpGif); - for (i=0; i<ColorMapSize; i++) { /* write out Global colormap */ - fputc(r1[i], fpGif); - fputc(g1[i], fpGif); - fputc(b1[i], fpGif); - } - - fputc (InitCodeSize , fpGif); - - i = hdfWriteGIF(fpGif , Image , 0 , (int)dim_sizes[0] , (int)dim_sizes[1] , r1, g1 , b1 , pc2nc , 256 , 8 , BitsPerPixel); - fputc(0x00 , fpGif); - free (Image); - } - - if (fputc(';',fpGif) == EOF) { /* Write GIF file terminator */ - fprintf(stderr , "Error!"); - return -1; - } - - fclose (fpGif); - - while (number_of_images--) { - /*if (image_name_arr[number_of_images]) - free(image_name_arr[number_of_images]);*/ - /*if (pal_name_arr[number_of_images]) - free(pal_name_arr[number_of_images]);*/ - } - - return(0); +int main(int argc , char **argv) +{ + FILE *fpGif; + hsize_t dim_sizes[2]; + BYTE *Image; + + /* compression structs */ + CHAR *HDFName = NULL; + CHAR *GIFName = NULL; + + /* reference variables */ + int has_local_palette; /* treated as a flag */ + int loop_times; /* number of times to loop, treat it as yes/no */ + + BYTE* b; + + BYTE GlobalPalette[256][3]; + BYTE Red[256]; + BYTE Green[256]; + BYTE Blue[256]; + + int RWidth, RHeight; + int LeftOfs, TopOfs; + int ColorMapSize, InitCodeSize, Background, BitsPerPixel; + int j,nc; + int w,h,i; + int numcols = 256; + int CountDown; + int curx , cury; + int time_out = 0; /* time between two images in the animation */ + int n_images , idx; + + BYTE pc2nc[256] , r1[256] , g1[256] , b1[256]; + + /* initial stuff */ + int number_of_images = 0; + int arg_index = 2; + int bool_is_image = 0; /* 0 = false , 1 = true */ + int bool_is_palette = 0; + CHAR* image_name_arr[MAX_NUMBER_IMAGES]; + CHAR* pal_name_arr[MAX_NUMBER_IMAGES]; + + if (argc < 5) { + /* they didn't supply at least one image -- bail */ + usage(); + return 0; + } + + memset(image_name_arr , NULL , MAX_NUMBER_IMAGES); + memset(pal_name_arr , NULL , MAX_NUMBER_IMAGES); + + HDFName = (CHAR *)malloc (strlen(argv[1]) + 1); + GIFName = (CHAR *)malloc (strlen(argv[2]) + 1); + + if (strlen(argv[1] + 1) > MAX_FILE_LEN || strlen(argv[2] + 1) > MAX_FILE_LEN) { + /* supplied file names are too long. bail. */ + usage(); + printf("Supplied filenames exceed maximum length of 256 bytes\n"); + } + + strcpy(HDFName , argv[1]); + strcpy(GIFName , argv[2]); + + /* get the options */ + while (arg_index++ < argc - 1 && number_of_images < MAX_NUMBER_IMAGES) { + if (!strcmp(argv[arg_index] , "-i")) { + bool_is_image = 1; + continue; + } + + if (!strcmp(argv[arg_index] , "-p")) { + bool_is_palette = 1; + continue; + } + + if (!strcmp(argv[arg_index] , "-a")) { + time_out = 10; + continue; + } + + if (bool_is_image) { + /* this is an image */ + /* allocate space to store the image name */ + image_name_arr[number_of_images] = (CHAR*) malloc(strlen(argv[arg_index] + 1)); + strcpy(image_name_arr[number_of_images] , argv[arg_index]); + + /* make the palette array for this NULL */ + pal_name_arr[number_of_images] = NULL; + number_of_images++; + bool_is_image = 0; + continue; + } + + if (bool_is_palette) { + /* this is a palette */ + /* allocate space to store the pal name */ + /* the palette was probably allocated for a previous image */ + pal_name_arr[number_of_images-1] = (CHAR*) malloc(strlen(argv[arg_index] + 1)); + strcpy(pal_name_arr[number_of_images - 1], argv[arg_index]); + bool_is_palette = 0; + continue; + } + + /* oops. This was not meant to happen */ + usage(); + +#if 0 + while (number_of_images--) { + cleanup(image_name_arr[number_of_images]); + cleanup(pal_name_arr[number_of_images]); + } +#endif /* 0 */ + + return -1; + } + + /* we shall always have a palette - read hdf will see to that */ + has_local_palette = true; + + /* Do Endian Order testing and set Endian Order */ + w = 0x0001; + b = (BYTE *) &w; + EndianOrder = (b[0] ? 1:0); + + if (!(fpGif = fopen(GIFName , "wb"))) { + printf("Error opening gif file for output. Aborting.\n"); + return -1; + } + + /* hardwire n_images to 1 for now. */ + n_images = number_of_images; + + Background = 0; + for (idx = 0 ; idx < n_images ; idx++) { + /* try to read the image and the palette */ + + /* + * Lots of funky stuff to support multiple images has been taken off. + * Just in case you're extending code, here's what you need to do in + * short: figure out if there is a global palette or not, if there is + * one store that one only. If they are all local or a combination of + * local and global palettes, you will have to write the global + * palette out and then independantly write the smaller local palettes + */ + if (ReadHDF(&Image, GlobalPalette, dim_sizes, HDFName, + image_name_arr[idx], pal_name_arr[idx]) < 0) { + fprintf(stderr , "Unable to read HDF file\n"); + return -1; + } + + w = dim_sizes[1]; + h = dim_sizes[0]; + + RWidth = dim_sizes[1]; + RHeight = dim_sizes[0]; + LeftOfs = TopOfs = 0; + + + /* + * If the first image does not have a palette, I make my own global + * color table Obviously this is not the best thing to do, better + * steps would be: + * + * 1. Check for either a global palette or a global attribute called + * palette + * 2. Check for palettes in any of the other images. + */ + if (!has_local_palette) { + for (i = 0 ; i < 256 ; i++) { + Red[i] = 255 - i; + Green[i] = 255 - i; + Blue[i] = 255 - i; + } + } else { + for (i = 0 ; i < 256 ; i++){ + Red[i] = GlobalPalette[i][0]; + Green[i] = GlobalPalette[i][1]; + Blue[i] = GlobalPalette[i][2]; + } + } + + for (i = 0; i < 256; i++) { + pc2nc[i] = r1[i] = g1[i] = b1[i] = 0; + } + + /* compute number of unique colors */ + nc = 0; + + for (i = 0; i < numcols; i++) { + /* see if color #i is already used */ + for (j = 0; j < i; j++) { + if (Red[i] == Red[j] && Green[i] == Green[j] && Blue[i] == Blue[j]) + break; + } + + if (j==i) { + /* wasn't found */ + pc2nc[i] = nc; + r1[nc] = Red[i]; + g1[nc] = Green[i]; + b1[nc] = Blue[i]; + nc++; + } else { + pc2nc[i] = pc2nc[j]; + } + } + + /* figure out 'BitsPerPixel' */ + for (i = 1; i < 8; i++) { + if ((1<<i) >= nc) + break; + } + + BitsPerPixel = i; + ColorMapSize = 1 << BitsPerPixel; + + CountDown = w * h; /* # of pixels we'll be doing */ + + if (BitsPerPixel <= 1) + InitCodeSize = 2; + else + InitCodeSize = BitsPerPixel; + + curx = cury = 0; + + if (!fpGif) { + fprintf(stderr, "WriteGIF: file not open for writing\n" ); + return (1); + } + + /* + * If it is the first image we do all the header stuff that isn't + * required for the rest of the images. + */ + if (idx == 0) { + /* Write out the GIF header and logical screen descriptor */ + if (n_images > 1) { + fwrite("GIF89a", 1, 6, fpGif); /* the GIF magic number */ + loop_times = 0; + } else { + fwrite("GIF87a", 1, 6, fpGif); /* the GIF magic number */ + loop_times = 1; + } + + putword(RWidth, fpGif); /* screen descriptor */ + putword(RHeight, fpGif); + + i = 0x00; /* No, there is no color map */ + i |= (8-1)<<4; /* OR in the color resolution (hardwired 8) */ + i |= (BitsPerPixel - 1); /* OR in the # of bits per pixel */ + fputc(i,fpGif); + + fputc(Background,fpGif); /* background color */ + fputc(0, fpGif); /* future expansion byte */ + + /* + * If loop_times is 0 , put in the application extension to make + * the gif anime loop indefinitely + */ + if (time_out > 0) { + fputc(0x21 , fpGif); + fputc(0xFF , fpGif); + fputc(11 , fpGif); + fwrite("NETSCAPE2.0" , 1 , 11 , fpGif); + fputc(3 , fpGif); + fputc(1 , fpGif); + fputc(0 , fpGif); + fputc(0 , fpGif); + fputc(0 , fpGif); + } + } + + if (n_images > 1) { + /* write a graphic control block */ + fputc(0x21 , fpGif); + fputc(0xF9 , fpGif); + fputc(4 , fpGif); + fputc(4 , fpGif); + putword(time_out , fpGif); + fputc(255, fpGif); + fputc(0 , fpGif); + } + + /* + * Put Image Descriptor + * Hardwiring Left Offset and Top Offset to 0x00 + */ + fputc(0x2c , fpGif); + putword(0x00 , fpGif); + putword(0x00 , fpGif); + putword(RWidth , fpGif); + putword(RHeight , fpGif); + + /* since we always have a local color palette ... */ + fputc((0x80 | (BitsPerPixel - 1)) , fpGif); + + for (i = 0; i < ColorMapSize; i++) { + /* write out Global colormap */ + fputc(r1[i], fpGif); + fputc(g1[i], fpGif); + fputc(b1[i], fpGif); + } + + fputc(InitCodeSize , fpGif); + + i = hdfWriteGIF(fpGif , Image , 0 , (int)dim_sizes[0] , + (int)dim_sizes[1] , r1, g1 , b1 , pc2nc , 256 , 8 , + BitsPerPixel); + fputc(0x00, fpGif); + free(Image); + } + + if (fputc(';',fpGif) == EOF) { + /* Write GIF file terminator */ + fprintf(stderr , "Error!"); + return -1; + } + + fclose(fpGif); + +#if 0 + while(number_of_images--) { + if (image_name_arr[number_of_images]) + free(image_name_arr[number_of_images]); + if (pal_name_arr[number_of_images]) + free(pal_name_arr[number_of_images]); + } +#endif /* 0 */ + + return 0; } diff --git a/tools/gifconv/hdfgifwr.c b/tools/gifconv/hdfgifwr.c index 62b3eae..e5f79e2 100644 --- a/tools/gifconv/hdfgifwr.c +++ b/tools/gifconv/hdfgifwr.c @@ -1,17 +1,17 @@ /* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + * * hdfgifwr.c - handles writing of GIF files. * * Contains: * hdfWriteGIF(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle, - * comment) + * comment) * * Note: slightly brain-damaged, in that it'll only write non-interlaced * GIF files (in the interests of speed, or something) - * */ - - /***************************************************************** * Portions of this code Copyright (C) 1989 by Michael Mauldin. * Permission is granted to use this file in whole or in @@ -36,10 +36,11 @@ #include <stdio.h> -#include "gif.h" #include <stdlib.h> #include <string.h> +#include "gif.h" + typedef BYTE byte; typedef long int count_int; @@ -77,59 +78,58 @@ static void flush_char(void); #else static void compress(), output(), cl_block(), cl_hash(); static void char_init(), char_out(), flush_char(); -#endif +#endif /* __STDC__ */ static byte pc2nc[256],r1[256],g1[256],b1[256]; /*************************************************************/ int hdfWriteGIF(FILE *fp, byte *pic, int ptype, int w, int h, byte *rmap, - byte *gmap, byte *bmap, byte *pc2ncmap, int numcols, int colorstyle, - int BitsPerPixel) + byte *gmap, byte *bmap, byte *pc2ncmap, int numcols, + int colorstyle, int BitsPerPixel) { - int RWidth, RHeight; - int LeftOfs, TopOfs; - int ColorMapSize, InitCodeSize, Background; - int i; - byte *pic8; - pic8 = pic; - - Interlace = 0; - Background = 0; - - for (i=0; i<256; i++) { - pc2nc[i] = pc2ncmap[i]; - r1[i] = rmap[i]; - g1[i] = gmap[i]; - b1[i] = bmap[i]; - } - - ColorMapSize = 1 << BitsPerPixel; - - RWidth = Width = w; - RHeight = Height = h; - LeftOfs = TopOfs = 0; - - CountDown = w * h; /* # of pixels we'll be doing */ - - if (BitsPerPixel <= 1) InitCodeSize = 2; - else InitCodeSize = BitsPerPixel; - - curx = cury = 0; - - if (!fp) { - fprintf(stderr, "WriteGIF: file not open for writing\n" ); - return (1); - } - - compress(InitCodeSize+1, fp, pic8, w*h); - - - if (ferror(fp)) return -1; - return (0); -} + int RWidth, RHeight; + int LeftOfs, TopOfs; + int ColorMapSize, InitCodeSize, Background; + int i; + byte *pic8 = pic; + + Interlace = 0; + Background = 0; + + for (i = 0; i < 256; i++) { + pc2nc[i] = pc2ncmap[i]; + r1[i] = rmap[i]; + g1[i] = gmap[i]; + b1[i] = bmap[i]; + } + + ColorMapSize = 1 << BitsPerPixel; + + RWidth = Width = w; + RHeight = Height = h; + LeftOfs = TopOfs = 0; + CountDown = w * h; /* # of pixels we'll be doing */ + if (BitsPerPixel <= 1) + InitCodeSize = 2; + else + InitCodeSize = BitsPerPixel; + + curx = cury = 0; + + if (!fp) { + fprintf(stderr, "WriteGIF: file not open for writing\n" ); + return (1); + } + + compress(InitCodeSize+1, fp, pic8, w*h); + + if (ferror(fp)) + return -1; + return 0 ; +} /***********************************************************************/ static unsigned long cur_accum = 0; @@ -142,6 +142,7 @@ static int cur_bits = 0; #define HSIZE 5003 /* 80% occupancy */ typedef unsigned char char_type; + static int n_bits; /* number of bits/code */ static int maxbits = XV_BITS; /* user settable max # bits/code */ static int maxcode; /* maximum code, given n_bits */ @@ -149,6 +150,7 @@ static int maxmaxcode = 1 << XV_BITS; /* NEVER generate this */ static count_int htab [HSIZE]; static unsigned short codetab [HSIZE]; + #define HashTabOf(i) htab[i] #define CodeTabOf(i) codetab[i] @@ -156,11 +158,11 @@ static int hsize = HSIZE; /* for dynamic table sizing */ /* * To save much memory, we overlay the table used by compress() with those - * used by decompress(). The tab_prefix table is the same size and type - * as the codetab. The tab_suffix table needs 2**BITS characters. We - * get this from the beginning of htab. The output stack uses the rest - * of htab, and contains characters. There is plenty of room for any - * possible stack (stack used to be 8000 characters). + * used by decompress(). The tab_prefix table is the same size and type as + * the codetab. The tab_suffix table needs 2**BITS characters. We get this + * from the beginning of htab. The output stack uses the rest of htab, and + * contains characters. There is plenty of room for any possible stack (stack + * used to be 8000 characters). */ #define tab_prefixof(i) CodeTabOf(i) @@ -181,17 +183,17 @@ static long int out_count = 0; /* # of codes output (for debugging) */ /* * compress stdin to stdout * - * Algorithm: use open addressing double hashing (no chaining) on the - * prefix code / next character combination. We do a variant of Knuth's - * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime - * secondary probe. Here, the modular division first probe is gives way - * to a faster exclusive-or manipulation. Also do block compression with - * an adaptive reset, whereby the code table is cleared when the compression - * ratio decreases, but after the table fills. The variable-length output - * codes are re-sized at this point, and a special CLEAR code is generated - * for the decompressor. Late addition: construct the table according to - * file size for noticeable speed improvement on small files. Please direct - * questions about this implementation to ames!jaw. + * Algorithm: use open addressing double hashing (no chaining) on the prefix + * code / next character combination. We do a variant of Knuth's algorithm D + * (vol. 3, sec. 6.4) along with G. Knott's relatively-prime secondary probe. + * Here, the modular division first probe is gives way to a faster + * exclusive-or manipulation. Also do block compression with an adaptive + * reset, whereby the code table is cleared when the compression ratio + * decreases, but after the table fills. The variable-length output codes are + * re-sized at this point, and a special CLEAR code is generated for the + * decompressor. Late addition: construct the table according to file size + * for noticeable speed improvement on small files. Please direct questions + * about this implementation to ames!jaw. */ static int g_init_bits; @@ -201,114 +203,111 @@ static int ClearCode; static int EOFCode; /********************************************************/ -static void compress(init_bits, outfile, data, len) -int init_bits; -FILE *outfile; -byte *data; -int len; +static void compress(int init_bits, FILE *outfile, byte *data, int len) { - register long fcode; - register int i = 0; - register int c; - register int ent; - register int disp; - register int hsize_reg; - register int hshift; - - /* - * Set up the globals: g_init_bits - initial number of bits - * g_outfile - pointer to output file - */ - g_init_bits = init_bits; - g_outfile = outfile; - - /* initialize 'compress' globals */ - maxbits = XV_BITS; - maxmaxcode = 1<<XV_BITS; - memset(htab, 0, sizeof(htab)); - memset(codetab, 0, sizeof(codetab)); - hsize = HSIZE; - free_ent = 0; - clear_flg = 0; - in_count = 1; - out_count = 0; - cur_accum = 0; - cur_bits = 0; - - - /* - * Set up the necessary values - */ - out_count = 0; - clear_flg = 0; - in_count = 1; - maxcode = MAXCODE(n_bits = g_init_bits); - - ClearCode = (1 << (init_bits - 1)); - EOFCode = ClearCode + 1; - free_ent = ClearCode + 2; - - char_init(); - ent = pc2nc[*data++]; len--; - - hshift = 0; - for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L ) - hshift++; - hshift = 8 - hshift; /* set hash code range bound */ - - hsize_reg = hsize; - cl_hash( (count_int) hsize_reg); /* clear hash table */ - - output(ClearCode); - - while (len) { - c = pc2nc[*data++]; len--; - in_count++; - - fcode = (long) ( ( (long) c << maxbits) + ent); - i = (((int) c << hshift) ^ ent); /* xor hashing */ - - if ( HashTabOf (i) == fcode ) { - ent = CodeTabOf (i); - continue; - } - - else if ( (long)HashTabOf (i) < 0 ) /* empty slot */ - goto nomatch; - - disp = hsize_reg - i; /* secondary hash (after G. Knott) */ - if ( i == 0 ) - disp = 1; + register long fcode; + register int i = 0; + register int c; + register int ent; + register int disp; + register int hsize_reg; + register int hshift; + + /* + * Set up the globals: g_init_bits - initial number of bits g_outfile - + * pointer to output file + */ + g_init_bits = init_bits; + g_outfile = outfile; + + /* initialize 'compress' globals */ + maxbits = XV_BITS; + maxmaxcode = 1<<XV_BITS; + memset(htab, 0, sizeof(htab)); + memset(codetab, 0, sizeof(codetab)); + hsize = HSIZE; + free_ent = 0; + clear_flg = 0; + in_count = 1; + out_count = 0; + cur_accum = 0; + cur_bits = 0; + + /* Set up the necessary values */ + out_count = 0; + clear_flg = 0; + in_count = 1; + maxcode = MAXCODE(n_bits = g_init_bits); + + ClearCode = (1 << (init_bits - 1)); + EOFCode = ClearCode + 1; + free_ent = ClearCode + 2; + + char_init(); + ent = pc2nc[*data++]; + len--; + + hshift = 0; + for (fcode = (long)hsize; fcode < 65536L; fcode *= 2L ) + hshift++; + + hshift = 8 - hshift; /* set hash code range bound */ + + hsize_reg = hsize; + cl_hash( (count_int) hsize_reg); /* clear hash table */ + + output(ClearCode); + + while (len) { + c = pc2nc[*data++]; + len--; + in_count++; + + fcode = (long)(((long) c << maxbits) + ent); + i = (((int) c << hshift) ^ ent); /* xor hashing */ + + if ( HashTabOf (i) == fcode ) { + ent = CodeTabOf (i); + continue; + } else if ( (long)HashTabOf (i) < 0) { + /* empty slot */ + goto nomatch; + } + + disp = hsize_reg - i; /* secondary hash (after G. Knott) */ + + if ( i == 0 ) + disp = 1; probe: - if ( (i -= disp) < 0 ) - i += hsize_reg; + if ((i -= disp) < 0) + i += hsize_reg; - if ( HashTabOf (i) == fcode ) { - ent = CodeTabOf (i); - continue; - } + if (HashTabOf (i) == fcode) { + ent = CodeTabOf (i); + continue; + } - if ( (long)HashTabOf (i) >= 0 ) - goto probe; + if ((long)HashTabOf (i) >= 0) + goto probe; nomatch: - output(ent); - out_count++; - ent = c; - - if ( free_ent < maxmaxcode ) { - CodeTabOf (i) = free_ent++; /* code -> hashtable */ - HashTabOf (i) = fcode; + output(ent); + out_count++; + ent = c; + + if (free_ent < maxmaxcode) { + CodeTabOf (i) = free_ent++; /* code -> hashtable */ + HashTabOf (i) = fcode; + } else { + cl_block(); + } } - else - cl_block(); - } - /* Put out the final code */ - output(ent); - out_count++; - output(EOFCode); + /* Put out the final code */ + output(ent); + out_count++; + output(EOFCode); } @@ -335,111 +334,104 @@ unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; -static void output(code) -int code; +static void +output(int code) { - cur_accum &= masks[cur_bits]; - - if (cur_bits > 0) - cur_accum |= ((long)code << cur_bits); - else - cur_accum = code; - - cur_bits += n_bits; - - while( cur_bits >= 8 ) { - char_out( (int)((unsigned int) cur_accum & 0xff) ); - cur_accum >>= 8; - cur_bits -= 8; - } - - /* - * If the next entry is going to be too big for the code size, - * then increase it, if possible. - */ - - if (free_ent > maxcode || clear_flg) { - - if( clear_flg ) { - maxcode = MAXCODE (n_bits = g_init_bits); - clear_flg = 0; - } - else { - n_bits++; - if ( n_bits == maxbits ) - maxcode = maxmaxcode; - else - maxcode = MAXCODE(n_bits); - } - } - - if( code == EOFCode ) { - /* At EOF, write the rest of the buffer */ - while( cur_bits > 0 ) { - char_out( (int)((unsigned int)cur_accum & 0xff) ); - cur_accum >>= 8; - cur_bits -= 8; + cur_accum &= masks[cur_bits]; + + if (cur_bits > 0) + cur_accum |= ((long)code << cur_bits); + else + cur_accum = code; + + cur_bits += n_bits; + + while( cur_bits >= 8 ) { + char_out( (int)((unsigned int) cur_accum & 0xff) ); + cur_accum >>= 8; + cur_bits -= 8; } - flush_char(); - - fflush( g_outfile ); + /* + * If the next entry is going to be too big for the code size, then + * increase it, if possible. + */ + if (free_ent > maxcode || clear_flg) { + if (clear_flg) { + maxcode = MAXCODE (n_bits = g_init_bits); + clear_flg = 0; + } else { + n_bits++; + + if ( n_bits == maxbits ) + maxcode = maxmaxcode; + else + maxcode = MAXCODE(n_bits); + } + } + + if (code == EOFCode) { + /* At EOF, write the rest of the buffer */ + while( cur_bits > 0 ) { + char_out( (int)((unsigned int)cur_accum & 0xff) ); + cur_accum >>= 8; + cur_bits -= 8; + } + + flush_char(); + fflush( g_outfile ); #ifdef FOO - if( ferror( g_outfile ) ) - FatalError("unable to write GIF file"); + if(ferror( g_outfile)) + FatalError("unable to write GIF file"); #endif - } + } } - /********************************/ -static void cl_block () /* table clear for block compress */ +static void +cl_block(void) /* table clear for block compress */ { - /* Clear out the hash table */ - - cl_hash ( (count_int) hsize ); - free_ent = ClearCode + 2; - clear_flg = 1; - - output(ClearCode); + /* Clear out the hash table */ + cl_hash((count_int) hsize); + free_ent = ClearCode + 2; + clear_flg = 1; + output(ClearCode); } - /********************************/ -static void cl_hash(hashsize) /* reset code table */ -count_int hashsize; +static void +cl_hash(count_int hashsize) /* reset code table */ { - count_int *htab_p = htab+hashsize; - long i; - long m1 = -1; - - i = hashsize - 16; - do { /* might use Sys V memset(3) here */ - *(htab_p-16) = m1; - *(htab_p-15) = m1; - *(htab_p-14) = m1; - *(htab_p-13) = m1; - *(htab_p-12) = m1; - *(htab_p-11) = m1; - *(htab_p-10) = m1; - *(htab_p-9) = m1; - *(htab_p-8) = m1; - *(htab_p-7) = m1; - *(htab_p-6) = m1; - *(htab_p-5) = m1; - *(htab_p-4) = m1; - *(htab_p-3) = m1; - *(htab_p-2) = m1; - *(htab_p-1) = m1; - htab_p -= 16; - } while ((i -= 16) >= 0); - - for ( i += 16; i > 0; i-- ) - *--htab_p = m1; + count_int *htab_p = htab+hashsize; + long i, m1 = -1; + + i = hashsize - 16; + + do { /* might use Sys V memset(3) here */ + *(htab_p-16) = m1; + *(htab_p-15) = m1; + *(htab_p-14) = m1; + *(htab_p-13) = m1; + *(htab_p-12) = m1; + *(htab_p-11) = m1; + *(htab_p-10) = m1; + *(htab_p-9) = m1; + *(htab_p-8) = m1; + *(htab_p-7) = m1; + *(htab_p-6) = m1; + *(htab_p-5) = m1; + *(htab_p-4) = m1; + *(htab_p-3) = m1; + *(htab_p-2) = m1; + *(htab_p-1) = m1; + htab_p -= 16; + } while ((i -= 16) >= 0); + + for ( i += 16; i > 0; i-- ) + *--htab_p = m1; } - /****************************************************************************** * * GIF Specific routines @@ -454,9 +446,10 @@ static int a_count; /* * Set up the 'byte output' routine */ -static void char_init() +static void +char_init(void) { - a_count = 0; + a_count = 0; } /* @@ -468,21 +461,24 @@ static char accum[ 256 ]; * Add a character to the end of the current packet, and if it is 254 * characters, flush the packet to disk. */ -static void char_out(int c) +static void +char_out(int c) { - accum[ a_count++ ] = c; - if( a_count >= 254 ) - flush_char(); + accum[ a_count++ ] = c; + + if (a_count >= 254) + flush_char(); } /* * Flush the packet to disk, and reset the accumulator */ -static void flush_char() +static void +flush_char(void) { - if( a_count > 0 ) { - fputc( a_count, g_outfile ); - fwrite( accum, 1, (size_t)a_count, g_outfile ); - a_count = 0; - } -} + if (a_count > 0) { + fputc( a_count, g_outfile ); + fwrite( accum, 1, (size_t)a_count, g_outfile); + a_count = 0; + } +} diff --git a/tools/gifconv/readhdf.c b/tools/gifconv/readhdf.c index 76bfb86..912c2c6 100644 --- a/tools/gifconv/readhdf.c +++ b/tools/gifconv/readhdf.c @@ -1,19 +1,25 @@ +/* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + */ #include "gif.h" /* just a small cleanup routine before we leave */ -void cleanup(BYTE *ptr) { - if (ptr) - free(ptr); +void +cleanup(BYTE *ptr) +{ + if (ptr) + free(ptr); } -/* Function : ReadHDF -** Return: 0 on completion without error, -1 on error -** Input: CHAR *h5_file - HDF file name -** CHAR *dset_name - Name of the HDF Image dataset -** CHAR *pal_name - Name of the HDF palette -** Output : BYTE** data - the HDF Image to be converted -** BYTE palette[256][3] - the corresponding palette -** hsize_t* image_size - the size of each dimension of the image +/* Function: ReadHDF +** Return: 0 on completion without error, -1 on error +** Input: CHAR *h5_file - HDF file name +** CHAR *dset_name - Name of the HDF Image dataset +** CHAR *pal_name - Name of the HDF palette +** Output: BYTE** data - the HDF Image to be converted +** BYTE palette[256][3] - the corresponding palette +** hsize_t* image_size - the size of each dimension of the image ** ** Future Notes: ** The way readHDF works right now is that it expects the user @@ -24,146 +30,144 @@ void cleanup(BYTE *ptr) { ** palette and throws it in. ** */ -int ReadHDF(BYTE** data , - BYTE palette[256][3] , - hsize_t *image_size , - CHAR *h5_file , - CHAR *dset_name , - CHAR *pal_name) +int ReadHDF(BYTE** data, BYTE palette[256][3], hsize_t *image_size, + CHAR *h5_file, CHAR *dset_name, CHAR *pal_name) { - hid_t fHfile; /* H5 file to open */ - herr_t status; /* status variable */ - hid_t dspace; /* dataspace identifier for the the dataset */ - hid_t dset; /* dataset identifier */ - hid_t pal_set; /* dataset for palette */ - hid_t pal_space;/* dataspace for palette */ - hsize_t datasize; /* size of the image */ - int pal_exist = 0; /* do we have a palette? */ - - /* check stuff */ - if (!h5_file || !dset_name || !image_size) { - fprintf(stderr , "NULL is not an acceptable input for HDFread. Aborting.\n"); - return -1; - } - - /* do we have a palette ? */ - if (pal_name) { - pal_exist = 1; - } - - /* try opening the file */ - /* H5 file open calls */ - if ((fHfile = H5Fopen(h5_file , H5F_ACC_RDONLY , H5P_DEFAULT)) < 0) { - fprintf(stderr , "Unable to open HDF file for input. Aborting.\n"); - return -1; - } - - /* open the dataset for reading */ - if ((dset = H5Dopen(fHfile , dset_name)) < 0) { - fprintf(stderr , "Unable to open dataset\n"); - return -1; - } - - /* get the dataspace */ - if ((dspace = H5Dget_space(dset)) < 0) { - fprintf(stderr , "Unable to get dataspace\n"); - return -1; - } - - /* get the dimension size of the image */ - if (H5Sget_simple_extent_dims(dspace , image_size , NULL) !=2 ) { - fprintf(stderr , "Unable to get dimension info\n"); - return -1; - } - - /* size needed to store the image */ - datasize = image_size[0] * image_size[1]; - - /* allocate memory to store the image */ - if ((*data = (BYTE*) malloc((size_t)datasize)) == NULL) { - fprintf(stderr , "Out of memory, exiting"); - return -1; - } - - /* get the actual image */ - if ((status = H5Dread(dset , H5Dget_type(dset) , H5S_ALL , H5S_ALL , H5P_DEFAULT , *data)) < 0) { - fprintf(stderr , "Unable to read data \n"); - cleanup(*data); - return -1; - } - - if (pal_exist) { - hsize_t loc_pal_size[2]; - hsize_t pal_datasize; - BYTE *temp_buf; - hsize_t temp_size; - - /* get the palette dataset */ - if ((pal_set = H5Dopen(fHfile , pal_name)) < 0) { - fprintf(stderr , "Unable to open dataset\n"); - pal_exist = 0; - return -1; - } - - /* get the dataspace */ - if ((pal_space = H5Dget_space(pal_set)) < 0) { - fprintf(stderr , "Unable to get dataspace\n"); - pal_exist = 0; - return -1; - } - - /* get the dimension size of the palette. */ - if (H5Sget_simple_extent_dims(pal_space , loc_pal_size , NULL) !=2 ) { - fprintf(stderr , "Unable to get dimension info\n"); - pal_exist = 0; - return -1; - } - - /* size needed to store the image */ - pal_datasize = loc_pal_size[0] * loc_pal_size[1]; - - /* copy stuff into a temp buffer and then copy 256*3 elements to palette */ - temp_size = H5Dget_storage_size(pal_set); - - temp_buf = (BYTE*) malloc ((size_t)temp_size * sizeof(BYTE)); - - /* make sure that the palette is actually 256 X 3 so that we don't create overflows */ - if (pal_datasize > 256 * 3) - { - fprintf(stderr , "Palette seems to be more than 256X3 bytes\n"); - fprintf(stderr , "Truncating palette to 256 colors. This might cause a problem with the final image\n"); - pal_datasize = 256 * 3; - } - - /* get the actual palette */ - if ((status = H5Dread(pal_set , H5Dget_type(pal_set) , H5S_ALL , H5S_ALL , H5P_DEFAULT , temp_buf)) < 0) { - fprintf(stderr , "Unable to read data \n"); - cleanup(*data); - cleanup(temp_buf); - return -1; - } - - /* copy stuff into the actual palette */ - memcpy(palette , temp_buf , (size_t)pal_datasize); - - /* get rid of the temp memory */ - cleanup(temp_buf); - /* end of if (pal_exist) */ - - } else { - int i; - /* if palette does not exist we just go ahead and create a uniform greyscale palette */ - for (i = 0 ; i < 256 ; i++) { - palette[i][0] = 255 - i; - palette[i][1] = 255 - i; - palette[i][2] = 255 - i; - } - } - - /* close everything */ - status = H5Dclose(dset); - status = H5Sclose(dspace); - status = H5Fclose(fHfile); - - return 0; + hid_t fHfile; /* H5 file to open */ + herr_t status; /* status variable */ + hid_t dspace; /* dataspace identifier for the the dataset */ + hid_t dset; /* dataset identifier */ + hid_t pal_set; /* dataset for palette */ + hid_t pal_space; /* dataspace for palette */ + hsize_t datasize; /* size of the image */ + int pal_exist = 0; /* do we have a palette? */ + + /* check stuff */ + if (!h5_file || !dset_name || !image_size) { + fprintf(stderr, "NULL is not an acceptable input for HDFread. Aborting.\n"); + return -1; + } + + /* do we have a palette ? */ + if (pal_name) { + pal_exist = 1; + } + + /* try opening the file */ + /* H5 file open calls */ + if ((fHfile = H5Fopen(h5_file , H5F_ACC_RDONLY , H5P_DEFAULT)) < 0) { + fprintf(stderr , "Unable to open HDF file for input. Aborting.\n"); + return -1; + } + + /* open the dataset for reading */ + if ((dset = H5Dopen(fHfile , dset_name)) < 0) { + fprintf(stderr , "Unable to open dataset\n"); + return -1; + } + + /* get the dataspace */ + if ((dspace = H5Dget_space(dset)) < 0) { + fprintf(stderr , "Unable to get dataspace\n"); + return -1; + } + + /* get the dimension size of the image */ + if (H5Sget_simple_extent_dims(dspace , image_size , NULL) !=2 ) { + fprintf(stderr , "Unable to get dimension info\n"); + return -1; + } + + /* size needed to store the image */ + datasize = image_size[0] * image_size[1]; + + /* allocate memory to store the image */ + if ((*data = (BYTE*) malloc((size_t)datasize)) == NULL) { + fprintf(stderr , "Out of memory, exiting"); + return -1; + } + + /* get the actual image */ + if ((status = H5Dread(dset , H5Dget_type(dset) , H5S_ALL , H5S_ALL , H5P_DEFAULT , *data)) < 0) { + fprintf(stderr , "Unable to read data \n"); + cleanup(*data); + return -1; + } + + if (pal_exist) { + hsize_t loc_pal_size[2]; + hsize_t pal_datasize; + BYTE *temp_buf; + hsize_t temp_size; + + /* get the palette dataset */ + if ((pal_set = H5Dopen(fHfile , pal_name)) < 0) { + fprintf(stderr , "Unable to open dataset\n"); + pal_exist = 0; + return -1; + } + + /* get the dataspace */ + if ((pal_space = H5Dget_space(pal_set)) < 0) { + fprintf(stderr , "Unable to get dataspace\n"); + pal_exist = 0; + return -1; + } + + /* get the dimension size of the palette. */ + if (H5Sget_simple_extent_dims(pal_space , loc_pal_size , NULL) !=2 ) { + fprintf(stderr , "Unable to get dimension info\n"); + pal_exist = 0; + return -1; + } + + /* size needed to store the image */ + pal_datasize = loc_pal_size[0] * loc_pal_size[1]; + + /* copy stuff into a temp buffer and then copy 256*3 elements to palette */ + temp_size = H5Dget_storage_size(pal_set); + temp_buf = (BYTE*) malloc ((size_t)temp_size * sizeof(BYTE)); + + /* + * make sure that the palette is actually 256 X 3 so that we don't + * create overflows + */ + if (pal_datasize > 256 * 3) { + fprintf(stderr , "Palette seems to be more than 256X3 bytes\n"); + fprintf(stderr , "Truncating palette to 256 colors. This might cause a problem with the final image\n"); + pal_datasize = 256 * 3; + } + + /* get the actual palette */ + if ((status = H5Dread(pal_set , H5Dget_type(pal_set) , H5S_ALL , H5S_ALL , H5P_DEFAULT , temp_buf)) < 0) { + fprintf(stderr , "Unable to read data \n"); + cleanup(*data); + cleanup(temp_buf); + return -1; + } + + /* copy stuff into the actual palette */ + memcpy(palette , temp_buf , (size_t)pal_datasize); + + /* get rid of the temp memory */ + cleanup(temp_buf); + /* end of if (pal_exist) */ + } else { + int i; + /* + * if palette does not exist we just go ahead and create a uniform + * greyscale palette + */ + for (i = 0 ; i < 256 ; i++) { + palette[i][0] = 255 - i; + palette[i][1] = 255 - i; + palette[i][2] = 255 - i; + } + } + + /* close everything */ + status = H5Dclose(dset); + status = H5Sclose(dspace); + status = H5Fclose(fHfile); + return 0; } diff --git a/tools/gifconv/writehdf.c b/tools/gifconv/writehdf.c index 313b57e..4d69d01 100644 --- a/tools/gifconv/writehdf.c +++ b/tools/gifconv/writehdf.c @@ -1,402 +1,401 @@ -#include "gif.h" +/* + * Copyright (C) 2001 National Center for Supercomputing Applications + * All rights reserved. + */ #include <string.h> #include <stdlib.h> #include <string.h> +#include "gif.h" + /******************************************************************* -** Function: write_text_attribute -** Use: Just a small wrapper to write text attributes easily -********************************************************************/ -static int write_text_attribute(hid_t dataset_id , const char *attr_name , const char *attr_value) + * Function: write_text_attribute + * Use: Just a small wrapper to write text attributes easily + *******************************************************************/ +static int write_text_attribute(hid_t dataset_id , const char *attr_name, + const char *attr_value) { - - /* variables for the attributes */ - hsize_t attr_dims_size; /* dimensions for the attribute */ - hid_t attr_dataspace_id; /* dataspaces needed for the various attributes */ - hid_t attr_attr_id; /* attribute id */ - herr_t status; /* check return status */ - hid_t attr_type_id; - - - /* check strings */ - if (!attr_name || !attr_value) - return -1; - - /* figure out size of the data */ - attr_dims_size = strlen(attr_value) + 1; - - /* set the type to string */ - attr_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(attr_type_id , (size_t)attr_dims_size); - - /* create the dataspace for the attribute */ - attr_dataspace_id = H5Screate_simple(1 , &attr_dims_size , NULL); - - /* create the attribute */ - attr_attr_id = H5Acreate(dataset_id , attr_name , attr_type_id , attr_dataspace_id , H5P_DEFAULT); - - /* write out the attribute data */ - if ((status = H5Awrite(attr_attr_id , attr_type_id , attr_value)) < 0) - return -1; - - /* close the attribute */ - if ((status = H5Aclose(attr_attr_id)) < 0) - return -1; - - /* close the dataspace */ - if ((status = H5Sclose(attr_dataspace_id)) < 0) { - fprintf(stderr , "Unable to close attribute dataspace. Aborting \n"); - return -1; - } - - return 0; - + /* variables for the attributes */ + hsize_t attr_dims_size; /* dimensions for the attribute */ + hid_t attr_dataspace_id; /* dataspaces needed for the various attributes */ + hid_t attr_attr_id; /* attribute id */ + herr_t status; /* check return status */ + hid_t attr_type_id; + + /* check strings */ + if (!attr_name || !attr_value) + return -1; + + /* figure out size of the data */ + attr_dims_size = strlen(attr_value) + 1; + + /* set the type to string */ + attr_type_id = H5Tcopy(H5T_C_S1); + H5Tset_size(attr_type_id , (size_t)attr_dims_size); + + /* create the dataspace for the attribute */ + attr_dataspace_id = H5Screate_simple(1 , &attr_dims_size , NULL); + + /* create the attribute */ + attr_attr_id = H5Acreate(dataset_id , attr_name , attr_type_id , + attr_dataspace_id , H5P_DEFAULT); + + /* write out the attribute data */ + if ((status = H5Awrite(attr_attr_id , attr_type_id , attr_value)) < 0) + return -1; + + /* close the attribute */ + if ((status = H5Aclose(attr_attr_id)) < 0) + return -1; + + /* close the dataspace */ + if ((status = H5Sclose(attr_dataspace_id)) < 0) { + fprintf(stderr , "Unable to close attribute dataspace. Aborting \n"); + return -1; + } + + return 0; } int -WriteHDF(GifMemoryStruct, HDFName , GIFFileName) -GIFTOMEM GifMemoryStruct; -char *HDFName; -char *GIFFileName; +WriteHDF(GIFTOMEM GifMemoryStruct, char *HDFName , char *GIFFileName) { - GIFHEAD gifHead; /* GIF Header structure */ - GIFIMAGEDESC* gifImageDesc; /* Logical Image Descriptor struct */ - - long ImageCount , /* number of images */ - CommentCount, /* number of comments */ - ApplicationCount , /* number of application extensions */ - PlainTextCount; /* number of plain text extensions */ - - char ImageName[256]; /* Image name for the GR Image */ - char GroupName[VSNAMELENMAX]; /* so that we can name the subgroups appropriately */ - - /* H5 variables */ - hid_t file_id; /* H5 file id */ - hid_t image_id; /* H5 id for the whole image */ - hid_t pal_id; /* H5 id for the palette */ - herr_t status; /* status variable */ - hobj_ref_t pal_ref; /* Create a reference for the palette */ - - /* temp counter */ - int i; - - /* get the GIFMem stuff */ - gifHead = *(GifMemoryStruct.GifHeader); - - /* get some data from gifHead */ - ImageCount = (WORD)gifHead.ImageCount; - CommentCount = (WORD)gifHead.CommentCount; - ApplicationCount = (WORD)gifHead.ApplicationCount; - PlainTextCount = (WORD)gifHead.PlainTextCount; - - /* get the main group name from GIFFileName */ - GroupName[0]= '/'; - if (strncpy(GroupName , GIFFileName , VSNAMELENMAX-2) == NULL) { - fprintf(stderr , "strncpy failed\n"); - exit(1); - } - GroupName[VSNAMELENMAX - 1] = '\0'; - - - if ((file_id = H5Fcreate(HDFName , H5F_ACC_TRUNC , H5P_DEFAULT , H5P_DEFAULT)) < 0) { - /* error occured opening the HDF File for write */ - fprintf(stderr , "HDF file could not be opened for writing\n"); - fprintf(stderr , "NOTE: GIF file must be present in the same directory as the binary on UNIX systems.\n"); - exit(1); - } - - /* create a group within the root group to hold the gif image */ - /* might want to make a different naming style out here */ - image_id = H5Gcreate(file_id, GroupName , 0); - - /* first create the global palette if there is one */ - if (gifHead.PackedField & 0x80) { /* global palette exists */ - hid_t dataspace_id; /* identifier for dataspace */ - hsize_t dims[2]; /* specify the dimensions of the palette */ - - hsize_t dimsr[1] = {1}; /* needed to store reference */ - hid_t ref_dataspace_id; /* dataspace id for references */ - hid_t ref_dataset_id; /* dataset id for references */ - - /* size of the palette is tablesize (rows) X 3 (columns) */ - dims[0] = gifHead.TableSize; - dims[1] = 3; - - /* create the dataspace */ - if ((dataspace_id = H5Screate_simple(2 , dims , NULL)) < 0) { - fprintf(stderr , "Could not create dataspace for palette. Aborting...\n"); - return -1; - } - - /* create the palette dataset */ - if ((pal_id = H5Dcreate(image_id , "Global Palette" , H5T_NATIVE_UINT8 , dataspace_id , H5P_DEFAULT )) < 0) { - fprintf(stderr , "Could not create palette dataset. Aborting...\n"); - return -1; - } - - /* write the palette data out */ - /****** Ask Elena about VOIDP ******/ - if ((status = H5Dwrite(pal_id , H5T_NATIVE_UINT8 , H5S_ALL , H5S_ALL , H5P_DEFAULT , (void *)gifHead.HDFPalette)) < 0) { - fprintf(stderr , "Error writing dataset. Aborting...\n"); - return -1; - } - - /* set palette attributes */ - - /* attribute CLASS = PALETTE */ - if ((write_text_attribute(pal_id , "CLASS" , "PALETTE")) < 0) { - fprintf(stderr , "Unable to write palette attributes. Aborting\n"); - return -1; - } - - /* attribute PAL_COLORMODEL = RGB */ - if ((write_text_attribute(pal_id , "PAL_COLORMODEL" , "RGB")) < 0) { - fprintf(stderr , "Unable to write palette attributes. Aborting\n"); - return -1; - } - - /* attribute PAL_TYPE = STANDARD8 */ - if ((write_text_attribute(pal_id , "PAL_TYPE" , "STANDARD8")) < 0) { - fprintf(stderr , "Unable to write palette attributes. Aborting\n"); - return -1; - } - - /* attribute PAL_VERSION = 1.0 */ - if ((write_text_attribute(pal_id , "PAL_VERSION" , "1.0")) < 0) { - fprintf(stderr , "Unable to write palette attributes. Aborting\n"); - return -1; - } - - /* create dataspace for the dataset to store references */ - ref_dataspace_id = H5Screate_simple(1 , dimsr , NULL); - - /* create a dataset to store the references */ - ref_dataset_id = H5Dcreate(image_id , "Palette Reference" , H5T_STD_REF_OBJ , ref_dataspace_id , H5P_DEFAULT); - - /* create a reference to the palette */ - if ((status = H5Rcreate(&pal_ref , image_id , "Global Palette" , H5R_OBJECT , -1)) < 0) { - fprintf(stderr , "Unable to create palette reference\n"); - return -1; - } - - /* write the reference out */ - if ((status = H5Dwrite(ref_dataset_id , H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL , H5P_DEFAULT, &pal_ref)) < 0) { - fprintf(stderr , "Unable to write Palette Reference"); - return -1; - } - - /* close dataset */ - if ((status = H5Dclose(ref_dataset_id)) < 0) { - fprintf(stderr , "Unable to close palette dataset.\n"); - return -1; - } - - /* close dataspace */ - if ((status = H5Sclose(ref_dataspace_id)) < 0) { - fprintf(stderr , "Unable to close palette dataspace.\n"); - return -1; - } - - /* close everything */ - if ((status = H5Dclose(pal_id)) < 0) { - fprintf(stderr , "Unable to close palette dataset. Aborting.\n"); - return -1; - } - - if ((status = H5Sclose(dataspace_id)) < 0) { - fprintf(stderr , "Unable to close palette dataspace. Aborting.\n"); - return -1; - } - - } - - for(i=0 ; i < ImageCount ; i++) { - /* variables for the images */ - hsize_t dims[2]; /* dimensions for the dataset */ - hid_t dataspace_id; /* identifier for the dataspace */ - hid_t sub_image_id; /* wierd name to distinguish from the group_id */ - - /* variables for the attributes */ - hsize_t attr_dims[2]; /* dimensions for the attribute */ - hid_t attr_dataspace_id; /* dataspaces needed for the various attributes */ - hid_t attr_attr_id; /* attribute id */ - BYTE minmax[2]; /* lower and upper minmax values */ - - /* initialise minmax */ - minmax[0] = 0 ; minmax[1] = 255; - - /* get the gifImageDesc */ - gifImageDesc = GifMemoryStruct.GifImageDesc[i]; - - /* set the dimensions */ - dims[0] = gifImageDesc->ImageHeight; - dims[1] = gifImageDesc->ImageWidth; - - /* create the empty dataspace */ - if ((dataspace_id = H5Screate_simple(2 , dims , NULL)) < 0) { - fprintf(stderr , "Could not create image dataspace. Aborting\n"); - return -1; - } - - /* create the image name */ - sprintf(ImageName , "Image%d" , i); - - /* create the image data set */ - if ((sub_image_id = H5Dcreate(image_id , ImageName , H5T_NATIVE_UINT8 , dataspace_id , H5P_DEFAULT)) < 0) { - fprintf(stderr , "Could not create dataset for image. Aborting... \n"); - return -1; - } - - /* write out the image */ - /****** Ask Elena about VOIDP ******/ - if ((status = H5Dwrite(sub_image_id , H5T_NATIVE_UINT8 , H5S_ALL , H5S_ALL , H5P_DEFAULT , (void *)(gifImageDesc->Image))) < 0) { - fprintf(stderr , "Error writing image. Aborting... \n"); - return -1; - } - - /* set the attributes */ - /* This info is available at http://hdf.ncsa.uiuc.edu/HDF5/doc/ImageSpec.html */ - /* The following attributes must be set for each image: - ** --------------------------------------- - ** Attribute Name Value - ** CLASS IMAGE - ** IMAGE_VERSION 1.0 - ** IMAGE_SUBCLASS IMAGE_BITMAP - ** PALETTE ref. to palette datasets - ** IMAGE_MINMAXRANGE [0,255] - ** --------------------------------------- - */ - - /**************************************** - ** Attribute: CLASS - ** Value : IMAGE - *****************************************/ - - if (write_text_attribute(sub_image_id , "CLASS" , "IMAGE") < 0) { - fprintf(stderr , "Unable to write CLASS = IMAGE attribute\n"); - return -1; - } - - /**************************************** - ** Attribute: IMAGE_VERSION - ** Value : 1.0 - *****************************************/ - - if (write_text_attribute(sub_image_id , "IMAGE_VERSION" , "1.0") < 0) { - fprintf(stderr , "Unable to write IMAGE_VERSION attribute\n"); - return -1; - } - - /**************************************** - ** Attribute: IMAGE_SUBCLASS - ** Value : IMAGE_BITMAP - *****************************************/ - - if (write_text_attribute(sub_image_id , "IMAGE_SUBCLASS" , "IMAGE_BITMAP") < 0) { - fprintf(stderr , "Unable to write IMAGE_SUBCLASS attribute\n"); - return -1; - } - - /**************************************** - ** Attribute: IMAGE_COLORMODEL - ** Value : RGB - *****************************************/ - - if (write_text_attribute(sub_image_id , "IMAGE_COLORMODEL" , "RGB") < 0) { - fprintf(stderr , "Unable to write IMAGE_SUBCLASS attribute\n"); - return -1; - } - - /**************************************** - ** Attribute: PALETTE - ** Value : Reference to Palette - *****************************************/ - - /**** MAKE SURE PALETTE EXISTS!!! ****/ - if (gifHead.PackedField & 0x80) { /* global palette exists */ - - attr_dims[0] = 1; - - /* create the dataspace for the attribute */ - attr_dataspace_id = H5Screate_simple(1 , attr_dims , NULL); - - /* create the attribute */ - attr_attr_id = H5Acreate(sub_image_id , "PALETTE" , H5T_STD_REF_OBJ , attr_dataspace_id , H5P_DEFAULT); - - if ((status = H5Awrite(attr_attr_id , H5T_STD_REF_OBJ , &pal_ref)) < 0) { - fprintf(stderr , "Unable to write attribute. Aborting \n"); - return -1; - } - - /* close the attribute */ - if ((status = H5Aclose(attr_attr_id)) < 0) { - fprintf(stderr , "Unable to close CLASS IMAGE attribute. Aborting.\n"); - return -1; - } - - /* close the dataspace */ - if ((status = H5Sclose(attr_dataspace_id)) < 0) { - fprintf(stderr , "Unable to close attribute dataspace. Aborting \n"); - return -1; - } - - } - - /**************************************** - ** Attribute: IMAGE_MINMAXRANGE - ** Value : minmax - *****************************************/ - - attr_dims[0] = 2; - - /* create the dataspace for the attribute */ - attr_dataspace_id = H5Screate_simple(1 , attr_dims , NULL); - - /* create the attribute */ - attr_attr_id = H5Acreate(sub_image_id , "IMAGE_MINMAXRANGE" , H5T_NATIVE_UINT8 , attr_dataspace_id , H5P_DEFAULT); - - if ((status = H5Awrite(attr_attr_id , H5T_NATIVE_UINT8 , minmax)) < 0) { - fprintf(stderr , "Unable to write attribute. Aborting \n"); - return -1; - } - - /* close the attribute */ - if ((status = H5Aclose(attr_attr_id)) < 0) { - fprintf(stderr , "Unable to close CLASS IMAGE attribute. Aborting.\n"); - return -1; - } - - /* close the dataspace */ - if ((status = H5Sclose(attr_dataspace_id)) < 0) { - fprintf(stderr , "Unable to close attribute dataspace. Aborting \n"); - return -1; - } - - - /* close everything */ - if ((status = H5Dclose(sub_image_id)) < 0) { - fprintf(stderr , "Unable to close image dataset. Aborting \n"); - return -1; - } - - if ((status = H5Sclose(dataspace_id)) < 0) { - fprintf(stderr , "Unable to close image dataspace. Aborting \n"); - return -1; - } - - } - - /* close the main image group */ - if ((status = H5Gclose(image_id)) < 0) { - fprintf(stderr , "Could not close the image group. Aborting...\n"); - return -1; - } - - /* close the H5 file */ - if ((status = H5Fclose(file_id)) < 0) { - fprintf(stderr , "Could not close HDF5 file. Aborting...\n"); - return -1; - } - - return(0); + GIFHEAD gifHead; /* GIF Header structure */ + GIFIMAGEDESC *gifImageDesc; /* Logical Image Descriptor struct */ + + long ImageCount, /* number of images */ + CommentCount, /* number of comments */ + ApplicationCount, /* number of application extensions */ + PlainTextCount; /* number of plain text extensions */ + + char ImageName[256]; /* Image name for the GR Image */ + char GroupName[VSNAMELENMAX]; /* so that we can name the subgroups appropriately */ + + /* H5 variables */ + hid_t file_id; /* H5 file id */ + hid_t image_id; /* H5 id for the whole image */ + hid_t pal_id; /* H5 id for the palette */ + herr_t status; /* status variable */ + hobj_ref_t pal_ref; /* Create a reference for the palette */ + + /* temp counter */ + int i; + + /* get the GIFMem stuff */ + gifHead = *(GifMemoryStruct.GifHeader); + + /* get some data from gifHead */ + ImageCount = (WORD)gifHead.ImageCount; + CommentCount = (WORD)gifHead.CommentCount; + ApplicationCount = (WORD)gifHead.ApplicationCount; + PlainTextCount = (WORD)gifHead.PlainTextCount; + + /* get the main group name from GIFFileName */ + GroupName[0]= '/'; + + if (strncpy(GroupName , GIFFileName , VSNAMELENMAX-2) == NULL) { + fprintf(stderr , "strncpy failed\n"); + exit(1); + } + + GroupName[VSNAMELENMAX - 1] = '\0'; + + if ((file_id = H5Fcreate(HDFName , H5F_ACC_TRUNC , H5P_DEFAULT , H5P_DEFAULT)) < 0) { + /* error occured opening the HDF File for write */ + fprintf(stderr , "HDF file could not be opened for writing\n"); + fprintf(stderr , "NOTE: GIF file must be present in the same directory as the binary on UNIX systems.\n"); + exit(1); + } + + /* create a group within the root group to hold the gif image */ + /* might want to make a different naming style out here */ + image_id = H5Gcreate(file_id, GroupName , 0); + + /* first create the global palette if there is one */ + if (gifHead.PackedField & 0x80) { /* global palette exists */ + hid_t dataspace_id; /* identifier for dataspace */ + hsize_t dims[2]; /* specify the dimensions of the palette */ + + hsize_t dimsr[1] = {1}; /* needed to store reference */ + hid_t ref_dataspace_id; /* dataspace id for references */ + hid_t ref_dataset_id; /* dataset id for references */ + + /* size of the palette is tablesize (rows) X 3 (columns) */ + dims[0] = gifHead.TableSize; + dims[1] = 3; + + /* create the dataspace */ + if ((dataspace_id = H5Screate_simple(2 , dims , NULL)) < 0) { + fprintf(stderr , "Could not create dataspace for palette. Aborting...\n"); + return -1; + } + + /* create the palette dataset */ + if ((pal_id = H5Dcreate(image_id , "Global Palette" , H5T_NATIVE_UINT8 , dataspace_id , H5P_DEFAULT )) < 0) { + fprintf(stderr , "Could not create palette dataset. Aborting...\n"); + return -1; + } + + /* write the palette data out */ + /****** Ask Elena about VOIDP ******/ + if ((status = H5Dwrite(pal_id , H5T_NATIVE_UINT8 , H5S_ALL , H5S_ALL , H5P_DEFAULT , (void *)gifHead.HDFPalette)) < 0) { + fprintf(stderr , "Error writing dataset. Aborting...\n"); + return -1; + } + + /* set palette attributes */ + + /* attribute CLASS = PALETTE */ + if ((write_text_attribute(pal_id , "CLASS" , "PALETTE")) < 0) { + fprintf(stderr , "Unable to write palette attributes. Aborting\n"); + return -1; + } + + /* attribute PAL_COLORMODEL = RGB */ + if ((write_text_attribute(pal_id , "PAL_COLORMODEL" , "RGB")) < 0) { + fprintf(stderr , "Unable to write palette attributes. Aborting\n"); + return -1; + } + + /* attribute PAL_TYPE = STANDARD8 */ + if ((write_text_attribute(pal_id , "PAL_TYPE" , "STANDARD8")) < 0) { + fprintf(stderr , "Unable to write palette attributes. Aborting\n"); + return -1; + } + + /* attribute PAL_VERSION = 1.0 */ + if ((write_text_attribute(pal_id , "PAL_VERSION" , "1.0")) < 0) { + fprintf(stderr , "Unable to write palette attributes. Aborting\n"); + return -1; + } + + /* create dataspace for the dataset to store references */ + ref_dataspace_id = H5Screate_simple(1 , dimsr , NULL); + + /* create a dataset to store the references */ + ref_dataset_id = H5Dcreate(image_id , "Palette Reference" , H5T_STD_REF_OBJ , ref_dataspace_id , H5P_DEFAULT); + + /* create a reference to the palette */ + if ((status = H5Rcreate(&pal_ref , image_id , "Global Palette" , H5R_OBJECT , -1)) < 0) { + fprintf(stderr , "Unable to create palette reference\n"); + return -1; + } + + /* write the reference out */ + if ((status = H5Dwrite(ref_dataset_id , H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL , H5P_DEFAULT, &pal_ref)) < 0) { + fprintf(stderr , "Unable to write Palette Reference"); + return -1; + } + + /* close dataset */ + if ((status = H5Dclose(ref_dataset_id)) < 0) { + fprintf(stderr , "Unable to close palette dataset.\n"); + return -1; + } + + /* close dataspace */ + if ((status = H5Sclose(ref_dataspace_id)) < 0) { + fprintf(stderr , "Unable to close palette dataspace.\n"); + return -1; + } + + /* close everything */ + if ((status = H5Dclose(pal_id)) < 0) { + fprintf(stderr , "Unable to close palette dataset. Aborting.\n"); + return -1; + } + + if ((status = H5Sclose(dataspace_id)) < 0) { + fprintf(stderr , "Unable to close palette dataspace. Aborting.\n"); + return -1; + } + } + + for(i = 0; i < ImageCount; i++) { + /* variables for the images */ + hsize_t dims[2]; /* dimensions for the dataset */ + hid_t dataspace_id; /* identifier for the dataspace */ + hid_t sub_image_id; /* wierd name to distinguish from the group_id */ + + /* variables for the attributes */ + hsize_t attr_dims[2]; /* dimensions for the attribute */ + hid_t attr_dataspace_id;/* dataspaces needed for the various attributes */ + hid_t attr_attr_id; /* attribute id */ + BYTE minmax[2]; /* lower and upper minmax values */ + + /* initialise minmax */ + minmax[0] = 0 ; + minmax[1] = 255; + + /* get the gifImageDesc */ + gifImageDesc = GifMemoryStruct.GifImageDesc[i]; + + /* set the dimensions */ + dims[0] = gifImageDesc->ImageHeight; + dims[1] = gifImageDesc->ImageWidth; + + /* create the empty dataspace */ + if ((dataspace_id = H5Screate_simple(2 , dims , NULL)) < 0) { + fprintf(stderr , "Could not create image dataspace. Aborting\n"); + return -1; + } + + /* create the image name */ + sprintf(ImageName , "Image%d" , i); + + /* create the image data set */ + if ((sub_image_id = H5Dcreate(image_id , ImageName , H5T_NATIVE_UINT8 , dataspace_id , H5P_DEFAULT)) < 0) { + fprintf(stderr , "Could not create dataset for image. Aborting... \n"); + return -1; + } + + /* write out the image */ + /****** Ask Elena about VOIDP ******/ + if ((status = H5Dwrite(sub_image_id , H5T_NATIVE_UINT8 , H5S_ALL , H5S_ALL , H5P_DEFAULT , (void *)(gifImageDesc->Image))) < 0) { + fprintf(stderr , "Error writing image. Aborting... \n"); + return -1; + } + + /* set the attributes */ + /* This info is available at http://hdf.ncsa.uiuc.edu/HDF5/doc/ImageSpec.html */ + /* The following attributes must be set for each image: + ** --------------------------------------- + ** Attribute Name Value + ** CLASS IMAGE + ** IMAGE_VERSION 1.0 + ** IMAGE_SUBCLASS IMAGE_BITMAP + ** PALETTE ref. to palette datasets + ** IMAGE_MINMAXRANGE [0,255] + ** --------------------------------------- + */ + + /**************************************** + ** Attribute: CLASS + ** Value : IMAGE + *****************************************/ + + if (write_text_attribute(sub_image_id , "CLASS" , "IMAGE") < 0) { + fprintf(stderr , "Unable to write CLASS = IMAGE attribute\n"); + return -1; + } + + /**************************************** + ** Attribute: IMAGE_VERSION + ** Value : 1.0 + *****************************************/ + + if (write_text_attribute(sub_image_id , "IMAGE_VERSION" , "1.0") < 0) { + fprintf(stderr , "Unable to write IMAGE_VERSION attribute\n"); + return -1; + } + + /**************************************** + ** Attribute: IMAGE_SUBCLASS + ** Value : IMAGE_BITMAP + *****************************************/ + + if (write_text_attribute(sub_image_id , "IMAGE_SUBCLASS" , "IMAGE_BITMAP") < 0) { + fprintf(stderr , "Unable to write IMAGE_SUBCLASS attribute\n"); + return -1; + } + + /**************************************** + ** Attribute: IMAGE_COLORMODEL + ** Value : RGB + *****************************************/ + + if (write_text_attribute(sub_image_id , "IMAGE_COLORMODEL" , "RGB") < 0) { + fprintf(stderr , "Unable to write IMAGE_SUBCLASS attribute\n"); + return -1; + } + + /**************************************** + ** Attribute: PALETTE + ** Value : Reference to Palette + *****************************************/ + + /**** MAKE SURE PALETTE EXISTS!!! ****/ + if (gifHead.PackedField & 0x80) { + /* global palette exists */ + attr_dims[0] = 1; + + /* create the dataspace for the attribute */ + attr_dataspace_id = H5Screate_simple(1 , attr_dims , NULL); + + /* create the attribute */ + attr_attr_id = H5Acreate(sub_image_id , "PALETTE" , H5T_STD_REF_OBJ , attr_dataspace_id , H5P_DEFAULT); + + if ((status = H5Awrite(attr_attr_id , H5T_STD_REF_OBJ , &pal_ref)) < 0) { + fprintf(stderr , "Unable to write attribute. Aborting \n"); + return -1; + } + + /* close the attribute */ + if ((status = H5Aclose(attr_attr_id)) < 0) { + fprintf(stderr , "Unable to close CLASS IMAGE attribute. Aborting.\n"); + return -1; + } + + /* close the dataspace */ + if ((status = H5Sclose(attr_dataspace_id)) < 0) { + fprintf(stderr , "Unable to close attribute dataspace. Aborting \n"); + return -1; + } + } + + /**************************************** + ** Attribute: IMAGE_MINMAXRANGE + ** Value : minmax + *****************************************/ + + attr_dims[0] = 2; + + /* create the dataspace for the attribute */ + attr_dataspace_id = H5Screate_simple(1 , attr_dims , NULL); + + /* create the attribute */ + attr_attr_id = H5Acreate(sub_image_id , "IMAGE_MINMAXRANGE" , H5T_NATIVE_UINT8 , attr_dataspace_id , H5P_DEFAULT); + + if ((status = H5Awrite(attr_attr_id , H5T_NATIVE_UINT8 , minmax)) < 0) { + fprintf(stderr , "Unable to write attribute. Aborting \n"); + return -1; + } + + /* close the attribute */ + if ((status = H5Aclose(attr_attr_id)) < 0) { + fprintf(stderr , "Unable to close CLASS IMAGE attribute. Aborting.\n"); + return -1; + } + + /* close the dataspace */ + if ((status = H5Sclose(attr_dataspace_id)) < 0) { + fprintf(stderr , "Unable to close attribute dataspace. Aborting \n"); + return -1; + } + + /* close everything */ + if ((status = H5Dclose(sub_image_id)) < 0) { + fprintf(stderr , "Unable to close image dataset. Aborting \n"); + return -1; + } + + if ((status = H5Sclose(dataspace_id)) < 0) { + fprintf(stderr , "Unable to close image dataspace. Aborting \n"); + return -1; + } + } + + /* close the main image group */ + if ((status = H5Gclose(image_id)) < 0) { + fprintf(stderr , "Could not close the image group. Aborting...\n"); + return -1; + } + + /* close the H5 file */ + if ((status = H5Fclose(file_id)) < 0) { + fprintf(stderr , "Could not close HDF5 file. Aborting...\n"); + return -1; + } + + return 0; } |