GifEncode.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * The Python Imaging Library.
  3. * $Id$
  4. *
  5. * encoder for uncompressed GIF data
  6. *
  7. * history:
  8. * 97-01-05 fl created (writes uncompressed data)
  9. * 97-08-27 fl fixed off-by-one error in buffer size test
  10. * 98-07-09 fl added interlace write support
  11. * 99-02-07 fl rewritten, now uses a run-length encoding strategy
  12. * 99-02-08 fl improved run-length encoding for long runs
  13. *
  14. * Copyright (c) Secret Labs AB 1997-99.
  15. * Copyright (c) Fredrik Lundh 1997.
  16. *
  17. * See the README file for information on usage and redistribution.
  18. */
  19. #include "Imaging.h"
  20. #include "Gif.h"
  21. /* codes from 0 to 255 are literals */
  22. #define CLEAR_CODE 256
  23. #define EOF_CODE 257
  24. #define FIRST_CODE 258
  25. #define LAST_CODE 511
  26. enum { INIT, ENCODE, ENCODE_EOF, FLUSH, EXIT };
  27. /* to make things a little less complicated, we use a simple output
  28. queue to hold completed blocks. the following inlined function
  29. adds a byte to the current block. it allocates a new block if
  30. necessary. */
  31. static inline int
  32. emit(GIFENCODERSTATE *context, int byte)
  33. {
  34. /* write a byte to the output buffer */
  35. if (!context->block || context->block->size == 255) {
  36. GIFENCODERBLOCK* block;
  37. /* no room in the current block (or no current block);
  38. allocate a new one */
  39. /* add current block to end of flush queue */
  40. if (context->block) {
  41. block = context->flush;
  42. while (block && block->next)
  43. block = block->next;
  44. if (block)
  45. block->next = context->block;
  46. else
  47. context->flush = context->block;
  48. }
  49. /* get a new block */
  50. if (context->free) {
  51. block = context->free;
  52. context->free = NULL;
  53. } else {
  54. /* malloc check ok, small constant allocation */
  55. block = malloc(sizeof(GIFENCODERBLOCK));
  56. if (!block)
  57. return 0;
  58. }
  59. block->size = 0;
  60. block->next = NULL;
  61. context->block = block;
  62. }
  63. /* write new byte to block */
  64. context->block->data[context->block->size++] = byte;
  65. return 1;
  66. }
  67. /* write a code word to the current block. this is a macro to make
  68. sure it's inlined on all platforms */
  69. #define EMIT(code) {\
  70. context->bitbuffer |= ((INT32) (code)) << context->bitcount;\
  71. context->bitcount += 9;\
  72. while (context->bitcount >= 8) {\
  73. if (!emit(context, (UINT8) context->bitbuffer)) {\
  74. state->errcode = IMAGING_CODEC_MEMORY;\
  75. return 0;\
  76. }\
  77. context->bitbuffer >>= 8;\
  78. context->bitcount -= 8;\
  79. }\
  80. }
  81. /* write a run. we use a combination of literals and combinations of
  82. literals. this can give quite decent compression for images with
  83. long stretches of identical pixels. but remember: if you want
  84. really good compression, use another file format. */
  85. #define EMIT_RUN(label) {\
  86. label:\
  87. while (context->count > 0) {\
  88. int run = 2;\
  89. EMIT(context->last);\
  90. context->count--;\
  91. if (state->count++ == LAST_CODE) {\
  92. EMIT(CLEAR_CODE);\
  93. state->count = FIRST_CODE;\
  94. goto label;\
  95. }\
  96. while (context->count >= run) {\
  97. EMIT(state->count - 1);\
  98. context->count -= run;\
  99. run++;\
  100. if (state->count++ == LAST_CODE) {\
  101. EMIT(CLEAR_CODE);\
  102. state->count = FIRST_CODE;\
  103. goto label;\
  104. }\
  105. }\
  106. if (context->count > 1) {\
  107. EMIT(state->count - 1 - (run - context->count));\
  108. context->count = 0;\
  109. if (state->count++ == LAST_CODE) {\
  110. EMIT(CLEAR_CODE);\
  111. state->count = FIRST_CODE;\
  112. }\
  113. break;\
  114. }\
  115. }\
  116. }
  117. int
  118. ImagingGifEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
  119. {
  120. UINT8* ptr;
  121. int this;
  122. GIFENCODERBLOCK* block;
  123. GIFENCODERSTATE *context = (GIFENCODERSTATE*) state->context;
  124. if (!state->state) {
  125. /* place a clear code in the output buffer */
  126. context->bitbuffer = CLEAR_CODE;
  127. context->bitcount = 9;
  128. state->count = FIRST_CODE;
  129. if (context->interlace) {
  130. context->interlace = 1;
  131. context->step = 8;
  132. } else
  133. context->step = 1;
  134. context->last = -1;
  135. /* sanity check */
  136. if (state->xsize <= 0 || state->ysize <= 0)
  137. state->state = ENCODE_EOF;
  138. }
  139. ptr = buf;
  140. for (;;)
  141. switch (state->state) {
  142. case INIT:
  143. case ENCODE:
  144. /* identify and store a run of pixels */
  145. if (state->x == 0 || state->x >= state->xsize) {
  146. if (!context->interlace && state->y >= state->ysize) {
  147. state->state = ENCODE_EOF;
  148. break;
  149. }
  150. if (context->flush) {
  151. state->state = FLUSH;
  152. break;
  153. }
  154. /* get another line of data */
  155. state->shuffle(
  156. state->buffer,
  157. (UINT8*) im->image[state->y + state->yoff] +
  158. state->xoff * im->pixelsize, state->xsize
  159. );
  160. state->x = 0;
  161. if (state->state == INIT) {
  162. /* preload the run-length buffer and get going */
  163. context->last = state->buffer[0];
  164. context->count = state->x = 1;
  165. state->state = ENCODE;
  166. }
  167. /* step forward, according to the interlace settings */
  168. state->y += context->step;
  169. while (context->interlace && state->y >= state->ysize)
  170. switch (context->interlace) {
  171. case 1:
  172. state->y = 4;
  173. context->interlace = 2;
  174. break;
  175. case 2:
  176. context->step = 4;
  177. state->y = 2;
  178. context->interlace = 3;
  179. break;
  180. case 3:
  181. context->step = 2;
  182. state->y = 1;
  183. context->interlace = 0;
  184. break;
  185. default:
  186. /* just make sure we don't loop forever */
  187. context->interlace = 0;
  188. }
  189. }
  190. this = state->buffer[state->x++];
  191. if (this == context->last)
  192. context->count++;
  193. else {
  194. EMIT_RUN(label1);
  195. context->last = this;
  196. context->count = 1;
  197. }
  198. break;
  199. case ENCODE_EOF:
  200. /* write the final run */
  201. EMIT_RUN(label2);
  202. /* write an end of image marker */
  203. EMIT(EOF_CODE);
  204. /* empty the bit buffer */
  205. while (context->bitcount > 0) {
  206. if (!emit(context, (UINT8) context->bitbuffer)) {
  207. state->errcode = IMAGING_CODEC_MEMORY;
  208. return 0;
  209. }
  210. context->bitbuffer >>= 8;
  211. context->bitcount -= 8;
  212. }
  213. /* flush the last block, and exit */
  214. if (context->block) {
  215. GIFENCODERBLOCK* block;
  216. block = context->flush;
  217. while (block && block->next)
  218. block = block->next;
  219. if (block)
  220. block->next = context->block;
  221. else
  222. context->flush = context->block;
  223. context->block = NULL;
  224. }
  225. state->state = EXIT;
  226. /* fall through... */
  227. case EXIT:
  228. case FLUSH:
  229. while (context->flush) {
  230. /* get a block from the flush queue */
  231. block = context->flush;
  232. if (block->size > 0) {
  233. /* make sure it fits into the output buffer */
  234. if (bytes < block->size+1)
  235. return ptr - buf;
  236. ptr[0] = block->size;
  237. memcpy(ptr+1, block->data, block->size);
  238. ptr += block->size+1;
  239. bytes -= block->size+1;
  240. }
  241. context->flush = block->next;
  242. if (context->free)
  243. free(context->free);
  244. context->free = block;
  245. }
  246. if (state->state == EXIT) {
  247. /* this was the last block! */
  248. if (context->free)
  249. free(context->free);
  250. state->errcode = IMAGING_CODEC_END;
  251. return ptr - buf;
  252. }
  253. state->state = ENCODE;
  254. break;
  255. }
  256. }