avi_tscc_decoder.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #include "avi_tscc_decoder.h"
  2. #include "avi_rle_decoder.h"
  3. #include "avi_yuv_decoder.h"
  4. #include "../Winamp/wa_ipc.h"
  5. #include "rle.h"
  6. #include <limits.h>
  7. #include <intsafe.h>
  8. AVITSCC *AVITSCC::CreateDecoder(nsavi::video_format *stream_format)
  9. {
  10. size_t bytes_per_pixel = stream_format->bits_per_pixel / 8U;
  11. if (bytes_per_pixel > 4)
  12. return 0;
  13. size_t image_size=0;
  14. size_t pixel_size=0;
  15. size_t data_len=0;
  16. /* set an upper bound on width so we don't overflow when we multiply uint8_t * 4 * width */
  17. if (stream_format->width > (1 << 20))
  18. return 0;
  19. if (SizeTMult(stream_format->width, stream_format->height, &pixel_size) != S_OK || SizeTMult(pixel_size, bytes_per_pixel, &image_size) != S_OK)
  20. return 0;
  21. // calculate worst-case data length (3 * pixel_size / 255 + image_size)
  22. if (SizeTMult(pixel_size, 3, &data_len) != S_OK)
  23. return 0;
  24. pixel_size /= 255;
  25. if (SizeTAdd(pixel_size, data_len, &data_len) != S_OK)
  26. return 0;
  27. void *video_frame = (uint8_t *)malloc(image_size);
  28. if (!video_frame)
  29. return 0;
  30. // upper bound for decompressed data size
  31. void *data = malloc(data_len);
  32. if (!data)
  33. {
  34. free(video_frame);
  35. return 0;
  36. }
  37. AVITSCC *decoder = new AVITSCC(video_frame, image_size, data, data_len, stream_format);
  38. if (!decoder)
  39. {
  40. free(video_frame);
  41. free(data);
  42. return 0;
  43. }
  44. return decoder;
  45. }
  46. AVITSCC::AVITSCC(void *video_frame, size_t video_frame_size, void *data, size_t data_len, nsavi::video_format *stream_format) : stream_format(stream_format), video_frame_size(video_frame_size), video_frame((uint8_t *)video_frame), data((uint8_t *)data), data_len(data_len)
  47. {
  48. video_outputted=false;
  49. zlib_stream.next_in = Z_NULL;
  50. zlib_stream.avail_in = Z_NULL;
  51. zlib_stream.next_out = Z_NULL;
  52. zlib_stream.avail_out = Z_NULL;
  53. zlib_stream.zalloc = (alloc_func)0;
  54. zlib_stream.zfree = (free_func)0;
  55. zlib_stream.opaque = 0;
  56. inflateInit(&zlib_stream);
  57. }
  58. int AVITSCC::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip)
  59. {
  60. if (stream_format)
  61. {
  62. *x = stream_format->width;
  63. *y = stream_format->height;
  64. *flip = 1;
  65. switch(stream_format->bits_per_pixel)
  66. {
  67. case 8:
  68. *color_format = '8BGR';
  69. break;
  70. case 16:
  71. *color_format = '555R';
  72. break;
  73. case 24:
  74. *color_format = '42GR';
  75. break;
  76. case 32:
  77. *color_format = '23GR';
  78. break;
  79. default:
  80. return AVI_FAILURE;
  81. }
  82. return AVI_SUCCESS;
  83. }
  84. return AVI_FAILURE;
  85. }
  86. static bool BoundsCheckX(uint8_t delta_x, size_t bytes_per_pixel, size_t video_frame_size, size_t output_pointer)
  87. {
  88. if ((size_t)delta_x*bytes_per_pixel >= (video_frame_size - output_pointer))
  89. return false;
  90. return true;
  91. }
  92. static bool BoundsCheckY(uint8_t delta_y, size_t bytes_per_pixel, size_t width, size_t video_frame_size, size_t output_pointer)
  93. {
  94. if ((size_t)delta_y*bytes_per_pixel*width >= (video_frame_size - output_pointer))
  95. return false;
  96. return true;
  97. }
  98. int AVITSCC::DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes)
  99. {
  100. if (stream_format)
  101. {
  102. if (inflateReset(&zlib_stream) != Z_OK)
  103. return AVI_FAILURE;
  104. size_t bytes_per_pixel = stream_format->bits_per_pixel / 8U;
  105. zlib_stream.next_in = (Bytef *)inputBuffer;
  106. zlib_stream.avail_in = (uInt)inputBufferBytes;
  107. zlib_stream.next_out = data;
  108. zlib_stream.avail_out = (uInt)data_len;
  109. int ret = inflate(&zlib_stream, Z_FINISH);
  110. if (ret == Z_OK || ret == Z_STREAM_END)
  111. {
  112. if (bytes_per_pixel == 2)
  113. {
  114. RLE16(data, data_len, (uint16_t *)video_frame, video_frame_size, stream_format->width);
  115. }
  116. else if (bytes_per_pixel == 1)
  117. {
  118. RLE8(data, data_len, (uint8_t *)video_frame, video_frame_size, stream_format->width);
  119. }
  120. else
  121. {
  122. const uint8_t * const rle = data;
  123. int input = 0;
  124. size_t output = 0;
  125. int next_line = (int)output + (int)bytes_per_pixel*stream_format->width;
  126. for (;;)
  127. {
  128. uint8_t b0 = rle[input++];
  129. if (b0)
  130. {
  131. uint8_t pixel[4] = {0};
  132. memcpy(pixel, &rle[input], bytes_per_pixel);
  133. input += (int)bytes_per_pixel;
  134. if (!BoundsCheckX(b0, bytes_per_pixel, video_frame_size, output))
  135. return AVI_FAILURE;
  136. while (b0--)
  137. {
  138. memcpy(&video_frame[output], &pixel, bytes_per_pixel);
  139. output+=bytes_per_pixel;
  140. }
  141. }
  142. else
  143. {
  144. uint8_t b1 = rle[input++];
  145. if (b1 == 0)
  146. {
  147. if (next_line > (int)video_frame_size)
  148. return AVI_FAILURE;
  149. output = next_line;
  150. next_line = (int)output + (int)bytes_per_pixel*stream_format->width;
  151. }
  152. else if (b1 == 1)
  153. {
  154. break;
  155. }
  156. else if (b1 == 2)
  157. {
  158. uint8_t p1 = rle[input++];
  159. uint8_t p2 = rle[input++];
  160. if (!BoundsCheckX(p1, bytes_per_pixel, video_frame_size, output))
  161. return AVI_FAILURE;
  162. output += bytes_per_pixel*p1;
  163. if (!BoundsCheckY(p2, bytes_per_pixel, stream_format->width, video_frame_size, output))
  164. return AVI_FAILURE;
  165. output += bytes_per_pixel*p2*stream_format->width;
  166. next_line += (int)bytes_per_pixel*p2*stream_format->width;
  167. }
  168. else
  169. {
  170. if (!BoundsCheckX(b1, bytes_per_pixel, video_frame_size, output))
  171. return AVI_FAILURE;
  172. memcpy(&video_frame[output], &rle[input], b1*bytes_per_pixel);
  173. input += b1* (int)bytes_per_pixel;
  174. output += b1*bytes_per_pixel;
  175. if (bytes_per_pixel == 1 && (b1 & 1))
  176. input++;
  177. }
  178. }
  179. }
  180. }
  181. }
  182. else if (ret != Z_DATA_ERROR)
  183. {
  184. return AVI_FAILURE;
  185. }
  186. video_outputted=false;
  187. return AVI_SUCCESS;
  188. }
  189. return AVI_FAILURE;
  190. }
  191. void AVITSCC::Flush()
  192. {
  193. }
  194. int AVITSCC::GetPicture(void **data, void **decoder_data)
  195. {
  196. if (!video_outputted && video_frame)
  197. {
  198. *data = video_frame;
  199. *decoder_data=0;
  200. video_outputted=true;
  201. return AVI_SUCCESS;
  202. }
  203. return AVI_FAILURE;
  204. }
  205. void AVITSCC::Close()
  206. {
  207. free(video_frame);
  208. free(data);
  209. inflateEnd(&zlib_stream);
  210. delete this;
  211. }
  212. #define CBCLASS AVITSCC
  213. START_DISPATCH;
  214. CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
  215. CB(DECODE_CHUNK, DecodeChunk)
  216. VCB(FLUSH, Flush)
  217. VCB(CLOSE, Close)
  218. CB(GET_PICTURE, GetPicture)
  219. END_DISPATCH;
  220. #undef CBCLASS