1/* 2 * Apple Pixlet decoder 3 * Copyright (c) 2016 Paul B Mahol 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#include <stdint.h> 23 24#include "libavutil/imgutils.h" 25#include "libavutil/intmath.h" 26#include "libavutil/opt.h" 27 28#include "avcodec.h" 29#include "bytestream.h" 30#include "codec_internal.h" 31#include "get_bits.h" 32#include "internal.h" 33#include "thread.h" 34#include "unary.h" 35 36#define NB_LEVELS 4 37 38#define PIXLET_MAGIC 0xDEADBEEF 39 40#define H 0 41#define V 1 42 43typedef struct SubBand { 44 unsigned width, height; 45 unsigned size; 46 unsigned x, y; 47} SubBand; 48 49typedef struct PixletContext { 50 AVClass *class; 51 52 GetByteContext gb; 53 GetBitContext bc; 54 55 int levels; 56 int depth; 57 int w, h; 58 59 int16_t *filter[2]; 60 int16_t *prediction; 61 int64_t scaling[4][2][NB_LEVELS]; 62 uint16_t lut[65536]; 63 SubBand band[4][NB_LEVELS * 3 + 1]; 64} PixletContext; 65 66static av_cold int pixlet_init(AVCodecContext *avctx) 67{ 68 avctx->pix_fmt = AV_PIX_FMT_YUV420P16; 69 avctx->color_range = AVCOL_RANGE_JPEG; 70 return 0; 71} 72 73static void free_buffers(AVCodecContext *avctx) 74{ 75 PixletContext *ctx = avctx->priv_data; 76 77 av_freep(&ctx->filter[0]); 78 av_freep(&ctx->filter[1]); 79 av_freep(&ctx->prediction); 80} 81 82static av_cold int pixlet_close(AVCodecContext *avctx) 83{ 84 PixletContext *ctx = avctx->priv_data; 85 free_buffers(avctx); 86 ctx->w = 0; 87 ctx->h = 0; 88 return 0; 89} 90 91static int init_decoder(AVCodecContext *avctx) 92{ 93 PixletContext *ctx = avctx->priv_data; 94 int i, plane; 95 96 ctx->filter[0] = av_malloc_array(ctx->h, sizeof(int16_t)); 97 ctx->filter[1] = av_malloc_array(FFMAX(ctx->h, ctx->w) + 16, sizeof(int16_t)); 98 ctx->prediction = av_malloc_array((ctx->w >> NB_LEVELS), sizeof(int16_t)); 99 if (!ctx->filter[0] || !ctx->filter[1] || !ctx->prediction) 100 return AVERROR(ENOMEM); 101 102 for (plane = 0; plane < 3; plane++) { 103 unsigned shift = plane > 0; 104 unsigned w = ctx->w >> shift; 105 unsigned h = ctx->h >> shift; 106 107 ctx->band[plane][0].width = w >> NB_LEVELS; 108 ctx->band[plane][0].height = h >> NB_LEVELS; 109 ctx->band[plane][0].size = (w >> NB_LEVELS) * (h >> NB_LEVELS); 110 111 for (i = 0; i < NB_LEVELS * 3; i++) { 112 unsigned scale = ctx->levels - (i / 3); 113 114 ctx->band[plane][i + 1].width = w >> scale; 115 ctx->band[plane][i + 1].height = h >> scale; 116 ctx->band[plane][i + 1].size = (w >> scale) * (h >> scale); 117 118 ctx->band[plane][i + 1].x = (w >> scale) * (((i + 1) % 3) != 2); 119 ctx->band[plane][i + 1].y = (h >> scale) * (((i + 1) % 3) != 1); 120 } 121 } 122 123 return 0; 124} 125 126static int read_low_coeffs(AVCodecContext *avctx, int16_t *dst, int size, 127 int width, ptrdiff_t stride) 128{ 129 PixletContext *ctx = avctx->priv_data; 130 GetBitContext *bc = &ctx->bc; 131 unsigned cnt1, nbits, k, j = 0, i = 0; 132 int64_t value, state = 3; 133 int rlen, escape, flag = 0; 134 135 while (i < size) { 136 nbits = FFMIN(ff_clz((state >> 8) + 3) ^ 0x1F, 14); 137 138 cnt1 = get_unary(bc, 0, 8); 139 if (cnt1 < 8) { 140 value = show_bits(bc, nbits); 141 if (value <= 1) { 142 skip_bits(bc, nbits - 1); 143 escape = ((1 << nbits) - 1) * cnt1; 144 } else { 145 skip_bits(bc, nbits); 146 escape = value + ((1 << nbits) - 1) * cnt1 - 1; 147 } 148 } else { 149 escape = get_bits(bc, 16); 150 } 151 152 value = -((escape + flag) & 1) | 1; 153 dst[j++] = value * ((escape + flag + 1) >> 1); 154 i++; 155 if (j == width) { 156 j = 0; 157 dst += stride; 158 } 159 state = 120 * (escape + flag) + state - (120 * state >> 8); 160 flag = 0; 161 162 if (state * 4ULL > 0xFF || i >= size) 163 continue; 164 165 nbits = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24; 166 escape = av_mod_uintp2(16383, nbits); 167 cnt1 = get_unary(bc, 0, 8); 168 if (cnt1 > 7) { 169 rlen = get_bits(bc, 16); 170 } else { 171 value = show_bits(bc, nbits); 172 if (value > 1) { 173 skip_bits(bc, nbits); 174 rlen = value + escape * cnt1 - 1; 175 } else { 176 skip_bits(bc, nbits - 1); 177 rlen = escape * cnt1; 178 } 179 } 180 181 if (rlen > size - i) 182 return AVERROR_INVALIDDATA; 183 i += rlen; 184 185 for (k = 0; k < rlen; k++) { 186 dst[j++] = 0; 187 if (j == width) { 188 j = 0; 189 dst += stride; 190 } 191 } 192 193 state = 0; 194 flag = rlen < 0xFFFF ? 1 : 0; 195 } 196 197 align_get_bits(bc); 198 return get_bits_count(bc) >> 3; 199} 200 201static int read_high_coeffs(AVCodecContext *avctx, const uint8_t *src, int16_t *dst, 202 int size, int c, int a, int d, 203 int width, ptrdiff_t stride) 204{ 205 PixletContext *ctx = avctx->priv_data; 206 GetBitContext *bc = &ctx->bc; 207 unsigned cnt1, shbits, rlen, nbits, length, i = 0, j = 0, k; 208 int ret, escape, pfx, value, yflag, xflag, flag = 0; 209 int64_t state = 3, tmp; 210 211 ret = init_get_bits8(bc, src, bytestream2_get_bytes_left(&ctx->gb)); 212 if (ret < 0) 213 return ret; 214 215 if (a ^ (a >> 31)) { 216 nbits = 33 - ff_clz(a ^ (a >> 31)); 217 if (nbits > 16) 218 return AVERROR_INVALIDDATA; 219 } else { 220 nbits = 1; 221 } 222 223 length = 25 - nbits; 224 225 while (i < size) { 226 if (((state >> 8) + 3) & 0xFFFFFFF) 227 value = ff_clz((state >> 8) + 3) ^ 0x1F; 228 else 229 value = -1; 230 231 cnt1 = get_unary(bc, 0, length); 232 if (cnt1 >= length) { 233 cnt1 = get_bits(bc, nbits); 234 } else { 235 pfx = 14 + ((((uint64_t)(value - 14)) >> 32) & (value - 14)); 236 if (pfx < 1 || pfx > 25) 237 return AVERROR_INVALIDDATA; 238 cnt1 *= (1 << pfx) - 1; 239 shbits = show_bits(bc, pfx); 240 if (shbits <= 1) { 241 skip_bits(bc, pfx - 1); 242 } else { 243 skip_bits(bc, pfx); 244 cnt1 += shbits - 1; 245 } 246 } 247 248 xflag = flag + cnt1; 249 yflag = xflag; 250 251 if (flag + cnt1 == 0) { 252 value = 0; 253 } else { 254 xflag &= 1u; 255 tmp = (int64_t)c * ((yflag + 1) >> 1) + (c >> 1); 256 value = xflag + (tmp ^ -xflag); 257 } 258 259 i++; 260 dst[j++] = value; 261 if (j == width) { 262 j = 0; 263 dst += stride; 264 } 265 state += (int64_t)d * (uint64_t)yflag - ((int64_t)(d * (uint64_t)state) >> 8); 266 267 flag = 0; 268 269 if ((uint64_t)state > 0xFF / 4 || i >= size) 270 continue; 271 272 pfx = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24; 273 escape = av_mod_uintp2(16383, pfx); 274 cnt1 = get_unary(bc, 0, 8); 275 if (cnt1 < 8) { 276 if (pfx < 1 || pfx > 25) 277 return AVERROR_INVALIDDATA; 278 279 value = show_bits(bc, pfx); 280 if (value > 1) { 281 skip_bits(bc, pfx); 282 rlen = value + escape * cnt1 - 1; 283 } else { 284 skip_bits(bc, pfx - 1); 285 rlen = escape * cnt1; 286 } 287 } else { 288 if (get_bits1(bc)) 289 value = get_bits(bc, 16); 290 else 291 value = get_bits(bc, 8); 292 293 rlen = value + 8 * escape; 294 } 295 296 if (rlen > 0xFFFF || i + rlen > size) 297 return AVERROR_INVALIDDATA; 298 i += rlen; 299 300 for (k = 0; k < rlen; k++) { 301 dst[j++] = 0; 302 if (j == width) { 303 j = 0; 304 dst += stride; 305 } 306 } 307 308 state = 0; 309 flag = rlen < 0xFFFF ? 1 : 0; 310 } 311 312 align_get_bits(bc); 313 return get_bits_count(bc) >> 3; 314} 315 316static int read_highpass(AVCodecContext *avctx, const uint8_t *ptr, 317 int plane, AVFrame *frame) 318{ 319 PixletContext *ctx = avctx->priv_data; 320 ptrdiff_t stride = frame->linesize[plane] / 2; 321 int i, ret; 322 323 for (i = 0; i < ctx->levels * 3; i++) { 324 int32_t a = bytestream2_get_be32(&ctx->gb); 325 int32_t b = bytestream2_get_be32(&ctx->gb); 326 int32_t c = bytestream2_get_be32(&ctx->gb); 327 int32_t d = bytestream2_get_be32(&ctx->gb); 328 int16_t *dest = (int16_t *)frame->data[plane] + 329 ctx->band[plane][i + 1].x + 330 ctx->band[plane][i + 1].y * stride; 331 unsigned size = ctx->band[plane][i + 1].size; 332 uint32_t magic = bytestream2_get_be32(&ctx->gb); 333 334 if (magic != PIXLET_MAGIC) { 335 av_log(avctx, AV_LOG_ERROR, 336 "wrong magic number: 0x%08"PRIX32" for plane %d, band %d\n", 337 magic, plane, i); 338 return AVERROR_INVALIDDATA; 339 } 340 341 if (a == INT32_MIN) 342 return AVERROR_INVALIDDATA; 343 344 ret = read_high_coeffs(avctx, ptr + bytestream2_tell(&ctx->gb), dest, size, 345 c, (b >= FFABS(a)) ? b : a, d, 346 ctx->band[plane][i + 1].width, stride); 347 if (ret < 0) { 348 av_log(avctx, AV_LOG_ERROR, 349 "error in highpass coefficients for plane %d, band %d\n", 350 plane, i); 351 return ret; 352 } 353 bytestream2_skip(&ctx->gb, ret); 354 } 355 356 return 0; 357} 358 359static void lowpass_prediction(int16_t *dst, int16_t *pred, 360 int width, int height, ptrdiff_t stride) 361{ 362 int16_t val; 363 int i, j; 364 365 memset(pred, 0, width * sizeof(*pred)); 366 367 for (i = 0; i < height; i++) { 368 val = pred[0] + dst[0]; 369 dst[0] = pred[0] = val; 370 for (j = 1; j < width; j++) { 371 val = pred[j] + dst[j]; 372 dst[j] = pred[j] = val; 373 dst[j] += dst[j-1]; 374 } 375 dst += stride; 376 } 377} 378 379static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale) 380{ 381 int16_t *low, *high, *ll, *lh, *hl, *hh; 382 int hsize, i, j; 383 int64_t value; 384 385 hsize = size >> 1; 386 low = tmp + 4; 387 high = &low[hsize + 8]; 388 389 memcpy(low, dest, size); 390 memcpy(high, dest + hsize, size); 391 392 ll = &low[hsize]; 393 lh = &low[hsize]; 394 hl = &high[hsize]; 395 hh = hl; 396 for (i = 4, j = 2; i; i--, j++, ll--, hh++, lh++, hl--) { 397 low[i - 5] = low[j - 1]; 398 lh[0] = ll[-1]; 399 high[i - 5] = high[j - 2]; 400 hh[0] = hl[-2]; 401 } 402 403 for (i = 0; i < hsize; i++) { 404 value = (int64_t) low [i + 1] * -INT64_C(325392907) + 405 (int64_t) low [i + 0] * INT64_C(3687786320) + 406 (int64_t) low [i - 1] * -INT64_C(325392907) + 407 (int64_t) high[i + 0] * INT64_C(1518500249) + 408 (int64_t) high[i - 1] * INT64_C(1518500249); 409 dest[i * 2] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); 410 } 411 412 for (i = 0; i < hsize; i++) { 413 value = (int64_t) low [i + 2] * -INT64_C(65078576) + 414 (int64_t) low [i + 1] * INT64_C(1583578880) + 415 (int64_t) low [i + 0] * INT64_C(1583578880) + 416 (int64_t) low [i - 1] * -INT64_C(65078576) + 417 (int64_t) high[i + 1] * INT64_C(303700064) + 418 (int64_t) high[i + 0] * -INT64_C(3644400640) + 419 (int64_t) high[i - 1] * INT64_C(303700064); 420 dest[i * 2 + 1] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); 421 } 422} 423 424static void reconstruction(AVCodecContext *avctx, int16_t *dest, 425 unsigned width, unsigned height, ptrdiff_t stride, 426 int64_t *scaling_h, int64_t *scaling_v) 427{ 428 PixletContext *ctx = avctx->priv_data; 429 unsigned scaled_width, scaled_height; 430 int16_t *ptr, *tmp; 431 int i, j, k; 432 433 scaled_width = width >> NB_LEVELS; 434 scaled_height = height >> NB_LEVELS; 435 tmp = ctx->filter[0]; 436 437 for (i = 0; i < NB_LEVELS; i++) { 438 int64_t scale_v = scaling_v[i]; 439 int64_t scale_h = scaling_h[i]; 440 scaled_width <<= 1; 441 scaled_height <<= 1; 442 443 ptr = dest; 444 for (j = 0; j < scaled_height; j++) { 445 filterfn(ptr, ctx->filter[1], scaled_width, scale_v); 446 ptr += stride; 447 } 448 449 for (j = 0; j < scaled_width; j++) { 450 ptr = dest + j; 451 for (k = 0; k < scaled_height; k++) { 452 tmp[k] = *ptr; 453 ptr += stride; 454 } 455 456 filterfn(tmp, ctx->filter[1], scaled_height, scale_h); 457 458 ptr = dest + j; 459 for (k = 0; k < scaled_height; k++) { 460 *ptr = tmp[k]; 461 ptr += stride; 462 } 463 } 464 } 465} 466 467static void build_luma_lut(AVCodecContext *avctx, int depth) 468{ 469 PixletContext *ctx = avctx->priv_data; 470 int max = (1 << depth) - 1; 471 472 if (ctx->depth == depth) 473 return; 474 ctx->depth = depth; 475 476 for (int i = 0; i < FF_ARRAY_ELEMS(ctx->lut); i++) 477 ctx->lut[i] = ((int64_t)i * i * 65535LL) / max / max; 478} 479 480static void postprocess_luma(AVCodecContext *avctx, AVFrame *frame, 481 int w, int h, int depth) 482{ 483 PixletContext *ctx = avctx->priv_data; 484 uint16_t *dsty = (uint16_t *)frame->data[0]; 485 int16_t *srcy = (int16_t *)frame->data[0]; 486 ptrdiff_t stridey = frame->linesize[0] / 2; 487 uint16_t *lut = ctx->lut; 488 int i, j; 489 490 for (j = 0; j < h; j++) { 491 for (i = 0; i < w; i++) { 492 if (srcy[i] <= 0) 493 dsty[i] = 0; 494 else if (srcy[i] > ((1 << depth) - 1)) 495 dsty[i] = 65535; 496 else 497 dsty[i] = lut[srcy[i]]; 498 } 499 dsty += stridey; 500 srcy += stridey; 501 } 502} 503 504static void postprocess_chroma(AVFrame *frame, int w, int h, int depth) 505{ 506 uint16_t *dstu = (uint16_t *)frame->data[1]; 507 uint16_t *dstv = (uint16_t *)frame->data[2]; 508 int16_t *srcu = (int16_t *)frame->data[1]; 509 int16_t *srcv = (int16_t *)frame->data[2]; 510 ptrdiff_t strideu = frame->linesize[1] / 2; 511 ptrdiff_t stridev = frame->linesize[2] / 2; 512 const unsigned add = 1 << (depth - 1); 513 const unsigned shift = 16 - depth; 514 int i, j; 515 516 for (j = 0; j < h; j++) { 517 for (i = 0; i < w; i++) { 518 dstu[i] = av_clip_uintp2_c(add + srcu[i], depth) << shift; 519 dstv[i] = av_clip_uintp2_c(add + srcv[i], depth) << shift; 520 } 521 dstu += strideu; 522 dstv += stridev; 523 srcu += strideu; 524 srcv += stridev; 525 } 526} 527 528static int decode_plane(AVCodecContext *avctx, int plane, 529 const AVPacket *avpkt, AVFrame *frame) 530{ 531 PixletContext *ctx = avctx->priv_data; 532 ptrdiff_t stride = frame->linesize[plane] / 2; 533 unsigned shift = plane > 0; 534 int16_t *dst; 535 int i, ret; 536 537 for (i = ctx->levels - 1; i >= 0; i--) { 538 int32_t h = sign_extend(bytestream2_get_be32(&ctx->gb), 32); 539 int32_t v = sign_extend(bytestream2_get_be32(&ctx->gb), 32); 540 541 if (!h || !v) 542 return AVERROR_INVALIDDATA; 543 544 ctx->scaling[plane][H][i] = (1000000ULL << 32) / h; 545 ctx->scaling[plane][V][i] = (1000000ULL << 32) / v; 546 } 547 548 bytestream2_skip(&ctx->gb, 4); 549 550 dst = (int16_t *)frame->data[plane]; 551 dst[0] = sign_extend(bytestream2_get_be16(&ctx->gb), 16); 552 553 ret = init_get_bits8(&ctx->bc, avpkt->data + bytestream2_tell(&ctx->gb), 554 bytestream2_get_bytes_left(&ctx->gb)); 555 if (ret < 0) 556 return ret; 557 558 ret = read_low_coeffs(avctx, dst + 1, ctx->band[plane][0].width - 1, 559 ctx->band[plane][0].width - 1, 0); 560 if (ret < 0) { 561 av_log(avctx, AV_LOG_ERROR, 562 "error in lowpass coefficients for plane %d, top row\n", plane); 563 return ret; 564 } 565 566 ret = read_low_coeffs(avctx, dst + stride, 567 ctx->band[plane][0].height - 1, 1, stride); 568 if (ret < 0) { 569 av_log(avctx, AV_LOG_ERROR, 570 "error in lowpass coefficients for plane %d, left column\n", 571 plane); 572 return ret; 573 } 574 575 ret = read_low_coeffs(avctx, dst + stride + 1, 576 (ctx->band[plane][0].width - 1) * (ctx->band[plane][0].height - 1), 577 ctx->band[plane][0].width - 1, stride); 578 if (ret < 0) { 579 av_log(avctx, AV_LOG_ERROR, 580 "error in lowpass coefficients for plane %d, rest\n", plane); 581 return ret; 582 } 583 584 bytestream2_skip(&ctx->gb, ret); 585 if (bytestream2_get_bytes_left(&ctx->gb) <= 0) { 586 av_log(avctx, AV_LOG_ERROR, "no bytes left\n"); 587 return AVERROR_INVALIDDATA; 588 } 589 590 ret = read_highpass(avctx, avpkt->data, plane, frame); 591 if (ret < 0) 592 return ret; 593 594 lowpass_prediction(dst, ctx->prediction, ctx->band[plane][0].width, 595 ctx->band[plane][0].height, stride); 596 597 reconstruction(avctx, (int16_t *)frame->data[plane], ctx->w >> shift, 598 ctx->h >> shift, stride, ctx->scaling[plane][H], 599 ctx->scaling[plane][V]); 600 601 return 0; 602} 603 604static int pixlet_decode_frame(AVCodecContext *avctx, AVFrame *p, 605 int *got_frame, AVPacket *avpkt) 606{ 607 PixletContext *ctx = avctx->priv_data; 608 int i, w, h, width, height, ret, version; 609 uint32_t pktsize, depth; 610 611 bytestream2_init(&ctx->gb, avpkt->data, avpkt->size); 612 613 pktsize = bytestream2_get_be32(&ctx->gb); 614 if (pktsize <= 44 + (NB_LEVELS * 8 + 6) * 3 || pktsize - 4 > bytestream2_get_bytes_left(&ctx->gb)) { 615 av_log(avctx, AV_LOG_ERROR, "Invalid packet size %"PRIu32"\n", pktsize); 616 return AVERROR_INVALIDDATA; 617 } 618 619 version = bytestream2_get_le32(&ctx->gb); 620 if (version != 1) 621 avpriv_request_sample(avctx, "Version %d", version); 622 623 bytestream2_skip(&ctx->gb, 4); 624 if (bytestream2_get_be32(&ctx->gb) != 1) 625 return AVERROR_INVALIDDATA; 626 bytestream2_skip(&ctx->gb, 4); 627 628 width = bytestream2_get_be32(&ctx->gb); 629 height = bytestream2_get_be32(&ctx->gb); 630 631 if ( width > INT_MAX - (1U << (NB_LEVELS + 1)) 632 || height > INT_MAX - (1U << (NB_LEVELS + 1))) 633 return AVERROR_INVALIDDATA; 634 635 w = FFALIGN(width, 1 << (NB_LEVELS + 1)); 636 h = FFALIGN(height, 1 << (NB_LEVELS + 1)); 637 638 ctx->levels = bytestream2_get_be32(&ctx->gb); 639 if (ctx->levels != NB_LEVELS) 640 return AVERROR_INVALIDDATA; 641 depth = bytestream2_get_be32(&ctx->gb); 642 if (depth < 8 || depth > 15) { 643 avpriv_request_sample(avctx, "Depth %d", depth); 644 return AVERROR_INVALIDDATA; 645 } 646 647 build_luma_lut(avctx, depth); 648 649 ret = ff_set_dimensions(avctx, w, h); 650 if (ret < 0) 651 return ret; 652 avctx->width = width; 653 avctx->height = height; 654 655 if (ctx->w != w || ctx->h != h) { 656 free_buffers(avctx); 657 ctx->w = w; 658 ctx->h = h; 659 660 ret = init_decoder(avctx); 661 if (ret < 0) { 662 free_buffers(avctx); 663 ctx->w = 0; 664 ctx->h = 0; 665 return ret; 666 } 667 } 668 669 bytestream2_skip(&ctx->gb, 8); 670 671 p->pict_type = AV_PICTURE_TYPE_I; 672 p->key_frame = 1; 673 p->color_range = AVCOL_RANGE_JPEG; 674 675 ret = ff_thread_get_buffer(avctx, p, 0); 676 if (ret < 0) 677 return ret; 678 679 for (i = 0; i < 3; i++) { 680 ret = decode_plane(avctx, i, avpkt, p); 681 if (ret < 0) 682 return ret; 683 if (avctx->flags & AV_CODEC_FLAG_GRAY) 684 break; 685 } 686 687 postprocess_luma(avctx, p, ctx->w, ctx->h, ctx->depth); 688 postprocess_chroma(p, ctx->w >> 1, ctx->h >> 1, ctx->depth); 689 690 *got_frame = 1; 691 692 return pktsize; 693} 694 695const FFCodec ff_pixlet_decoder = { 696 .p.name = "pixlet", 697 .p.long_name = NULL_IF_CONFIG_SMALL("Apple Pixlet"), 698 .p.type = AVMEDIA_TYPE_VIDEO, 699 .p.id = AV_CODEC_ID_PIXLET, 700 .init = pixlet_init, 701 .close = pixlet_close, 702 FF_CODEC_DECODE_CB(pixlet_decode_frame), 703 .priv_data_size = sizeof(PixletContext), 704 .p.capabilities = AV_CODEC_CAP_DR1 | 705 AV_CODEC_CAP_FRAME_THREADS, 706 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | 707 FF_CODEC_CAP_INIT_CLEANUP, 708}; 709