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.

625 lines
18KB

  1. /*
  2. * Quicktime Animation (RLE) Video Decoder
  3. * Copyright (C) 2004 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 qtrle.c
  23. * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
  24. * For more information about the QT RLE format, visit:
  25. * http://www.pcisys.net/~melanson/codecs/
  26. *
  27. * The QT RLE decoder has seven modes of operation:
  28. * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8
  29. * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555
  30. * data. 24-bit data is RGB24 and 32-bit data is RGB32.
  31. */
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36. #include "avcodec.h"
  37. typedef struct QtrleContext {
  38. AVCodecContext *avctx;
  39. AVFrame frame;
  40. const unsigned char *buf;
  41. int size;
  42. } QtrleContext;
  43. #define CHECK_STREAM_PTR(n) \
  44. if ((stream_ptr + n) > s->size) { \
  45. av_log (s->avctx, AV_LOG_INFO, "Problem: stream_ptr out of bounds (%d >= %d)\n", \
  46. stream_ptr + n, s->size); \
  47. return; \
  48. }
  49. #define CHECK_PIXEL_PTR(n) \
  50. if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \
  51. av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \
  52. pixel_ptr + n, pixel_limit); \
  53. return; \
  54. } \
  55. static void qtrle_decode_1bpp(QtrleContext *s)
  56. {
  57. }
  58. static void qtrle_decode_2bpp(QtrleContext *s)
  59. {
  60. }
  61. static void qtrle_decode_4bpp(QtrleContext *s)
  62. {
  63. int stream_ptr;
  64. int header;
  65. int start_line;
  66. int lines_to_change;
  67. int rle_code;
  68. int row_ptr, pixel_ptr;
  69. int row_inc = s->frame.linesize[0];
  70. unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8; /* 8 palette indices */
  71. unsigned char *rgb = s->frame.data[0];
  72. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  73. /* check if this frame is even supposed to change */
  74. if (s->size < 8)
  75. return;
  76. /* start after the chunk size */
  77. stream_ptr = 4;
  78. /* fetch the header */
  79. CHECK_STREAM_PTR(2);
  80. header = AV_RB16(&s->buf[stream_ptr]);
  81. stream_ptr += 2;
  82. /* if a header is present, fetch additional decoding parameters */
  83. if (header & 0x0008) {
  84. CHECK_STREAM_PTR(8);
  85. start_line = AV_RB16(&s->buf[stream_ptr]);
  86. stream_ptr += 4;
  87. lines_to_change = AV_RB16(&s->buf[stream_ptr]);
  88. stream_ptr += 4;
  89. } else {
  90. start_line = 0;
  91. lines_to_change = s->avctx->height;
  92. }
  93. row_ptr = row_inc * start_line;
  94. while (lines_to_change--) {
  95. CHECK_STREAM_PTR(2);
  96. pixel_ptr = row_ptr + (8 * (s->buf[stream_ptr++] - 1));
  97. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  98. if (rle_code == 0) {
  99. /* there's another skip code in the stream */
  100. CHECK_STREAM_PTR(1);
  101. pixel_ptr += (8 * (s->buf[stream_ptr++] - 1));
  102. CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
  103. } else if (rle_code < 0) {
  104. /* decode the run length code */
  105. rle_code = -rle_code;
  106. /* get the next 4 bytes from the stream, treat them as palette
  107. * indices, and output them rle_code times */
  108. CHECK_STREAM_PTR(4);
  109. pi1 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  110. pi2 = (s->buf[stream_ptr++]) & 0x0f;
  111. pi3 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  112. pi4 = (s->buf[stream_ptr++]) & 0x0f;
  113. pi5 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  114. pi6 = (s->buf[stream_ptr++]) & 0x0f;
  115. pi7 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  116. pi8 = (s->buf[stream_ptr++]) & 0x0f;
  117. CHECK_PIXEL_PTR(rle_code * 8);
  118. while (rle_code--) {
  119. rgb[pixel_ptr++] = pi1;
  120. rgb[pixel_ptr++] = pi2;
  121. rgb[pixel_ptr++] = pi3;
  122. rgb[pixel_ptr++] = pi4;
  123. rgb[pixel_ptr++] = pi5;
  124. rgb[pixel_ptr++] = pi6;
  125. rgb[pixel_ptr++] = pi7;
  126. rgb[pixel_ptr++] = pi8;
  127. }
  128. } else {
  129. /* copy the same pixel directly to output 4 times */
  130. rle_code *= 4;
  131. CHECK_STREAM_PTR(rle_code);
  132. CHECK_PIXEL_PTR(rle_code*2);
  133. while (rle_code--) {
  134. rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x0f;
  135. rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x0f;
  136. }
  137. }
  138. }
  139. row_ptr += row_inc;
  140. }
  141. }
  142. static void qtrle_decode_8bpp(QtrleContext *s)
  143. {
  144. int stream_ptr;
  145. int header;
  146. int start_line;
  147. int lines_to_change;
  148. int rle_code;
  149. int row_ptr, pixel_ptr;
  150. int row_inc = s->frame.linesize[0];
  151. unsigned char pi1, pi2, pi3, pi4; /* 4 palette indices */
  152. unsigned char *rgb = s->frame.data[0];
  153. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  154. /* check if this frame is even supposed to change */
  155. if (s->size < 8)
  156. return;
  157. /* start after the chunk size */
  158. stream_ptr = 4;
  159. /* fetch the header */
  160. CHECK_STREAM_PTR(2);
  161. header = AV_RB16(&s->buf[stream_ptr]);
  162. stream_ptr += 2;
  163. /* if a header is present, fetch additional decoding parameters */
  164. if (header & 0x0008) {
  165. CHECK_STREAM_PTR(8);
  166. start_line = AV_RB16(&s->buf[stream_ptr]);
  167. stream_ptr += 4;
  168. lines_to_change = AV_RB16(&s->buf[stream_ptr]);
  169. stream_ptr += 4;
  170. } else {
  171. start_line = 0;
  172. lines_to_change = s->avctx->height;
  173. }
  174. row_ptr = row_inc * start_line;
  175. while (lines_to_change--) {
  176. CHECK_STREAM_PTR(2);
  177. pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1));
  178. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  179. if (rle_code == 0) {
  180. /* there's another skip code in the stream */
  181. CHECK_STREAM_PTR(1);
  182. pixel_ptr += (4 * (s->buf[stream_ptr++] - 1));
  183. CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
  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. int 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 = AV_RB16(&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 = AV_RB16(&s->buf[stream_ptr]);
  239. stream_ptr += 4;
  240. lines_to_change = AV_RB16(&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. CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
  256. } else if (rle_code < 0) {
  257. /* decode the run length code */
  258. rle_code = -rle_code;
  259. CHECK_STREAM_PTR(2);
  260. rgb16 = AV_RB16(&s->buf[stream_ptr]);
  261. stream_ptr += 2;
  262. CHECK_PIXEL_PTR(rle_code * 2);
  263. while (rle_code--) {
  264. *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
  265. pixel_ptr += 2;
  266. }
  267. } else {
  268. CHECK_STREAM_PTR(rle_code * 2);
  269. CHECK_PIXEL_PTR(rle_code * 2);
  270. /* copy pixels directly to output */
  271. while (rle_code--) {
  272. rgb16 = AV_RB16(&s->buf[stream_ptr]);
  273. stream_ptr += 2;
  274. *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
  275. pixel_ptr += 2;
  276. }
  277. }
  278. }
  279. row_ptr += row_inc;
  280. }
  281. }
  282. static void qtrle_decode_24bpp(QtrleContext *s)
  283. {
  284. int stream_ptr;
  285. int header;
  286. int start_line;
  287. int lines_to_change;
  288. int rle_code;
  289. int row_ptr, pixel_ptr;
  290. int row_inc = s->frame.linesize[0];
  291. unsigned char r, g, b;
  292. unsigned char *rgb = s->frame.data[0];
  293. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  294. /* check if this frame is even supposed to change */
  295. if (s->size < 8)
  296. return;
  297. /* start after the chunk size */
  298. stream_ptr = 4;
  299. /* fetch the header */
  300. CHECK_STREAM_PTR(2);
  301. header = AV_RB16(&s->buf[stream_ptr]);
  302. stream_ptr += 2;
  303. /* if a header is present, fetch additional decoding parameters */
  304. if (header & 0x0008) {
  305. CHECK_STREAM_PTR(8);
  306. start_line = AV_RB16(&s->buf[stream_ptr]);
  307. stream_ptr += 4;
  308. lines_to_change = AV_RB16(&s->buf[stream_ptr]);
  309. stream_ptr += 4;
  310. } else {
  311. start_line = 0;
  312. lines_to_change = s->avctx->height;
  313. }
  314. row_ptr = row_inc * start_line;
  315. while (lines_to_change--) {
  316. CHECK_STREAM_PTR(2);
  317. pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3;
  318. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  319. if (rle_code == 0) {
  320. /* there's another skip code in the stream */
  321. CHECK_STREAM_PTR(1);
  322. pixel_ptr += (s->buf[stream_ptr++] - 1) * 3;
  323. CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
  324. } else if (rle_code < 0) {
  325. /* decode the run length code */
  326. rle_code = -rle_code;
  327. CHECK_STREAM_PTR(3);
  328. r = s->buf[stream_ptr++];
  329. g = s->buf[stream_ptr++];
  330. b = s->buf[stream_ptr++];
  331. CHECK_PIXEL_PTR(rle_code * 3);
  332. while (rle_code--) {
  333. rgb[pixel_ptr++] = r;
  334. rgb[pixel_ptr++] = g;
  335. rgb[pixel_ptr++] = b;
  336. }
  337. } else {
  338. CHECK_STREAM_PTR(rle_code * 3);
  339. CHECK_PIXEL_PTR(rle_code * 3);
  340. /* copy pixels directly to output */
  341. while (rle_code--) {
  342. rgb[pixel_ptr++] = s->buf[stream_ptr++];
  343. rgb[pixel_ptr++] = s->buf[stream_ptr++];
  344. rgb[pixel_ptr++] = s->buf[stream_ptr++];
  345. }
  346. }
  347. }
  348. row_ptr += row_inc;
  349. }
  350. }
  351. static void qtrle_decode_32bpp(QtrleContext *s)
  352. {
  353. int stream_ptr;
  354. int header;
  355. int start_line;
  356. int lines_to_change;
  357. int rle_code;
  358. int row_ptr, pixel_ptr;
  359. int row_inc = s->frame.linesize[0];
  360. unsigned char a, r, g, b;
  361. unsigned int argb;
  362. unsigned char *rgb = s->frame.data[0];
  363. int pixel_limit = s->frame.linesize[0] * s->avctx->height;
  364. /* check if this frame is even supposed to change */
  365. if (s->size < 8)
  366. return;
  367. /* start after the chunk size */
  368. stream_ptr = 4;
  369. /* fetch the header */
  370. CHECK_STREAM_PTR(2);
  371. header = AV_RB16(&s->buf[stream_ptr]);
  372. stream_ptr += 2;
  373. /* if a header is present, fetch additional decoding parameters */
  374. if (header & 0x0008) {
  375. CHECK_STREAM_PTR(8);
  376. start_line = AV_RB16(&s->buf[stream_ptr]);
  377. stream_ptr += 4;
  378. lines_to_change = AV_RB16(&s->buf[stream_ptr]);
  379. stream_ptr += 4;
  380. } else {
  381. start_line = 0;
  382. lines_to_change = s->avctx->height;
  383. }
  384. row_ptr = row_inc * start_line;
  385. while (lines_to_change--) {
  386. CHECK_STREAM_PTR(2);
  387. pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4;
  388. while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
  389. if (rle_code == 0) {
  390. /* there's another skip code in the stream */
  391. CHECK_STREAM_PTR(1);
  392. pixel_ptr += (s->buf[stream_ptr++] - 1) * 4;
  393. CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
  394. } else if (rle_code < 0) {
  395. /* decode the run length code */
  396. rle_code = -rle_code;
  397. CHECK_STREAM_PTR(4);
  398. a = s->buf[stream_ptr++];
  399. r = s->buf[stream_ptr++];
  400. g = s->buf[stream_ptr++];
  401. b = s->buf[stream_ptr++];
  402. argb = (a << 24) | (r << 16) | (g << 8) | (b << 0);
  403. CHECK_PIXEL_PTR(rle_code * 4);
  404. while (rle_code--) {
  405. *(unsigned int *)(&rgb[pixel_ptr]) = argb;
  406. pixel_ptr += 4;
  407. }
  408. } else {
  409. CHECK_STREAM_PTR(rle_code * 4);
  410. CHECK_PIXEL_PTR(rle_code * 4);
  411. /* copy pixels directly to output */
  412. while (rle_code--) {
  413. a = s->buf[stream_ptr++];
  414. r = s->buf[stream_ptr++];
  415. g = s->buf[stream_ptr++];
  416. b = s->buf[stream_ptr++];
  417. argb = (a << 24) | (r << 16) | (g << 8) | (b << 0);
  418. *(unsigned int *)(&rgb[pixel_ptr]) = argb;
  419. pixel_ptr += 4;
  420. }
  421. }
  422. }
  423. row_ptr += row_inc;
  424. }
  425. }
  426. static av_cold int qtrle_decode_init(AVCodecContext *avctx)
  427. {
  428. QtrleContext *s = avctx->priv_data;
  429. s->avctx = avctx;
  430. switch (avctx->bits_per_sample) {
  431. case 1:
  432. case 2:
  433. case 4:
  434. case 8:
  435. case 33:
  436. case 34:
  437. case 36:
  438. case 40:
  439. avctx->pix_fmt = PIX_FMT_PAL8;
  440. break;
  441. case 16:
  442. avctx->pix_fmt = PIX_FMT_RGB555;
  443. break;
  444. case 24:
  445. avctx->pix_fmt = PIX_FMT_RGB24;
  446. break;
  447. case 32:
  448. avctx->pix_fmt = PIX_FMT_RGB32;
  449. break;
  450. default:
  451. av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
  452. avctx->bits_per_sample);
  453. break;
  454. }
  455. s->frame.data[0] = NULL;
  456. return 0;
  457. }
  458. static int qtrle_decode_frame(AVCodecContext *avctx,
  459. void *data, int *data_size,
  460. const uint8_t *buf, int buf_size)
  461. {
  462. QtrleContext *s = avctx->priv_data;
  463. s->buf = buf;
  464. s->size = buf_size;
  465. s->frame.reference = 1;
  466. s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
  467. FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
  468. if (avctx->reget_buffer(avctx, &s->frame)) {
  469. av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
  470. return -1;
  471. }
  472. switch (avctx->bits_per_sample) {
  473. case 1:
  474. case 33:
  475. qtrle_decode_1bpp(s);
  476. break;
  477. case 2:
  478. case 34:
  479. qtrle_decode_2bpp(s);
  480. break;
  481. case 4:
  482. case 36:
  483. qtrle_decode_4bpp(s);
  484. /* make the palette available on the way out */
  485. memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
  486. if (s->avctx->palctrl->palette_changed) {
  487. s->frame.palette_has_changed = 1;
  488. s->avctx->palctrl->palette_changed = 0;
  489. }
  490. break;
  491. case 8:
  492. case 40:
  493. qtrle_decode_8bpp(s);
  494. /* make the palette available on the way out */
  495. memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
  496. if (s->avctx->palctrl->palette_changed) {
  497. s->frame.palette_has_changed = 1;
  498. s->avctx->palctrl->palette_changed = 0;
  499. }
  500. break;
  501. case 16:
  502. qtrle_decode_16bpp(s);
  503. break;
  504. case 24:
  505. qtrle_decode_24bpp(s);
  506. break;
  507. case 32:
  508. qtrle_decode_32bpp(s);
  509. break;
  510. default:
  511. av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
  512. avctx->bits_per_sample);
  513. break;
  514. }
  515. *data_size = sizeof(AVFrame);
  516. *(AVFrame*)data = s->frame;
  517. /* always report that the buffer was completely consumed */
  518. return buf_size;
  519. }
  520. static av_cold int qtrle_decode_end(AVCodecContext *avctx)
  521. {
  522. QtrleContext *s = avctx->priv_data;
  523. if (s->frame.data[0])
  524. avctx->release_buffer(avctx, &s->frame);
  525. return 0;
  526. }
  527. AVCodec qtrle_decoder = {
  528. "qtrle",
  529. CODEC_TYPE_VIDEO,
  530. CODEC_ID_QTRLE,
  531. sizeof(QtrleContext),
  532. qtrle_decode_init,
  533. NULL,
  534. qtrle_decode_end,
  535. qtrle_decode_frame,
  536. CODEC_CAP_DR1,
  537. };