Statistics
| Branch: | Revision:

ffmpeg / libavcodec / indeo3.c @ 2c4b4829

History | View | Annotate | Download (46 KB)

1 deabd4fd Mike Melanson
/*
2
 * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg
3
 * written, produced, and directed by Alan Smithee
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 deabd4fd Mike Melanson
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 deabd4fd Mike Melanson
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 deabd4fd Mike Melanson
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 deabd4fd Mike Melanson
 */
21
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <unistd.h>
26
27
#include "avcodec.h"
28
#include "dsputil.h"
29 972c99c1 Michael Niedermayer
#include "bytestream.h"
30 deabd4fd Mike Melanson
31
#include "indeo3data.h"
32
33
typedef struct
34
{
35 6f427ccb Benoit Fouet
    uint8_t *Ybuf;
36
    uint8_t *Ubuf;
37
    uint8_t *Vbuf;
38
    unsigned short y_w, y_h;
39
    unsigned short uv_w, uv_h;
40 deabd4fd Mike Melanson
} YUVBufs;
41
42
typedef struct Indeo3DecodeContext {
43
    AVCodecContext *avctx;
44
    int width, height;
45
    AVFrame frame;
46
47 ffc64ac0 Benoit Fouet
    uint8_t *buf;
48 deabd4fd Mike Melanson
    YUVBufs iv_frame[2];
49
    YUVBufs *cur_frame;
50
    YUVBufs *ref_frame;
51
52 68e9c68f Benoit Fouet
    uint8_t *ModPred;
53 e679560d Benoit Fouet
    uint8_t *corrector_type;
54 deabd4fd Mike Melanson
} Indeo3DecodeContext;
55
56 9fd88b29 Benoit Fouet
static const uint8_t corrector_type_0[24] = {
57 6f427ccb Benoit Fouet
    195, 159, 133, 115, 101,  93,  87,  77,
58
    195, 159, 133, 115, 101,  93,  87,  77,
59
    128,  79,  79,  79,  79,  79,  79,  79
60 deabd4fd Mike Melanson
};
61
62 9fd88b29 Benoit Fouet
static const uint8_t corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
63 deabd4fd Mike Melanson
64 8b27f76b Benoit Fouet
static av_cold int build_modpred(Indeo3DecodeContext *s)
65 deabd4fd Mike Melanson
{
66 6f427ccb Benoit Fouet
    int i, j;
67
68
    if (!(s->ModPred = av_malloc(8 * 128)))
69
        return AVERROR(ENOMEM);
70
71
    for (i=0; i < 128; ++i) {
72
        s->ModPred[i+0*128] = i >  126 ? 254 : 2*(i + 1 - ((i + 1) % 2));
73
        s->ModPred[i+1*128] = i ==   7 ?  20 :
74
                              i == 119 ||
75
                              i == 120 ? 236 : 2*(i + 2 - ((i + 1) % 3));
76
        s->ModPred[i+2*128] = i >  125 ? 248 : 2*(i + 2 - ((i + 2) % 4));
77
        s->ModPred[i+3*128] =                  2*(i + 1 - ((i - 3) % 5));
78
        s->ModPred[i+4*128] = i ==   8 ?  20 : 2*(i + 1 - ((i - 3) % 6));
79
        s->ModPred[i+5*128] =                  2*(i + 4 - ((i + 3) % 7));
80
        s->ModPred[i+6*128] = i >  123 ? 240 : 2*(i + 4 - ((i + 4) % 8));
81
        s->ModPred[i+7*128] =                  2*(i + 5 - ((i + 4) % 9));
82
    }
83
84
    if (!(s->corrector_type = av_malloc(24 * 256)))
85
        return AVERROR(ENOMEM);
86
87
    for (i=0; i < 24; ++i) {
88
        for (j=0; j < 256; ++j) {
89
            s->corrector_type[i*256+j] = j < corrector_type_0[i]          ? 1 :
90
                                         j < 248 || (i == 16 && j == 248) ? 0 :
91
                                         corrector_type_2[j - 248];
92
        }
93 deabd4fd Mike Melanson
    }
94 8b27f76b Benoit Fouet
95
  return 0;
96 deabd4fd Mike Melanson
}
97
98 8b27f76b Benoit Fouet
static av_cold int iv_alloc_frames(Indeo3DecodeContext *s)
99 deabd4fd Mike Melanson
{
100 96320336 Benoit Fouet
    int luma_width    = (s->width           + 3) & ~3,
101
        luma_height   = (s->height          + 3) & ~3,
102
        chroma_width  = ((luma_width  >> 2) + 3) & ~3,
103
        chroma_height = ((luma_height >> 2) + 3) & ~3,
104
        luma_pixels   = luma_width   * luma_height,
105
        chroma_pixels = chroma_width * chroma_height,
106
        i;
107
    unsigned int bufsize = luma_pixels * 2 + luma_width * 3 +
108
                          (chroma_pixels   + chroma_width) * 4;
109 6f427ccb Benoit Fouet
110
    if(!(s->buf = av_malloc(bufsize)))
111
        return AVERROR(ENOMEM);
112
    s->iv_frame[0].y_w = s->iv_frame[1].y_w = luma_width;
113
    s->iv_frame[0].y_h = s->iv_frame[1].y_h = luma_height;
114
    s->iv_frame[0].uv_w = s->iv_frame[1].uv_w = chroma_width;
115
    s->iv_frame[0].uv_h = s->iv_frame[1].uv_h = chroma_height;
116
117
    s->iv_frame[0].Ybuf = s->buf + luma_width;
118
    i = luma_pixels + luma_width * 2;
119
    s->iv_frame[1].Ybuf = s->buf + i;
120
    i += (luma_pixels + luma_width);
121
    s->iv_frame[0].Ubuf = s->buf + i;
122
    i += (chroma_pixels + chroma_width);
123
    s->iv_frame[1].Ubuf = s->buf + i;
124
    i += (chroma_pixels + chroma_width);
125
    s->iv_frame[0].Vbuf = s->buf + i;
126
    i += (chroma_pixels + chroma_width);
127
    s->iv_frame[1].Vbuf = s->buf + i;
128
129
    for(i = 1; i <= luma_width; i++)
130
        s->iv_frame[0].Ybuf[-i] = s->iv_frame[1].Ybuf[-i] =
131
            s->iv_frame[0].Ubuf[-i] = 0x80;
132
133
    for(i = 1; i <= chroma_width; i++) {
134
        s->iv_frame[1].Ubuf[-i] = 0x80;
135
        s->iv_frame[0].Vbuf[-i] = 0x80;
136
        s->iv_frame[1].Vbuf[-i] = 0x80;
137
        s->iv_frame[1].Vbuf[chroma_pixels+i-1] = 0x80;
138
    }
139 8b27f76b Benoit Fouet
140 6f427ccb Benoit Fouet
    return 0;
141 deabd4fd Mike Melanson
}
142
143 98a6fff9 Zuxy Meng
static av_cold void iv_free_func(Indeo3DecodeContext *s)
144 deabd4fd Mike Melanson
{
145 6f427ccb Benoit Fouet
    av_free(s->buf);
146
    av_free(s->ModPred);
147
    av_free(s->corrector_type);
148 deabd4fd Mike Melanson
}
149
150
typedef struct {
151 6f427ccb Benoit Fouet
    long xpos;
152
    long ypos;
153
    long width;
154
    long height;
155
    long split_flag;
156
    long split_direction;
157
    long usl7;
158 deabd4fd Mike Melanson
} ustr_t;
159
160
161 a44f8ccb Mike Melanson
#define LV1_CHECK(buf1,rle_v3,lv1,lp2)  \
162 6f427ccb Benoit Fouet
    if((lv1 & 0x80) != 0) {             \
163
        if(rle_v3 != 0)                 \
164
            rle_v3 = 0;                 \
165
        else {                          \
166
            rle_v3 = 1;                 \
167
            buf1 -= 2;                  \
168
        }                               \
169
    }                                   \
170
    lp2 = 4;
171 a44f8ccb Mike Melanson
172
173
#define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)  \
174 6f427ccb Benoit Fouet
    if(rle_v3 == 0) {                            \
175
        rle_v2 = *buf1;                          \
176
        rle_v1 = 1;                              \
177
        if(rle_v2 > 32) {                        \
178
            rle_v2 -= 32;                        \
179
            rle_v1 = 0;                          \
180
        }                                        \
181
        rle_v3 = 1;                              \
182
    }                                            \
183
    buf1--;
184 a44f8ccb Mike Melanson
185
186
#define LP2_CHECK(buf1,rle_v3,lp2)  \
187 6f427ccb Benoit Fouet
    if(lp2 == 0 && rle_v3 != 0)     \
188
        rle_v3 = 0;                 \
189
    else {                          \
190
        buf1--;                     \
191
        rle_v3 = 1;                 \
192
    }
193 a44f8ccb Mike Melanson
194
195
#define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
196 6f427ccb Benoit Fouet
    rle_v2--;                                 \
197
    if(rle_v2 == 0) {                         \
198
        rle_v3 = 0;                           \
199
        buf1 += 2;                            \
200
    }                                         \
201
    lp2 = 4;
202 a44f8ccb Mike Melanson
203 deabd4fd Mike Melanson
static void iv_Decode_Chunk(Indeo3DecodeContext *s,
204 6f427ccb Benoit Fouet
        uint8_t *cur, uint8_t *ref, int width, int height,
205 2c4b4829 Benoit Fouet
        const uint8_t *buf1, long cb_offset, const uint8_t *hdr,
206 6f427ccb Benoit Fouet
        const uint8_t *buf2, int min_width_160)
207 deabd4fd Mike Melanson
{
208 6f427ccb Benoit Fouet
    uint8_t bit_buf;
209
    unsigned long bit_pos, lv, lv1, lv2;
210
    long *width_tbl, width_tbl_arr[10];
211
    const signed char *ref_vectors;
212
    uint8_t *cur_frm_pos, *ref_frm_pos, *cp, *cp2;
213
    uint32_t *cur_lp, *ref_lp;
214
    const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2];
215
    uint8_t *correction_type_sp[2];
216
    ustr_t strip_tbl[20], *strip;
217
    int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width,
218
        rle_v1, rle_v2, rle_v3;
219
    unsigned short res;
220
221
    bit_buf = 0;
222
    ref_vectors = NULL;
223
224
    width_tbl = width_tbl_arr + 1;
225
    i = (width < 0 ? width + 3 : width)/4;
226
    for(j = -1; j < 8; j++)
227
        width_tbl[j] = i * j;
228
229
    strip = strip_tbl;
230
231
    for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160);
232
233
    strip->ypos = strip->xpos = 0;
234
    for(strip->width = min_width_160; width > strip->width; strip->width *= 2);
235
    strip->height = height;
236
    strip->split_direction = 0;
237
    strip->split_flag = 0;
238
    strip->usl7 = 0;
239
240
    bit_pos = 0;
241
242
    rle_v1 = rle_v2 = rle_v3 = 0;
243
244
    while(strip >= strip_tbl) {
245
        if(bit_pos <= 0) {
246
            bit_pos = 8;
247
            bit_buf = *buf1++;
248 09b85c13 Fabrice Bellard
        }
249 deabd4fd Mike Melanson
250 6f427ccb Benoit Fouet
        bit_pos -= 2;
251
        cmd = (bit_buf >> bit_pos) & 0x03;
252
253
        if(cmd == 0) {
254
            strip++;
255
            memcpy(strip, strip-1, sizeof(ustr_t));
256
            strip->split_flag = 1;
257
            strip->split_direction = 0;
258
            strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);
259
            continue;
260
        } else if(cmd == 1) {
261
            strip++;
262
            memcpy(strip, strip-1, sizeof(ustr_t));
263
            strip->split_flag = 1;
264
            strip->split_direction = 1;
265
            strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);
266
            continue;
267
        } else if(cmd == 2) {
268
            if(strip->usl7 == 0) {
269
                strip->usl7 = 1;
270
                ref_vectors = NULL;
271
                continue;
272
            }
273
        } else if(cmd == 3) {
274
            if(strip->usl7 == 0) {
275
                strip->usl7 = 1;
276
                ref_vectors = (const signed char*)buf2 + (*buf1 * 2);
277
                buf1++;
278
                continue;
279 deabd4fd Mike Melanson
            }
280 6f427ccb Benoit Fouet
        }
281 deabd4fd Mike Melanson
282 6f427ccb Benoit Fouet
        cur_frm_pos = cur + width * strip->ypos + strip->xpos;
283 deabd4fd Mike Melanson
284 6f427ccb Benoit Fouet
        if((blks_width = strip->width) < 0)
285
            blks_width += 3;
286
        blks_width >>= 2;
287
        blks_height = strip->height;
288 deabd4fd Mike Melanson
289 6f427ccb Benoit Fouet
        if(ref_vectors != NULL) {
290
            ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +
291
                ref_vectors[1] + strip->xpos;
292
        } else
293
            ref_frm_pos = cur_frm_pos - width_tbl[4];
294
295
        if(cmd == 2) {
296
            if(bit_pos <= 0) {
297
                bit_pos = 8;
298
                bit_buf = *buf1++;
299
            }
300
301
            bit_pos -= 2;
302
            cmd = (bit_buf >> bit_pos) & 0x03;
303
304
            if(cmd == 0 || ref_vectors != NULL) {
305
                for(lp1 = 0; lp1 < blks_width; lp1++) {
306
                    for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])
307
                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
308
                    cur_frm_pos += 4;
309
                    ref_frm_pos += 4;
310
                }
311
            } else if(cmd != 1)
312
                return;
313
        } else {
314
            k = *buf1 >> 4;
315
            j = *buf1 & 0x0f;
316
            buf1++;
317 2c4b4829 Benoit Fouet
            lv = j + cb_offset;
318 6f427ccb Benoit Fouet
319
            if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {
320
                cp2 = s->ModPred + ((lv - 8) << 7);
321
                cp = ref_frm_pos;
322
                for(i = 0; i < blks_width << 2; i++) {
323
                    int v = *cp >> 1;
324
                    *(cp++) = cp2[v];
325 deabd4fd Mike Melanson
                }
326 6f427ccb Benoit Fouet
            }
327 deabd4fd Mike Melanson
328 6f427ccb Benoit Fouet
            if(k == 1 || k == 4) {
329 2c4b4829 Benoit Fouet
                lv = (hdr[j] & 0xf) + cb_offset;
330 6f427ccb Benoit Fouet
                correction_type_sp[0] = s->corrector_type + (lv << 8);
331
                correction_lp[0] = correction + (lv << 8);
332 2c4b4829 Benoit Fouet
                lv = (hdr[j] >> 4) + cb_offset;
333 6f427ccb Benoit Fouet
                correction_lp[1] = correction + (lv << 8);
334
                correction_type_sp[1] = s->corrector_type + (lv << 8);
335
            } else {
336
                correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);
337
                correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);
338
                correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);
339
                correction_lp[0] = correction_lp[1] = correction + (lv << 8);
340 deabd4fd Mike Melanson
            }
341
342 6f427ccb Benoit Fouet
            switch(k) {
343
            case 1:
344
            case 0:                    /********** CASE 0 **********/
345
                for( ; blks_height > 0; blks_height -= 4) {
346
                    for(lp1 = 0; lp1 < blks_width; lp1++) {
347
                        for(lp2 = 0; lp2 < 4; ) {
348
                            k = *buf1++;
349
                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];
350
                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];
351
352
                            switch(correction_type_sp[0][k]) {
353
                            case 0:
354
                                *cur_lp = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
355
                                lp2++;
356
                                break;
357
                            case 1:
358
                                res = ((le2me_16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
359
                                ((unsigned short *)cur_lp)[0] = le2me_16(res);
360
                                res = ((le2me_16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
361
                                ((unsigned short *)cur_lp)[1] = le2me_16(res);
362
                                buf1++;
363
                                lp2++;
364
                                break;
365
                            case 2:
366
                                if(lp2 == 0) {
367
                                    for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])
368
                                        cur_lp[j] = ref_lp[j];
369
                                    lp2 += 2;
370
                                }
371
                                break;
372
                            case 3:
373
                                if(lp2 < 2) {
374
                                    for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])
375
                                        cur_lp[j] = ref_lp[j];
376
                                    lp2 = 3;
377
                                }
378
                                break;
379
                            case 8:
380
                                if(lp2 == 0) {
381
                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
382
383 b07e52a9 Benoit Fouet
                                    if(rle_v1 == 1 || ref_vectors != NULL) {
384
                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
385
                                            cur_lp[j] = ref_lp[j];
386
                                    }
387 6f427ccb Benoit Fouet
388
                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
389 b07e52a9 Benoit Fouet
                                    break;
390 6f427ccb Benoit Fouet
                                } else {
391
                                    rle_v1 = 1;
392
                                    rle_v2 = *buf1 - 1;
393
                                }
394
                            case 5:
395
                                LP2_CHECK(buf1,rle_v3,lp2)
396
                            case 4:
397
                                for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])
398
                                    cur_lp[j] = ref_lp[j];
399
                                lp2 = 4;
400
                                break;
401
402
                            case 7:
403
                                if(rle_v3 != 0)
404
                                    rle_v3 = 0;
405
                                else {
406
                                    buf1--;
407
                                    rle_v3 = 1;
408
                                }
409
                            case 6:
410
                                if(ref_vectors != NULL) {
411
                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
412
                                        cur_lp[j] = ref_lp[j];
413
                                }
414
                                lp2 = 4;
415
                                break;
416
417
                            case 9:
418
                                lv1 = *buf1++;
419
                                lv = (lv1 & 0x7F) << 1;
420
                                lv += (lv << 8);
421
                                lv += (lv << 16);
422
                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
423
                                    cur_lp[j] = lv;
424
425
                                LV1_CHECK(buf1,rle_v3,lv1,lp2)
426 b07e52a9 Benoit Fouet
                                break;
427 6f427ccb Benoit Fouet
                            default:
428
                                return;
429 deabd4fd Mike Melanson
                            }
430
                        }
431
432 6f427ccb Benoit Fouet
                        cur_frm_pos += 4;
433
                        ref_frm_pos += 4;
434
                    }
435 deabd4fd Mike Melanson
436 6f427ccb Benoit Fouet
                    cur_frm_pos += ((width - blks_width) * 4);
437
                    ref_frm_pos += ((width - blks_width) * 4);
438 deabd4fd Mike Melanson
                }
439 6f427ccb Benoit Fouet
                break;
440 deabd4fd Mike Melanson
441 6f427ccb Benoit Fouet
            case 4:
442
            case 3:                    /********** CASE 3 **********/
443
                if(ref_vectors != NULL)
444
                    return;
445
                flag1 = 1;
446
447
                for( ; blks_height > 0; blks_height -= 8) {
448
                    for(lp1 = 0; lp1 < blks_width; lp1++) {
449
                        for(lp2 = 0; lp2 < 4; ) {
450
                            k = *buf1++;
451
452
                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
453
                            ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
454
455
                            switch(correction_type_sp[lp2 & 0x01][k]) {
456
                            case 0:
457
                                cur_lp[width_tbl[1]] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
458
                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
459
                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
460
                                else
461
                                    cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
462
                                lp2++;
463
                                break;
464
465
                            case 1:
466
                                res = ((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
467
                                ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
468
                                res = ((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
469
                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
470
471
                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
472
                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
473
                                else
474
                                    cur_lp[0] = cur_lp[width_tbl[1]];
475
                                buf1++;
476
                                lp2++;
477
                                break;
478
479
                            case 2:
480
                                if(lp2 == 0) {
481
                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
482
                                        cur_lp[j] = *ref_lp;
483
                                    lp2 += 2;
484
                                }
485
                                break;
486
487
                            case 3:
488
                                if(lp2 < 2) {
489
                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
490
                                        cur_lp[j] = *ref_lp;
491
                                    lp2 = 3;
492
                                }
493
                                break;
494
495
                            case 6:
496
                                lp2 = 4;
497
                                break;
498
499
                            case 7:
500
                                if(rle_v3 != 0)
501
                                    rle_v3 = 0;
502
                                else {
503
                                    buf1--;
504
                                    rle_v3 = 1;
505
                                }
506
                                lp2 = 4;
507
                                break;
508
509
                            case 8:
510
                                if(lp2 == 0) {
511
                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
512
513
                                    if(rle_v1 == 1) {
514
                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
515
                                            cur_lp[j] = ref_lp[j];
516
                                    }
517
518
                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
519
                                    break;
520
                                } else {
521
                                    rle_v2 = (*buf1) - 1;
522
                                    rle_v1 = 1;
523
                                }
524
                            case 5:
525
                                LP2_CHECK(buf1,rle_v3,lp2)
526
                            case 4:
527
                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
528
                                    cur_lp[j] = *ref_lp;
529
                                lp2 = 4;
530
                                break;
531
532
                            case 9:
533
                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
534
                                lv1 = *buf1++;
535
                                lv = (lv1 & 0x7F) << 1;
536
                                lv += (lv << 8);
537
                                lv += (lv << 16);
538
539
                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
540
                                    cur_lp[j] = lv;
541
542
                                LV1_CHECK(buf1,rle_v3,lv1,lp2)
543
                                break;
544
545
                            default:
546
                                return;
547
                            }
548
                        }
549 deabd4fd Mike Melanson
550 6f427ccb Benoit Fouet
                        cur_frm_pos += 4;
551
                    }
552 deabd4fd Mike Melanson
553 6f427ccb Benoit Fouet
                    cur_frm_pos += (((width * 2) - blks_width) * 4);
554
                    flag1 = 0;
555
                }
556
                break;
557
558
            case 10:                    /********** CASE 10 **********/
559
                if(ref_vectors == NULL) {
560
                    flag1 = 1;
561
562
                    for( ; blks_height > 0; blks_height -= 8) {
563
                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
564
                            for(lp2 = 0; lp2 < 4; ) {
565
                                k = *buf1++;
566
                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
567
                                ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
568
                                lv1 = ref_lp[0];
569
                                lv2 = ref_lp[1];
570
                                if(lp2 == 0 && flag1 != 0) {
571
#ifdef WORDS_BIGENDIAN
572
                                    lv1 = lv1 & 0xFF00FF00;
573
                                    lv1 = (lv1 >> 8) | lv1;
574
                                    lv2 = lv2 & 0xFF00FF00;
575
                                    lv2 = (lv2 >> 8) | lv2;
576
#else
577
                                    lv1 = lv1 & 0x00FF00FF;
578
                                    lv1 = (lv1 << 8) | lv1;
579
                                    lv2 = lv2 & 0x00FF00FF;
580
                                    lv2 = (lv2 << 8) | lv2;
581
#endif
582
                                }
583
584
                                switch(correction_type_sp[lp2 & 0x01][k]) {
585
                                case 0:
586
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
587
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1);
588
                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
589
                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
590
                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
591
                                    } else {
592
                                        cur_lp[0] = cur_lp[width_tbl[1]];
593
                                        cur_lp[1] = cur_lp[width_tbl[1]+1];
594
                                    }
595
                                    lp2++;
596
                                    break;
597
598
                                case 1:
599
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1);
600
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
601
                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
602
                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
603
                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
604
                                    } else {
605
                                        cur_lp[0] = cur_lp[width_tbl[1]];
606
                                        cur_lp[1] = cur_lp[width_tbl[1]+1];
607
                                    }
608
                                    buf1++;
609
                                    lp2++;
610
                                    break;
611
612
                                case 2:
613
                                    if(lp2 == 0) {
614
                                        if(flag1 != 0) {
615
                                            for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {
616
                                                cur_lp[j] = lv1;
617
                                                cur_lp[j+1] = lv2;
618
                                            }
619
                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
620
                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
621
                                        } else {
622
                                            for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
623
                                                cur_lp[j] = lv1;
624
                                                cur_lp[j+1] = lv2;
625
                                            }
626
                                        }
627
                                        lp2 += 2;
628
                                    }
629
                                    break;
630
631
                                case 3:
632
                                    if(lp2 < 2) {
633
                                        if(lp2 == 0 && flag1 != 0) {
634
                                            for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {
635
                                                cur_lp[j] = lv1;
636
                                                cur_lp[j+1] = lv2;
637
                                            }
638
                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
639
                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
640
                                        } else {
641
                                            for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
642
                                                cur_lp[j] = lv1;
643
                                                cur_lp[j+1] = lv2;
644
                                            }
645
                                        }
646
                                        lp2 = 3;
647
                                    }
648
                                    break;
649
650
                                case 8:
651
                                    if(lp2 == 0) {
652
                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
653
                                        if(rle_v1 == 1) {
654
                                            if(flag1 != 0) {
655
                                                for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
656
                                                    cur_lp[j] = lv1;
657
                                                    cur_lp[j+1] = lv2;
658
                                                }
659
                                                cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
660
                                                cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
661
                                            } else {
662
                                                for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
663
                                                    cur_lp[j] = lv1;
664
                                                    cur_lp[j+1] = lv2;
665
                                                }
666
                                            }
667
                                        }
668
                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
669
                                        break;
670
                                    } else {
671
                                        rle_v1 = 1;
672
                                        rle_v2 = (*buf1) - 1;
673
                                    }
674
                                case 5:
675
                                    LP2_CHECK(buf1,rle_v3,lp2)
676
                                case 4:
677
                                    if(lp2 == 0 && flag1 != 0) {
678
                                        for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
679
                                            cur_lp[j] = lv1;
680
                                            cur_lp[j+1] = lv2;
681
                                        }
682
                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
683
                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
684
                                    } else {
685
                                        for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
686
                                            cur_lp[j] = lv1;
687
                                            cur_lp[j+1] = lv2;
688
                                        }
689
                                    }
690
                                    lp2 = 4;
691
                                    break;
692
693
                                case 6:
694
                                    lp2 = 4;
695
                                    break;
696
697
                                case 7:
698
                                    if(lp2 == 0) {
699
                                        if(rle_v3 != 0)
700
                                            rle_v3 = 0;
701
                                        else {
702
                                            buf1--;
703
                                            rle_v3 = 1;
704
                                        }
705
                                        lp2 = 4;
706
                                    }
707
                                    break;
708
709
                                case 9:
710
                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
711
                                    lv1 = *buf1;
712
                                    lv = (lv1 & 0x7F) << 1;
713
                                    lv += (lv << 8);
714
                                    lv += (lv << 16);
715
                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
716
                                        cur_lp[j] = lv;
717
                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)
718
                                    break;
719
720
                                default:
721
                                    return;
722
                                }
723
                            }
724 deabd4fd Mike Melanson
725 6f427ccb Benoit Fouet
                            cur_frm_pos += 8;
726
                        }
727 deabd4fd Mike Melanson
728 6f427ccb Benoit Fouet
                        cur_frm_pos += (((width * 2) - blks_width) * 4);
729
                        flag1 = 0;
730 deabd4fd Mike Melanson
                    }
731 6f427ccb Benoit Fouet
                } else {
732
                    for( ; blks_height > 0; blks_height -= 8) {
733
                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
734
                            for(lp2 = 0; lp2 < 4; ) {
735
                                k = *buf1++;
736
                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
737
                                ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
738
739
                                switch(correction_type_sp[lp2 & 0x01][k]) {
740
                                case 0:
741
                                    lv1 = correctionloworder_lp[lp2 & 0x01][k];
742
                                    lv2 = correctionhighorder_lp[lp2 & 0x01][k];
743
                                    cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
744
                                    cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
745
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
746
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
747
                                    lp2++;
748
                                    break;
749
750
                                case 1:
751
                                    lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];
752
                                    lv2 = correctionloworder_lp[lp2 & 0x01][k];
753
                                    cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
754
                                    cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
755
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
756
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
757
                                    lp2++;
758
                                    break;
759
760
                                case 2:
761
                                    if(lp2 == 0) {
762
                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
763
                                            cur_lp[j] = ref_lp[j];
764
                                            cur_lp[j+1] = ref_lp[j+1];
765
                                        }
766
                                        lp2 += 2;
767
                                    }
768
                                    break;
769
770
                                case 3:
771
                                    if(lp2 < 2) {
772
                                        for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
773
                                            cur_lp[j] = ref_lp[j];
774
                                            cur_lp[j+1] = ref_lp[j+1];
775
                                        }
776
                                        lp2 = 3;
777
                                    }
778
                                    break;
779
780
                                case 8:
781
                                    if(lp2 == 0) {
782
                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
783
                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
784
                                            ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
785
                                            ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];
786
                                        }
787
                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
788
                                        break;
789
                                    } else {
790
                                        rle_v1 = 1;
791
                                        rle_v2 = (*buf1) - 1;
792
                                    }
793
                                case 5:
794
                                case 7:
795
                                    LP2_CHECK(buf1,rle_v3,lp2)
796
                                case 6:
797
                                case 4:
798
                                    for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
799
                                        cur_lp[j] = ref_lp[j];
800
                                        cur_lp[j+1] = ref_lp[j+1];
801
                                    }
802
                                    lp2 = 4;
803
                                    break;
804
805
                                case 9:
806
                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
807
                                    lv1 = *buf1;
808
                                    lv = (lv1 & 0x7F) << 1;
809
                                    lv += (lv << 8);
810
                                    lv += (lv << 16);
811
                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
812
                                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;
813
                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)
814
                                    break;
815
816
                                default:
817
                                    return;
818
                                }
819
                            }
820 deabd4fd Mike Melanson
821 6f427ccb Benoit Fouet
                            cur_frm_pos += 8;
822
                            ref_frm_pos += 8;
823
                        }
824 deabd4fd Mike Melanson
825 6f427ccb Benoit Fouet
                        cur_frm_pos += (((width * 2) - blks_width) * 4);
826
                        ref_frm_pos += (((width * 2) - blks_width) * 4);
827 deabd4fd Mike Melanson
                    }
828
                }
829 6f427ccb Benoit Fouet
                break;
830 deabd4fd Mike Melanson
831 6f427ccb Benoit Fouet
            case 11:                    /********** CASE 11 **********/
832
                if(ref_vectors == NULL)
833
                    return;
834 deabd4fd Mike Melanson
835 6f427ccb Benoit Fouet
                for( ; blks_height > 0; blks_height -= 8) {
836
                    for(lp1 = 0; lp1 < blks_width; lp1++) {
837
                        for(lp2 = 0; lp2 < 4; ) {
838
                            k = *buf1++;
839
                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
840
                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
841
842
                            switch(correction_type_sp[lp2 & 0x01][k]) {
843
                            case 0:
844
                                cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
845
                                cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
846
                                lp2++;
847
                                break;
848
849
                            case 1:
850
                                lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);
851
                                lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);
852
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1);
853
                                ((unsigned short *)cur_lp)[0] = le2me_16(res);
854
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1);
855
                                ((unsigned short *)cur_lp)[1] = le2me_16(res);
856
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1);
857
                                ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
858
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1);
859
                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
860
                                lp2++;
861
                                break;
862
863
                            case 2:
864
                                if(lp2 == 0) {
865
                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
866
                                        cur_lp[j] = ref_lp[j];
867
                                    lp2 += 2;
868
                                }
869
                                break;
870
871
                            case 3:
872
                                if(lp2 < 2) {
873
                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
874
                                        cur_lp[j] = ref_lp[j];
875
                                    lp2 = 3;
876
                                }
877
                                break;
878
879
                            case 8:
880
                                if(lp2 == 0) {
881
                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
882
883
                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
884
                                        cur_lp[j] = ref_lp[j];
885
886
                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
887
                                    break;
888
                                } else {
889
                                    rle_v1 = 1;
890
                                    rle_v2 = (*buf1) - 1;
891
                                }
892
                            case 5:
893
                            case 7:
894
                                LP2_CHECK(buf1,rle_v3,lp2)
895
                            case 4:
896
                            case 6:
897
                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
898
                                    cur_lp[j] = ref_lp[j];
899
                                lp2 = 4;
900
                                break;
901
902
                            case 9:
903
                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
904
                                lv1 = *buf1++;
905
                                lv = (lv1 & 0x7F) << 1;
906
                                lv += (lv << 8);
907
                                lv += (lv << 16);
908
                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
909
                                    cur_lp[j] = lv;
910
                                LV1_CHECK(buf1,rle_v3,lv1,lp2)
911
                                break;
912
913
                            default:
914
                                return;
915
                            }
916
                        }
917 deabd4fd Mike Melanson
918 6f427ccb Benoit Fouet
                        cur_frm_pos += 4;
919
                        ref_frm_pos += 4;
920
                    }
921 deabd4fd Mike Melanson
922 6f427ccb Benoit Fouet
                    cur_frm_pos += (((width * 2) - blks_width) * 4);
923
                    ref_frm_pos += (((width * 2) - blks_width) * 4);
924
                }
925
                break;
926
927
            default:
928
                return;
929
            }
930
        }
931 deabd4fd Mike Melanson
932 6f427ccb Benoit Fouet
        if(strip < strip_tbl)
933
            return;
934 deabd4fd Mike Melanson
935 6f427ccb Benoit Fouet
        for( ; strip >= strip_tbl; strip--) {
936
            if(strip->split_flag != 0) {
937
                strip->split_flag = 0;
938
                strip->usl7 = (strip-1)->usl7;
939
940
                if(strip->split_direction) {
941
                    strip->xpos += strip->width;
942
                    strip->width = (strip-1)->width - strip->width;
943
                    if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)
944
                        strip->width = width - strip->xpos;
945
                } else {
946
                    strip->ypos += strip->height;
947
                    strip->height = (strip-1)->height - strip->height;
948
                }
949
                break;
950
            }
951 deabd4fd Mike Melanson
        }
952
    }
953
}
954
955 98a6fff9 Zuxy Meng
static av_cold int indeo3_decode_init(AVCodecContext *avctx)
956 deabd4fd Mike Melanson
{
957
    Indeo3DecodeContext *s = avctx->priv_data;
958 8b27f76b Benoit Fouet
    int ret = 0;
959 deabd4fd Mike Melanson
960
    s->avctx = avctx;
961
    s->width = avctx->width;
962
    s->height = avctx->height;
963
    avctx->pix_fmt = PIX_FMT_YUV410P;
964
965 8b27f76b Benoit Fouet
    if (!(ret = build_modpred(s)))
966 6f427ccb Benoit Fouet
        ret = iv_alloc_frames(s);
967 8b27f76b Benoit Fouet
    if (ret)
968 6f427ccb Benoit Fouet
        iv_free_func(s);
969 deabd4fd Mike Melanson
970 8b27f76b Benoit Fouet
    return ret;
971 deabd4fd Mike Melanson
}
972
973 21899717 Benoit Fouet
static unsigned long iv_decode_frame(Indeo3DecodeContext *s,
974
                                     const uint8_t *buf, int buf_size)
975
{
976 2c4b4829 Benoit Fouet
    unsigned int image_width, image_height,
977 21899717 Benoit Fouet
                 chroma_width, chroma_height;
978 2c4b4829 Benoit Fouet
    unsigned long flags, cb_offset, data_size,
979
                  y_offset, v_offset, u_offset, mc_vector_count;
980 21899717 Benoit Fouet
    const uint8_t *hdr_pos, *buf_pos;
981
982
    buf_pos = buf;
983 2c4b4829 Benoit Fouet
    buf_pos += 18; /* skip OS header (16 bytes) and version number */
984 21899717 Benoit Fouet
985 2c4b4829 Benoit Fouet
    flags = bytestream_get_le16(&buf_pos);
986
    data_size = bytestream_get_le32(&buf_pos);
987
    cb_offset = *buf_pos++;
988
    buf_pos += 3; /* skip reserved byte and checksum */
989
    image_height = bytestream_get_le16(&buf_pos);
990
    image_width  = bytestream_get_le16(&buf_pos);
991 21899717 Benoit Fouet
992 2c4b4829 Benoit Fouet
    if(avcodec_check_dimensions(NULL, image_width, image_height))
993 21899717 Benoit Fouet
        return -1;
994
995 2c4b4829 Benoit Fouet
    chroma_height = ((image_height >> 2) + 3) & 0x7ffc;
996
    chroma_width = ((image_width >> 2) + 3) & 0x7ffc;
997
    y_offset = bytestream_get_le32(&buf_pos);
998
    v_offset = bytestream_get_le32(&buf_pos);
999
    u_offset = bytestream_get_le32(&buf_pos);
1000
    buf_pos += 4; /* reserved */
1001 21899717 Benoit Fouet
    hdr_pos = buf_pos;
1002 2c4b4829 Benoit Fouet
    if(data_size == 0x80) return 4;
1003 21899717 Benoit Fouet
1004 2c4b4829 Benoit Fouet
    if(flags & 0x200) {
1005 21899717 Benoit Fouet
        s->cur_frame = s->iv_frame + 1;
1006
        s->ref_frame = s->iv_frame;
1007
    } else {
1008
        s->cur_frame = s->iv_frame;
1009
        s->ref_frame = s->iv_frame + 1;
1010
    }
1011
1012 2c4b4829 Benoit Fouet
    buf_pos = buf + 16 + y_offset;
1013
    mc_vector_count = bytestream_get_le32(&buf_pos);
1014 21899717 Benoit Fouet
1015 2c4b4829 Benoit Fouet
    iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width,
1016
                    image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1017
                    FFMIN(image_width, 160));
1018 21899717 Benoit Fouet
1019
    if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1020
    {
1021
1022 2c4b4829 Benoit Fouet
        buf_pos = buf + 16 + v_offset;
1023
        mc_vector_count = bytestream_get_le32(&buf_pos);
1024 21899717 Benoit Fouet
1025
        iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width,
1026 2c4b4829 Benoit Fouet
                chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1027 21899717 Benoit Fouet
                FFMIN(chroma_width, 40));
1028
1029 2c4b4829 Benoit Fouet
        buf_pos = buf + 16 + u_offset;
1030
        mc_vector_count = bytestream_get_le32(&buf_pos);
1031 21899717 Benoit Fouet
1032
        iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width,
1033 2c4b4829 Benoit Fouet
                chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1034 21899717 Benoit Fouet
                FFMIN(chroma_width, 40));
1035
1036
    }
1037
1038
    return 8;
1039
}
1040
1041 deabd4fd Mike Melanson
static int indeo3_decode_frame(AVCodecContext *avctx,
1042
                               void *data, int *data_size,
1043 68e9c68f Benoit Fouet
                               const uint8_t *buf, int buf_size)
1044 deabd4fd Mike Melanson
{
1045
    Indeo3DecodeContext *s=avctx->priv_data;
1046 68e9c68f Benoit Fouet
    uint8_t *src, *dest;
1047 deabd4fd Mike Melanson
    int y;
1048
1049
    iv_decode_frame(s, buf, buf_size);
1050
1051 e20c4069 Michael Niedermayer
    if(s->frame.data[0])
1052
        avctx->release_buffer(avctx, &s->frame);
1053
1054 deabd4fd Mike Melanson
    s->frame.reference = 0;
1055
    if(avctx->get_buffer(avctx, &s->frame) < 0) {
1056 9b879566 Michel Bardiaux
        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1057 deabd4fd Mike Melanson
        return -1;
1058
    }
1059
1060
    src = s->cur_frame->Ybuf;
1061
    dest = s->frame.data[0];
1062
    for (y = 0; y < s->height; y++) {
1063 6f427ccb Benoit Fouet
        memcpy(dest, src, s->cur_frame->y_w);
1064
        src += s->cur_frame->y_w;
1065
        dest += s->frame.linesize[0];
1066 deabd4fd Mike Melanson
    }
1067
1068 f970a8e6 Alex Beregszaszi
    if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1069
    {
1070 6f427ccb Benoit Fouet
        src = s->cur_frame->Ubuf;
1071
        dest = s->frame.data[1];
1072
        for (y = 0; y < s->height / 4; y++) {
1073
            memcpy(dest, src, s->cur_frame->uv_w);
1074
            src += s->cur_frame->uv_w;
1075
            dest += s->frame.linesize[1];
1076
        }
1077 deabd4fd Mike Melanson
1078 6f427ccb Benoit Fouet
        src = s->cur_frame->Vbuf;
1079
        dest = s->frame.data[2];
1080
        for (y = 0; y < s->height / 4; y++) {
1081
            memcpy(dest, src, s->cur_frame->uv_w);
1082
            src += s->cur_frame->uv_w;
1083
            dest += s->frame.linesize[2];
1084
        }
1085 f970a8e6 Alex Beregszaszi
    }
1086 deabd4fd Mike Melanson
1087
    *data_size=sizeof(AVFrame);
1088
    *(AVFrame*)data= s->frame;
1089
1090
    return buf_size;
1091
}
1092
1093 98a6fff9 Zuxy Meng
static av_cold int indeo3_decode_end(AVCodecContext *avctx)
1094 deabd4fd Mike Melanson
{
1095
    Indeo3DecodeContext *s = avctx->priv_data;
1096
1097
    iv_free_func(s);
1098
1099
    return 0;
1100
}
1101
1102
AVCodec indeo3_decoder = {
1103
    "indeo3",
1104
    CODEC_TYPE_VIDEO,
1105
    CODEC_ID_INDEO3,
1106
    sizeof(Indeo3DecodeContext),
1107
    indeo3_decode_init,
1108
    NULL,
1109
    indeo3_decode_end,
1110
    indeo3_decode_frame,
1111
    0,
1112 d5202e4f Stefano Sabatini
    NULL,
1113 fe4bf374 Stefano Sabatini
    .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
1114 deabd4fd Mike Melanson
};