Statistics
| Branch: | Revision:

ffmpeg / libavcodec / indeo3.c @ 63613fe6

History | View | Annotate | Download (47.4 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
26
#include "avcodec.h"
27
#include "dsputil.h"
28 972c99c1 Michael Niedermayer
#include "bytestream.h"
29 deabd4fd Mike Melanson
30
#include "indeo3data.h"
31
32
typedef struct
33
{
34 6f427ccb Benoit Fouet
    uint8_t *Ybuf;
35
    uint8_t *Ubuf;
36
    uint8_t *Vbuf;
37
    unsigned short y_w, y_h;
38
    unsigned short uv_w, uv_h;
39 deabd4fd Mike Melanson
} YUVBufs;
40
41
typedef struct Indeo3DecodeContext {
42
    AVCodecContext *avctx;
43
    int width, height;
44
    AVFrame frame;
45
46 ffc64ac0 Benoit Fouet
    uint8_t *buf;
47 deabd4fd Mike Melanson
    YUVBufs iv_frame[2];
48
    YUVBufs *cur_frame;
49
    YUVBufs *ref_frame;
50
51 68e9c68f Benoit Fouet
    uint8_t *ModPred;
52 e679560d Benoit Fouet
    uint8_t *corrector_type;
53 deabd4fd Mike Melanson
} Indeo3DecodeContext;
54
55 9fd88b29 Benoit Fouet
static const uint8_t corrector_type_0[24] = {
56 6f427ccb Benoit Fouet
    195, 159, 133, 115, 101,  93,  87,  77,
57
    195, 159, 133, 115, 101,  93,  87,  77,
58
    128,  79,  79,  79,  79,  79,  79,  79
59 deabd4fd Mike Melanson
};
60
61 9fd88b29 Benoit Fouet
static const uint8_t corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
62 deabd4fd Mike Melanson
63 8b27f76b Benoit Fouet
static av_cold int build_modpred(Indeo3DecodeContext *s)
64 deabd4fd Mike Melanson
{
65 6f427ccb Benoit Fouet
    int i, j;
66
67
    if (!(s->ModPred = av_malloc(8 * 128)))
68
        return AVERROR(ENOMEM);
69
70
    for (i=0; i < 128; ++i) {
71
        s->ModPred[i+0*128] = i >  126 ? 254 : 2*(i + 1 - ((i + 1) % 2));
72
        s->ModPred[i+1*128] = i ==   7 ?  20 :
73
                              i == 119 ||
74
                              i == 120 ? 236 : 2*(i + 2 - ((i + 1) % 3));
75
        s->ModPred[i+2*128] = i >  125 ? 248 : 2*(i + 2 - ((i + 2) % 4));
76
        s->ModPred[i+3*128] =                  2*(i + 1 - ((i - 3) % 5));
77
        s->ModPred[i+4*128] = i ==   8 ?  20 : 2*(i + 1 - ((i - 3) % 6));
78
        s->ModPred[i+5*128] =                  2*(i + 4 - ((i + 3) % 7));
79
        s->ModPred[i+6*128] = i >  123 ? 240 : 2*(i + 4 - ((i + 4) % 8));
80
        s->ModPred[i+7*128] =                  2*(i + 5 - ((i + 4) % 9));
81
    }
82
83
    if (!(s->corrector_type = av_malloc(24 * 256)))
84
        return AVERROR(ENOMEM);
85
86
    for (i=0; i < 24; ++i) {
87
        for (j=0; j < 256; ++j) {
88
            s->corrector_type[i*256+j] = j < corrector_type_0[i]          ? 1 :
89
                                         j < 248 || (i == 16 && j == 248) ? 0 :
90
                                         corrector_type_2[j - 248];
91
        }
92 deabd4fd Mike Melanson
    }
93 8b27f76b Benoit Fouet
94
  return 0;
95 deabd4fd Mike Melanson
}
96
97 8b27f76b Benoit Fouet
static av_cold int iv_alloc_frames(Indeo3DecodeContext *s)
98 deabd4fd Mike Melanson
{
99 96320336 Benoit Fouet
    int luma_width    = (s->width           + 3) & ~3,
100
        luma_height   = (s->height          + 3) & ~3,
101
        chroma_width  = ((luma_width  >> 2) + 3) & ~3,
102
        chroma_height = ((luma_height >> 2) + 3) & ~3,
103
        luma_pixels   = luma_width   * luma_height,
104
        chroma_pixels = chroma_width * chroma_height,
105
        i;
106
    unsigned int bufsize = luma_pixels * 2 + luma_width * 3 +
107
                          (chroma_pixels   + chroma_width) * 4;
108 6f427ccb Benoit Fouet
109 16c83185 Reimar Döffinger
    av_freep(&s->buf);
110 6f427ccb Benoit Fouet
    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 4f76697b Reimar Döffinger
    av_freep(&s->buf);
146
    av_freep(&s->ModPred);
147
    av_freep(&s->corrector_type);
148 deabd4fd Mike Melanson
}
149
150 bda4e394 Diego Biurrun
struct ustr {
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 bda4e394 Diego Biurrun
};
159 deabd4fd Mike Melanson
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 bda4e394 Diego Biurrun
    struct ustr strip_tbl[20], *strip;
217 6f427ccb Benoit Fouet
    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 a44cb89b Benoit Fouet
            if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) {
256
                av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n");
257
                break;
258
            }
259 1238fa9f Aurelien Jacobs
            memcpy(strip, strip-1, sizeof(*strip));
260 6f427ccb Benoit Fouet
            strip->split_flag = 1;
261
            strip->split_direction = 0;
262
            strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);
263
            continue;
264
        } else if(cmd == 1) {
265
            strip++;
266 a44cb89b Benoit Fouet
            if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) {
267
                av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n");
268
                break;
269
            }
270 1238fa9f Aurelien Jacobs
            memcpy(strip, strip-1, sizeof(*strip));
271 6f427ccb Benoit Fouet
            strip->split_flag = 1;
272
            strip->split_direction = 1;
273
            strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);
274
            continue;
275
        } else if(cmd == 2) {
276
            if(strip->usl7 == 0) {
277
                strip->usl7 = 1;
278
                ref_vectors = NULL;
279
                continue;
280
            }
281
        } else if(cmd == 3) {
282
            if(strip->usl7 == 0) {
283
                strip->usl7 = 1;
284
                ref_vectors = (const signed char*)buf2 + (*buf1 * 2);
285
                buf1++;
286
                continue;
287 deabd4fd Mike Melanson
            }
288 6f427ccb Benoit Fouet
        }
289 deabd4fd Mike Melanson
290 6f427ccb Benoit Fouet
        cur_frm_pos = cur + width * strip->ypos + strip->xpos;
291 deabd4fd Mike Melanson
292 6f427ccb Benoit Fouet
        if((blks_width = strip->width) < 0)
293
            blks_width += 3;
294
        blks_width >>= 2;
295
        blks_height = strip->height;
296 deabd4fd Mike Melanson
297 6f427ccb Benoit Fouet
        if(ref_vectors != NULL) {
298
            ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +
299
                ref_vectors[1] + strip->xpos;
300
        } else
301
            ref_frm_pos = cur_frm_pos - width_tbl[4];
302
303
        if(cmd == 2) {
304
            if(bit_pos <= 0) {
305
                bit_pos = 8;
306
                bit_buf = *buf1++;
307
            }
308
309
            bit_pos -= 2;
310
            cmd = (bit_buf >> bit_pos) & 0x03;
311
312
            if(cmd == 0 || ref_vectors != NULL) {
313
                for(lp1 = 0; lp1 < blks_width; lp1++) {
314
                    for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])
315
                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
316
                    cur_frm_pos += 4;
317
                    ref_frm_pos += 4;
318
                }
319
            } else if(cmd != 1)
320
                return;
321
        } else {
322
            k = *buf1 >> 4;
323
            j = *buf1 & 0x0f;
324
            buf1++;
325 2c4b4829 Benoit Fouet
            lv = j + cb_offset;
326 6f427ccb Benoit Fouet
327
            if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {
328
                cp2 = s->ModPred + ((lv - 8) << 7);
329
                cp = ref_frm_pos;
330
                for(i = 0; i < blks_width << 2; i++) {
331
                    int v = *cp >> 1;
332
                    *(cp++) = cp2[v];
333 deabd4fd Mike Melanson
                }
334 6f427ccb Benoit Fouet
            }
335 deabd4fd Mike Melanson
336 6f427ccb Benoit Fouet
            if(k == 1 || k == 4) {
337 2c4b4829 Benoit Fouet
                lv = (hdr[j] & 0xf) + cb_offset;
338 6f427ccb Benoit Fouet
                correction_type_sp[0] = s->corrector_type + (lv << 8);
339
                correction_lp[0] = correction + (lv << 8);
340 2c4b4829 Benoit Fouet
                lv = (hdr[j] >> 4) + cb_offset;
341 6f427ccb Benoit Fouet
                correction_lp[1] = correction + (lv << 8);
342
                correction_type_sp[1] = s->corrector_type + (lv << 8);
343
            } else {
344
                correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);
345
                correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);
346
                correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);
347
                correction_lp[0] = correction_lp[1] = correction + (lv << 8);
348 deabd4fd Mike Melanson
            }
349
350 6f427ccb Benoit Fouet
            switch(k) {
351
            case 1:
352
            case 0:                    /********** CASE 0 **********/
353
                for( ; blks_height > 0; blks_height -= 4) {
354
                    for(lp1 = 0; lp1 < blks_width; lp1++) {
355
                        for(lp2 = 0; lp2 < 4; ) {
356
                            k = *buf1++;
357
                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];
358
                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];
359
360
                            switch(correction_type_sp[0][k]) {
361
                            case 0:
362
                                *cur_lp = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
363
                                lp2++;
364
                                break;
365
                            case 1:
366
                                res = ((le2me_16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
367
                                ((unsigned short *)cur_lp)[0] = le2me_16(res);
368
                                res = ((le2me_16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
369
                                ((unsigned short *)cur_lp)[1] = le2me_16(res);
370
                                buf1++;
371
                                lp2++;
372
                                break;
373
                            case 2:
374
                                if(lp2 == 0) {
375
                                    for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])
376
                                        cur_lp[j] = ref_lp[j];
377
                                    lp2 += 2;
378
                                }
379
                                break;
380
                            case 3:
381
                                if(lp2 < 2) {
382
                                    for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])
383
                                        cur_lp[j] = ref_lp[j];
384
                                    lp2 = 3;
385
                                }
386
                                break;
387
                            case 8:
388
                                if(lp2 == 0) {
389
                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
390
391 b07e52a9 Benoit Fouet
                                    if(rle_v1 == 1 || ref_vectors != NULL) {
392
                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
393
                                            cur_lp[j] = ref_lp[j];
394
                                    }
395 6f427ccb Benoit Fouet
396
                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
397 b07e52a9 Benoit Fouet
                                    break;
398 6f427ccb Benoit Fouet
                                } else {
399
                                    rle_v1 = 1;
400
                                    rle_v2 = *buf1 - 1;
401
                                }
402
                            case 5:
403
                                LP2_CHECK(buf1,rle_v3,lp2)
404
                            case 4:
405
                                for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])
406
                                    cur_lp[j] = ref_lp[j];
407
                                lp2 = 4;
408
                                break;
409
410
                            case 7:
411
                                if(rle_v3 != 0)
412
                                    rle_v3 = 0;
413
                                else {
414
                                    buf1--;
415
                                    rle_v3 = 1;
416
                                }
417
                            case 6:
418
                                if(ref_vectors != NULL) {
419
                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
420
                                        cur_lp[j] = ref_lp[j];
421
                                }
422
                                lp2 = 4;
423
                                break;
424
425
                            case 9:
426
                                lv1 = *buf1++;
427
                                lv = (lv1 & 0x7F) << 1;
428
                                lv += (lv << 8);
429
                                lv += (lv << 16);
430
                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
431
                                    cur_lp[j] = lv;
432
433
                                LV1_CHECK(buf1,rle_v3,lv1,lp2)
434 b07e52a9 Benoit Fouet
                                break;
435 6f427ccb Benoit Fouet
                            default:
436
                                return;
437 deabd4fd Mike Melanson
                            }
438
                        }
439
440 6f427ccb Benoit Fouet
                        cur_frm_pos += 4;
441
                        ref_frm_pos += 4;
442
                    }
443 deabd4fd Mike Melanson
444 6f427ccb Benoit Fouet
                    cur_frm_pos += ((width - blks_width) * 4);
445
                    ref_frm_pos += ((width - blks_width) * 4);
446 deabd4fd Mike Melanson
                }
447 6f427ccb Benoit Fouet
                break;
448 deabd4fd Mike Melanson
449 6f427ccb Benoit Fouet
            case 4:
450
            case 3:                    /********** CASE 3 **********/
451
                if(ref_vectors != NULL)
452
                    return;
453
                flag1 = 1;
454
455
                for( ; blks_height > 0; blks_height -= 8) {
456
                    for(lp1 = 0; lp1 < blks_width; lp1++) {
457
                        for(lp2 = 0; lp2 < 4; ) {
458
                            k = *buf1++;
459
460
                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
461
                            ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
462
463
                            switch(correction_type_sp[lp2 & 0x01][k]) {
464
                            case 0:
465
                                cur_lp[width_tbl[1]] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
466
                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
467
                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
468
                                else
469
                                    cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
470
                                lp2++;
471
                                break;
472
473
                            case 1:
474
                                res = ((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
475
                                ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
476
                                res = ((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
477
                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
478
479
                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
480
                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
481
                                else
482
                                    cur_lp[0] = cur_lp[width_tbl[1]];
483
                                buf1++;
484
                                lp2++;
485
                                break;
486
487
                            case 2:
488
                                if(lp2 == 0) {
489
                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
490
                                        cur_lp[j] = *ref_lp;
491
                                    lp2 += 2;
492
                                }
493
                                break;
494
495
                            case 3:
496
                                if(lp2 < 2) {
497
                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
498
                                        cur_lp[j] = *ref_lp;
499
                                    lp2 = 3;
500
                                }
501
                                break;
502
503
                            case 6:
504
                                lp2 = 4;
505
                                break;
506
507
                            case 7:
508
                                if(rle_v3 != 0)
509
                                    rle_v3 = 0;
510
                                else {
511
                                    buf1--;
512
                                    rle_v3 = 1;
513
                                }
514
                                lp2 = 4;
515
                                break;
516
517
                            case 8:
518
                                if(lp2 == 0) {
519
                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
520
521
                                    if(rle_v1 == 1) {
522
                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
523
                                            cur_lp[j] = ref_lp[j];
524
                                    }
525
526
                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
527
                                    break;
528
                                } else {
529
                                    rle_v2 = (*buf1) - 1;
530
                                    rle_v1 = 1;
531
                                }
532
                            case 5:
533
                                LP2_CHECK(buf1,rle_v3,lp2)
534
                            case 4:
535
                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
536
                                    cur_lp[j] = *ref_lp;
537
                                lp2 = 4;
538
                                break;
539
540
                            case 9:
541
                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
542
                                lv1 = *buf1++;
543
                                lv = (lv1 & 0x7F) << 1;
544
                                lv += (lv << 8);
545
                                lv += (lv << 16);
546
547
                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
548
                                    cur_lp[j] = lv;
549
550
                                LV1_CHECK(buf1,rle_v3,lv1,lp2)
551
                                break;
552
553
                            default:
554
                                return;
555
                            }
556
                        }
557 deabd4fd Mike Melanson
558 6f427ccb Benoit Fouet
                        cur_frm_pos += 4;
559
                    }
560 deabd4fd Mike Melanson
561 6f427ccb Benoit Fouet
                    cur_frm_pos += (((width * 2) - blks_width) * 4);
562
                    flag1 = 0;
563
                }
564
                break;
565
566
            case 10:                    /********** CASE 10 **********/
567
                if(ref_vectors == NULL) {
568
                    flag1 = 1;
569
570
                    for( ; blks_height > 0; blks_height -= 8) {
571
                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
572
                            for(lp2 = 0; lp2 < 4; ) {
573
                                k = *buf1++;
574
                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
575
                                ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
576
                                lv1 = ref_lp[0];
577
                                lv2 = ref_lp[1];
578
                                if(lp2 == 0 && flag1 != 0) {
579 63613fe6 Måns Rullgård
#if HAVE_BIGENDIAN
580 6f427ccb Benoit Fouet
                                    lv1 = lv1 & 0xFF00FF00;
581
                                    lv1 = (lv1 >> 8) | lv1;
582
                                    lv2 = lv2 & 0xFF00FF00;
583
                                    lv2 = (lv2 >> 8) | lv2;
584
#else
585
                                    lv1 = lv1 & 0x00FF00FF;
586
                                    lv1 = (lv1 << 8) | lv1;
587
                                    lv2 = lv2 & 0x00FF00FF;
588
                                    lv2 = (lv2 << 8) | lv2;
589
#endif
590
                                }
591
592
                                switch(correction_type_sp[lp2 & 0x01][k]) {
593
                                case 0:
594
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
595
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1);
596
                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
597
                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
598
                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
599
                                    } else {
600
                                        cur_lp[0] = cur_lp[width_tbl[1]];
601
                                        cur_lp[1] = cur_lp[width_tbl[1]+1];
602
                                    }
603
                                    lp2++;
604
                                    break;
605
606
                                case 1:
607
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1);
608
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
609
                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
610
                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
611
                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
612
                                    } else {
613
                                        cur_lp[0] = cur_lp[width_tbl[1]];
614
                                        cur_lp[1] = cur_lp[width_tbl[1]+1];
615
                                    }
616
                                    buf1++;
617
                                    lp2++;
618
                                    break;
619
620
                                case 2:
621
                                    if(lp2 == 0) {
622
                                        if(flag1 != 0) {
623
                                            for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {
624
                                                cur_lp[j] = lv1;
625
                                                cur_lp[j+1] = lv2;
626
                                            }
627
                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
628
                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
629
                                        } else {
630
                                            for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
631
                                                cur_lp[j] = lv1;
632
                                                cur_lp[j+1] = lv2;
633
                                            }
634
                                        }
635
                                        lp2 += 2;
636
                                    }
637
                                    break;
638
639
                                case 3:
640
                                    if(lp2 < 2) {
641
                                        if(lp2 == 0 && flag1 != 0) {
642
                                            for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {
643
                                                cur_lp[j] = lv1;
644
                                                cur_lp[j+1] = lv2;
645
                                            }
646
                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
647
                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
648
                                        } else {
649
                                            for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
650
                                                cur_lp[j] = lv1;
651
                                                cur_lp[j+1] = lv2;
652
                                            }
653
                                        }
654
                                        lp2 = 3;
655
                                    }
656
                                    break;
657
658
                                case 8:
659
                                    if(lp2 == 0) {
660
                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
661
                                        if(rle_v1 == 1) {
662
                                            if(flag1 != 0) {
663
                                                for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
664
                                                    cur_lp[j] = lv1;
665
                                                    cur_lp[j+1] = lv2;
666
                                                }
667
                                                cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
668
                                                cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
669
                                            } else {
670
                                                for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
671
                                                    cur_lp[j] = lv1;
672
                                                    cur_lp[j+1] = lv2;
673
                                                }
674
                                            }
675
                                        }
676
                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
677
                                        break;
678
                                    } else {
679
                                        rle_v1 = 1;
680
                                        rle_v2 = (*buf1) - 1;
681
                                    }
682
                                case 5:
683
                                    LP2_CHECK(buf1,rle_v3,lp2)
684
                                case 4:
685
                                    if(lp2 == 0 && flag1 != 0) {
686
                                        for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
687
                                            cur_lp[j] = lv1;
688
                                            cur_lp[j+1] = lv2;
689
                                        }
690
                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
691
                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
692
                                    } else {
693
                                        for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
694
                                            cur_lp[j] = lv1;
695
                                            cur_lp[j+1] = lv2;
696
                                        }
697
                                    }
698
                                    lp2 = 4;
699
                                    break;
700
701
                                case 6:
702
                                    lp2 = 4;
703
                                    break;
704
705
                                case 7:
706
                                    if(lp2 == 0) {
707
                                        if(rle_v3 != 0)
708
                                            rle_v3 = 0;
709
                                        else {
710
                                            buf1--;
711
                                            rle_v3 = 1;
712
                                        }
713
                                        lp2 = 4;
714
                                    }
715
                                    break;
716
717
                                case 9:
718
                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
719
                                    lv1 = *buf1;
720
                                    lv = (lv1 & 0x7F) << 1;
721
                                    lv += (lv << 8);
722
                                    lv += (lv << 16);
723
                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
724
                                        cur_lp[j] = lv;
725
                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)
726
                                    break;
727
728
                                default:
729
                                    return;
730
                                }
731
                            }
732 deabd4fd Mike Melanson
733 6f427ccb Benoit Fouet
                            cur_frm_pos += 8;
734
                        }
735 deabd4fd Mike Melanson
736 6f427ccb Benoit Fouet
                        cur_frm_pos += (((width * 2) - blks_width) * 4);
737
                        flag1 = 0;
738 deabd4fd Mike Melanson
                    }
739 6f427ccb Benoit Fouet
                } else {
740
                    for( ; blks_height > 0; blks_height -= 8) {
741
                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
742
                            for(lp2 = 0; lp2 < 4; ) {
743
                                k = *buf1++;
744
                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
745
                                ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
746
747
                                switch(correction_type_sp[lp2 & 0x01][k]) {
748
                                case 0:
749
                                    lv1 = correctionloworder_lp[lp2 & 0x01][k];
750
                                    lv2 = correctionhighorder_lp[lp2 & 0x01][k];
751
                                    cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
752
                                    cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
753
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
754
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
755
                                    lp2++;
756
                                    break;
757
758
                                case 1:
759
                                    lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];
760
                                    lv2 = correctionloworder_lp[lp2 & 0x01][k];
761
                                    cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
762
                                    cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
763
                                    cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
764
                                    cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
765
                                    lp2++;
766
                                    break;
767
768
                                case 2:
769
                                    if(lp2 == 0) {
770
                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
771
                                            cur_lp[j] = ref_lp[j];
772
                                            cur_lp[j+1] = ref_lp[j+1];
773
                                        }
774
                                        lp2 += 2;
775
                                    }
776
                                    break;
777
778
                                case 3:
779
                                    if(lp2 < 2) {
780
                                        for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
781
                                            cur_lp[j] = ref_lp[j];
782
                                            cur_lp[j+1] = ref_lp[j+1];
783
                                        }
784
                                        lp2 = 3;
785
                                    }
786
                                    break;
787
788
                                case 8:
789
                                    if(lp2 == 0) {
790
                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
791
                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
792
                                            ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
793
                                            ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];
794
                                        }
795
                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
796
                                        break;
797
                                    } else {
798
                                        rle_v1 = 1;
799
                                        rle_v2 = (*buf1) - 1;
800
                                    }
801
                                case 5:
802
                                case 7:
803
                                    LP2_CHECK(buf1,rle_v3,lp2)
804
                                case 6:
805
                                case 4:
806
                                    for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
807
                                        cur_lp[j] = ref_lp[j];
808
                                        cur_lp[j+1] = ref_lp[j+1];
809
                                    }
810
                                    lp2 = 4;
811
                                    break;
812
813
                                case 9:
814
                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
815
                                    lv1 = *buf1;
816
                                    lv = (lv1 & 0x7F) << 1;
817
                                    lv += (lv << 8);
818
                                    lv += (lv << 16);
819
                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
820
                                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;
821
                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)
822
                                    break;
823
824
                                default:
825
                                    return;
826
                                }
827
                            }
828 deabd4fd Mike Melanson
829 6f427ccb Benoit Fouet
                            cur_frm_pos += 8;
830
                            ref_frm_pos += 8;
831
                        }
832 deabd4fd Mike Melanson
833 6f427ccb Benoit Fouet
                        cur_frm_pos += (((width * 2) - blks_width) * 4);
834
                        ref_frm_pos += (((width * 2) - blks_width) * 4);
835 deabd4fd Mike Melanson
                    }
836
                }
837 6f427ccb Benoit Fouet
                break;
838 deabd4fd Mike Melanson
839 6f427ccb Benoit Fouet
            case 11:                    /********** CASE 11 **********/
840
                if(ref_vectors == NULL)
841
                    return;
842 deabd4fd Mike Melanson
843 6f427ccb Benoit Fouet
                for( ; blks_height > 0; blks_height -= 8) {
844
                    for(lp1 = 0; lp1 < blks_width; lp1++) {
845
                        for(lp2 = 0; lp2 < 4; ) {
846
                            k = *buf1++;
847
                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
848
                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
849
850
                            switch(correction_type_sp[lp2 & 0x01][k]) {
851
                            case 0:
852
                                cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
853
                                cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
854
                                lp2++;
855
                                break;
856
857
                            case 1:
858
                                lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);
859
                                lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);
860
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1);
861
                                ((unsigned short *)cur_lp)[0] = le2me_16(res);
862
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1);
863
                                ((unsigned short *)cur_lp)[1] = le2me_16(res);
864
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1);
865
                                ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
866
                                res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1);
867
                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
868
                                lp2++;
869
                                break;
870
871
                            case 2:
872
                                if(lp2 == 0) {
873
                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
874
                                        cur_lp[j] = ref_lp[j];
875
                                    lp2 += 2;
876
                                }
877
                                break;
878
879
                            case 3:
880
                                if(lp2 < 2) {
881
                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
882
                                        cur_lp[j] = ref_lp[j];
883
                                    lp2 = 3;
884
                                }
885
                                break;
886
887
                            case 8:
888
                                if(lp2 == 0) {
889
                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
890
891
                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
892
                                        cur_lp[j] = ref_lp[j];
893
894
                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
895
                                    break;
896
                                } else {
897
                                    rle_v1 = 1;
898
                                    rle_v2 = (*buf1) - 1;
899
                                }
900
                            case 5:
901
                            case 7:
902
                                LP2_CHECK(buf1,rle_v3,lp2)
903
                            case 4:
904
                            case 6:
905
                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
906
                                    cur_lp[j] = ref_lp[j];
907
                                lp2 = 4;
908
                                break;
909
910
                            case 9:
911
                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
912
                                lv1 = *buf1++;
913
                                lv = (lv1 & 0x7F) << 1;
914
                                lv += (lv << 8);
915
                                lv += (lv << 16);
916
                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
917
                                    cur_lp[j] = lv;
918
                                LV1_CHECK(buf1,rle_v3,lv1,lp2)
919
                                break;
920
921
                            default:
922
                                return;
923
                            }
924
                        }
925 deabd4fd Mike Melanson
926 6f427ccb Benoit Fouet
                        cur_frm_pos += 4;
927
                        ref_frm_pos += 4;
928
                    }
929 deabd4fd Mike Melanson
930 6f427ccb Benoit Fouet
                    cur_frm_pos += (((width * 2) - blks_width) * 4);
931
                    ref_frm_pos += (((width * 2) - blks_width) * 4);
932
                }
933
                break;
934
935
            default:
936
                return;
937
            }
938
        }
939 deabd4fd Mike Melanson
940 6f427ccb Benoit Fouet
        for( ; strip >= strip_tbl; strip--) {
941
            if(strip->split_flag != 0) {
942
                strip->split_flag = 0;
943
                strip->usl7 = (strip-1)->usl7;
944
945
                if(strip->split_direction) {
946
                    strip->xpos += strip->width;
947
                    strip->width = (strip-1)->width - strip->width;
948
                    if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)
949
                        strip->width = width - strip->xpos;
950
                } else {
951
                    strip->ypos += strip->height;
952
                    strip->height = (strip-1)->height - strip->height;
953
                }
954
                break;
955
            }
956 deabd4fd Mike Melanson
        }
957
    }
958
}
959
960 98a6fff9 Zuxy Meng
static av_cold int indeo3_decode_init(AVCodecContext *avctx)
961 deabd4fd Mike Melanson
{
962
    Indeo3DecodeContext *s = avctx->priv_data;
963 8b27f76b Benoit Fouet
    int ret = 0;
964 deabd4fd Mike Melanson
965
    s->avctx = avctx;
966
    s->width = avctx->width;
967
    s->height = avctx->height;
968
    avctx->pix_fmt = PIX_FMT_YUV410P;
969
970 8b27f76b Benoit Fouet
    if (!(ret = build_modpred(s)))
971 6f427ccb Benoit Fouet
        ret = iv_alloc_frames(s);
972 8b27f76b Benoit Fouet
    if (ret)
973 6f427ccb Benoit Fouet
        iv_free_func(s);
974 deabd4fd Mike Melanson
975 8b27f76b Benoit Fouet
    return ret;
976 deabd4fd Mike Melanson
}
977
978 28bcc76a Reimar Döffinger
static int iv_decode_frame(AVCodecContext *avctx,
979 d42e44a0 Alex Converse
                           const uint8_t *buf, int buf_size)
980 21899717 Benoit Fouet
{
981 28bcc76a Reimar Döffinger
    Indeo3DecodeContext *s = avctx->priv_data;
982 2c4b4829 Benoit Fouet
    unsigned int image_width, image_height,
983 21899717 Benoit Fouet
                 chroma_width, chroma_height;
984 2c4b4829 Benoit Fouet
    unsigned long flags, cb_offset, data_size,
985
                  y_offset, v_offset, u_offset, mc_vector_count;
986 21899717 Benoit Fouet
    const uint8_t *hdr_pos, *buf_pos;
987
988
    buf_pos = buf;
989 2c4b4829 Benoit Fouet
    buf_pos += 18; /* skip OS header (16 bytes) and version number */
990 21899717 Benoit Fouet
991 2c4b4829 Benoit Fouet
    flags = bytestream_get_le16(&buf_pos);
992
    data_size = bytestream_get_le32(&buf_pos);
993
    cb_offset = *buf_pos++;
994
    buf_pos += 3; /* skip reserved byte and checksum */
995
    image_height = bytestream_get_le16(&buf_pos);
996
    image_width  = bytestream_get_le16(&buf_pos);
997 21899717 Benoit Fouet
998 28bcc76a Reimar Döffinger
    if(avcodec_check_dimensions(avctx, image_width, image_height))
999 21899717 Benoit Fouet
        return -1;
1000 16c83185 Reimar Döffinger
    if (image_width != avctx->width || image_height != avctx->height) {
1001
        int ret;
1002
        avcodec_set_dimensions(avctx, image_width, image_height);
1003
        s->width  = avctx->width;
1004
        s->height = avctx->height;
1005
        ret = iv_alloc_frames(s);
1006
        if (ret < 0) {
1007
            s->width = s->height = 0;
1008
            return ret;
1009
        }
1010
    }
1011 21899717 Benoit Fouet
1012 2c4b4829 Benoit Fouet
    chroma_height = ((image_height >> 2) + 3) & 0x7ffc;
1013
    chroma_width = ((image_width >> 2) + 3) & 0x7ffc;
1014
    y_offset = bytestream_get_le32(&buf_pos);
1015
    v_offset = bytestream_get_le32(&buf_pos);
1016
    u_offset = bytestream_get_le32(&buf_pos);
1017
    buf_pos += 4; /* reserved */
1018 21899717 Benoit Fouet
    hdr_pos = buf_pos;
1019 2c4b4829 Benoit Fouet
    if(data_size == 0x80) return 4;
1020 21899717 Benoit Fouet
1021 274aa1d0 Alex Converse
    if(FFMAX3(y_offset, v_offset, u_offset) >= buf_size-16) {
1022
        av_log(s->avctx, AV_LOG_ERROR, "y/u/v offset outside buffer\n");
1023
        return -1;
1024
    }
1025
1026 2c4b4829 Benoit Fouet
    if(flags & 0x200) {
1027 21899717 Benoit Fouet
        s->cur_frame = s->iv_frame + 1;
1028
        s->ref_frame = s->iv_frame;
1029
    } else {
1030
        s->cur_frame = s->iv_frame;
1031
        s->ref_frame = s->iv_frame + 1;
1032
    }
1033
1034 2c4b4829 Benoit Fouet
    buf_pos = buf + 16 + y_offset;
1035
    mc_vector_count = bytestream_get_le32(&buf_pos);
1036 274aa1d0 Alex Converse
    if(2LL*mc_vector_count >= buf_size-16-y_offset) {
1037
        av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
1038
        return -1;
1039
    }
1040 21899717 Benoit Fouet
1041 2c4b4829 Benoit Fouet
    iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width,
1042
                    image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1043
                    FFMIN(image_width, 160));
1044 21899717 Benoit Fouet
1045
    if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1046
    {
1047
1048 2c4b4829 Benoit Fouet
        buf_pos = buf + 16 + v_offset;
1049
        mc_vector_count = bytestream_get_le32(&buf_pos);
1050 274aa1d0 Alex Converse
        if(2LL*mc_vector_count >= buf_size-16-v_offset) {
1051
            av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
1052
            return -1;
1053
        }
1054 21899717 Benoit Fouet
1055
        iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width,
1056 2c4b4829 Benoit Fouet
                chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1057 21899717 Benoit Fouet
                FFMIN(chroma_width, 40));
1058
1059 2c4b4829 Benoit Fouet
        buf_pos = buf + 16 + u_offset;
1060
        mc_vector_count = bytestream_get_le32(&buf_pos);
1061 274aa1d0 Alex Converse
        if(2LL*mc_vector_count >= buf_size-16-u_offset) {
1062
            av_log(s->avctx, AV_LOG_ERROR, "mc_vector_count too large\n");
1063
            return -1;
1064
        }
1065 21899717 Benoit Fouet
1066
        iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width,
1067 2c4b4829 Benoit Fouet
                chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1068 21899717 Benoit Fouet
                FFMIN(chroma_width, 40));
1069
1070
    }
1071
1072
    return 8;
1073
}
1074
1075 deabd4fd Mike Melanson
static int indeo3_decode_frame(AVCodecContext *avctx,
1076
                               void *data, int *data_size,
1077 7a00bbad Thilo Borgmann
                               AVPacket *avpkt)
1078 deabd4fd Mike Melanson
{
1079 7a00bbad Thilo Borgmann
    const uint8_t *buf = avpkt->data;
1080
    int buf_size = avpkt->size;
1081 deabd4fd Mike Melanson
    Indeo3DecodeContext *s=avctx->priv_data;
1082 68e9c68f Benoit Fouet
    uint8_t *src, *dest;
1083 deabd4fd Mike Melanson
    int y;
1084
1085 28bcc76a Reimar Döffinger
    if (iv_decode_frame(avctx, buf, buf_size) < 0)
1086 274aa1d0 Alex Converse
        return -1;
1087 deabd4fd Mike Melanson
1088 e20c4069 Michael Niedermayer
    if(s->frame.data[0])
1089
        avctx->release_buffer(avctx, &s->frame);
1090
1091 deabd4fd Mike Melanson
    s->frame.reference = 0;
1092
    if(avctx->get_buffer(avctx, &s->frame) < 0) {
1093 9b879566 Michel Bardiaux
        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1094 deabd4fd Mike Melanson
        return -1;
1095
    }
1096
1097
    src = s->cur_frame->Ybuf;
1098
    dest = s->frame.data[0];
1099
    for (y = 0; y < s->height; y++) {
1100 6f427ccb Benoit Fouet
        memcpy(dest, src, s->cur_frame->y_w);
1101
        src += s->cur_frame->y_w;
1102
        dest += s->frame.linesize[0];
1103 deabd4fd Mike Melanson
    }
1104
1105 f970a8e6 Alex Beregszaszi
    if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1106
    {
1107 6f427ccb Benoit Fouet
        src = s->cur_frame->Ubuf;
1108
        dest = s->frame.data[1];
1109
        for (y = 0; y < s->height / 4; y++) {
1110
            memcpy(dest, src, s->cur_frame->uv_w);
1111
            src += s->cur_frame->uv_w;
1112
            dest += s->frame.linesize[1];
1113
        }
1114 deabd4fd Mike Melanson
1115 6f427ccb Benoit Fouet
        src = s->cur_frame->Vbuf;
1116
        dest = s->frame.data[2];
1117
        for (y = 0; y < s->height / 4; y++) {
1118
            memcpy(dest, src, s->cur_frame->uv_w);
1119
            src += s->cur_frame->uv_w;
1120
            dest += s->frame.linesize[2];
1121
        }
1122 f970a8e6 Alex Beregszaszi
    }
1123 deabd4fd Mike Melanson
1124
    *data_size=sizeof(AVFrame);
1125
    *(AVFrame*)data= s->frame;
1126
1127
    return buf_size;
1128
}
1129
1130 98a6fff9 Zuxy Meng
static av_cold int indeo3_decode_end(AVCodecContext *avctx)
1131 deabd4fd Mike Melanson
{
1132
    Indeo3DecodeContext *s = avctx->priv_data;
1133
1134
    iv_free_func(s);
1135
1136
    return 0;
1137
}
1138
1139
AVCodec indeo3_decoder = {
1140
    "indeo3",
1141
    CODEC_TYPE_VIDEO,
1142
    CODEC_ID_INDEO3,
1143
    sizeof(Indeo3DecodeContext),
1144
    indeo3_decode_init,
1145
    NULL,
1146
    indeo3_decode_end,
1147
    indeo3_decode_frame,
1148 7bbf3f2c Baptiste Coudurier
    CODEC_CAP_DR1,
1149 d5202e4f Stefano Sabatini
    NULL,
1150 fe4bf374 Stefano Sabatini
    .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
1151 deabd4fd Mike Melanson
};