Statistics
| Branch: | Revision:

ffmpeg / libavcodec / indeo3.c @ 4cfbf61b

History | View | Annotate | Download (37.4 KB)

1
/*
2
 * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg
3
 * written, produced, and directed by Alan Smithee
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19

    
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <string.h>
23
#include <unistd.h>
24

    
25
#include "common.h"
26
#include "avcodec.h"
27
#include "dsputil.h"
28
#include "mpegvideo.h"
29

    
30
#include "indeo3data.h"
31

    
32
typedef struct
33
{
34
  unsigned char *Ybuf;
35
  unsigned char *Ubuf;
36
  unsigned char *Vbuf;
37
  unsigned char *the_buf;
38
  unsigned int the_buf_size;
39
  unsigned short y_w, y_h;
40
  unsigned short uv_w, uv_h;
41
} YUVBufs;
42

    
43
typedef struct Indeo3DecodeContext {
44
    AVCodecContext *avctx;
45
    int width, height;
46
    AVFrame frame;
47

    
48
    YUVBufs iv_frame[2];
49
    YUVBufs *cur_frame;
50
    YUVBufs *ref_frame;
51

    
52
    unsigned char *ModPred;
53
    unsigned short *corrector_type;
54
} Indeo3DecodeContext;
55

    
56
static int corrector_type_0[24] = {
57
  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
};
61

    
62
static int corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
63

    
64
static void build_modpred(Indeo3DecodeContext *s) 
65
{
66
  int i, j;
67

    
68
  s->ModPred = (unsigned char *) av_malloc (8 * 128);
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 : ((i == 119 || i == 120)
73
                                 ? 236 : 2*((i + 2) - ((i + 1) % 3)));
74
    s->ModPred[i+2*128] = (i > 125) ? 248 : 2*((i + 2) - ((i + 2) % 4));
75
    s->ModPred[i+3*128] =                         2*((i + 1) - ((i - 3) % 5));
76
    s->ModPred[i+4*128] = (i == 8)  ?  20 : 2*((i + 1) - ((i - 3) % 6));
77
    s->ModPred[i+5*128] =                         2*((i + 4) - ((i + 3) % 7));
78
    s->ModPred[i+6*128] = (i > 123) ? 240 : 2*((i + 4) - ((i + 4) % 8));
79
    s->ModPred[i+7*128] =                         2*((i + 5) - ((i + 4) % 9));
80
  }
81

    
82
  s->corrector_type = (unsigned short *) av_malloc (24 * 256 * sizeof(unsigned short));
83

    
84
  for (i=0; i < 24; ++i) {
85
    for (j=0; j < 256; ++j) {
86
      s->corrector_type[i*256+j] = (j < corrector_type_0[i])
87
                                ? 1 : ((j < 248 || (i == 16 && j == 248))
88
                                       ? 0 : corrector_type_2[j - 248]);
89
    }
90
  }
91
}
92

    
93
static void iv_Decode_Chunk(Indeo3DecodeContext *s, unsigned char *cur, 
94
  unsigned char *ref, int width, int height, unsigned char *buf1, 
95
  long fflags2, unsigned char *hdr,
96
  unsigned char *buf2, int min_width_160);
97

    
98
#define min(a,b) ((a) < (b) ? (a) : (b))
99

    
100
/* ---------------------------------------------------------------------- */
101
static void iv_alloc_frames(Indeo3DecodeContext *s) 
102
{
103
  int luma_width, luma_height, luma_pixels, chroma_width, chroma_height,
104
    chroma_pixels, bufsize, i;
105

    
106
  luma_width = (s->width + 15) & -0x10;
107
  luma_height = (s->height + 15) & -0x10;
108

    
109
  s->iv_frame[0].y_w = s->iv_frame[0].y_h = 
110
    s->iv_frame[0].the_buf_size = 0;
111
  s->iv_frame[1].y_w = s->iv_frame[1].y_h = 
112
    s->iv_frame[1].the_buf_size = 0;
113
  s->iv_frame[1].the_buf = NULL;
114

    
115
  chroma_width = luma_width >> 2;
116
  chroma_height = luma_height >> 2;
117
  luma_pixels = luma_width * luma_height;
118
  chroma_pixels = chroma_width * chroma_height;
119

    
120
  bufsize = luma_pixels * 2 + luma_width * 3 + 
121
    (chroma_pixels + chroma_width) * 4;
122

    
123
  if((s->iv_frame[0].the_buf = 
124
    (s->iv_frame[0].the_buf_size == 0 ? av_malloc(bufsize) : 
125
      av_realloc(s->iv_frame[0].the_buf, bufsize))) == NULL)
126
    return;
127
  s->iv_frame[0].y_w = s->iv_frame[1].y_w = luma_width;
128
  s->iv_frame[0].y_h = s->iv_frame[1].y_h = luma_height;
129
  s->iv_frame[0].uv_w = s->iv_frame[1].uv_w = chroma_width;
130
  s->iv_frame[0].uv_h = s->iv_frame[1].uv_h = chroma_height;
131
  s->iv_frame[0].the_buf_size = bufsize;
132

    
133
  s->iv_frame[0].Ybuf = s->iv_frame[0].the_buf + luma_width;
134
  i = luma_pixels + luma_width * 2;
135
  s->iv_frame[1].Ybuf = s->iv_frame[0].the_buf + i;
136
  i += (luma_pixels + luma_width);
137
  s->iv_frame[0].Ubuf = s->iv_frame[0].the_buf + i;
138
  i += (chroma_pixels + chroma_width);
139
  s->iv_frame[1].Ubuf = s->iv_frame[0].the_buf + i;
140
  i += (chroma_pixels + chroma_width);
141
  s->iv_frame[0].Vbuf = s->iv_frame[0].the_buf + i;
142
  i += (chroma_pixels + chroma_width);
143
  s->iv_frame[1].Vbuf = s->iv_frame[0].the_buf + i;
144

    
145
  for(i = 1; i <= luma_width; i++)
146
    s->iv_frame[0].Ybuf[-i] = s->iv_frame[1].Ybuf[-i] = 
147
      s->iv_frame[0].Ubuf[-i] = 0x80;
148

    
149
  for(i = 1; i <= chroma_width; i++) {
150
    s->iv_frame[1].Ubuf[-i] = 0x80;
151
    s->iv_frame[0].Vbuf[-i] = 0x80;
152
    s->iv_frame[1].Vbuf[-i] = 0x80;
153
    s->iv_frame[1].Vbuf[chroma_pixels+i-1] = 0x80;
154
  }
155
}
156

    
157
/* ---------------------------------------------------------------------- */
158
static void iv_free_func(Indeo3DecodeContext *s) 
159
{
160
  int i;
161

    
162
  for(i = 0 ; i < 2 ; i++) {
163
    if(s->iv_frame[i].the_buf != NULL) 
164
      av_free(s->iv_frame[i].the_buf);
165
    s->iv_frame[i].Ybuf = s->iv_frame[i].Ubuf = 
166
      s->iv_frame[i].Vbuf = NULL;
167
    s->iv_frame[i].the_buf = NULL;
168
    s->iv_frame[i].the_buf_size = 0;
169
    s->iv_frame[i].y_w = s->iv_frame[i].y_h = 0;
170
    s->iv_frame[i].uv_w = s->iv_frame[i].uv_h = 0;
171
  }
172

    
173
  av_free(s->ModPred);
174
  av_free(s->corrector_type);
175
}
176

    
177
/* ---------------------------------------------------------------------- */
178
static unsigned long iv_decode_frame(Indeo3DecodeContext *s, 
179
                                     unsigned char *buf, int buf_size) 
180
{
181
  unsigned int hdr_width, hdr_height,
182
    chroma_width, chroma_height;
183
  unsigned long fflags1, fflags2, fflags3, offs1, offs2, offs3, offs;
184
  unsigned char *hdr_pos, *buf_pos;
185

    
186
  buf_pos = buf;
187
  buf_pos += 18;
188

    
189
  fflags1 = le2me_16(*(uint16_t *)buf_pos);
190
  buf_pos += 2;
191
  fflags3 = le2me_32(*(uint32_t *)buf_pos);
192
  buf_pos += 4;
193
  fflags2 = *buf_pos++;
194
  buf_pos += 3;
195
  hdr_height = le2me_16(*(uint16_t *)buf_pos);
196
  buf_pos += 2;
197
  hdr_width = le2me_16(*(uint16_t *)buf_pos);
198
  buf_pos += 2;
199
  chroma_height = ((hdr_height >> 2) + 3) & 0x7ffc;
200
  chroma_width = ((hdr_width >> 2) + 3) & 0x7ffc;
201
  offs1 = le2me_32(*(uint32_t *)buf_pos);
202
  buf_pos += 4;
203
  offs2 = le2me_32(*(uint32_t *)buf_pos);
204
  buf_pos += 4;
205
  offs3 = le2me_32(*(uint32_t *)buf_pos);
206
  buf_pos += 8;
207
  hdr_pos = buf_pos;
208
  if(fflags3 == 0x80) return 4;
209

    
210
  if(fflags1 & 0x200) {
211
    s->cur_frame = s->iv_frame + 1;
212
    s->ref_frame = s->iv_frame;
213
  } else {
214
    s->cur_frame = s->iv_frame;
215
    s->ref_frame = s->iv_frame + 1;
216
  }
217

    
218
  buf_pos = buf + 16 + offs1;
219
  offs = le2me_32(*(uint32_t *)buf_pos);
220
  buf_pos += 4;
221

    
222
  iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, hdr_width, 
223
    hdr_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, 
224
    min(hdr_width, 160));
225

    
226
  buf_pos = buf + 16 + offs2;
227
  offs = le2me_32(*(uint32_t *)buf_pos);
228
  buf_pos += 4;
229

    
230
  iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width, 
231
    chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, 
232
    min(chroma_width, 40));
233

    
234
  buf_pos = buf + 16 + offs3;
235
  offs = le2me_32(*(uint32_t *)buf_pos);
236
  buf_pos += 4;
237

    
238
  iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width, 
239
    chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, 
240
    min(chroma_width, 40));
241

    
242
  return 8;
243
}
244

    
245
typedef struct {
246
  long xpos;
247
  long ypos;
248
  long width;
249
  long height;
250
  long split_flag;
251
  long split_direction;
252
  long usl7;
253
} ustr_t;
254

    
255
/* ---------------------------------------------------------------------- */
256

    
257
#define LV1_CHECK(buf1,rle_v3,lv1,lp2)  \
258
  if((lv1 & 0x80) != 0) {   \
259
    if(rle_v3 != 0)         \
260
      rle_v3 = 0;           \
261
    else {                  \
262
      rle_v3 = 1;           \
263
      buf1 -= 2;            \
264
    }                       \
265
  }                         \
266
  lp2 = 4;
267

    
268

    
269
#define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)  \
270
  if(rle_v3 == 0) {         \
271
    rle_v2 = *buf1;         \
272
    rle_v1 = 1;             \
273
    if(rle_v2 > 32) {       \
274
      rle_v2 -= 32;         \
275
      rle_v1 = 0;           \
276
    }                       \
277
    rle_v3 = 1;             \
278
  }                         \
279
  buf1--;
280

    
281

    
282
#define LP2_CHECK(buf1,rle_v3,lp2)  \
283
  if(lp2 == 0 && rle_v3 != 0)     \
284
    rle_v3 = 0;           \
285
  else {                  \
286
    buf1--;               \
287
    rle_v3 = 1;           \
288
  }
289

    
290

    
291
#define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
292
  rle_v2--;             \
293
  if(rle_v2 == 0) {     \
294
    rle_v3 = 0;         \
295
    buf1 += 2;          \
296
  }                     \
297
  lp2 = 4;
298

    
299
static void iv_Decode_Chunk(Indeo3DecodeContext *s,
300
  unsigned char *cur, unsigned char *ref, int width, int height, 
301
  unsigned char *buf1, long fflags2, unsigned char *hdr,
302
  unsigned char *buf2, int min_width_160)
303
{
304
  unsigned char bit_buf;
305
  unsigned long bit_pos, lv, lv1, lv2;
306
  long *width_tbl, width_tbl_arr[10];
307
  char *ref_vectors;
308
  unsigned char *cur_frm_pos, *ref_frm_pos, *cp, *cp2;
309
  unsigned long *cur_lp, *ref_lp, *correction_lp[2], *correctionloworder_lp[2],
310
    *correctionhighorder_lp[2];
311
  unsigned short *correction_type_sp[2];
312
  ustr_t strip_tbl[20], *strip;
313
  int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width,
314
    rle_v1, rle_v2, rle_v3;
315

    
316
  bit_buf = 0;
317
  ref_vectors = NULL;
318

    
319
  width_tbl = width_tbl_arr + 1;
320
  i = (width < 0 ? width + 3 : width)/4;
321
  for(j = -1; j < 8; j++) 
322
    width_tbl[j] = i * j;
323

    
324
  strip = strip_tbl;
325

    
326
  for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160);
327

    
328
  strip->ypos = strip->xpos = 0;
329
  for(strip->width = min_width_160; width > strip->width; strip->width *= 2);
330
  strip->height = height;
331
  strip->split_direction = 0;
332
  strip->split_flag = 0;
333
  strip->usl7 = 0;
334

    
335
  bit_pos = 0;
336

    
337
  rle_v1 = rle_v2 = rle_v3 = 0;
338

    
339
  while(strip >= strip_tbl) {
340
    if(bit_pos <= 0) {
341
      bit_pos = 8;
342
      bit_buf = *buf1++;
343
    }
344

    
345
    bit_pos -= 2;
346
    cmd = (bit_buf >> bit_pos) & 0x03;
347

    
348
    if(cmd == 0) {
349
      strip++;
350
      memcpy(strip, strip-1, sizeof(ustr_t));
351
      strip->split_flag = 1;
352
      strip->split_direction = 0;
353
      strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);
354
      continue;
355
    } else if(cmd == 1) {
356
      strip++;
357
      memcpy(strip, strip-1, sizeof(ustr_t));
358
      strip->split_flag = 1;
359
      strip->split_direction = 1;
360
      strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);
361
      continue;
362
    } else if(cmd == 2) {
363
      if(strip->usl7 == 0) {
364
        strip->usl7 = 1;
365
        ref_vectors = NULL;
366
        continue;
367
      }
368
    } else if(cmd == 3) {
369
      if(strip->usl7 == 0) {
370
        strip->usl7 = 1;
371
        ref_vectors = buf2 + (*buf1 * 2);
372
        buf1++;
373
        continue;
374
      }
375
    }
376

    
377
    cur_frm_pos = cur + width * strip->ypos + strip->xpos;
378

    
379
    if((blks_width = strip->width) < 0) 
380
      blks_width += 3;
381
    blks_width >>= 2;
382
    blks_height = strip->height;
383

    
384
    if(ref_vectors != NULL) {
385
      ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +
386
        ref_vectors[1] + strip->xpos;
387
    } else 
388
      ref_frm_pos = cur_frm_pos - width_tbl[4];
389

    
390
    if(cmd == 2) {
391
      if(bit_pos <= 0) {
392
        bit_pos = 8;
393
        bit_buf = *buf1++;
394
      }
395

    
396
      bit_pos -= 2;
397
      cmd = (bit_buf >> bit_pos) & 0x03;
398

    
399
      if(cmd == 0 || ref_vectors != NULL) {
400
        for(lp1 = 0; lp1 < blks_width; lp1++) {
401
          for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])
402
            ((unsigned long *)cur_frm_pos)[j] = ((unsigned long *)ref_frm_pos)[j];
403
          cur_frm_pos += 4;
404
          ref_frm_pos += 4;
405
        }
406
      } else if(cmd != 1) 
407
        return;
408
    } else {
409
      k = *buf1 >> 4;
410
      j = *buf1 & 0x0f;
411
      buf1++;
412
      lv = j + fflags2;
413

    
414
      if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {
415
        cp2 = s->ModPred + ((lv - 8) << 7);
416
        cp = ref_frm_pos;
417
        for(i = 0; i < blks_width << 2; i++) { *(cp++) = cp2[*cp >> 1]; }
418
      }
419

    
420
      if(k == 1 || k == 4) {
421
        lv = (hdr[j] & 0xf) + fflags2;
422
        correction_type_sp[0] = s->corrector_type + (lv << 8);
423
        correction_lp[0] = correction + (lv << 8);
424
        lv = (hdr[j] >> 4) + fflags2;
425
        correction_lp[1] = correction + (lv << 8);
426
        correction_type_sp[1] = s->corrector_type + (lv << 8);
427
      } else {
428
        correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);
429
        correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);
430
        correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);
431
        correction_lp[0] = correction_lp[1] = correction + (lv << 8);
432
      }
433

    
434
      switch(k) {
435
        case 1:
436
        case 0:                    /********** CASE 0 **********/
437
          for( ; blks_height > 0; blks_height -= 4) {
438
            for(lp1 = 0; lp1 < blks_width; lp1++) {
439
              for(lp2 = 0; lp2 < 4; ) {
440
                k = *buf1++;
441
                cur_lp = ((unsigned long *)cur_frm_pos) + width_tbl[lp2];
442
                ref_lp = ((unsigned long *)ref_frm_pos) + width_tbl[lp2];
443

    
444
                switch(correction_type_sp[0][k]) {
445
                  case 0:
446
                    *cur_lp = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
447
                    lp2++;
448
                    break;
449
                  case 1:
450
                    ((unsigned short *)cur_lp)[0] = ((((unsigned short *)(ref_lp))[0] >> 1)
451
                      + correction_lp[lp2 & 0x01][*buf1++]) << 1;
452
                    ((unsigned short *)cur_lp)[1] = ((((unsigned short *)(ref_lp))[1] >> 1)
453
                      + correction_lp[lp2 & 0x01][k]) << 1;
454
                    lp2++;
455
                    break;
456
                  case 2:
457
                    if(lp2 == 0) {
458
                      for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])
459
                        cur_lp[j] = ref_lp[j];
460
                      lp2 += 2;
461
                    }
462
                    break;
463
                  case 3:
464
                    if(lp2 < 2) {
465
                      for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])
466
                        cur_lp[j] = ref_lp[j];
467
                      lp2 = 3;
468
                    }
469
                    break;
470
                  case 8:
471
                    if(lp2 == 0) {
472
                      RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
473

    
474
                      if(rle_v1 == 1 || ref_vectors != NULL) {
475
                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
476
                          cur_lp[j] = ref_lp[j];
477
                      }
478

    
479
                      RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
480
                      break;
481
                    } else {
482
                      rle_v1 = 1;
483
                      rle_v2 = *buf1 - 1;
484
                    }
485
                  case 5:
486
                      LP2_CHECK(buf1,rle_v3,lp2)
487
                  case 4:
488
                    for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])
489
                      cur_lp[j] = ref_lp[j];
490
                    lp2 = 4;
491
                    break;
492

    
493
                  case 7:
494
                    if(rle_v3 != 0) 
495
                      rle_v3 = 0;
496
                    else {
497
                      buf1--;
498
                      rle_v3 = 1;
499
                    }
500
                  case 6:
501
                    if(ref_vectors != NULL) {
502
                      for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
503
                        cur_lp[j] = ref_lp[j];
504
                    }
505
                    lp2 = 4;
506
                    break;
507

    
508
                  case 9:
509
                    lv1 = *buf1++;
510
                    lv = (lv1 & 0x7F) << 1;
511
                    lv += (lv << 8);
512
                    lv += (lv << 16);
513
                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
514
                      cur_lp[j] = lv;
515

    
516
                    LV1_CHECK(buf1,rle_v3,lv1,lp2)
517
                    break;
518
                  default: 
519
                    return;
520
                }
521
              }
522

    
523
              cur_frm_pos += 4;
524
              ref_frm_pos += 4;
525
            }
526

    
527
            cur_frm_pos += ((width - blks_width) * 4);
528
            ref_frm_pos += ((width - blks_width) * 4);
529
          }
530
          break;
531

    
532
        case 4:
533
        case 3:                    /********** CASE 3 **********/
534
          if(ref_vectors != NULL) 
535
            return;
536
          flag1 = 1;
537

    
538
          for( ; blks_height > 0; blks_height -= 8) {
539
            for(lp1 = 0; lp1 < blks_width; lp1++) {
540
              for(lp2 = 0; lp2 < 4; ) {
541
                k = *buf1++;
542

    
543
                cur_lp = ((unsigned long *)cur_frm_pos) + width_tbl[lp2 * 2];
544
                ref_lp = ((unsigned long *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
545

    
546
                switch(correction_type_sp[lp2 & 0x01][k]) {
547
                  case 0:
548
                    cur_lp[width_tbl[1]] = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
549
                    if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
550
                      cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
551
                    else
552
                      cur_lp[0] = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
553
                    lp2++;
554
                    break;
555

    
556
                  case 1:
557
                    ((unsigned short *)cur_lp)[width_tbl[2]] =
558
                      ((((unsigned short *)ref_lp)[0] >> 1) + correction_lp[lp2 & 0x01][*buf1++]) << 1;
559
                    ((unsigned short *)cur_lp)[width_tbl[2]+1] =
560
                      ((((unsigned short *)ref_lp)[1] >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
561
                    if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
562
                      cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
563
                    else
564
                      cur_lp[0] = cur_lp[width_tbl[1]];
565
                    lp2++;
566
                    break;
567

    
568
                  case 2:
569
                    if(lp2 == 0) {
570
                      for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
571
                        cur_lp[j] = *ref_lp;
572
                      lp2 += 2;
573
                    }
574
                    break;
575

    
576
                  case 3:
577
                    if(lp2 < 2) {
578
                      for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
579
                        cur_lp[j] = *ref_lp;
580
                      lp2 = 3;
581
                    }
582
                    break;
583

    
584
                  case 6:
585
                    lp2 = 4;
586
                    break;
587

    
588
                  case 7:
589
                    if(rle_v3 != 0) 
590
                      rle_v3 = 0;
591
                    else {
592
                      buf1--;
593
                      rle_v3 = 1;
594
                    }
595
                    lp2 = 4;
596
                    break;
597

    
598
                  case 8:
599
                    if(lp2 == 0) {
600
                      RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
601

    
602
                      if(rle_v1 == 1) {
603
                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
604
                          cur_lp[j] = ref_lp[j];
605
                      }
606

    
607
                      RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
608
                      break;
609
                    } else {
610
                      rle_v2 = (*buf1) - 1;
611
                      rle_v1 = 1;
612
                    }
613
                  case 5:
614
                      LP2_CHECK(buf1,rle_v3,lp2)
615
                  case 4:
616
                    for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
617
                      cur_lp[j] = *ref_lp;
618
                    lp2 = 4;
619
                    break;
620

    
621
                  case 9:
622
                    fprintf(stderr, "UNTESTED.\n");
623
                    lv1 = *buf1++;
624
                    lv = (lv1 & 0x7F) << 1;
625
                    lv += (lv << 8);
626
                    lv += (lv << 16);
627

    
628
                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
629
                      cur_lp[j] = lv;
630

    
631
                    LV1_CHECK(buf1,rle_v3,lv1,lp2)
632
                    break;
633

    
634
                  default: 
635
                    return;
636
                }
637
              }
638

    
639
              cur_frm_pos += 4;
640
            }
641

    
642
            cur_frm_pos += (((width * 2) - blks_width) * 4);
643
            flag1 = 0;
644
          }
645
          break;
646

    
647
        case 10:                    /********** CASE 10 **********/
648
          if(ref_vectors == NULL) {
649
            flag1 = 1;
650

    
651
            for( ; blks_height > 0; blks_height -= 8) {
652
              for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
653
                for(lp2 = 0; lp2 < 4; ) {
654
                  k = *buf1++;
655
                  cur_lp = ((unsigned long *)cur_frm_pos) + width_tbl[lp2 * 2];
656
                  ref_lp = ((unsigned long *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
657
                  lv1 = ref_lp[0];
658
                  lv2 = ref_lp[1];
659
                  if(lp2 == 0 && flag1 != 0) {
660
                    lv1 = lv1 & 0x00FF00FF;
661
                    lv1 = (lv1 << 8) | lv1;
662
                    lv2 = lv2 & 0x00FF00FF;
663
                    lv2 = (lv2 << 8) | lv2;
664
                  }
665

    
666
                  switch(correction_type_sp[lp2 & 0x01][k]) {
667
                    case 0:
668
                      cur_lp[width_tbl[1]] = ((lv1 >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1;
669
                      cur_lp[width_tbl[1]+1] = ((lv2 >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1;
670
                      if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
671
                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
672
                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
673
                      } else {
674
                        cur_lp[0] = cur_lp[width_tbl[1]];
675
                        cur_lp[1] = cur_lp[width_tbl[1]+1];
676
                      }
677
                      lp2++;
678
                      break;
679

    
680
                    case 1:
681
                      cur_lp[width_tbl[1]] = ((lv1 >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1++]) << 1;
682
                      cur_lp[width_tbl[1]+1] = ((lv2 >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1;
683
                      if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
684
                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
685
                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
686
                      } else {
687
                        cur_lp[0] = cur_lp[width_tbl[1]];
688
                        cur_lp[1] = cur_lp[width_tbl[1]+1];
689
                      }
690
                      lp2++;
691
                      break;
692

    
693
                    case 2:
694
                      if(lp2 == 0) {
695
                        if(flag1 != 0) {
696
                          for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {
697
                            cur_lp[j] = lv1;
698
                            cur_lp[j+1] = lv2;
699
                          }
700
                          cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
701
                          cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
702
                        } else {
703
                          for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
704
                            cur_lp[j] = lv1;
705
                            cur_lp[j+1] = lv2;
706
                          }
707
                        }
708
                        lp2 += 2;
709
                      }
710
                      break;
711

    
712
                    case 3:
713
                      if(lp2 < 2) {
714
                        if(lp2 == 0 && flag1 != 0) {
715
                          for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {
716
                            cur_lp[j] = lv1;
717
                            cur_lp[j+1] = lv2;
718
                          }
719
                          cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
720
                          cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
721
                        } else {
722
                          for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
723
                            cur_lp[j] = lv1;
724
                            cur_lp[j+1] = lv2;
725
                          }
726
                        }
727
                        lp2 = 3;
728
                      }
729
                      break;
730

    
731
                    case 8:
732
                      if(lp2 == 0) {
733
                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
734
                        if(rle_v1 == 1) {
735
                          if(flag1 != 0) {
736
                            for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
737
                              cur_lp[j] = lv1;
738
                              cur_lp[j+1] = lv2;
739
                            }
740
                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
741
                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
742
                          } else {
743
                            for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
744
                              cur_lp[j] = lv1;
745
                              cur_lp[j+1] = lv2;
746
                            }
747
                          }
748
                        }
749
                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
750
                        break;
751
                      } else {
752
                        rle_v1 = 1;
753
                        rle_v2 = (*buf1) - 1;
754
                      }
755
                    case 5:
756
                        LP2_CHECK(buf1,rle_v3,lp2)
757
                    case 4:
758
                      if(lp2 == 0 && flag1 != 0) {
759
                        for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
760
                          cur_lp[j] = lv1;
761
                          cur_lp[j+1] = lv2;
762
                        }
763
                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
764
                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
765
                      } else {
766
                        for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
767
                          cur_lp[j] = lv1;
768
                          cur_lp[j+1] = lv2;
769
                        }
770
                      }
771
                      lp2 = 4;
772
                      break;
773

    
774
                    case 6:
775
                      lp2 = 4;
776
                      break;
777

    
778
                    case 7:
779
                      if(lp2 == 0) {
780
                        if(rle_v3 != 0) 
781
                          rle_v3 = 0;
782
                        else {
783
                          buf1--;
784
                          rle_v3 = 1;
785
                        }
786
                        lp2 = 4;
787
                      }
788
                      break;
789

    
790
                    case 9:
791
                      fprintf(stderr, "UNTESTED.\n");
792
                      lv1 = *buf1;
793
                      lv = (lv1 & 0x7F) << 1;
794
                      lv += (lv << 8);
795
                      lv += (lv << 16);
796
                      for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
797
                        cur_lp[j] = lv;
798
                      LV1_CHECK(buf1,rle_v3,lv1,lp2)
799
                      break;
800

    
801
                    default: 
802
                      return;
803
                  }
804
                }
805

    
806
                cur_frm_pos += 8;
807
              }
808

    
809
              cur_frm_pos += (((width * 2) - blks_width) * 4);
810
              flag1 = 0;
811
            }
812
          } else {
813
            for( ; blks_height > 0; blks_height -= 8) {
814
              for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
815
                for(lp2 = 0; lp2 < 4; ) {
816
                  k = *buf1++;
817
                  cur_lp = ((unsigned long *)cur_frm_pos) + width_tbl[lp2 * 2];
818
                  ref_lp = ((unsigned long *)ref_frm_pos) + width_tbl[lp2 * 2];
819

    
820
                  switch(correction_type_sp[lp2 & 0x01][k]) {
821
                    case 0:
822
                      lv1 = correctionloworder_lp[lp2 & 0x01][k];
823
                      lv2 = correctionhighorder_lp[lp2 & 0x01][k];
824
                      cur_lp[0] = ((ref_lp[0] >> 1) + lv1) << 1;
825
                      cur_lp[1] = ((ref_lp[1] >> 1) + lv2) << 1;
826
                      cur_lp[width_tbl[1]] = ((ref_lp[width_tbl[1]] >> 1) + lv1) << 1;
827
                      cur_lp[width_tbl[1]+1] = ((ref_lp[width_tbl[1]+1] >> 1) + lv2) << 1;
828
                      lp2++;
829
                      break;
830

    
831
                    case 1:
832
                      lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];
833
                      lv2 = correctionloworder_lp[lp2 & 0x01][k];
834
                      cur_lp[0] = ((ref_lp[0] >> 1) + lv1) << 1;
835
                      cur_lp[1] = ((ref_lp[1] >> 1) + lv2) << 1;
836
                      cur_lp[width_tbl[1]] = ((ref_lp[width_tbl[1]] >> 1) + lv1) << 1;
837
                      cur_lp[width_tbl[1]+1] = ((ref_lp[width_tbl[1]+1] >> 1) + lv2) << 1;
838
                      lp2++;
839
                      break;
840

    
841
                    case 2:
842
                      if(lp2 == 0) {
843
                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
844
                          cur_lp[j] = ref_lp[j];
845
                          cur_lp[j+1] = ref_lp[j+1];
846
                        }
847
                        lp2 += 2;
848
                      }
849
                      break;
850

    
851
                    case 3:
852
                      if(lp2 < 2) {
853
                        for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
854
                          cur_lp[j] = ref_lp[j];
855
                          cur_lp[j+1] = ref_lp[j+1];
856
                        }
857
                        lp2 = 3;
858
                      }
859
                      break;
860

    
861
                    case 8:
862
                      if(lp2 == 0) {
863
                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
864
                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
865
                          ((unsigned long *)cur_frm_pos)[j] = ((unsigned long *)ref_frm_pos)[j];
866
                          ((unsigned long *)cur_frm_pos)[j+1] = ((unsigned long *)ref_frm_pos)[j+1];
867
                        }
868
                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
869
                        break;
870
                      } else {
871
                        rle_v1 = 1;
872
                        rle_v2 = (*buf1) - 1;
873
                      }
874
                    case 5:
875
                    case 7:
876
                        LP2_CHECK(buf1,rle_v3,lp2)
877
                    case 6:
878
                    case 4:
879
                      for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
880
                        cur_lp[j] = ref_lp[j];
881
                        cur_lp[j+1] = ref_lp[j+1];
882
                      }
883
                      lp2 = 4;
884
                      break;
885

    
886
                    case 9:
887
                      fprintf(stderr, "UNTESTED.\n");
888
                      lv1 = *buf1;
889
                      lv = (lv1 & 0x7F) << 1;
890
                      lv += (lv << 8);
891
                      lv += (lv << 16);
892
                      for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
893
                        ((unsigned long *)cur_frm_pos)[j] = ((unsigned long *)cur_frm_pos)[j+1] = lv;
894
                      LV1_CHECK(buf1,rle_v3,lv1,lp2)
895
                      break;
896

    
897
                    default: 
898
                      return;
899
                  }
900
                }
901

    
902
                cur_frm_pos += 8;
903
                ref_frm_pos += 8;
904
              }
905

    
906
              cur_frm_pos += (((width * 2) - blks_width) * 4);
907
              ref_frm_pos += (((width * 2) - blks_width) * 4);
908
            }
909
          }
910
          break;
911

    
912
        case 11:                    /********** CASE 11 **********/
913
          if(ref_vectors == NULL) 
914
            return;
915

    
916
          for( ; blks_height > 0; blks_height -= 8) {
917
            for(lp1 = 0; lp1 < blks_width; lp1++) {
918
              for(lp2 = 0; lp2 < 4; ) {
919
                k = *buf1++;
920
                cur_lp = ((unsigned long *)cur_frm_pos) + width_tbl[lp2 * 2];
921
                ref_lp = ((unsigned long *)ref_frm_pos) + width_tbl[lp2 * 2];
922

    
923
                switch(correction_type_sp[lp2 & 0x01][k]) {
924
                  case 0:
925
                    cur_lp[0] = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
926
                    cur_lp[width_tbl[1]] = ((ref_lp[width_tbl[1]] >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
927
                    lp2++;
928
                    break;
929

    
930
                  case 1:
931
                    lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);
932
                    lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);
933
                    ((unsigned short *)cur_lp)[0] = ((((unsigned short *)ref_lp)[0] >> 1) + lv1) << 1;
934
                    ((unsigned short *)cur_lp)[1] = ((((unsigned short *)ref_lp)[1] >> 1) + lv2) << 1;
935
                    ((unsigned short *)cur_lp)[width_tbl[2]] = ((((unsigned short *)ref_lp)[width_tbl[2]] >> 1) + lv1) << 1;
936
                    ((unsigned short *)cur_lp)[width_tbl[2]+1] = ((((unsigned short *)ref_lp)[width_tbl[2]+1] >> 1) + lv2) << 1;
937
                    lp2++;
938
                    break;
939

    
940
                  case 2:
941
                    if(lp2 == 0) {
942
                      for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
943
                        cur_lp[j] = ref_lp[j];
944
                      lp2 += 2;
945
                    }
946
                    break;
947

    
948
                  case 3:
949
                    if(lp2 < 2) {
950
                      for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
951
                        cur_lp[j] = ref_lp[j];
952
                      lp2 = 3;
953
                    }
954
                    break;
955

    
956
                  case 8:
957
                    if(lp2 == 0) {
958
                      RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
959

    
960
                      for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
961
                        cur_lp[j] = ref_lp[j];
962

    
963
                      RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
964
                      break;
965
                    } else {
966
                      rle_v1 = 1;
967
                      rle_v2 = (*buf1) - 1;
968
                    }
969
                  case 5:
970
                  case 7:
971
                      LP2_CHECK(buf1,rle_v3,lp2)
972
                  case 4:
973
                  case 6:
974
                    for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
975
                      cur_lp[j] = ref_lp[j];
976
                    lp2 = 4;
977
                    break;
978

    
979
                case 9:
980
                  fprintf(stderr, "UNTESTED.\n");
981
                  lv1 = *buf1++;
982
                  lv = (lv1 & 0x7F) << 1;
983
                  lv += (lv << 8);
984
                  lv += (lv << 16);
985
                  for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
986
                    cur_lp[j] = lv;
987
                  LV1_CHECK(buf1,rle_v3,lv1,lp2)
988
                  break;
989

    
990
                  default: 
991
                    return;
992
                }
993
              }
994

    
995
              cur_frm_pos += 4;
996
              ref_frm_pos += 4;
997
            }
998

    
999
            cur_frm_pos += (((width * 2) - blks_width) * 4);
1000
            ref_frm_pos += (((width * 2) - blks_width) * 4);
1001
          }
1002
          break;
1003

    
1004
        default: 
1005
          return;
1006
      }
1007
    }
1008

    
1009
    if(strip < strip_tbl) 
1010
      return;
1011

    
1012
    for( ; strip >= strip_tbl; strip--) {
1013
      if(strip->split_flag != 0) {
1014
        strip->split_flag = 0;
1015
        strip->usl7 = (strip-1)->usl7;
1016

    
1017
        if(strip->split_direction) {
1018
          strip->xpos += strip->width;
1019
          strip->width = (strip-1)->width - strip->width;
1020
          if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)
1021
            strip->width = width - strip->xpos;
1022
        } else {
1023
          strip->ypos += strip->height;
1024
          strip->height = (strip-1)->height - strip->height;
1025
        }
1026
        break;
1027
      }
1028
    }
1029
  }
1030
}
1031

    
1032
static int indeo3_decode_init(AVCodecContext *avctx)
1033
{
1034
    Indeo3DecodeContext *s = avctx->priv_data;
1035

    
1036
    s->avctx = avctx;
1037
    s->width = avctx->width;
1038
    s->height = avctx->height;
1039
    avctx->pix_fmt = PIX_FMT_YUV410P;
1040
    avctx->has_b_frames = 0;
1041

    
1042
    build_modpred(s);
1043
    iv_alloc_frames(s);
1044

    
1045
    return 0;
1046
}
1047

    
1048
static int indeo3_decode_frame(AVCodecContext *avctx,
1049
                               void *data, int *data_size,
1050
                               unsigned char *buf, int buf_size)
1051
{
1052
    Indeo3DecodeContext *s=avctx->priv_data;
1053
    unsigned char *src, *dest;
1054
    int y;
1055

    
1056
    iv_decode_frame(s, buf, buf_size);
1057

    
1058
    if(s->frame.data[0])
1059
        avctx->release_buffer(avctx, &s->frame);
1060

    
1061
    s->frame.reference = 0;
1062
    if(avctx->get_buffer(avctx, &s->frame) < 0) {
1063
        fprintf(stderr, "get_buffer() failed\n");
1064
        return -1;
1065
    }
1066

    
1067
    src = s->cur_frame->Ybuf;
1068
    dest = s->frame.data[0];
1069
    for (y = 0; y < s->height; y++) {
1070
      memcpy(dest, src, s->cur_frame->y_w);
1071
      src += s->cur_frame->y_w;
1072
      dest += s->frame.linesize[0];
1073
    }
1074

    
1075
    src = s->cur_frame->Ubuf;
1076
    dest = s->frame.data[1];
1077
    for (y = 0; y < s->height / 4; y++) {
1078
      memcpy(dest, src, s->cur_frame->uv_w);
1079
      src += s->cur_frame->uv_w;
1080
      dest += s->frame.linesize[1];
1081
    }
1082

    
1083
    src = s->cur_frame->Vbuf;
1084
    dest = s->frame.data[2];
1085
    for (y = 0; y < s->height / 4; y++) {
1086
      memcpy(dest, src, s->cur_frame->uv_w);
1087
      src += s->cur_frame->uv_w;
1088
      dest += s->frame.linesize[2];
1089
    }
1090

    
1091
    *data_size=sizeof(AVFrame);
1092
    *(AVFrame*)data= s->frame;
1093

    
1094
    return buf_size;
1095
}
1096

    
1097
static int indeo3_decode_end(AVCodecContext *avctx)
1098
{
1099
    Indeo3DecodeContext *s = avctx->priv_data;
1100

    
1101
    iv_free_func(s);
1102

    
1103
    return 0;
1104
}
1105

    
1106
AVCodec indeo3_decoder = {
1107
    "indeo3",
1108
    CODEC_TYPE_VIDEO,
1109
    CODEC_ID_INDEO3,
1110
    sizeof(Indeo3DecodeContext),
1111
    indeo3_decode_init,
1112
    NULL,
1113
    indeo3_decode_end,
1114
    indeo3_decode_frame,
1115
    0,
1116
    NULL
1117
};