Merge pull request #228 from zanderyk/jpeg-utils-match
Some checks failed
C/C++ CI / build (push) Has been cancelled

Jpeg utils match
This commit is contained in:
Revo 2026-02-27 22:01:32 -05:00 committed by GitHub
commit 756f7e332e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 211 additions and 274 deletions

View File

@ -274,6 +274,8 @@ build/src/hal_libc.o: CFLAGS += -signed
build/src/libleo/%.o: CC := $(CC_OLD)
build/src/jpegutils.o: CC := $(CC_OLD)
build/src/D470.o: CC := $(CC_OLD)
build/src/D470.o: OPTFLAGS := -O0
build/src/D470.o: MIPS_VERSION := -mips1

View File

@ -305,14 +305,14 @@ abs_asm = 0x8000B8A0; // type:func
LeoBootGame = 0x8000B8B0; // type:func
__LeoBootGame2 = 0x8000B9EC; // type:func
__LeoBootGame3 = 0x8000BD10; // type:func
func_8000BD70 = 0x8000BD70; // type:func
func_8000BDD8 = 0x8000BDD8; // type:func
func_8000BE5C = 0x8000BE5C; // type:func
func_8000BEC8 = 0x8000BEC8; // type:func
func_8000BF70 = 0x8000BF70; // type:func
JpegUtils_ProcessQuantizationTable = 0x8000BD70; // type:func
JpegUtils_ParseHuffmanCodesLengths = 0x8000BDD8; // type:func
JpegUtils_GetHuffmanCodes = 0x8000BE5C; // type:func
JpegUtils_SetHuffmanTable = 0x8000BEC8; // type:func
JpegUtils_ProcessHuffmanTableImpl = 0x8000BF70; // type:func
func_8000C02C = 0x8000C02C; // type:func
func_8000C104 = 0x8000C104; // type:func
func_8000C1AC = 0x8000C1AC; // type:func
JpegUtils_SetHuffmanTableOld = 0x8000C104; // type:func
JpegUtils_ProcessHuffmanTableImplOld = 0x8000C1AC; // type:func
func_8000C280 = 0x8000C280; // type:func
func_8000C4A8 = 0x8000C4A8; // type:func
func_8000C644 = 0x8000C644; // type:func

View File

@ -119,7 +119,7 @@ void func_80003558(UnkStruct80001380* arg0, unk_func_80003680_sp90* arg1) {
osCreateMesgQueue(&arg0->queue, &arg0->mesg, 1);
}
void func_80003608(unk_func_80003680_sp27* arg0, unk_func_80003680_spB0* arg1, unk_func_80003680_sp300* arg2) {
void func_80003608(unk_func_80003680_sp27* arg0, JpegHuffmanTable* arg1, unk_func_80003680_sp300* arg2) {
arg0->unk_00 = arg2->start_of_scan;
arg0->unk_04 = arg2->unk_00;
arg0->unk_05 = 2;
@ -143,7 +143,7 @@ s32 func_80003680(u32 addr, s32 arg1, u8* arg2) {
UnkStruct80001380 sp318;
unk_func_80003680_sp300 sp300;
u8 sp200[2][0x80];
unk_func_80003680_spB0 spB0[4];
JpegHuffmanTable spB0[4];
u16* temp_s0;
u8* temp_s3;
unk_func_80003680_sp90 sp90;
@ -159,8 +159,8 @@ s32 func_80003680(u32 addr, s32 arg1, u8* arg2) {
temp_s0 = Util_Malloc(0x210);
func_800033C8(&sp300, arg2);
func_8000BD70(sp300.quantization_table, sp200, 2);
func_8000C02C(sp300.huffman_table, spB0, temp_s3, temp_s0, 4);
JpegUtils_ProcessQuantizationTable(sp300.quantization_table, sp200, 2);
JpegUtils_ProcessHuffmanTable(sp300.huffman_table, spB0, temp_s3, temp_s0, 4);
Util_Free(temp_s0);
Util_Free(temp_s3);

View File

@ -3,7 +3,7 @@
#include "global.h"
#include "5580.h"
#include "C970.h"
#include "jpegutils.h"
#include "CE80.h"
#include "src/memmap.h"
#include "src/memory.h"
@ -87,7 +87,7 @@ typedef void (*ret_func_80004454)(void);
s32 func_800033B0(u8* arg0);
void func_800033C8(unk_func_80003680_sp300* arg0, u8* arg1);
void func_80003558(UnkStruct80001380* arg0, unk_func_80003680_sp90* arg1);
void func_80003608(unk_func_80003680_sp27* arg0, unk_func_80003680_spB0* arg1, unk_func_80003680_sp300* arg2);
void func_80003608(unk_func_80003680_sp27* arg0, JpegHuffmanTable* arg1, unk_func_80003680_sp300* arg2);
void func_80003648(unk_func_80003680_sp90* arg0, u8(arg1)[2][0x80], unk_func_80003680_sp300* arg2);
s32 func_80003680(u32 addr, s32 arg1, u8* arg2);
void func_80003860(void);

View File

@ -1,229 +0,0 @@
#include "C970.h"
typedef struct unk_func_8000C104_arg1 {
/* 0x000 */ u8 value;
/* 0x001 */ u8 pad01[0x0F];
/* 0x010 */ u16 unk_10;
/* 0x012 */ u8 pad12[0xEE];
/* 0x100 */ u16 unk_100;
} unk_func_8000C104_arg1; // size >= 0x102
#ifdef NON_MATCHING
void func_8000BD70(u8* in_quantization_tables, u8* out_quantization_tables, s32 num_tables) {
u8* src;
u8* dst;
s32 i;
s32 j;
s32 count;
src = in_quantization_tables;
count = num_tables & 0xFF;
for (i = 0; i < count; i++) {
src++;
for (j = 0; j < 0x40; j++) {
dst = out_quantization_tables + (i << 7) + (j * 2);
*(s16*)dst = (s16)*src;
src++;
}
}
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BD70.s")
#endif
#ifdef NON_MATCHING
s16 func_8000BDD8(u8* arg0, u16* arg1) {
s16 var_a2;
s16 var_v1;
s8 i;
s8 var_v0;
u8* temp_a1;
var_v0 = 1;
var_v1 = 0;
var_a2 = 1;
for (i = 1; i < 0x11; i = (var_v0 + 1) & 0xFF) {
temp_a1 = &arg0[i];
if ((s32) temp_a1[-1] > 0) {
do {
arg1[var_v1] = var_v0;
var_a2 += 1;
var_v1 += 1;
} while ((s32) temp_a1[-1] >= var_a2);
var_a2 = 1;
}
var_v0 = i;
}
arg1[var_v1] = 0;
return var_v1;
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BDD8.s")
#endif
#ifdef NON_MATCHING
s16 func_8000BE5C(u8* arg0, u16* arg1) {
s16 var_v0;
s16 var_v1;
s32 temp_t6;
u8 temp_t0;
u8 var_a2;
u8 var_a3;
var_a2 = *arg0;
var_v1 = 0;
var_v0 = 0;
var_a3 = var_a2;
while(1) {
temp_t6 = var_v1 * 2;
var_v1 += 1;
arg1[temp_t6] = var_v0;
temp_t0 = arg0[var_v1];
var_v0 = (var_v0 + 1) & 0xFFFF;
if (var_a3 == temp_t0) {
continue;
}
if (temp_t0 != 0) {
do {
var_a3 = (var_a2 + 1) & 0xFF;
var_v0 = (var_v0 * 2) & 0xFFFF;
var_a2 = var_a3;
} while (temp_t0 != var_a3);
continue;
}
break;
}
return var_v1;
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BE5C.s")
#endif
#ifdef NON_MATCHING
s8 func_8000BEC8(u8* arg0, unk_func_80003680_spB0* arg1, u16* arg2) {
s32 i;
s32 temp_t4;
s8 var_v1;
var_v1 = 0;
for (i = 0; i < 16; i = (i + 1) & 0xFF) {
if (arg0[i] != 0) {
arg1->unk_00[i] = var_v1;
arg1->unk_10[i] = arg2[var_v1];
temp_t4 = ((var_v1 + arg0[i]) - 1) & 0xFFFF;
var_v1 = (temp_t4 + 1);
arg1->unk_30[i] = arg2[temp_t4];
} else {
arg1->unk_30[i] = 0xFFFF;
}
}
return var_v1;
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BEC8.s")
#endif
#ifdef NON_MATCHING
s16 func_8000BF70(u8* arg0, unk_func_80003680_spB0* arg1, u8* arg2, u16* arg3, u8 arg4) {
s16 temp_v0;
temp_v0 = func_8000BDD8(arg2, arg3);
if ((temp_v0 == 0) || ((arg4 != 0) && (temp_v0 >= 0x101)) || ((arg4 == 0) && (temp_v0 >= 0x11))) {
return 0;
}
if (func_8000BE5C(arg2, arg3) != temp_v0) {
return 0;
}
if (temp_v0 != func_8000BEC8(arg0, arg1, arg3)) {
return 0;
}
return temp_v0;
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000BF70.s")
#endif
#ifdef NON_MATCHING
s32 func_8000C02C(u8* arg0, unk_func_80003680_spB0* arg1, u8* arg2, u16* arg3, s32 arg4) {
s32 temp_at;
s32 temp_lo;
s32 temp_t8;
s32 temp_v0;
s32 var_s1;
u8* var_s0;
u8* temp_s0;
u8* temp_s0_2;
var_s0 = arg0;
var_s1 = 0;
if ((s32) arg4 > 0) {
while(1) {
temp_lo = var_s1 * 0x54;
temp_s0 = var_s0 + 1;
temp_v0 = func_8000BF70(temp_s0, &arg1[temp_lo], arg2, arg3, (s32) *var_s0 >> 4);
temp_s0_2 = temp_s0 + 0x10;
if (temp_v0 == 0) {
return 1;
}
temp_t8 = (var_s1 + 1) & 0xFF;
temp_at = temp_t8 < (s32) arg4;
arg1[temp_lo].unk_50 = temp_s0_2;
var_s1 = temp_t8;
var_s0 = temp_s0_2 + temp_v0;
if (temp_at == 0) {
return 0;
}
}
}
return 0;
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000C02C.s")
#endif
#ifdef NON_MATCHING
void func_8000C104(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3, s16 arg4, u8 arg5) {
s16 i;
u8 temp_v1;
for (i = 0; i < arg4; i++) {
temp_v1 = arg0[i];
if (arg5 != 0) {
arg1[temp_v1 * 2].unk_100 = arg3[i];
arg1[temp_v1].value = arg2[i];
} else {
arg1[temp_v1 * 2].unk_10 = arg3[i];
arg1[temp_v1].value = arg2[i];
}
}
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000C104.s")
#endif
#ifdef NON_MATCHING
s32 func_8000C1AC(u8* arg0, unk_func_8000C104_arg1* arg1, u8* arg2, u16* arg3) {
u8 sp2F;
s16 sp2C;
s16 temp_v0;
u8* temp_s0;
temp_s0 = arg0 + 1;
sp2F = (u8) ((s32) *arg0 >> 4);
temp_v0 = func_8000BDD8(temp_s0, arg2);
if ((temp_v0 == 0) || ((sp2F != 0) && (temp_v0 >= 0x101)) || ((sp2F == 0) && (temp_v0 >= 0x11))) {
return 1;
}
sp2C = temp_v0;
if (func_8000BE5C(arg2, arg3) != temp_v0) {
return 1;
}
func_8000C104((u8*)temp_s0 + 0x10, arg1, arg2, arg3, temp_v0, sp2F);
return 0;
}
#else
#pragma GLOBAL_ASM("asm/us/nonmatchings/C970/func_8000C1AC.s")
#endif

View File

@ -1,16 +0,0 @@
#ifndef _C970_H_
#define _C970_H_
#include "global.h"
typedef struct unk_func_80003680_spB0 {
/* 0x00 */ u8 unk_00[16];
/* 0x10 */ u16 unk_10[16];
/* 0x30 */ u16 unk_30[16];
/* 0x50 */ s32 unk_50;
} unk_func_80003680_spB0; // size = 0x54
void func_8000BD70(u8* in_quantization_tables, u8* out_quantization_tables, s32 num_tables);
s32 func_8000C02C(u8*, unk_func_80003680_spB0*, u8*, u16*, s32);
#endif // _C970_H_

View File

@ -14,10 +14,10 @@ s32 func_8000C280(unk_func_80003680_sp27* arg0, u32 arg1, u32 arg2, u8 arg3, unk
s16 sp60;
u32 i;
s32 sp58;
unk_func_80003680_spB0* temp_fp;
unk_func_80003680_spB0* temp_s4;
unk_func_80003680_spB0* temp_s5;
unk_func_80003680_spB0* temp_s7;
JpegHuffmanTable* temp_fp;
JpegHuffmanTable* temp_s4;
JpegHuffmanTable* temp_s5;
JpegHuffmanTable* temp_s7;
sp58 = 0;
D_800A82D0 = arg0->unk_00;
@ -93,7 +93,7 @@ s32 func_8000C280(unk_func_80003680_sp27* arg0, u32 arg1, u32 arg2, u8 arg3, unk
#endif
#ifdef NON_MATCHING
s32 func_8000C4A8(unk_func_80003680_spB0* arg0, unk_func_80003680_spB0* arg1, s16* arg2, s16* arg3) {
s32 func_8000C4A8(JpegHuffmanTable* arg0, JpegHuffmanTable* arg1, s16* arg2, s16* arg3) {
s8 i;
s8 sp36;
s16 sp34;
@ -146,7 +146,7 @@ typedef struct sp24_func_8000C644 {
} sp24_func_8000C644;
#ifdef NON_MATCHING
s32 func_8000C644(unk_func_80003680_spB0* arg0, s16* arg1, s8* arg2) {
s32 func_8000C644(JpegHuffmanTable* arg0, s16* arg1, s8* arg2) {
u8 i;
sp24_func_8000C644 sp24;
s16 temp_v0;
@ -157,7 +157,7 @@ s32 func_8000C644(unk_func_80003680_spB0* arg0, s16* arg1, s8* arg2) {
for (i = 0; i < 16; i++) {
sp24.unk_00 = temp_v0 >> (0xF - i);
if ((arg0->unk_30[i] != 0xFFFF) && !(arg0->unk_30[i] < sp24.unk_00)) {
if ((arg0->codesB[i] != 0xFFFF) && !(arg0->codesB[i] < sp24.unk_00)) {
break;
}
}
@ -166,7 +166,7 @@ s32 func_8000C644(unk_func_80003680_spB0* arg0, s16* arg1, s8* arg2) {
return 1;
}
sp24.unk_02 = *(u8*)(((arg0->unk_00[i] + sp24.unk_00) - arg0->unk_10[i]) + arg0->unk_50);
sp24.unk_02 = *(u8*)(((arg0->codeOffs[i] + sp24.unk_00) - arg0->codesA[i]) + arg0->symbols);
*arg2 = sp24.unk_02 >> 4;
D_800A82D8 = (D_800A82D8 + i) - 0xF;

View File

@ -2,16 +2,16 @@
#define _CE80_H_
#include "global.h"
#include "C970.h"
#include "jpegutils.h"
typedef struct unk_func_80003680_sp27 {
/* 0x00 */ s32 unk_00;
/* 0x04 */ u8 unk_04;
/* 0x05 */ u8 unk_05;
/* 0x08 */ unk_func_80003680_spB0* unk_08;
/* 0x0C */ unk_func_80003680_spB0* unk_0C;
/* 0x10 */ unk_func_80003680_spB0* unk_10;
/* 0x14 */ unk_func_80003680_spB0* unk_14;
/* 0x08 */ JpegHuffmanTable* unk_08;
/* 0x0C */ JpegHuffmanTable* unk_0C;
/* 0x10 */ JpegHuffmanTable* unk_10;
/* 0x14 */ JpegHuffmanTable* unk_14;
/* 0x18 */ s8 unk_18;
} unk_func_80003680_sp27; // size == 0x1C
@ -26,8 +26,8 @@ typedef struct unk_func_80003680_sp60 {
} unk_func_80003680_sp60; // size = 0x14
s32 func_8000C280(unk_func_80003680_sp27*, u32, u32, u8, unk_func_80003680_sp60*);
s32 func_8000C4A8(unk_func_80003680_spB0*, unk_func_80003680_spB0*, s16*, s16*);
s32 func_8000C644(unk_func_80003680_spB0*, s16*, s8*);
s32 func_8000C4A8(JpegHuffmanTable*, JpegHuffmanTable*, s16*, s16*);
s32 func_8000C644(JpegHuffmanTable*, s16*, s8*);
u16 func_8000C780(u8);
#endif // _CE80_H_

159
src/jpegutils.c Normal file
View File

@ -0,0 +1,159 @@
#include "jpegutils.h"
typedef struct JpegHuffmanTableOld {
/* 0x000 */ u8 codeOffs[16];
/* 0x010 */ u16 dcCodes[120];
/* 0x100 */ u16 acCodes[256];
} JpegHuffmanTableOld; // size >= 0x300
void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 num_tables) {
u8 i;
for (i = 0; i < num_tables; 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;
}
s16 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;
}
u16 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;
}
s32 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;
}

21
src/jpegutils.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef JPEGUTILS_H
#define JPEGUTILS_H
#include "global.h"
typedef struct JpegHuffmanTable {
/* 0x00 */ u8 codeOffs[16];
/* 0x10 */ u16 codesA[16];
/* 0x30 */ u16 codesB[16];
/* 0x50 */ u8* symbols;
} JpegHuffmanTable; // size = 0x54
typedef struct JpegQuantizationTable {
/* 0x00 */ u16 table[8*8];
} JpegQuantizationTable; // size = 0x80
void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 num_tables);
s32 JpegUtils_ProcessHuffmanTable(u8*, JpegHuffmanTable*, u8*, u16*, u8);
u16 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes);
#endif // JPEGUTILS_H

View File

@ -47,7 +47,7 @@
- [0xC4A0, hasm, abs] # abs function
- [0xC4B0, c, libleo/bootdisk]
- [0xC910, hasm, ../../src/libleo/bootstrap]
- [0xC970, c]
- [0xC970, c, jpegutils]
- [0xCE80, c] #
- [0xD470, c] #
- [0xDDC0, c]