FliDecode.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * The Python Imaging Library.
  3. * $Id$
  4. *
  5. * decoder for Autodesk Animator FLI/FLC animations
  6. *
  7. * history:
  8. * 97-01-03 fl Created
  9. * 97-01-17 fl Added SS2 support (FLC)
  10. *
  11. * Copyright (c) Fredrik Lundh 1997.
  12. * Copyright (c) Secret Labs AB 1997.
  13. *
  14. * See the README file for information on usage and redistribution.
  15. */
  16. #include "Imaging.h"
  17. #define I16(ptr)\
  18. ((ptr)[0] + ((ptr)[1] << 8))
  19. #define I32(ptr)\
  20. ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
  21. int
  22. ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t bytes)
  23. {
  24. UINT8* ptr;
  25. int framesize;
  26. int c, chunks, advance;
  27. int l, lines;
  28. int i, j, x = 0, y, ymax;
  29. /* If not even the chunk size is present, we'd better leave */
  30. if (bytes < 4)
  31. return 0;
  32. /* We don't decode anything unless we have a full chunk in the
  33. input buffer */
  34. ptr = buf;
  35. framesize = I32(ptr);
  36. if (framesize < I32(ptr))
  37. return 0;
  38. /* Make sure this is a frame chunk. The Python driver takes
  39. case of other chunk types. */
  40. if (bytes < 8) {
  41. state->errcode = IMAGING_CODEC_OVERRUN;
  42. return -1;
  43. }
  44. if (I16(ptr+4) != 0xF1FA) {
  45. state->errcode = IMAGING_CODEC_UNKNOWN;
  46. return -1;
  47. }
  48. chunks = I16(ptr+6);
  49. ptr += 16;
  50. bytes -= 16;
  51. /* Process subchunks */
  52. for (c = 0; c < chunks; c++) {
  53. UINT8* data;
  54. if (bytes < 10) {
  55. state->errcode = IMAGING_CODEC_OVERRUN;
  56. return -1;
  57. }
  58. data = ptr + 6;
  59. switch (I16(ptr+4)) {
  60. case 4: case 11:
  61. /* FLI COLOR chunk */
  62. break; /* ignored; handled by Python code */
  63. case 7:
  64. /* FLI SS2 chunk (word delta) */
  65. lines = I16(data); data += 2;
  66. for (l = y = 0; l < lines && y < state->ysize; l++, y++) {
  67. UINT8* buf = (UINT8*) im->image[y];
  68. int p, packets;
  69. packets = I16(data); data += 2;
  70. while (packets & 0x8000) {
  71. /* flag word */
  72. if (packets & 0x4000) {
  73. y += 65536 - packets; /* skip lines */
  74. if (y >= state->ysize) {
  75. state->errcode = IMAGING_CODEC_OVERRUN;
  76. return -1;
  77. }
  78. buf = (UINT8*) im->image[y];
  79. } else {
  80. /* store last byte (used if line width is odd) */
  81. buf[state->xsize-1] = (UINT8) packets;
  82. }
  83. packets = I16(data); data += 2;
  84. }
  85. for (p = x = 0; p < packets; p++) {
  86. x += data[0]; /* pixel skip */
  87. if (data[1] >= 128) {
  88. i = 256-data[1]; /* run */
  89. if (x + i + i > state->xsize)
  90. break;
  91. for (j = 0; j < i; j++) {
  92. buf[x++] = data[2];
  93. buf[x++] = data[3];
  94. }
  95. data += 2 + 2;
  96. } else {
  97. i = 2 * (int) data[1]; /* chunk */
  98. if (x + i > state->xsize)
  99. break;
  100. memcpy(buf + x, data + 2, i);
  101. data += 2 + i;
  102. x += i;
  103. }
  104. }
  105. if (p < packets)
  106. break; /* didn't process all packets */
  107. }
  108. if (l < lines) {
  109. /* didn't process all lines */
  110. state->errcode = IMAGING_CODEC_OVERRUN;
  111. return -1;
  112. }
  113. break;
  114. case 12:
  115. /* FLI LC chunk (byte delta) */
  116. y = I16(data); ymax = y + I16(data+2); data += 4;
  117. for (; y < ymax && y < state->ysize; y++) {
  118. UINT8* out = (UINT8*) im->image[y];
  119. int p, packets = *data++;
  120. for (p = x = 0; p < packets; p++, x += i) {
  121. x += data[0]; /* skip pixels */
  122. if (data[1] & 0x80) {
  123. i = 256-data[1]; /* run */
  124. if (x + i > state->xsize)
  125. break;
  126. memset(out + x, data[2], i);
  127. data += 3;
  128. } else {
  129. i = data[1]; /* chunk */
  130. if (x + i > state->xsize)
  131. break;
  132. memcpy(out + x, data + 2, i);
  133. data += i + 2;
  134. }
  135. }
  136. if (p < packets)
  137. break; /* didn't process all packets */
  138. }
  139. if (y < ymax) {
  140. /* didn't process all lines */
  141. state->errcode = IMAGING_CODEC_OVERRUN;
  142. return -1;
  143. }
  144. break;
  145. case 13:
  146. /* FLI BLACK chunk */
  147. for (y = 0; y < state->ysize; y++)
  148. memset(im->image[y], 0, state->xsize);
  149. break;
  150. case 15:
  151. /* FLI BRUN chunk */
  152. for (y = 0; y < state->ysize; y++) {
  153. UINT8* out = (UINT8*) im->image[y];
  154. data += 1; /* ignore packetcount byte */
  155. for (x = 0; x < state->xsize; x += i) {
  156. if (data[0] & 0x80) {
  157. i = 256 - data[0];
  158. if (x + i > state->xsize)
  159. break; /* safety first */
  160. memcpy(out + x, data + 1, i);
  161. data += i + 1;
  162. } else {
  163. i = data[0];
  164. if (x + i > state->xsize)
  165. break; /* safety first */
  166. memset(out + x, data[1], i);
  167. data += 2;
  168. }
  169. }
  170. if (x != state->xsize) {
  171. /* didn't unpack whole line */
  172. state->errcode = IMAGING_CODEC_OVERRUN;
  173. return -1;
  174. }
  175. }
  176. break;
  177. case 16:
  178. /* COPY chunk */
  179. for (y = 0; y < state->ysize; y++) {
  180. UINT8* buf = (UINT8*) im->image[y];
  181. memcpy(buf, data, state->xsize);
  182. data += state->xsize;
  183. }
  184. break;
  185. case 18:
  186. /* PSTAMP chunk */
  187. break; /* ignored */
  188. default:
  189. /* unknown chunk */
  190. /* printf("unknown FLI/FLC chunk: %d\n", I16(ptr+4)); */
  191. state->errcode = IMAGING_CODEC_UNKNOWN;
  192. return -1;
  193. }
  194. advance = I32(ptr);
  195. ptr += advance;
  196. bytes -= advance;
  197. }
  198. return -1; /* end of frame */
  199. }