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

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

#include "avcodec.h"
32
#include "get_bits.h"
33
#include "put_bits.h"
Michael Niedermayer's avatar
Michael Niedermayer committed
34 35 36
#include "dsputil.h"

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

38
#if HAVE_BIGENDIAN
39 40 41
#define B 3
#define G 2
#define R 1
42
#define A 0
43 44 45 46
#else
#define B 0
#define G 1
#define R 2
47
#define A 3
48 49
#endif

Michael Niedermayer's avatar
Michael Niedermayer committed
50 51 52 53 54
typedef enum Predictor{
    LEFT= 0,
    PLANE,
    MEDIAN,
} Predictor;
55

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

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

134
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
135
    int i;
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
    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
151 152
    }
}
153

Loren Merritt's avatar
Loren Merritt committed
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
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];
}

177
static int read_len_table(uint8_t *dst, GetBitContext *gb){
Michael Niedermayer's avatar
Michael Niedermayer committed
178
    int i, val, repeat;
179

Michael Niedermayer's avatar
Michael Niedermayer committed
180 181 182 183 184 185
    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);
186 187 188 189
        if(i+repeat > 256) {
            av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
            return -1;
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
190 191 192
        while (repeat--)
            dst[i++] = val;
    }
193
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
194 195
}

196
static int generate_bits_table(uint32_t *dst, const uint8_t *len_table){
Michael Niedermayer's avatar
Michael Niedermayer committed
197 198 199 200 201
    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
202 203
            if(len_table[index]==len)
                dst[index]= bits++;
Michael Niedermayer's avatar
Michael Niedermayer committed
204
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
205
        if(bits & 1){
206
            av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
207 208 209
            return -1;
        }
        bits >>= 1;
Michael Niedermayer's avatar
Michael Niedermayer committed
210 211 212 213
    }
    return 0;
}

214
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
215 216 217
typedef struct {
    uint64_t val;
    int name;
218
} HeapElem;
219

220
static void heap_sift(HeapElem *h, int root, int size)
221 222 223 224 225 226
{
    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) {
227
            FFSWAP(HeapElem, h[root], h[child]);
228 229 230 231 232 233
            root = child;
        } else
            break;
    }
}

234
static void generate_len_table(uint8_t *dst, const uint64_t *stats){
235 236 237
    HeapElem h[256];
    int up[2*256];
    int len[2*256];
Michael Niedermayer's avatar
Michael Niedermayer committed
238
    int offset, i, next;
239
    int size = 256;
240

Michael Niedermayer's avatar
Michael Niedermayer committed
241 242
    for(offset=1; ; offset<<=1){
        for(i=0; i<size; i++){
243 244
            h[i].name = i;
            h[i].val = (stats[i] << 8) + offset;
Michael Niedermayer's avatar
Michael Niedermayer committed
245
        }
246 247 248 249 250 251 252 253 254 255 256 257 258
        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
259
        }
260

261 262 263 264 265
        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;
266
            if(dst[i] >= 32) break;
Michael Niedermayer's avatar
Michael Niedermayer committed
267 268 269 270
        }
        if(i==size) break;
    }
}
271
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
272

273
static void generate_joint_tables(HYuvContext *s){
274 275 276
    uint16_t symbols[1<<VLC_BITS];
    uint16_t bits[1<<VLC_BITS];
    uint8_t len[1<<VLC_BITS];
277 278 279 280 281 282
    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;
283 284 285 286 287 288 289 290 291 292 293
                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++;
294 295 296
                }
            }
            free_vlc(&s->vlc[3+p]);
297
            init_vlc_sparse(&s->vlc[3+p], VLC_BITS, i, len, 1, 1, bits, 2, 2, symbols, 2, 2, 0);
298
        }
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
    }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);
339 340 341
    }
}

342
static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length){
Michael Niedermayer's avatar
Michael Niedermayer committed
343 344
    GetBitContext gb;
    int i;
345

346
    init_get_bits(&gb, src, length*8);
347

Michael Niedermayer's avatar
Michael Niedermayer committed
348
    for(i=0; i<3; i++){
349 350
        if(read_len_table(s->len[i], &gb)<0)
            return -1;
Michael Niedermayer's avatar
Michael Niedermayer committed
351 352 353 354 355 356 357 358
        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
359
        free_vlc(&s->vlc[i]);
360
        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
361
    }
362

363 364
    generate_joint_tables(s);

365
    return (get_bits_count(&gb)+7)/8;
Michael Niedermayer's avatar
Michael Niedermayer committed
366 367 368
}

static int read_old_huffman_tables(HYuvContext *s){
369
#if 1
Michael Niedermayer's avatar
Michael Niedermayer committed
370 371 372
    GetBitContext gb;
    int i;

373
    init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
374 375
    if(read_len_table(s->len[0], &gb)<0)
        return -1;
376
    init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
377 378
    if(read_len_table(s->len[1], &gb)<0)
        return -1;
379

Michael Niedermayer's avatar
Michael Niedermayer committed
380 381 382 383 384 385 386 387 388
    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));
389

390 391
    for(i=0; i<3; i++){
        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);
393
    }
394

395 396
    generate_joint_tables(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
397 398
    return 0;
#else
399
    av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n");
Michael Niedermayer's avatar
Michael Niedermayer committed
400 401 402 403
    return -1;
#endif
}

404
static av_cold void alloc_temp(HYuvContext *s){
Michael Niedermayer's avatar
Michael Niedermayer committed
405
    int i;
406

Michael Niedermayer's avatar
Michael Niedermayer committed
407 408 409 410 411
    if(s->bitstream_bpp<24){
        for(i=0; i<3; i++){
            s->temp[i]= av_malloc(s->width + 16);
        }
    }else{
412
        s->temp[0]= av_mallocz(4*s->width + 16);
Michael Niedermayer's avatar
Michael Niedermayer committed
413 414 415
    }
}

416
static av_cold int common_init(AVCodecContext *avctx){
Michael Niedermayer's avatar
Michael Niedermayer committed
417 418 419 420
    HYuvContext *s = avctx->priv_data;

    s->avctx= avctx;
    s->flags= avctx->flags;
421

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

424 425 426
    s->width= avctx->width;
    s->height= avctx->height;
    assert(s->width>0 && s->height>0);
427

428 429 430
    return 0;
}

431
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
432
static av_cold int decode_init(AVCodecContext *avctx)
433 434 435 436
{
    HYuvContext *s = avctx->priv_data;

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

439
    avctx->coded_frame= &s->picture;
440
    s->interlaced= s->height > 288;
Michael Niedermayer's avatar
Michael Niedermayer committed
441

Michael Niedermayer's avatar
Michael Niedermayer committed
442 443 444 445
s->bgr32=1;
//if(avctx->extradata)
//  printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
    if(avctx->extradata_size){
446
        if((avctx->bits_per_coded_sample&7) && avctx->bits_per_coded_sample != 12)
Michael Niedermayer's avatar
Michael Niedermayer committed
447 448 449 450 451
            s->version=1; // do such files exist at all?
        else
            s->version=2;
    }else
        s->version=0;
452

Michael Niedermayer's avatar
Michael Niedermayer committed
453
    if(s->version==2){
454
        int method, interlace;
Michael Niedermayer's avatar
Michael Niedermayer committed
455

456 457 458
        if (avctx->extradata_size < 4)
            return -1;

Michael Niedermayer's avatar
Michael Niedermayer committed
459 460 461 462
        method= ((uint8_t*)avctx->extradata)[0];
        s->decorrelate= method&64 ? 1 : 0;
        s->predictor= method&63;
        s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
463
        if(s->bitstream_bpp==0)
464
            s->bitstream_bpp= avctx->bits_per_coded_sample&~7;
465 466
        interlace= (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4;
        s->interlaced= (interlace==1) ? 1 : (interlace==2) ? 0 : s->interlaced;
467
        s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;
468

469
        if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size-4) < 0)
Michael Niedermayer's avatar
Michael Niedermayer committed
470 471
            return -1;
    }else{
472
        switch(avctx->bits_per_coded_sample&7){
Michael Niedermayer's avatar
Michael Niedermayer committed
473 474 475 476 477 478 479 480 481 482
        case 1:
            s->predictor= LEFT;
            s->decorrelate= 0;
            break;
        case 2:
            s->predictor= LEFT;
            s->decorrelate= 1;
            break;
        case 3:
            s->predictor= PLANE;
483
            s->decorrelate= avctx->bits_per_coded_sample >= 24;
Michael Niedermayer's avatar
Michael Niedermayer committed
484 485 486 487 488 489 490 491 492 493
            break;
        case 4:
            s->predictor= MEDIAN;
            s->decorrelate= 0;
            break;
        default:
            s->predictor= LEFT; //OLD
            s->decorrelate= 0;
            break;
        }
494
        s->bitstream_bpp= avctx->bits_per_coded_sample & ~7;
495
        s->context= 0;
496

Michael Niedermayer's avatar
Michael Niedermayer committed
497 498 499
        if(read_old_huffman_tables(s) < 0)
            return -1;
    }
500

Michael Niedermayer's avatar
Michael Niedermayer committed
501 502 503 504 505 506
    switch(s->bitstream_bpp){
    case 12:
        avctx->pix_fmt = PIX_FMT_YUV420P;
        break;
    case 16:
        if(s->yuy2){
507
            avctx->pix_fmt = PIX_FMT_YUYV422;
Michael Niedermayer's avatar
Michael Niedermayer committed
508 509 510 511 512 513 514
        }else{
            avctx->pix_fmt = PIX_FMT_YUV422P;
        }
        break;
    case 24:
    case 32:
        if(s->bgr32){
515
            avctx->pix_fmt = PIX_FMT_RGB32;
Michael Niedermayer's avatar
Michael Niedermayer committed
516 517 518 519 520 521 522
        }else{
            avctx->pix_fmt = PIX_FMT_BGR24;
        }
        break;
    default:
        assert(0);
    }
523

Michael Niedermayer's avatar
Michael Niedermayer committed
524
    alloc_temp(s);
525

526
//    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);
527

Michael Niedermayer's avatar
Michael Niedermayer committed
528 529
    return 0;
}
530
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
531

532
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
533
static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf){
Michael Niedermayer's avatar
Michael Niedermayer committed
534
    int i;
535
    int index= 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
536 537 538

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

541 542
        for(; i<256 && len[i]==val && repeat<255; i++)
            repeat++;
543

544
        assert(val < 32 && val >0 && repeat<256 && repeat>0);
Michael Niedermayer's avatar
Michael Niedermayer committed
545
        if(repeat>7){
546 547
            buf[index++]= val;
            buf[index++]= repeat;
Michael Niedermayer's avatar
Michael Niedermayer committed
548
        }else{
549
            buf[index++]= val | (repeat<<5);
Michael Niedermayer's avatar
Michael Niedermayer committed
550 551
        }
    }
552

553
    return index;
Michael Niedermayer's avatar
Michael Niedermayer committed
554 555
}

556
static av_cold int encode_init(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
557 558
{
    HYuvContext *s = avctx->priv_data;
559
    int i, j;
Michael Niedermayer's avatar
Michael Niedermayer committed
560

561
    common_init(avctx);
562

563 564
    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
565
    s->version=2;
566

567
    avctx->coded_frame= &s->picture;
568

Michael Niedermayer's avatar
Michael Niedermayer committed
569
    switch(avctx->pix_fmt){
570 571 572
    case PIX_FMT_YUV420P:
        s->bitstream_bpp= 12;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
573 574 575
    case PIX_FMT_YUV422P:
        s->bitstream_bpp= 16;
        break;
Loren Merritt's avatar
Loren Merritt committed
576 577 578
    case PIX_FMT_RGB32:
        s->bitstream_bpp= 24;
        break;
Michael Niedermayer's avatar
Michael Niedermayer committed
579
    default:
580
        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
581 582
        return -1;
    }
583
    avctx->bits_per_coded_sample= s->bitstream_bpp;
Michael Niedermayer's avatar
Michael Niedermayer committed
584 585
    s->decorrelate= s->bitstream_bpp >= 24;
    s->predictor= avctx->prediction_method;
586
    s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
587 588 589 590 591 592 593
    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;
594

595 596 597 598 599 600 601 602 603
    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;
        }
604
        if(s->interlaced != ( s->height > 288 ))
605 606
            av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n");
    }
607

Loren Merritt's avatar
Loren Merritt committed
608 609 610 611 612 613
    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
614
    ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
615
    ((uint8_t*)avctx->extradata)[2]= s->interlaced ? 0x10 : 0x20;
616 617
    if(s->context)
        ((uint8_t*)avctx->extradata)[2]|= 0x40;
Michael Niedermayer's avatar
Michael Niedermayer committed
618 619
    ((uint8_t*)avctx->extradata)[3]= 0;
    s->avctx->extradata_size= 4;
620

Michael Niedermayer's avatar
Michael Niedermayer committed
621 622
    if(avctx->stats_in){
        char *p= avctx->stats_in;
623

Michael Niedermayer's avatar
Michael Niedermayer committed
624 625 626 627 628 629 630 631 632 633 634 635
        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;
636
                }
Michael Niedermayer's avatar
Michael Niedermayer committed
637 638 639 640 641 642 643
            }
            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);
644

Michael Niedermayer's avatar
Michael Niedermayer committed
645 646 647
                s->stats[i][j]= 100000000/(d+1);
            }
    }
648

Michael Niedermayer's avatar
Michael Niedermayer committed
649
    for(i=0; i<3; i++){
650
        generate_len_table(s->len[i], s->stats[i]);
Michael Niedermayer's avatar
Michael Niedermayer committed
651 652 653 654

        if(generate_bits_table(s->bits[i], s->len[i])<0){
            return -1;
        }
655

656 657
        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
658 659
    }

660 661
    if(s->context){
        for(i=0; i<3; i++){
662
            int pels = s->width*s->height / (i?40:10);
663 664 665 666 667 668 669 670 671 672
            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;
    }
673

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

Michael Niedermayer's avatar
Michael Niedermayer committed
676 677
    alloc_temp(s);

Michael Niedermayer's avatar
Michael Niedermayer committed
678
    s->picture_number=0;
679

Michael Niedermayer's avatar
Michael Niedermayer committed
680 681
    return 0;
}
682
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
683

684 685 686
/* 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){\
687 688 689 690
    uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\
    if(code != 0xffff){\
        dst0 = code>>8;\
        dst1 = code;\
691 692 693 694 695 696
    }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
697 698
static void decode_422_bitstream(HYuvContext *s, int count){
    int i;
699

Michael Niedermayer's avatar
Michael Niedermayer committed
700
    count/=2;
701

702
    if(count >= (get_bits_left(&s->gb))/(31*4)){
703 704 705 706 707
        for(i=0; i<count && get_bits_count(&s->gb) < s->gb.size_in_bits; i++){
            READ_2PIX(s->temp[0][2*i  ], s->temp[1][i], 1);
            READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2);
        }
    }else{
Michael Niedermayer's avatar
Michael Niedermayer committed
708 709 710 711
        for(i=0; i<count; i++){
            READ_2PIX(s->temp[0][2*i  ], s->temp[1][i], 1);
            READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2);
        }
712
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
713 714
}

715 716
static void decode_gray_bitstream(HYuvContext *s, int count){
    int i;
717

718
    count/=2;
719

720
    if(count >= (get_bits_left(&s->gb))/(31*2)){
721 722 723 724
        for(i=0; i<count && get_bits_count(&s->gb) < s->gb.size_in_bits; i++){
            READ_2PIX(s->temp[0][2*i  ], s->temp[0][2*i+1], 0);
        }
    }else{
Michael Niedermayer's avatar
Michael Niedermayer committed
725 726 727
        for(i=0; i<count; i++){
            READ_2PIX(s->temp[0][2*i  ], s->temp[0][2*i+1], 0);
        }
728
    }
729 730
}

731
#if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
732
static int encode_422_bitstream(HYuvContext *s, int offset, int count){
Michael Niedermayer's avatar
Michael Niedermayer committed
733
    int i;
734 735 736
    const uint8_t *y = s->temp[0] + offset;
    const uint8_t *u = s->temp[1] + offset/2;
    const uint8_t *v = s->temp[2] + offset/2;
737

738 739 740 741
    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;
    }
742

743
#define LOAD4\
744 745 746 747
            int y0 = y[2*i];\
            int y1 = y[2*i+1];\
            int u0 = u[i];\
            int v0 = v[i];
748

Michael Niedermayer's avatar
Michael Niedermayer committed
749 750 751
    count/=2;
    if(s->flags&CODEC_FLAG_PASS1){
        for(i=0; i<count; i++){
752 753 754 755 756
            LOAD4;
            s->stats[0][y0]++;
            s->stats[1][u0]++;
            s->stats[0][y1]++;
            s->stats[2][v0]++;
Michael Niedermayer's avatar
Michael Niedermayer committed
757
        }
758 759 760 761
    }
    if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)
        return 0;
    if(s->context){
762
        for(i=0; i<count; i++){
763 764 765 766 767 768 769 770 771
            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]);
772
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
773 774
    }else{
        for(i=0; i<count; i++){
775 776 777 778 779
            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
780 781
        }
    }
782
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
783 784
}

785
static int encode_gray_bitstream(HYuvContext *s, int count){
786
    int i;
787

788 789 790 791 792
    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;
    }

793 794 795 796 797 798 799 800 801 802
#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]);

803 804 805
    count/=2;
    if(s->flags&CODEC_FLAG_PASS1){
        for(i=0; i<count; i++){
806 807
            LOAD2;
            STAT2;
808
        }
809 810 811
    }
    if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)
        return 0;
812

813
    if(s->context){
814
        for(i=0; i<count; i++){
815 816 817
            LOAD2;
            STAT2;
            WRITE2;
818
        }
819 820
    }else{
        for(i=0; i<count; i++){
821 822
            LOAD2;
            WRITE2;
823 824
        }
    }
825
    return 0;
826
}
827
#endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */
828

829
static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorrelate, int alpha){
Michael Niedermayer's avatar
Michael Niedermayer committed
830
    int i;
831 832 833 834 835 836 837 838
    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
839
        }else{
840 841 842
            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
843
        }
844
        if(alpha)
845
            s->temp[0][4*i+A] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
846 847 848 849 850 851 852 853 854
    }
}

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
855
    }else{
856 857 858 859
        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
860 861 862
    }
}

Loren Merritt's avatar
Loren Merritt committed
863 864 865 866 867 868 869 870
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;
    }

871 872 873
#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
874
            int r= (s->temp[0][4*i+R] - g) & 0xff;
875 876 877
#define STAT3\
            s->stats[0][b]++;\
            s->stats[1][g]++;\
Loren Merritt's avatar
Loren Merritt committed
878
            s->stats[2][r]++;
879 880 881 882 883 884 885 886 887
#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
888 889 890
        }
    }else if(s->context || (s->flags&CODEC_FLAG_PASS1)){
        for(i=0; i<count; i++){
891 892 893
            LOAD3;
            STAT3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
894 895 896
        }
    }else{
        for(i=0; i<count; i++){
897 898
            LOAD3;
            WRITE3;
Loren Merritt's avatar
Loren Merritt committed
899 900 901 902 903
        }
    }
    return 0;
}

904
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
905 906
static void draw_slice(HYuvContext *s, int y){
    int h, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
907
    int offset[4];
908 909

    if(s->avctx->draw_horiz_band==NULL)
910
        return;
911

912 913
    h= y - s->last_slice_end;
    y -= h;
914

915 916 917 918 919
    if(s->bitstream_bpp==12){
        cy= y>>1;
    }else{
        cy= y;
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
920 921 922 923 924

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

927
    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
928

929 930 931
    s->last_slice_end= y + h;
}

932 933 934
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
Michael Niedermayer's avatar
Michael Niedermayer committed
935 936 937 938
    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
939
    int fake_ystride, fake_ustride, fake_vstride;
940
    AVFrame * const p= &s->picture;
941
    int table_size= 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
942

943
    AVFrame *picture = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
944

945 946 947
    av_fast_malloc(&s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!s->bitstream_buffer)
        return AVERROR(ENOMEM);
Michael Niedermayer's avatar
Michael Niedermayer committed
948

949
    memset(s->bitstream_buffer + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
Michael Niedermayer's avatar
Michael Niedermayer committed
950
    s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size/4);
951

952 953 954
    if(p->data[0])
        avctx->release_buffer(avctx, p);

Michael Niedermayer's avatar
Michael Niedermayer committed
955 956
    p->reference= 0;
    if(avctx->get_buffer(avctx, p) < 0){
957
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
958
        return -1;
Michael Niedermayer's avatar
Michael Niedermayer committed
959
    }
960

961 962 963 964 965 966
    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
967 968 969
    if((unsigned)(buf_size-table_size) >= INT_MAX/8)
        return -1;

970
    init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8);
Michael Niedermayer's avatar
Michael Niedermayer committed
971 972 973 974

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

976
    s->last_slice_end= 0;
977

Michael Niedermayer's avatar
Michael Niedermayer committed
978
    if(s->bitstream_bpp<24){
979
        int y, cy;
Michael Niedermayer's avatar
Michael Niedermayer committed
980 981
        int lefty, leftu, leftv;
        int lefttopy, lefttopu, lefttopv;
982

Michael Niedermayer's avatar
Michael Niedermayer committed
983
        if(s->yuy2){
Michael Niedermayer's avatar
Michael Niedermayer committed
984 985 986 987
            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);
988

989
            av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
990 991
            return -1;
        }else{
992

Michael Niedermayer's avatar
Michael Niedermayer committed
993 994 995 996
            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);
997

Michael Niedermayer's avatar
Michael Niedermayer committed
998 999 1000 1001
            switch(s->predictor){
            case LEFT:
            case PLANE:
                decode_422_bitstream(s, width-2);
1002
                lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1003
                if(!(s->flags&CODEC_FLAG_GRAY)){
1004 1005
                    leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
                    leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1006 1007
                }

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

1011 1012
                    if(s->bitstream_bpp==12){
                        decode_gray_bitstream(s, width);
1013

Michael Niedermayer's avatar
Michael Niedermayer committed
1014
                        ydst= p->data[0] + p->linesize[0]*y;
1015

1016
                        lefty= s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
1017 1018 1019 1020 1021 1022 1023
                        if(s->predictor == PLANE){
                            if(y>s->interlaced)
                                s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
                        }
                        y++;
                        if(y>=s->height) break;
                    }
1024

1025
                    draw_slice(s, y);
1026

Michael Niedermayer's avatar
Michael Niedermayer committed
1027 1028 1029
                    ydst= p->data[0] + p->linesize[0]*y;
                    udst= p->data[1] + p->linesize[1]*cy;
                    vdst= p->data[2] + p->linesize[2]*cy;
1030

1031
                    decode_422_bitstream(s, width);
1032
                    lefty= s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1033
                    if(!(s->flags&CODEC_FLAG_GRAY)){
1034 1035
                        leftu= s->dsp.add_hfyu_left_prediction(udst, s->temp[1], width2, leftu);
                        leftv= s->dsp.add_hfyu_left_prediction(vdst, s->temp[2], width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1036 1037
                    }
                    if(s->predictor == PLANE){
1038
                        if(cy>s->interlaced){
Michael Niedermayer's avatar
Michael Niedermayer committed
1039 1040 1041 1042 1043 1044 1045 1046
                            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);
                            }
                        }
                    }
                }
1047
                draw_slice(s, height);
1048

Michael Niedermayer's avatar
Michael Niedermayer committed
1049 1050 1051 1052
                break;
            case MEDIAN:
                /* first line except first 2 pixels is left predicted */
                decode_422_bitstream(s, width-2);
1053
                lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1054
                if(!(s->flags&CODEC_FLAG_GRAY)){
1055 1056
                    leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
                    leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1057
                }
1058

1059
                cy=y=1;
1060

Michael Niedermayer's avatar
Michael Niedermayer committed
1061 1062 1063
                /* second line is left predicted for interlaced case */
                if(s->interlaced){
                    decode_422_bitstream(s, width);
1064
                    lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1065
                    if(!(s->flags&CODEC_FLAG_GRAY)){
1066 1067
                        leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
                        leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1068
                    }
1069
                    y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1070 1071 1072 1073
                }

                /* next 4 pixels are left predicted too */
                decode_422_bitstream(s, 4);
1074
                lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
Michael Niedermayer's avatar
Michael Niedermayer committed
1075
                if(!(s->flags&CODEC_FLAG_GRAY)){
1076 1077
                    leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
                    leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
Michael Niedermayer's avatar
Michael Niedermayer committed
1078 1079 1080
                }

                /* next line except the first 4 pixels is median predicted */
Michael Niedermayer's avatar
Michael Niedermayer committed
1081
                lefttopy= p->data[0][3];
Michael Niedermayer's avatar
Michael Niedermayer committed
1082
                decode_422_bitstream(s, width-4);
1083
                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
1084
                if(!(s->flags&CODEC_FLAG_GRAY)){
Michael Niedermayer's avatar
Michael Niedermayer committed
1085 1086
                    lefttopu= p->data[1][1];
                    lefttopv= p->data[2][1];
1087 1088
                    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
1089
                }
1090
                y++; cy++;
1091

1092
                for(; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1093
                    uint8_t *ydst, *udst, *vdst;
1094 1095 1096 1097

                    if(s->bitstream_bpp==12){
                        while(2*cy > y){
                            decode_gray_bitstream(s, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1098
                            ydst= p->data[0] + p->linesize[0]*y;
1099
                            s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
1100 1101 1102 1103
                            y++;
                        }
                        if(y>=height) break;
                    }
1104
                    draw_slice(s, y);
1105

Michael Niedermayer's avatar
Michael Niedermayer committed
1106
                    decode_422_bitstream(s, width);
1107

Michael Niedermayer's avatar
Michael Niedermayer committed
1108 1109 1110
                    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
1111

1112
                    s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
Michael Niedermayer's avatar
Michael Niedermayer committed
1113
                    if(!(s->flags&CODEC_FLAG_GRAY)){
1114 1115
                        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
1116 1117
                    }
                }
1118 1119

                draw_slice(s, height);
Michael Niedermayer's avatar
Michael Niedermayer committed
1120 1121 1122 1123 1124
                break;
            }
        }
    }else{
        int y;
1125
        int leftr, leftg, leftb, lefta;
Michael Niedermayer's avatar
Michael Niedermayer committed
1126
        const int last_line= (height-1)*p->linesize[0];
1127

Michael Niedermayer's avatar
Michael Niedermayer committed
1128
        if(s->bitstream_bpp==32){
1129
            lefta= p->data[0][last_line+A]= get_bits(&s->gb, 8);
1130 1131 1132
            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
1133
        }else{
1134 1135 1136
            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);
1137
            lefta= p->data[0][last_line+A]= 255;
Michael Niedermayer's avatar
Michael Niedermayer committed
1138 1139
            skip_bits(&s->gb, 8);
        }
1140

Michael Niedermayer's avatar
Michael Niedermayer committed
1141 1142 1143 1144 1145
        if(s->bgr32){
            switch(s->predictor){
            case LEFT:
            case PLANE:
                decode_bgr_bitstream(s, width-1);
1146
                s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb, &lefta);
Michael Niedermayer's avatar
Michael Niedermayer committed
1147

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

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

1167
            av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1168 1169 1170 1171
            return -1;
        }
    }
    emms_c();
1172

Michael Niedermayer's avatar
Michael Niedermayer committed
1173
    *picture= *p;
1174
    *data_size = sizeof(AVFrame);
1175

1176
    return (get_bits_count(&s->gb)+31)/32*4 + table_size;
Michael Niedermayer's avatar
Michael Niedermayer committed
1177
}
1178
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1179

1180 1181
static int common_end(HYuvContext *s){
    int i;
1182

1183 1184 1185 1186 1187 1188
    for(i=0; i<3; i++){
        av_freep(&s->temp[i]);
    }
    return 0;
}

1189
#if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER
1190
static av_cold int decode_end(AVCodecContext *avctx)
Michael Niedermayer's avatar
Michael Niedermayer committed
1191 1192 1193
{
    HYuvContext *s = avctx->priv_data;
    int i;
1194

1195 1196 1197
    if (s->picture.data[0])
        avctx->release_buffer(avctx, &s->picture);

1198 1199
    common_end(s);
    av_freep(&s->bitstream_buffer);
1200

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

Michael Niedermayer's avatar
Michael Niedermayer committed
1205 1206
    return 0;
}
1207
#endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */
Michael Niedermayer's avatar
Michael Niedermayer committed
1208

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

Michael Niedermayer's avatar
Michael Niedermayer committed
1222
    *p = *pict;
Michael Niedermayer's avatar
Michael Niedermayer committed
1223 1224
    p->pict_type= FF_I_TYPE;
    p->key_frame= 1;
1225

1226 1227
    if(s->context){
        for(i=0; i<3; i++){
1228
            generate_len_table(s->len[i], s->stats[i]);
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
            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);

1241 1242
    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
1243

Michael Niedermayer's avatar
Michael Niedermayer committed
1244 1245 1246 1247
        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]);
1248

1249 1250 1251
        lefty= sub_left_prediction(s, s->temp[0], p->data[0], width , 0);
        leftu= sub_left_prediction(s, s->temp[1], p->data[1], width2, 0);
        leftv= sub_left_prediction(s, s->temp[2], p->data[2], width2, 0);
1252

1253
        encode_422_bitstream(s, 2, width-2);
1254

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

1263
                encode_422_bitstream(s, 0, width);
1264
                y++; cy++;
Michael Niedermayer's avatar
Michael Niedermayer committed
1265
            }
1266

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

1271
            encode_422_bitstream(s, 0, 4);
1272

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

1282
            for(; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1283
                uint8_t *ydst, *udst, *vdst;
1284

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

1298 1299 1300
                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
1301

1302
                encode_422_bitstream(s, 0, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1303 1304
            }
        }else{
1305
            for(cy=y=1; y<height; y++,cy++){
Michael Niedermayer's avatar
Michael Niedermayer committed
1306
                uint8_t *ydst, *udst, *vdst;
1307

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

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

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

Michael Niedermayer's avatar
Michael Niedermayer committed
1324 1325 1326
                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
1327

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

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

1342
                encode_422_bitstream(s, 0, width);
Michael Niedermayer's avatar
Michael Niedermayer committed
1343
            }
1344
        }
Loren Merritt's avatar
Loren Merritt committed
1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369
    }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
1370
    }else{
1371
        av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
1372 1373
    }
    emms_c();
1374

1375
    size+= (put_bits_count(&s->pb)+31)/8;
1376 1377
    put_bits(&s->pb, 16, 0);
    put_bits(&s->pb, 15, 0);
1378
    size/= 4;
1379

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

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

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

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

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

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

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

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

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

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

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