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.

628 lines
18KB

  1. /*
  2. * Quicktime Animation (RLE) Video Decoder
  3. * Copyright (C) 2004 the ffmpeg project
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. */
  20. /**
  21. * @file qtrle.c
  22. * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
  23. * For more information about the QT RLE format, visit:
  24. * http://www.pcisys.net/~melanson/codecs/
  25. *
  26. * The QT RLE decoder has seven modes of operation:
  27. * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8
  28. * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555
  29. * data. 24-bit data is RGB24 and 32-bit data is RGBA32.
  30. */
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <unistd.h>
  35. #include "common.h"
  36. #include "avcodec.h"
  37. #include "dsputil.h"
  38. typedef struct QtrleContext {
  39. AVCodecContext *avctx;
  40. DSPContext dsp;
  41. AVFrame frame;
  42. unsigned char *buf;
  43. int size;
  44. } QtrleContext;
  45. #define CHECK_STREAM_PTR(n) \
  46. if ((stream_ptr + n) > s->size) { \
  47. av_log (s->avctx, AV_LOG_INFO, "Problem: stream_ptr out of bounds (%d >= %d)\n", \
  48. stream_ptr + n, s->size); \
  49. return; \
  50. }
  51. #define CHECK_PIXEL_PTR(n) \
  52. if (pixel_ptr + n > pixel_limit) { \
  53. av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
  54. pixel_ptr + n, pixel_limit); \
  55. return; \
  56. } \
  57. static void qtrle_decode_1bpp(QtrleContext *s)
  58. {
  59. }
  60. static void qtrle_decode_2bpp(QtrleContext *s)
  61. {
  62. }
  63. static void qtrle_decode_4bpp(QtrleContext *s)
  64. {
  65. int stream_ptr;
  66. int header;
  67. int start_line;
  68. int lines_to_change;
  69. int rle_code;
  70. int row_ptr, pixel_ptr;
  71. int row_inc = s->frame.linesize[0];
  72. unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8; /* 8 palette indices */
  73. unsigned char *rgb = s->frame.data[0];
  74. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  75. /* check if this frame is even supposed to change */
  76. if (s->size < 8)
  77. return;
  78. /* start after the chunk size */
  79. stream_ptr = 4;
  80. /* fetch the header */
  81. CHECK_STREAM_PTR(2);
  82. header = BE_16(&s->buf[stream_ptr]);
  83. stream_ptr += 2;
  84. /* if a header is present, fetch additional decoding parameters */
  85. if (header & 0x0008) {
  86. CHECK_STREAM_PTR(8);
  87. start_line = BE_16(&s->buf[stream_ptr]);
  88. stream_ptr += 4;
  89. lines_to_change = BE_16(&s->buf[stream_ptr]);
  90. stream_ptr += 4;
  91. } else {
  92. start_line = 0;
  93. lines_to_change = s->avctx->height;
  94. }
  95. row_ptr = row_inc * start_line;
  96. while (lines_to_change--) {
  97. CHECK_STREAM_PTR(2);
  98. pixel_ptr = row_ptr + (8 * (s->buf[stream_ptr++] - 1));
  99. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  100. if (rle_code == 0) {
  101. /* there's another skip code in the stream */
  102. CHECK_STREAM_PTR(1);
  103. pixel_ptr += (8 * (s->buf[stream_ptr++] - 1));
  104. } else if (rle_code < 0) {
  105. /* decode the run length code */
  106. rle_code = -rle_code;
  107. /* get the next 4 bytes from the stream, treat them as palette
  108. * indices, and output them rle_code times */
  109. CHECK_STREAM_PTR(4);
  110. pi1 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  111. pi2 = (s->buf[stream_ptr++]) & 0x0f;
  112. pi3 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  113. pi4 = (s->buf[stream_ptr++]) & 0x0f;
  114. pi5 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  115. pi6 = (s->buf[stream_ptr++]) & 0x0f;
  116. pi7 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  117. pi8 = (s->buf[stream_ptr++]) & 0x0f;
  118. CHECK_PIXEL_PTR(rle_code * 8);
  119. while (rle_code--) {
  120. rgb[pixel_ptr++] = pi1;
  121. rgb[pixel_ptr++] = pi2;
  122. rgb[pixel_ptr++] = pi3;
  123. rgb[pixel_ptr++] = pi4;
  124. rgb[pixel_ptr++] = pi5;
  125. rgb[pixel_ptr++] = pi6;
  126. rgb[pixel_ptr++] = pi7;
  127. rgb[pixel_ptr++] = pi8;
  128. }
  129. } else {
  130. /* copy the same pixel directly to output 4 times */
  131. rle_code *= 4;
  132. CHECK_STREAM_PTR(rle_code);
  133. CHECK_PIXEL_PTR(rle_code*2);
  134. while (rle_code--) {
  135. rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  136. rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x0f;
  137. }
  138. }
  139. }
  140. row_ptr += row_inc;
  141. }
  142. }
  143. static void qtrle_decode_8bpp(QtrleContext *s)
  144. {
  145. int stream_ptr;
  146. int header;
  147. int start_line;
  148. int lines_to_change;
  149. int rle_code;
  150. int row_ptr, pixel_ptr;
  151. int row_inc = s->frame.linesize[0];
  152. unsigned char pi1, pi2, pi3, pi4; /* 4 palette indices */
  153. unsigned char *rgb = s->frame.data[0];
  154. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  155. /* check if this frame is even supposed to change */
  156. if (s->size < 8)
  157. return;
  158. /* start after the chunk size */
  159. stream_ptr = 4;
  160. /* fetch the header */
  161. CHECK_STREAM_PTR(2);
  162. header = BE_16(&s->buf[stream_ptr]);
  163. stream_ptr += 2;
  164. /* if a header is present, fetch additional decoding parameters */
  165. if (header & 0x0008) {
  166. CHECK_STREAM_PTR(8);
  167. start_line = BE_16(&s->buf[stream_ptr]);
  168. stream_ptr += 4;
  169. lines_to_change = BE_16(&s->buf[stream_ptr]);
  170. stream_ptr += 4;
  171. } else {
  172. start_line = 0;
  173. lines_to_change = s->avctx->height;
  174. }
  175. row_ptr = row_inc * start_line;
  176. while (lines_to_change--) {
  177. CHECK_STREAM_PTR(2);
  178. pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1));
  179. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  180. if (rle_code == 0) {
  181. /* there's another skip code in the stream */
  182. CHECK_STREAM_PTR(1);
  183. pixel_ptr += (4 * (s->buf[stream_ptr++] - 1));
  184. } else if (rle_code < 0) {
  185. /* decode the run length code */
  186. rle_code = -rle_code;
  187. /* get the next 4 bytes from the stream, treat them as palette
  188. * indices, and output them rle_code times */
  189. CHECK_STREAM_PTR(4);
  190. pi1 = s->buf[stream_ptr++];
  191. pi2 = s->buf[stream_ptr++];
  192. pi3 = s->buf[stream_ptr++];
  193. pi4 = s->buf[stream_ptr++];
  194. CHECK_PIXEL_PTR(rle_code * 4);
  195. while (rle_code--) {
  196. rgb[pixel_ptr++] = pi1;
  197. rgb[pixel_ptr++] = pi2;
  198. rgb[pixel_ptr++] = pi3;
  199. rgb[pixel_ptr++] = pi4;
  200. }
  201. } else {
  202. /* copy the same pixel directly to output 4 times */
  203. rle_code *= 4;
  204. CHECK_STREAM_PTR(rle_code);
  205. CHECK_PIXEL_PTR(rle_code);
  206. while (rle_code--) {
  207. rgb[pixel_ptr++] = s->buf[stream_ptr++];
  208. }
  209. }
  210. }
  211. row_ptr += row_inc;
  212. }
  213. }
  214. static void qtrle_decode_16bpp(QtrleContext *s)
  215. {
  216. int stream_ptr;
  217. int header;
  218. int start_line;
  219. int lines_to_change;
  220. signed char rle_code;
  221. int row_ptr, pixel_ptr;
  222. int row_inc = s->frame.linesize[0];
  223. unsigned short rgb16;
  224. unsigned char *rgb = s->frame.data[0];
  225. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  226. /* check if this frame is even supposed to change */
  227. if (s->size < 8)
  228. return;
  229. /* start after the chunk size */
  230. stream_ptr = 4;
  231. /* fetch the header */
  232. CHECK_STREAM_PTR(2);
  233. header = BE_16(&s->buf[stream_ptr]);
  234. stream_ptr += 2;
  235. /* if a header is present, fetch additional decoding parameters */
  236. if (header & 0x0008) {
  237. CHECK_STREAM_PTR(8);
  238. start_line = BE_16(&s->buf[stream_ptr]);
  239. stream_ptr += 4;
  240. lines_to_change = BE_16(&s->buf[stream_ptr]);
  241. stream_ptr += 4;
  242. } else {
  243. start_line = 0;
  244. lines_to_change = s->avctx->height;
  245. }
  246. row_ptr = row_inc * start_line;
  247. while (lines_to_change--) {
  248. CHECK_STREAM_PTR(2);
  249. pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2;
  250. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  251. if (rle_code == 0) {
  252. /* there's another skip code in the stream */
  253. CHECK_STREAM_PTR(1);
  254. pixel_ptr += (s->buf[stream_ptr++] - 1) * 2;
  255. } else if (rle_code < 0) {
  256. /* decode the run length code */
  257. rle_code = -rle_code;
  258. CHECK_STREAM_PTR(2);
  259. rgb16 = BE_16(&s->buf[stream_ptr]);
  260. stream_ptr += 2;
  261. CHECK_PIXEL_PTR(rle_code * 2);
  262. while (rle_code--) {
  263. *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
  264. pixel_ptr += 2;
  265. }
  266. } else {
  267. CHECK_STREAM_PTR(rle_code * 2);
  268. CHECK_PIXEL_PTR(rle_code * 2);
  269. /* copy pixels directly to output */
  270. while (rle_code--) {
  271. rgb16 = BE_16(&s->buf[stream_ptr]);
  272. stream_ptr += 2;
  273. *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
  274. pixel_ptr += 2;
  275. }
  276. }
  277. }
  278. row_ptr += row_inc;
  279. }
  280. }
  281. static void qtrle_decode_24bpp(QtrleContext *s)
  282. {
  283. int stream_ptr;
  284. int header;
  285. int start_line;
  286. int lines_to_change;
  287. signed char rle_code;
  288. int row_ptr, pixel_ptr;
  289. int row_inc = s->frame.linesize[0];
  290. unsigned char r, g, b;
  291. unsigned char *rgb = s->frame.data[0];
  292. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  293. /* check if this frame is even supposed to change */
  294. if (s->size < 8)
  295. return;
  296. /* start after the chunk size */
  297. stream_ptr = 4;
  298. /* fetch the header */
  299. CHECK_STREAM_PTR(2);
  300. header = BE_16(&s->buf[stream_ptr]);
  301. stream_ptr += 2;
  302. /* if a header is present, fetch additional decoding parameters */
  303. if (header & 0x0008) {
  304. CHECK_STREAM_PTR(8);
  305. start_line = BE_16(&s->buf[stream_ptr]);
  306. stream_ptr += 4;
  307. lines_to_change = BE_16(&s->buf[stream_ptr]);
  308. stream_ptr += 4;
  309. } else {
  310. start_line = 0;
  311. lines_to_change = s->avctx->height;
  312. }
  313. row_ptr = row_inc * start_line;
  314. while (lines_to_change--) {
  315. CHECK_STREAM_PTR(2);
  316. pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3;
  317. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  318. if (rle_code == 0) {
  319. /* there's another skip code in the stream */
  320. CHECK_STREAM_PTR(1);
  321. pixel_ptr += (s->buf[stream_ptr++] - 1) * 3;
  322. } else if (rle_code < 0) {
  323. /* decode the run length code */
  324. rle_code = -rle_code;
  325. CHECK_STREAM_PTR(3);
  326. r = s->buf[stream_ptr++];
  327. g = s->buf[stream_ptr++];
  328. b = s->buf[stream_ptr++];
  329. CHECK_PIXEL_PTR(rle_code * 3);
  330. while (rle_code--) {
  331. rgb[pixel_ptr++] = r;
  332. rgb[pixel_ptr++] = g;
  333. rgb[pixel_ptr++] = b;
  334. }
  335. } else {
  336. CHECK_STREAM_PTR(rle_code * 3);
  337. CHECK_PIXEL_PTR(rle_code * 3);
  338. /* copy pixels directly to output */
  339. while (rle_code--) {
  340. rgb[pixel_ptr++] = s->buf[stream_ptr++];
  341. rgb[pixel_ptr++] = s->buf[stream_ptr++];
  342. rgb[pixel_ptr++] = s->buf[stream_ptr++];
  343. }
  344. }
  345. }
  346. row_ptr += row_inc;
  347. }
  348. }
  349. static void qtrle_decode_32bpp(QtrleContext *s)
  350. {
  351. int stream_ptr;
  352. int header;
  353. int start_line;
  354. int lines_to_change;
  355. signed char rle_code;
  356. int row_ptr, pixel_ptr;
  357. int row_inc = s->frame.linesize[0];
  358. unsigned char r, g, b;
  359. unsigned int argb;
  360. unsigned char *rgb = s->frame.data[0];
  361. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  362. /* check if this frame is even supposed to change */
  363. if (s->size < 8)
  364. return;
  365. /* start after the chunk size */
  366. stream_ptr = 4;
  367. /* fetch the header */
  368. CHECK_STREAM_PTR(2);
  369. header = BE_16(&s->buf[stream_ptr]);
  370. stream_ptr += 2;
  371. /* if a header is present, fetch additional decoding parameters */
  372. if (header & 0x0008) {
  373. CHECK_STREAM_PTR(8);
  374. start_line = BE_16(&s->buf[stream_ptr]);
  375. stream_ptr += 4;
  376. lines_to_change = BE_16(&s->buf[stream_ptr]);
  377. stream_ptr += 4;
  378. } else {
  379. start_line = 0;
  380. lines_to_change = s->avctx->height;
  381. }
  382. row_ptr = row_inc * start_line;
  383. while (lines_to_change--) {
  384. CHECK_STREAM_PTR(2);
  385. pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4;
  386. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  387. if (rle_code == 0) {
  388. /* there's another skip code in the stream */
  389. CHECK_STREAM_PTR(1);
  390. pixel_ptr += (s->buf[stream_ptr++] - 1) * 4;
  391. } else if (rle_code < 0) {
  392. /* decode the run length code */
  393. rle_code = -rle_code;
  394. CHECK_STREAM_PTR(4);
  395. stream_ptr++; /* skip the alpha (?) byte */
  396. r = s->buf[stream_ptr++];
  397. g = s->buf[stream_ptr++];
  398. b = s->buf[stream_ptr++];
  399. argb = (r << 16) | (g << 8) | (b << 0);
  400. CHECK_PIXEL_PTR(rle_code * 4);
  401. while (rle_code--) {
  402. *(unsigned int *)(&rgb[pixel_ptr]) = argb;
  403. pixel_ptr += 4;
  404. }
  405. } else {
  406. CHECK_STREAM_PTR(rle_code * 4);
  407. CHECK_PIXEL_PTR(rle_code * 4);
  408. /* copy pixels directly to output */
  409. while (rle_code--) {
  410. stream_ptr++; /* skip the alpha (?) byte */
  411. r = s->buf[stream_ptr++];
  412. g = s->buf[stream_ptr++];
  413. b = s->buf[stream_ptr++];
  414. argb = (r << 16) | (g << 8) | (b << 0);
  415. *(unsigned int *)(&rgb[pixel_ptr]) = argb;
  416. pixel_ptr += 4;
  417. }
  418. }
  419. }
  420. row_ptr += row_inc;
  421. }
  422. }
  423. static int qtrle_decode_init(AVCodecContext *avctx)
  424. {
  425. QtrleContext *s = (QtrleContext *)avctx->priv_data;
  426. s->avctx = avctx;
  427. switch (avctx->bits_per_sample) {
  428. case 1:
  429. case 2:
  430. case 4:
  431. case 8:
  432. case 33:
  433. case 34:
  434. case 36:
  435. case 40:
  436. avctx->pix_fmt = PIX_FMT_PAL8;
  437. break;
  438. case 16:
  439. avctx->pix_fmt = PIX_FMT_RGB555;
  440. break;
  441. case 24:
  442. avctx->pix_fmt = PIX_FMT_RGB24;
  443. break;
  444. case 32:
  445. avctx->pix_fmt = PIX_FMT_RGBA32;
  446. break;
  447. default:
  448. av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
  449. avctx->bits_per_sample);
  450. break;
  451. }
  452. avctx->has_b_frames = 0;
  453. dsputil_init(&s->dsp, avctx);
  454. s->frame.data[0] = NULL;
  455. return 0;
  456. }
  457. static int qtrle_decode_frame(AVCodecContext *avctx,
  458. void *data, int *data_size,
  459. uint8_t *buf, int buf_size)
  460. {
  461. QtrleContext *s = (QtrleContext *)avctx->priv_data;
  462. /* no supplementary picture */
  463. if (buf_size == 0)
  464. return 0;
  465. s->buf = buf;
  466. s->size = buf_size;
  467. s->frame.reference = 1;
  468. s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
  469. FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
  470. if (avctx->reget_buffer(avctx, &s->frame)) {
  471. av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
  472. return -1;
  473. }
  474. switch (avctx->bits_per_sample) {
  475. case 1:
  476. case 33:
  477. qtrle_decode_1bpp(s);
  478. break;
  479. case 2:
  480. case 34:
  481. qtrle_decode_2bpp(s);
  482. break;
  483. case 4:
  484. case 36:
  485. qtrle_decode_4bpp(s);
  486. /* make the palette available on the way out */
  487. memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
  488. if (s->avctx->palctrl->palette_changed) {
  489. s->frame.palette_has_changed = 1;
  490. s->avctx->palctrl->palette_changed = 0;
  491. }
  492. break;
  493. case 8:
  494. case 40:
  495. qtrle_decode_8bpp(s);
  496. /* make the palette available on the way out */
  497. memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
  498. if (s->avctx->palctrl->palette_changed) {
  499. s->frame.palette_has_changed = 1;
  500. s->avctx->palctrl->palette_changed = 0;
  501. }
  502. break;
  503. case 16:
  504. qtrle_decode_16bpp(s);
  505. break;
  506. case 24:
  507. qtrle_decode_24bpp(s);
  508. break;
  509. case 32:
  510. qtrle_decode_32bpp(s);
  511. break;
  512. default:
  513. av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
  514. avctx->bits_per_sample);
  515. break;
  516. }
  517. *data_size = sizeof(AVFrame);
  518. *(AVFrame*)data = s->frame;
  519. /* always report that the buffer was completely consumed */
  520. return buf_size;
  521. }
  522. static int qtrle_decode_end(AVCodecContext *avctx)
  523. {
  524. QtrleContext *s = (QtrleContext *)avctx->priv_data;
  525. if (s->frame.data[0])
  526. avctx->release_buffer(avctx, &s->frame);
  527. return 0;
  528. }
  529. AVCodec qtrle_decoder = {
  530. "qtrle",
  531. CODEC_TYPE_VIDEO,
  532. CODEC_ID_QTRLE,
  533. sizeof(QtrleContext),
  534. qtrle_decode_init,
  535. NULL,
  536. qtrle_decode_end,
  537. qtrle_decode_frame,
  538. CODEC_CAP_DR1,
  539. };