lagarith.c 22.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * Lagarith lossless decoder
 * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
23
 * @file
24 25 26 27
 * Lagarith lossless decoder
 * @author Nathan Caldwell
 */

28 29
#include <inttypes.h>

30 31 32 33
#include "avcodec.h"
#include "get_bits.h"
#include "mathops.h"
#include "lagarithrac.h"
34
#include "lossless_videodsp.h"
35
#include "thread.h"
36 37

enum LagarithFrameType {
38 39 40 41 42 43 44 45 46 47 48
    FRAME_RAW           = 1,    /**< uncompressed */
    FRAME_U_RGB24       = 2,    /**< unaligned RGB24 */
    FRAME_ARITH_YUY2    = 3,    /**< arithmetic coded YUY2 */
    FRAME_ARITH_RGB24   = 4,    /**< arithmetic coded RGB24 */
    FRAME_SOLID_GRAY    = 5,    /**< solid grayscale color frame */
    FRAME_SOLID_COLOR   = 6,    /**< solid non-grayscale color frame */
    FRAME_OLD_ARITH_RGB = 7,    /**< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
    FRAME_ARITH_RGBA    = 8,    /**< arithmetic coded RGBA */
    FRAME_SOLID_RGBA    = 9,    /**< solid RGBA color frame */
    FRAME_ARITH_YV12    = 10,   /**< arithmetic coded YV12 */
    FRAME_REDUCED_RES   = 11,   /**< reduced resolution YV12 frame */
49 50 51 52
};

typedef struct LagarithContext {
    AVCodecContext *avctx;
53
    LLVidDSPContext llviddsp;
54 55
    int zeros;                  /**< number of consecutive zero bytes encountered */
    int zeros_rem;              /**< number of zero bytes remaining to output */
56 57 58
} LagarithContext;

/**
59
 * Compute the 52-bit mantissa of 1/(double)denom.
60 61 62
 * This crazy format uses floats in an entropy coder and we have to match x86
 * rounding exactly, thus ordinary floats aren't portable enough.
 * @param denom denominator
63
 * @return 52-bit mantissa
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
 * @see softfloat_mul
 */
static uint64_t softfloat_reciprocal(uint32_t denom)
{
    int shift = av_log2(denom - 1) + 1;
    uint64_t ret = (1ULL << 52) / denom;
    uint64_t err = (1ULL << 52) - ret * denom;
    ret <<= shift;
    err <<= shift;
    err +=  denom / 2;
    return ret + err / denom;
}

/**
 * (uint32_t)(x*f), where f has the given mantissa, and exponent 0
 * Used in combination with softfloat_reciprocal computes x/(double)denom.
80
 * @param x 32-bit integer factor
81
 * @param mantissa mantissa of f with exponent 0
82
 * @return 32-bit integer value (x*f)
83 84 85 86 87 88 89 90
 * @see softfloat_reciprocal
 */
static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)
{
    uint64_t l = x * (mantissa & 0xffffffff);
    uint64_t h = x * (mantissa >> 32);
    h += l >> 32;
    l &= 0xffffffff;
91
    l += 1LL << av_log2(h >> 21);
92 93 94 95 96 97
    h += l >> 32;
    return h >> 20;
}

static uint8_t lag_calc_zero_run(int8_t x)
{
98
    return (x * 2) ^ (x >> 7);
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
}

static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
{
    static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 };
    int i;
    int bit     = 0;
    int bits    = 0;
    int prevbit = 0;
    unsigned val;

    for (i = 0; i < 7; i++) {
        if (prevbit && bit)
            break;
        prevbit = bit;
        bit = get_bits1(gb);
        if (bit && !prevbit)
            bits += series[i];
    }
    bits--;
    if (bits < 0 || bits > 31) {
        *value = 0;
        return -1;
    } else if (bits == 0) {
        *value = 0;
        return 0;
    }

    val  = get_bits_long(gb, bits);
128
    val |= 1U << bits;
129 130 131 132 133 134 135 136 137 138 139 140

    *value = val - 1;

    return 0;
}

static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
{
    int i, j, scale_factor;
    unsigned prob, cumulative_target;
    unsigned cumul_prob = 0;
    unsigned scaled_cumul_prob = 0;
141
    int nnz = 0;
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

    rac->prob[0] = 0;
    rac->prob[257] = UINT_MAX;
    /* Read probabilities from bitstream */
    for (i = 1; i < 257; i++) {
        if (lag_decode_prob(gb, &rac->prob[i]) < 0) {
            av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability encountered.\n");
            return -1;
        }
        if ((uint64_t)cumul_prob + rac->prob[i] > UINT_MAX) {
            av_log(rac->avctx, AV_LOG_ERROR, "Integer overflow encountered in cumulative probability calculation.\n");
            return -1;
        }
        cumul_prob += rac->prob[i];
        if (!rac->prob[i]) {
            if (lag_decode_prob(gb, &prob)) {
                av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability run encountered.\n");
                return -1;
            }
161 162
            if (prob > 256 - i)
                prob = 256 - i;
163 164
            for (j = 0; j < prob; j++)
                rac->prob[++i] = 0;
165 166
        }else {
            nnz++;
167 168 169 170 171 172 173 174
        }
    }

    if (!cumul_prob) {
        av_log(rac->avctx, AV_LOG_ERROR, "All probabilities are 0!\n");
        return -1;
    }

175 176 177 178
    if (nnz == 1 && (show_bits_long(gb, 32) & 0xFFFFFF)) {
        return AVERROR_INVALIDDATA;
    }

179 180 181 182 183
    /* Scale probabilities so cumulative probability is an even power of 2. */
    scale_factor = av_log2(cumul_prob);

    if (cumul_prob & (cumul_prob - 1)) {
        uint64_t mul = softfloat_reciprocal(cumul_prob);
184 185 186 187 188 189 190 191 192
        for (i = 1; i <= 128; i++) {
            rac->prob[i] = softfloat_mul(rac->prob[i], mul);
            scaled_cumul_prob += rac->prob[i];
        }
        if (scaled_cumul_prob <= 0) {
            av_log(rac->avctx, AV_LOG_ERROR, "Scaled probabilities invalid\n");
            return AVERROR_INVALIDDATA;
        }
        for (; i < 257; i++) {
193 194 195 196 197
            rac->prob[i] = softfloat_mul(rac->prob[i], mul);
            scaled_cumul_prob += rac->prob[i];
        }

        scale_factor++;
198 199 200
        if (scale_factor >= 32U)
            return AVERROR_INVALIDDATA;
        cumulative_target = 1U << scale_factor;
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

        if (scaled_cumul_prob > cumulative_target) {
            av_log(rac->avctx, AV_LOG_ERROR,
                   "Scaled probabilities are larger than target!\n");
            return -1;
        }

        scaled_cumul_prob = cumulative_target - scaled_cumul_prob;

        for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
            if (rac->prob[i]) {
                rac->prob[i]++;
                scaled_cumul_prob--;
            }
            /* Comment from reference source:
             * if (b & 0x80 == 0) {     // order of operations is 'wrong'; it has been left this way
Diego Biurrun's avatar
Diego Biurrun committed
217
             *                          // since the compression change is negligible and fixing it
218
             *                          // breaks backwards compatibility
219 220 221 222 223 224 225 226 227 228
             *      b =- (signed int)b;
             *      b &= 0xFF;
             * } else {
             *      b++;
             *      b &= 0x7f;
             * }
             */
        }
    }

229 230 231
    if (scale_factor > 23)
        return AVERROR_INVALIDDATA;

232 233 234 235 236 237 238 239 240 241 242 243 244
    rac->scale = scale_factor;

    /* Fill probability array with cumulative probability for each symbol. */
    for (i = 1; i < 257; i++)
        rac->prob[i] += rac->prob[i - 1];

    return 0;
}

static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1,
                                      uint8_t *diff, int w, int *left,
                                      int *left_top)
{
245
    /* This is almost identical to add_hfyu_median_pred in huffyuvdsp.h.
246
     * However the &0xFF on the gradient predictor yields incorrect output
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
     * for lagarith.
     */
    int i;
    uint8_t l, lt;

    l  = *left;
    lt = *left_top;

    for (i = 0; i < w; i++) {
        l = mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
        lt = src1[i];
        dst[i] = l;
    }

    *left     = l;
    *left_top = lt;
}

static void lag_pred_line(LagarithContext *l, uint8_t *buf,
                          int width, int stride, int line)
{
    int L, TL;

    if (!line) {
        /* Left prediction only for first line */
272
        L = l->llviddsp.add_left_pred(buf, buf, width, 0);
273
    } else {
274 275 276 277 278 279
        /* Left pixel is actually prev_row[width] */
        L = buf[width - stride - 1];

        if (line == 1) {
            /* Second line, left predict first pixel, the rest of the line is median predicted
             * NOTE: In the case of RGB this pixel is top predicted */
280
            TL = l->avctx->pix_fmt == AV_PIX_FMT_YUV420P ? buf[-stride] : L;
281 282 283 284
        } else {
            /* Top left is 2 rows back, last pixel */
            TL = buf[width - (2 * stride) - 1];
        }
285

286 287 288
        add_lag_median_prediction(buf, buf - stride, buf,
                                  width, &L, &TL);
    }
289 290
}

291 292 293 294 295 296 297
static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
                               int width, int stride, int line,
                               int is_luma)
{
    int L, TL;

    if (!line) {
298 299 300
        L= buf[0];
        if (is_luma)
            buf[0] = 0;
301
        l->llviddsp.add_left_pred(buf, buf, width, 0);
302 303
        if (is_luma)
            buf[0] = L;
304 305 306 307 308 309 310 311 312 313 314 315
        return;
    }
    if (line == 1) {
        const int HEAD = is_luma ? 4 : 2;
        int i;

        L  = buf[width - stride - 1];
        TL = buf[HEAD  - stride - 1];
        for (i = 0; i < HEAD; i++) {
            L += buf[i];
            buf[i] = L;
        }
316 317 318 319
        for (; i < width; i++) {
            L      = mid_pred(L & 0xFF, buf[i - stride], (L + buf[i - stride] - TL) & 0xFF) + buf[i];
            TL     = buf[i - stride];
            buf[i] = L;
320
        }
321 322 323
    } else {
        TL = buf[width - (2 * stride) - 1];
        L  = buf[width - stride - 1];
324
        l->llviddsp.add_median_pred(buf, buf - stride, buf, width, &L, &TL);
325 326 327
    }
}

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
static int lag_decode_line(LagarithContext *l, lag_rac *rac,
                           uint8_t *dst, int width, int stride,
                           int esc_count)
{
    int i = 0;
    int ret = 0;

    if (!esc_count)
        esc_count = -1;

    /* Output any zeros remaining from the previous run */
handle_zeros:
    if (l->zeros_rem) {
        int count = FFMIN(l->zeros_rem, width - i);
        memset(dst + i, 0, count);
        i += count;
        l->zeros_rem -= count;
    }

    while (i < width) {
        dst[i] = lag_get_rac(rac);
        ret++;

        if (dst[i])
            l->zeros = 0;
        else
            l->zeros++;

        i++;
        if (l->zeros == esc_count) {
            int index = lag_get_rac(rac);
            ret++;

            l->zeros = 0;

            l->zeros_rem = lag_calc_zero_run(index);
            goto handle_zeros;
        }
    }
    return ret;
}

static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
371 372
                                    const uint8_t *src, const uint8_t *src_end,
                                    int width, int esc_count)
373 374 375 376
{
    int i = 0;
    int count;
    uint8_t zero_run = 0;
377
    const uint8_t *src_start = src;
378 379 380 381
    uint8_t mask1 = -(esc_count < 2);
    uint8_t mask2 = -(esc_count < 3);
    uint8_t *end = dst + (width - 2);

382
    avpriv_request_sample(l->avctx, "zero_run_line");
383 384

    memset(dst, 0, width);
385

386 387 388
output_zeros:
    if (l->zeros_rem) {
        count = FFMIN(l->zeros_rem, width - i);
389 390
        if (end - dst < count) {
            av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
391 392
            return AVERROR_INVALIDDATA;
        }
393

394 395 396 397 398 399 400 401 402
        memset(dst, 0, count);
        l->zeros_rem -= count;
        dst += count;
    }

    while (dst < end) {
        i = 0;
        while (!zero_run && dst + i < end) {
            i++;
403
            if (i+2 >= src_end - src)
404
                return AVERROR_INVALIDDATA;
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
            zero_run =
                !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
        }
        if (zero_run) {
            zero_run = 0;
            i += esc_count;
            memcpy(dst, src, i);
            dst += i;
            l->zeros_rem = lag_calc_zero_run(src[i]);

            src += i + 1;
            goto output_zeros;
        } else {
            memcpy(dst, src, i);
            src += i;
420
            dst += i;
421 422
        }
    }
423
    return  src - src_start;
424 425 426 427 428 429 430 431 432 433 434 435
}



static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
                                  int width, int height, int stride,
                                  const uint8_t *src, int src_size)
{
    int i = 0;
    int read = 0;
    uint32_t length;
    uint32_t offset = 1;
436
    int esc_count;
437 438
    GetBitContext gb;
    lag_rac rac;
439
    const uint8_t *src_end = src + src_size;
440
    int ret;
441 442 443 444

    rac.avctx = l->avctx;
    l->zeros = 0;

445 446 447 448
    if(src_size < 2)
        return AVERROR_INVALIDDATA;

    esc_count = src[0];
449 450
    if (esc_count < 4) {
        length = width * height;
451 452
        if(src_size < 5)
            return AVERROR_INVALIDDATA;
453 454 455 456 457
        if (esc_count && AV_RL32(src + 1) < length) {
            length = AV_RL32(src + 1);
            offset += 4;
        }

458 459
        if ((ret = init_get_bits8(&gb, src + offset, src_size - offset)) < 0)
            return ret;
460 461 462 463

        if (lag_read_prob_header(&rac, &gb) < 0)
            return -1;

464
        ff_lag_rac_init(&rac, &gb, length - stride);
465 466 467
        for (i = 0; i < height; i++) {
            if (rac.overread > MAX_OVERREAD)
                return AVERROR_INVALIDDATA;
468 469
            read += lag_decode_line(l, &rac, dst + (i * stride), width,
                                    stride, esc_count);
470
        }
471 472 473

        if (read > length)
            av_log(l->avctx, AV_LOG_WARNING,
474
                   "Output more bytes than length (%d of %"PRIu32")\n", read,
475 476 477
                   length);
    } else if (esc_count < 8) {
        esc_count -= 4;
478 479
        src ++;
        src_size --;
480 481
        if (esc_count > 0) {
            /* Zero run coding only, no range coding. */
482 483 484 485 486 487 488
            for (i = 0; i < height; i++) {
                int res = lag_decode_zero_run_line(l, dst + (i * stride), src,
                                                   src_end, width, esc_count);
                if (res < 0)
                    return res;
                src += res;
            }
489
        } else {
490 491
            if (src_size < width * height)
                return AVERROR_INVALIDDATA; // buffer not big enough
492 493 494 495 496 497 498
            /* Plane is stored uncompressed */
            for (i = 0; i < height; i++) {
                memcpy(dst + (i * stride), src, width);
                src += width;
            }
        }
    } else if (esc_count == 0xff) {
499
        /* Plane is a solid run of given value */
500
        for (i = 0; i < height; i++)
501 502 503 504 505
            memset(dst + i * stride, src[1], width);
        /* Do not apply prediction.
           Note: memset to 0 above, setting first value to src[1]
           and applying prediction gives the same result. */
        return 0;
506 507 508 509 510 511
    } else {
        av_log(l->avctx, AV_LOG_ERROR,
               "Invalid zero run escape code! (%#x)\n", esc_count);
        return -1;
    }

512
    if (l->avctx->pix_fmt != AV_PIX_FMT_YUV422P) {
513 514 515 516 517 518 519 520 521 522
        for (i = 0; i < height; i++) {
            lag_pred_line(l, dst, width, stride, i);
            dst += stride;
        }
    } else {
        for (i = 0; i < height; i++) {
            lag_pred_line_yuy2(l, dst, width, stride, i,
                               width == l->avctx->width);
            dst += stride;
        }
523 524 525 526 527 528 529 530 531 532 533 534 535 536
    }

    return 0;
}

/**
 * Decode a frame.
 * @param avctx codec context
 * @param data output AVFrame
 * @param data_size size of output data or 0 if no picture is returned
 * @param avpkt input packet
 * @return number of consumed bytes on success or negative if decode fails
 */
static int lag_decode_frame(AVCodecContext *avctx,
537
                            void *data, int *got_frame, AVPacket *avpkt)
538 539
{
    const uint8_t *buf = avpkt->data;
540
    unsigned int buf_size = avpkt->size;
541
    LagarithContext *l = avctx->priv_data;
542 543
    ThreadFrame frame = { .f = data };
    AVFrame *const p  = data;
544
    uint8_t frametype;
545
    uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
546
    uint32_t offs[4];
547
    uint8_t *srcs[4];
Paul B Mahol's avatar
Paul B Mahol committed
548
    int i, j, planes = 3;
549
    int ret;
550 551

    p->key_frame = 1;
552
    p->pict_type = AV_PICTURE_TYPE_I;
553 554 555 556 557 558 559

    frametype = buf[0];

    offset_gu = AV_RL32(buf + 1);
    offset_bv = AV_RL32(buf + 5);

    switch (frametype) {
560
    case FRAME_SOLID_RGBA:
561
        avctx->pix_fmt = AV_PIX_FMT_GBRAP;
562 563 564
    case FRAME_SOLID_GRAY:
        if (frametype == FRAME_SOLID_GRAY)
            if (avctx->bits_per_coded_sample == 24) {
565
                avctx->pix_fmt = AV_PIX_FMT_GBRP;
566
            } else {
567
                avctx->pix_fmt = AV_PIX_FMT_GBRAP;
568 569
                planes = 4;
            }
570

571
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
572
            return ret;
573

574
        if (frametype == FRAME_SOLID_RGBA) {
575 576 577 578 579
            for (i = 0; i < avctx->height; i++) {
                memset(p->data[0] + i * p->linesize[0], buf[2], avctx->width);
                memset(p->data[1] + i * p->linesize[1], buf[1], avctx->width);
                memset(p->data[2] + i * p->linesize[2], buf[3], avctx->width);
                memset(p->data[3] + i * p->linesize[3], buf[4], avctx->width);
580
            }
581
        } else {
582 583 584
            for (i = 0; i < avctx->height; i++) {
                for (j = 0; j < planes; j++)
                    memset(p->data[j] + i * p->linesize[j], buf[1], avctx->width);
585 586
            }
        }
587
        break;
588 589
    case FRAME_SOLID_COLOR:
        if (avctx->bits_per_coded_sample == 24) {
590
            avctx->pix_fmt = AV_PIX_FMT_GBRP;
591
        } else {
592
            avctx->pix_fmt = AV_PIX_FMT_GBRAP;
593 594 595 596 597
        }

        if ((ret = ff_thread_get_buffer(avctx, &frame,0)) < 0)
            return ret;

598 599 600 601 602 603
        for (i = 0; i < avctx->height; i++) {
            memset(p->data[0] + i * p->linesize[0], buf[2], avctx->width);
            memset(p->data[1] + i * p->linesize[1], buf[1], avctx->width);
            memset(p->data[2] + i * p->linesize[2], buf[3], avctx->width);
            if (avctx->pix_fmt == AV_PIX_FMT_GBRAP)
                memset(p->data[3] + i * p->linesize[3], 0xFFu, avctx->width);
604 605
        }
        break;
606
    case FRAME_ARITH_RGBA:
607
        avctx->pix_fmt = AV_PIX_FMT_GBRAP;
Paul B Mahol's avatar
Paul B Mahol committed
608 609 610 611
        planes = 4;
        offset_ry += 4;
        offs[3] = AV_RL32(buf + 9);
    case FRAME_ARITH_RGB24:
612 613
    case FRAME_U_RGB24:
        if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
614
            avctx->pix_fmt = AV_PIX_FMT_GBRP;
615

616
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
617
            return ret;
Paul B Mahol's avatar
Paul B Mahol committed
618

619 620
        offs[0] = offset_bv;
        offs[1] = offset_gu;
Paul B Mahol's avatar
Paul B Mahol committed
621
        offs[2] = offset_ry;
622

Paul B Mahol's avatar
Paul B Mahol committed
623
        for (i = 0; i < planes; i++)
624
            srcs[i] = p->data[i] + (avctx->height - 1) * p->linesize[i];
625
        for (i = 0; i < planes; i++)
626
            if (buf_size <= offs[i]) {
627 628
                av_log(avctx, AV_LOG_ERROR,
                        "Invalid frame offsets\n");
629 630
                return AVERROR_INVALIDDATA;
            }
631

632
        for (i = 0; i < planes; i++)
633 634
            lag_decode_arith_plane(l, srcs[i],
                                   avctx->width, avctx->height,
635
                                   -p->linesize[i], buf + offs[i],
636
                                   buf_size - offs[i]);
637 638 639
        for (i = 0; i < avctx->height; i++) {
            l->llviddsp.add_bytes(p->data[0] + i * p->linesize[0], p->data[1] + i * p->linesize[1], avctx->width);
            l->llviddsp.add_bytes(p->data[2] + i * p->linesize[2], p->data[1] + i * p->linesize[1], avctx->width);
640
        }
641 642 643 644
        FFSWAP(uint8_t*, p->data[0], p->data[1]);
        FFSWAP(int, p->linesize[0], p->linesize[1]);
        FFSWAP(uint8_t*, p->data[2], p->data[1]);
        FFSWAP(int, p->linesize[2], p->linesize[1]);
645
        break;
646
    case FRAME_ARITH_YUY2:
647
        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
648

649
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
650
            return ret;
651 652 653 654 655 656 657 658 659 660 661 662

        if (offset_ry >= buf_size ||
            offset_gu >= buf_size ||
            offset_bv >= buf_size) {
            av_log(avctx, AV_LOG_ERROR,
                   "Invalid frame offsets\n");
            return AVERROR_INVALIDDATA;
        }

        lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
                               p->linesize[0], buf + offset_ry,
                               buf_size - offset_ry);
663
        lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
664
                               avctx->height, p->linesize[1],
665
                               buf + offset_gu, buf_size - offset_gu);
666
        lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
667
                               avctx->height, p->linesize[2],
668 669
                               buf + offset_bv, buf_size - offset_bv);
        break;
670
    case FRAME_ARITH_YV12:
671
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
672

673
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
674
            return ret;
675

676 677 678 679 680 681 682 683
        if (offset_ry >= buf_size ||
            offset_gu >= buf_size ||
            offset_bv >= buf_size) {
            av_log(avctx, AV_LOG_ERROR,
                   "Invalid frame offsets\n");
            return AVERROR_INVALIDDATA;
        }

684 685
        lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
                               p->linesize[0], buf + offset_ry,
686
                               buf_size - offset_ry);
687 688
        lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
                               (avctx->height + 1) / 2, p->linesize[2],
689
                               buf + offset_gu, buf_size - offset_gu);
690 691
        lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
                               (avctx->height + 1) / 2, p->linesize[1],
692
                               buf + offset_bv, buf_size - offset_bv);
693 694 695
        break;
    default:
        av_log(avctx, AV_LOG_ERROR,
696
               "Unsupported Lagarith frame type: %#"PRIx8"\n", frametype);
697
        return AVERROR_PATCHWELCOME;
698 699
    }

700
    *got_frame = 1;
701 702 703 704 705 706 707 708 709

    return buf_size;
}

static av_cold int lag_decode_init(AVCodecContext *avctx)
{
    LagarithContext *l = avctx->priv_data;
    l->avctx = avctx;

710
    ff_llviddsp_init(&l->llviddsp);
711 712 713 714

    return 0;
}

715
AVCodec ff_lagarith_decoder = {
716
    .name           = "lagarith",
717
    .long_name      = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
718
    .type           = AVMEDIA_TYPE_VIDEO,
719
    .id             = AV_CODEC_ID_LAGARITH,
720 721 722
    .priv_data_size = sizeof(LagarithContext),
    .init           = lag_decode_init,
    .decode         = lag_decode_frame,
723
    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
724
};