From e37ee72feb21fadc2ff3aa3dbf450b18fc71afe9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 19 Jun 2025 08:28:36 -0700 Subject: [PATCH] ditto --- src/lib_rdi/rdi_parse.c | 350 +++++++++++++++++++++++----------------- src/lib_rdi/rdi_parse.h | 3 + src/rdi/rdi_local.c | 49 ------ src/rdi/rdi_local.h | 5 - 4 files changed, 204 insertions(+), 203 deletions(-) diff --git a/src/lib_rdi/rdi_parse.c b/src/lib_rdi/rdi_parse.c index 2c36ccb4..b4ebc551 100644 --- a/src/lib_rdi/rdi_parse.c +++ b/src/lib_rdi/rdi_parse.c @@ -1,6 +1,159 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) +//////////////////////////////// +//~ Compression/Decompression Forward-Declares + +#ifndef _RAD_LZB_SIMPLE_H_ +#define _RAD_LZB_SIMPLE_H_ + +/*====================================================== + +To encode : + + Set up an rr_lzb_simple_context + + fill out m_tableSizeBits (14-16 is typical) + + allocate m_hashTable + + rr_lzb_simple_context c; + c.m_tableSizeBits = 14; + c.m_hashTable = OODLE_MALLOC_ARRAY(U16,RR_ONE_SA< +typedef uint8_t U8; +typedef uint16_t U16; +typedef uint32_t U32; +typedef uint64_t U64; +typedef int8_t S8; +typedef int16_t S16; +typedef int32_t S32; +typedef int64_t S64; + +typedef S64 SINTa; +typedef U64 RAD_U64; +typedef S64 RAD_S64; +typedef U32 RAD_U32; +typedef S32 RAD_S32; + +#define RADINLINE __inline + +#if defined(_MSC_VER) +# define RADFORCEINLINE __forceinline +#elif defined(__clang__) || defined(__GNUC__) +# define RADFORCEINLINE __attribute__((always_inline)) +#else +# error need force inline for this compiler +#endif + +#if _MSC_VER +# define RADLZB_TRAP() __debugbreak() +#elif __clang__ || __GNUC__ +# define RADLZB_TRAP() __builtin_trap() +#else +# error Unknown trap intrinsic for this compiler. +#endif + +#define RR_STRING_JOIN(arg1, arg2) RR_STRING_JOIN_DELAY(arg1, arg2) +#define RR_STRING_JOIN_DELAY(arg1, arg2) RR_STRING_JOIN_IMMEDIATE(arg1, arg2) +#define RR_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2 + +#ifdef _MSC_VER +#define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__COUNTER__) +#else +#define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__LINE__) +#endif + +#define RR_COMPILER_ASSERT(exp) typedef char RR_NUMBERNAME(_dummy_array) [ (exp) ? 1 : -1 ] + +#if defined(__clang__) +# define Expect(expr, val) __builtin_expect((expr), (val)) +#else +# define Expect(expr, val) (expr) +#endif + +#define RAD_LIKELY(expr) Expect(expr,1) +#define RAD_UNLIKELY(expr) Expect(expr,0) + +#define __RADLITTLEENDIAN__ 1 +#define RAD_PTRBYTES 8 +#define RR_MIN(a,b) ( (a) < (b) ? (a) : (b) ) +#define RR_MAX(a,b) ( (a) > (b) ? (a) : (b) ) +#define RR_ASSERT_ALWAYS(c) do{if(!(c)) {RADLZB_TRAP();}}while(0) +#define RR_ASSERT(c) RR_ASSERT_ALWAYS(c) + +#define RR_PUT16_LE(ptr,val) *((U16 *)(ptr)) = (U16)(val) +#define RR_GET16_LE_UNALIGNED(ptr) *((const U16 *)(ptr)) + +static RADINLINE U32 +rrCtzBytes32(U32 val) +{ + // Don't get fancy here. Assumes val != 0. + if (val & 0x000000ffu) return 0; + if (val & 0x0000ff00u) return 1; + if (val & 0x00ff0000u) return 2; + return 3; +} + +static RADINLINE U32 +rrCtzBytes64(U64 val) +{ + U32 lo = (U32) val; + return lo ? rrCtzBytes32(lo) : 4 + rrCtzBytes32((U32) (val >> 32)); +} + +//~ + +//--------------------- + +typedef struct rr_lzb_simple_context rr_lzb_simple_context; +struct rr_lzb_simple_context +{ + U16 * m_hashTable; // must be allocated to sizeof(U16)*(1<raw_data; + RDI_Header *dst_header = (RDI_Header *)decompressed_data; + { + MemoryCopy(dst_header, src_header, sizeof(RDI_Header)); + } + + // rjf: copy & adjust sections for decompressed version + if(og_rdi->sections_count != 0) + { + RDI_Section *dsec_base = (RDI_Section *)(decompressed_data + dst_header->data_section_off); + MemoryCopy(dsec_base, (U8 *)og_rdi->raw_data + src_header->data_section_off, sizeof(RDI_Section) * og_rdi->sections_count); + U64 off = dst_header->data_section_off + sizeof(RDI_Section) * og_rdi->sections_count; + off += 7; + off -= off%8; + for(U64 idx = 0; idx < og_rdi->sections_count; idx += 1) + { + dsec_base[idx].encoding = RDI_SectionEncoding_Unpacked; + dsec_base[idx].off = off; + dsec_base[idx].encoded_size = dsec_base[idx].unpacked_size; + off += dsec_base[idx].unpacked_size; + off += 7; + off -= off%8; + } + } + + // rjf: decompress sections into new decompressed file buffer + if(og_rdi->sections_count != 0) + { + RDI_Section *src_first = og_rdi->sections; + RDI_Section *dst_first = (RDI_Section *)(decompressed_data + dst_header->data_section_off); + RDI_Section *src_opl = src_first + og_rdi->sections_count; + RDI_Section *dst_opl = dst_first + og_rdi->sections_count; + for(RDI_Section *src = src_first, *dst = dst_first; + src < src_opl && dst < dst_opl; + src += 1, dst += 1) + { + rr_lzb_simple_decode((U8*)og_rdi->raw_data + src->off, src->encoded_size, + decompressed_data + dst->off, dst->unpacked_size); + } + } +} + //- strings RDI_PROC RDI_U8 * @@ -866,155 +1067,6 @@ rdi_size_from_bytecode_stream(RDI_U8 *ptr, RDI_U8 *opl) //////////////////////////////// //~ Compression/Decompression Implementation -#ifndef _RAD_LZB_SIMPLE_H_ -#define _RAD_LZB_SIMPLE_H_ - -/*====================================================== - -To encode : - - Set up an rr_lzb_simple_context - - fill out m_tableSizeBits (14-16 is typical) - - allocate m_hashTable - - rr_lzb_simple_context c; - c.m_tableSizeBits = 14; - c.m_hashTable = OODLE_MALLOC_ARRAY(U16,RR_ONE_SA< -typedef uint8_t U8; -typedef uint16_t U16; -typedef uint32_t U32; -typedef uint64_t U64; -typedef int8_t S8; -typedef int16_t S16; -typedef int32_t S32; -typedef int64_t S64; - -typedef S64 SINTa; -typedef U64 RAD_U64; -typedef S64 RAD_S64; -typedef U32 RAD_U32; -typedef S32 RAD_S32; - -#define RADINLINE __inline - -#if defined(_MSC_VER) -# define RADFORCEINLINE __forceinline -#elif defined(__clang__) || defined(__GNUC__) -# define RADFORCEINLINE __attribute__((always_inline)) -#else -# error need force inline for this compiler -#endif - -#if _MSC_VER -# define RADLZB_TRAP() __debugbreak() -#elif __clang__ || __GNUC__ -# define RADLZB_TRAP() __builtin_trap() -#else -# error Unknown trap intrinsic for this compiler. -#endif - -#define RR_STRING_JOIN(arg1, arg2) RR_STRING_JOIN_DELAY(arg1, arg2) -#define RR_STRING_JOIN_DELAY(arg1, arg2) RR_STRING_JOIN_IMMEDIATE(arg1, arg2) -#define RR_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2 - -#ifdef _MSC_VER -#define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__COUNTER__) -#else -#define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__LINE__) -#endif - -#define RR_COMPILER_ASSERT(exp) typedef char RR_NUMBERNAME(_dummy_array) [ (exp) ? 1 : -1 ] - -#if defined(__clang__) -# define Expect(expr, val) __builtin_expect((expr), (val)) -#else -# define Expect(expr, val) (expr) -#endif - -#define RAD_LIKELY(expr) Expect(expr,1) -#define RAD_UNLIKELY(expr) Expect(expr,0) - -#define __RADLITTLEENDIAN__ 1 -#define RAD_PTRBYTES 8 -#define RR_MIN(a,b) ( (a) < (b) ? (a) : (b) ) -#define RR_MAX(a,b) ( (a) > (b) ? (a) : (b) ) -#define RR_ASSERT_ALWAYS(c) do{if(!(c)) {RADLZB_TRAP();}}while(0) -#define RR_ASSERT(c) RR_ASSERT_ALWAYS(c) - -#define RR_PUT16_LE(ptr,val) *((U16 *)(ptr)) = (U16)(val) -#define RR_GET16_LE_UNALIGNED(ptr) *((const U16 *)(ptr)) - -static RADINLINE U32 -rrCtzBytes32(U32 val) -{ - // Don't get fancy here. Assumes val != 0. - if (val & 0x000000ffu) return 0; - if (val & 0x0000ff00u) return 1; - if (val & 0x00ff0000u) return 2; - return 3; -} - -static RADINLINE U32 -rrCtzBytes64(U64 val) -{ - U32 lo = (U32) val; - return lo ? rrCtzBytes32(lo) : 4 + rrCtzBytes32((U32) (val >> 32)); -} - -//~ - -//--------------------- - -typedef struct rr_lzb_simple_context rr_lzb_simple_context; -struct rr_lzb_simple_context -{ - U16 * m_hashTable; // must be allocated to sizeof(U16)*(1< //------------------------------------------------- diff --git a/src/lib_rdi/rdi_parse.h b/src/lib_rdi/rdi_parse.h index c5267b01..7ea6193c 100644 --- a/src/lib_rdi/rdi_parse.h +++ b/src/lib_rdi/rdi_parse.h @@ -152,6 +152,9 @@ RDI_PROC void *rdi_section_raw_element_from_kind_idx(RDI_Parsed *rdi, RDI_Sectio //- info about whole parse RDI_PROC RDI_U64 rdi_decompressed_size_from_parsed(RDI_Parsed *rdi); +//- decompression +internal void rdi_decompress_parsed(U8 *decompressed_data, U64 decompressed_size, RDI_Parsed *og_rdi); + //- strings RDI_PROC RDI_U8 *rdi_string_from_idx(RDI_Parsed *rdi, RDI_U32 idx, RDI_U64 *len_out); diff --git a/src/rdi/rdi_local.c b/src/rdi/rdi_local.c index 166bc023..d0a973e3 100644 --- a/src/rdi/rdi_local.c +++ b/src/rdi/rdi_local.c @@ -4,55 +4,6 @@ #include "lib_rdi/rdi.c" #include "lib_rdi/rdi_parse.c" -//////////////////////////////// -//~ rjf: RDI Decompression - -internal void -rdi_decompress_parsed(U8 *decompressed_data, U64 decompressed_size, RDI_Parsed *og_rdi) -{ - // rjf: copy header - RDI_Header *src_header = (RDI_Header *)og_rdi->raw_data; - RDI_Header *dst_header = (RDI_Header *)decompressed_data; - { - MemoryCopy(dst_header, src_header, sizeof(RDI_Header)); - } - - // rjf: copy & adjust sections for decompressed version - if(og_rdi->sections_count != 0) - { - RDI_Section *dsec_base = (RDI_Section *)(decompressed_data + dst_header->data_section_off); - MemoryCopy(dsec_base, (U8 *)og_rdi->raw_data + src_header->data_section_off, sizeof(RDI_Section) * og_rdi->sections_count); - U64 off = dst_header->data_section_off + sizeof(RDI_Section) * og_rdi->sections_count; - off += 7; - off -= off%8; - for(U64 idx = 0; idx < og_rdi->sections_count; idx += 1) - { - dsec_base[idx].encoding = RDI_SectionEncoding_Unpacked; - dsec_base[idx].off = off; - dsec_base[idx].encoded_size = dsec_base[idx].unpacked_size; - off += dsec_base[idx].unpacked_size; - off += 7; - off -= off%8; - } - } - - // rjf: decompress sections into new decompressed file buffer - if(og_rdi->sections_count != 0) - { - RDI_Section *src_first = og_rdi->sections; - RDI_Section *dst_first = (RDI_Section *)(decompressed_data + dst_header->data_section_off); - RDI_Section *src_opl = src_first + og_rdi->sections_count; - RDI_Section *dst_opl = dst_first + og_rdi->sections_count; - for(RDI_Section *src = src_first, *dst = dst_first; - src < src_opl && dst < dst_opl; - src += 1, dst += 1) - { - rr_lzb_simple_decode((U8*)og_rdi->raw_data + src->off, src->encoded_size, - decompressed_data + dst->off, dst->unpacked_size); - } - } -} - //////////////////////////////// //~ rjf: Lookup Helpers diff --git a/src/rdi/rdi_local.h b/src/rdi/rdi_local.h index 53b8f2b8..9b35144e 100644 --- a/src/rdi/rdi_local.h +++ b/src/rdi/rdi_local.h @@ -64,11 +64,6 @@ read_only global String8 rdi_name_title_from_dump_subset_table[] = #undef X }; -//////////////////////////////// -//~ rjf: RDI Decompression - -internal void rdi_decompress_parsed(U8 *decompressed_data, U64 decompressed_size, RDI_Parsed *og_rdi); - //////////////////////////////// //~ rjf: Lookup Helpers