huffyuv.c 46.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 28 29
/**
 * @file huffyuv.c
 * 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 158 159 160
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_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
    int i;
    uint8_t l, lt;

    l= *left;
    lt= *left_top;

    for(i=0; i<w; i++){
        l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
        lt= src1[i];
        dst[i]= l;
161
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
162 163 164 165

    *left= l;
    *left_top= lt;
}
166

Michael Niedermayer's avatar
Michael Niedermayer committed
167 168 169 170 171 172 173 174
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++){
175 176 177
        b+= src[4*i+B];
        g+= src[4*i+G];
        r+= src[4*i+R];
178

179 180 181
        dst[4*i+B]= b;
        dst[4*i+G]= g;
        dst[4*i+R]= r;
Michael Niedermayer's avatar
Michael Niedermayer committed
182 183 184 185 186 187 188
    }

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

189
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
190
    int i;
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
    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
206 207
    }
}
208

Loren Merritt's avatar
Loren Merritt committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
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
232 233
static void read_len_table(uint8_t *dst, GetBitContext *gb){
    int i, val, repeat;
234

Michael Niedermayer's avatar
Michael Niedermayer committed
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
    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
252 253
            if(len_table[index]==len)
                dst[index]= bits++;
Michael Niedermayer's avatar
Michael Niedermayer committed
254
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
255
        if(bits & 1){
256
            av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
257 258 259
            return -1;
        }
        bits >>= 1;
Michael Niedermayer's avatar
Michael Niedermayer committed
260 261 262 263
    }
    return 0;
}

264
#ifdef CONFIG_ENCODERS
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
typedef struct {
    uint64_t val;
    int name;
} heap_elem_t;

static void heap_sift(heap_elem_t *h, int root, int size)
{
    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) {
            FFSWAP(heap_elem_t, h[root], h[child]);
            root = child;
        } else
            break;
    }
}

Michael Niedermayer's avatar
Michael Niedermayer committed
284
static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
285
    heap_elem_t h[size];
Michael Niedermayer's avatar
Michael Niedermayer committed
286
    int up[2*size];
287
    int len[2*size];
Michael Niedermayer's avatar
Michael Niedermayer committed
288
    int offset, i, next;
289

Michael Niedermayer's avatar
Michael Niedermayer committed
290 291
    for(offset=1; ; offset<<=1){
        for(i=0; i<size; i++){
292 293
            h[i].name = i;
            h[i].val = (stats[i] << 8) + offset;
Michael Niedermayer's avatar
Michael Niedermayer committed
294
        }
295 296 297 298 299 300 301 302 303 304 305 306 307
        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
308
        }
309

310 311 312 313 314
        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;
315
            if(dst[i] >= 32) break;
Michael Niedermayer's avatar
Michael Niedermayer committed
316 317 318 319
        }
        if(i==size) break;
    }
}
320
#endif /* CONFIG_ENCODERS */
Michael Niedermayer's avatar
Michael Niedermayer committed
321

322
static void generate_joint_tables(HYuvContext *s){
323 324 325
    uint16_t symbols[1<<VLC_BITS];
    uint16_t bits[1<<VLC_BITS];
    uint8_t len[1<<VLC_BITS];
326 327 328 329 330 331
    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;
332 333 334 335 336 337 338 339 340 341 342
                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++;
343 344 345
                }
            }
            free_vlc(&s->vlc[3+p]);
346
            init_vlc_sparse(&s->vlc[3+p], VLC_BITS, i, len, 1, 1, bits, 2, 2, symbols, 2, 2, 0);
347
        }
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
    }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);
388 389 390
    }
}

Michael Niedermayer's avatar
Michael Niedermayer committed
391 392 393
static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
    GetBitContext gb;
    int i;
394

395
    init_get_bits(&gb, src, length*8);
396

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

Michael Niedermayer's avatar
Michael Niedermayer committed
400 401 402 403 404 405 406 407
        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
408
        free_vlc(&s->vlc[i]);
409
        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
410
    }
411

412 413
    generate_joint_tables(s);

414
    return (get_bits_count(&gb)+7)/8;
Michael Niedermayer's avatar
Michael Niedermayer committed
415 416 417
}

static int read_old_huffman_tables(HYuvContext *s){
418
#if 1
Michael Niedermayer's avatar
Michael Niedermayer committed
419 420 421
    GetBitContext gb;
    int i;

422
    init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
Michael Niedermayer's avatar
Michael Niedermayer committed
423
    read_len_table(s->len[0], &gb);
424
    init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
Michael Niedermayer's avatar
Michael Niedermayer committed
425
    read_len_table(s->len[1], &gb);
426

Michael Niedermayer's avatar
Michael Niedermayer committed
427 428 429 430 431 432 433 434 435
    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));
436

437 438
    for(i=0; i<3; i++){
        free_vlc(&s->vlc[i]);
439
        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0);
440
    }
441

442 443
    generate_joint_tables(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
444 445
    return 0;
#else
446
    av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n");
Michael Niedermayer's avatar
Michael Niedermayer committed
447 448 449 450
    return -1;
#endif
}

Michael Niedermayer's avatar
Michael Niedermayer committed
451 452
static void alloc_temp(HYuvContext *s){
    int i;
453

Michael Niedermayer's avatar
Michael Niedermayer committed
454 455 456 457 458
    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
459 460 461
        for(i=0; i<2; i++){
            s->temp[i]= av_malloc(4*s->width + 16);
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
462 463 464
    }
}

465
static int common_init(AVCodecContext *avctx){
Michael Niedermayer's avatar
Michael Niedermayer committed
466 467 468 469
    HYuvContext *s = avctx->priv_data;

    s->avctx= avctx;
    s->flags= avctx->flags;
470

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

473 474 475
    s->width= avctx->width;
    s->height= avctx->height;
    assert(s->width>0 && s->height>0);
476

477 478 479
    return 0;
}

480
#ifdef CONFIG_DECODERS
481
static av_cold int decode_init(AVCodecContext *avctx)
482 483 484 485
{
    HYuvContext *s = avctx->priv_data;

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

488
    avctx->coded_frame= &s->picture;
489
    s->interlaced= s->height > 288;
Michael Niedermayer's avatar
Michael Niedermayer committed
490

Michael Niedermayer's avatar
Michael Niedermayer committed
491 492 493 494
s->bgr32=1;
//if(avctx->extradata)
//  printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
    if(avctx->extradata_size){
495
        if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
Michael Niedermayer's avatar
Michael Niedermayer committed
496 497 498 499 500
            s->version=1; // do such files exist at all?
        else
            s->version=2;
    }else
        s->version=0;
501

Michael Niedermayer's avatar
Michael Niedermayer committed
502
    if(s->version==2){
503
        int method, interlace;
Michael Niedermayer's avatar
Michael Niedermayer committed
504 505 506 507 508

        method= ((uint8_t*)avctx->extradata)[0];
        s->decorrelate= method&64 ? 1 : 0;
        s->predictor= method&63;
        s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
509
        if(s->bitstream_bpp==0)
Michael Niedermayer's avatar
Michael Niedermayer committed
510
            s->bitstream_bpp= avctx->bits_per_sample&~7;
511 512
        interlace= (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4;
        s->interlaced= (interlace==1) ? 1 : (interlace==2) ? 0 : s->interlaced;
513
        s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;
514

Michael Niedermayer's avatar
Michael Niedermayer committed
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
        if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
            return -1;
    }else{
        switch(avctx->bits_per_sample&7){
        case 1:
            s->predictor= LEFT;
            s->decorrelate= 0;
            break;
        case 2:
            s->predictor= LEFT;
            s->decorrelate= 1;
            break;
        case 3:
            s->predictor= PLANE;
            s->decorrelate= avctx->bits_per_sample >= 24;
            break;
        case 4:
            s->predictor= MEDIAN;
            s->decorrelate= 0;
            break;
        default:
            s->predictor= LEFT; //OLD
            s->decorrelate= 0;
            break;
        }
        s->bitstream_bpp= avctx->bits_per_sample & ~7;
541
        s->context= 0;
542

Michael Niedermayer's avatar
Michael Niedermayer committed
543 544 545
        if(read_old_huffman_tables(s) < 0)
            return -1;
    }
546

Michael Niedermayer's avatar
Michael Niedermayer committed
547 548 549 550 551 552
    switch(s->bitstream_bpp){
    case 12:
        avctx->pix_fmt = PIX_FMT_YUV420P;
        break;
    case 16:
        if(s->yuy2){
553
            avctx->pix_fmt = PIX_FMT_YUYV422;
Michael Niedermayer's avatar
Michael Niedermayer committed
554 555 556 557 558 559 560
        }else{
            avctx->pix_fmt = PIX_FMT_YUV422P;
        }
        break;
    case 24:
    case 32:
        if(s->bgr32){
561
            avctx->pix_fmt = PIX_FMT_RGB32;
Michael Niedermayer's avatar
Michael Niedermayer committed
562 563 564 565 566 567 568
        }else{
            avctx->pix_fmt = PIX_FMT_BGR24;
        }
        break;
    default:
        assert(0);
    }
569

Michael Niedermayer's avatar
Michael Niedermayer committed
570
    alloc_temp(s);
571

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

Michael Niedermayer's avatar
Michael Niedermayer committed
574 575
    return 0;
}
576
#endif
Michael Niedermayer's avatar
Michael Niedermayer committed
577

578
#ifdef CONFIG_ENCODERS
579
static int store_table(HYuvContext *s, uint8_t *len, uint8_t *buf){
Michael Niedermayer's avatar
Michael Niedermayer committed
580
    int i;
581
    int index= 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
582 583 584

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

587 588
        for(; i<256 && len[i]==val && repeat<255; i++)
            repeat++;
589

590
        assert(val < 32 && val >0 && repeat<256 && repeat>0);
Michael Niedermayer's avatar
Michael Niedermayer committed
591
        if(repeat>7){
592 593
            buf[index++]= val;
            buf[index++]= repeat;
Michael Niedermayer's avatar
Michael Niedermayer committed
594
        }else{
595
            buf[index++]= val | (repeat<<5);
Michael Niedermayer's avatar
Michael Niedermayer committed
596 597
        }
    }
598

599
    return index;
Michael Niedermayer's avatar
Michael Niedermayer committed
600 601
}

602
static av_cold int encode_init(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
603 604
{
    HYuvContext *s = avctx->priv_data;
605
    int i, j;
Michael Niedermayer's avatar
Michael Niedermayer committed
606

607
    common_init(avctx);
608

609 610
    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
611
    s->version=2;
612

613
    avctx->coded_frame= &s->picture;
614

Michael Niedermayer's avatar
Michael Niedermayer committed
615
    switch(avctx->pix_fmt){
616 617 618
    case PIX_FMT_YUV420P:
        s->bitstream_bpp= 12;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
619 620 621
    case PIX_FMT_YUV422P:
        s->bitstream_bpp= 16;
        break;
Loren Merritt's avatar
Loren Merritt committed
622 623 624
    case PIX_FMT_RGB32:
        s->bitstream_bpp= 24;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
625
    default:
626
        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
627 628 629 630 631
        return -1;
    }
    avctx->bits_per_sample= s->bitstream_bpp;
    s->decorrelate= s->bitstream_bpp >= 24;
    s->predictor= avctx->prediction_method;
632
    s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
633 634 635 636 637 638 639
    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;
640

641 642 643 644 645 646 647 648 649
    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;
        }
650
        if(s->interlaced != ( s->height > 288 ))
651 652
            av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n");
    }
653

Loren Merritt's avatar
Loren Merritt committed
654 655 656 657 658 659
    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
660
    ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
661
    ((uint8_t*)avctx->extradata)[2]= s->interlaced ? 0x10 : 0x20;
662 663
    if(s->context)
        ((uint8_t*)avctx->extradata)[2]|= 0x40;
Michael Niedermayer's avatar
Michael Niedermayer committed
664 665
    ((uint8_t*)avctx->extradata)[3]= 0;
    s->avctx->extradata_size= 4;
666

Michael Niedermayer's avatar
Michael Niedermayer committed
667 668
    if(avctx->stats_in){
        char *p= avctx->stats_in;
669

Michael Niedermayer's avatar
Michael Niedermayer committed
670 671 672 673 674 675 676 677 678 679 680 681
        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;
682
                }
Michael Niedermayer's avatar
Michael Niedermayer committed
683 684 685 686 687 688 689
            }
            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);
690

Michael Niedermayer's avatar
Michael Niedermayer committed
691 692 693
                s->stats[i][j]= 100000000/(d+1);
            }
    }
694

Michael Niedermayer's avatar
Michael Niedermayer committed
695 696 697 698 699 700
    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;
        }
701

702 703
        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
704 705
    }

706 707
    if(s->context){
        for(i=0; i<3; i++){
708
            int pels = s->width*s->height / (i?40:10);
709 710 711 712 713 714 715 716 717 718
            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;
    }
719

Michael Niedermayer's avatar
Michael Niedermayer committed
720
//    printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
721

Michael Niedermayer's avatar
Michael Niedermayer committed
722 723
    alloc_temp(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
724
    s->picture_number=0;
725

Michael Niedermayer's avatar
Michael Niedermayer committed
726 727
    return 0;
}
728
#endif /* CONFIG_ENCODERS */
Michael Niedermayer's avatar
Michael Niedermayer committed
729

730 731 732
/* 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){\
733 734 735 736
    uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\
    if(code != 0xffff){\
        dst0 = code>>8;\
        dst1 = code;\
737 738 739 740 741 742
    }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
743 744
static void decode_422_bitstream(HYuvContext *s, int count){
    int i;
745

Michael Niedermayer's avatar
Michael Niedermayer committed
746
    count/=2;
747

Michael Niedermayer's avatar
Michael Niedermayer committed
748
    for(i=0; i<count; i++){
749 750
        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
751 752 753
    }
}

754 755
static void decode_gray_bitstream(HYuvContext *s, int count){
    int i;
756

757
    count/=2;
758

759
    for(i=0; i<count; i++){
760
        READ_2PIX(s->temp[0][2*i  ], s->temp[0][2*i+1], 0);
761 762 763
    }
}

764
#ifdef CONFIG_ENCODERS
765
static int encode_422_bitstream(HYuvContext *s, int count){
Michael Niedermayer's avatar
Michael Niedermayer committed
766
    int i;
767

768 769 770 771
    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;
    }
772

773 774 775 776 777 778
#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
779 780 781
    count/=2;
    if(s->flags&CODEC_FLAG_PASS1){
        for(i=0; i<count; i++){
782 783 784 785 786
            LOAD4;
            s->stats[0][y0]++;
            s->stats[1][u0]++;
            s->stats[0][y1]++;
            s->stats[2][v0]++;
Michael Niedermayer's avatar
Michael Niedermayer committed
787
        }
788 789 790 791
    }
    if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)
        return 0;
    if(s->context){
792
        for(i=0; i<count; i++){
793 794 795 796 797 798 799 800 801
            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]);
802
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
803 804
    }else{
        for(i=0; i<count; i++){
805 806 807 808 809
            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
810 811
        }
    }
812
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
813 814
}

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

818 819 820 821 822
    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;
    }

823 824 825 826 827 828 829 830 831 832
#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]);

833 834 835
    count/=2;
    if(s->flags&CODEC_FLAG_PASS1){
        for(i=0; i<count; i++){
836 837
            LOAD2;
            STAT2;
838
        }
839 840 841
    }
    if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)
        return 0;
842

843
    if(s->context){
844
        for(i=0; i<count; i++){
845 846 847
            LOAD2;
            STAT2;
            WRITE2;
848
        }
849 850
    }else{
        for(i=0; i<count; i++){
851 852
            LOAD2;
            WRITE2;
853 854
        }
    }
855
    return 0;
856
}
857
#endif /* CONFIG_ENCODERS */
858

859
static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorrelate, int alpha){
Michael Niedermayer's avatar
Michael Niedermayer committed
860
    int i;
861 862 863 864 865 866 867 868
    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
869
        }else{
870 871 872
            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
873
        }
874 875 876 877 878 879 880 881 882 883 884
        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
885
    }else{
886 887 888 889
        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
890 891 892
    }
}

Loren Merritt's avatar
Loren Merritt committed
893 894 895 896 897 898 899 900
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;
    }

901 902 903
#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
904
            int r= (s->temp[0][4*i+R] - g) & 0xff;
905 906 907
#define STAT3\
            s->stats[0][b]++;\
            s->stats[1][g]++;\
Loren Merritt's avatar
Loren Merritt committed
908
            s->stats[2][r]++;
909 910 911 912 913 914 915 916 917
#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
918 919 920
        }
    }else if(s->context || (s->flags&CODEC_FLAG_PASS1)){
        for(i=0; i<count; i++){
921 922 923
            LOAD3;
            STAT3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
924 925 926
        }
    }else{
        for(i=0; i<count; i++){
927 928
            LOAD3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
929 930 931 932 933
        }
    }
    return 0;
}

934
#ifdef CONFIG_DECODERS
935 936
static void draw_slice(HYuvContext *s, int y){
    int h, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
937
    int offset[4];
938 939

    if(s->avctx->draw_horiz_band==NULL)
940
        return;
941

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

945 946 947 948 949
    if(s->bitstream_bpp==12){
        cy= y>>1;
    }else{
        cy= y;
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
950 951 952 953 954

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

957
    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
958

959 960 961
    s->last_slice_end= y + h;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
962
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
963 964 965 966
    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
967
    int fake_ystride, fake_ustride, fake_vstride;
968
    AVFrame * const p= &s->picture;
969
    int table_size= 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
970

971
    AVFrame *picture = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
972

973
    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
974

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

977 978 979
    if(p->data[0])
        avctx->release_buffer(avctx, p);

Michael Niedermayer's avatar
Michael Niedermayer committed
980 981
    p->reference= 0;
    if(avctx->get_buffer(avctx, p) < 0){
982
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
983
        return -1;
Michael Niedermayer's avatar
Michael Niedermayer committed
984
    }
985

986 987 988 989 990 991
    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
992 993 994
    if((unsigned)(buf_size-table_size) >= INT_MAX/8)
        return -1;

995
    init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8);
Michael Niedermayer's avatar
Michael Niedermayer committed
996 997 998 999

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

1001
    s->last_slice_end= 0;
1002

Michael Niedermayer's avatar
Michael Niedermayer committed
1003
    if(s->bitstream_bpp<24){
1004
        int y, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
1005 1006
        int lefty, leftu, leftv;
        int lefttopy, lefttopu, lefttopv;
1007

Michael Niedermayer's avatar
Michael Niedermayer committed
1008
        if(s->yuy2){
Michael Niedermayer's avatar
Michael Niedermayer committed
1009 1010 1011 1012
            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);
1013

1014
            av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1015 1016
            return -1;
        }else{
1017

Michael Niedermayer's avatar
Michael Niedermayer committed
1018 1019 1020 1021
            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);
1022

Michael Niedermayer's avatar
Michael Niedermayer committed
1023 1024 1025 1026
            switch(s->predictor){
            case LEFT:
            case PLANE:
                decode_422_bitstream(s, width-2);
Michael Niedermayer's avatar
Michael Niedermayer committed
1027
                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1028
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1029 1030
                    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
1031 1032
                }

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

1036 1037
                    if(s->bitstream_bpp==12){
                        decode_gray_bitstream(s, width);
1038

Michael Niedermayer's avatar
Michael Niedermayer committed
1039
                        ydst= p->data[0] + p->linesize[0]*y;
1040 1041 1042 1043 1044 1045 1046 1047 1048

                        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;
                    }
1049

1050
                    draw_slice(s, y);
1051

Michael Niedermayer's avatar
Michael Niedermayer committed
1052 1053 1054
                    ydst= p->data[0] + p->linesize[0]*y;
                    udst= p->data[1] + p->linesize[1]*cy;
                    vdst= p->data[2] + p->linesize[2]*cy;
1055

1056
                    decode_422_bitstream(s, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1057 1058 1059 1060 1061 1062
                    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){
1063
                        if(cy>s->interlaced){
Michael Niedermayer's avatar
Michael Niedermayer committed
1064 1065 1066 1067 1068 1069 1070 1071
                            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);
                            }
                        }
                    }
                }
1072
                draw_slice(s, height);
1073

Michael Niedermayer's avatar
Michael Niedermayer committed
1074 1075 1076 1077
                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
1078
                lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1079
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1080 1081
                    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
1082
                }
1083

1084
                cy=y=1;
1085

Michael Niedermayer's avatar
Michael Niedermayer committed
1086 1087 1088
                /* second line is left predicted for interlaced case */
                if(s->interlaced){
                    decode_422_bitstream(s, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1089
                    lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1090
                    if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1091 1092
                        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
1093
                    }
1094
                    y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1095 1096 1097 1098
                }

                /* next 4 pixels are left predicted too */
                decode_422_bitstream(s, 4);
Michael Niedermayer's avatar
Michael Niedermayer committed
1099
                lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1100
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1101 1102
                    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
1103 1104 1105
                }

                /* next line except the first 4 pixels is median predicted */
Michael Niedermayer's avatar
Michael Niedermayer committed
1106
                lefttopy= p->data[0][3];
Michael Niedermayer's avatar
Michael Niedermayer committed
1107
                decode_422_bitstream(s, width-4);
Michael Niedermayer's avatar
Michael Niedermayer committed
1108
                add_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
1109
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1110 1111 1112 1113
                    lefttopu= p->data[1][1];
                    lefttopv= p->data[2][1];
                    add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
                    add_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
1114
                }
1115
                y++; cy++;
1116

1117
                for(; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1118
                    uint8_t *ydst, *udst, *vdst;
1119 1120 1121 1122

                    if(s->bitstream_bpp==12){
                        while(2*cy > y){
                            decode_gray_bitstream(s, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1123
                            ydst= p->data[0] + p->linesize[0]*y;
1124 1125 1126 1127 1128
                            add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
                            y++;
                        }
                        if(y>=height) break;
                    }
1129
                    draw_slice(s, y);
1130

Michael Niedermayer's avatar
Michael Niedermayer committed
1131
                    decode_422_bitstream(s, width);
1132

Michael Niedermayer's avatar
Michael Niedermayer committed
1133 1134 1135
                    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
1136 1137 1138 1139 1140 1141 1142

                    add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
                    if(!(s->flags&CODEC_FLAG_GRAY)){
                        add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
                        add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
                    }
                }
1143 1144

                draw_slice(s, height);
Michael Niedermayer's avatar
Michael Niedermayer committed
1145 1146 1147 1148 1149 1150
                break;
            }
        }
    }else{
        int y;
        int leftr, leftg, leftb;
Michael Niedermayer's avatar
Michael Niedermayer committed
1151
        const int last_line= (height-1)*p->linesize[0];
1152

Michael Niedermayer's avatar
Michael Niedermayer committed
1153
        if(s->bitstream_bpp==32){
1154 1155 1156 1157
            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
1158
        }else{
1159 1160 1161
            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
1162 1163
            skip_bits(&s->gb, 8);
        }
1164

Michael Niedermayer's avatar
Michael Niedermayer committed
1165 1166 1167 1168 1169
        if(s->bgr32){
            switch(s->predictor){
            case LEFT:
            case PLANE:
                decode_bgr_bitstream(s, width-1);
Michael Niedermayer's avatar
Michael Niedermayer committed
1170
                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
1171

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

Michael Niedermayer's avatar
Michael Niedermayer committed
1175
                    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
1176
                    if(s->predictor == PLANE){
1177
                        if((y&s->interlaced)==0 && y<s->height-1-s->interlaced){
1178
                            s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
Michael Niedermayer's avatar
Michael Niedermayer committed
1179
                                             p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
Michael Niedermayer's avatar
Michael Niedermayer committed
1180 1181 1182
                        }
                    }
                }
1183
                draw_slice(s, height); // just 1 large slice as this is not possible in reverse order
Michael Niedermayer's avatar
Michael Niedermayer committed
1184 1185
                break;
            default:
1186
                av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1187 1188 1189
            }
        }else{

1190
            av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1191 1192 1193 1194
            return -1;
        }
    }
    emms_c();
1195

Michael Niedermayer's avatar
Michael Niedermayer committed
1196
    *picture= *p;
1197
    *data_size = sizeof(AVFrame);
1198

1199
    return (get_bits_count(&s->gb)+31)/32*4 + table_size;
Michael Niedermayer's avatar
Michael Niedermayer committed
1200
}
1201
#endif
Michael Niedermayer's avatar
Michael Niedermayer committed
1202

1203 1204
static int common_end(HYuvContext *s){
    int i;
1205

1206 1207 1208 1209 1210 1211
    for(i=0; i<3; i++){
        av_freep(&s->temp[i]);
    }
    return 0;
}

1212
#ifdef CONFIG_DECODERS
1213
static av_cold int decode_end(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
1214 1215 1216
{
    HYuvContext *s = avctx->priv_data;
    int i;
1217

1218 1219
    common_end(s);
    av_freep(&s->bitstream_buffer);
1220

Oliver Pfister's avatar
Oliver Pfister committed
1221
    for(i=0; i<6; i++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1222 1223
        free_vlc(&s->vlc[i]);
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
1224

Michael Niedermayer's avatar
Michael Niedermayer committed
1225 1226
    return 0;
}
1227
#endif
Michael Niedermayer's avatar
Michael Niedermayer committed
1228

1229
#ifdef CONFIG_ENCODERS
Michael Niedermayer's avatar
Michael Niedermayer committed
1230 1231
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
    HYuvContext *s = avctx->priv_data;
1232
    AVFrame *pict = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
1233 1234 1235 1236 1237 1238
    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];
1239
    AVFrame * const p= &s->picture;
1240
    int i, j, size=0;
Michael Niedermayer's avatar
Michael Niedermayer committed
1241

Michael Niedermayer's avatar
Michael Niedermayer committed
1242
    *p = *pict;
Michael Niedermayer's avatar
Michael Niedermayer committed
1243 1244
    p->pict_type= FF_I_TYPE;
    p->key_frame= 1;
1245

1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260
    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);

1261 1262
    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
1263

Michael Niedermayer's avatar
Michael Niedermayer committed
1264 1265 1266 1267
        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]);
1268

Michael Niedermayer's avatar
Michael Niedermayer committed
1269 1270 1271
        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);
1272

Michael Niedermayer's avatar
Michael Niedermayer committed
1273
        encode_422_bitstream(s, width-2);
1274

Michael Niedermayer's avatar
Michael Niedermayer committed
1275 1276
        if(s->predictor==MEDIAN){
            int lefttopy, lefttopu, lefttopv;
1277
            cy=y=1;
Michael Niedermayer's avatar
Michael Niedermayer committed
1278
            if(s->interlaced){
Michael Niedermayer's avatar
Michael Niedermayer committed
1279 1280 1281
                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);
1282

Michael Niedermayer's avatar
Michael Niedermayer committed
1283
                encode_422_bitstream(s, width);
1284
                y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1285
            }
1286

Michael Niedermayer's avatar
Michael Niedermayer committed
1287
            lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
1288 1289
            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);
1290

Michael Niedermayer's avatar
Michael Niedermayer committed
1291
            encode_422_bitstream(s, 4);
1292

Michael Niedermayer's avatar
Michael Niedermayer committed
1293 1294 1295
            lefttopy= p->data[0][3];
            lefttopu= p->data[1][1];
            lefttopv= p->data[2][1];
1296 1297 1298
            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
1299
            encode_422_bitstream(s, width-4);
1300
            y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1301

1302
            for(; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1303
                uint8_t *ydst, *udst, *vdst;
1304

1305 1306
                if(s->bitstream_bpp==12){
                    while(2*cy > y){
Michael Niedermayer's avatar
Michael Niedermayer committed
1307
                        ydst= p->data[0] + p->linesize[0]*y;
1308
                        s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1309 1310 1311 1312 1313
                        encode_gray_bitstream(s, width);
                        y++;
                    }
                    if(y>=height) break;
                }
Michael Niedermayer's avatar
Michael Niedermayer committed
1314 1315 1316
                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
1317

1318 1319 1320
                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
1321 1322 1323 1324

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

1328 1329
                /* encode a luma only line & y++ */
                if(s->bitstream_bpp==12){
Michael Niedermayer's avatar
Michael Niedermayer committed
1330
                    ydst= p->data[0] + p->linesize[0]*y;
1331 1332

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

1335
                        lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1336
                    }else{
1337
                        lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1338 1339 1340 1341 1342
                    }
                    encode_gray_bitstream(s, width);
                    y++;
                    if(y>=height) break;
                }
1343

Michael Niedermayer's avatar
Michael Niedermayer committed
1344 1345 1346
                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
1347

1348
                if(s->predictor == PLANE && s->interlaced < cy){
1349 1350
                    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
1351
                    s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2);
Michael Niedermayer's avatar
Michael Niedermayer committed
1352

1353 1354
                    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
1355
                    leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1356
                }else{
1357 1358 1359
                    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
1360 1361 1362 1363
                }

                encode_422_bitstream(s, width);
            }
1364
        }
Loren Merritt's avatar
Loren Merritt committed
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389
    }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
1390
    }else{
1391
        av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1392 1393
    }
    emms_c();
1394

1395 1396
    size+= (put_bits_count(&s->pb)+31)/8;
    size/= 4;
1397

Michael Niedermayer's avatar
Michael Niedermayer committed
1398 1399 1400
    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
1401
        char *end= p + 1024*30;
Michael Niedermayer's avatar
Michael Niedermayer committed
1402 1403
        for(i=0; i<3; i++){
            for(j=0; j<256; j++){
1404
                snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]);
Michael Niedermayer's avatar
Michael Niedermayer committed
1405 1406 1407
                p+= strlen(p);
                s->stats[i][j]= 0;
            }
Michael Niedermayer's avatar
Michael Niedermayer committed
1408
            snprintf(p, end-p, "\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1409 1410
            p++;
        }
1411 1412
    } else
        avctx->stats_out[0] = '\0';
1413
    if(!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)){
1414
        flush_put_bits(&s->pb);
Michael Niedermayer's avatar
Michael Niedermayer committed
1415
        s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
Michael Niedermayer's avatar
Michael Niedermayer committed
1416
    }
1417

Michael Niedermayer's avatar
Michael Niedermayer committed
1418
    s->picture_number++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1419

Michael Niedermayer's avatar
Michael Niedermayer committed
1420 1421 1422
    return size*4;
}

1423
static av_cold int encode_end(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
1424
{
1425
    HYuvContext *s = avctx->priv_data;
1426

1427
    common_end(s);
Michael Niedermayer's avatar
Michael Niedermayer committed
1428 1429 1430

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

Michael Niedermayer's avatar
Michael Niedermayer committed
1432 1433
    return 0;
}
1434
#endif /* CONFIG_ENCODERS */
Michael Niedermayer's avatar
Michael Niedermayer committed
1435

1436
#ifdef CONFIG_DECODERS
Michael Niedermayer's avatar
Michael Niedermayer committed
1437 1438 1439 1440 1441 1442 1443 1444 1445
AVCodec huffyuv_decoder = {
    "huffyuv",
    CODEC_TYPE_VIDEO,
    CODEC_ID_HUFFYUV,
    sizeof(HYuvContext),
    decode_init,
    NULL,
    decode_end,
    decode_frame,
1446
    CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1447
    NULL,
1448
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
Michael Niedermayer's avatar
Michael Niedermayer committed
1449 1450
};

1451 1452 1453 1454 1455 1456 1457 1458 1459 1460
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,
1461
    NULL,
1462
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
1463
};
1464
#endif
1465

1466 1467
#ifdef CONFIG_ENCODERS

Michael Niedermayer's avatar
Michael Niedermayer committed
1468 1469 1470 1471 1472 1473 1474 1475
AVCodec huffyuv_encoder = {
    "huffyuv",
    CODEC_TYPE_VIDEO,
    CODEC_ID_HUFFYUV,
    sizeof(HYuvContext),
    encode_init,
    encode_frame,
    encode_end,
1476
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
1477
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
Michael Niedermayer's avatar
Michael Niedermayer committed
1478
};
1479

1480 1481 1482 1483 1484 1485 1486 1487
AVCodec ffvhuff_encoder = {
    "ffvhuff",
    CODEC_TYPE_VIDEO,
    CODEC_ID_FFVHUFF,
    sizeof(HYuvContext),
    encode_init,
    encode_frame,
    encode_end,
1488
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
1489
    .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
1490 1491
};

1492
#endif //CONFIG_ENCODERS