huffyuv.c 52.4 KB
Newer Older
Michael Niedermayer's avatar
Michael Niedermayer committed
1 2 3
/*
 * huffyuv codec for libavcodec
 *
Michael Niedermayer's avatar
Michael Niedermayer committed
4
 * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
Michael Niedermayer's avatar
Michael Niedermayer committed
5
 *
6 7 8
 * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
 * the algorithm used
 *
9 10 11
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
Michael Niedermayer's avatar
Michael Niedermayer committed
12 13
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
14
 * version 2.1 of the License, or (at your option) any later version.
Michael Niedermayer's avatar
Michael Niedermayer committed
15
 *
16
 * FFmpeg is distributed in the hope that it will be useful,
Michael Niedermayer's avatar
Michael Niedermayer committed
17 18 19 20 21
 * 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
22
 * License along with FFmpeg; if not, write to the Free Software
23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Michael Niedermayer's avatar
Michael Niedermayer committed
24
 */
25

Michael Niedermayer's avatar
Michael Niedermayer committed
26
/**
27
 * @file
Michael Niedermayer's avatar
Michael Niedermayer committed
28 29
 * huffyuv codec for libavcodec.
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
30 31

#include "avcodec.h"
32
#include "internal.h"
33
#include "get_bits.h"
34
#include "put_bits.h"
Michael Niedermayer's avatar
Michael Niedermayer committed
35
#include "dsputil.h"
36
#include "thread.h"
37
#include "huffman.h"
Michael Niedermayer's avatar
Michael Niedermayer committed
38 39

#define VLC_BITS 11
Michael Niedermayer's avatar
Michael Niedermayer committed
40

41
#if HAVE_BIGENDIAN
42 43 44
#define B 3
#define G 2
#define R 1
45
#define A 0
46 47 48 49
#else
#define B 0
#define G 1
#define R 2
50
#define A 3
51 52
#endif

53
typedef enum Predictor {
Michael Niedermayer's avatar
Michael Niedermayer committed
54 55 56 57
    LEFT= 0,
    PLANE,
    MEDIAN,
} Predictor;
58

59
typedef struct HYuvContext {
Michael Niedermayer's avatar
Michael Niedermayer committed
60 61 62 63 64 65 66 67 68 69 70 71
    AVCodecContext *avctx;
    Predictor predictor;
    GetBitContext gb;
    PutBitContext pb;
    int interlaced;
    int decorrelate;
    int bitstream_bpp;
    int version;
    int yuy2;                               //use yuy2 instead of 422P
    int bgr32;                              //use bgr32 instead of bgr24
    int width, height;
    int flags;
72
    int context;
Michael Niedermayer's avatar
Michael Niedermayer committed
73
    int picture_number;
74
    int last_slice_end;
75
    uint8_t *temp[3];
Michael Niedermayer's avatar
Michael Niedermayer committed
76 77 78
    uint64_t stats[3][256];
    uint8_t len[3][256];
    uint32_t bits[3][256];
79
    uint32_t pix_bgr_map[1<<VLC_BITS];
80
    VLC vlc[6];                             //Y,U,V,YY,YU,YV
81
    AVFrame picture;
82
    uint8_t *bitstream_buffer;
83
    unsigned int bitstream_buffer_size;
84
    DSPContext dsp;
85
} HYuvContext;
Michael Niedermayer's avatar
Michael Niedermayer committed
86

87 88
#define classic_shift_luma_table_size 42
static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
89 90
  34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
  16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
91 92
  69,68, 0,
  0,0,0,0,0,0,0,0,
93 94
};

95 96
#define classic_shift_chroma_table_size 59
static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
97 98
  66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
  56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
99 100
  214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0,
  0,0,0,0,0,0,0,0,
101 102
};

Zdenek Kabelac's avatar
Zdenek Kabelac committed
103
static const unsigned char classic_add_luma[256] = {
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
    3,  9,  5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
   73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
   68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
   35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
   37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
   35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
   27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
   15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
   12, 17, 19, 13,  4,  9,  2, 11,  1,  7,  8,  0, 16,  3, 14,  6,
   12, 10,  5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
   18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
   28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
   28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
   62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
   54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
   46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13,  7,  8,
};

Zdenek Kabelac's avatar
Zdenek Kabelac committed
122
static const unsigned char classic_add_chroma[256] = {
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    3,  1,  2,  2,  2,  2,  3,  3,  7,  5,  7,  5,  8,  6, 11,  9,
    7, 13, 11, 10,  9,  8,  7,  5,  9,  7,  6,  4,  7,  5,  8,  7,
   11,  8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
   43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
  143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
   17, 14,  5,  6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
  112,113,114,115,  4,117,118, 92, 94,121,122,  3,124,103,  2,  1,
    0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
  135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
   52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
   19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10,  9,  8, 36,
    7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
   83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
   14, 16, 17, 18, 20, 21, 12, 14, 15,  9, 10,  6,  9,  6,  5,  8,
    6, 12,  8, 10,  7,  9,  6,  4,  6,  2,  2,  3,  3,  3,  3,  2,
};

141
static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
142
                                      const uint8_t *src, int w, int left)
143
{
Michael Niedermayer's avatar
Michael Niedermayer committed
144
    int i;
145 146 147 148 149
    if (w < 32) {
        for (i = 0; i < w; i++) {
            const int temp = src[i];
            dst[i] = temp - left;
            left   = temp;
150 151
        }
        return left;
152 153 154 155 156
    } else {
        for (i = 0; i < 16; i++) {
            const int temp = src[i];
            dst[i] = temp - left;
            left   = temp;
157
        }
158
        s->dsp.diff_bytes(dst + 16, src + 16, src + 15, w - 16);
159
        return src[w-1];
Michael Niedermayer's avatar
Michael Niedermayer committed
160 161
    }
}
162

163
static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst,
164 165
                                             const uint8_t *src, int w,
                                             int *red, int *green, int *blue, int *alpha)
166
{
Loren Merritt's avatar
Loren Merritt committed
167
    int i;
168
    int r,g,b,a;
169 170 171
    r = *red;
    g = *green;
    b = *blue;
172
    a = *alpha;
173 174 175 176
    for (i = 0; i < FFMIN(w, 4); i++) {
        const int rt = src[i * 4 + R];
        const int gt = src[i * 4 + G];
        const int bt = src[i * 4 + B];
177
        const int at = src[i * 4 + A];
178 179 180
        dst[i * 4 + R] = rt - r;
        dst[i * 4 + G] = gt - g;
        dst[i * 4 + B] = bt - b;
181
        dst[i * 4 + A] = at - a;
Loren Merritt's avatar
Loren Merritt committed
182 183 184
        r = rt;
        g = gt;
        b = bt;
185
        a = at;
Loren Merritt's avatar
Loren Merritt committed
186
    }
187 188 189 190 191 192

    s->dsp.diff_bytes(dst + 16, src + 16, src + 12, w * 4 - 16);

    *red   = src[(w - 1) * 4 + R];
    *green = src[(w - 1) * 4 + G];
    *blue  = src[(w - 1) * 4 + B];
193
    *alpha = src[(w - 1) * 4 + A];
Loren Merritt's avatar
Loren Merritt committed
194 195
}

196
static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue){
197 198
    int i;
    int r,g,b;
199 200 201 202 203 204 205 206 207 208
    r = *red;
    g = *green;
    b = *blue;
    for (i = 0; i < FFMIN(w,16); i++) {
        const int rt = src[i*3 + 0];
        const int gt = src[i*3 + 1];
        const int bt = src[i*3 + 2];
        dst[i*3 + 0] = rt - r;
        dst[i*3 + 1] = gt - g;
        dst[i*3 + 2] = bt - b;
209 210 211 212
        r = rt;
        g = gt;
        b = bt;
    }
213 214 215 216 217 218

    s->dsp.diff_bytes(dst + 48, src + 48, src + 48 - 3, w*3 - 48);

    *red   = src[(w - 1)*3 + 0];
    *green = src[(w - 1)*3 + 1];
    *blue  = src[(w - 1)*3 + 2];
219 220
}

221 222
static int read_len_table(uint8_t *dst, GetBitContext *gb)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
223
    int i, val, repeat;
224

225 226 227 228 229 230
    for (i = 0; i < 256;) {
        repeat = get_bits(gb, 3);
        val    = get_bits(gb, 5);
        if (repeat == 0)
            repeat = get_bits(gb, 8);
        if (i + repeat > 256 || get_bits_left(gb) < 0) {
231 232 233
            av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
            return -1;
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
234 235 236
        while (repeat--)
            dst[i++] = val;
    }
237
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
238 239
}

240 241
static int generate_bits_table(uint32_t *dst, const uint8_t *len_table)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
242
    int len, index;
243
    uint32_t bits = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
244

245 246 247 248
    for (len = 32; len > 0; len--) {
        for (index = 0; index < 256; index++) {
            if (len_table[index] == len)
                dst[index] = bits++;
Michael Niedermayer's avatar
Michael Niedermayer committed
249
        }
250
        if (bits & 1) {
251
            av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
252 253 254
            return -1;
        }
        bits >>= 1;
Michael Niedermayer's avatar
Michael Niedermayer committed
255 256 257 258
    }
    return 0;
}

259 260 261 262 263 264
static void generate_joint_tables(HYuvContext *s)
{
    uint16_t symbols[1 << VLC_BITS];
    uint16_t bits[1 << VLC_BITS];
    uint8_t len[1 << VLC_BITS];
    if (s->bitstream_bpp < 24) {
265
        int p, i, y, u;
266 267
        for (p = 0; p < 3; p++) {
            for (i = y = 0; y < 256; y++) {
268 269
                int len0 = s->len[0][y];
                int limit = VLC_BITS - len0;
270 271
                if(limit <= 0)
                    continue;
272
                for (u = 0; u < 256; u++) {
273
                    int len1 = s->len[p][u];
274
                    if (len1 > limit)
275 276 277
                        continue;
                    len[i] = len0 + len1;
                    bits[i] = (s->bits[0][y] << len1) + s->bits[p][u];
278
                    symbols[i] = (y << 8) + u;
279 280
                    if(symbols[i] != 0xffff) // reserved to mean "invalid"
                        i++;
281 282
                }
            }
283 284 285
            ff_free_vlc(&s->vlc[3 + p]);
            ff_init_vlc_sparse(&s->vlc[3 + p], VLC_BITS, i, len, 1, 1,
                               bits, 2, 2, symbols, 2, 2, 0);
286
        }
287
    } else {
288 289 290 291
        uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map;
        int i, b, g, r, code;
        int p0 = s->decorrelate;
        int p1 = !s->decorrelate;
292
        // restrict the range to +/-16 because that's pretty much guaranteed to
293 294
        // cover all the combinations that fit in 11 bits total, and it doesn't
        // matter if we miss a few rare codes.
295 296
        for (i = 0, g = -16; g < 16; g++) {
            int len0 = s->len[p0][g & 255];
297
            int limit0 = VLC_BITS - len0;
298
            if (limit0 < 2)
299
                continue;
300 301
            for (b = -16; b < 16; b++) {
                int len1 = s->len[p1][b & 255];
302
                int limit1 = limit0 - len1;
303
                if (limit1 < 1)
304
                    continue;
305 306 307 308
                code = (s->bits[p0][g & 255] << len1) + s->bits[p1][b & 255];
                for (r = -16; r < 16; r++) {
                    int len2 = s->len[2][r & 255];
                    if (len2 > limit1)
309 310
                        continue;
                    len[i] = len0 + len1 + len2;
311 312
                    bits[i] = (code << len2) + s->bits[2][r & 255];
                    if (s->decorrelate) {
313
                        map[i][G] = g;
314 315 316
                        map[i][B] = g + b;
                        map[i][R] = g + r;
                    } else {
317 318 319 320 321 322 323 324
                        map[i][B] = g;
                        map[i][G] = b;
                        map[i][R] = r;
                    }
                    i++;
                }
            }
        }
325
        ff_free_vlc(&s->vlc[3]);
326
        init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0);
327 328 329
    }
}

330 331
static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
332 333
    GetBitContext gb;
    int i;
334

335
    init_get_bits(&gb, src, length * 8);
336

337 338
    for (i = 0; i < 3; i++) {
        if (read_len_table(s->len[i], &gb) < 0)
339
            return -1;
340
        if (generate_bits_table(s->bits[i], s->len[i]) < 0) {
Michael Niedermayer's avatar
Michael Niedermayer committed
341 342
            return -1;
        }
343
        ff_free_vlc(&s->vlc[i]);
344 345
        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1,
                 s->bits[i], 4, 4, 0);
Michael Niedermayer's avatar
Michael Niedermayer committed
346
    }
347

348 349
    generate_joint_tables(s);

350
    return (get_bits_count(&gb) + 7) / 8;
Michael Niedermayer's avatar
Michael Niedermayer committed
351 352
}

353 354
static int read_old_huffman_tables(HYuvContext *s)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
355 356 357
    GetBitContext gb;
    int i;

358 359 360
    init_get_bits(&gb, classic_shift_luma,
                  classic_shift_luma_table_size * 8);
    if (read_len_table(s->len[0], &gb) < 0)
361
        return -1;
362 363 364 365

    init_get_bits(&gb, classic_shift_chroma,
                  classic_shift_chroma_table_size * 8);
    if (read_len_table(s->len[1], &gb) < 0)
366
        return -1;
367

Michael Niedermayer's avatar
Michael Niedermayer committed
368 369 370
    for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma  [i];
    for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];

371 372 373
    if (s->bitstream_bpp >= 24) {
        memcpy(s->bits[1], s->bits[0], 256 * sizeof(uint32_t));
        memcpy(s->len[1] , s->len [0], 256 * sizeof(uint8_t));
Michael Niedermayer's avatar
Michael Niedermayer committed
374
    }
375 376
    memcpy(s->bits[2], s->bits[1], 256 * sizeof(uint32_t));
    memcpy(s->len[2] , s->len [1], 256 * sizeof(uint8_t));
377

378
    for (i = 0; i < 3; i++) {
379
        ff_free_vlc(&s->vlc[i]);
380 381
        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1,
                 s->bits[i], 4, 4, 0);
382
    }
383

384 385
    generate_joint_tables(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
386 387 388
    return 0;
}

389 390
static av_cold void alloc_temp(HYuvContext *s)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
391
    int i;
392

393 394
    if (s->bitstream_bpp<24) {
        for (i=0; i<3; i++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
395 396
            s->temp[i]= av_malloc(s->width + 16);
        }
397
    } else {
398
        s->temp[0]= av_mallocz(4*s->width + 16);
Michael Niedermayer's avatar
Michael Niedermayer committed
399 400 401
    }
}

402 403
static av_cold int common_init(AVCodecContext *avctx)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
404 405
    HYuvContext *s = avctx->priv_data;

406 407
    s->avctx = avctx;
    s->flags = avctx->flags;
408

409
    ff_dsputil_init(&s->dsp, avctx);
410

411 412
    s->width = avctx->width;
    s->height = avctx->height;
413
    av_assert1(s->width > 0 && s->height > 0);
414

415 416 417
    return 0;
}

418
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
419
static av_cold int decode_init(AVCodecContext *avctx)
420 421 422 423
{
    HYuvContext *s = avctx->priv_data;

    common_init(avctx);
424
    memset(s->vlc, 0, 3 * sizeof(VLC));
425

426
    avctx->coded_frame = &s->picture;
427
    avcodec_get_frame_defaults(&s->picture);
428 429 430 431 432 433 434 435
    s->interlaced = s->height > 288;

    s->bgr32 = 1;

    if (avctx->extradata_size) {
        if ((avctx->bits_per_coded_sample & 7) &&
            avctx->bits_per_coded_sample != 12)
            s->version = 1; // do such files exist at all?
Michael Niedermayer's avatar
Michael Niedermayer committed
436
        else
437 438 439
            s->version = 2;
    } else
        s->version = 0;
440

441
    if (s->version == 2) {
442
        int method, interlace;
Michael Niedermayer's avatar
Michael Niedermayer committed
443

444 445 446
        if (avctx->extradata_size < 4)
            return -1;

447 448 449 450 451 452 453 454 455 456 457 458
        method = ((uint8_t*)avctx->extradata)[0];
        s->decorrelate = method & 64 ? 1 : 0;
        s->predictor = method & 63;
        s->bitstream_bpp = ((uint8_t*)avctx->extradata)[1];
        if (s->bitstream_bpp == 0)
            s->bitstream_bpp = avctx->bits_per_coded_sample & ~7;
        interlace = (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4;
        s->interlaced = (interlace == 1) ? 1 : (interlace == 2) ? 0 : s->interlaced;
        s->context = ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;

        if ( read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4,
                                 avctx->extradata_size - 4) < 0)
Michael Niedermayer's avatar
Michael Niedermayer committed
459 460
            return -1;
    }else{
461
        switch (avctx->bits_per_coded_sample & 7) {
Michael Niedermayer's avatar
Michael Niedermayer committed
462
        case 1:
463 464
            s->predictor = LEFT;
            s->decorrelate = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
465 466
            break;
        case 2:
467 468
            s->predictor = LEFT;
            s->decorrelate = 1;
Michael Niedermayer's avatar
Michael Niedermayer committed
469 470
            break;
        case 3:
471 472
            s->predictor = PLANE;
            s->decorrelate = avctx->bits_per_coded_sample >= 24;
Michael Niedermayer's avatar
Michael Niedermayer committed
473 474
            break;
        case 4:
475 476
            s->predictor = MEDIAN;
            s->decorrelate = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
477 478
            break;
        default:
479 480
            s->predictor = LEFT; //OLD
            s->decorrelate = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
481 482
            break;
        }
483 484
        s->bitstream_bpp = avctx->bits_per_coded_sample & ~7;
        s->context = 0;
485

486
        if (read_old_huffman_tables(s) < 0)
Michael Niedermayer's avatar
Michael Niedermayer committed
487 488
            return -1;
    }
489

490
    switch (s->bitstream_bpp) {
Michael Niedermayer's avatar
Michael Niedermayer committed
491
    case 12:
492
        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
Michael Niedermayer's avatar
Michael Niedermayer committed
493 494
        break;
    case 16:
495
        if (s->yuy2) {
496
            avctx->pix_fmt = AV_PIX_FMT_YUYV422;
497
        } else {
498
            avctx->pix_fmt = AV_PIX_FMT_YUV422P;
Michael Niedermayer's avatar
Michael Niedermayer committed
499 500 501 502
        }
        break;
    case 24:
    case 32:
503
        if (s->bgr32) {
504
            avctx->pix_fmt = AV_PIX_FMT_RGB32;
505
        } else {
506
            avctx->pix_fmt = AV_PIX_FMT_BGR24;
Michael Niedermayer's avatar
Michael Niedermayer committed
507 508 509
        }
        break;
    default:
510
        return AVERROR_INVALIDDATA;
Michael Niedermayer's avatar
Michael Niedermayer committed
511
    }
512

513
    if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) {
514 515 516 517
        av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
        return AVERROR_INVALIDDATA;
    }

Michael Niedermayer's avatar
Michael Niedermayer committed
518
    alloc_temp(s);
519

Michael Niedermayer's avatar
Michael Niedermayer committed
520 521
    return 0;
}
522 523 524 525 526 527 528 529 530 531 532 533

static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
{
    HYuvContext *s = avctx->priv_data;
    int i;

    avctx->coded_frame= &s->picture;
    alloc_temp(s);

    for (i = 0; i < 6; i++)
        s->vlc[i].table = NULL;

534 535 536
    if (s->version == 2) {
        if (read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4,
                                avctx->extradata_size) < 0)
537
            return -1;
538 539
    } else {
        if (read_old_huffman_tables(s) < 0)
540 541 542 543 544
            return -1;
    }

    return 0;
}
545
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
546

547
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
548 549
static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
550
    int i;
551
    int index = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
552

553 554 555
    for (i = 0; i < 256;) {
        int val = len[i];
        int repeat = 0;
556

557
        for (; i < 256 && len[i] == val && repeat < 255; i++)
558
            repeat++;
559

560
        av_assert0(val < 32 && val >0 && repeat<256 && repeat>0);
561
        if (repeat > 7) {
562 563 564 565
            buf[index++] = val;
            buf[index++] = repeat;
        } else {
            buf[index++] = val | (repeat << 5);
Michael Niedermayer's avatar
Michael Niedermayer committed
566 567
        }
    }
568

569
    return index;
Michael Niedermayer's avatar
Michael Niedermayer committed
570 571
}

572
static av_cold int encode_init(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
573 574
{
    HYuvContext *s = avctx->priv_data;
575
    int i, j;
Michael Niedermayer's avatar
Michael Niedermayer committed
576

577
    common_init(avctx);
578

579 580 581
    avctx->extradata = av_mallocz(1024*30); // 256*3+4 == 772
    avctx->stats_out = av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
    s->version = 2;
582

583
    avctx->coded_frame = &s->picture;
584

585
    switch (avctx->pix_fmt) {
586 587
    case AV_PIX_FMT_YUV420P:
    case AV_PIX_FMT_YUV422P:
588 589 590 591
        if (s->width & 1) {
            av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
            return AVERROR(EINVAL);
        }
592
        s->bitstream_bpp = avctx->pix_fmt == AV_PIX_FMT_YUV420P ? 12 : 16;
Michael Niedermayer's avatar
Michael Niedermayer committed
593
        break;
594
    case AV_PIX_FMT_RGB32:
595
        s->bitstream_bpp = 32;
Loren Merritt's avatar
Loren Merritt committed
596
        break;
597
    case AV_PIX_FMT_RGB24:
598
        s->bitstream_bpp = 24;
599
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
600
    default:
601
        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
602 603
        return -1;
    }
604 605 606 607 608 609 610 611 612 613
    avctx->bits_per_coded_sample = s->bitstream_bpp;
    s->decorrelate = s->bitstream_bpp >= 24;
    s->predictor = avctx->prediction_method;
    s->interlaced = avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
    if (avctx->context_model == 1) {
        s->context = avctx->context_model;
        if (s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)) {
            av_log(avctx, AV_LOG_ERROR,
                   "context=1 is not compatible with "
                   "2 pass huffyuv encoding\n");
614 615 616
            return -1;
        }
    }else s->context= 0;
617

618
    if (avctx->codec->id == AV_CODEC_ID_HUFFYUV) {
619
        if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
620 621 622
            av_log(avctx, AV_LOG_ERROR,
                   "Error: YV12 is not supported by huffyuv; use "
                   "vcodec=ffvhuff or format=422p\n");
623 624
            return -1;
        }
625 626 627 628
        if (avctx->context_model) {
            av_log(avctx, AV_LOG_ERROR,
                   "Error: per-frame huffman tables are not supported "
                   "by huffyuv; use vcodec=ffvhuff\n");
629 630
            return -1;
        }
631 632 633
        if (s->interlaced != ( s->height > 288 ))
            av_log(avctx, AV_LOG_INFO,
                   "using huffyuv 2.2.0 or newer interlacing flag\n");
634
    }
635

636 637 638
    if (s->bitstream_bpp >= 24 && s->predictor == MEDIAN) {
        av_log(avctx, AV_LOG_ERROR,
               "Error: RGB is incompatible with median predictor\n");
Loren Merritt's avatar
Loren Merritt committed
639 640 641
        return -1;
    }

642 643 644 645 646 647 648
    ((uint8_t*)avctx->extradata)[0] = s->predictor | (s->decorrelate << 6);
    ((uint8_t*)avctx->extradata)[1] = s->bitstream_bpp;
    ((uint8_t*)avctx->extradata)[2] = s->interlaced ? 0x10 : 0x20;
    if (s->context)
        ((uint8_t*)avctx->extradata)[2] |= 0x40;
    ((uint8_t*)avctx->extradata)[3] = 0;
    s->avctx->extradata_size = 4;
649

650 651
    if (avctx->stats_in) {
        char *p = avctx->stats_in;
652

653 654 655
        for (i = 0; i < 3; i++)
            for (j = 0; j < 256; j++)
                s->stats[i][j] = 1;
Michael Niedermayer's avatar
Michael Niedermayer committed
656

657 658
        for (;;) {
            for (i = 0; i < 3; i++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
659 660
                char *next;

661 662 663 664
                for (j = 0; j < 256; j++) {
                    s->stats[i][j] += strtol(p, &next, 0);
                    if (next == p) return -1;
                    p = next;
665
                }
Michael Niedermayer's avatar
Michael Niedermayer committed
666
            }
667
            if (p[0] == 0 || p[1] == 0 || p[2] == 0) break;
Michael Niedermayer's avatar
Michael Niedermayer committed
668
        }
669 670 671 672
    } else {
        for (i = 0; i < 3; i++)
            for (j = 0; j < 256; j++) {
                int d = FFMIN(j, 256 - j);
673

674
                s->stats[i][j] = 100000000 / (d + 1);
Michael Niedermayer's avatar
Michael Niedermayer committed
675 676
            }
    }
677

678
    for (i = 0; i < 3; i++) {
679
        ff_huff_gen_len_table(s->len[i], s->stats[i]);
Michael Niedermayer's avatar
Michael Niedermayer committed
680

681
        if (generate_bits_table(s->bits[i], s->len[i]) < 0) {
Michael Niedermayer's avatar
Michael Niedermayer committed
682 683
            return -1;
        }
684

685 686
        s->avctx->extradata_size +=
            store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]);
Michael Niedermayer's avatar
Michael Niedermayer committed
687 688
    }

689 690 691 692 693 694
    if (s->context) {
        for (i = 0; i < 3; i++) {
            int pels = s->width * s->height / (i ? 40 : 10);
            for (j = 0; j < 256; j++) {
                int d = FFMIN(j, 256 - j);
                s->stats[i][j] = pels/(d + 1);
695 696
            }
        }
697 698 699
    } else {
        for (i = 0; i < 3; i++)
            for (j = 0; j < 256; j++)
700 701
                s->stats[i][j]= 0;
    }
702

Michael Niedermayer's avatar
Michael Niedermayer committed
703 704
    alloc_temp(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
705
    s->picture_number=0;
706

Michael Niedermayer's avatar
Michael Niedermayer committed
707 708
    return 0;
}
709
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
710

711 712 713
/* TODO instead of restarting the read when the code isn't in the first level
 * of the joint table, jump into the 2nd level of the individual table. */
#define READ_2PIX(dst0, dst1, plane1){\
714 715 716 717
    uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\
    if(code != 0xffff){\
        dst0 = code>>8;\
        dst1 = code;\
718 719 720 721 722 723
    }else{\
        dst0 = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);\
        dst1 = get_vlc2(&s->gb, s->vlc[plane1].table, VLC_BITS, 3);\
    }\
}

724 725
static void decode_422_bitstream(HYuvContext *s, int count)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
726
    int i;
727

728
    count /= 2;
729

730
    if (count >= (get_bits_left(&s->gb)) / (31 * 4)) {
731
        for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
732 733
            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);
            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);
734
        }
735 736 737 738
    } else {
        for (i = 0; i < count; i++) {
            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);
            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);
Michael Niedermayer's avatar
Michael Niedermayer committed
739
        }
740
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
741 742
}

743 744
static void decode_gray_bitstream(HYuvContext *s, int count)
{
745
    int i;
746

747
    count/=2;
748

749
    if (count >= (get_bits_left(&s->gb)) / (31 * 2)) {
750
        for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
751
            READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0);
752
        }
753
    } else {
Michael Niedermayer's avatar
Michael Niedermayer committed
754
        for(i=0; i<count; i++){
755
            READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0);
Michael Niedermayer's avatar
Michael Niedermayer committed
756
        }
757
    }
758 759
}

760
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
761 762
static int encode_422_bitstream(HYuvContext *s, int offset, int count)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
763
    int i;
764
    const uint8_t *y = s->temp[0] + offset;
765 766
    const uint8_t *u = s->temp[1] + offset / 2;
    const uint8_t *v = s->temp[2] + offset / 2;
767

768
    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < 2 * 4 * count) {
769 770 771
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
        return -1;
    }
772

773
#define LOAD4\
774 775
            int y0 = y[2 * i];\
            int y1 = y[2 * i + 1];\
776 777
            int u0 = u[i];\
            int v0 = v[i];
778

779 780 781 782
    count /= 2;

    if (s->flags & CODEC_FLAG_PASS1) {
        for(i = 0; i < count; i++) {
783 784 785 786 787
            LOAD4;
            s->stats[0][y0]++;
            s->stats[1][u0]++;
            s->stats[0][y1]++;
            s->stats[2][v0]++;
Michael Niedermayer's avatar
Michael Niedermayer committed
788
        }
789
    }
790
    if (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)
791
        return 0;
792 793
    if (s->context) {
        for (i = 0; i < count; i++) {
794 795 796 797 798 799 800 801 802
            LOAD4;
            s->stats[0][y0]++;
            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
            s->stats[1][u0]++;
            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
            s->stats[0][y1]++;
            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
            s->stats[2][v0]++;
            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
803
        }
804 805
    } else {
        for(i = 0; i < count; i++) {
806 807 808 809 810
            LOAD4;
            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);
            put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]);
            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);
            put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]);
Michael Niedermayer's avatar
Michael Niedermayer committed
811 812
        }
    }
813
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
814 815
}

816 817
static int encode_gray_bitstream(HYuvContext *s, int count)
{
818
    int i;
819

820
    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < 4 * count) {
821 822 823 824
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
        return -1;
    }

825
#define LOAD2\
826 827
            int y0 = s->temp[0][2 * i];\
            int y1 = s->temp[0][2 * i + 1];
828 829 830 831 832 833 834
#define STAT2\
            s->stats[0][y0]++;\
            s->stats[0][y1]++;
#define WRITE2\
            put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\
            put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]);

835 836 837 838
    count /= 2;

    if (s->flags & CODEC_FLAG_PASS1) {
        for (i = 0; i < count; i++) {
839 840
            LOAD2;
            STAT2;
841
        }
842
    }
843
    if (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)
844
        return 0;
845

846 847
    if (s->context) {
        for (i = 0; i < count; i++) {
848 849 850
            LOAD2;
            STAT2;
            WRITE2;
851
        }
852 853
    } else {
        for (i = 0; i < count; i++) {
854 855
            LOAD2;
            WRITE2;
856 857
        }
    }
858
    return 0;
859
}
860
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
861

862 863 864
static av_always_inline void decode_bgr_1(HYuvContext *s, int count,
                                          int decorrelate, int alpha)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
865
    int i;
866
    for (i = 0; i < count; i++) {
867
        int code = get_vlc2(&s->gb, s->vlc[3].table, VLC_BITS, 1);
868 869 870 871 872 873 874 875 876 877 878 879
        if (code != -1) {
            *(uint32_t*)&s->temp[0][4 * i] = s->pix_bgr_map[code];
        } else if(decorrelate) {
            s->temp[0][4 * i + G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
            s->temp[0][4 * i + B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) +
                                    s->temp[0][4 * i + G];
            s->temp[0][4 * i + R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) +
                                    s->temp[0][4 * i + G];
        } else {
            s->temp[0][4 * i + B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
            s->temp[0][4 * i + G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
            s->temp[0][4 * i + R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
Michael Niedermayer's avatar
Michael Niedermayer committed
880
        }
881 882
        if (alpha)
            s->temp[0][4 * i + A] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
883 884 885
    }
}

886 887 888 889
static void decode_bgr_bitstream(HYuvContext *s, int count)
{
    if (s->decorrelate) {
        if (s->bitstream_bpp==24)
890 891 892
            decode_bgr_1(s, count, 1, 0);
        else
            decode_bgr_1(s, count, 1, 1);
893 894
    } else {
        if (s->bitstream_bpp==24)
895 896 897
            decode_bgr_1(s, count, 0, 0);
        else
            decode_bgr_1(s, count, 0, 1);
Michael Niedermayer's avatar
Michael Niedermayer committed
898 899 900
    }
}

901
static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes)
902
{
Loren Merritt's avatar
Loren Merritt committed
903 904
    int i;

905
    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*planes*count) {
Loren Merritt's avatar
Loren Merritt committed
906 907 908 909
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
        return -1;
    }

910
#define LOAD3\
911 912 913 914
            int g =  s->temp[0][planes==3 ? 3*i + 1 : 4*i + G];\
            int b = (s->temp[0][planes==3 ? 3*i + 2 : 4*i + B] - g) & 0xff;\
            int r = (s->temp[0][planes==3 ? 3*i + 0 : 4*i + R] - g) & 0xff;\
            int a =  s->temp[0][planes*i + A];
915 916 917
#define STAT3\
            s->stats[0][b]++;\
            s->stats[1][g]++;\
918
            s->stats[2][r]++;\
919
            if(planes==4) s->stats[2][a]++;
920 921 922
#define WRITE3\
            put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\
            put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\
923
            put_bits(&s->pb, s->len[2][r], s->bits[2][r]);\
924
            if(planes==4) put_bits(&s->pb, s->len[2][a], s->bits[2][a]);
925

926 927 928
    if ((s->flags & CODEC_FLAG_PASS1) &&
        (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
        for (i = 0; i < count; i++) {
929 930
            LOAD3;
            STAT3;
Loren Merritt's avatar
Loren Merritt committed
931
        }
932 933
    } else if (s->context || (s->flags & CODEC_FLAG_PASS1)) {
        for (i = 0; i < count; i++) {
934 935 936
            LOAD3;
            STAT3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
937
        }
938 939
    } else {
        for (i = 0; i < count; i++) {
940 941
            LOAD3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
942 943 944 945 946
        }
    }
    return 0;
}

947
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
948 949
static void draw_slice(HYuvContext *s, int y)
{
950 951
    int h, cy, i;
    int offset[AV_NUM_DATA_POINTERS];
952

953
    if (s->avctx->draw_horiz_band==NULL)
954
        return;
955

956
    h = y - s->last_slice_end;
957
    y -= h;
958

959 960 961 962
    if (s->bitstream_bpp == 12) {
        cy = y>>1;
    } else {
        cy = y;
963
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
964 965 966 967

    offset[0] = s->picture.linesize[0]*y;
    offset[1] = s->picture.linesize[1]*cy;
    offset[2] = s->picture.linesize[2]*cy;
968 969
    for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
        offset[i] = 0;
970 971
    emms_c();

972
    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
973

974
    s->last_slice_end = y + h;
975 976
}

977 978 979
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                        AVPacket *avpkt)
{
980 981
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
Michael Niedermayer's avatar
Michael Niedermayer committed
982
    HYuvContext *s = avctx->priv_data;
983 984 985
    const int width = s->width;
    const int width2 = s->width>>1;
    const int height = s->height;
Michael Niedermayer's avatar
Michael Niedermayer committed
986
    int fake_ystride, fake_ustride, fake_vstride;
987 988
    AVFrame * const p = &s->picture;
    int table_size = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
989

990
    AVFrame *picture = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
991

992 993 994
    av_fast_malloc(&s->bitstream_buffer,
                   &s->bitstream_buffer_size,
                   buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
995 996
    if (!s->bitstream_buffer)
        return AVERROR(ENOMEM);
Michael Niedermayer's avatar
Michael Niedermayer committed
997

998
    memset(s->bitstream_buffer + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
999 1000
    s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer,
                     (const uint32_t*)buf, buf_size / 4);
1001

1002
    if (p->data[0])
1003
        ff_thread_release_buffer(avctx, p);
1004

1005 1006
    p->reference = 0;
    if (ff_thread_get_buffer(avctx, p) < 0) {
1007
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1008
        return -1;
Michael Niedermayer's avatar
Michael Niedermayer committed
1009
    }
1010

1011
    if (s->context) {
1012
        table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size);
1013
        if (table_size < 0)
1014 1015 1016
            return -1;
    }

1017
    if ((unsigned)(buf_size-table_size) >= INT_MAX / 8)
Michael Niedermayer's avatar
Michael Niedermayer committed
1018 1019
        return -1;

1020 1021
    init_get_bits(&s->gb, s->bitstream_buffer+table_size,
                  (buf_size-table_size) * 8);
Michael Niedermayer's avatar
Michael Niedermayer committed
1022

1023 1024 1025
    fake_ystride = s->interlaced ? p->linesize[0] * 2  : p->linesize[0];
    fake_ustride = s->interlaced ? p->linesize[1] * 2  : p->linesize[1];
    fake_vstride = s->interlaced ? p->linesize[2] * 2  : p->linesize[2];
1026

1027
    s->last_slice_end = 0;
1028

1029
    if (s->bitstream_bpp < 24) {
1030
        int y, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
1031 1032
        int lefty, leftu, leftv;
        int lefttopy, lefttopu, lefttopv;
1033

1034 1035 1036 1037 1038
        if (s->yuy2) {
            p->data[0][3] = get_bits(&s->gb, 8);
            p->data[0][2] = get_bits(&s->gb, 8);
            p->data[0][1] = get_bits(&s->gb, 8);
            p->data[0][0] = get_bits(&s->gb, 8);
1039

1040 1041
            av_log(avctx, AV_LOG_ERROR,
                   "YUY2 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1042
            return -1;
1043
        } else {
1044

1045 1046 1047 1048
            leftv = p->data[2][0] = get_bits(&s->gb, 8);
            lefty = p->data[0][1] = get_bits(&s->gb, 8);
            leftu = p->data[1][0] = get_bits(&s->gb, 8);
                    p->data[0][0] = get_bits(&s->gb, 8);
1049

1050
            switch (s->predictor) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1051 1052 1053
            case LEFT:
            case PLANE:
                decode_422_bitstream(s, width-2);
1054 1055 1056 1057
                lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
                if (!(s->flags&CODEC_FLAG_GRAY)) {
                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu);
                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1058 1059
                }

1060
                for (cy = y = 1; y < s->height; y++, cy++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1061
                    uint8_t *ydst, *udst, *vdst;
1062

1063
                    if (s->bitstream_bpp == 12) {
1064
                        decode_gray_bitstream(s, width);
1065

1066
                        ydst = p->data[0] + p->linesize[0] * y;
1067

1068 1069 1070
                        lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
                        if (s->predictor == PLANE) {
                            if (y > s->interlaced)
1071 1072 1073
                                s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
                        }
                        y++;
1074
                        if (y >= s->height) break;
1075
                    }
1076

1077
                    draw_slice(s, y);
1078

1079 1080 1081
                    ydst = p->data[0] + p->linesize[0]*y;
                    udst = p->data[1] + p->linesize[1]*cy;
                    vdst = p->data[2] + p->linesize[2]*cy;
1082

1083
                    decode_422_bitstream(s, width);
1084 1085
                    lefty = s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
                    if (!(s->flags & CODEC_FLAG_GRAY)) {
1086 1087
                        leftu= s->dsp.add_hfyu_left_prediction(udst, s->temp[1], width2, leftu);
                        leftv= s->dsp.add_hfyu_left_prediction(vdst, s->temp[2], width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1088
                    }
1089 1090
                    if (s->predictor == PLANE) {
                        if (cy > s->interlaced) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1091
                            s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
1092
                            if (!(s->flags & CODEC_FLAG_GRAY)) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1093 1094 1095 1096 1097 1098
                                s->dsp.add_bytes(udst, udst - fake_ustride, width2);
                                s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
                            }
                        }
                    }
                }
1099
                draw_slice(s, height);
1100

Michael Niedermayer's avatar
Michael Niedermayer committed
1101 1102 1103
                break;
            case MEDIAN:
                /* first line except first 2 pixels is left predicted */
1104 1105 1106 1107 1108
                decode_422_bitstream(s, width - 2);
                lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width - 2, lefty);
                if (!(s->flags & CODEC_FLAG_GRAY)) {
                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2 - 1, leftu);
                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2 - 1, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1109
                }
1110

1111
                cy = y = 1;
1112

Michael Niedermayer's avatar
Michael Niedermayer committed
1113
                /* second line is left predicted for interlaced case */
1114
                if (s->interlaced) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1115
                    decode_422_bitstream(s, width);
1116 1117 1118 1119
                    lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
                    if (!(s->flags & CODEC_FLAG_GRAY)) {
                        leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
                        leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1120
                    }
1121
                    y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1122 1123 1124 1125
                }

                /* next 4 pixels are left predicted too */
                decode_422_bitstream(s, 4);
1126 1127 1128 1129
                lefty = s->dsp.add_hfyu_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
                if (!(s->flags&CODEC_FLAG_GRAY)) {
                    leftu = s->dsp.add_hfyu_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
                    leftv = s->dsp.add_hfyu_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1130 1131 1132
                }

                /* next line except the first 4 pixels is median predicted */
1133 1134
                lefttopy = p->data[0][3];
                decode_422_bitstream(s, width - 4);
1135
                s->dsp.add_hfyu_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
1136 1137 1138 1139 1140
                if (!(s->flags&CODEC_FLAG_GRAY)) {
                    lefttopu = p->data[1][1];
                    lefttopv = p->data[2][1];
                    s->dsp.add_hfyu_median_prediction(p->data[1] + fake_ustride+2, p->data[1] + 2, s->temp[1], width2 - 2, &leftu, &lefttopu);
                    s->dsp.add_hfyu_median_prediction(p->data[2] + fake_vstride+2, p->data[2] + 2, s->temp[2], width2 - 2, &leftv, &lefttopv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1141
                }
1142
                y++; cy++;
1143

1144
                for (; y<height; y++, cy++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1145
                    uint8_t *ydst, *udst, *vdst;
1146

1147 1148
                    if (s->bitstream_bpp == 12) {
                        while (2 * cy > y) {
1149
                            decode_gray_bitstream(s, width);
1150
                            ydst = p->data[0] + p->linesize[0] * y;
1151
                            s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
1152 1153
                            y++;
                        }
1154
                        if (y >= height) break;
1155
                    }
1156
                    draw_slice(s, y);
1157

Michael Niedermayer's avatar
Michael Niedermayer committed
1158
                    decode_422_bitstream(s, width);
1159

1160 1161 1162
                    ydst = p->data[0] + p->linesize[0] * y;
                    udst = p->data[1] + p->linesize[1] * cy;
                    vdst = p->data[2] + p->linesize[2] * cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
1163

1164
                    s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
1165
                    if (!(s->flags & CODEC_FLAG_GRAY)) {
1166 1167
                        s->dsp.add_hfyu_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
                        s->dsp.add_hfyu_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1168 1169
                    }
                }
1170 1171

                draw_slice(s, height);
Michael Niedermayer's avatar
Michael Niedermayer committed
1172 1173 1174
                break;
            }
        }
1175
    } else {
Michael Niedermayer's avatar
Michael Niedermayer committed
1176
        int y;
1177
        int leftr, leftg, leftb, lefta;
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
        const int last_line = (height - 1) * p->linesize[0];

        if (s->bitstream_bpp == 32) {
            lefta = p->data[0][last_line+A] = get_bits(&s->gb, 8);
            leftr = p->data[0][last_line+R] = get_bits(&s->gb, 8);
            leftg = p->data[0][last_line+G] = get_bits(&s->gb, 8);
            leftb = p->data[0][last_line+B] = get_bits(&s->gb, 8);
        } else {
            leftr = p->data[0][last_line+R] = get_bits(&s->gb, 8);
            leftg = p->data[0][last_line+G] = get_bits(&s->gb, 8);
            leftb = p->data[0][last_line+B] = get_bits(&s->gb, 8);
            lefta = p->data[0][last_line+A] = 255;
Michael Niedermayer's avatar
Michael Niedermayer committed
1190 1191
            skip_bits(&s->gb, 8);
        }
1192

1193 1194
        if (s->bgr32) {
            switch (s->predictor) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1195 1196
            case LEFT:
            case PLANE:
1197 1198
                decode_bgr_bitstream(s, width - 1);
                s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width - 1, &leftr, &leftg, &leftb, &lefta);
Michael Niedermayer's avatar
Michael Niedermayer committed
1199

1200
                for (y = s->height - 2; y >= 0; y--) { //Yes it is stored upside down.
Michael Niedermayer's avatar
Michael Niedermayer committed
1201
                    decode_bgr_bitstream(s, width);
1202

1203
                    s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta);
1204 1205 1206 1207 1208 1209 1210
                    if (s->predictor == PLANE) {
                        if (s->bitstream_bpp != 32) lefta = 0;
                        if ((y & s->interlaced) == 0 &&
                            y < s->height - 1 - s->interlaced) {
                            s->dsp.add_bytes(p->data[0] + p->linesize[0] * y,
                                             p->data[0] + p->linesize[0] * y +
                                             fake_ystride, fake_ystride);
Michael Niedermayer's avatar
Michael Niedermayer committed
1211 1212 1213
                        }
                    }
                }
1214 1215
                // just 1 large slice as this is not possible in reverse order
                draw_slice(s, height);
Michael Niedermayer's avatar
Michael Niedermayer committed
1216 1217
                break;
            default:
1218 1219
                av_log(avctx, AV_LOG_ERROR,
                       "prediction type not supported!\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1220 1221
            }
        }else{
1222 1223
            av_log(avctx, AV_LOG_ERROR,
                   "BGR24 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1224 1225 1226 1227
            return -1;
        }
    }
    emms_c();
1228

1229
    *picture = *p;
1230
    *data_size = sizeof(AVFrame);
1231

1232
    return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size;
Michael Niedermayer's avatar
Michael Niedermayer committed
1233
}
1234
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1235

1236 1237
static int common_end(HYuvContext *s)
{
1238
    int i;
1239

1240
    for(i = 0; i < 3; i++) {
1241 1242 1243 1244 1245
        av_freep(&s->temp[i]);
    }
    return 0;
}

1246
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
1247
static av_cold int decode_end(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
1248 1249 1250
{
    HYuvContext *s = avctx->priv_data;
    int i;
1251

1252 1253 1254
    if (s->picture.data[0])
        avctx->release_buffer(avctx, &s->picture);

1255 1256
    common_end(s);
    av_freep(&s->bitstream_buffer);
1257

1258
    for (i = 0; i < 6; i++) {
1259
        ff_free_vlc(&s->vlc[i]);
Michael Niedermayer's avatar
Michael Niedermayer committed
1260
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
1261

Michael Niedermayer's avatar
Michael Niedermayer committed
1262 1263
    return 0;
}
1264
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1265

1266
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
1267 1268 1269
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                        const AVFrame *pict, int *got_packet)
{
Michael Niedermayer's avatar
Michael Niedermayer committed
1270
    HYuvContext *s = avctx->priv_data;
1271 1272 1273 1274 1275 1276 1277
    const int width = s->width;
    const int width2 = s->width>>1;
    const int height = s->height;
    const int fake_ystride = s->interlaced ? pict->linesize[0]*2  : pict->linesize[0];
    const int fake_ustride = s->interlaced ? pict->linesize[1]*2  : pict->linesize[1];
    const int fake_vstride = s->interlaced ? pict->linesize[2]*2  : pict->linesize[2];
    AVFrame * const p = &s->picture;
1278 1279
    int i, j, size = 0, ret;

1280
    if ((ret = ff_alloc_packet2(avctx, pkt, width * height * 3 * 4 + FF_MIN_BUFFER_SIZE)) < 0)
1281
        return ret;
Michael Niedermayer's avatar
Michael Niedermayer committed
1282

Michael Niedermayer's avatar
Michael Niedermayer committed
1283
    *p = *pict;
1284 1285
    p->pict_type = AV_PICTURE_TYPE_I;
    p->key_frame = 1;
1286

1287 1288
    if (s->context) {
        for (i = 0; i < 3; i++) {
1289
            ff_huff_gen_len_table(s->len[i], s->stats[i]);
1290
            if (generate_bits_table(s->bits[i], s->len[i]) < 0)
1291
                return -1;
1292
            size += store_table(s, s->len[i], &pkt->data[size]);
1293 1294
        }

1295 1296
        for (i = 0; i < 3; i++)
            for (j = 0; j < 256; j++)
1297 1298 1299
                s->stats[i][j] >>= 1;
    }

1300
    init_put_bits(&s->pb, pkt->data + size, pkt->size - size);
1301

1302 1303
    if (avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
        avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
1304
        int lefty, leftu, leftv, y, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
1305

1306 1307 1308 1309
        put_bits(&s->pb, 8, leftv = p->data[2][0]);
        put_bits(&s->pb, 8, lefty = p->data[0][1]);
        put_bits(&s->pb, 8, leftu = p->data[1][0]);
        put_bits(&s->pb, 8,         p->data[0][0]);
1310

1311 1312 1313
        lefty = sub_left_prediction(s, s->temp[0], p->data[0], width , 0);
        leftu = sub_left_prediction(s, s->temp[1], p->data[1], width2, 0);
        leftv = sub_left_prediction(s, s->temp[2], p->data[2], width2, 0);
1314

1315
        encode_422_bitstream(s, 2, width-2);
1316

1317
        if (s->predictor==MEDIAN) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1318
            int lefttopy, lefttopu, lefttopv;
1319 1320 1321 1322 1323
            cy = y = 1;
            if (s->interlaced) {
                lefty = sub_left_prediction(s, s->temp[0], p->data[0] + p->linesize[0], width , lefty);
                leftu = sub_left_prediction(s, s->temp[1], p->data[1] + p->linesize[1], width2, leftu);
                leftv = sub_left_prediction(s, s->temp[2], p->data[2] + p->linesize[2], width2, leftv);
1324

1325
                encode_422_bitstream(s, 0, width);
1326
                y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1327
            }
1328

1329 1330 1331
            lefty = sub_left_prediction(s, s->temp[0], p->data[0] + fake_ystride, 4, lefty);
            leftu = sub_left_prediction(s, s->temp[1], p->data[1] + fake_ustride, 2, leftu);
            leftv = sub_left_prediction(s, s->temp[2], p->data[2] + fake_vstride, 2, leftv);
1332

1333
            encode_422_bitstream(s, 0, 4);
1334

1335 1336 1337 1338 1339 1340 1341
            lefttopy = p->data[0][3];
            lefttopu = p->data[1][1];
            lefttopv = p->data[2][1];
            s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride + 4, width - 4 , &lefty, &lefttopy);
            s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride + 2, width2 - 2, &leftu, &lefttopu);
            s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride + 2, width2 - 2, &leftv, &lefttopv);
            encode_422_bitstream(s, 0, width - 4);
1342
            y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1343

1344
            for (; y < height; y++,cy++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1345
                uint8_t *ydst, *udst, *vdst;
1346

1347 1348 1349
                if (s->bitstream_bpp == 12) {
                    while (2 * cy > y) {
                        ydst = p->data[0] + p->linesize[0] * y;
1350
                        s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1351 1352 1353
                        encode_gray_bitstream(s, width);
                        y++;
                    }
1354
                    if (y >= height) break;
1355
                }
1356 1357 1358
                ydst = p->data[0] + p->linesize[0] * y;
                udst = p->data[1] + p->linesize[1] * cy;
                vdst = p->data[2] + p->linesize[2] * cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
1359

1360 1361 1362
                s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
                s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
                s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1363

1364
                encode_422_bitstream(s, 0, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1365
            }
1366 1367
        } else {
            for (cy = y = 1; y < height; y++, cy++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1368
                uint8_t *ydst, *udst, *vdst;
1369

1370
                /* encode a luma only line & y++ */
1371 1372
                if (s->bitstream_bpp == 12) {
                    ydst = p->data[0] + p->linesize[0] * y;
1373

1374
                    if (s->predictor == PLANE && s->interlaced < y) {
1375
                        s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1376

1377 1378 1379
                        lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
                    } else {
                        lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1380 1381 1382
                    }
                    encode_gray_bitstream(s, width);
                    y++;
1383
                    if (y >= height) break;
1384
                }
1385

1386 1387 1388
                ydst = p->data[0] + p->linesize[0] * y;
                udst = p->data[1] + p->linesize[1] * cy;
                vdst = p->data[2] + p->linesize[2] * cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
1389

1390
                if (s->predictor == PLANE && s->interlaced < cy) {
1391 1392
                    s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
                    s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
Michael Niedermayer's avatar
Michael Niedermayer committed
1393
                    s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2);
Michael Niedermayer's avatar
Michael Niedermayer committed
1394

1395 1396 1397 1398 1399 1400 1401
                    lefty = sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
                    leftu = sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
                    leftv = sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv);
                } else {
                    lefty = sub_left_prediction(s, s->temp[0], ydst, width , lefty);
                    leftu = sub_left_prediction(s, s->temp[1], udst, width2, leftu);
                    leftv = sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1402 1403
                }

1404
                encode_422_bitstream(s, 0, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1405
            }
1406
        }
1407
    } else if(avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1408
        uint8_t *data = p->data[0] + (height - 1) * p->linesize[0];
Loren Merritt's avatar
Loren Merritt committed
1409 1410 1411
        const int stride = -p->linesize[0];
        const int fake_stride = -fake_ystride;
        int y;
1412
        int leftr, leftg, leftb, lefta;
Loren Merritt's avatar
Loren Merritt committed
1413

1414
        put_bits(&s->pb, 8, lefta = data[A]);
1415 1416 1417
        put_bits(&s->pb, 8, leftr = data[R]);
        put_bits(&s->pb, 8, leftg = data[G]);
        put_bits(&s->pb, 8, leftb = data[B]);
Loren Merritt's avatar
Loren Merritt committed
1418

1419 1420
        sub_left_prediction_bgr32(s, s->temp[0], data + 4, width - 1, &leftr, &leftg, &leftb, &lefta);
        encode_bgra_bitstream(s, width - 1, 4);
Loren Merritt's avatar
Loren Merritt committed
1421

1422
        for (y = 1; y < s->height; y++) {
Loren Merritt's avatar
Loren Merritt committed
1423
            uint8_t *dst = data + y*stride;
1424 1425
            if (s->predictor == PLANE && s->interlaced < y) {
                s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width * 4);
1426
                sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb, &lefta);
1427
            } else {
1428
                sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb, &lefta);
Loren Merritt's avatar
Loren Merritt committed
1429
            }
1430 1431
            encode_bgra_bitstream(s, width, 4);
        }
1432
    }else if(avctx->pix_fmt == AV_PIX_FMT_RGB24){
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455
        uint8_t *data = p->data[0] + (height-1)*p->linesize[0];
        const int stride = -p->linesize[0];
        const int fake_stride = -fake_ystride;
        int y;
        int leftr, leftg, leftb;

        put_bits(&s->pb, 8, leftr= data[0]);
        put_bits(&s->pb, 8, leftg= data[1]);
        put_bits(&s->pb, 8, leftb= data[2]);
        put_bits(&s->pb, 8, 0);

        sub_left_prediction_rgb24(s, s->temp[0], data+3, width-1, &leftr, &leftg, &leftb);
        encode_bgra_bitstream(s, width-1, 3);

        for(y=1; y<s->height; y++){
            uint8_t *dst = data + y*stride;
            if(s->predictor == PLANE && s->interlaced < y){
                s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*3);
                sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb);
            }else{
                sub_left_prediction_rgb24(s, s->temp[0], dst, width, &leftr, &leftg, &leftb);
            }
            encode_bgra_bitstream(s, width, 3);
Loren Merritt's avatar
Loren Merritt committed
1456
        }
1457
    } else {
1458
        av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1459 1460
    }
    emms_c();
1461

1462
    size += (put_bits_count(&s->pb) + 31) / 8;
1463 1464
    put_bits(&s->pb, 16, 0);
    put_bits(&s->pb, 15, 0);
1465
    size /= 4;
1466

1467
    if ((s->flags&CODEC_FLAG_PASS1) && (s->picture_number & 31) == 0) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1468
        int j;
1469 1470 1471 1472
        char *p = avctx->stats_out;
        char *end = p + 1024*30;
        for (i = 0; i < 3; i++) {
            for (j = 0; j < 256; j++) {
1473
                snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]);
1474
                p += strlen(p);
Michael Niedermayer's avatar
Michael Niedermayer committed
1475 1476
                s->stats[i][j]= 0;
            }
Michael Niedermayer's avatar
Michael Niedermayer committed
1477
            snprintf(p, end-p, "\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1478 1479
            p++;
        }
1480 1481
    } else
        avctx->stats_out[0] = '\0';
1482
    if (!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
1483
        flush_put_bits(&s->pb);
1484
        s->dsp.bswap_buf((uint32_t*)pkt->data, (uint32_t*)pkt->data, size);
Michael Niedermayer's avatar
Michael Niedermayer committed
1485
    }
1486

Michael Niedermayer's avatar
Michael Niedermayer committed
1487
    s->picture_number++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1488

1489
    pkt->size   = size * 4;
1490 1491 1492 1493
    pkt->flags |= AV_PKT_FLAG_KEY;
    *got_packet = 1;

    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
1494 1495
}

1496
static av_cold int encode_end(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
1497
{
1498
    HYuvContext *s = avctx->priv_data;
1499

1500
    common_end(s);
Michael Niedermayer's avatar
Michael Niedermayer committed
1501 1502 1503

    av_freep(&avctx->extradata);
    av_freep(&avctx->stats_out);
1504

Michael Niedermayer's avatar
Michael Niedermayer committed
1505 1506
    return 0;
}
1507
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1508

1509
#if CONFIG_HUFFYUV_DECODER
1510
AVCodec ff_huffyuv_decoder = {
1511 1512
    .name             = "huffyuv",
    .type             = AVMEDIA_TYPE_VIDEO,
1513
    .id               = AV_CODEC_ID_HUFFYUV,
1514 1515 1516 1517 1518 1519
    .priv_data_size   = sizeof(HYuvContext),
    .init             = decode_init,
    .close            = decode_end,
    .decode           = decode_frame,
    .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
                        CODEC_CAP_FRAME_THREADS,
1520
    .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
1521
    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
Michael Niedermayer's avatar
Michael Niedermayer committed
1522
};
1523
#endif
Michael Niedermayer's avatar
Michael Niedermayer committed
1524

1525
#if CONFIG_FFVHUFF_DECODER
1526
AVCodec ff_ffvhuff_decoder = {
1527 1528
    .name             = "ffvhuff",
    .type             = AVMEDIA_TYPE_VIDEO,
1529
    .id               = AV_CODEC_ID_FFVHUFF,
1530 1531 1532 1533 1534 1535
    .priv_data_size   = sizeof(HYuvContext),
    .init             = decode_init,
    .close            = decode_end,
    .decode           = decode_frame,
    .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
                        CODEC_CAP_FRAME_THREADS,
1536
    .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
1537
    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
1538
};
1539
#endif
1540

1541
#if CONFIG_HUFFYUV_ENCODER
1542
AVCodec ff_huffyuv_encoder = {
1543 1544
    .name           = "huffyuv",
    .type           = AVMEDIA_TYPE_VIDEO,
1545
    .id             = AV_CODEC_ID_HUFFYUV,
1546 1547
    .priv_data_size = sizeof(HYuvContext),
    .init           = encode_init,
1548
    .encode2        = encode_frame,
1549
    .close          = encode_end,
1550
    .pix_fmts       = (const enum AVPixelFormat[]){
1551
        AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
1552 1553
    },
    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
Michael Niedermayer's avatar
Michael Niedermayer committed
1554
};
1555
#endif
1556

1557
#if CONFIG_FFVHUFF_ENCODER
1558
AVCodec ff_ffvhuff_encoder = {
1559 1560
    .name           = "ffvhuff",
    .type           = AVMEDIA_TYPE_VIDEO,
1561
    .id             = AV_CODEC_ID_FFVHUFF,
1562 1563
    .priv_data_size = sizeof(HYuvContext),
    .init           = encode_init,
1564
    .encode2        = encode_frame,
1565
    .close          = encode_end,
1566
    .pix_fmts       = (const enum AVPixelFormat[]){
1567
        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
1568 1569
    },
    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
1570
};
1571
#endif