diff --git a/src/object.c b/src/object.c index b03c07a0ba..936e4d3526 100644 --- a/src/object.c +++ b/src/object.c @@ -2641,7 +2641,7 @@ int object_get_scenario_text(rct_object_entry *entry) } else { chunk = (uint8*)malloc(chunkSize); - sawyercoding_read_chunk(rw, chunk); + sawyercoding_read_chunk_with_size(rw, chunk, chunkSize); } SDL_RWclose(rw); diff --git a/src/util/sawyercoding.c b/src/util/sawyercoding.c index cce8181427..b903823720 100644 --- a/src/util/sawyercoding.c +++ b/src/util/sawyercoding.c @@ -140,6 +140,52 @@ size_t sawyercoding_read_chunk(SDL_RWops* rw, uint8 *buffer) return chunkHeader.length; } +/** + * + * rct2: 0x0067685F + * buffer (esi) + */ +size_t sawyercoding_read_chunk_with_size(SDL_RWops* rw, uint8 *buffer, const size_t buffer_size) +{ + sawyercoding_chunk_header chunkHeader; + + // Read chunk header + if (SDL_RWread(rw, &chunkHeader, sizeof(sawyercoding_chunk_header), 1) != 1) { + log_error("Unable to read chunk header!"); + return -1; + } + + uint8* src_buffer = malloc(chunkHeader.length); + + // Read chunk data + if (SDL_RWread(rw, src_buffer, chunkHeader.length, 1) != 1) { + free(src_buffer); + log_error("Unable to read chunk data!"); + return -1; + } + + // Decode chunk data + switch (chunkHeader.encoding) { + case CHUNK_ENCODING_NONE: + assert(chunkHeader.length <= buffer_size); + memcpy(buffer, src_buffer, chunkHeader.length); + break; + case CHUNK_ENCODING_RLE: + chunkHeader.length = decode_chunk_rle(src_buffer, buffer, chunkHeader.length); + break; + case CHUNK_ENCODING_RLECOMPRESSED: + chunkHeader.length = decode_chunk_rle(src_buffer, buffer, chunkHeader.length); + chunkHeader.length = decode_chunk_repeat(buffer, chunkHeader.length); + break; + case CHUNK_ENCODING_ROTATE: + memcpy(buffer, src_buffer, chunkHeader.length); + decode_chunk_rotate(buffer, chunkHeader.length); + break; + } + free(src_buffer); + return chunkHeader.length; +} + /** * * rct2: 0x006762E1 diff --git a/src/util/sawyercoding.h b/src/util/sawyercoding.h index 360ef82246..5160c125ce 100644 --- a/src/util/sawyercoding.h +++ b/src/util/sawyercoding.h @@ -51,6 +51,7 @@ int sawyercoding_validate_checksum(SDL_RWops* rw); uint32 sawyercoding_calculate_checksum(const uint8* buffer, size_t length); bool sawyercoding_read_chunk_safe(SDL_RWops *rw, void *dst, size_t dstLength); size_t sawyercoding_read_chunk(SDL_RWops* rw, uint8 *buffer); +size_t sawyercoding_read_chunk_with_size(SDL_RWops* rw, uint8 *buffer, const size_t buffer_size); size_t sawyercoding_write_chunk_buffer(uint8 *dst_file, uint8* buffer, sawyercoding_chunk_header chunkHeader); size_t sawyercoding_decode_sv4(const uint8 *src, uint8 *dst, size_t length); size_t sawyercoding_decode_sc4(const uint8 *src, uint8 *dst, size_t length);