memory.c
上传用户:sorock1981
上传日期:2007-01-06
资源大小:73k
文件大小:4k
源码类别:

图片显示

开发平台:

Unix_Linux

  1. /*
  2.  * memory.c: memory storage for gif conversion
  3.  * Copyright (C) 1995 Alexander Lehmann
  4.  * For conditions of distribution and use, see the file COPYING.
  5.  */
  6. /*
  7.  * currently two modes are supported:
  8.  * - (default) store complete images in continuous blocks in memory, this works
  9.  *   with systems that support virtual memory, e.g. unix, djgpp, etc.
  10.  * - (-DTMPFILE) store the image data in a temporary file, this should work on
  11.  *  any system regardless of memory restrictions, but may be significantly
  12.  *  slower than the full memory version.
  13.  */
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <assert.h>
  18. #include "gif2png.h"
  19. #ifdef TMPFILE
  20. FILE *tempfile;
  21. #endif
  22. void *xalloc(unsigned long s)
  23. {
  24.   void *p=malloc((size_t)s);
  25.   if(p==NULL) {
  26.     fprintf(stderr, "gif2png: fatal error, out of memoryn");
  27.     fprintf(stderr, "gif2png: exiting ungracefullyn");
  28.     exit(1);
  29.   }
  30.   return p;
  31. }
  32. void *xrealloc(void *p, unsigned long s)
  33. {
  34.   p=realloc(p,(size_t)s);
  35.   if(p==NULL) {
  36.     fprintf(stderr, "gif2png: fatal error, out of memoryn");
  37.     fprintf(stderr, "gif2png: exiting ungracefullyn");
  38.     exit(1);
  39.   }
  40.   return p;
  41. }
  42. #ifndef TMPFILE
  43. /* assume unlimited memory */
  44. /* allocate a new GIFelement, advance current pointer and initialize
  45.    size to 0 */
  46. #define ALLOCSIZE 8192
  47. void allocate_element(void)
  48. {
  49.   struct GIFelement *new=xalloc(sizeof(*new));
  50.   memset(new, 0, sizeof(*new));
  51.   new->next=NULL; /* just in case NULL is not represented by a binary 0 */
  52.   current->next=new;
  53.   current=new;
  54. }
  55. /* set size of current element to at least size bytes */
  56. void set_size(long size)
  57. {
  58.   long nalloc;
  59.   if(current->allocated_size==0) {
  60.     nalloc=size;
  61.     if(nalloc<ALLOCSIZE) nalloc=ALLOCSIZE;
  62.     current->data=xalloc(nalloc);
  63.     current->allocated_size=nalloc;
  64.   } else
  65.   if(current->allocated_size<size) {
  66.     nalloc=size-current->allocated_size;
  67.     if(nalloc<ALLOCSIZE) nalloc=ALLOCSIZE;
  68.     current->data=xrealloc(current->data, current->allocated_size+nalloc);
  69.     current->allocated_size+=nalloc;
  70.   }
  71. }
  72. void store_block(char *data, int size)
  73. {
  74.   set_size(current->size+size);
  75.   memcpy(current->data+current->size, data, size);
  76.   current->size+=size;
  77. }
  78. void allocate_image(void)
  79. {
  80.   allocate_element();
  81.   current->GIFtype=GIFimage;
  82.   current->imagestruct=xalloc(sizeof(*current->imagestruct));
  83.   memset(current->imagestruct, 0, sizeof(*current->imagestruct));
  84. }
  85. void fix_current(void)
  86. {
  87.   if(current->allocated_size!=current->size) {
  88.     current->data=xrealloc(current->data, current->size);
  89.     current->allocated_size=current->size;
  90.   }
  91. }
  92. byte *access_data(struct GIFelement *e, unsigned long pos, unsigned long len)
  93. {
  94.   return e->data+pos;
  95. }
  96. void free_mem(void)
  97. {
  98.   struct GIFelement *p,*t;
  99.   p=first.next;
  100.   first.next=NULL;
  101.   while(p) {
  102.     t=p;
  103.     p=p->next;
  104.     if(t->data) free(t->data);
  105.     if(t->imagestruct) free(t->imagestruct);
  106.     free(t);
  107.   }
  108. }
  109. #else /* TMPFILE */
  110. /* use temporary file for most of the data */
  111. /* allocate a new GIFelement, advance current pointer and initialize
  112.    size to 0 */
  113. void allocate_element(void)
  114. {
  115.   struct GIFelement *new=xalloc(sizeof(*new));
  116.   memset(new, 0, sizeof(*new));
  117.   current->next=new;
  118.   current=new;
  119.   current->file_offset=ftell(tempfile);
  120. }
  121. void set_size(long size)
  122. {
  123. }
  124. void store_block(char *data, int size)
  125. {
  126.   fwrite(data, 1, size, tempfile);
  127.   current->size+=size;
  128. }
  129. void allocate_image(void)
  130. {
  131.   allocate_element();
  132.   current->GIFtype=GIFimage;
  133.   current->imagestruct=xalloc(sizeof(*current->imagestruct));
  134.   memset(current->imagestruct, 0, sizeof(*current->imagestruct));
  135. }
  136. void fix_current(void)
  137. {
  138. }
  139. byte *access_data(struct GIFelement *e, unsigned long pos, unsigned long len)
  140. {
  141.   static byte *data=NULL;
  142.   static size_t allocated_size=0;
  143. #ifdef PNG_MAX_ALLOC_64K
  144.   if(len>65535) {
  145.     fprintf(stderr, "gif2png: single image element too large, use the 32 bit version of gif2pngn");
  146.     exit(1);
  147.   }
  148. #endif
  149.   if(len==0) {
  150.     free(data);
  151.     data=NULL;
  152.     allocated_size=0;
  153.     return NULL;
  154.   }
  155.   if(data==NULL) {
  156.     data=xalloc(len);
  157.     allocated_size=len;
  158.   } else {
  159.     if(allocated_size!=len) {
  160.       data=xrealloc(data, len);
  161.       allocated_size=len;
  162.     }
  163.   }
  164.   fseek(tempfile, e->file_offset+pos, SEEK_SET);
  165.   fread(data, 1, len, tempfile);
  166.   return data;
  167. }
  168. void free_mem(void)
  169. {
  170.   struct GIFelement *p,*t;
  171.   p=first.next;
  172.   first.next=NULL;
  173.   while(p) {
  174.     t=p;
  175.     p=p->next;
  176.     if(t->imagestruct) free(t->imagestruct);
  177.     free(t);
  178.   }
  179.   access_data(NULL, 0, 0);
  180. }
  181. #endif /* TMPFILE */