You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
9.4KB

  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 "avcodec.h"
  40. #ifdef CONFIG_ZLIB
  41. #include <zlib.h>
  42. #endif
  43. /*
  44. * Decoder context
  45. */
  46. typedef struct TsccContext {
  47. AVCodecContext *avctx;
  48. AVFrame pic;
  49. // Bits per pixel
  50. int bpp;
  51. // Decompressed data size
  52. unsigned int decomp_size;
  53. // Decompression buffer
  54. unsigned char* decomp_buf;
  55. int height;
  56. #ifdef CONFIG_ZLIB
  57. z_stream zstream;
  58. #endif
  59. } CamtasiaContext;
  60. /*
  61. *
  62. * Decode RLE - almost identical to Windows BMP RLE8
  63. * and enhanced to bigger color depths
  64. *
  65. */
  66. static int decode_rle(CamtasiaContext *c, unsigned int srcsize)
  67. {
  68. unsigned char *src = c->decomp_buf;
  69. unsigned char *output, *output_end;
  70. int p1, p2, line=c->height, pos=0, i;
  71. uint16_t pix16;
  72. uint32_t pix32;
  73. output = c->pic.data[0] + (c->height - 1) * c->pic.linesize[0];
  74. output_end = c->pic.data[0] + (c->height) * c->pic.linesize[0];
  75. while(src < c->decomp_buf + srcsize) {
  76. p1 = *src++;
  77. if(p1 == 0) { //Escape code
  78. p2 = *src++;
  79. if(p2 == 0) { //End-of-line
  80. output = c->pic.data[0] + (--line) * c->pic.linesize[0];
  81. if (line < 0)
  82. return -1;
  83. pos = 0;
  84. continue;
  85. } else if(p2 == 1) { //End-of-picture
  86. return 0;
  87. } else if(p2 == 2) { //Skip
  88. p1 = *src++;
  89. p2 = *src++;
  90. line -= p2;
  91. if (line < 0)
  92. return -1;
  93. pos += p1;
  94. output = c->pic.data[0] + line * c->pic.linesize[0] + pos * (c->bpp / 8);
  95. continue;
  96. }
  97. // Copy data
  98. if (output + p2 * (c->bpp / 8) > output_end) {
  99. src += p2 * (c->bpp / 8);
  100. continue;
  101. }
  102. if ((c->bpp == 8) || (c->bpp == 24)) {
  103. for(i = 0; i < p2 * (c->bpp / 8); i++) {
  104. *output++ = *src++;
  105. }
  106. // RLE8 copy is actually padded - and runs are not!
  107. if(c->bpp == 8 && (p2 & 1)) {
  108. src++;
  109. }
  110. } else if (c->bpp == 16) {
  111. for(i = 0; i < p2; i++) {
  112. pix16 = AV_RL16(src);
  113. src += 2;
  114. *(uint16_t*)output = pix16;
  115. output += 2;
  116. }
  117. } else if (c->bpp == 32) {
  118. for(i = 0; i < p2; i++) {
  119. pix32 = AV_RL32(src);
  120. src += 4;
  121. *(uint32_t*)output = pix32;
  122. output += 4;
  123. }
  124. }
  125. pos += p2;
  126. } else { //Run of pixels
  127. int pix[4]; //original pixel
  128. switch(c->bpp){
  129. case 8: pix[0] = *src++;
  130. break;
  131. case 16: pix16 = AV_RL16(src);
  132. src += 2;
  133. *(uint16_t*)pix = pix16;
  134. break;
  135. case 24: pix[0] = *src++;
  136. pix[1] = *src++;
  137. pix[2] = *src++;
  138. break;
  139. case 32: pix32 = AV_RL32(src);
  140. src += 4;
  141. *(uint32_t*)pix = pix32;
  142. break;
  143. }
  144. if (output + p1 * (c->bpp / 8) > output_end)
  145. continue;
  146. for(i = 0; i < p1; i++) {
  147. switch(c->bpp){
  148. case 8: *output++ = pix[0];
  149. break;
  150. case 16: *(uint16_t*)output = pix16;
  151. output += 2;
  152. break;
  153. case 24: *output++ = pix[0];
  154. *output++ = pix[1];
  155. *output++ = pix[2];
  156. break;
  157. case 32: *(uint32_t*)output = pix32;
  158. output += 4;
  159. break;
  160. }
  161. }
  162. pos += p1;
  163. }
  164. }
  165. av_log(c->avctx, AV_LOG_ERROR, "Camtasia warning: no End-of-picture code\n");
  166. return 1;
  167. }
  168. /*
  169. *
  170. * Decode a frame
  171. *
  172. */
  173. static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
  174. {
  175. CamtasiaContext * const c = avctx->priv_data;
  176. unsigned char *encoded = (unsigned char *)buf;
  177. unsigned char *outptr;
  178. #ifdef CONFIG_ZLIB
  179. int zret; // Zlib return code
  180. #endif
  181. int len = buf_size;
  182. if(c->pic.data[0])
  183. avctx->release_buffer(avctx, &c->pic);
  184. c->pic.reference = 1;
  185. c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
  186. if(avctx->get_buffer(avctx, &c->pic) < 0){
  187. av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
  188. return -1;
  189. }
  190. outptr = c->pic.data[0]; // Output image pointer
  191. #ifdef CONFIG_ZLIB
  192. zret = inflateReset(&(c->zstream));
  193. if (zret != Z_OK) {
  194. av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
  195. return -1;
  196. }
  197. c->zstream.next_in = encoded;
  198. c->zstream.avail_in = len;
  199. c->zstream.next_out = c->decomp_buf;
  200. c->zstream.avail_out = c->decomp_size;
  201. zret = inflate(&(c->zstream), Z_FINISH);
  202. // Z_DATA_ERROR means empty picture
  203. if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
  204. av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
  205. return -1;
  206. }
  207. if(zret != Z_DATA_ERROR)
  208. decode_rle(c, c->zstream.avail_out);
  209. /* make the palette available on the way out */
  210. if (c->avctx->pix_fmt == PIX_FMT_PAL8) {
  211. memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE);
  212. if (c->avctx->palctrl->palette_changed) {
  213. c->pic.palette_has_changed = 1;
  214. c->avctx->palctrl->palette_changed = 0;
  215. }
  216. }
  217. #else
  218. av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
  219. return -1;
  220. #endif
  221. *data_size = sizeof(AVFrame);
  222. *(AVFrame*)data = c->pic;
  223. /* always report that the buffer was completely consumed */
  224. return buf_size;
  225. }
  226. /*
  227. *
  228. * Init tscc decoder
  229. *
  230. */
  231. static int decode_init(AVCodecContext *avctx)
  232. {
  233. CamtasiaContext * const c = avctx->priv_data;
  234. int zret; // Zlib return code
  235. c->avctx = avctx;
  236. c->pic.data[0] = NULL;
  237. c->height = avctx->height;
  238. if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
  239. return 1;
  240. }
  241. #ifdef CONFIG_ZLIB
  242. // Needed if zlib unused or init aborted before inflateInit
  243. memset(&(c->zstream), 0, sizeof(z_stream));
  244. #else
  245. av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
  246. return 1;
  247. #endif
  248. switch(avctx->bits_per_sample){
  249. case 8: avctx->pix_fmt = PIX_FMT_PAL8; break;
  250. case 16: avctx->pix_fmt = PIX_FMT_RGB555; break;
  251. case 24:
  252. avctx->pix_fmt = PIX_FMT_BGR24;
  253. break;
  254. case 32: avctx->pix_fmt = PIX_FMT_RGB32; break;
  255. default: av_log(avctx, AV_LOG_ERROR, "Camtasia error: unknown depth %i bpp\n", avctx->bits_per_sample);
  256. return -1;
  257. }
  258. c->bpp = avctx->bits_per_sample;
  259. c->decomp_size = (avctx->width * c->bpp + (avctx->width + 254) / 255 + 2) * avctx->height + 2;//RLE in the 'best' case
  260. /* Allocate decompression buffer */
  261. if (c->decomp_size) {
  262. if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
  263. av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
  264. return 1;
  265. }
  266. }
  267. #ifdef CONFIG_ZLIB
  268. c->zstream.zalloc = Z_NULL;
  269. c->zstream.zfree = Z_NULL;
  270. c->zstream.opaque = Z_NULL;
  271. zret = inflateInit(&(c->zstream));
  272. if (zret != Z_OK) {
  273. av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
  274. return 1;
  275. }
  276. #endif
  277. return 0;
  278. }
  279. /*
  280. *
  281. * Uninit tscc decoder
  282. *
  283. */
  284. static int decode_end(AVCodecContext *avctx)
  285. {
  286. CamtasiaContext * const c = avctx->priv_data;
  287. av_freep(&c->decomp_buf);
  288. if (c->pic.data[0])
  289. avctx->release_buffer(avctx, &c->pic);
  290. #ifdef CONFIG_ZLIB
  291. inflateEnd(&(c->zstream));
  292. #endif
  293. return 0;
  294. }
  295. AVCodec tscc_decoder = {
  296. "camtasia",
  297. CODEC_TYPE_VIDEO,
  298. CODEC_ID_TSCC,
  299. sizeof(CamtasiaContext),
  300. decode_init,
  301. NULL,
  302. decode_end,
  303. decode_frame,
  304. CODEC_CAP_DR1,
  305. };