-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Yoink THP from mkdd -- matches perfectly
- Loading branch information
Showing
4 changed files
with
2,553 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#ifndef _DOLPHIN_THP_H | ||
#define _DOLPHIN_THP_H | ||
|
||
#include <dolphin/types.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef u8 THPSample; | ||
typedef s16 THPCoeff; | ||
typedef float THPQuantTab[64]; | ||
|
||
typedef struct _THPHuffmanTab { | ||
u8 quick[32]; | ||
u8 increment[32]; | ||
u8* Vij; | ||
s32 maxCode[18]; | ||
s32 valPtr[18]; | ||
u8 Vij1; | ||
u8 pad[11]; | ||
} THPHuffmanTab; | ||
|
||
typedef struct _THPComponent { | ||
u8 quantizationTableSelector; | ||
u8 DCTableSelector; | ||
u8 ACTableSelector; | ||
THPCoeff predDC; | ||
} THPComponent; | ||
|
||
typedef struct _THPFileInfo { | ||
THPQuantTab quantTabs[3]; | ||
THPHuffmanTab huffmanTabs[4]; | ||
THPComponent components[3]; | ||
u16 xPixelSize; | ||
u16 yPixelSize; | ||
u16 MCUsPerRow; | ||
u16 decompressedY; | ||
u8* c; | ||
u32 currByte; | ||
u32 cnt; | ||
u8 validHuffmanTabs; | ||
u8 RST; | ||
u16 nMCU; | ||
u16 currMCU; | ||
u8* dLC[3]; | ||
} THPFileInfo; | ||
|
||
typedef struct { | ||
u32 offsetNextChannel; | ||
u32 sampleSize; | ||
s16 lCoef[8][2]; | ||
s16 rCoef[8][2]; | ||
s16 lYn1; | ||
s16 lYn2; | ||
s16 rYn1; | ||
s16 rYn2; | ||
} THPAudioRecordHeader; | ||
|
||
typedef struct { | ||
u8* encodeData; | ||
u32 offsetNibbles; | ||
u8 predictor; | ||
u8 scale; | ||
s16 yn1; | ||
s16 yn2; | ||
} THPAudioDecodeInfo; | ||
|
||
BOOL THPInit(); | ||
s32 THPVideoDecode(void* file, void* tileY, void* tileU, void* tileV, | ||
void* work); | ||
u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag); | ||
|
||
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo*); | ||
static void __THPAudioInitialize(THPAudioDecodeInfo*, u8*); | ||
|
||
static void __THPSetupBuffers(void); | ||
static u8 __THPReadFrameHeader(void); | ||
static u8 __THPReadScaneHeader(void); | ||
static u8 __THPReadQuantizationTable(void); | ||
static u8 __THPReadHuffmanTableSpecification(void); | ||
static void __THPHuffGenerateSizeTable(void); | ||
static void __THPHuffGenerateCodeTable(void); | ||
static void __THPHuffGenerateDecoderTables(u8 tabIndex); | ||
static void __THPRestartDefinition(void); | ||
static void __THPPrepBitStream(void); | ||
static void __THPDecompressYUV(void*, void*, void*); | ||
static void __THPGQRRestore(void); | ||
static void __THPDecompressiMCURow512x448(void); | ||
static void __THPDecompressiMCURow640x480(void); | ||
static void __THPDecompressiMCURowNxN(void); | ||
static void __THPHuffDecodeDCTCompY(THPFileInfo*, THPCoeff*); | ||
static void __THPHuffDecodeDCTCompU(THPFileInfo*, THPCoeff*); | ||
static void __THPHuffDecodeDCTCompV(THPFileInfo*, THPCoeff*); | ||
|
||
static const u8 __THPJpegNaturalOrder[80] = { | ||
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, | ||
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, | ||
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, | ||
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, | ||
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, | ||
}; | ||
|
||
static const f64 __THPAANScaleFactor[8] = { | ||
1.0f, 1.387039845f, 1.306562965f, 1.175875602f, | ||
1.0f, 0.785694958f, 0.541196100f, 0.275899379f, | ||
}; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
#include <dolphin/thp.h> | ||
|
||
u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag) | ||
{ | ||
THPAudioRecordHeader* header; | ||
THPAudioDecodeInfo decInfo; | ||
u8 *left, *right; | ||
s16 *decLeftPtr, *decRightPtr; | ||
s16 yn1, yn2; | ||
s32 i; | ||
s32 step; | ||
s32 sample; | ||
s64 yn; | ||
|
||
if (audioBuffer == NULL || audioFrame == NULL) { | ||
return 0; | ||
} | ||
|
||
header = (THPAudioRecordHeader*)audioFrame; | ||
left = audioFrame + sizeof(THPAudioRecordHeader); | ||
right = left + header->offsetNextChannel; | ||
|
||
if (flag == 1) { | ||
decRightPtr = audioBuffer; | ||
decLeftPtr = audioBuffer + header->sampleSize; | ||
step = 1; | ||
} else { | ||
decRightPtr = audioBuffer; | ||
decLeftPtr = audioBuffer + 1; | ||
step = 2; | ||
} | ||
|
||
if (header->offsetNextChannel == 0) { | ||
__THPAudioInitialize(&decInfo, left); | ||
|
||
yn1 = header->lYn1; | ||
yn2 = header->lYn2; | ||
|
||
for (i = 0; i < header->sampleSize; i++) { | ||
sample = __THPAudioGetNewSample(&decInfo); | ||
yn = header->lCoef[decInfo.predictor][1] * yn2; | ||
yn += header->lCoef[decInfo.predictor][0] * yn1; | ||
yn += (sample << decInfo.scale) << 11; | ||
yn <<= 5; | ||
|
||
if ((u16)(yn & 0xffff) > 0x8000) { | ||
yn += 0x10000; | ||
} else if ((u16)(yn & 0xffff) == 0x8000) { | ||
if ((yn & 0x10000)) | ||
yn += 0x10000; | ||
} | ||
|
||
if (yn > 2147483647LL) { | ||
yn = 2147483647LL; | ||
} | ||
|
||
if (yn < -2147483648LL) { | ||
yn = -2147483648LL; | ||
} | ||
|
||
*decLeftPtr = (s16)(yn >> 16); | ||
decLeftPtr += step; | ||
*decRightPtr = (s16)(yn >> 16); | ||
decRightPtr += step; | ||
yn2 = yn1; | ||
yn1 = (s16)(yn >> 16); | ||
} | ||
} else { | ||
__THPAudioInitialize(&decInfo, left); | ||
|
||
yn1 = header->lYn1; | ||
yn2 = header->lYn2; | ||
|
||
for (i = 0; i < header->sampleSize; i++) { | ||
sample = __THPAudioGetNewSample(&decInfo); | ||
yn = header->lCoef[decInfo.predictor][1] * yn2; | ||
yn += header->lCoef[decInfo.predictor][0] * yn1; | ||
yn += (sample << decInfo.scale) << 11; | ||
yn <<= 5; | ||
if ((u16)(yn & 0xffff) > 0x8000) { | ||
yn += 0x10000; | ||
} else { | ||
if ((u16)(yn & 0xffff) == 0x8000) { | ||
if ((yn & 0x10000)) | ||
yn += 0x10000; | ||
} | ||
} | ||
|
||
if (yn > 2147483647LL) { | ||
yn = 2147483647LL; | ||
} | ||
|
||
if (yn < -2147483648LL) { | ||
yn = -2147483648LL; | ||
} | ||
|
||
*decLeftPtr = (s16)(yn >> 16); | ||
decLeftPtr += step; | ||
yn2 = yn1; | ||
yn1 = (s16)(yn >> 16); | ||
} | ||
|
||
__THPAudioInitialize(&decInfo, right); | ||
|
||
yn1 = header->rYn1; | ||
yn2 = header->rYn2; | ||
|
||
for (i = 0; i < header->sampleSize; i++) { | ||
sample = __THPAudioGetNewSample(&decInfo); | ||
yn = header->rCoef[decInfo.predictor][1] * yn2; | ||
yn += header->rCoef[decInfo.predictor][0] * yn1; | ||
yn += (sample << decInfo.scale) << 11; | ||
yn <<= 5; | ||
|
||
if ((u16)(yn & 0xffff) > 0x8000) { | ||
yn += 0x10000; | ||
} else { | ||
if ((u16)(yn & 0xffff) == 0x8000) { | ||
if ((yn & 0x10000)) | ||
yn += 0x10000; | ||
} | ||
} | ||
|
||
if (yn > 2147483647LL) { | ||
yn = 2147483647LL; | ||
} | ||
|
||
if (yn < -2147483648LL) { | ||
yn = -2147483648LL; | ||
} | ||
|
||
*decRightPtr = (s16)(yn >> 16); | ||
decRightPtr += step; | ||
yn2 = yn1; | ||
yn1 = (s16)(yn >> 16); | ||
} | ||
} | ||
|
||
return header->sampleSize; | ||
} | ||
|
||
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo* info) | ||
{ | ||
s32 sample; | ||
|
||
if (!(info->offsetNibbles & 0x0f)) { | ||
info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); | ||
info->scale = (u8)((*(info->encodeData) & 0xF)); | ||
info->encodeData++; | ||
info->offsetNibbles += 2; | ||
} | ||
|
||
if (info->offsetNibbles & 0x1) { | ||
sample = (s32)((*(info->encodeData) & 0xF) << 28) >> 28; | ||
info->encodeData++; | ||
} else { | ||
sample = (s32)((*(info->encodeData) & 0xF0) << 24) >> 28; | ||
} | ||
|
||
info->offsetNibbles++; | ||
return sample; | ||
} | ||
|
||
static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr) | ||
{ | ||
info->encodeData = ptr; | ||
info->offsetNibbles = 2; | ||
info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4); | ||
info->scale = (u8)((*(info->encodeData) & 0xF)); | ||
info->encodeData++; | ||
} |
Oops, something went wrong.