Example #1
0
INLINE void *
gif_save(const Image *image, const ColorMapObject *color_map, Frame *frames, int count, int *size)
{
    GifBuffer buf = {0,};
    int estimated = count * (image->columns * image->rows);
    buf.alloc = estimated;
    buf.data = malloc(estimated);
    GifFileType *gif_file = EGifOpen(&buf, gif_buffer_write);
    if (!gif_file) {
        return NULL;
    }
    if (EGifPutScreenDesc(gif_file, image->columns, image->rows, NCOLORS, 0, color_map) == GIF_ERROR) {
        EGifCloseFile(gif_file);
        return NULL;
    }
    if (EGifPutExtensionFirst(gif_file, APPLICATION_EXT_FUNC_CODE, strlen(GIF_APP), GIF_APP) == GIF_ERROR) {
        EGifCloseFile(gif_file);
        return NULL;
    }
    unsigned char meta[] = {
        0x01, //  data sub-block index (always 1)
        0xFF, 0xFF // 65535 repetitions - unsigned
    };
    if (EGifPutExtensionLast(gif_file, APPLICATION_EXT_FUNC_CODE, sizeof(meta), meta) == GIF_ERROR) {
        EGifCloseFile(gif_file);
        return NULL;
    }
    int ii;
    for (ii = 0; ii < count; ii++) {
        Frame *frame = &frames[ii];
        // GCE
        unsigned char gce[] = {
            0x08, // no transparency
            frame->duration % 256, // LSB of delay
            frame->duration / 256, // MSB of delay in millisecs
            0x00, // no transparent color
        };
        if (EGifPutExtension(gif_file, GRAPHICS_EXT_FUNC_CODE, sizeof(gce), gce) == GIF_ERROR) {
            EGifCloseFile(gif_file);
            return NULL;
        }
        if (EGifPutImageDesc(gif_file, frame->x, frame->y, frame->width, frame->height, 0, NULL) == GIF_ERROR) {
            EGifCloseFile(gif_file);
            return NULL;
        }
        int yy;
        GifPixelType *p = frame->data;
        for (yy = 0; yy < frame->height; yy++, p += frame->width) {
            if (EGifPutLine(gif_file, p, frame->width) == GIF_ERROR) {
                EGifCloseFile(gif_file);
                return NULL;
            }
        }
    } 
    EGifCloseFile(gif_file);
    *size = buf.size;
    return buf.data;
}
Example #2
0
int main(int argc, char **argv) {
   FILE *input_file;
   float arg,size,rx,ry,rz;
   float f,fmin=1e10,fmax=-1e10;
   uint16_t i;
   uint64_t count;
   int xi,yi,zi,xo,yo,zo,nx,ny,nz,dx,dy,dz,x0,y0,z0,h;
   int **image;
   char format,type,comment[256];
   GifFileType *GIFfile;
   ColorMapObject *GIFcmap;
   GifPixelType *GIFline;
   //
   // command line args
   //
   if (!((argc == 6) || (argc == 7)  || (argc == 8) || (argc == 9) || (argc == 10) || (argc == 13) || (argc == 16) || (argc == 19))) {
      printf("command line: vol_gif in.vol out.gif nx ny nz [format [type [arg [size [dx dy dz [x0 y0 z0 [rx ry rz]]]]]]]\n");
      printf("   in.vol = input volume file\n");
      printf("   out.gif = output GIF file\n");
      printf("   nx,ny,nz = x,y,z input voxel number\n");
      printf("   format = 'f' for float 32, 'i' for uint16_t (default 'f')\n");
      printf("   type = 's' for section, 'h' for height (default 's')\n");
      printf("   arg = gamma for 's', threshold for 'h' (default 1)\n");
      printf("   size = mm per voxel (default 1)\n");
      printf("   dx,dy,dz = x,y,z output voxel number (default all)\n");
      printf("   x0,y0,z0 = x,y,z output voxel origin (default 0)\n");
      printf("   to be implemented: rx,ry,rz = view rotation angles (degrees; default 0)\n");
      exit(-1);
      }
   format = 'f';
   type = 's';
   arg = 1;
   size = 1.0;
   rx = ry = rz = 0;
   sscanf(argv[3],"%d",&nx);
   sscanf(argv[4],"%d",&ny);
   sscanf(argv[5],"%d",&nz);
   dx = nx; dy = ny; dz = nz;
   x0 = y0 = z0 = 0;
   if (argc >= 7) {
      sscanf(argv[6],"%c",&format);
      if (!((format == 'f') || (format == 'i'))) {
         printf("vol_gif: oops -- format must be 'f' or 'i'\n");
         exit(-1);
         }
      }
   if (argc >= 8) {
      sscanf(argv[7],"%c",&type);
      if (!((type == 's') || (type == 'h'))) {
         printf("vol_gif: oops -- type must be 's' or 'h'\n");
         exit(-1);
         }
      }
   if (argc >= 9) {
      sscanf(argv[8],"%f",&arg);
      }
   if (argc >= 10) {
      sscanf(argv[9],"%f",&size);
      }
   if (argc >= 13) {
      sscanf(argv[10],"%d",&x0);
      sscanf(argv[11],"%d",&y0);
      sscanf(argv[12],"%d",&z0);
      }
   if (argc >= 16) {
      sscanf(argv[13],"%d",&dx);
      sscanf(argv[14],"%d",&dy);
      sscanf(argv[15],"%d",&dz);
      }
   if (argc >= 19) {
      sscanf(argv[16],"%f",&rx);
      sscanf(argv[17],"%f",&ry);
      sscanf(argv[18],"%f",&rz);
      }
   //
   // check and find limits
   //
   input_file = fopen(argv[1],"rb");
   if (input_file == NULL) {
      printf("vol_gif: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   if (((x0 + dx) > nx) || ((y0 + dy) > ny) || ((z0 + dz) > nz)) {
      printf("vol_gif: oops -- region too large\n");
      exit(-1);
      }
   printf("read %s\n",argv[1]);
   if (format == 'f') {
      count = 0;
      while (fread(&f,sizeof(f),1,input_file) != 0) {
         if (f > fmax) fmax = f;
         if (f < fmin) fmin = f;
         count += 1;
         }
      }
   else if (format == 'i') {
      count = 0;
      while (fread(&i,sizeof(i),1,input_file) != 0) {
         if (i > fmax) fmax = i;
         if (i < fmin) fmin = i;
         count += 1;
         }
      }
   printf("   %" PRIu64 " points, min %f, max %f\n",count,fmin,fmax);
   printf("   nx ny nz: %d %d %d\n",nx,ny,nz);
   rewind(input_file);
   //
   // set up color map
   //
#if GIFLIB_MAJOR >= 5
   GIFcmap = GifMakeMapObject(256, NULL);
#else
   GIFcmap = MakeMapObject(256, NULL);
#endif
   for (i = 0; i < 256; i++) {
      GIFcmap->Colors[i].Red = i;
      GIFcmap->Colors[i].Green = i;
      GIFcmap->Colors[i].Blue = i;
      }
   //
   // open GIF file
   //
   printf("write %s\n",argv[2]);

   EGifPutScreenDesc(GIFfile,dx,dy,8,0,GIFcmap);
   unsigned char loop_count[] = {1,0,0};
#if GIFLIB_MAJOR >= 5
   GIFfile = EGifOpenFileName(argv[2], 0, NULL);
   EGifPutExtension(GIFfile, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0");
   EGifPutExtension(GIFfile, APPLICATION_EXT_FUNC_CODE, 3, loop_count);
#else
   GIFfile = EGifOpenFileName(argv[2], 0);
   EGifPutExtensionFirst(GIFfile, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0");
   EGifPutExtensionLast(GIFfile, APPLICATION_EXT_FUNC_CODE, 3, loop_count);
#endif


   unsigned char delay_count[5] = { 
      0, // no transparency
      0, // delay time
      0, // delay time
      0 // transparent index not used
      };
   //
   // allocate image
   //
   image = malloc(dy*sizeof(int *));
   for (yo = 0; yo < dy; ++yo) {
      image[yo] = malloc(dx*sizeof(int));
      for (xo = 0; xo < dx; ++xo)
         image[yo][xo] = 0;
      }
   GIFline = malloc(dx*sizeof(GifPixelType));
   //
   // scan file
   //
   xi = yi = zi = 0;
   for (zo = 0; zo < dz; ++zo) {
      printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b   layer = %d",zo);
      EGifPutExtension(GIFfile,GRAPHICS_EXT_FUNC_CODE,4,delay_count);
      EGifPutImageDesc(GIFfile,0,0,dx,dy,0,NULL);
      //
      // read layer
      //
      for (yo = 0; yo < dy; ++yo) {
         for (xo = 0; xo < dx; ++xo) {
            if (format == 'f') {
               read_voxel_f(input_file,&f,xo+x0,yo+y0,zo+z0,&xi,&yi,&zi,nx,ny,nz);
               if (type == 'h') {
                  h = 255*zo/(nz-1.0);
                  if ((h > image[yo][xo]) && (f > arg))
                     image[yo][xo] = h;
                  GIFline[xo] = image[yo][xo]*(nz-1.0)/zo;
                  }
               else if (type == 's') {
                  GIFline[xo] = 255*pow((f-fmin)/(fmax-fmin),arg);
                  }
               }
            else if (format == 'i') {
               read_voxel_i(input_file,&i,xo+x0,yo+y0,zo+z0,&xi,&yi,&zi,nx,ny,nz);
               if (type == 'h') {
                  h = 255*zo/(nz-1.0);
                  if ((h > image[yo][xo]) && (i > arg))
                     image[yo][xo] = h;
                  GIFline[xo] = image[yo][xo]*(nz-1.0)/zo;
                  }
               else if (type == 's') {
                  GIFline[xo] = 255*pow((i-fmin)/(fmax-fmin),arg);
                  }
               }
            }
         EGifPutLine(GIFfile,GIFline,dx);
         }
      }
   printf("\n");
   //
   // put mm per pixel in comment
   //
   sprintf(comment,"mm per pixel: %f;",size);
   EGifPutComment(GIFfile,comment);
   //
   // exit
   //
   fclose(input_file);
   EGifCloseFile(GIFfile);
   exit(0);
   }
Example #3
0
static int write_gif_info(const psx_image* image, image_writer_fn func, void* param,
                                                     float quality, psx_image_header* header)
{
    size_t buf_size;
#if GIFLIB_MAJOR >= 5
    int errorcode = 0;
#endif

    struct gif_image_ctx* ctx = (struct gif_image_ctx*)calloc(1, sizeof(struct gif_image_ctx));
    if (!ctx) {
        return -1; // out of memory.
    }

    ctx->writer = func;
    ctx->writer_param = param;

#if GIFLIB_MAJOR >= 5
    if ((ctx->gif = EGifOpen((void*)ctx, write_gif_from_memory, &errorcode)) == NULL) {
        free(ctx);
        return -1;
    }

    if (image->num_frames > 1) {
        EGifSetGifVersion(ctx->gif, true);
    }
#else
    if ((ctx->gif = EGifOpen((void*)ctx, write_gif_from_memory)) == NULL) {
        free(ctx);
        return -1;
    }

    if (image->num_frames > 1) {
        EGifSetGifVersion("89a");
    } else {
        EGifSetGifVersion("87a");
    }
#endif

    if (EGifPutScreenDesc(ctx->gif, image->width, image->height, 8, 0, NULL) == GIF_ERROR) {
        GIF_CLOSE_EFILE(ctx->gif);
        free(ctx);
        return -1;
    }

    if (image->num_frames > 1) { // add netscape2.0 application extension to an animation gif.
#if GIFLIB_MAJOR >= 5
        EGifPutExtensionLeader(ctx->gif, APPLICATION_EXT_FUNC_CODE);
        EGifPutExtensionBlock(ctx->gif, 11, "NETSCAPE2.0");
        EGifPutExtensionBlock(ctx->gif, 3, "\x01\x00\x00");
        EGifPutExtensionTrailer(ctx->gif);
#else
        EGifPutExtensionFirst(ctx->gif, APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0");
        EGifPutExtensionLast(ctx->gif, APPLICATION_EXT_FUNC_CODE, 3, "\x01\x00\x00");
#endif
    }

    buf_size = image->width * image->height * sizeof(GifByteType);

    ctx->red_buf = (GifByteType*)malloc(buf_size);
    ctx->green_buf = (GifByteType*)malloc(buf_size);
    ctx->blue_buf = (GifByteType*)malloc(buf_size);
    ctx->output_buffer = (GifByteType*)malloc(buf_size);

    if (!ctx->red_buf || !ctx->green_buf || !ctx->blue_buf || !ctx->output_buffer) {
        GIF_CLOSE_EFILE(ctx->gif);

        if (ctx->red_buf) 
            free(ctx->red_buf);
        if (ctx->green_buf)
            free(ctx->green_buf);
        if (ctx->blue_buf)
            free(ctx->blue_buf);
        if (ctx->output_buffer)
            free(ctx->output_buffer);

        free(ctx);
        return -1;
    }

    header->priv = ctx;
    header->width = image->width;
    header->height = image->height;
    header->pitch = image->pitch;
    header->depth = get_depth(image->format);
    header->bpp = get_bpp(image->format);
    header->format = (int)image->format;
    header->alpha = 1;
    header->frames = (int)image->num_frames;
    return 0;
}