📄 ov518_decomp.c
字号:
{ -1, -1, 16, 6, 8, 0}, {182, 185, -1, 0, -1, 0},
{183, 184, -1, 0, -1, 0}, { -1, -1, 16, 7, 8, 0},
{ -1, -1, 16, 8, 8, 0}, {186, 187, -1, 0, -1, 0},
{ -1, -1, 16, 9, 8, 0}, { -1, -1, 16, 10, 8, 0},
{ -1, -1, 9, 1, 9, 0}, {190, 257, -1, 0, -1, 0},
{191, 224, -1, 0, -1, 0}, {192, 207, -1, 0, -1, 0},
{193, 200, -1, 0, -1, 0}, {194, 197, -1, 0, -1, 0},
{195, 196, -1, 0, -1, 0}, { -1, -1, 16, 2, 9, 0},
{ -1, -1, 16, 3, 9, 0}, {198, 199, -1, 0, -1, 0},
{ -1, -1, 16, 4, 9, 0}, { -1, -1, 16, 5, 9, 0},
{201, 204, -1, 0, -1, 0}, {202, 203, -1, 0, -1, 0},
{ -1, -1, 16, 6, 9, 0}, { -1, -1, 16, 7, 9, 0},
{205, 206, -1, 0, -1, 0}, { -1, -1, 16, 8, 9, 0},
{ -1, -1, 16, 9, 9, 0}, {208, 217, -1, 0, -1, 0},
{209, 214, -1, 0, -1, 0}, {210, 213, -1, 0, -1, 0},
{ -1, -1, 16, 10, 9, 0}, {212, 230, -1, 0, -1, 0},
{ -1, -1, 9, 1, 10, 0}, { -1, -1, 16, 2, 10, 0},
{215, 216, -1, 0, -1, 0}, { -1, -1, 16, 3, 10, 0},
{ -1, -1, 16, 4, 10, 0}, {218, 221, -1, 0, -1, 0},
{219, 220, -1, 0, -1, 0}, { -1, -1, 16, 5, 10, 0},
{ -1, -1, 16, 6, 10, 0}, {222, 223, -1, 0, -1, 0},
{ -1, -1, 16, 7, 10, 0}, { -1, -1, 16, 8, 10, 0},
{225, 241, -1, 0, -1, 0}, {226, 234, -1, 0, -1, 0},
{227, 231, -1, 0, -1, 0}, {228, 229, -1, 0, -1, 0},
{ -1, -1, 16, 9, 10, 0}, { -1, -1, 16, 10, 10, 0},
{ -1, -1, 9, 1, 11, 0}, {232, 233, -1, 0, -1, 0},
{ -1, -1, 16, 2, 11, 0}, { -1, -1, 16, 3, 11, 0},
{235, 238, -1, 0, -1, 0}, {236, 237, -1, 0, -1, 0},
{ -1, -1, 16, 4, 11, 0}, { -1, -1, 16, 5, 11, 0},
{239, 240, -1, 0, -1, 0}, { -1, -1, 16, 6, 11, 0},
{ -1, -1, 16, 7, 11, 0}, {242, 250, -1, 0, -1, 0},
{243, 246, -1, 0, -1, 0}, {244, 245, -1, 0, -1, 0},
{ -1, -1, 16, 8, 11, 0}, { -1, -1, 16, 9, 11, 0},
{247, 249, -1, 0, -1, 0}, { -1, -1, 16, 10, 11, 0},
{ -1, -1, 9, 1, 12, 0}, { -1, -1, 16, 2, 12, 0},
{251, 254, -1, 0, -1, 0}, {252, 253, -1, 0, -1, 0},
{ -1, -1, 16, 3, 12, 0}, { -1, -1, 16, 4, 12, 0},
{255, 256, -1, 0, -1, 0}, { -1, -1, 16, 5, 12, 0},
{ -1, -1, 16, 6, 12, 0}, {258, 291, -1, 0, -1, 0},
{259, 275, -1, 0, -1, 0}, {260, 268, -1, 0, -1, 0},
{261, 264, -1, 0, -1, 0}, {262, 263, -1, 0, -1, 0},
{ -1, -1, 16, 7, 12, 0}, { -1, -1, 16, 8, 12, 0},
{265, 266, -1, 0, -1, 0}, { -1, -1, 16, 9, 12, 0},
{ -1, -1, 16, 10, 12, 0}, { -1, -1, 11, 1, 13, 0},
{269, 272, -1, 0, -1, 0}, {270, 271, -1, 0, -1, 0},
{ -1, -1, 16, 2, 13, 0}, { -1, -1, 16, 3, 13, 0},
{273, 274, -1, 0, -1, 0}, { -1, -1, 16, 4, 13, 0},
{ -1, -1, 16, 5, 13, 0}, {276, 283, -1, 0, -1, 0},
{277, 280, -1, 0, -1, 0}, {278, 279, -1, 0, -1, 0},
{ -1, -1, 16, 6, 13, 0}, { -1, -1, 16, 7, 13, 0},
{281, 282, -1, 0, -1, 0}, { -1, -1, 16, 8, 13, 0},
{ -1, -1, 16, 9, 13, 0}, {284, 288, -1, 0, -1, 0},
{285, 287, -1, 0, -1, 0}, { -1, -1, 16, 10, 13, 0},
{ -1, -1, 14, 1, 14, 0}, { -1, -1, 16, 2, 14, 0},
{289, 290, -1, 0, -1, 0}, { -1, -1, 16, 3, 14, 0},
{ -1, -1, 16, 4, 14, 0}, {292, 308, -1, 0, -1, 0},
{293, 300, -1, 0, -1, 0}, {294, 297, -1, 0, -1, 0},
{295, 296, -1, 0, -1, 0}, { -1, -1, 16, 5, 14, 0},
{ -1, -1, 16, 6, 14, 0}, {298, 299, -1, 0, -1, 0},
{ -1, -1, 16, 7, 14, 0}, { -1, -1, 16, 8, 14, 0},
{301, 305, -1, 0, -1, 0}, {302, 303, -1, 0, -1, 0},
{ -1, -1, 16, 9, 14, 0}, { -1, -1, 16, 10, 14, 0},
{ -1, -1, 15, 1, 15, 0}, {306, 307, -1, 0, -1, 0},
{ -1, -1, 16, 2, 15, 0}, { -1, -1, 16, 3, 15, 0},
{309, 316, -1, 0, -1, 0}, {310, 313, -1, 0, -1, 0},
{311, 312, -1, 0, -1, 0}, { -1, -1, 16, 4, 15, 0},
{ -1, -1, 16, 5, 15, 0}, {314, 315, -1, 0, -1, 0},
{ -1, -1, 16, 6, 15, 0}, { -1, -1, 16, 7, 15, 0},
{317, 320, -1, 0, -1, 0}, {318, 319, -1, 0, -1, 0},
{ -1, -1, 16, 8, 15, 0}, { -1, -1, 16, 9, 15, 0},
{321, -1, -1, 0, -1, 0}, { -1, -1, 16, 10, 15, 0},
{ -1, -1, 10, 0, 16, 0}, { -1, -1, 2, 0, -1, 0},
};
static const tree_node treeYDC[] = {
{ 1, 6, -1, 0, 0, 0}, { 2, 3, -1, 0, 0, 0},
{ -1, -1, 2, 0, 0, 0}, { 4, 5, -1, 0, 0, 0},
{ -1, -1, 3, 1, 0, 0}, { -1, -1, 3, 2, 0, 0},
{ 7, 10, -1, 0, 0, 0}, { 8, 9, -1, 0, 0, 0},
{ -1, -1, 3, 3, 0, 0}, { -1, -1, 3, 4, 0, 0},
{ 11, 12, -1, 0, 0, 0}, { -1, -1, 3, 5, 0, 0},
{ 13, 14, -1, 0, 0, 0}, { -1, -1, 4, 6, 0, 0},
{ 15, 16, -1, 0, 0, 0}, { -1, -1, 5, 7, 0, 0},
{ 17, 18, -1, 0, 0, 0}, { -1, -1, 6, 8, 0, 0},
{ 19, 20, -1, 0, 0, 0}, { -1, -1, 7, 9, 0, 0},
{ 21, 22, -1, 0, 0, 0}, { -1, -1, 8, 10, 0, 0},
{ 23, -1, -1, 0, 0, 0}, { -1, -1, 9, 11, 0, 0},
};
static const tree_node treeUVDC[] = {
{ 1, 4, -1, 0, 0, 0}, { 2, 3, -1, 0, 0, 0},
{ -1, -1, 2, 0, 0, 0}, { -1, -1, 2, 1, 0, 0},
{ 5, 6, -1, 0, 0, 0}, { -1, -1, 2, 2, 0, 0},
{ 7, 8, -1, 0, 0, 0}, { -1, -1, 3, 3, 0, 0},
{ 9, 10, -1, 0, 0, 0}, { -1, -1, 4, 4, 0, 0},
{ 11, 12, -1, 0, 0, 0}, { -1, -1, 5, 5, 0, 0},
{ 13, 14, -1, 0, 0, 0}, { -1, -1, 6, 6, 0, 0},
{ 15, 16, -1, 0, 0, 0}, { -1, -1, 7, 7, 0, 0},
{ 17, 18, -1, 0, 0, 0}, { -1, -1, 8, 8, 0, 0},
{ 19, 20, -1, 0, 0, 0}, { -1, -1, 9, 9, 0, 0},
{ 21, 22, -1, 0, 0, 0}, { -1, -1, 10, 10, 0, 0},
{ 23, -1, -1, 0, 0, 0}, { -1, -1, 11, 11, 0, 0},
};
/******************************************************************************
* Debugging
******************************************************************************/
#ifdef PRINT_QT
#define PRN_QT_ROW(a, i) PDEBUG(5, "%02x %02x %02x %02x %02x %02x %02x %02x", \
(a)[(i)], (a)[(i)+1], (a)[(i)+2], (a)[(i)+3], (a)[(i)+4], (a)[(i)+5], \
(a)[(i)+6], (a)[(i)+7])
static inline void
print_qt(unsigned char *qt)
{
PDEBUG(5, "Y Quantization table:");
PRN_QT_ROW(qt, 0);
PRN_QT_ROW(qt, 8);
PRN_QT_ROW(qt, 16);
PRN_QT_ROW(qt, 24);
PDEBUG(5, "UV Quantization table:");
PRN_QT_ROW(qt, 32);
PRN_QT_ROW(qt, 40);
PRN_QT_ROW(qt, 48);
PRN_QT_ROW(qt, 56);
}
#else
static inline void
print_qt(unsigned char *qt) { }
#endif /* PRINT_QT */
/******************************************************************************
* Huffman Decoder
******************************************************************************/
/* Note: There is no penalty for passing the tree as an argument, since dummy
* args are passed anyway (to maintain 16-byte stack alignment), and since the
* address is loaded into a register either way. */
/* If no node is found, coeffbits and skip will not be modified */
/* Return: Depth of node found, or -1 if invalid input code */
static int
getNodeAC(unsigned int in, signed char *coeffbits, signed char *skip,
const tree_node *tree)
{
int node = 0;
int i = 0;
int depth;
do {
if ((in & 0x80000000) == 0)
node = tree[node].left;
else
node = tree[node].right;
if (node == -1)
break;
depth = tree[node].depth;
/* Is it a leaf? If not, branch downward */
if (depth != -1) {
*coeffbits = tree[node].coeffbits;
*skip = tree[node].skip;
return depth;
}
in <<= 1;
++i;
} while (i <= 15);
return -1;
}
/* If no node is found, coeffbits will not be modified */
/* Return: Depth of node found, or -1 if invalid input code */
static int
getNodeDC(unsigned int in, signed char *coeffbits, const tree_node *tree)
{
int node = 0;
int i = 0;
int depth;
do {
if ((in & 0x80000000) == 0)
node = tree[node].left;
else
node = tree[node].right;
if (node == -1)
break;
depth = tree[node].depth;
/* Is it a leaf? If not, branch downward */
if (depth != -1) {
*coeffbits = tree[node].coeffbits;
return depth;
}
in <<= 1;
++i;
} while (i <= 15);
return -1;
}
static inline unsigned int
getBytes(int *rawData, CompInfo *cinfo)
{
int bufLen = cinfo->rawLen;
int bits = cinfo->bits;
int bytes = cinfo->bytes;
unsigned char *in = bytes + (unsigned char *) rawData;
unsigned char b1, b2, b3, b4, b5;
unsigned int packedIn;
/* Pull 5 bytes out of raw data */
if (bytes < bufLen - 4) {
b1 = in[0];
b2 = in[1];
b3 = in[2];
b4 = in[3];
b5 = in[4];
} else {
if (bytes < bufLen - 3) {
b1 = in[0];
b2 = in[1];
b3 = in[2];
b4 = in[3];
} else {
if (bytes < bufLen - 2) {
b1 = in[0];
b2 = in[1];
b3 = in[2];
} else {
if (bytes < bufLen - 1) {
b1 = in[0];
b2 = in[1];
} else {
if (bytes <= bufLen) {
b1 = in[0];
} else {
b1 = 0;
}
b2 = 0;
}
b3 = 0;
}
b4 = 0;
}
b5 = 0;
}
/* Pack the bytes */
packedIn = b1 << 24;
packedIn += b2 << 16;
packedIn += b3 << 8;
packedIn += b4;
if (bits != 0) {
packedIn = packedIn << bits;
packedIn += b5 >> (8 - bits);
}
return packedIn;
}
static int
getACCoefficient(int *rawData, int *coeff, CompInfo *cinfo,
const tree_node *tree)
{
int input, bits, bytes, tmp_c;
signed char coeffbits = 0;
signed char skip = 0;
input = getBytes(rawData, cinfo);
bits = getNodeAC(input, &coeffbits, &skip, tree);
if (coeffbits) {
input = input << (bits - 1);
input &= 0x7fffffff;
if (! (input & 0x40000000))
input |= 0x80000000;
tmp_c = input >> (31 - coeffbits);
if (tmp_c < 0)
tmp_c++;
*coeff = tmp_c;
bits += coeffbits;
}
bytes = (bits + cinfo->bits) >> 3;
cinfo->bytes += bytes;
cinfo->bits += bits - (bytes << 3);
return skip;
}
static void
getDCCoefficient(int *rawData, int *coeff, CompInfo *cinfo,
const tree_node *tree)
{
int input, bits, bytes, tmp_c;
signed char coeffbits = 0;
input = getBytes(rawData, cinfo);
bits = getNodeDC(input, &coeffbits, tree);
if (bits == -1) {
bits = 1; /* Try to re-sync at the next bit */
*coeff = 0; /* Indicates no change from last DC */
} else {
input = input << (bits - 1);
input &= 0x7fffffff;
if (! (input & 0x40000000))
input |= 0x80000000;
tmp_c = input >> (31 - coeffbits);
if (tmp_c < 0)
tmp_c++;
*coeff = tmp_c;
bits += coeffbits;
}
bytes = (bits + cinfo->bits) >> 3;
cinfo->bytes += bytes;
cinfo->bits += bits - (bytes << 3);
}
/* For AC coefficients, here is what the "skip" value means:
* -1: Either the 8x4 block has ended, or the decoding failed.
* 0: Use the returned coeff. Don't skip anything.
* 1-15: The next <skip> coeffs are zero. The returned coeff is used.
* 16: The next 16 coeffs are zero. The returned coeff is ignored.
*
* You must ensure that the C[] array not be overrun, or stack corruption will
* result.
*/
static void
huffmanDecoderY(int *C, int *pIn, CompInfo *cinfo)
{
int coeff = 0;
int i = 1;
int k, skip;
getDCCoefficient(pIn, C, cinfo, treeYDC);
i = 1;
do {
skip = getACCoefficient(pIn, &coeff, cinfo, treeYAC);
if (skip == -1) {
break;
} else if (skip == 0) {
C[i++] = coeff;
} else if (skip == 16) {
k = 16;
if (i > 16)
k = 32 - i;
while (k--)
C[i++] = 0;
} else {
k = skip;
if (skip > 31 - i)
k = 31 - i;
while (k--)
C[i++] = 0;
C[i++] = coeff;
}
} while (i <= 31);
if (skip == -1)
while (i <= 31) C[i++] = 0;
else
getACCoefficient(pIn, &coeff, cinfo, treeYAC);
}
/* Same as huffmanDecoderY, except for the tables used */
static void
huffmanDecoderUV(int *C, int *pIn, CompInfo *cinfo)
{
int coeff = 0;
int i = 1;
int k, skip;
getDCCoefficient(pIn, C, cinfo, treeUVDC);
i = 1;
do {
skip = getACCoefficient(pIn, &coeff, cinfo, treeUVAC);
if (skip == -1) {
break;
} else if (skip == 0) {
C[i++] = coeff;
} else if (skip == 16) {
k = 16;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -