yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
compression.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GFX_COMPRESSION_H
2#define YAZE_APP_GFX_COMPRESSION_H
3
4#include <cstdint>
5#include <memory>
6#include <string>
7#include <vector>
8
9#include "absl/status/status.h"
10#include "absl/status/statusor.h"
11#include "util/macro.h"
12
13#define BUILD_HEADER(command, length) (command << 5) + (length - 1)
14
15namespace yaze {
16namespace gfx {
17
18std::vector<uint8_t> HyruleMagicCompress(uint8_t const* const src,
19 int const oldsize, int* const size,
20 int const flag);
21
22std::vector<uint8_t> HyruleMagicDecompress(
23 uint8_t const* src, int* const size, int const p_big_endian,
24 size_t max_src_size = static_cast<size_t>(-1));
25
30namespace lc_lz2 {
31
32const int D_NINTENDO_C_MODE1 = 0;
33const int D_NINTENDO_C_MODE2 = 1;
34
35const int D_CMD_COPY = 0;
36const int D_CMD_BYTE_REPEAT = 1;
37const int D_CMD_WORD_REPEAT = 2;
38const int D_CMD_BYTE_INC = 3;
39const int D_CMD_COPY_EXISTING = 4;
40
41const int D_MAX_NORMAL_LENGTH = 32;
42const int D_MAX_LENGTH = 1024;
43
44const int INITIAL_ALLOC_SIZE = 1024;
45
46constexpr int kCommandDirectCopy = 0;
47constexpr int kCommandByteFill = 1;
48constexpr int kCommandWordFill = 2;
49constexpr int kCommandIncreasingFill = 3;
50constexpr int kCommandRepeatingBytes = 4;
51constexpr int kCommandLongLength = 7;
52constexpr int kMaxLengthNormalHeader = 32;
53constexpr int kMaxLengthCompression = 1024;
54constexpr int kNintendoMode1 = 0;
55constexpr int kNintendoMode2 = 1;
56constexpr int kSnesByteMax = 0xFF;
57constexpr int kCommandMod = 0x07;
58constexpr int kExpandedMod = 0xE0;
59constexpr int kExpandedLengthMod = 0x3FF;
60constexpr int kNormalLengthMod = 0x1F;
61constexpr int kCompressionStringMod = 7 << 5;
62
63// Represents a command in the compression algorithm.
65 // The command arguments for each possible command.
66 std::array<std::array<char, 2>, 5> arguments;
67
68 // The size of each possible command.
69 std::array<uint, 5> cmd_size;
70
71 // The size of the data processed by each possible command.
72 std::array<uint, 5> data_size;
73};
74
75using CommandArgumentArray = std::array<std::array<char, 2>, 5>;
76using CommandSizeArray = std::array<uint, 5>;
77using DataSizeArray = std::array<uint, 5>;
78
79// Represents a piece of compressed data.
81 char command;
82 int length;
84 std::string argument;
85 std::shared_ptr<CompressionPiece> next = nullptr;
86 CompressionPiece() = default;
87 CompressionPiece(int cmd, int len, std::string& args, int arg_len)
88 : command(cmd), length(len), argument_length(arg_len), argument(args) {}
89};
91using CompressionPiecePointer = std::shared_ptr<CompressionPiece>;
92
94
96
97// Compression V1
98
99void CheckByteRepeat(const uint8_t* rom_data, DataSizeArray& data_size_taken,
100 CommandArgumentArray& cmd_args, uint& src_data_pos,
101 const unsigned int last_pos);
102
103void CheckWordRepeat(const uint8_t* rom_data, DataSizeArray& data_size_taken,
104 CommandArgumentArray& cmd_args, uint& src_data_pos,
105 const unsigned int last_pos);
106
107void CheckIncByte(const uint8_t* rom_data, DataSizeArray& data_size_taken,
108 CommandArgumentArray& cmd_args, uint& src_data_pos,
109 const unsigned int last_pos);
110
111void CheckIntraCopy(const uint8_t* rom_data, DataSizeArray& data_size_taken,
112 CommandArgumentArray& cmd_args, uint& src_data_pos,
113 const unsigned int last_pos, unsigned int start);
114
115void ValidateForByteGain(const DataSizeArray& data_size_taken,
116 const CommandSizeArray& cmd_size, uint& max_win,
117 uint& cmd_with_max);
118
119void CompressionCommandAlternative(const uint8_t* rom_data,
120 CompressionPiecePointer& compressed_chain,
121 const CommandSizeArray& cmd_size,
122 const CommandArgumentArray& cmd_args,
123 uint& src_data_pos, uint& comp_accumulator,
124 uint& cmd_with_max, uint& max_win);
125
126// Compression V2
127
128void CheckByteRepeatV2(const uint8_t* data, uint& src_pos,
129 const unsigned int last_pos, CompressionCommand& cmd);
130
131void CheckWordRepeatV2(const uint8_t* data, uint& src_pos,
132 const unsigned int last_pos, CompressionCommand& cmd);
133
134void CheckIncByteV2(const uint8_t* data, uint& src_pos,
135 const unsigned int last_pos, CompressionCommand& cmd);
136
137void CheckIntraCopyV2(const uint8_t* data, uint& src_pos,
138 const unsigned int last_pos, unsigned int start,
139 CompressionCommand& cmd);
140
141void ValidateForByteGainV2(const CompressionCommand& cmd, uint& max_win,
142 uint& cmd_with_max);
143
144void CompressionCommandAlternativeV2(const uint8_t* data,
145 const CompressionCommand& cmd,
146 CompressionPiecePointer& compressed_chain,
147 uint& src_pos, uint& comp_accumulator,
148 uint& cmd_with_max, uint& max_win);
149
154absl::StatusOr<std::vector<uint8_t>> CompressV2(const uint8_t* data,
155 const int start,
156 const int length, int mode = 1,
157 bool check = false);
158
159absl::StatusOr<std::vector<uint8_t>> CompressGraphics(const uint8_t* data,
160 const int pos,
161 const int length);
162absl::StatusOr<std::vector<uint8_t>> CompressOverworld(const uint8_t* data,
163 const int pos,
164 const int length);
165absl::StatusOr<std::vector<uint8_t>> CompressOverworld(
166 const std::vector<uint8_t> data, const int pos, const int length);
167
168absl::StatusOr<CompressionPiecePointer> SplitCompressionPiece(
169 CompressionPiecePointer& piece, int mode);
170
171std::vector<uint8_t> CreateCompressionString(CompressionPiecePointer& start,
172 int mode);
173
175 int mode, int start, int src_data_pos);
176
178
180 std::vector<uint8_t> data;
181 std::vector<uint8_t> compressed_data;
182 std::vector<CompressionPiece> compression_pieces;
183 std::vector<uint8_t> compression_string;
184 unsigned int src_pos;
185 unsigned int last_pos;
186 unsigned int start;
187 unsigned int comp_accumulator = 0;
189 unsigned int max_win = 0;
191 int mode;
192
193 // Constructor to initialize the context
194 CompressionContext(const std::vector<uint8_t>& data_, const int start,
195 const int length)
196 : data(data_), src_pos(start), last_pos(start + length - 1), mode(0) {}
197
198 // Constructor to initialize the context
199 CompressionContext(const std::vector<uint8_t>& data_, const int start,
200 const int length, int mode_)
201 : data(data_),
202 src_pos(start),
203 last_pos(start + length - 1),
204 mode(mode_) {}
205};
206
207void CheckByteRepeatV3(CompressionContext& context);
208void CheckWordRepeatV3(CompressionContext& context);
209void CheckIncByteV3(CompressionContext& context);
210void CheckIntraCopyV3(CompressionContext& context);
211
212void InitializeCompression(CompressionContext& context);
213void CheckAvailableCompressionCommands(CompressionContext& context);
214void DetermineBestCompression(CompressionContext& context);
215void HandleDirectCopy(CompressionContext& context);
216void AddCompressionToChain(CompressionContext& context);
217absl::Status ValidateCompressionResultV3(const CompressionContext& context);
218
219absl::StatusOr<CompressionPiece> SplitCompressionPieceV3(
220 CompressionPiece& piece, int mode);
221void FinalizeCompression(CompressionContext& context);
222
227absl::StatusOr<std::vector<uint8_t>> CompressV3(
228 const std::vector<uint8_t>& data, const int start, const int length,
229 int mode = 1, bool check = false);
230
231std::string SetBuffer(const std::vector<uint8_t>& data, int src_pos,
232 int comp_accumulator);
233std::string SetBuffer(const uint8_t* data, int src_pos, int comp_accumulator);
234void memfill(const uint8_t* data, std::vector<uint8_t>& buffer, int buffer_pos,
235 int offset, int length);
236
256absl::StatusOr<std::vector<uint8_t>> DecompressV2(const uint8_t* data,
257 int offset, int size = 0x800,
258 int mode = 1, size_t rom_size = static_cast<size_t>(-1));
259absl::StatusOr<std::vector<uint8_t>> DecompressGraphics(const uint8_t* data,
260 int pos, int size);
261absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(const uint8_t* data,
262 int pos, int size);
263absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(
264 const std::vector<uint8_t> data, int pos, int size);
265
266} // namespace lc_lz2
267} // namespace gfx
268} // namespace yaze
269
270#endif // YAZE_APP_GFX_COMPRESSION_H
unsigned int uint
Definition macro.h:4
const int D_CMD_COPY_EXISTING
Definition compression.h:39
void CheckIntraCopyV3(CompressionContext &context)
absl::StatusOr< std::vector< uint8_t > > CompressGraphics(const uint8_t *data, const int pos, const int length)
absl::StatusOr< std::vector< uint8_t > > CompressV3(const std::vector< uint8_t > &data, const int start, const int length, int mode, bool check)
Compresses a buffer of data using the LC_LZ2 algorithm.
constexpr int kExpandedLengthMod
Definition compression.h:59
const int D_CMD_COPY
Definition compression.h:35
constexpr int kCommandDirectCopy
Definition compression.h:46
void memfill(const uint8_t *data, std::vector< uint8_t > &buffer, int buffer_pos, int offset, int length)
void FinalizeCompression(CompressionContext &context)
void CheckWordRepeatV2(const uint8_t *data, uint &src_pos, const unsigned int last_pos, CompressionCommand &cmd)
void InitializeCompression(CompressionContext &context)
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uint8_t *data, int offset, int size, int mode, size_t rom_size)
Decompresses a buffer of data using the LC_LZ2 algorithm.
struct CompressionPiece CompressionPiece
Definition compression.h:90
absl::StatusOr< std::vector< uint8_t > > CompressOverworld(const uint8_t *data, const int pos, const int length)
constexpr int kSnesByteMax
Definition compression.h:56
const int D_NINTENDO_C_MODE2
Definition compression.h:33
constexpr int kNintendoMode1
Definition compression.h:54
std::shared_ptr< CompressionPiece > CompressionPiecePointer
Definition compression.h:91
void CheckIncByteV3(CompressionContext &context)
absl::Status ValidateCompressionResultV3(const CompressionContext &context)
constexpr int kNintendoMode2
Definition compression.h:55
std::string SetBuffer(const uint8_t *data, int src_pos, int comp_accumulator)
constexpr int kCommandRepeatingBytes
Definition compression.h:50
std::array< std::array< char, 2 >, 5 > CommandArgumentArray
Definition compression.h:75
const int D_MAX_LENGTH
Definition compression.h:42
void CheckByteRepeat(const uint8_t *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const unsigned int last_pos)
const int INITIAL_ALLOC_SIZE
Definition compression.h:44
void CheckByteRepeatV2(const uint8_t *data, uint &src_pos, const unsigned int last_pos, CompressionCommand &cmd)
void HandleDirectCopy(CompressionContext &context)
void CheckIncByteV2(const uint8_t *rom_data, uint &src_data_pos, const unsigned int last_pos, CompressionCommand &cmd)
absl::StatusOr< std::vector< uint8_t > > DecompressGraphics(const uint8_t *data, int pos, int size)
const int D_CMD_BYTE_INC
Definition compression.h:38
constexpr int kCommandMod
Definition compression.h:57
void PrintCompressionPiece(const CompressionPiecePointer &piece)
constexpr int kCommandWordFill
Definition compression.h:48
constexpr int kMaxLengthNormalHeader
Definition compression.h:52
void CheckAvailableCompressionCommands(CompressionContext &context)
constexpr int kMaxLengthCompression
Definition compression.h:53
const int D_MAX_NORMAL_LENGTH
Definition compression.h:41
void CompressionCommandAlternativeV2(const uint8_t *rom_data, const CompressionCommand &cmd, CompressionPiecePointer &compressed_chain, uint &src_data_pos, uint &comp_accumulator, uint &cmd_with_max, uint &max_win)
void CheckIntraCopyV2(const uint8_t *rom_data, uint &src_data_pos, const unsigned int last_pos, unsigned int start, CompressionCommand &cmd)
std::vector< uint8_t > CreateCompressionString(CompressionPiecePointer &start, int mode)
absl::StatusOr< std::vector< uint8_t > > DecompressOverworld(const uint8_t *data, int pos, int size)
std::array< uint, 5 > DataSizeArray
Definition compression.h:77
constexpr int kCommandIncreasingFill
Definition compression.h:49
void ValidateForByteGainV2(const CompressionCommand &cmd, uint &max_win, uint &cmd_with_max)
void ValidateForByteGain(const DataSizeArray &data_size_taken, const CommandSizeArray &cmd_size, uint &max_win, uint &cmd_with_max)
constexpr int kCommandByteFill
Definition compression.h:47
void PrintCompressionChain(const CompressionPiecePointer &chain_head)
void CheckIncByte(const uint8_t *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const unsigned int last_pos)
constexpr int kExpandedMod
Definition compression.h:58
void AddCompressionToChain(CompressionContext &context)
absl::StatusOr< CompressionPiecePointer > SplitCompressionPiece(CompressionPiecePointer &piece, int mode)
void CompressionCommandAlternative(const uint8_t *rom_data, CompressionPiecePointer &compressed_chain, const CommandSizeArray &cmd_size, const CommandArgumentArray &cmd_args, uint &src_data_pos, uint &comp_accumulator, uint &cmd_with_max, uint &max_win)
constexpr int kNormalLengthMod
Definition compression.h:60
constexpr int kCompressionStringMod
Definition compression.h:61
void CheckWordRepeat(const uint8_t *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const unsigned int last_pos)
constexpr int kCommandLongLength
Definition compression.h:51
void CheckByteRepeatV3(CompressionContext &context)
const int D_CMD_WORD_REPEAT
Definition compression.h:37
CompressionPiecePointer MergeCopy(CompressionPiecePointer &start)
std::array< uint, 5 > CommandSizeArray
Definition compression.h:76
void DetermineBestCompression(CompressionContext &context)
absl::StatusOr< CompressionPiece > SplitCompressionPieceV3(CompressionPiece &piece, int mode)
absl::StatusOr< std::vector< uint8_t > > CompressV2(const uint8_t *data, const int start, const int length, int mode, bool check)
Compresses a buffer of data using the LC_LZ2 algorithm.
void CheckWordRepeatV3(CompressionContext &context)
const int D_CMD_BYTE_REPEAT
Definition compression.h:36
const int D_NINTENDO_C_MODE1
Definition compression.h:32
void CheckIntraCopy(const uint8_t *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const unsigned int last_pos, unsigned int start)
absl::Status ValidateCompressionResult(CompressionPiecePointer &chain_head, int mode, int start, int src_data_pos)
std::vector< uint8_t > HyruleMagicDecompress(uint8_t const *src, int *const size, int const p_big_endian, size_t max_src_size)
std::vector< uint8_t > HyruleMagicCompress(uint8_t const *const src, int const oldsize, int *const size, int const flag)
std::array< std::array< char, 2 >, 5 > arguments
Definition compression.h:66
std::vector< CompressionPiece > compression_pieces
std::vector< uint8_t > compression_string
std::vector< uint8_t > compressed_data
CompressionContext(const std::vector< uint8_t > &data_, const int start, const int length, int mode_)
CompressionContext(const std::vector< uint8_t > &data_, const int start, const int length)
std::shared_ptr< CompressionPiece > next
Definition compression.h:85
CompressionPiece(int cmd, int len, std::string &args, int arg_len)
Definition compression.h:87