smc.c 16 KB

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