summaryrefslogtreecommitdiff
path: root/src/code/jpegdecoder.c
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2021-11-19 17:34:45 -0300
committerGitHub <noreply@github.com>2021-11-19 17:34:45 -0300
commit2854294009725379c73e121671f7f3b0dadfed67 (patch)
treed3607be7fd2c9b9617709b55382ab1275f0370c9 /src/code/jpegdecoder.c
parentc8b0ff3f747e7c3651788b703cfa355fd9c28b8c (diff)
`z_jpeg`, `jpegutils` and `jpegdecoder` OK (#322)
* this is a disaster * two more * func_800F470C * split and rename jpegutils and jpegdecoder * match jpegutils * match jpegdecoder.c * audio_rodata * data split * Split rsp * Steal documentation from OoT * cleanup * Format * remove removed members in JpegContext * Update include/z64.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/jpegdecoder.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update include/functions.h Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Update src/code/jpegutils.c Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * review renames * true * Some type fixes * Update include/z64.h Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * add comment * Update src/code/z_jpeg.c Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * format * bss fix * decr * format * z64jpeg.h * Add stdbool * Rename audio_init_params * whoops * whoops++ * whoops# * remove extra dumb variables in variables.txt * fix Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>
Diffstat (limited to 'src/code/jpegdecoder.c')
-rw-r--r--src/code/jpegdecoder.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/code/jpegdecoder.c b/src/code/jpegdecoder.c
new file mode 100644
index 000000000..336e381f9
--- /dev/null
+++ b/src/code/jpegdecoder.c
@@ -0,0 +1,193 @@
+#include "z64jpeg.h"
+#include "libc/stdbool.h"
+#include "macros.h"
+
+u8* sJpegBitStreamPtr;
+u32 sJpegBitStreamByteIdx;
+u8 sJpegBitStreamBitIdx;
+u8 sJpegBitStreamDontSkip;
+u32 sJpegBitStreamCurWord;
+
+s32 JpegDecoder_Decode(JpegDecoder* decoder, u16* mcuBuff, s32 count, u8 isFollowing, JpegDecoderState* state) {
+ s16 pad;
+ s16 unk0;
+ s16 unk1;
+ s16 unk2;
+ u32 idx;
+ s32 inc;
+ u16 unkCount;
+
+ JpegHuffmanTable* hTable0;
+ JpegHuffmanTable* hTable1;
+ JpegHuffmanTable* hTable2;
+ JpegHuffmanTable* hTable3;
+
+ inc = 0;
+ sJpegBitStreamPtr = decoder->imageData;
+ if (decoder->mode == 0) {
+ unkCount = 2;
+ } else {
+ unkCount = 4;
+ if (decoder->unk_05 == 1) {
+ inc = 8 * 8 * 2;
+ }
+ }
+
+ hTable0 = decoder->hTablePtrs[0];
+ hTable1 = decoder->hTablePtrs[1];
+ hTable2 = decoder->hTablePtrs[2];
+ hTable3 = decoder->hTablePtrs[3];
+
+ if (!isFollowing) {
+ sJpegBitStreamByteIdx = 0;
+ sJpegBitStreamBitIdx = 32;
+ sJpegBitStreamCurWord = 0;
+ sJpegBitStreamDontSkip = 0;
+ unk0 = 0;
+ unk1 = 0;
+ unk2 = 0;
+ } else {
+ sJpegBitStreamByteIdx = state->byteIdx;
+ sJpegBitStreamBitIdx = state->bitIdx;
+ sJpegBitStreamCurWord = state->curWord;
+ sJpegBitStreamDontSkip = state->dontSkip;
+ unk0 = state->unk_0C;
+ unk1 = state->unk_0E;
+ unk2 = state->unk_10;
+ }
+
+ while (count != 0) {
+ for (idx = 0; idx < unkCount; idx++) {
+ if (JpegDecoder_ProcessMcu(hTable0, hTable1, mcuBuff, &unk0)) {
+ return 2;
+ }
+ mcuBuff += 8 * 8;
+ }
+
+ if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk1)) {
+ return 2;
+ }
+ mcuBuff += 8 * 8;
+
+ if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk2)) {
+ return 2;
+ }
+
+ count--;
+ mcuBuff += 8 * 8;
+ mcuBuff += inc;
+ }
+
+ state->byteIdx = sJpegBitStreamByteIdx;
+ state->bitIdx = sJpegBitStreamBitIdx;
+ state->curWord = sJpegBitStreamCurWord;
+ state->dontSkip = sJpegBitStreamDontSkip;
+ state->unk_0C = unk0;
+ state->unk_0E = unk1;
+ state->unk_10 = unk2;
+ return 0;
+}
+
+s32 JpegDecoder_ProcessMcu(JpegHuffmanTable* hTable0, JpegHuffmanTable* hTable1, u16* mcu, s16* unk) {
+ s8 i = 0;
+ s8 zeroCount;
+ s16 coeff;
+
+ if (JpegDecoder_ParseNextSymbol(hTable0, &coeff, &zeroCount)) {
+ return true;
+ }
+
+ *unk += coeff;
+ mcu[i++] = *unk;
+ while (i < 8 * 8) {
+ if (JpegDecoder_ParseNextSymbol(hTable1, &coeff, &zeroCount)) {
+ return true;
+ }
+
+ if (coeff == 0) {
+ if (zeroCount == 0xF) {
+ while (zeroCount-- >= 0) {
+ mcu[i++] = 0;
+ }
+ } else {
+ while (i < 8 * 8) {
+ mcu[i++] = 0;
+ }
+ break;
+ }
+ } else {
+ while (0 < zeroCount--) {
+ mcu[i++] = 0;
+ }
+ mcu[i++] = coeff;
+ }
+ }
+
+ return false;
+}
+
+s32 JpegDecoder_ParseNextSymbol(JpegHuffmanTable* hTable, s16* outCoeff, s8* outZeroCount) {
+ u8 codeIdx;
+ u8 sym;
+ u16 codeOff = 0;
+ u16 buff = JpegDecoder_ReadBits(16);
+
+ for (codeIdx = 0; codeIdx < ARRAY_COUNT(hTable->codesB); codeIdx++) {
+ if (hTable->codesB[codeIdx] == 0xFFFF) {
+ continue;
+ }
+
+ codeOff = buff >> (15 - codeIdx);
+ if (codeOff <= hTable->codesB[codeIdx]) {
+ break;
+ }
+ }
+
+ if (codeIdx >= ARRAY_COUNT(hTable->codesB)) {
+ return true;
+ }
+
+ sym = hTable->symbols[hTable->codeOffs[codeIdx] + codeOff - hTable->codesA[codeIdx]];
+ *outZeroCount = sym >> 4;
+ sym &= 0xF;
+
+ sJpegBitStreamBitIdx += codeIdx - 15;
+ *outCoeff = 0;
+ if (sym) {
+ *outCoeff = JpegDecoder_ReadBits(sym);
+ if (*outCoeff < (1 << (sym - 1))) {
+ *outCoeff += (-1 << sym) + 1;
+ }
+ }
+
+ return false;
+}
+
+u16 JpegDecoder_ReadBits(u8 len) {
+ u8 byteCount;
+ u8 data;
+ s32 ret;
+ u32 temp;
+ ret = 0; // this is required for some reason
+
+ for (byteCount = sJpegBitStreamBitIdx >> 3; byteCount > 0; byteCount--) {
+ data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++];
+ if (sJpegBitStreamDontSkip) {
+ if (data == 0) {
+ data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++];
+ }
+ }
+
+ sJpegBitStreamDontSkip = (data == 0xFF) ? true : false;
+
+ sJpegBitStreamCurWord <<= 8;
+ sJpegBitStreamCurWord |= data;
+ sJpegBitStreamBitIdx -= 8;
+ }
+
+ ret = (sJpegBitStreamCurWord << (sJpegBitStreamBitIdx));
+ temp = ret;
+ ret = temp >> -len;
+ sJpegBitStreamBitIdx += len;
+ return ret;
+}