/* */
+static void DecodeDCCoefficients(FrameDecoder_t* t)
+{
+ INT32 i;
+
+ INT32 eob = 0;
+
+ const UINT8* c = t->Count;
+
+ INT16* dc = t->DC;
+
+ for (i = 0; i < 3; i++) {
+ const INT8* br = t->BRun [i][0];
+ const INT16* bc = t->BCoeff[i][0];
+
+ const UINT8* end = c + t->Index->BC[i];
+
+ const UINT16* bi = t->Index->BIndex[i];
+
+ for (; ; ) {
+ INT16 coeff = 0;
+
+ for (; c < end && *c == 0xff; c++) {
+ dc[*(bi++)] = NOT_CODED;
+ }
+
+ if (c >= end) {
+ break;
+ }
+
+ if (eob == 0) {
+ INT8 rr = *(br++);
+ INT16 cc = *(bc++);
+
+ if (rr == 0) {
+ coeff = cc;
+
+ } else if (rr < 0) {
+ eob = cc;
+ }
+ }
+
+ if (eob > 0) {
+ eob--;
+ }
+
+ dc[*(bi++)] = coeff;
+
+ c++;
+ }
+
+ dc += t->Index->BC[i];
+ }
+}
+
+/* */
+
+static const INT32 DCP_W[16][4] = {
+ /* L DL D DR */
+ { 1, 2, 4, 8 },
+
+ { 128, 0, 0, 0 }, /* 1 */
+ { 0, 128, 0, 0 }, /* 2 */
+ { 128, 0, 0, 0 }, /* 3 */
+ { 0, 0, 128, 0 }, /* 4 */
+ { 64, 0, 64, 0 }, /* 5 */
+ { 0, 0, 128, 0 }, /* 6 */
+ { 116, -104, 116, 0 }, /* 7 */
+ { 0, 0, 0, 128 }, /* 8 */
+ { 75, 0, 0, 53 }, /* 9 */
+ { 0, 64, 0, 64 }, /* 10 */
+ { 75, 0, 0, 53 }, /* 11 */
+ { 0, 0, 128, 0 }, /* 12 */
+ { 75, 0, 0, 53 }, /* 13 */
+ { 0, 24, 80, 24 }, /* 14 */
+ { 116, -104, 116, 0 } /* 15 */
+
+};
+
+static const INT32 DCP_T[8] = {
+ 1, 0, 1, 1,
+ 1, 2, 2, 1
+};
+
+/* */
+
+static void UndoDCPrediction(
+ FrameDecoder_t* t)
+{
+ INT32 i;
+ INT32 x, y;
+
+ INT16* DC = t->DC;
+
+ const UINT8* mode = t->BMode;
+
+ for (i = 0; i < 3; i++) {
+ INT32 bx = t->Index->BX[i];
+ INT32 by = t->Index->BY[i];
+
+ INT16 last[3] = { 0 };
+
+ INT32 v[4] = { 0 };
+
+ INT32 idx = 0;
+
+ for (y = 0; y < by; y++) {
+ for (x = 0; x < bx; x++, idx++) {
+ INT32 dc = DC[idx];
+ if (dc != NOT_CODED) {
+ INT32 pred;
+
+ INT32 t0 = 0;
+ INT32 type = DCP_T[mode[idx]];
+
+ if (x > 0) {
+ INT32 i0 = idx - 1;
+ v[0] = DC[i0];
+ if (v[0] != NOT_CODED && DCP_T[mode[i0]] == type) {
+ t0 += DCP_W[0][0];
+ }
+ }
+
+ if (y > 0) {
+ if (x > 0) {
+ INT32 i1 = idx - bx - 1;
+ v[1] = DC[i1];
+ if (v[1] != NOT_CODED && DCP_T[mode[i1]] == type) {
+ t0 += DCP_W[0][1];
+ }
+ }
+
+ {
+ INT32 i2 = idx - bx;
+ v[2] = DC[i2];
+ if (v[2] != NOT_CODED && DCP_T[mode[i2]] == type) {
+ t0 += DCP_W[0][2];
+ }
+ }
+
+ if (x < bx - 1) {
+ INT32 i3 = idx - bx + 1;
+ v[3] = DC[i3];
+ if (v[3] != NOT_CODED && DCP_T[mode[i3]] == type) {
+ t0 += DCP_W[0][3];
+ }
+ }
+ }
+
+ if (t0 > 0) {
+ pred =
+ ( v[0] * DCP_W[t0][0]
+ + v[1] * DCP_W[t0][1]
+ + v[2] * DCP_W[t0][2]
+ + v[3] * DCP_W[t0][3] ) / 128;
+
+ if ((t0 & 0x7) == 7) {
+ INT32 d = pred - v[2]; /* D */
+ if (d < -128 || d > 128) {
+ pred = v[2];
+ } else if (d = pred - v[0], d < -128 || d > 128) { /* L */
+ pred = v[0];
+ } else if (d = pred - v[1], d < -128 || d > 128) { /* DL */
+ pred = v[1];
+ }
+ }
+
+ } else {
+ pred = last[type];
+ }
+
+ dc += pred;
+
+ DC[idx] = dc;
+
+ last[type] = dc;
+ }
+ }
+ }
+
+ DC += t->Index->BC[i];
+ mode += t->Index->BC[i];
+ }
+}
+
+/* */
+
#define ARCH_C
#include "QTheoraArch.h"
return FALSE;
}
+ t->BMode = (UINT8*)QT_MemoryPool_Allocate(pool, sizeof(UINT8) * index->Blocks);
+ if (t->BMode == NULL) {
+ return FALSE;
+ }
+
t->MV = (MotionVector_t*)QT_MemoryPool_Allocate(pool, sizeof(MotionVector_t) * index->BC[0]);
if (t->MV == NULL) {
return FALSE;
return FALSE;
}
+ t->DC = (INT16*)QT_MemoryPool_Allocate(pool, sizeof(INT16) * index->Blocks);
+ if (t->DC == NULL) {
+ return FALSE;
+ }
+
/* */
if (g_QT_Enable_SSE2 || g_QT_Enable_MMX) {
t->BlocksCoded[i] = 0;
}
+ memset(t->Count, 0, sizeof(UINT8) * t->Index->Blocks);
+
/* PARTIAL or FULL */
FETCH_BITS_I(x, 1)
UINT8* m = t->MBMode;
UINT8* end = m + t->Index->MC;
+ const UINT16* mbi = t->Index->MBIndex;
+ const UINT16* cbi = t->Index->CBIndex;
+
+ UINT8* m0 = t->BMode;
+ UINT8* m1 = m0 + t->Index->BC[0];
+ UINT8* m2 = m1 + t->Index->BC[1];
+
const UINT8* c = t->Count;
FETCH_BITS_I(scheme, 3)
}
if (scheme != 7) {
- for (; m < end; m++, c += 4) {
+ for (; m < end; m++, c += 4, mbi += 4, cbi++) {
UINT8 mm = 0;
if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff || c[3] != 0xff) {
}
*m = mm;
+
+ m0[mbi[0]] = mm;
+ m0[mbi[1]] = mm;
+ m0[mbi[2]] = mm;
+ m0[mbi[3]] = mm;
+ m1[cbi[0]] = mm;
+ m2[cbi[0]] = mm;
}
} else {
- for (; m < end; m++, c += 4) {
+ for (; m < end; m++, c += 4, mbi += 4, cbi++) {
UINT8 mm = 0;
if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff || c[3] != 0xff) {
}
*m = mm;
+
+ m0[mbi[0]] = mm;
+ m0[mbi[1]] = mm;
+ m0[mbi[2]] = mm;
+ m0[mbi[3]] = mm;
+ m1[cbi[0]] = mm;
+ m2[cbi[0]] = mm;
}
}
const UINT8* m = t->MBMode;
const UINT8* end = m + t->Index->MC;
- const UINT8* c = t->Count;
+ const UINT16* mbi = t->Index->MBIndex;
- MotionVector_t* mv = t->MV;
+ const UINT8* c = t->Count;
MotionVector_t last[2] = { { 0, 0 }, { 0, 0 } };
Decode = (x == 0) ? DecodeMV0 : DecodeMV1;
- for (; m < end; m++, c += 4, mv += 4) {
+ for (; m < end; m++, c += 4, mbi += 4) {
+ MotionVector_t* mv = t->MV + mbi[0];
+
switch (*m) {
case 2: /* INTER_MV */
LOAD_BITS
case 7: /* INTER_MV_FOUR */
{
- const MotionVector_t* mv0 = mv;
-
INT32 i;
for (i = 0; i < 4; i++) {
- /* Check: Raster Order */
+ MotionVector_t* v = t->MV + mbi[i];
+
if (c[i] != 0xff) {
LOAD_BITS
x = GET_BITS_I(16);
- s = Decode(mv + i, x);
+ s = Decode(v, x);
RETIRE_BITS(s)
- mv0 = mv + i;
+ mv = v;
} else {
- mv[i].X = 0;
- mv[i].Y = 0;
+ v->X = 0;
+ v->Y = 0;
}
}
last[1] = last[0];
- last[0] = *mv0;
+ last[0] = *mv;
break;
}
}
}
- printf("T: %d\n", token);
-
if (token >= 0 && token < 7) {
INT32 blen = EOB_BITS_LEN[token];
ctx->EOB_Run = EOB_RUN_BASE[token];
*((ctx->Run )++) = run;
*((ctx->Coeff)++) = coeff;
- if (index + run + 1 >= 64) {
+ if (index + run + 1 > 64) {
return FALSE;
}
} else {
INT32 eob = ctx->EOB_Run;
- *((ctx->Run )++) = -1;
- *((ctx->Coeff)++) = eob;
-
if (eob > count) {
eob = count;
}
+ *((ctx->Run )++) = -1;
+ *((ctx->Coeff)++) = eob;
+
for (i = index + 1; i < 64; i++) {
ctx->BlocksCoded[i] -= eob;
}
ctx.BlocksCoded = Coded[k];
- printf("DCT: %d : %d\n", index, k);
-
if (!FrameDecoder_DecodeBlocks(
t,
d,
if (t->Header.Type == 0) { /* Intra */
memset(t->Count, 0, sizeof(UINT8) * t->Index->Blocks);
+ memset(t->BMode, 1, t->Index->Blocks);
+
t->BlocksCoded[0] = t->Index->BC[0];
t->BlocksCoded[1] = t->Index->BC[1];
t->BlocksCoded[2] = t->Index->BC[2];
/* */
+ DecodeDCCoefficients(t);
+
+#if 0
+ {
+ INT32 i;
+ INT32 x, y;
+
+ const INT16* dc = t->DC;
+
+ for (i = 0; i < 3; i++) {
+ INT32 bx = t->Index->BX[i];
+ INT32 by = t->Index->BY[i];
+
+ printf("DC: %d\n", i);
+ for (y = 0; y < by; y++) {
+ for (x = 0; x < bx; x++, dc++) {
+ if (x > 0) {
+ printf(" ");
+ }
+ printf("%d", *dc);
+ }
+ printf("\n");
+ }
+ }
+ }
+#endif
+
+ /* */
+
+ UndoDCPrediction(t);
+
+ {
+ INT32 i;
+ INT32 x, y;
+
+ const INT16* dc = t->DC;
+
+ for (i = 0; i < 3; i++) {
+ INT32 bx = t->Index->BX[i];
+ INT32 by = t->Index->BY[i];
+
+ printf("DC: %d\n", i);
+ for (y = 0; y < by; y++) {
+ for (x = 0; x < bx; x++, dc++) {
+ if (x > 0) {
+ printf(" ");
+ }
+ printf("%d", *dc);
+ }
+ printf("\n");
+ }
+ }
+ }
+
+ /* */
+
return TRUE;
}