Skip to content

Commit 67947a5

Browse files
author
Gin
committed
add bitmap compression library
1 parent e6ef4ce commit 67947a5

File tree

3 files changed

+190
-5
lines changed

3 files changed

+190
-5
lines changed

Common/Cpp/BitmapConversion.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// Base64 Originally from René Nyffenegger's public domain base64 code
2+
// (https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp/)
3+
//
4+
// These changes were made:
5+
// 1. String input/output interface
6+
// 2. Proper padding handling
7+
// 3. Explicit character validation
8+
9+
#include <string>
10+
#include <vector>
11+
12+
static const std::string BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
13+
"abcdefghijklmnopqrstuvwxyz"
14+
"0123456789+/";
15+
16+
bool is_base64(unsigned char c) {
17+
return (isalnum(c) || (c == '+') || (c == '/'));
18+
}
19+
20+
bool base64_encode(std::string &out, const std::string &in) {
21+
int i = 0, j = 0;
22+
unsigned char char_array_3[3];
23+
unsigned char char_array_4[4];
24+
out.clear();
25+
26+
for (auto c : in) {
27+
char_array_3[i++] = c;
28+
if (i == 3) {
29+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
30+
char_array_4[1] =
31+
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
32+
char_array_4[2] =
33+
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
34+
char_array_4[3] = char_array_3[2] & 0x3f;
35+
36+
for (i = 0; i < 4; i++)
37+
out += BASE64_CHARS[char_array_4[i]];
38+
i = 0;
39+
}
40+
}
41+
42+
if (i) {
43+
for (j = i; j < 3; j++)
44+
char_array_3[j] = '\0';
45+
46+
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
47+
char_array_4[1] =
48+
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
49+
char_array_4[2] =
50+
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
51+
52+
for (j = 0; j < i + 1; j++)
53+
out += BASE64_CHARS[char_array_4[j]];
54+
55+
while (i++ < 3)
56+
out += '=';
57+
}
58+
59+
return true;
60+
}
61+
62+
bool base64_decode(std::string &out, const std::string &in) {
63+
int i = 0, j = 0;
64+
unsigned char char_array_4[4], char_array_3[3];
65+
out.clear();
66+
67+
for (auto c : in) {
68+
if (c == '=')
69+
break;
70+
71+
if (!is_base64(c))
72+
return false;
73+
74+
char_array_4[i++] = c;
75+
if (i == 4) {
76+
for (i = 0; i < 4; i++)
77+
char_array_4[i] = BASE64_CHARS.find(char_array_4[i]);
78+
79+
char_array_3[0] =
80+
(char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
81+
char_array_3[1] =
82+
((char_array_4[1] & 0x0f) << 4) + ((char_array_4[2] & 0x3c) >> 2);
83+
char_array_3[2] = ((char_array_4[2] & 0x03) << 6) + char_array_4[3];
84+
85+
for (i = 0; i < 3; i++)
86+
out += char_array_3[i];
87+
i = 0;
88+
}
89+
}
90+
91+
if (i) {
92+
for (j = i; j < 4; j++)
93+
char_array_4[j] = 0;
94+
95+
for (j = 0; j < 4; j++)
96+
char_array_4[j] = BASE64_CHARS.find(char_array_4[j]);
97+
98+
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
99+
char_array_3[1] =
100+
((char_array_4[1] & 0x0f) << 4) + ((char_array_4[2] & 0x3c) >> 2);
101+
102+
for (j = 0; j < i - 1; j++)
103+
out += char_array_3[j];
104+
}
105+
106+
return true;
107+
}
108+
109+
std::string pack_bits_to_string(const std::vector<bool> &vec) {
110+
std::string packed;
111+
if (vec.empty())
112+
return packed;
113+
114+
packed.reserve((vec.size() + 7) / 8);
115+
for (size_t i = 0; i < vec.size(); i += 8) {
116+
unsigned char byte = 0;
117+
for (size_t j = 0; j < 8 && (i + j) < vec.size(); ++j) {
118+
if (vec[i + j]) {
119+
byte |= (1 << (7 - j));
120+
}
121+
}
122+
packed.push_back(byte);
123+
}
124+
return packed;
125+
}
126+
127+
std::vector<bool> unpack_bits_from_string(const std::string &packed,
128+
size_t original_size) {
129+
std::vector<bool> vec;
130+
vec.reserve(original_size);
131+
for (size_t i = 0; i < packed.size(); ++i) {
132+
unsigned char byte = packed[i];
133+
for (int j = 7; j >= 0 && vec.size() < original_size; --j) {
134+
vec.push_back((byte >> j) & 1);
135+
}
136+
}
137+
return vec;
138+
}
139+
140+
std::string pack_bit_vector_to_base64(const std::vector<bool> &vec) {
141+
std::string packed = pack_bits_to_string(vec);
142+
std::string b64;
143+
base64_encode(b64, packed);
144+
return b64;
145+
}
146+
147+
std::vector<bool> unpack_bit_vector_from_base64(const std::string &b64,
148+
size_t original_size) {
149+
std::string packed;
150+
base64_decode(packed, b64);
151+
return unpack_bits_from_string(packed, original_size);
152+
}

Common/Cpp/BitmapConversion.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* Bitmap Conversion
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
* Functions to:
6+
* - convert vector<bool> to string and back
7+
* - convert vector<bool> to base64 string and back.
8+
*
9+
* The Base64 algorithm is originally from René Nyffenegger's public domain base64 code
10+
* (https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp/)
11+
*
12+
* These changes were made:
13+
* 1. String input/output interface
14+
* 2. Proper padding handling
15+
* 3. Explicit character validation
16+
*/
17+
18+
#ifndef PokemonAutomation_BitmapCompression_H
19+
#define PokemonAutomation_BitmapCompression_H
20+
21+
#include <vector>
22+
23+
std::string pack_bits_to_string(const std::vector<bool> &vec);
24+
25+
std::vector<bool> unpack_bits_from_string(const std::string &packed, size_t original_size);
26+
27+
std::string pack_bit_vector_to_base64(const std::vector<bool> &vec);
28+
29+
std::vector<bool> unpack_bit_vector_from_base64(const std::string &b64, size_t original_size);
30+
31+
#endif

SerialPrograms/CMakeLists.txt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ file(GLOB MAIN_SOURCES
6363
../Common/CRC32.h
6464
../Common/Compiler.h
6565
../Common/Cpp/AbstractLogger.h
66+
../Common/Cpp/BitmapConversion.cpp
67+
../Common/Cpp/BitmapConversion.h
6668
../Common/Cpp/CancellableScope.cpp
6769
../Common/Cpp/CancellableScope.h
6870
../Common/Cpp/Color.cpp
@@ -188,13 +190,13 @@ file(GLOB MAIN_SOURCES
188190
../Common/Cpp/Rectangle.tpp
189191
../Common/Cpp/RecursiveThrottler.h
190192
../Common/Cpp/SIMDDebuggers.h
191-
../Common/Cpp/Stopwatch.h
192193
../Common/Cpp/Sockets/AbstractClientSocket.h
193194
../Common/Cpp/Sockets/ClientSocket.cpp
194195
../Common/Cpp/Sockets/ClientSocket.h
195196
../Common/Cpp/Sockets/ClientSocket_POSIX.h
196197
../Common/Cpp/Sockets/ClientSocket_Qt.h
197198
../Common/Cpp/Sockets/ClientSocket_WinSocket.h
199+
../Common/Cpp/Stopwatch.h
198200
../Common/Cpp/StreamConverters.cpp
199201
../Common/Cpp/StreamConverters.h
200202
../Common/Cpp/StringTools.cpp
@@ -968,6 +970,8 @@ file(GLOB MAIN_SOURCES
968970
Source/NintendoSwitch/Framework/UI/NintendoSwitch_SingleSwitchProgramWidget.h
969971
Source/NintendoSwitch/Framework/UI/NintendoSwitch_SwitchSystemWidget.cpp
970972
Source/NintendoSwitch/Framework/UI/NintendoSwitch_SwitchSystemWidget.h
973+
Source/NintendoSwitch/Inference/NintendoSwitch2_BinarySliderDetector.cpp
974+
Source/NintendoSwitch/Inference/NintendoSwitch2_BinarySliderDetector.h
971975
Source/NintendoSwitch/Inference/NintendoSwitch_ConsoleTypeDetector.cpp
972976
Source/NintendoSwitch/Inference/NintendoSwitch_ConsoleTypeDetector.h
973977
Source/NintendoSwitch/Inference/NintendoSwitch_DateChangeDetector.cpp
@@ -982,8 +986,6 @@ file(GLOB MAIN_SOURCES
982986
Source/NintendoSwitch/Inference/NintendoSwitch_StartGameUserSelectDetector.h
983987
Source/NintendoSwitch/Inference/NintendoSwitch_UpdatePopupDetector.cpp
984988
Source/NintendoSwitch/Inference/NintendoSwitch_UpdatePopupDetector.h
985-
Source/NintendoSwitch/Inference/NintendoSwitch2_BinarySliderDetector.cpp
986-
Source/NintendoSwitch/Inference/NintendoSwitch2_BinarySliderDetector.h
987989
Source/NintendoSwitch/NintendoSwitch_ConsoleHandle.cpp
988990
Source/NintendoSwitch/NintendoSwitch_ConsoleHandle.h
989991
Source/NintendoSwitch/NintendoSwitch_ConsoleState.cpp
@@ -1017,6 +1019,8 @@ file(GLOB MAIN_SOURCES
10171019
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_24h.h
10181020
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.cpp
10191021
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.h
1022+
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch1_HomeToDateTime.cpp
1023+
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch2_HomeToDateTime.cpp
10201024
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_HomeToDateTime.cpp
10211025
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_HomeToDateTime.h
10221026
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_NeutralDateSkip.cpp
@@ -1025,8 +1029,6 @@ file(GLOB MAIN_SOURCES
10251029
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_RollDateBackwardN.h
10261030
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_RollDateForward1.cpp
10271031
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_RollDateForward1.h
1028-
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch1_HomeToDateTime.cpp
1029-
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch2_HomeToDateTime.cpp
10301032
Source/NintendoSwitch/Programs/FastCodeEntry/NintendoSwitch_CodeEntryTools.cpp
10311033
Source/NintendoSwitch/Programs/FastCodeEntry/NintendoSwitch_CodeEntryTools.h
10321034
Source/NintendoSwitch/Programs/FastCodeEntry/NintendoSwitch_KeyboardCodeEntry.cpp

0 commit comments

Comments
 (0)