yaze 0.2.0
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 <iostream>
5#include <memory>
6#include <string>
7
8#include "absl/status/status.h"
9#include "absl/status/statusor.h"
10#include "app/core/constants.h"
11
12#define BUILD_HEADER(command, length) (command << 5) + (length - 1)
13
14namespace yaze {
15namespace app {
16namespace gfx {
17
22namespace lc_lz2 {
23
24const int D_NINTENDO_C_MODE1 = 0;
25const int D_NINTENDO_C_MODE2 = 1;
26
27const int D_CMD_COPY = 0;
28const int D_CMD_BYTE_REPEAT = 1;
29const int D_CMD_WORD_REPEAT = 2;
30const int D_CMD_BYTE_INC = 3;
31const int D_CMD_COPY_EXISTING = 4;
32
33const int D_MAX_NORMAL_LENGTH = 32;
34const int D_MAX_LENGTH = 1024;
35
36const int INITIAL_ALLOC_SIZE = 1024;
37
38constexpr int kCommandDirectCopy = 0;
39constexpr int kCommandByteFill = 1;
40constexpr int kCommandWordFill = 2;
41constexpr int kCommandIncreasingFill = 3;
42constexpr int kCommandRepeatingBytes = 4;
43constexpr int kCommandLongLength = 7;
44constexpr int kMaxLengthNormalHeader = 32;
45constexpr int kMaxLengthCompression = 1024;
46constexpr int kNintendoMode1 = 0;
47constexpr int kNintendoMode2 = 1;
48constexpr int kSnesByteMax = 0xFF;
49constexpr int kCommandMod = 0x07;
50constexpr int kExpandedMod = 0xE0;
51constexpr int kExpandedLengthMod = 0x3FF;
52constexpr int kNormalLengthMod = 0x1F;
53constexpr int kCompressionStringMod = 7 << 5;
54
55// Represents a command in the compression algorithm.
57 // The command arguments for each possible command.
58 std::array<std::array<char, 2>, 5> arguments;
59
60 // The size of each possible command.
61 std::array<uint, 5> cmd_size;
62
63 // The size of the data processed by each possible command.
64 std::array<uint, 5> data_size;
65};
66
67using CommandArgumentArray = std::array<std::array<char, 2>, 5>;
68using CommandSizeArray = std::array<uint, 5>;
69using DataSizeArray = std::array<uint, 5>;
70
71// Represents a piece of compressed data.
73 char command;
74 int length;
76 std::string argument;
77 std::shared_ptr<CompressionPiece> next = nullptr;
78 CompressionPiece() = default;
79 CompressionPiece(int cmd, int len, std::string args, int arg_len)
80 : command(cmd), length(len), argument_length(arg_len), argument(args) {}
81};
83using CompressionPiecePointer = std::shared_ptr<CompressionPiece>;
84
86
88
89// Compression V1
90
91void CheckByteRepeat(const uchar* rom_data, DataSizeArray& data_size_taken,
92 CommandArgumentArray& cmd_args, uint& src_data_pos,
93 const uint last_pos);
94
95void CheckWordRepeat(const uchar* rom_data, DataSizeArray& data_size_taken,
96 CommandArgumentArray& cmd_args, uint& src_data_pos,
97 const uint last_pos);
98
99void CheckIncByte(const uchar* rom_data, DataSizeArray& data_size_taken,
100 CommandArgumentArray& cmd_args, uint& src_data_pos,
101 const uint last_pos);
102
103void CheckIntraCopy(const uchar* rom_data, DataSizeArray& data_size_taken,
104 CommandArgumentArray& cmd_args, uint& src_data_pos,
105 const uint last_pos, uint start);
106
107void ValidateForByteGain(const DataSizeArray& data_size_taken,
108 const CommandSizeArray& cmd_size, uint& max_win,
109 uint& cmd_with_max);
110
111void CompressionCommandAlternative(const uchar* rom_data,
112 CompressionPiecePointer& compressed_chain,
113 const CommandSizeArray& cmd_size,
114 const CommandArgumentArray& cmd_args,
115 uint& src_data_pos, uint& comp_accumulator,
116 uint& cmd_with_max, uint& max_win);
117
118// Compression V2
119
120void CheckByteRepeatV2(const uchar* data, uint& src_pos, const uint last_pos,
121 CompressionCommand& cmd);
122
123void CheckWordRepeatV2(const uchar* data, uint& src_pos, const uint last_pos,
124 CompressionCommand& cmd);
125
126void CheckIncByteV2(const uchar* data, uint& src_pos, const uint last_pos,
127 CompressionCommand& cmd);
128
129void CheckIntraCopyV2(const uchar* data, uint& src_pos, const uint last_pos,
130 uint start, CompressionCommand& cmd);
131
132void ValidateForByteGainV2(const CompressionCommand& cmd, uint& max_win,
133 uint& cmd_with_max);
134
136 const CompressionCommand& cmd,
137 CompressionPiecePointer& compressed_chain,
138 uint& src_pos, uint& comp_accumulator,
139 uint& cmd_with_max, uint& max_win);
140
145absl::StatusOr<std::vector<uint8_t>> CompressV2(const uchar* data, const int start,
146 const int length, int mode = 1,
147 bool check = false);
148
149absl::StatusOr<std::vector<uint8_t>> CompressGraphics(const uchar* data, const int pos,
150 const int length);
151absl::StatusOr<std::vector<uint8_t>> CompressOverworld(const uchar* data, const int pos,
152 const int length);
153absl::StatusOr<std::vector<uint8_t>> CompressOverworld(const std::vector<uint8_t> data,
154 const int pos, const int length);
155
156absl::StatusOr<CompressionPiecePointer> SplitCompressionPiece(
157 CompressionPiecePointer& piece, int mode);
158
159std::vector<uint8_t> CreateCompressionString(CompressionPiecePointer& start, int mode);
160
162 int mode, int start, int src_data_pos);
163
165
166// Compression V3
167
169 std::vector<uint8_t> data;
170 std::vector<uint8_t> compressed_data;
171 std::vector<CompressionPiece> compression_pieces;
172 std::vector<uint8_t> compression_string;
180 int mode;
181
182 // Constructor to initialize the context
183 CompressionContext(const std::vector<uint8_t>& data_, const int start,
184 const int length)
185 : data(data_), src_pos(start), last_pos(start + length - 1), mode(0) {}
186
187 // Constructor to initialize the context
188 CompressionContext(const std::vector<uint8_t>& data_, const int start,
189 const int length, int mode_)
190 : data(data_),
191 src_pos(start),
192 last_pos(start + length - 1),
193 mode(mode_) {}
194};
195
196void CheckByteRepeatV3(CompressionContext& context);
197void CheckWordRepeatV3(CompressionContext& context);
198void CheckIncByteV3(CompressionContext& context);
199void CheckIntraCopyV3(CompressionContext& context);
200
201void InitializeCompression(CompressionContext& context);
202void CheckAvailableCompressionCommands(CompressionContext& context);
203void DetermineBestCompression(CompressionContext& context);
204void HandleDirectCopy(CompressionContext& context);
205void AddCompressionToChain(CompressionContext& context);
206absl::Status ValidateCompressionResultV3(const CompressionContext& context);
207
208absl::StatusOr<CompressionPiece> SplitCompressionPieceV3(
209 CompressionPiece& piece, int mode);
210void FinalizeCompression(CompressionContext& context);
211
216absl::StatusOr<std::vector<uint8_t>> CompressV3(const std::vector<uint8_t>& data,
217 const int start, const int length,
218 int mode = 1, bool check = false);
219
220// Hyrule Magic
221uint8_t* Compress(uint8_t const* const src, int const oldsize, int* const size,
222 int const flag);
223
224uint8_t* Uncompress(uint8_t const* src, int* const size,
225 int const p_big_endian);
226
227// Decompression
228
229std::string SetBuffer(const std::vector<uint8_t>& data, int src_pos,
230 int comp_accumulator);
231std::string SetBuffer(const uchar* data, int src_pos, int comp_accumulator);
232void memfill(const uchar* data, std::vector<uint8_t>& buffer, int buffer_pos, int offset,
233 int length);
234
239absl::StatusOr<std::vector<uint8_t>> DecompressV2(const uchar* data, int offset,
240 int size = 0x800, int mode = 1);
241absl::StatusOr<std::vector<uint8_t>> DecompressGraphics(const uchar* data, int pos, int size);
242absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(const uchar* data, int pos, int size);
243absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(const std::vector<uint8_t> data,
244 int pos, int size);
245
246} // namespace lc_lz2
247
248} // namespace gfx
249} // namespace app
250} // namespace yaze
251
252#endif // YAZE_APP_GFX_COMPRESSION_H
unsigned int uint
Definition constants.h:120
unsigned char uchar
Definition constants.h:121
constexpr int kCommandMod
Definition compression.h:49
constexpr int kExpandedMod
Definition compression.h:50
void DetermineBestCompression(CompressionContext &context)
std::vector< uint8_t > CreateCompressionString(CompressionPiecePointer &start, int mode)
absl::StatusOr< std::vector< uint8_t > > CompressOverworld(const uchar *data, const int pos, const int length)
void ValidateForByteGain(const DataSizeArray &data_size_taken, const CommandSizeArray &cmd_size, uint &max_win, uint &cmd_with_max)
constexpr int kNintendoMode2
Definition compression.h:47
constexpr int kSnesByteMax
Definition compression.h:48
void CheckIntraCopyV2(const uchar *rom_data, uint &src_data_pos, const uint last_pos, uint start, CompressionCommand &cmd)
constexpr int kNormalLengthMod
Definition compression.h:52
const int D_CMD_COPY_EXISTING
Definition compression.h:31
constexpr int kCompressionStringMod
Definition compression.h:53
absl::StatusOr< std::vector< uint8_t > > DecompressGraphics(const uchar *data, int pos, int size)
void CheckIntraCopy(const uchar *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const uint last_pos, uint start)
void CheckWordRepeatV3(CompressionContext &context)
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.
void CheckIncByteV3(CompressionContext &context)
void CheckIncByteV2(const uchar *rom_data, uint &src_data_pos, const uint last_pos, CompressionCommand &cmd)
absl::StatusOr< std::vector< uint8_t > > DecompressOverworld(const uchar *data, int pos, int size)
const int D_CMD_BYTE_REPEAT
Definition compression.h:28
void AddCompressionToChain(CompressionContext &context)
void PrintCompressionPiece(const CompressionPiecePointer &piece)
void InitializeCompression(CompressionContext &context)
constexpr int kCommandDirectCopy
Definition compression.h:38
std::array< uint, 5 > CommandSizeArray
Definition compression.h:68
constexpr int kMaxLengthNormalHeader
Definition compression.h:44
void CheckIntraCopyV3(CompressionContext &context)
void CheckWordRepeat(const uchar *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const uint last_pos)
const int D_MAX_NORMAL_LENGTH
Definition compression.h:33
absl::Status ValidateCompressionResult(CompressionPiecePointer &chain_head, int mode, int start, int src_data_pos)
absl::StatusOr< std::vector< uint8_t > > CompressV2(const uchar *data, const int start, const int length, int mode, bool check)
Compresses a buffer of data using the LC_LZ2 algorithm.
void memfill(const uchar *data, std::vector< uint8_t > &buffer, int buffer_pos, int offset, int length)
CompressionPiecePointer MergeCopy(CompressionPiecePointer &start)
std::array< std::array< char, 2 >, 5 > CommandArgumentArray
Definition compression.h:67
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uchar *data, int offset, int size, int mode)
Decompresses a buffer of data using the LC_LZ2 algorithm.
void CheckByteRepeat(const uchar *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const uint last_pos)
absl::StatusOr< CompressionPiecePointer > SplitCompressionPiece(CompressionPiecePointer &piece, int mode)
void CheckWordRepeatV2(const uchar *data, uint &src_pos, const uint last_pos, CompressionCommand &cmd)
constexpr int kNintendoMode1
Definition compression.h:46
constexpr int kExpandedLengthMod
Definition compression.h:51
uint8_t * Uncompress(uint8_t const *src, int *const size, int const p_big_endian)
void CheckAvailableCompressionCommands(CompressionContext &context)
uint8_t * Compress(uint8_t const *const src, int const oldsize, int *const size, int const flag)
constexpr int kMaxLengthCompression
Definition compression.h:45
void CheckByteRepeatV2(const uchar *data, uint &src_pos, const uint last_pos, CompressionCommand &cmd)
void CompressionCommandAlternativeV2(const uchar *rom_data, const CompressionCommand &cmd, CompressionPiecePointer &compressed_chain, uint &src_data_pos, uint &comp_accumulator, uint &cmd_with_max, uint &max_win)
std::array< uint, 5 > DataSizeArray
Definition compression.h:69
absl::StatusOr< CompressionPiece > SplitCompressionPieceV3(CompressionPiece &piece, int mode)
const int D_CMD_WORD_REPEAT
Definition compression.h:29
void ValidateForByteGainV2(const CompressionCommand &cmd, uint &max_win, uint &cmd_with_max)
const int INITIAL_ALLOC_SIZE
Definition compression.h:36
void CheckIncByte(const uchar *rom_data, DataSizeArray &data_size_taken, CommandArgumentArray &cmd_args, uint &src_data_pos, const uint last_pos)
absl::StatusOr< std::vector< uint8_t > > CompressGraphics(const uchar *data, const int pos, const int length)
void HandleDirectCopy(CompressionContext &context)
const int D_NINTENDO_C_MODE1
Definition compression.h:24
std::string SetBuffer(const uchar *data, int src_pos, int comp_accumulator)
void CompressionCommandAlternative(const uchar *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)
void FinalizeCompression(CompressionContext &context)
void PrintCompressionChain(const CompressionPiecePointer &chain_head)
const int D_NINTENDO_C_MODE2
Definition compression.h:25
void CheckByteRepeatV3(CompressionContext &context)
std::shared_ptr< CompressionPiece > CompressionPiecePointer
Definition compression.h:83
struct CompressionPiece CompressionPiece
Definition compression.h:82
absl::Status ValidateCompressionResultV3(const CompressionContext &context)
Definition common.cc:21
std::array< std::array< char, 2 >, 5 > arguments
Definition compression.h:58
CompressionContext(const std::vector< uint8_t > &data_, const int start, const int length)
CompressionContext(const std::vector< uint8_t > &data_, const int start, const int length, int mode_)
std::vector< CompressionPiece > compression_pieces
CompressionPiece(int cmd, int len, std::string args, int arg_len)
Definition compression.h:79
std::shared_ptr< CompressionPiece > next
Definition compression.h:77