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.

488 lines
16KB

  1. /*
  2. * Quicktime Graphics (SMC) Video Decoder
  3. * Copyright (C) 2003 The FFmpeg project
  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. * @file
  23. * QT SMC Video Decoder by Mike Melanson (melanson@pcisys.net)
  24. * For more information about the SMC format, visit:
  25. * http://www.pcisys.net/~melanson/codecs/
  26. *
  27. * The SMC decoder outputs PAL8 colorspace data.
  28. */
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "libavutil/intreadwrite.h"
  33. #include "avcodec.h"
  34. #include "bytestream.h"
  35. #include "internal.h"
  36. #define CPAIR 2
  37. #define CQUAD 4
  38. #define COCTET 8
  39. #define COLORS_PER_TABLE 256
  40. typedef struct SmcContext {
  41. AVCodecContext *avctx;
  42. AVFrame *frame;
  43. GetByteContext gb;
  44. /* SMC color tables */
  45. unsigned char color_pairs[COLORS_PER_TABLE * CPAIR];
  46. unsigned char color_quads[COLORS_PER_TABLE * CQUAD];
  47. unsigned char color_octets[COLORS_PER_TABLE * COCTET];
  48. uint32_t pal[256];
  49. } SmcContext;
  50. #define GET_BLOCK_COUNT() \
  51. (opcode & 0x10) ? (1 + bytestream2_get_byte(&s->gb)) : 1 + (opcode & 0x0F);
  52. #define ADVANCE_BLOCK() \
  53. { \
  54. pixel_ptr += 4; \
  55. if (pixel_ptr >= width) \
  56. { \
  57. pixel_ptr = 0; \
  58. row_ptr += stride * 4; \
  59. } \
  60. total_blocks--; \
  61. if (total_blocks < !!n_blocks) \
  62. { \
  63. av_log(s->avctx, AV_LOG_INFO, "warning: block counter just went negative (this should not happen)\n"); \
  64. return; \
  65. } \
  66. }
  67. static void smc_decode_stream(SmcContext *s)
  68. {
  69. int width = s->avctx->width;
  70. int height = s->avctx->height;
  71. int stride = s->frame->linesize[0];
  72. int i;
  73. int chunk_size;
  74. int buf_size = bytestream2_size(&s->gb);
  75. unsigned char opcode;
  76. int n_blocks;
  77. unsigned int color_flags;
  78. unsigned int color_flags_a;
  79. unsigned int color_flags_b;
  80. unsigned int flag_mask;
  81. unsigned char * const pixels = s->frame->data[0];
  82. int image_size = height * s->frame->linesize[0];
  83. int row_ptr = 0;
  84. int pixel_ptr = 0;
  85. int pixel_x, pixel_y;
  86. int row_inc = stride - 4;
  87. int block_ptr;
  88. int prev_block_ptr;
  89. int prev_block_ptr1, prev_block_ptr2;
  90. int prev_block_flag;
  91. int total_blocks;
  92. int color_table_index; /* indexes to color pair, quad, or octet tables */
  93. int pixel;
  94. int color_pair_index = 0;
  95. int color_quad_index = 0;
  96. int color_octet_index = 0;
  97. /* make the palette available */
  98. memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
  99. bytestream2_skip(&s->gb, 1);
  100. chunk_size = bytestream2_get_be24(&s->gb);
  101. if (chunk_size != buf_size)
  102. av_log(s->avctx, AV_LOG_INFO, "warning: MOV chunk size != encoded chunk size (%d != %d); using MOV chunk size\n",
  103. chunk_size, buf_size);
  104. chunk_size = buf_size;
  105. total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4);
  106. /* traverse through the blocks */
  107. while (total_blocks) {
  108. /* sanity checks */
  109. /* make sure the row pointer hasn't gone wild */
  110. if (row_ptr >= image_size) {
  111. av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (row ptr = %d, height = %d)\n",
  112. row_ptr, image_size);
  113. return;
  114. }
  115. if (bytestream2_get_bytes_left(&s->gb) < 1) {
  116. av_log(s->avctx, AV_LOG_ERROR, "input too small\n");
  117. return;
  118. }
  119. opcode = bytestream2_get_byte(&s->gb);
  120. switch (opcode & 0xF0) {
  121. /* skip n blocks */
  122. case 0x00:
  123. case 0x10:
  124. n_blocks = GET_BLOCK_COUNT();
  125. while (n_blocks--) {
  126. ADVANCE_BLOCK();
  127. }
  128. break;
  129. /* repeat last block n times */
  130. case 0x20:
  131. case 0x30:
  132. n_blocks = GET_BLOCK_COUNT();
  133. /* sanity check */
  134. if ((row_ptr == 0) && (pixel_ptr == 0)) {
  135. av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but no blocks rendered yet\n",
  136. opcode & 0xF0);
  137. return;
  138. }
  139. /* figure out where the previous block started */
  140. if (pixel_ptr == 0)
  141. prev_block_ptr1 =
  142. (row_ptr - s->avctx->width * 4) + s->avctx->width - 4;
  143. else
  144. prev_block_ptr1 = row_ptr + pixel_ptr - 4;
  145. while (n_blocks--) {
  146. block_ptr = row_ptr + pixel_ptr;
  147. prev_block_ptr = prev_block_ptr1;
  148. for (pixel_y = 0; pixel_y < 4; pixel_y++) {
  149. for (pixel_x = 0; pixel_x < 4; pixel_x++) {
  150. pixels[block_ptr++] = pixels[prev_block_ptr++];
  151. }
  152. block_ptr += row_inc;
  153. prev_block_ptr += row_inc;
  154. }
  155. ADVANCE_BLOCK();
  156. }
  157. break;
  158. /* repeat previous pair of blocks n times */
  159. case 0x40:
  160. case 0x50:
  161. n_blocks = GET_BLOCK_COUNT();
  162. n_blocks *= 2;
  163. /* sanity check */
  164. if ((row_ptr == 0) && (pixel_ptr < 2 * 4)) {
  165. av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but not enough blocks rendered yet\n",
  166. opcode & 0xF0);
  167. return;
  168. }
  169. /* figure out where the previous 2 blocks started */
  170. if (pixel_ptr == 0)
  171. prev_block_ptr1 = (row_ptr - s->avctx->width * 4) +
  172. s->avctx->width - 4 * 2;
  173. else if (pixel_ptr == 4)
  174. prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + row_inc;
  175. else
  176. prev_block_ptr1 = row_ptr + pixel_ptr - 4 * 2;
  177. if (pixel_ptr == 0)
  178. prev_block_ptr2 = (row_ptr - s->avctx->width * 4) + row_inc;
  179. else
  180. prev_block_ptr2 = row_ptr + pixel_ptr - 4;
  181. prev_block_flag = 0;
  182. while (n_blocks--) {
  183. block_ptr = row_ptr + pixel_ptr;
  184. if (prev_block_flag)
  185. prev_block_ptr = prev_block_ptr2;
  186. else
  187. prev_block_ptr = prev_block_ptr1;
  188. prev_block_flag = !prev_block_flag;
  189. for (pixel_y = 0; pixel_y < 4; pixel_y++) {
  190. for (pixel_x = 0; pixel_x < 4; pixel_x++) {
  191. pixels[block_ptr++] = pixels[prev_block_ptr++];
  192. }
  193. block_ptr += row_inc;
  194. prev_block_ptr += row_inc;
  195. }
  196. ADVANCE_BLOCK();
  197. }
  198. break;
  199. /* 1-color block encoding */
  200. case 0x60:
  201. case 0x70:
  202. n_blocks = GET_BLOCK_COUNT();
  203. pixel = bytestream2_get_byte(&s->gb);
  204. while (n_blocks--) {
  205. block_ptr = row_ptr + pixel_ptr;
  206. for (pixel_y = 0; pixel_y < 4; pixel_y++) {
  207. for (pixel_x = 0; pixel_x < 4; pixel_x++) {
  208. pixels[block_ptr++] = pixel;
  209. }
  210. block_ptr += row_inc;
  211. }
  212. ADVANCE_BLOCK();
  213. }
  214. break;
  215. /* 2-color block encoding */
  216. case 0x80:
  217. case 0x90:
  218. n_blocks = (opcode & 0x0F) + 1;
  219. /* figure out which color pair to use to paint the 2-color block */
  220. if ((opcode & 0xF0) == 0x80) {
  221. /* fetch the next 2 colors from bytestream and store in next
  222. * available entry in the color pair table */
  223. for (i = 0; i < CPAIR; i++) {
  224. pixel = bytestream2_get_byte(&s->gb);
  225. color_table_index = CPAIR * color_pair_index + i;
  226. s->color_pairs[color_table_index] = pixel;
  227. }
  228. /* this is the base index to use for this block */
  229. color_table_index = CPAIR * color_pair_index;
  230. color_pair_index++;
  231. /* wraparound */
  232. if (color_pair_index == COLORS_PER_TABLE)
  233. color_pair_index = 0;
  234. } else
  235. color_table_index = CPAIR * bytestream2_get_byte(&s->gb);
  236. while (n_blocks--) {
  237. color_flags = bytestream2_get_be16(&s->gb);
  238. flag_mask = 0x8000;
  239. block_ptr = row_ptr + pixel_ptr;
  240. for (pixel_y = 0; pixel_y < 4; pixel_y++) {
  241. for (pixel_x = 0; pixel_x < 4; pixel_x++) {
  242. if (color_flags & flag_mask)
  243. pixel = color_table_index + 1;
  244. else
  245. pixel = color_table_index;
  246. flag_mask >>= 1;
  247. pixels[block_ptr++] = s->color_pairs[pixel];
  248. }
  249. block_ptr += row_inc;
  250. }
  251. ADVANCE_BLOCK();
  252. }
  253. break;
  254. /* 4-color block encoding */
  255. case 0xA0:
  256. case 0xB0:
  257. n_blocks = (opcode & 0x0F) + 1;
  258. /* figure out which color quad to use to paint the 4-color block */
  259. if ((opcode & 0xF0) == 0xA0) {
  260. /* fetch the next 4 colors from bytestream and store in next
  261. * available entry in the color quad table */
  262. for (i = 0; i < CQUAD; i++) {
  263. pixel = bytestream2_get_byte(&s->gb);
  264. color_table_index = CQUAD * color_quad_index + i;
  265. s->color_quads[color_table_index] = pixel;
  266. }
  267. /* this is the base index to use for this block */
  268. color_table_index = CQUAD * color_quad_index;
  269. color_quad_index++;
  270. /* wraparound */
  271. if (color_quad_index == COLORS_PER_TABLE)
  272. color_quad_index = 0;
  273. } else
  274. color_table_index = CQUAD * bytestream2_get_byte(&s->gb);
  275. while (n_blocks--) {
  276. color_flags = bytestream2_get_be32(&s->gb);
  277. /* flag mask actually acts as a bit shift count here */
  278. flag_mask = 30;
  279. block_ptr = row_ptr + pixel_ptr;
  280. for (pixel_y = 0; pixel_y < 4; pixel_y++) {
  281. for (pixel_x = 0; pixel_x < 4; pixel_x++) {
  282. pixel = color_table_index +
  283. ((color_flags >> flag_mask) & 0x03);
  284. flag_mask -= 2;
  285. pixels[block_ptr++] = s->color_quads[pixel];
  286. }
  287. block_ptr += row_inc;
  288. }
  289. ADVANCE_BLOCK();
  290. }
  291. break;
  292. /* 8-color block encoding */
  293. case 0xC0:
  294. case 0xD0:
  295. n_blocks = (opcode & 0x0F) + 1;
  296. /* figure out which color octet to use to paint the 8-color block */
  297. if ((opcode & 0xF0) == 0xC0) {
  298. /* fetch the next 8 colors from bytestream and store in next
  299. * available entry in the color octet table */
  300. for (i = 0; i < COCTET; i++) {
  301. pixel = bytestream2_get_byte(&s->gb);
  302. color_table_index = COCTET * color_octet_index + i;
  303. s->color_octets[color_table_index] = pixel;
  304. }
  305. /* this is the base index to use for this block */
  306. color_table_index = COCTET * color_octet_index;
  307. color_octet_index++;
  308. /* wraparound */
  309. if (color_octet_index == COLORS_PER_TABLE)
  310. color_octet_index = 0;
  311. } else
  312. color_table_index = COCTET * bytestream2_get_byte(&s->gb);
  313. while (n_blocks--) {
  314. /*
  315. For this input of 6 hex bytes:
  316. 01 23 45 67 89 AB
  317. Mangle it to this output:
  318. flags_a = xx012456, flags_b = xx89A37B
  319. */
  320. /* build the color flags */
  321. int val1 = bytestream2_get_be16(&s->gb);
  322. int val2 = bytestream2_get_be16(&s->gb);
  323. int val3 = bytestream2_get_be16(&s->gb);
  324. color_flags_a = ((val1 & 0xFFF0) << 8) | (val2 >> 4);
  325. color_flags_b = ((val3 & 0xFFF0) << 8) |
  326. ((val1 & 0x0F) << 8) | ((val2 & 0x0F) << 4) | (val3 & 0x0F);
  327. color_flags = color_flags_a;
  328. /* flag mask actually acts as a bit shift count here */
  329. flag_mask = 21;
  330. block_ptr = row_ptr + pixel_ptr;
  331. for (pixel_y = 0; pixel_y < 4; pixel_y++) {
  332. /* reload flags at third row (iteration pixel_y == 2) */
  333. if (pixel_y == 2) {
  334. color_flags = color_flags_b;
  335. flag_mask = 21;
  336. }
  337. for (pixel_x = 0; pixel_x < 4; pixel_x++) {
  338. pixel = color_table_index +
  339. ((color_flags >> flag_mask) & 0x07);
  340. flag_mask -= 3;
  341. pixels[block_ptr++] = s->color_octets[pixel];
  342. }
  343. block_ptr += row_inc;
  344. }
  345. ADVANCE_BLOCK();
  346. }
  347. break;
  348. /* 16-color block encoding (every pixel is a different color) */
  349. case 0xE0:
  350. n_blocks = (opcode & 0x0F) + 1;
  351. while (n_blocks--) {
  352. block_ptr = row_ptr + pixel_ptr;
  353. for (pixel_y = 0; pixel_y < 4; pixel_y++) {
  354. for (pixel_x = 0; pixel_x < 4; pixel_x++) {
  355. pixels[block_ptr++] = bytestream2_get_byte(&s->gb);
  356. }
  357. block_ptr += row_inc;
  358. }
  359. ADVANCE_BLOCK();
  360. }
  361. break;
  362. case 0xF0:
  363. avpriv_request_sample(s->avctx, "0xF0 opcode");
  364. break;
  365. }
  366. }
  367. return;
  368. }
  369. static av_cold int smc_decode_init(AVCodecContext *avctx)
  370. {
  371. SmcContext *s = avctx->priv_data;
  372. s->avctx = avctx;
  373. avctx->pix_fmt = AV_PIX_FMT_PAL8;
  374. s->frame = av_frame_alloc();
  375. if (!s->frame)
  376. return AVERROR(ENOMEM);
  377. return 0;
  378. }
  379. static int smc_decode_frame(AVCodecContext *avctx,
  380. void *data, int *got_frame,
  381. AVPacket *avpkt)
  382. {
  383. const uint8_t *buf = avpkt->data;
  384. int buf_size = avpkt->size;
  385. SmcContext *s = avctx->priv_data;
  386. int pal_size;
  387. const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size);
  388. int ret;
  389. int total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4);
  390. if (total_blocks / 1024 > avpkt->size)
  391. return AVERROR_INVALIDDATA;
  392. bytestream2_init(&s->gb, buf, buf_size);
  393. if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
  394. return ret;
  395. if (pal && pal_size == AVPALETTE_SIZE) {
  396. s->frame->palette_has_changed = 1;
  397. memcpy(s->pal, pal, AVPALETTE_SIZE);
  398. } else if (pal) {
  399. av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", pal_size);
  400. }
  401. smc_decode_stream(s);
  402. *got_frame = 1;
  403. if ((ret = av_frame_ref(data, s->frame)) < 0)
  404. return ret;
  405. /* always report that the buffer was completely consumed */
  406. return buf_size;
  407. }
  408. static av_cold int smc_decode_end(AVCodecContext *avctx)
  409. {
  410. SmcContext *s = avctx->priv_data;
  411. av_frame_free(&s->frame);
  412. return 0;
  413. }
  414. AVCodec ff_smc_decoder = {
  415. .name = "smc",
  416. .long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"),
  417. .type = AVMEDIA_TYPE_VIDEO,
  418. .id = AV_CODEC_ID_SMC,
  419. .priv_data_size = sizeof(SmcContext),
  420. .init = smc_decode_init,
  421. .close = smc_decode_end,
  422. .decode = smc_decode_frame,
  423. .capabilities = AV_CODEC_CAP_DR1,
  424. };