OpenBarnyard
 
Loading...
Searching...
No Matches
TCompress Class Reference

#include <TCompress.h>

Classes

struct  Header
 

Static Public Member Functions

static size_t Compress (TFile *file, TBYTE *data, TUINT32 size, TUINT32 unused, TBOOL isBigEndian)
 
static uintptr_t Decompress (TFile *file, TCompress::Header *header, TBYTE *buffer, TUINT32 bufferSize)
 
static int8_t GetHeader (TFile *file, TCompress::Header &btecHeader)
 
static TINT GetCommand (TFile *file, TBOOL &hasOffset, TUINT32 &size, TINT &offset)
 

Static Public Attributes

static constexpr TUINT32 HEADER_SIZE_12 = sizeof( Header ) - sizeof( Header::XorValue )
 
static constexpr TUINT32 HEADER_SIZE_13 = sizeof( Header )
 
static TBOOL ms_bIsBigEndian = false
 
static constexpr TINT maxlength = 0x4000
 
static TINT usemaxoffset
 

Detailed Description

Definition at line 29 of file TCompress.h.

Member Function Documentation

◆ Compress()

TSIZE TCompress::Compress ( TFile * file,
TBYTE * data,
TUINT32 size,
TUINT32 unused,
TBOOL isBigEndian )
static

Definition at line 89 of file TCompress_Compress.cpp.

90{
91 BTECCompressor compressor;
92
93 usemaxoffset = 0x8000;
94 compressor.Initialize( buffer, size, usemaxoffset, 3 );
95
96 TBYTE* bufferPos = buffer;
97 TBYTE* bufferEnd = buffer + size;
98
99 auto initialPos = file->Tell();
101
102 TSIZE compressedSize = 0;
103 TSIZE chunkSize = 0;
104 TBYTE* chunkStart = TNULL;
105
106 while ( bufferPos < bufferEnd )
107 {
108 TSIZE uncompressedLeft = TMath::Min<TSIZE>( size - ( bufferPos - buffer ), maxlength );
109
110 TBYTE* offset = TNULL;
111 TSIZE dataSize = 0;
112 TBOOL hasOffset = compressor.FUN_0068af10( bufferPos, uncompressedLeft, offset, dataSize );
113
114 if ( hasOffset == TFALSE || dataSize < 3 )
115 {
116 dataSize = 1;
117
118 // Check if we have to start a new chunk
119 if ( chunkStart == TNULL ) chunkStart = bufferPos;
120 chunkSize += 1;
121
122 if ( maxlength <= chunkSize )
123 {
124 // Write a chunk of data
125 compressedSize += TCompress::Write( chunkSize, chunkStart, file );
126 chunkStart = TNULL;
127 chunkSize = 0;
128 }
129
130 bufferPos += 1;
131 }
132 else
133 {
134 if ( chunkStart != TNULL )
135 {
136 // We found an offset but we have a not-written chunk of data so write it
137 compressedSize += TCompress::Write( chunkSize, chunkStart, file );
138 chunkStart = TNULL;
139 chunkSize = 0;
140 }
141
142 compressedSize += TCompress::WriteOffset( dataSize, bufferPos - offset, bufferPos, file );
143 }
144
145 compressor.FUN_0068ae40( dataSize );
146 }
147
148 if ( chunkStart != TNULL )
149 {
150 // We are out of the while loop but still have some chunk of data that should be written
151 compressedSize += TCompress::Write( chunkSize, chunkStart, file );
152 }
153
154 TCompress::Header btecHeader;
155 btecHeader.Magic = TFourCC( "BTEC" );
156 btecHeader.Version = TVERSION( 1, 2 );
157 btecHeader.CompressedSize = compressedSize;
158 btecHeader.Size = size;
159
160 if ( isBigEndian )
161 {
162 btecHeader.Magic = PARSEDWORD_BIG( btecHeader.Magic );
163 btecHeader.Version = PARSEDWORD_BIG( btecHeader.Version );
164 btecHeader.CompressedSize = PARSEDWORD_BIG( btecHeader.CompressedSize );
165 btecHeader.Size = PARSEDWORD_BIG( btecHeader.Size );
166 }
167
168 file->Seek( initialPos, TSEEK_SET );
169 file->Write( &btecHeader, TCompress::HEADER_SIZE_12 );
170 file->Seek( compressedSize, TSEEK_CUR );
171
172 return compressedSize;
173}
@ TSEEK_SET
Definition TFile.h:30
@ TSEEK_CUR
Definition TFile.h:31
#define TVERSION(VER_MAJOR, VER_MINOR)
Definition Defines.h:14
TFORCEINLINE constexpr TUINT32 TFourCC(const TCHAR str[4])
Definition Helpers.h:15
size_t TSIZE
Definition Typedefs.h:9
#define TNULL
Definition Typedefs.h:23
#define TFALSE
Definition Typedefs.h:24
bool TBOOL
Definition Typedefs.h:6
uint8_t TBYTE
Definition Typedefs.h:19
TFORCEINLINE const T & Min(const T &a, const T &b)
void FUN_0068ae40(size_t dataSize)
TBOOL FUN_0068af10(TBYTE *buffer, size_t bufferSize, TBYTE *&offset, size_t &dataSize)
void Initialize(TBYTE *buffer, size_t bufferSize, TINT maxoffset, TINT unk)
static constexpr TUINT32 HEADER_SIZE_12
Definition TCompress.h:46
static constexpr TINT maxlength
Definition TCompress.h:59
static TINT usemaxoffset
Definition TCompress.h:60
TVersion Version
Definition TCompress.h:39
TUINT32 CompressedSize
Definition TCompress.h:40
virtual TBOOL Seek(TINT a_iOffset, TSEEK a_eOrigin=TSEEK_CUR)=0
Shifts current file cursor based on the specified offset and origin.
virtual TSIZE Tell()=0
virtual TSIZE Write(const void *a_pSrc, TSIZE a_uiSize)=0
Writes specified number of bytes to the file from the buffer.

◆ Decompress()

uintptr_t TCompress::Decompress ( TFile * file,
TCompress::Header * header,
TBYTE * buffer,
TUINT32 bufferSize )
static

Definition at line 13 of file TCompress_Decompress.cpp.

14{
16
17 if ( header->Magic != TFourCC( "BTEC" ) )
19 if ( header->Version != TVERSION( 1, 2 ) && header->Version != TVERSION( 1, 3 ) )
21 if ( header->Size > bufferSize )
23
24 TBYTE* pBufferPos = buffer;
25 TUINT32 compressedLeft = header->CompressedSize;
26
27 while ( compressedLeft > 0 )
28 {
29 TUINT32 chunkSize;
30 TBOOL noOffset;
31 TINT offset;
32
33 compressedLeft -= GetCommand( file, noOffset, chunkSize, offset );
34
35 if ( !noOffset )
36 {
37 // The data is already unpacked so just copy it
38 TBYTE* unpackedData = pBufferPos - offset;
39
40 while ( chunkSize > 0 )
41 {
42 *( pBufferPos++ ) = *( unpackedData++ );
43 chunkSize--;
44 }
45 }
46 else
47 {
48 // The data wasn't previously unpacked, read it from file
49 TSIZE readedCount = file->Read( pBufferPos, chunkSize );
50 pBufferPos += readedCount;
51 compressedLeft -= readedCount;
52 }
53 }
54
55 if ( header->Version == TVERSION( 1, 3 ) )
56 {
57 pBufferPos = buffer;
58 for ( TSIZE i = 0; i < header->Size; i++, pBufferPos++ )
59 {
60 *pBufferPos ^= header->XorValue;
61 }
62 }
63
64 uintptr_t sizeDecompressed = pBufferPos - buffer;
65 TASSERT( sizeDecompressed == header->Size, "Wrong decompressed size" );
66
67 return sizeDecompressed;
68}
@ TCOMPRESS_ERROR_WRONG_MAGIC
Definition TCompress.h:10
@ TCOMPRESS_ERROR_WRONG_SIZE
Definition TCompress.h:12
@ TCOMPRESS_ERROR_WRONG_VERSION
Definition TCompress.h:11
#define TASSERT(X,...)
Definition Defines.h:138
#define TPROFILER_SCOPE()
Definition Profiler.h:17
uint32_t TUINT32
Definition Typedefs.h:13
int TINT
Definition Typedefs.h:7
static TINT GetCommand(TFile *file, TBOOL &hasOffset, TUINT32 &size, TINT &offset)
virtual TSIZE Read(void *a_pDst, TSIZE a_uiSize)=0
Reads specified number of bytes from the file into the buffer.

◆ GetCommand()

TINT TCompress::GetCommand ( TFile * file,
TBOOL & hasOffset,
TUINT32 & size,
TINT & offset )
static

Definition at line 114 of file TCompress_Decompress.cpp.

115{
116 TINT read_count = file->Read( &size, 1 );
117 TBOOL isBigSize = size & BTECSizeFlag_BigSize;
118 noOffset = size & BTECSizeFlag_NoOffset;
119 offset = -1;
120
121 // by default size is 6 bits long
122 size &= BTECSizeFlag_SizeMask;
123
124 if ( isBigSize )
125 {
126 // now the size is 14 bits long
127 uint8_t secondByte;
128 read_count += file->Read( &secondByte, 1 );
129 size = ( size << 8 ) | secondByte;
130 }
131
132 if ( !noOffset )
133 {
134 // by default offset is 7 bits long
135 read_count += file->Read( &offset, 1 );
136 TBOOL bigOffset = offset & BTECOffsetFlag_BigOffset;
138
139 if ( bigOffset )
140 {
141 // now the offset is 15 bits long
142 uint8_t secondByte;
143 read_count += file->Read( &secondByte, 1 );
144 offset = ( offset << 8 ) | secondByte;
145 }
146 }
147
148 size += 1;
149 offset += 1;
150
151 return read_count;
152}
@ BTECSizeFlag_NoOffset
Definition TCompress.h:19
@ BTECSizeFlag_BigSize
Definition TCompress.h:18
@ BTECSizeFlag_SizeMask
Definition TCompress.h:20
@ BTECOffsetFlag_BigOffset
Definition TCompress.h:25
@ BTECOffsetFlag_OffsetMask
Definition TCompress.h:26

◆ GetHeader()

int8_t TCompress::GetHeader ( TFile * file,
TCompress::Header & btecHeader )
static

Definition at line 71 of file TCompress_Decompress.cpp.

72{
74 TUINT32 savedPos = file->Tell();
75 TSIZE readedSize = file->Read( &btecHeader, headerSize );
76
77 if ( ms_bIsBigEndian )
78 {
79 btecHeader.Size = CONVERTENDIANESS( Endianess_Big, btecHeader.Size );
80 btecHeader.CompressedSize = CONVERTENDIANESS( Endianess_Big, btecHeader.CompressedSize );
81 btecHeader.Magic = CONVERTENDIANESS( Endianess_Big, btecHeader.Magic );
82 btecHeader.Version = CONVERTENDIANESS( Endianess_Big, btecHeader.Version.Value );
83 }
84
85 if ( btecHeader.Version == TVERSION( 1, 3 ) )
86 {
87 readedSize += file->Read( &btecHeader.XorValue, sizeof( TCompress::Header::XorValue ) );
88 headerSize += sizeof( TCompress::Header::XorValue );
89
90 if ( ms_bIsBigEndian )
91 {
92 btecHeader.XorValue = CONVERTENDIANESS( Endianess_Big, btecHeader.XorValue );
93 }
94 }
95
96 if ( readedSize != headerSize )
97 {
98 file->Seek( savedPos, TSEEK_SET );
100 }
101
102 if ( btecHeader.Magic != TFourCC( "BTEC" ) )
103 {
104 file->Seek( savedPos, TSEEK_SET );
106 }
107
108 return TCOMPRESS_ERROR_OK;
109}
@ TCOMPRESS_ERROR_WRONG_HEADERSIZE
Definition TCompress.h:13
@ TCOMPRESS_ERROR_OK
Definition TCompress.h:9
@ Endianess_Big
Definition Endianness.h:9
static TBOOL ms_bIsBigEndian
Definition TCompress.h:52
TUINT32 Value
Definition TVersion.h:8

Member Data Documentation

◆ HEADER_SIZE_12

TUINT32 TCompress::HEADER_SIZE_12 = sizeof( Header ) - sizeof( Header::XorValue )
staticconstexpr

Definition at line 46 of file TCompress.h.

◆ HEADER_SIZE_13

TUINT32 TCompress::HEADER_SIZE_13 = sizeof( Header )
staticconstexpr

Definition at line 49 of file TCompress.h.

◆ maxlength

TINT TCompress::maxlength = 0x4000
staticconstexpr

Definition at line 59 of file TCompress.h.

◆ ms_bIsBigEndian

TBOOL TCompress::ms_bIsBigEndian = false
inlinestatic

Definition at line 52 of file TCompress.h.

◆ usemaxoffset

TINT TCompress::usemaxoffset
static

Definition at line 60 of file TCompress.h.


The documentation for this class was generated from the following files: