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.

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