huffyuv.c 46.8 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 libavcodec/huffyuv.c
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 "bitstream.h"
Michael Niedermayer's avatar
Michael Niedermayer committed
33 34 35
#include "dsputil.h"

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

37 38 39 40 41 42 43 44 45 46
#ifdef WORDS_BIGENDIAN
#define B 3
#define G 2
#define R 1
#else
#define B 0
#define G 1
#define R 2
#endif

Michael Niedermayer's avatar
Michael Niedermayer committed
47 48 49 50 51
typedef enum Predictor{
    LEFT= 0,
    PLANE,
    MEDIAN,
} Predictor;
52

Michael Niedermayer's avatar
Michael Niedermayer committed
53 54 55 56 57 58 59 60 61 62 63 64 65
typedef struct HYuvContext{
    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;
66
    int context;
Michael Niedermayer's avatar
Michael Niedermayer committed
67
    int picture_number;
68
    int last_slice_end;
69
    uint8_t *temp[3];
Michael Niedermayer's avatar
Michael Niedermayer committed
70 71 72
    uint64_t stats[3][256];
    uint8_t len[3][256];
    uint32_t bits[3][256];
73
    uint32_t pix_bgr_map[1<<VLC_BITS];
74
    VLC vlc[6];                             //Y,U,V,YY,YU,YV
75
    AVFrame picture;
76
    uint8_t *bitstream_buffer;
77
    unsigned int bitstream_buffer_size;
78
    DSPContext dsp;
Michael Niedermayer's avatar
Michael Niedermayer committed
79 80
}HYuvContext;

Zdenek Kabelac's avatar
Zdenek Kabelac committed
81
static const unsigned char classic_shift_luma[] = {
82 83 84 85 86
  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,
  69,68, 0
};

Zdenek Kabelac's avatar
Zdenek Kabelac committed
87
static const unsigned char classic_shift_chroma[] = {
88 89 90 91 92
  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,
  214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
};

Zdenek Kabelac's avatar
Zdenek Kabelac committed
93
static const unsigned char classic_add_luma[256] = {
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    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
112
static const unsigned char classic_add_chroma[256] = {
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    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,
};

Michael Niedermayer's avatar
Michael Niedermayer committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
    int i;

    for(i=0; i<w-1; i++){
        acc+= src[i];
        dst[i]= acc;
        i++;
        acc+= src[i];
        dst[i]= acc;
    }

    for(; i<w; i++){
        acc+= src[i];
        dst[i]= acc;
    }

    return acc;
}

static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
    int i;
    int r,g,b;
    r= *red;
    g= *green;
    b= *blue;

    for(i=0; i<w; i++){
158 159 160
        b+= src[4*i+B];
        g+= src[4*i+G];
        r+= src[4*i+R];
161

162 163 164
        dst[4*i+B]= b;
        dst[4*i+G]= g;
        dst[4*i+R]= r;
Michael Niedermayer's avatar
Michael Niedermayer committed
165 166 167 168 169 170 171
    }

    *red= r;
    *green= g;
    *blue= b;
}

172
static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
Michael Niedermayer's avatar
Michael Niedermayer committed
173
    int i;
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    if(w<32){
        for(i=0; i<w; i++){
            const int temp= src[i];
            dst[i]= temp - left;
            left= temp;
        }
        return left;
    }else{
        for(i=0; i<16; i++){
            const int temp= src[i];
            dst[i]= temp - left;
            left= temp;
        }
        s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
        return src[w-1];
Michael Niedermayer's avatar
Michael Niedermayer committed
189 190
    }
}
191

Loren Merritt's avatar
Loren Merritt committed
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
    int i;
    int r,g,b;
    r= *red;
    g= *green;
    b= *blue;
    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];
        dst[i*4+R]= rt - r;
        dst[i*4+G]= gt - g;
        dst[i*4+B]= bt - b;
        r = rt;
        g = gt;
        b = bt;
    }
    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];
}

Michael Niedermayer's avatar
Michael Niedermayer committed
215 216
static void read_len_table(uint8_t *dst, GetBitContext *gb){
    int i, val, repeat;
217

Michael Niedermayer's avatar
Michael Niedermayer committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    for(i=0; i<256;){
        repeat= get_bits(gb, 3);
        val   = get_bits(gb, 5);
        if(repeat==0)
            repeat= get_bits(gb, 8);
//printf("%d %d\n", val, repeat);
        while (repeat--)
            dst[i++] = val;
    }
}

static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
    int len, index;
    uint32_t bits=0;

    for(len=32; len>0; len--){
        for(index=0; index<256; index++){
Michael Niedermayer's avatar
Michael Niedermayer committed
235 236
            if(len_table[index]==len)
                dst[index]= bits++;
Michael Niedermayer's avatar
Michael Niedermayer committed
237
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
238
        if(bits & 1){
239
            av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
240 241 242
            return -1;
        }
        bits >>= 1;
Michael Niedermayer's avatar
Michael Niedermayer committed
243 244 245 246
    }
    return 0;
}

247
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
248 249 250
typedef struct {
    uint64_t val;
    int name;
251
} HeapElem;
252

253
static void heap_sift(HeapElem *h, int root, int size)
254 255 256 257 258 259
{
    while(root*2+1 < size) {
        int child = root*2+1;
        if(child < size-1 && h[child].val > h[child+1].val)
            child++;
        if(h[root].val > h[child].val) {
260
            FFSWAP(HeapElem, h[root], h[child]);
261 262 263 264 265 266
            root = child;
        } else
            break;
    }
}

Michael Niedermayer's avatar
Michael Niedermayer committed
267
static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
268
    HeapElem h[size];
Michael Niedermayer's avatar
Michael Niedermayer committed
269
    int up[2*size];
270
    int len[2*size];
Michael Niedermayer's avatar
Michael Niedermayer committed
271
    int offset, i, next;
272

Michael Niedermayer's avatar
Michael Niedermayer committed
273 274
    for(offset=1; ; offset<<=1){
        for(i=0; i<size; i++){
275 276
            h[i].name = i;
            h[i].val = (stats[i] << 8) + offset;
Michael Niedermayer's avatar
Michael Niedermayer committed
277
        }
278 279 280 281 282 283 284 285 286 287 288 289 290
        for(i=size/2-1; i>=0; i--)
            heap_sift(h, i, size);

        for(next=size; next<size*2-1; next++){
            // merge the two smallest entries, and put it back in the heap
            uint64_t min1v = h[0].val;
            up[h[0].name] = next;
            h[0].val = INT64_MAX;
            heap_sift(h, 0, size);
            up[h[0].name] = next;
            h[0].name = next;
            h[0].val += min1v;
            heap_sift(h, 0, size);
Michael Niedermayer's avatar
Michael Niedermayer committed
291
        }
292

293 294 295 296 297
        len[2*size-2] = 0;
        for(i=2*size-3; i>=size; i--)
            len[i] = len[up[i]] + 1;
        for(i=0; i<size; i++) {
            dst[i] = len[up[i]] + 1;
298
            if(dst[i] >= 32) break;
Michael Niedermayer's avatar
Michael Niedermayer committed
299 300 301 302
        }
        if(i==size) break;
    }
}
303
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
304

305
static void generate_joint_tables(HYuvContext *s){
306 307 308
    uint16_t symbols[1<<VLC_BITS];
    uint16_t bits[1<<VLC_BITS];
    uint8_t len[1<<VLC_BITS];
309 310 311 312 313 314
    if(s->bitstream_bpp < 24){
        int p, i, y, u;
        for(p=0; p<3; p++){
            for(i=y=0; y<256; y++){
                int len0 = s->len[0][y];
                int limit = VLC_BITS - len0;
315 316 317 318 319 320 321 322 323 324 325
                if(limit <= 0)
                    continue;
                for(u=0; u<256; u++){
                    int len1 = s->len[p][u];
                    if(len1 > limit)
                        continue;
                    len[i] = len0 + len1;
                    bits[i] = (s->bits[0][y] << len1) + s->bits[p][u];
                    symbols[i] = (y<<8) + u;
                    if(symbols[i] != 0xffff) // reserved to mean "invalid"
                        i++;
326 327 328
                }
            }
            free_vlc(&s->vlc[3+p]);
329
            init_vlc_sparse(&s->vlc[3+p], VLC_BITS, i, len, 1, 1, bits, 2, 2, symbols, 2, 2, 0);
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
    }else{
        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;
        // restrict the range to +/-16 becaues that's pretty much guaranteed to
        // cover all the combinations that fit in 11 bits total, and it doesn't
        // matter if we miss a few rare codes.
        for(i=0, g=-16; g<16; g++){
            int len0 = s->len[p0][g&255];
            int limit0 = VLC_BITS - len0;
            if(limit0 < 2)
                continue;
            for(b=-16; b<16; b++){
                int len1 = s->len[p1][b&255];
                int limit1 = limit0 - len1;
                if(limit1 < 1)
                    continue;
                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)
                        continue;
                    len[i] = len0 + len1 + len2;
                    bits[i] = (code << len2) + s->bits[2][r&255];
                    if(s->decorrelate){
                        map[i][G] = g;
                        map[i][B] = g+b;
                        map[i][R] = g+r;
                    }else{
                        map[i][B] = g;
                        map[i][G] = b;
                        map[i][R] = r;
                    }
                    i++;
                }
            }
        }
        free_vlc(&s->vlc[3]);
        init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0);
371 372 373
    }
}

Michael Niedermayer's avatar
Michael Niedermayer committed
374 375 376
static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
    GetBitContext gb;
    int i;
377

378
    init_get_bits(&gb, src, length*8);
379

Michael Niedermayer's avatar
Michael Niedermayer committed
380 381
    for(i=0; i<3; i++){
        read_len_table(s->len[i], &gb);
382

Michael Niedermayer's avatar
Michael Niedermayer committed
383 384 385 386 387 388 389 390
        if(generate_bits_table(s->bits[i], s->len[i])<0){
            return -1;
        }
#if 0
for(j=0; j<256; j++){
printf("%6X, %2d,  %3d\n", s->bits[i][j], s->len[i][j], j);
}
#endif
391
        free_vlc(&s->vlc[i]);
392
        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
393
    }
394

395 396
    generate_joint_tables(s);

397
    return (get_bits_count(&gb)+7)/8;
Michael Niedermayer's avatar
Michael Niedermayer committed
398 399 400
}

static int read_old_huffman_tables(HYuvContext *s){
401
#if 1
Michael Niedermayer's avatar
Michael Niedermayer committed
402 403 404
    GetBitContext gb;
    int i;

405
    init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
Michael Niedermayer's avatar
Michael Niedermayer committed
406
    read_len_table(s->len[0], &gb);
407
    init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
Michael Niedermayer's avatar
Michael Niedermayer committed
408
    read_len_table(s->len[1], &gb);
409

Michael Niedermayer's avatar
Michael Niedermayer committed
410 411 412 413 414 415 416 417 418
    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];

    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));
    }
    memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
    memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
419

420 421
    for(i=0; i<3; i++){
        free_vlc(&s->vlc[i]);
422
        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0);
423
    }
424

425 426
    generate_joint_tables(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
427 428
    return 0;
#else
429
    av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n");
Michael Niedermayer's avatar
Michael Niedermayer committed
430 431 432 433
    return -1;
#endif
}

434
static av_cold void alloc_temp(HYuvContext *s){
Michael Niedermayer's avatar
Michael Niedermayer committed
435
    int i;
436

Michael Niedermayer's avatar
Michael Niedermayer committed
437 438 439 440 441
    if(s->bitstream_bpp<24){
        for(i=0; i<3; i++){
            s->temp[i]= av_malloc(s->width + 16);
        }
    }else{
Loren Merritt's avatar
Loren Merritt committed
442 443 444
        for(i=0; i<2; i++){
            s->temp[i]= av_malloc(4*s->width + 16);
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
445 446 447
    }
}

448
static av_cold int common_init(AVCodecContext *avctx){
Michael Niedermayer's avatar
Michael Niedermayer committed
449 450 451 452
    HYuvContext *s = avctx->priv_data;

    s->avctx= avctx;
    s->flags= avctx->flags;
453

Michael Niedermayer's avatar
Michael Niedermayer committed
454
    dsputil_init(&s->dsp, avctx);
455

456 457 458
    s->width= avctx->width;
    s->height= avctx->height;
    assert(s->width>0 && s->height>0);
459

460 461 462
    return 0;
}

463
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
464
static av_cold int decode_init(AVCodecContext *avctx)
465 466 467 468
{
    HYuvContext *s = avctx->priv_data;

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

471
    avctx->coded_frame= &s->picture;
472
    s->interlaced= s->height > 288;
Michael Niedermayer's avatar
Michael Niedermayer committed
473

Michael Niedermayer's avatar
Michael Niedermayer committed
474 475 476 477
s->bgr32=1;
//if(avctx->extradata)
//  printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
    if(avctx->extradata_size){
478
        if((avctx->bits_per_coded_sample&7) && avctx->bits_per_coded_sample != 12)
Michael Niedermayer's avatar
Michael Niedermayer committed
479 480 481 482 483
            s->version=1; // do such files exist at all?
        else
            s->version=2;
    }else
        s->version=0;
484

Michael Niedermayer's avatar
Michael Niedermayer committed
485
    if(s->version==2){
486
        int method, interlace;
Michael Niedermayer's avatar
Michael Niedermayer committed
487 488 489 490 491

        method= ((uint8_t*)avctx->extradata)[0];
        s->decorrelate= method&64 ? 1 : 0;
        s->predictor= method&63;
        s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
492
        if(s->bitstream_bpp==0)
493
            s->bitstream_bpp= avctx->bits_per_coded_sample&~7;
494 495
        interlace= (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4;
        s->interlaced= (interlace==1) ? 1 : (interlace==2) ? 0 : s->interlaced;
496
        s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;
497

Michael Niedermayer's avatar
Michael Niedermayer committed
498 499 500
        if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
            return -1;
    }else{
501
        switch(avctx->bits_per_coded_sample&7){
Michael Niedermayer's avatar
Michael Niedermayer committed
502 503 504 505 506 507 508 509 510 511
        case 1:
            s->predictor= LEFT;
            s->decorrelate= 0;
            break;
        case 2:
            s->predictor= LEFT;
            s->decorrelate= 1;
            break;
        case 3:
            s->predictor= PLANE;
512
            s->decorrelate= avctx->bits_per_coded_sample >= 24;
Michael Niedermayer's avatar
Michael Niedermayer committed
513 514 515 516 517 518 519 520 521 522
            break;
        case 4:
            s->predictor= MEDIAN;
            s->decorrelate= 0;
            break;
        default:
            s->predictor= LEFT; //OLD
            s->decorrelate= 0;
            break;
        }
523
        s->bitstream_bpp= avctx->bits_per_coded_sample & ~7;
524
        s->context= 0;
525

Michael Niedermayer's avatar
Michael Niedermayer committed
526 527 528
        if(read_old_huffman_tables(s) < 0)
            return -1;
    }
529

Michael Niedermayer's avatar
Michael Niedermayer committed
530 531 532 533 534 535
    switch(s->bitstream_bpp){
    case 12:
        avctx->pix_fmt = PIX_FMT_YUV420P;
        break;
    case 16:
        if(s->yuy2){
536
            avctx->pix_fmt = PIX_FMT_YUYV422;
Michael Niedermayer's avatar
Michael Niedermayer committed
537 538 539 540 541 542 543
        }else{
            avctx->pix_fmt = PIX_FMT_YUV422P;
        }
        break;
    case 24:
    case 32:
        if(s->bgr32){
544
            avctx->pix_fmt = PIX_FMT_RGB32;
Michael Niedermayer's avatar
Michael Niedermayer committed
545 546 547 548 549 550 551
        }else{
            avctx->pix_fmt = PIX_FMT_BGR24;
        }
        break;
    default:
        assert(0);
    }
552

Michael Niedermayer's avatar
Michael Niedermayer committed
553
    alloc_temp(s);
554

555
//    av_log(NULL, AV_LOG_DEBUG, "pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_coded_sample, s->interlaced);
556

Michael Niedermayer's avatar
Michael Niedermayer committed
557 558
    return 0;
}
559
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
560

561
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
562
static int store_table(HYuvContext *s, uint8_t *len, uint8_t *buf){
Michael Niedermayer's avatar
Michael Niedermayer committed
563
    int i;
564
    int index= 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
565 566 567

    for(i=0; i<256;){
        int val= len[i];
568
        int repeat=0;
569

570 571
        for(; i<256 && len[i]==val && repeat<255; i++)
            repeat++;
572

573
        assert(val < 32 && val >0 && repeat<256 && repeat>0);
Michael Niedermayer's avatar
Michael Niedermayer committed
574
        if(repeat>7){
575 576
            buf[index++]= val;
            buf[index++]= repeat;
Michael Niedermayer's avatar
Michael Niedermayer committed
577
        }else{
578
            buf[index++]= val | (repeat<<5);
Michael Niedermayer's avatar
Michael Niedermayer committed
579 580
        }
    }
581

582
    return index;
Michael Niedermayer's avatar
Michael Niedermayer committed
583 584
}

585
static av_cold int encode_init(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
586 587
{
    HYuvContext *s = avctx->priv_data;
588
    int i, j;
Michael Niedermayer's avatar
Michael Niedermayer committed
589

590
    common_init(avctx);
591

592 593
    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
Michael Niedermayer's avatar
Michael Niedermayer committed
594
    s->version=2;
595

596
    avctx->coded_frame= &s->picture;
597

Michael Niedermayer's avatar
Michael Niedermayer committed
598
    switch(avctx->pix_fmt){
599 600 601
    case PIX_FMT_YUV420P:
        s->bitstream_bpp= 12;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
602 603 604
    case PIX_FMT_YUV422P:
        s->bitstream_bpp= 16;
        break;
Loren Merritt's avatar
Loren Merritt committed
605 606 607
    case PIX_FMT_RGB32:
        s->bitstream_bpp= 24;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
608
    default:
609
        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
610 611
        return -1;
    }
612
    avctx->bits_per_coded_sample= s->bitstream_bpp;
Michael Niedermayer's avatar
Michael Niedermayer committed
613 614
    s->decorrelate= s->bitstream_bpp >= 24;
    s->predictor= avctx->prediction_method;
615
    s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
616 617 618 619 620 621 622
    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");
            return -1;
        }
    }else s->context= 0;
623

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

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

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

Michael Niedermayer's avatar
Michael Niedermayer committed
650 651
    if(avctx->stats_in){
        char *p= avctx->stats_in;
652

Michael Niedermayer's avatar
Michael Niedermayer committed
653 654 655 656 657 658 659 660 661 662 663 664
        for(i=0; i<3; i++)
            for(j=0; j<256; j++)
                s->stats[i][j]= 1;

        for(;;){
            for(i=0; i<3; i++){
                char *next;

                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 668 669 670 671 672
            }
            if(p[0]==0 || p[1]==0 || p[2]==0) break;
        }
    }else{
        for(i=0; i<3; i++)
            for(j=0; j<256; j++){
                int d= FFMIN(j, 256-j);
673

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

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

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

703
//    printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_coded_sample, s->interlaced);
704

Michael Niedermayer's avatar
Michael Niedermayer committed
705 706
    alloc_temp(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
707
    s->picture_number=0;
708

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

713 714 715
/* 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){\
716 717 718 719
    uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\
    if(code != 0xffff){\
        dst0 = code>>8;\
        dst1 = code;\
720 721 722 723 724 725
    }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);\
    }\
}

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

Michael Niedermayer's avatar
Michael Niedermayer committed
729
    count/=2;
730

Michael Niedermayer's avatar
Michael Niedermayer committed
731
    for(i=0; i<count; 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);
Michael Niedermayer's avatar
Michael Niedermayer committed
734 735 736
    }
}

737 738
static void decode_gray_bitstream(HYuvContext *s, int count){
    int i;
739

740
    count/=2;
741

742
    for(i=0; i<count; i++){
743
        READ_2PIX(s->temp[0][2*i  ], s->temp[0][2*i+1], 0);
744 745 746
    }
}

747
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
748
static int encode_422_bitstream(HYuvContext *s, int count){
Michael Niedermayer's avatar
Michael Niedermayer committed
749
    int i;
750

751 752 753 754
    if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 2*4*count){
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
        return -1;
    }
755

756 757 758 759 760 761
#define LOAD4\
            int y0 = s->temp[0][2*i];\
            int y1 = s->temp[0][2*i+1];\
            int u0 = s->temp[1][i];\
            int v0 = s->temp[2][i];

Michael Niedermayer's avatar
Michael Niedermayer committed
762 763 764
    count/=2;
    if(s->flags&CODEC_FLAG_PASS1){
        for(i=0; i<count; i++){
765 766 767 768 769
            LOAD4;
            s->stats[0][y0]++;
            s->stats[1][u0]++;
            s->stats[0][y1]++;
            s->stats[2][v0]++;
Michael Niedermayer's avatar
Michael Niedermayer committed
770
        }
771 772 773 774
    }
    if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)
        return 0;
    if(s->context){
775
        for(i=0; i<count; i++){
776 777 778 779 780 781 782 783 784
            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]);
785
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
786 787
    }else{
        for(i=0; i<count; i++){
788 789 790 791 792
            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
793 794
        }
    }
795
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
796 797
}

798
static int encode_gray_bitstream(HYuvContext *s, int count){
799
    int i;
800

801 802 803 804 805
    if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*count){
        av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
        return -1;
    }

806 807 808 809 810 811 812 813 814 815
#define LOAD2\
            int y0 = s->temp[0][2*i];\
            int y1 = s->temp[0][2*i+1];
#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]);

816 817 818
    count/=2;
    if(s->flags&CODEC_FLAG_PASS1){
        for(i=0; i<count; i++){
819 820
            LOAD2;
            STAT2;
821
        }
822 823 824
    }
    if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)
        return 0;
825

826
    if(s->context){
827
        for(i=0; i<count; i++){
828 829 830
            LOAD2;
            STAT2;
            WRITE2;
831
        }
832 833
    }else{
        for(i=0; i<count; i++){
834 835
            LOAD2;
            WRITE2;
836 837
        }
    }
838
    return 0;
839
}
840
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
841

842
static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorrelate, int alpha){
Michael Niedermayer's avatar
Michael Niedermayer committed
843
    int i;
844 845 846 847 848 849 850 851
    for(i=0; i<count; i++){
        int code = get_vlc2(&s->gb, s->vlc[3].table, VLC_BITS, 1);
        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];
Michael Niedermayer's avatar
Michael Niedermayer committed
852
        }else{
853 854 855
            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
856
        }
857 858 859 860 861 862 863 864 865 866 867
        if(alpha)
            get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
    }
}

static void decode_bgr_bitstream(HYuvContext *s, int count){
    if(s->decorrelate){
        if(s->bitstream_bpp==24)
            decode_bgr_1(s, count, 1, 0);
        else
            decode_bgr_1(s, count, 1, 1);
Michael Niedermayer's avatar
Michael Niedermayer committed
868
    }else{
869 870 871 872
        if(s->bitstream_bpp==24)
            decode_bgr_1(s, count, 0, 0);
        else
            decode_bgr_1(s, count, 0, 1);
Michael Niedermayer's avatar
Michael Niedermayer committed
873 874 875
    }
}

Loren Merritt's avatar
Loren Merritt committed
876 877 878 879 880 881 882 883
static int encode_bgr_bitstream(HYuvContext *s, int count){
    int i;

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

884 885 886
#define LOAD3\
            int g= s->temp[0][4*i+G];\
            int b= (s->temp[0][4*i+B] - g) & 0xff;\
Loren Merritt's avatar
Loren Merritt committed
887
            int r= (s->temp[0][4*i+R] - g) & 0xff;
888 889 890
#define STAT3\
            s->stats[0][b]++;\
            s->stats[1][g]++;\
Loren Merritt's avatar
Loren Merritt committed
891
            s->stats[2][r]++;
892 893 894 895 896 897 898 899 900
#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]);\
            put_bits(&s->pb, s->len[2][r], s->bits[2][r]);

    if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){
        for(i=0; i<count; i++){
            LOAD3;
            STAT3;
Loren Merritt's avatar
Loren Merritt committed
901 902 903
        }
    }else if(s->context || (s->flags&CODEC_FLAG_PASS1)){
        for(i=0; i<count; i++){
904 905 906
            LOAD3;
            STAT3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
907 908 909
        }
    }else{
        for(i=0; i<count; i++){
910 911
            LOAD3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
912 913 914 915 916
        }
    }
    return 0;
}

917
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
918 919
static void draw_slice(HYuvContext *s, int y){
    int h, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
920
    int offset[4];
921 922

    if(s->avctx->draw_horiz_band==NULL)
923
        return;
924

925 926
    h= y - s->last_slice_end;
    y -= h;
927

928 929 930 931 932
    if(s->bitstream_bpp==12){
        cy= y>>1;
    }else{
        cy= y;
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
933 934 935 936 937

    offset[0] = s->picture.linesize[0]*y;
    offset[1] = s->picture.linesize[1]*cy;
    offset[2] = s->picture.linesize[2]*cy;
    offset[3] = 0;
938 939
    emms_c();

940
    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
941

942 943 944
    s->last_slice_end= y + h;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
945
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size){
Michael Niedermayer's avatar
Michael Niedermayer committed
946 947 948 949
    HYuvContext *s = avctx->priv_data;
    const int width= s->width;
    const int width2= s->width>>1;
    const int height= s->height;
Michael Niedermayer's avatar
Michael Niedermayer committed
950
    int fake_ystride, fake_ustride, fake_vstride;
951
    AVFrame * const p= &s->picture;
952
    int table_size= 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
953

954
    AVFrame *picture = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
955

956
    s->bitstream_buffer= av_fast_realloc(s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
Michael Niedermayer's avatar
Michael Niedermayer committed
957

Michael Niedermayer's avatar
Michael Niedermayer committed
958
    s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size/4);
959

960 961 962
    if(p->data[0])
        avctx->release_buffer(avctx, p);

Michael Niedermayer's avatar
Michael Niedermayer committed
963 964
    p->reference= 0;
    if(avctx->get_buffer(avctx, p) < 0){
965
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
966
        return -1;
Michael Niedermayer's avatar
Michael Niedermayer committed
967
    }
968

969 970 971 972 973 974
    if(s->context){
        table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size);
        if(table_size < 0)
            return -1;
    }

Michael Niedermayer's avatar
Michael Niedermayer committed
975 976 977
    if((unsigned)(buf_size-table_size) >= INT_MAX/8)
        return -1;

978
    init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8);
Michael Niedermayer's avatar
Michael Niedermayer committed
979 980 981 982

    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];
983

984
    s->last_slice_end= 0;
985

Michael Niedermayer's avatar
Michael Niedermayer committed
986
    if(s->bitstream_bpp<24){
987
        int y, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
988 989
        int lefty, leftu, leftv;
        int lefttopy, lefttopu, lefttopv;
990

Michael Niedermayer's avatar
Michael Niedermayer committed
991
        if(s->yuy2){
Michael Niedermayer's avatar
Michael Niedermayer committed
992 993 994 995
            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);
996

997
            av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
998 999
            return -1;
        }else{
1000

Michael Niedermayer's avatar
Michael Niedermayer committed
1001 1002 1003 1004
            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);
1005

Michael Niedermayer's avatar
Michael Niedermayer committed
1006 1007 1008 1009
            switch(s->predictor){
            case LEFT:
            case PLANE:
                decode_422_bitstream(s, width-2);
Michael Niedermayer's avatar
Michael Niedermayer committed
1010
                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1011
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1012 1013
                    leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
                    leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1014 1015
                }

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

1019 1020
                    if(s->bitstream_bpp==12){
                        decode_gray_bitstream(s, width);
1021

Michael Niedermayer's avatar
Michael Niedermayer committed
1022
                        ydst= p->data[0] + p->linesize[0]*y;
1023 1024 1025 1026 1027 1028 1029 1030 1031

                        lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
                        if(s->predictor == PLANE){
                            if(y>s->interlaced)
                                s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
                        }
                        y++;
                        if(y>=s->height) break;
                    }
1032

1033
                    draw_slice(s, y);
1034

Michael Niedermayer's avatar
Michael Niedermayer committed
1035 1036 1037
                    ydst= p->data[0] + p->linesize[0]*y;
                    udst= p->data[1] + p->linesize[1]*cy;
                    vdst= p->data[2] + p->linesize[2]*cy;
1038

1039
                    decode_422_bitstream(s, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1040 1041 1042 1043 1044 1045
                    lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
                    if(!(s->flags&CODEC_FLAG_GRAY)){
                        leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
                        leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
                    }
                    if(s->predictor == PLANE){
1046
                        if(cy>s->interlaced){
Michael Niedermayer's avatar
Michael Niedermayer committed
1047 1048 1049 1050 1051 1052 1053 1054
                            s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
                            if(!(s->flags&CODEC_FLAG_GRAY)){
                                s->dsp.add_bytes(udst, udst - fake_ustride, width2);
                                s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
                            }
                        }
                    }
                }
1055
                draw_slice(s, height);
1056

Michael Niedermayer's avatar
Michael Niedermayer committed
1057 1058 1059 1060
                break;
            case MEDIAN:
                /* first line except first 2 pixels is left predicted */
                decode_422_bitstream(s, width-2);
Michael Niedermayer's avatar
Michael Niedermayer committed
1061
                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1062
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1063 1064
                    leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
                    leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1065
                }
1066

1067
                cy=y=1;
1068

Michael Niedermayer's avatar
Michael Niedermayer committed
1069 1070 1071
                /* second line is left predicted for interlaced case */
                if(s->interlaced){
                    decode_422_bitstream(s, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1072
                    lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1073
                    if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1074 1075
                        leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
                        leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1076
                    }
1077
                    y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1078 1079 1080 1081
                }

                /* next 4 pixels are left predicted too */
                decode_422_bitstream(s, 4);
Michael Niedermayer's avatar
Michael Niedermayer committed
1082
                lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1083
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1084 1085
                    leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
                    leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1086 1087 1088
                }

                /* next line except the first 4 pixels is median predicted */
Michael Niedermayer's avatar
Michael Niedermayer committed
1089
                lefttopy= p->data[0][3];
Michael Niedermayer's avatar
Michael Niedermayer committed
1090
                decode_422_bitstream(s, width-4);
1091
                s->dsp.add_hfyu_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
Michael Niedermayer's avatar
Michael Niedermayer committed
1092
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1093 1094
                    lefttopu= p->data[1][1];
                    lefttopv= p->data[2][1];
1095 1096
                    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
1097
                }
1098
                y++; cy++;
1099

1100
                for(; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1101
                    uint8_t *ydst, *udst, *vdst;
1102 1103 1104 1105

                    if(s->bitstream_bpp==12){
                        while(2*cy > y){
                            decode_gray_bitstream(s, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1106
                            ydst= p->data[0] + p->linesize[0]*y;
1107
                            s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
1108 1109 1110 1111
                            y++;
                        }
                        if(y>=height) break;
                    }
1112
                    draw_slice(s, y);
1113

Michael Niedermayer's avatar
Michael Niedermayer committed
1114
                    decode_422_bitstream(s, width);
1115

Michael Niedermayer's avatar
Michael Niedermayer committed
1116 1117 1118
                    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
1119

1120
                    s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
Michael Niedermayer's avatar
Michael Niedermayer committed
1121
                    if(!(s->flags&CODEC_FLAG_GRAY)){
1122 1123
                        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
1124 1125
                    }
                }
1126 1127

                draw_slice(s, height);
Michael Niedermayer's avatar
Michael Niedermayer committed
1128 1129 1130 1131 1132 1133
                break;
            }
        }
    }else{
        int y;
        int leftr, leftg, leftb;
Michael Niedermayer's avatar
Michael Niedermayer committed
1134
        const int last_line= (height-1)*p->linesize[0];
1135

Michael Niedermayer's avatar
Michael Niedermayer committed
1136
        if(s->bitstream_bpp==32){
1137 1138 1139 1140
            skip_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);
Michael Niedermayer's avatar
Michael Niedermayer committed
1141
        }else{
1142 1143 1144
            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);
Michael Niedermayer's avatar
Michael Niedermayer committed
1145 1146
            skip_bits(&s->gb, 8);
        }
1147

Michael Niedermayer's avatar
Michael Niedermayer committed
1148 1149 1150 1151 1152
        if(s->bgr32){
            switch(s->predictor){
            case LEFT:
            case PLANE:
                decode_bgr_bitstream(s, width-1);
Michael Niedermayer's avatar
Michael Niedermayer committed
1153
                add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
Michael Niedermayer's avatar
Michael Niedermayer committed
1154

Diego Biurrun's avatar
Diego Biurrun committed
1155
                for(y=s->height-2; y>=0; y--){ //Yes it is stored upside down.
Michael Niedermayer's avatar
Michael Niedermayer committed
1156
                    decode_bgr_bitstream(s, width);
1157

Michael Niedermayer's avatar
Michael Niedermayer committed
1158
                    add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
Michael Niedermayer's avatar
Michael Niedermayer committed
1159
                    if(s->predictor == PLANE){
1160
                        if((y&s->interlaced)==0 && y<s->height-1-s->interlaced){
1161
                            s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
Michael Niedermayer's avatar
Michael Niedermayer committed
1162
                                             p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
Michael Niedermayer's avatar
Michael Niedermayer committed
1163 1164 1165
                        }
                    }
                }
1166
                draw_slice(s, height); // just 1 large slice as this is not possible in reverse order
Michael Niedermayer's avatar
Michael Niedermayer committed
1167 1168
                break;
            default:
1169
                av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1170 1171 1172
            }
        }else{

1173
            av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1174 1175 1176 1177
            return -1;
        }
    }
    emms_c();
1178

Michael Niedermayer's avatar
Michael Niedermayer committed
1179
    *picture= *p;
1180
    *data_size = sizeof(AVFrame);
1181

1182
    return (get_bits_count(&s->gb)+31)/32*4 + table_size;
Michael Niedermayer's avatar
Michael Niedermayer committed
1183
}
1184
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1185

1186 1187
static int common_end(HYuvContext *s){
    int i;
1188

1189 1190 1191 1192 1193 1194
    for(i=0; i<3; i++){
        av_freep(&s->temp[i]);
    }
    return 0;
}

1195
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
1196
static av_cold int decode_end(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
1197 1198 1199
{
    HYuvContext *s = avctx->priv_data;
    int i;
1200

1201 1202
    common_end(s);
    av_freep(&s->bitstream_buffer);
1203

Oliver Pfister's avatar
Oliver Pfister committed
1204
    for(i=0; i<6; i++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1205 1206
        free_vlc(&s->vlc[i]);
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
1207

Michael Niedermayer's avatar
Michael Niedermayer committed
1208 1209
    return 0;
}
1210
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1211

1212
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
Michael Niedermayer's avatar
Michael Niedermayer committed
1213 1214
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
    HYuvContext *s = avctx->priv_data;
1215
    AVFrame *pict = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
1216 1217 1218 1219 1220 1221
    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];
1222
    AVFrame * const p= &s->picture;
1223
    int i, j, size=0;
Michael Niedermayer's avatar
Michael Niedermayer committed
1224

Michael Niedermayer's avatar
Michael Niedermayer committed
1225
    *p = *pict;
Michael Niedermayer's avatar
Michael Niedermayer committed
1226 1227
    p->pict_type= FF_I_TYPE;
    p->key_frame= 1;
1228

1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
    if(s->context){
        for(i=0; i<3; i++){
            generate_len_table(s->len[i], s->stats[i], 256);
            if(generate_bits_table(s->bits[i], s->len[i])<0)
                return -1;
            size+= store_table(s, s->len[i], &buf[size]);
        }

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

    init_put_bits(&s->pb, buf+size, buf_size-size);

1244 1245
    if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
        int lefty, leftu, leftv, y, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
1246

Michael Niedermayer's avatar
Michael Niedermayer committed
1247 1248 1249 1250
        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]);
1251

Michael Niedermayer's avatar
Michael Niedermayer committed
1252 1253 1254
        lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
        leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
        leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
1255

Michael Niedermayer's avatar
Michael Niedermayer committed
1256
        encode_422_bitstream(s, width-2);
1257

Michael Niedermayer's avatar
Michael Niedermayer committed
1258 1259
        if(s->predictor==MEDIAN){
            int lefttopy, lefttopu, lefttopv;
1260
            cy=y=1;
Michael Niedermayer's avatar
Michael Niedermayer committed
1261
            if(s->interlaced){
Michael Niedermayer's avatar
Michael Niedermayer committed
1262 1263 1264
                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);
1265

Michael Niedermayer's avatar
Michael Niedermayer committed
1266
                encode_422_bitstream(s, width);
1267
                y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1268
            }
1269

Michael Niedermayer's avatar
Michael Niedermayer committed
1270
            lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
1271 1272
            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);
1273

Michael Niedermayer's avatar
Michael Niedermayer committed
1274
            encode_422_bitstream(s, 4);
1275

Michael Niedermayer's avatar
Michael Niedermayer committed
1276 1277 1278
            lefttopy= p->data[0][3];
            lefttopu= p->data[1][1];
            lefttopv= p->data[2][1];
1279 1280 1281
            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);
Michael Niedermayer's avatar
Michael Niedermayer committed
1282
            encode_422_bitstream(s, width-4);
1283
            y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1284

1285
            for(; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1286
                uint8_t *ydst, *udst, *vdst;
1287

1288 1289
                if(s->bitstream_bpp==12){
                    while(2*cy > y){
Michael Niedermayer's avatar
Michael Niedermayer committed
1290
                        ydst= p->data[0] + p->linesize[0]*y;
1291
                        s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1292 1293 1294 1295 1296
                        encode_gray_bitstream(s, width);
                        y++;
                    }
                    if(y>=height) break;
                }
Michael Niedermayer's avatar
Michael Niedermayer committed
1297 1298 1299
                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
1300

1301 1302 1303
                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
1304 1305 1306 1307

                encode_422_bitstream(s, width);
            }
        }else{
1308
            for(cy=y=1; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1309
                uint8_t *ydst, *udst, *vdst;
1310

1311 1312
                /* encode a luma only line & y++ */
                if(s->bitstream_bpp==12){
Michael Niedermayer's avatar
Michael Niedermayer committed
1313
                    ydst= p->data[0] + p->linesize[0]*y;
1314 1315

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

1318
                        lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1319
                    }else{
1320
                        lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1321 1322 1323 1324 1325
                    }
                    encode_gray_bitstream(s, width);
                    y++;
                    if(y>=height) break;
                }
1326

Michael Niedermayer's avatar
Michael Niedermayer committed
1327 1328 1329
                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
1330

1331
                if(s->predictor == PLANE && s->interlaced < cy){
1332 1333
                    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
1334
                    s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2);
Michael Niedermayer's avatar
Michael Niedermayer committed
1335

1336 1337
                    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);
Michael Niedermayer's avatar
Michael Niedermayer committed
1338
                    leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1339
                }else{
1340 1341 1342
                    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
1343 1344 1345 1346
                }

                encode_422_bitstream(s, width);
            }
1347
        }
Loren Merritt's avatar
Loren Merritt committed
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
    }else if(avctx->pix_fmt == PIX_FMT_RGB32){
        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[R]);
        put_bits(&s->pb, 8, leftg= data[G]);
        put_bits(&s->pb, 8, leftb= data[B]);
        put_bits(&s->pb, 8, 0);

        sub_left_prediction_bgr32(s, s->temp[0], data+4, width-1, &leftr, &leftg, &leftb);
        encode_bgr_bitstream(s, width-1);

        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*4);
                sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb);
            }else{
                sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb);
            }
            encode_bgr_bitstream(s, width);
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
1373
    }else{
1374
        av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1375 1376
    }
    emms_c();
1377

1378 1379
    size+= (put_bits_count(&s->pb)+31)/8;
    size/= 4;
1380

Michael Niedermayer's avatar
Michael Niedermayer committed
1381 1382 1383
    if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
        int j;
        char *p= avctx->stats_out;
Michael Niedermayer's avatar
Michael Niedermayer committed
1384
        char *end= p + 1024*30;
Michael Niedermayer's avatar
Michael Niedermayer committed
1385 1386
        for(i=0; i<3; i++){
            for(j=0; j<256; j++){
1387
                snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]);
Michael Niedermayer's avatar
Michael Niedermayer committed
1388 1389 1390
                p+= strlen(p);
                s->stats[i][j]= 0;
            }
Michael Niedermayer's avatar
Michael Niedermayer committed
1391
            snprintf(p, end-p, "\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1392 1393
            p++;
        }
1394 1395
    } else
        avctx->stats_out[0] = '\0';
1396
    if(!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)){
1397
        flush_put_bits(&s->pb);
Michael Niedermayer's avatar
Michael Niedermayer committed
1398
        s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
Michael Niedermayer's avatar
Michael Niedermayer committed
1399
    }
1400

Michael Niedermayer's avatar
Michael Niedermayer committed
1401
    s->picture_number++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1402

Michael Niedermayer's avatar
Michael Niedermayer committed
1403 1404 1405
    return size*4;
}

1406
static av_cold int encode_end(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
1407
{
1408
    HYuvContext *s = avctx->priv_data;
1409

1410
    common_end(s);
Michael Niedermayer's avatar
Michael Niedermayer committed
1411 1412 1413

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

Michael Niedermayer's avatar
Michael Niedermayer committed
1415 1416
    return 0;
}
1417
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1418

1419
#if CONFIG_HUFFYUV_DECODER
Michael Niedermayer's avatar
Michael Niedermayer committed
1420 1421 1422 1423 1424 1425 1426 1427 1428
AVCodec huffyuv_decoder = {
    "huffyuv",
    CODEC_TYPE_VIDEO,
    CODEC_ID_HUFFYUV,
    sizeof(HYuvContext),
    decode_init,
    NULL,
    decode_end,
    decode_frame,
1429
    CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1430
    NULL,
1431
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
Michael Niedermayer's avatar
Michael Niedermayer committed
1432
};
1433
#endif
Michael Niedermayer's avatar
Michael Niedermayer committed
1434

1435
#if CONFIG_FFVHUFF_DECODER
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445
AVCodec ffvhuff_decoder = {
    "ffvhuff",
    CODEC_TYPE_VIDEO,
    CODEC_ID_FFVHUFF,
    sizeof(HYuvContext),
    decode_init,
    NULL,
    decode_end,
    decode_frame,
    CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1446
    NULL,
1447
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
1448
};
1449
#endif
1450

1451
#if CONFIG_HUFFYUV_ENCODER
Michael Niedermayer's avatar
Michael Niedermayer committed
1452 1453 1454 1455 1456 1457 1458 1459
AVCodec huffyuv_encoder = {
    "huffyuv",
    CODEC_TYPE_VIDEO,
    CODEC_ID_HUFFYUV,
    sizeof(HYuvContext),
    encode_init,
    encode_frame,
    encode_end,
1460
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
1461
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
Michael Niedermayer's avatar
Michael Niedermayer committed
1462
};
1463
#endif
1464

1465
#if CONFIG_FFVHUFF_ENCODER
1466 1467 1468 1469 1470 1471 1472 1473
AVCodec ffvhuff_encoder = {
    "ffvhuff",
    CODEC_TYPE_VIDEO,
    CODEC_ID_FFVHUFF,
    sizeof(HYuvContext),
    encode_init,
    encode_frame,
    encode_end,
1474
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
1475
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
1476
};
1477
#endif