diff options
| author | Anghelo Carvajal <angheloalf95@gmail.com> | 2021-11-19 17:34:45 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-19 17:34:45 -0300 |
| commit | 2854294009725379c73e121671f7f3b0dadfed67 (patch) | |
| tree | d3607be7fd2c9b9617709b55382ab1275f0370c9 /src/code/jpegdecoder.c | |
| parent | c8b0ff3f747e7c3651788b703cfa355fd9c28b8c (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.c | 193 |
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; +} |
