mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-01 16:15:07 -04:00
154 lines
3.5 KiB
C
154 lines
3.5 KiB
C
|
#include "global.h"
|
||
|
|
||
|
void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 count) {
|
||
|
u8 i;
|
||
|
|
||
|
for (i = 0; i < count; i++) {
|
||
|
u8 j;
|
||
|
|
||
|
dqt++;
|
||
|
for (j = 0; j < 64; j++) {
|
||
|
qt[i].table[j] = *dqt++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths) {
|
||
|
u8 off = 1;
|
||
|
s16 count = 0;
|
||
|
s16 idx = 1;
|
||
|
|
||
|
while (off < 0x11) {
|
||
|
while (idx <= ptr[off - 1]) {
|
||
|
codesLengths[count++] = off;
|
||
|
idx++;
|
||
|
}
|
||
|
idx = 1;
|
||
|
off++;
|
||
|
}
|
||
|
|
||
|
codesLengths[count] = 0;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
s32 JpegUtils_GetHuffmanCodes(u8* codesLengths, u16* codes) {
|
||
|
s16 idx = 0;
|
||
|
u16 code = 0;
|
||
|
u8 lastLen = codesLengths[0];
|
||
|
|
||
|
while (true) {
|
||
|
while (true) {
|
||
|
codes[idx++] = code++;
|
||
|
|
||
|
if (codesLengths[idx] != lastLen) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (codesLengths[idx] == 0) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
while (true) {
|
||
|
if (code <<= 1, codesLengths[idx] == ++lastLen) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return idx;
|
||
|
}
|
||
|
|
||
|
s32 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) {
|
||
|
u8 idx;
|
||
|
u16 codeOff = 0;
|
||
|
|
||
|
for (idx = 0; idx < 0x10; idx++) {
|
||
|
if (data[idx]) {
|
||
|
ht->codeOffs[idx] = codeOff;
|
||
|
ht->codesA[idx] = codes[codeOff];
|
||
|
codeOff += data[idx] - 1;
|
||
|
ht->codesB[idx] = codes[codeOff];
|
||
|
codeOff++;
|
||
|
} else {
|
||
|
ht->codesB[idx] = 0xFFFF;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return codeOff;
|
||
|
}
|
||
|
|
||
|
u32 JpegUtils_ProcessHuffmanTableImpl(u8* data, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 isAc) {
|
||
|
s16 ret;
|
||
|
s32 count = JpegUtils_ParseHuffmanCodesLengths(data, codesLengths);
|
||
|
s32 temp;
|
||
|
|
||
|
ret = count;
|
||
|
if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) {
|
||
|
return 0;
|
||
|
}
|
||
|
if (ret != JpegUtils_GetHuffmanCodes(codesLengths, codes)) {
|
||
|
return 0;
|
||
|
}
|
||
|
if (temp = JpegUtils_SetHuffmanTable(data, ht, codes), temp != ret) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
u32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 count) {
|
||
|
u8 idx;
|
||
|
u32 codeCount;
|
||
|
|
||
|
for (idx = 0; idx < count; idx++) {
|
||
|
u32 ac = (*dht++ >> 4);
|
||
|
|
||
|
codeCount = JpegUtils_ProcessHuffmanTableImpl(dht, &ht[idx], codesLengths, codes, ac);
|
||
|
if (codeCount == 0) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
dht += 0x10;
|
||
|
ht[idx].symbols = dht;
|
||
|
dht += codeCount;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void JpegUtils_SetHuffmanTableOld(u8* data, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes, s16 count, u8 isAc) {
|
||
|
s16 idx;
|
||
|
u8 a;
|
||
|
|
||
|
for (idx = 0; idx < count; idx++) {
|
||
|
a = data[idx];
|
||
|
if (isAc) {
|
||
|
ht->acCodes[a] = codes[idx];
|
||
|
ht->codeOffs[a] = codesLengths[idx];
|
||
|
} else {
|
||
|
ht->dcCodes[a] = codes[idx];
|
||
|
ht->codeOffs[a] = codesLengths[idx];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 JpegUtils_ProcessHuffmanTableImplOld(u8* dht, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes) {
|
||
|
u8 isAc = *dht++ >> 4;
|
||
|
s16 count2;
|
||
|
s32 count;
|
||
|
|
||
|
count2 = count = JpegUtils_ParseHuffmanCodesLengths(dht, codesLengths);
|
||
|
|
||
|
if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (JpegUtils_GetHuffmanCodes(codesLengths, codes) != count2) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
JpegUtils_SetHuffmanTableOld(dht + 0x10, ht, codesLengths, codes, count2, isAc);
|
||
|
|
||
|
return 0;
|
||
|
}
|