tscc.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * TechSmith Camtasia decoder
  3. * Copyright (c) 2004 Konstantin Shishkov
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. /**
  23. * @file tscc.c
  24. * TechSmith Camtasia decoder
  25. *
  26. * Fourcc: TSCC
  27. *
  28. * Codec is very simple:
  29. * it codes picture (picture difference, really)
  30. * with algorithm almost identical to Windows RLE8,
  31. * only without padding and with greater pixel sizes,
  32. * then this coded picture is packed with ZLib
  33. *
  34. * Supports: BGR8,BGR555,BGR24 - only BGR8 and BGR555 tested
  35. *
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include "common.h"
  40. #include "avcodec.h"
  41. #ifdef CONFIG_ZLIB
  42. #include <zlib.h>
  43. #endif
  44. /*
  45. * Decoder context
  46. */
  47. typedef struct TsccContext {
  48. AVCodecContext *avctx;
  49. AVFrame pic;
  50. // Bits per pixel
  51. int bpp;
  52. // Decompressed data size
  53. unsigned int decomp_size;
  54. // Decompression buffer
  55. unsigned char* decomp_buf;
  56. int height;
  57. #ifdef CONFIG_ZLIB
  58. z_stream zstream;
  59. #endif
  60. } CamtasiaContext;
  61. /*
  62. *
  63. * Decode RLE - almost identical to Windows BMP RLE8
  64. * and enhanced to bigger color depths
  65. *
  66. */
  67. static int decode_rle(CamtasiaContext *c, unsigned int srcsize)
  68. {
  69. unsigned char *src = c->decomp_buf;
  70. unsigned char *output, *output_end;
  71. int p1, p2, line=c->height, pos=0, i;
  72. uint16_t pix16;
  73. uint32_t pix32;
  74. output = c->pic.data[0] + (c->height - 1) * c->pic.linesize[0];
  75. output_end = c->pic.data[0] + (c->height) * c->pic.linesize[0];
  76. while(src < c->decomp_buf + srcsize) {
  77. p1 = *src++;
  78. if(p1 == 0) { //Escape code
  79. p2 = *src++;
  80. if(p2 == 0) { //End-of-line
  81. output = c->pic.data[0] + (--line) * c->pic.linesize[0];
  82. if (line < 0)
  83. return -1;
  84. pos = 0;
  85. continue;
  86. } else if(p2 == 1) { //End-of-picture
  87. return 0;
  88. } else if(p2 == 2) { //Skip
  89. p1 = *src++;
  90. p2 = *src++;
  91. line -= p2;
  92. if (line < 0)
  93. return -1;
  94. pos += p1;
  95. output = c->pic.data[0] + line * c->pic.linesize[0] + pos * (c->bpp / 8);
  96. continue;
  97. }
  98. // Copy data
  99. if (output + p2 * (c->bpp / 8) > output_end) {
  100. src += p2 * (c->bpp / 8);
  101. continue;
  102. }
  103. if ((c->bpp == 8) || (c->bpp == 24)) {
  104. for(i = 0; i < p2 * (c->bpp / 8); i++) {
  105. *output++ = *src++;
  106. }
  107. // RLE8 copy is actually padded - and runs are not!
  108. if(c->bpp == 8 && (p2 & 1)) {
  109. src++;
  110. }
  111. } else if (c->bpp == 16) {
  112. for(i = 0; i < p2; i++) {
  113. pix16 = AV_RL16(src);
  114. src += 2;
  115. *(uint16_t*)output = pix16;
  116. output += 2;
  117. }
  118. } else if (c->bpp == 32) {
  119. for(i = 0; i < p2; i++) {
  120. pix32 = AV_RL32(src);
  121. src += 4;
  122. *(uint32_t*)output = pix32;
  123. output += 4;
  124. }
  125. }
  126. pos += p2;
  127. } else { //Run of pixels
  128. int pix[4]; //original pixel
  129. switch(c->bpp){
  130. case 8: pix[0] = *src++;
  131. break;
  132. case 16: pix16 = AV_RL16(src);
  133. src += 2;
  134. *(uint16_t*)pix = pix16;
  135. break;
  136. case 24: pix[0] = *src++;
  137. pix[1] = *src++;
  138. pix[2] = *src++;
  139. break;
  140. case 32: pix32 = AV_RL32(src);
  141. src += 4;
  142. *(uint32_t*)pix = pix32;
  143. break;
  144. }
  145. if (output + p1 * (c->bpp / 8) > output_end)
  146. continue;
  147. for(i = 0; i < p1; i++) {
  148. switch(c->bpp){
  149. case 8: *output++ = pix[0];
  150. break;
  151. case 16: *(uint16_t*)output = pix16;
  152. output += 2;
  153. break;
  154. case 24: *output++ = pix[0];
  155. *output++ = pix[1];
  156. *output++ = pix[2];
  157. break;
  158. case 32: *(uint32_t*)output = pix32;
  159. output += 4;
  160. break;
  161. }
  162. }
  163. pos += p1;
  164. }
  165. }
  166. av_log(c->avctx, AV_LOG_ERROR, "Camtasia warning: no End-of-picture code\n");
  167. return 1;
  168. }
  169. /*
  170. *
  171. * Decode a frame
  172. *
  173. */
  174. static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
  175. {
  176. CamtasiaContext * const c = (CamtasiaContext *)avctx->priv_data;
  177. unsigned char *encoded = (unsigned char *)buf;
  178. unsigned char *outptr;
  179. #ifdef CONFIG_ZLIB
  180. int zret; // Zlib return code
  181. #endif
  182. int len = buf_size;
  183. if(c->pic.data[0])
  184. avctx->release_buffer(avctx, &c->pic);
  185. c->pic.reference = 1;
  186. c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
  187. if(avctx->get_buffer(avctx, &c->pic) < 0){
  188. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  189. return -1;
  190. }
  191. outptr = c->pic.data[0]; // Output image pointer
  192. #ifdef CONFIG_ZLIB
  193. zret = inflateReset(&(c->zstream));
  194. if (zret != Z_OK) {
  195. av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
  196. return -1;
  197. }
  198. c->zstream.next_in = encoded;
  199. c->zstream.avail_in = len;
  200. c->zstream.next_out = c->decomp_buf;
  201. c->zstream.avail_out = c->decomp_size;
  202. zret = inflate(&(c->zstream), Z_FINISH);
  203. // Z_DATA_ERROR means empty picture
  204. if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
  205. av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
  206. return -1;
  207. }
  208. if(zret != Z_DATA_ERROR)
  209. decode_rle(c, c->zstream.avail_out);
  210. /* make the palette available on the way out */
  211. if (c->avctx->pix_fmt == PIX_FMT_PAL8) {
  212. memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE);
  213. if (c->avctx->palctrl->palette_changed) {
  214. c->pic.palette_has_changed = 1;
  215. c->avctx->palctrl->palette_changed = 0;
  216. }
  217. }
  218. #else
  219. av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
  220. return -1;
  221. #endif
  222. *data_size = sizeof(AVFrame);
  223. *(AVFrame*)data = c->pic;
  224. /* always report that the buffer was completely consumed */
  225. return buf_size;
  226. }
  227. /*
  228. *
  229. * Init tscc decoder
  230. *
  231. */
  232. static int decode_init(AVCodecContext *avctx)
  233. {
  234. CamtasiaContext * const c = (CamtasiaContext *)avctx->priv_data;
  235. int zret; // Zlib return code
  236. c->avctx = avctx;
  237. c->pic.data[0] = NULL;
  238. c->height = avctx->height;
  239. if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
  240. return 1;
  241. }
  242. #ifdef CONFIG_ZLIB
  243. // Needed if zlib unused or init aborted before inflateInit
  244. memset(&(c->zstream), 0, sizeof(z_stream));
  245. #else
  246. av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
  247. return 1;
  248. #endif
  249. switch(avctx->bits_per_sample){
  250. case 8: avctx->pix_fmt = PIX_FMT_PAL8; break;
  251. case 16: avctx->pix_fmt = PIX_FMT_RGB555; break;
  252. case 24:
  253. avctx->pix_fmt = PIX_FMT_BGR24;
  254. break;
  255. case 32: avctx->pix_fmt = PIX_FMT_RGB32; break;
  256. default: av_log(avctx, AV_LOG_ERROR, "Camtasia error: unknown depth %i bpp\n", avctx->bits_per_sample);
  257. return -1;
  258. }
  259. c->bpp = avctx->bits_per_sample;
  260. c->decomp_size = (avctx->width * c->bpp + (avctx->width + 254) / 255 + 2) * avctx->height + 2;//RLE in the 'best' case
  261. /* Allocate decompression buffer */
  262. if (c->decomp_size) {
  263. if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
  264. av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
  265. return 1;
  266. }
  267. }
  268. #ifdef CONFIG_ZLIB
  269. c->zstream.zalloc = Z_NULL;
  270. c->zstream.zfree = Z_NULL;
  271. c->zstream.opaque = Z_NULL;
  272. zret = inflateInit(&(c->zstream));
  273. if (zret != Z_OK) {
  274. av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
  275. return 1;
  276. }
  277. #endif
  278. return 0;
  279. }
  280. /*
  281. *
  282. * Uninit tscc decoder
  283. *
  284. */
  285. static int decode_end(AVCodecContext *avctx)
  286. {
  287. CamtasiaContext * const c = (CamtasiaContext *)avctx->priv_data;
  288. av_freep(&c->decomp_buf);
  289. if (c->pic.data[0])
  290. avctx->release_buffer(avctx, &c->pic);
  291. #ifdef CONFIG_ZLIB
  292. inflateEnd(&(c->zstream));
  293. #endif
  294. return 0;
  295. }
  296. AVCodec tscc_decoder = {
  297. "camtasia",
  298. CODEC_TYPE_VIDEO,
  299. CODEC_ID_TSCC,
  300. sizeof(CamtasiaContext),
  301. decode_init,
  302. NULL,
  303. decode_end,
  304. decode_frame,
  305. CODEC_CAP_DR1,
  306. };