FliDecode.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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) ((ptr)[0] + ((ptr)[1] << 8))
  18. #define I32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
  19. #define ERR_IF_DATA_OOB(offset) \
  20. if ((data + (offset)) > ptr + bytes) { \
  21. state->errcode = IMAGING_CODEC_OVERRUN; \
  22. return -1; \
  23. }
  24. int
  25. ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
  26. UINT8 *ptr;
  27. int framesize;
  28. int c, chunks, advance;
  29. int l, lines;
  30. int i, j, x = 0, y, ymax;
  31. /* If not even the chunk size is present, we'd better leave */
  32. if (bytes < 4) {
  33. return 0;
  34. }
  35. /* We don't decode anything unless we have a full chunk in the
  36. input buffer */
  37. ptr = buf;
  38. framesize = I32(ptr);
  39. // there can be one pad byte in the framesize
  40. if (bytes + (bytes % 2) < framesize) {
  41. return 0;
  42. }
  43. /* Make sure this is a frame chunk. The Python driver takes
  44. case of other chunk types. */
  45. if (bytes < 8) {
  46. state->errcode = IMAGING_CODEC_OVERRUN;
  47. return -1;
  48. }
  49. if (I16(ptr + 4) != 0xF1FA) {
  50. state->errcode = IMAGING_CODEC_UNKNOWN;
  51. return -1;
  52. }
  53. chunks = I16(ptr + 6);
  54. ptr += 16;
  55. bytes -= 16;
  56. /* Process subchunks */
  57. for (c = 0; c < chunks; c++) {
  58. UINT8 *data;
  59. if (bytes < 10) {
  60. state->errcode = IMAGING_CODEC_OVERRUN;
  61. return -1;
  62. }
  63. data = ptr + 6;
  64. switch (I16(ptr + 4)) {
  65. case 4:
  66. case 11:
  67. /* FLI COLOR chunk */
  68. break; /* ignored; handled by Python code */
  69. case 7:
  70. /* FLI SS2 chunk (word delta) */
  71. /* OOB ok, we've got 4 bytes min on entry */
  72. lines = I16(data);
  73. data += 2;
  74. for (l = y = 0; l < lines && y < state->ysize; l++, y++) {
  75. UINT8 *local_buf = (UINT8 *)im->image[y];
  76. int p, packets;
  77. ERR_IF_DATA_OOB(2)
  78. packets = I16(data);
  79. data += 2;
  80. while (packets & 0x8000) {
  81. /* flag word */
  82. if (packets & 0x4000) {
  83. y += 65536 - packets; /* skip lines */
  84. if (y >= state->ysize) {
  85. state->errcode = IMAGING_CODEC_OVERRUN;
  86. return -1;
  87. }
  88. local_buf = (UINT8 *)im->image[y];
  89. } else {
  90. /* store last byte (used if line width is odd) */
  91. local_buf[state->xsize - 1] = (UINT8)packets;
  92. }
  93. ERR_IF_DATA_OOB(2)
  94. packets = I16(data);
  95. data += 2;
  96. }
  97. for (p = x = 0; p < packets; p++) {
  98. ERR_IF_DATA_OOB(2)
  99. x += data[0]; /* pixel skip */
  100. if (data[1] >= 128) {
  101. ERR_IF_DATA_OOB(4)
  102. i = 256 - data[1]; /* run */
  103. if (x + i + i > state->xsize) {
  104. break;
  105. }
  106. for (j = 0; j < i; j++) {
  107. local_buf[x++] = data[2];
  108. local_buf[x++] = data[3];
  109. }
  110. data += 2 + 2;
  111. } else {
  112. i = 2 * (int)data[1]; /* chunk */
  113. if (x + i > state->xsize) {
  114. break;
  115. }
  116. ERR_IF_DATA_OOB(2 + i)
  117. memcpy(local_buf + x, data + 2, i);
  118. data += 2 + i;
  119. x += i;
  120. }
  121. }
  122. if (p < packets) {
  123. break; /* didn't process all packets */
  124. }
  125. }
  126. if (l < lines) {
  127. /* didn't process all lines */
  128. state->errcode = IMAGING_CODEC_OVERRUN;
  129. return -1;
  130. }
  131. break;
  132. case 12:
  133. /* FLI LC chunk (byte delta) */
  134. /* OOB Check ok, we have 4 bytes min here */
  135. y = I16(data);
  136. ymax = y + I16(data + 2);
  137. data += 4;
  138. for (; y < ymax && y < state->ysize; y++) {
  139. UINT8 *out = (UINT8 *)im->image[y];
  140. ERR_IF_DATA_OOB(1)
  141. int p, packets = *data++;
  142. for (p = x = 0; p < packets; p++, x += i) {
  143. ERR_IF_DATA_OOB(2)
  144. x += data[0]; /* skip pixels */
  145. if (data[1] & 0x80) {
  146. i = 256 - data[1]; /* run */
  147. if (x + i > state->xsize) {
  148. break;
  149. }
  150. ERR_IF_DATA_OOB(3)
  151. memset(out + x, data[2], i);
  152. data += 3;
  153. } else {
  154. i = data[1]; /* chunk */
  155. if (x + i > state->xsize) {
  156. break;
  157. }
  158. ERR_IF_DATA_OOB(2 + i)
  159. memcpy(out + x, data + 2, i);
  160. data += i + 2;
  161. }
  162. }
  163. if (p < packets) {
  164. break; /* didn't process all packets */
  165. }
  166. }
  167. if (y < ymax) {
  168. /* didn't process all lines */
  169. state->errcode = IMAGING_CODEC_OVERRUN;
  170. return -1;
  171. }
  172. break;
  173. case 13:
  174. /* FLI BLACK chunk */
  175. for (y = 0; y < state->ysize; y++) {
  176. memset(im->image[y], 0, state->xsize);
  177. }
  178. break;
  179. case 15:
  180. /* FLI BRUN chunk */
  181. /* OOB, ok, we've got 4 bytes min on entry */
  182. for (y = 0; y < state->ysize; y++) {
  183. UINT8 *out = (UINT8 *)im->image[y];
  184. data += 1; /* ignore packetcount byte */
  185. for (x = 0; x < state->xsize; x += i) {
  186. ERR_IF_DATA_OOB(2)
  187. if (data[0] & 0x80) {
  188. i = 256 - data[0];
  189. if (x + i > state->xsize) {
  190. break; /* safety first */
  191. }
  192. ERR_IF_DATA_OOB(i + 1)
  193. memcpy(out + x, data + 1, i);
  194. data += i + 1;
  195. } else {
  196. i = data[0];
  197. if (x + i > state->xsize) {
  198. break; /* safety first */
  199. }
  200. memset(out + x, data[1], i);
  201. data += 2;
  202. }
  203. }
  204. if (x != state->xsize) {
  205. /* didn't unpack whole line */
  206. state->errcode = IMAGING_CODEC_OVERRUN;
  207. return -1;
  208. }
  209. }
  210. break;
  211. case 16:
  212. /* COPY chunk */
  213. if (INT32_MAX / state->xsize < state->ysize) {
  214. /* Integer overflow, bail */
  215. state->errcode = IMAGING_CODEC_OVERRUN;
  216. return -1;
  217. }
  218. /* Note, have to check Data + size, not just ptr + size) */
  219. if (data + (state->xsize * state->ysize) > ptr + bytes) {
  220. /* not enough data for frame */
  221. /* UNDONE Unclear that we're actually going to leave the buffer at the right place. */
  222. return ptr - buf; /* bytes consumed */
  223. }
  224. for (y = 0; y < state->ysize; y++) {
  225. UINT8 *local_buf = (UINT8 *)im->image[y];
  226. memcpy(local_buf, data, state->xsize);
  227. data += state->xsize;
  228. }
  229. break;
  230. case 18:
  231. /* PSTAMP chunk */
  232. break; /* ignored */
  233. default:
  234. /* unknown chunk */
  235. /* printf("unknown FLI/FLC chunk: %d\n", I16(ptr+4)); */
  236. state->errcode = IMAGING_CODEC_UNKNOWN;
  237. return -1;
  238. }
  239. advance = I32(ptr);
  240. if (advance == 0 ) {
  241. // If there's no advance, we're in an infinite loop
  242. state->errcode = IMAGING_CODEC_BROKEN;
  243. return -1;
  244. }
  245. if (advance < 0 || advance > bytes) {
  246. state->errcode = IMAGING_CODEC_OVERRUN;
  247. return -1;
  248. }
  249. ptr += advance;
  250. bytes -= advance;
  251. }
  252. return -1; /* end of frame */
  253. }