summaryrefslogtreecommitdiffstats
path: root/hl/tools/gif2h5/hdf2gif.c
diff options
context:
space:
mode:
Diffstat (limited to 'hl/tools/gif2h5/hdf2gif.c')
-rw-r--r--hl/tools/gif2h5/hdf2gif.c354
1 files changed, 354 insertions, 0 deletions
diff --git a/hl/tools/gif2h5/hdf2gif.c b/hl/tools/gif2h5/hdf2gif.c
new file mode 100644
index 0000000..9c4133e
--- /dev/null
+++ b/hl/tools/gif2h5/hdf2gif.c
@@ -0,0 +1,354 @@
+/* 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
+
+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;
+
+void PutByte(BYTE b , FILE *fpGif)
+{
+ if (fputc(b , fpGif) == EOF) {
+ printf("File Writing Error, cannot continue");
+ exit(-1);
+ }
+}
+
+
+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);
+}
+
+void usage() {
+ 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");
+}
+
+int main(int argc , char **argv) {
+
+ FILE *fpGif;
+
+ hsize_t dim_sizes[2];
+
+ BYTE *Image;
+ /* compression structs */
+
+ CHAR *HDFName = NULL;
+ CHAR *GIFName = NULL;
+ CHAR *image_path = NULL;
+ CHAR *pal_path = 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 , index;
+
+ 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 (index = 0 ; index < n_images ; index++) {
+
+ /* 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[index] , pal_name_arr[index]) < 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 (index == 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 , dim_sizes[0] , 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);
+}