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/** 23 * @file 24 * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net) 25 * For more information about the QT RLE format, visit: 26 * http://www.pcisys.net/~melanson/codecs/ 27 * 28 * The QT RLE decoder has seven modes of operation: 29 * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8 30 * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555 31 * data. 24-bit data is RGB24 and 32-bit data is RGB32. 32 */ 33 34#include <stdio.h> 35#include <stdlib.h> 36#include <string.h> 37 38#include "avcodec.h" 39#include "decode.h" 40#include "bytestream.h" 41#include "codec_internal.h" 42#include "internal.h" 43 44typedef struct QtrleContext { 45 AVCodecContext *avctx; 46 AVFrame *frame; 47 48 GetByteContext g; 49 uint32_t pal[256]; 50} QtrleContext; 51 52#define CHECK_PIXEL_PTR(n) \ 53 if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \ 54 av_log (s->avctx, AV_LOG_ERROR, "Problem: pixel_ptr = %d, pixel_limit = %d\n",\ 55 pixel_ptr + n, pixel_limit); \ 56 return; \ 57 } \ 58 59static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change) 60{ 61 int rle_code; 62 int pixel_ptr; 63 int row_inc = s->frame->linesize[0]; 64 uint8_t pi0, pi1; /* 2 8-pixel values */ 65 uint8_t *rgb = s->frame->data[0]; 66 int pixel_limit = s->frame->linesize[0] * s->avctx->height; 67 int skip; 68 /* skip & 0x80 appears to mean 'start a new line', which can be interpreted 69 * as 'go to next line' during the decoding of a frame but is 'go to first 70 * line' at the beginning. Since we always interpret it as 'go to next line' 71 * in the decoding loop (which makes code simpler/faster), the first line 72 * would not be counted, so we count one more. 73 * See: https://trac.ffmpeg.org/ticket/226 74 * In the following decoding loop, row_ptr will be the position of the 75 * current row. */ 76 77 row_ptr -= row_inc; 78 pixel_ptr = row_ptr; 79 lines_to_change++; 80 while (lines_to_change) { 81 skip = bytestream2_get_byte(&s->g); 82 rle_code = (int8_t)bytestream2_get_byte(&s->g); 83 if (rle_code == 0) 84 break; 85 if(skip & 0x80) { 86 lines_to_change--; 87 row_ptr += row_inc; 88 pixel_ptr = row_ptr + 2 * 8 * (skip & 0x7f); 89 } else 90 pixel_ptr += 2 * 8 * skip; 91 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ 92 93 if(rle_code == -1) 94 continue; 95 96 if (rle_code < 0) { 97 /* decode the run length code */ 98 rle_code = -rle_code; 99 /* get the next 2 bytes from the stream, treat them as groups 100 * of 8 pixels, and output them rle_code times */ 101 102 pi0 = bytestream2_get_byte(&s->g); 103 pi1 = bytestream2_get_byte(&s->g); 104 CHECK_PIXEL_PTR(rle_code * 2 * 8); 105 106 while (rle_code--) { 107 rgb[pixel_ptr++] = (pi0 >> 7) & 0x01; 108 rgb[pixel_ptr++] = (pi0 >> 6) & 0x01; 109 rgb[pixel_ptr++] = (pi0 >> 5) & 0x01; 110 rgb[pixel_ptr++] = (pi0 >> 4) & 0x01; 111 rgb[pixel_ptr++] = (pi0 >> 3) & 0x01; 112 rgb[pixel_ptr++] = (pi0 >> 2) & 0x01; 113 rgb[pixel_ptr++] = (pi0 >> 1) & 0x01; 114 rgb[pixel_ptr++] = pi0 & 0x01; 115 rgb[pixel_ptr++] = (pi1 >> 7) & 0x01; 116 rgb[pixel_ptr++] = (pi1 >> 6) & 0x01; 117 rgb[pixel_ptr++] = (pi1 >> 5) & 0x01; 118 rgb[pixel_ptr++] = (pi1 >> 4) & 0x01; 119 rgb[pixel_ptr++] = (pi1 >> 3) & 0x01; 120 rgb[pixel_ptr++] = (pi1 >> 2) & 0x01; 121 rgb[pixel_ptr++] = (pi1 >> 1) & 0x01; 122 rgb[pixel_ptr++] = pi1 & 0x01; 123 } 124 } else { 125 /* copy the same pixel directly to output 2 times */ 126 rle_code *= 2; 127 CHECK_PIXEL_PTR(rle_code * 8); 128 129 while (rle_code--) { 130 int x = bytestream2_get_byte(&s->g); 131 rgb[pixel_ptr++] = (x >> 7) & 0x01; 132 rgb[pixel_ptr++] = (x >> 6) & 0x01; 133 rgb[pixel_ptr++] = (x >> 5) & 0x01; 134 rgb[pixel_ptr++] = (x >> 4) & 0x01; 135 rgb[pixel_ptr++] = (x >> 3) & 0x01; 136 rgb[pixel_ptr++] = (x >> 2) & 0x01; 137 rgb[pixel_ptr++] = (x >> 1) & 0x01; 138 rgb[pixel_ptr++] = x & 0x01; 139 } 140 } 141 } 142} 143 144static inline void qtrle_decode_2n4bpp(QtrleContext *s, int row_ptr, 145 int lines_to_change, int bpp) 146{ 147 int rle_code, i; 148 int pixel_ptr; 149 int row_inc = s->frame->linesize[0]; 150 uint8_t pi[16]; /* 16 palette indices */ 151 uint8_t *rgb = s->frame->data[0]; 152 int pixel_limit = s->frame->linesize[0] * s->avctx->height; 153 int num_pixels = (bpp == 4) ? 8 : 16; 154 155 while (lines_to_change--) { 156 pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1)); 157 CHECK_PIXEL_PTR(0); 158 159 while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { 160 if (bytestream2_get_bytes_left(&s->g) < 1) 161 return; 162 if (rle_code == 0) { 163 /* there's another skip code in the stream */ 164 pixel_ptr += (num_pixels * (bytestream2_get_byte(&s->g) - 1)); 165 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ 166 } else if (rle_code < 0) { 167 /* decode the run length code */ 168 rle_code = -rle_code; 169 /* get the next 4 bytes from the stream, treat them as palette 170 * indexes, and output them rle_code times */ 171 for (i = num_pixels-1; i >= 0; i--) { 172 pi[num_pixels-1-i] = (bytestream2_peek_byte(&s->g) >> ((i*bpp) & 0x07)) & ((1<<bpp)-1); 173 bytestream2_skip(&s->g, ((i & ((num_pixels>>2)-1)) == 0)); 174 } 175 CHECK_PIXEL_PTR(rle_code * num_pixels); 176 while (rle_code--) { 177 memcpy(&rgb[pixel_ptr], &pi, num_pixels); 178 pixel_ptr += num_pixels; 179 } 180 } else { 181 /* copy the same pixel directly to output 4 times */ 182 rle_code *= 4; 183 CHECK_PIXEL_PTR(rle_code*(num_pixels>>2)); 184 while (rle_code--) { 185 if(bpp == 4) { 186 int x = bytestream2_get_byte(&s->g); 187 rgb[pixel_ptr++] = (x >> 4) & 0x0f; 188 rgb[pixel_ptr++] = x & 0x0f; 189 } else { 190 int x = bytestream2_get_byte(&s->g); 191 rgb[pixel_ptr++] = (x >> 6) & 0x03; 192 rgb[pixel_ptr++] = (x >> 4) & 0x03; 193 rgb[pixel_ptr++] = (x >> 2) & 0x03; 194 rgb[pixel_ptr++] = x & 0x03; 195 } 196 } 197 } 198 } 199 row_ptr += row_inc; 200 } 201} 202 203static void qtrle_decode_8bpp(QtrleContext *s, int row_ptr, int lines_to_change) 204{ 205 int rle_code; 206 int pixel_ptr; 207 int row_inc = s->frame->linesize[0]; 208 uint8_t pi1, pi2, pi3, pi4; /* 4 palette indexes */ 209 uint8_t *rgb = s->frame->data[0]; 210 int pixel_limit = s->frame->linesize[0] * s->avctx->height; 211 212 while (lines_to_change--) { 213 pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1)); 214 CHECK_PIXEL_PTR(0); 215 216 while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { 217 if (bytestream2_get_bytes_left(&s->g) < 1) 218 return; 219 if (rle_code == 0) { 220 /* there's another skip code in the stream */ 221 pixel_ptr += (4 * (bytestream2_get_byte(&s->g) - 1)); 222 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ 223 } else if (rle_code < 0) { 224 /* decode the run length code */ 225 rle_code = -rle_code; 226 /* get the next 4 bytes from the stream, treat them as palette 227 * indexes, and output them rle_code times */ 228 pi1 = bytestream2_get_byte(&s->g); 229 pi2 = bytestream2_get_byte(&s->g); 230 pi3 = bytestream2_get_byte(&s->g); 231 pi4 = bytestream2_get_byte(&s->g); 232 233 CHECK_PIXEL_PTR(rle_code * 4); 234 235 while (rle_code--) { 236 rgb[pixel_ptr++] = pi1; 237 rgb[pixel_ptr++] = pi2; 238 rgb[pixel_ptr++] = pi3; 239 rgb[pixel_ptr++] = pi4; 240 } 241 } else { 242 /* copy the same pixel directly to output 4 times */ 243 rle_code *= 4; 244 CHECK_PIXEL_PTR(rle_code); 245 246 bytestream2_get_buffer(&s->g, &rgb[pixel_ptr], rle_code); 247 pixel_ptr += rle_code; 248 } 249 } 250 row_ptr += row_inc; 251 } 252} 253 254static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change) 255{ 256 int rle_code; 257 int pixel_ptr; 258 int row_inc = s->frame->linesize[0]; 259 uint16_t rgb16; 260 uint8_t *rgb = s->frame->data[0]; 261 int pixel_limit = s->frame->linesize[0] * s->avctx->height; 262 263 while (lines_to_change--) { 264 pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2; 265 CHECK_PIXEL_PTR(0); 266 267 while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { 268 if (bytestream2_get_bytes_left(&s->g) < 1) 269 return; 270 if (rle_code == 0) { 271 /* there's another skip code in the stream */ 272 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 2; 273 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ 274 } else if (rle_code < 0) { 275 /* decode the run length code */ 276 rle_code = -rle_code; 277 rgb16 = bytestream2_get_be16(&s->g); 278 279 CHECK_PIXEL_PTR(rle_code * 2); 280 281 while (rle_code--) { 282 *(uint16_t *)(&rgb[pixel_ptr]) = rgb16; 283 pixel_ptr += 2; 284 } 285 } else { 286 CHECK_PIXEL_PTR(rle_code * 2); 287 288 /* copy pixels directly to output */ 289 while (rle_code--) { 290 rgb16 = bytestream2_get_be16(&s->g); 291 *(uint16_t *)(&rgb[pixel_ptr]) = rgb16; 292 pixel_ptr += 2; 293 } 294 } 295 } 296 row_ptr += row_inc; 297 } 298} 299 300static void qtrle_decode_24bpp(QtrleContext *s, int row_ptr, int lines_to_change) 301{ 302 int rle_code, rle_code_half; 303 int pixel_ptr; 304 int row_inc = s->frame->linesize[0]; 305 uint8_t b; 306 uint16_t rg; 307 uint8_t *rgb = s->frame->data[0]; 308 int pixel_limit = s->frame->linesize[0] * s->avctx->height; 309 310 while (lines_to_change--) { 311 pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3; 312 CHECK_PIXEL_PTR(0); 313 314 while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { 315 if (bytestream2_get_bytes_left(&s->g) < 1) 316 return; 317 if (rle_code == 0) { 318 /* there's another skip code in the stream */ 319 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 3; 320 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ 321 } else if (rle_code < 0) { 322 /* decode the run length code */ 323 rle_code = -rle_code; 324 rg = bytestream2_get_ne16(&s->g); 325 b = bytestream2_get_byte(&s->g); 326 327 CHECK_PIXEL_PTR(rle_code * 3); 328 329 while (rle_code--) { 330 AV_WN16(rgb + pixel_ptr, rg); 331 rgb[pixel_ptr + 2] = b; 332 pixel_ptr += 3; 333 } 334 } else { 335 CHECK_PIXEL_PTR(rle_code * 3); 336 337 rle_code_half = rle_code / 2; 338 339 while (rle_code_half--) { /* copy 2 raw rgb value at the same time */ 340 AV_WN32(rgb + pixel_ptr, bytestream2_get_ne32(&s->g)); /* rgbr */ 341 AV_WN16(rgb + pixel_ptr + 4, bytestream2_get_ne16(&s->g)); /* rgbr */ 342 pixel_ptr += 6; 343 } 344 345 if (rle_code % 2 != 0){ /* not even raw value */ 346 AV_WN16(rgb + pixel_ptr, bytestream2_get_ne16(&s->g)); 347 rgb[pixel_ptr + 2] = bytestream2_get_byte(&s->g); 348 pixel_ptr += 3; 349 } 350 } 351 } 352 row_ptr += row_inc; 353 } 354} 355 356static void qtrle_decode_32bpp(QtrleContext *s, int row_ptr, int lines_to_change) 357{ 358 int rle_code, rle_code_half; 359 int pixel_ptr; 360 int row_inc = s->frame->linesize[0]; 361 unsigned int argb; 362 uint8_t *rgb = s->frame->data[0]; 363 int pixel_limit = s->frame->linesize[0] * s->avctx->height; 364 365 while (lines_to_change--) { 366 pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4; 367 CHECK_PIXEL_PTR(0); 368 369 while ((rle_code = (int8_t)bytestream2_get_byte(&s->g)) != -1) { 370 if (bytestream2_get_bytes_left(&s->g) < 1) 371 return; 372 if (rle_code == 0) { 373 /* there's another skip code in the stream */ 374 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 4; 375 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ 376 } else if (rle_code < 0) { 377 /* decode the run length code */ 378 rle_code = -rle_code; 379 argb = bytestream2_get_ne32(&s->g); 380 381 CHECK_PIXEL_PTR(rle_code * 4); 382 383 while (rle_code--) { 384 AV_WN32A(rgb + pixel_ptr, argb); 385 pixel_ptr += 4; 386 } 387 } else { 388 CHECK_PIXEL_PTR(rle_code * 4); 389 390 /* copy pixels directly to output */ 391 rle_code_half = rle_code / 2; 392 while (rle_code_half--) { /* copy 2 argb raw value at the same time */ 393 AV_WN64(rgb + pixel_ptr, bytestream2_get_ne64(&s->g)); 394 pixel_ptr += 8; 395 } 396 397 if (rle_code % 2 != 0){ /* not even raw value */ 398 AV_WN32A(rgb + pixel_ptr, bytestream2_get_ne32(&s->g)); 399 pixel_ptr += 4; 400 } 401 } 402 } 403 row_ptr += row_inc; 404 } 405} 406 407static av_cold int qtrle_decode_init(AVCodecContext *avctx) 408{ 409 QtrleContext *s = avctx->priv_data; 410 411 s->avctx = avctx; 412 switch (avctx->bits_per_coded_sample) { 413 case 1: 414 case 2: 415 case 4: 416 case 8: 417 case 33: 418 case 34: 419 case 36: 420 case 40: 421 avctx->pix_fmt = AV_PIX_FMT_PAL8; 422 break; 423 424 case 16: 425 avctx->pix_fmt = AV_PIX_FMT_RGB555; 426 break; 427 428 case 24: 429 avctx->pix_fmt = AV_PIX_FMT_RGB24; 430 break; 431 432 case 32: 433 avctx->pix_fmt = AV_PIX_FMT_ARGB; 434 break; 435 436 default: 437 av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", 438 avctx->bits_per_coded_sample); 439 return AVERROR_INVALIDDATA; 440 } 441 442 s->frame = av_frame_alloc(); 443 if (!s->frame) 444 return AVERROR(ENOMEM); 445 446 return 0; 447} 448 449static int qtrle_decode_frame(AVCodecContext *avctx, AVFrame *rframe, 450 int *got_frame, AVPacket *avpkt) 451{ 452 QtrleContext *s = avctx->priv_data; 453 int header, start_line; 454 int height, row_ptr; 455 int has_palette = 0; 456 int duplicate = 0; 457 int ret, size; 458 459 bytestream2_init(&s->g, avpkt->data, avpkt->size); 460 461 /* check if this frame is even supposed to change */ 462 if (avpkt->size < 8) { 463 duplicate = 1; 464 goto done; 465 } 466 467 /* start after the chunk size */ 468 size = bytestream2_get_be32(&s->g) & 0x3FFFFFFF; 469 if (size - avpkt->size > size * (int64_t)avctx->discard_damaged_percentage / 100) 470 return AVERROR_INVALIDDATA; 471 472 473 /* fetch the header */ 474 header = bytestream2_get_be16(&s->g); 475 476 /* if a header is present, fetch additional decoding parameters */ 477 if (header & 0x0008) { 478 if (avpkt->size < 14) { 479 duplicate = 1; 480 goto done; 481 } 482 start_line = bytestream2_get_be16(&s->g); 483 bytestream2_skip(&s->g, 2); 484 height = bytestream2_get_be16(&s->g); 485 bytestream2_skip(&s->g, 2); 486 if (height > s->avctx->height - start_line) { 487 duplicate = 1; 488 goto done; 489 } 490 } else { 491 start_line = 0; 492 height = s->avctx->height; 493 } 494 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0) 495 return ret; 496 497 row_ptr = s->frame->linesize[0] * start_line; 498 499 switch (avctx->bits_per_coded_sample) { 500 case 1: 501 case 33: 502 qtrle_decode_1bpp(s, row_ptr, height); 503 has_palette = 1; 504 break; 505 506 case 2: 507 case 34: 508 qtrle_decode_2n4bpp(s, row_ptr, height, 2); 509 has_palette = 1; 510 break; 511 512 case 4: 513 case 36: 514 qtrle_decode_2n4bpp(s, row_ptr, height, 4); 515 has_palette = 1; 516 break; 517 518 case 8: 519 case 40: 520 qtrle_decode_8bpp(s, row_ptr, height); 521 has_palette = 1; 522 break; 523 524 case 16: 525 qtrle_decode_16bpp(s, row_ptr, height); 526 break; 527 528 case 24: 529 qtrle_decode_24bpp(s, row_ptr, height); 530 break; 531 532 case 32: 533 qtrle_decode_32bpp(s, row_ptr, height); 534 break; 535 536 default: 537 av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", 538 avctx->bits_per_coded_sample); 539 break; 540 } 541 542 if(has_palette) { 543 s->frame->palette_has_changed = ff_copy_palette(s->pal, avpkt, avctx); 544 545 /* make the palette available on the way out */ 546 memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); 547 } 548 549done: 550 if (!s->frame->data[0]) 551 return AVERROR_INVALIDDATA; 552 if (duplicate) { 553 // ff_reget_buffer() isn't needed when frames don't change, so just update 554 // frame props. 555 ret = ff_decode_frame_props(avctx, s->frame); 556 if (ret < 0) 557 return ret; 558 } 559 560 if ((ret = av_frame_ref(rframe, s->frame)) < 0) 561 return ret; 562 *got_frame = 1; 563 564 /* always report that the buffer was completely consumed */ 565 return avpkt->size; 566} 567 568static void qtrle_decode_flush(AVCodecContext *avctx) 569{ 570 QtrleContext *s = avctx->priv_data; 571 572 av_frame_unref(s->frame); 573} 574 575static av_cold int qtrle_decode_end(AVCodecContext *avctx) 576{ 577 QtrleContext *s = avctx->priv_data; 578 579 av_frame_free(&s->frame); 580 581 return 0; 582} 583 584const FFCodec ff_qtrle_decoder = { 585 .p.name = "qtrle", 586 .p.long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), 587 .p.type = AVMEDIA_TYPE_VIDEO, 588 .p.id = AV_CODEC_ID_QTRLE, 589 .priv_data_size = sizeof(QtrleContext), 590 .init = qtrle_decode_init, 591 .close = qtrle_decode_end, 592 FF_CODEC_DECODE_CB(qtrle_decode_frame), 593 .flush = qtrle_decode_flush, 594 .p.capabilities = AV_CODEC_CAP_DR1, 595 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 596}; 597