-
Notifications
You must be signed in to change notification settings - Fork 0
/
fill_decoder.cc
232 lines (199 loc) · 8.33 KB
/
fill_decoder.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//
// fill_decoder.cc
//
// Created by Erick Li on 05/29/19.
// Copyright © 2019 Erick Li. All rights reserved.
//
#include "fill_decoder.hh"
#include "decoder.hh"
void decodeFillPattern(char **cursor, std::string &jstring, int level, char **tail) {
int num_of_layers = 1;
try {
if (getChar(cursor) != 4) {
num_of_layers = 1;
bytesRewinder(cursor, 1);
} else {
// validate the header of the file.
int s = hexValidation(cursor, "E6147992C8D011", DO_REWIND);
if (s == 1) {
LOG("ERROR: Header cannot be decoded.");
throw std::string("Header.\n");
} else {
LOG("File is validated.");
}
// Move infile pointer 26 bytes to skip the header metadata.
bytesHopper(cursor, 25);
// decode the first color pattern. Usage so far is unknown...
decodeColorPattern(cursor, jstring, 1, "Unknown");
// decode out the number of layers...
num_of_layers = decodeLayerNumber(cursor, jstring, 1);
// Test if the number of layers behaves weird...
if (-1 == num_of_layers) {
LOG("ERROR: Number of Layers is abnormal.");
throw std::string("Number of layers.\n");
}
}
write_to_json(jstring, "fillLayer", "[", 1);
// Start decoding each layer.
for (int i = 0; i < num_of_layers; i++) {
LOG("++++ START decoding layer NO. " + std::to_string(i + 1));
write_to_json(jstring, "", "{", 2);
write_to_json(jstring, "number", std::to_string(i + 1) + ",", 3);
decodeLayer(cursor, jstring, 3, 0);
// Inter-layer pattern...
if (i < num_of_layers - 1) {
bytesRewinder(cursor, 1);
int b = 0;
do {
b = getChar(cursor);
} while (b != 3 && b != 6 && b != 8 && b != 9);
bytesRewinder(cursor, 1);
}
write_to_json(jstring, "", "},", 2);
}
write_to_json(jstring, "", "],", 1);
} catch (std::string err) {
throw err;
}
int stnl = get64Bit(cursor);
if (0x0D != stnl) {
LOG("ERROR: sentinel");
throw std::string("0x0D sentinel");
}
LOG("Checking fill layer activeness...");
// Move to the end of the file
while (*cursor != *tail) {
// printHex(cursor, 10);
*cursor += 1;
}
bytesRewinder(cursor, 5);
if (0x02 == getChar(cursor)) {
bytesRewinder(cursor, 6 * (num_of_layers - 1) + 1);
bytesRewinder(cursor, 8 * num_of_layers);
write_to_json(jstring, "fillLayerActiveness", "[", 1);
for (size_t i = 0; i < num_of_layers; i++) {
int activeness = get32Bit(cursor);
LOG("Fill layer " + std::to_string(i + 1) + ": " + std::to_string(activeness));
write_to_json(jstring, "", std::to_string(activeness) + ",", 2);
}
write_to_json(jstring, "", "],", 1);
write_to_json(jstring, "fillLayerLock", "[", 1);
for (size_t i = 0; i < num_of_layers; i++) {
int flock = get32Bit(cursor);
LOG("Fill layer lock " + std::to_string(i + 1) + ": " + std::to_string(flock));
write_to_json(jstring, "", std::to_string(flock) + ",", 2);
}
write_to_json(jstring, "", "],", 1);
} else {
LOG("WARNING: No ending pattern...we let user know.");
write_to_json(jstring, "fillLayerActiveness", "[", 1);
for (size_t i = 0; i < num_of_layers; i++) {
write_to_json(jstring, "", "2,", 2);
}
write_to_json(jstring, "", "],", 1);
write_to_json(jstring, "fillLayerLock", "[", 1);
for (size_t i = 0; i < num_of_layers; i++) {
write_to_json(jstring, "", "2,", 2);
}
write_to_json(jstring, "", "],", 1);
}
}
void decodeLayer(char **cursor, std::string &jstring, int level, int type) {
// Type 0: A normal layer
if (type == 0) {
LOG("START decoding a fill layer...");
// A Symbol
} else {
LOG("START decoding a symbol...");
}
// Get the filling type (3 for simple fill; 6 for line fill; 8 for marker fill)
int filling_type = get16Bit(cursor);
// name of the corresponding filling type.
std::string filling_type_name = "";
// For each filling type, enter into the corresponding field.
if (0xE603 == filling_type) {
decodeSimpleFill(cursor, jstring, level, type);
} else if (0xE606 == filling_type) {
decodeLineFill(cursor, jstring, level);
} else if (0xE608 == filling_type) {
decodeMarkerFill(cursor, jstring, level);
} else if (0xE609 == filling_type) {
LOG("ERROR: Gradient Fill is currently not supported");
throw std::string("Currently unsupported filling type.");
} else {
LOG("ERROR: Filling type " + std::to_string(filling_type) + " not supported");
throw std::string("Filling type.");
}
}
void decodeSimpleFill(char **cursor, std::string &jstring, int level, int type) {
LOG("Filling type: Simple Fill");
write_to_json(jstring, "fillingType", "\"Simple Fill\",", level);
try {
// Validate if the header is there.
if (0 != hexValidation(cursor, "147992C8D0118BB6080009EE4E41", !DO_REWIND)) {
LOG("ERROR: Fail to validate Simple Fill pattern header...");
throw std::string("Validation.");
}
bytesHopper(cursor, 2);
// Type of the process (0 for normal process; 1 for the symbol process)
if (type == 0) {
decodeLinePattern(cursor, jstring, 0, level, "Outline");
} else {
decodeLinePattern(cursor, jstring, 1, level, "Filling Line");
}
decodeColorPattern(cursor, jstring, level, "Filling Color");
} catch (std::string err) {
throw err;
}
}
void decodeLineFill(char **cursor, std::string &jstring, int level) {
LOG("Filling type: Line Fill");
write_to_json(jstring, "fillingType", "\"Line Fill\",", level);
try {
// Validate if the header is there.
if (0 != hexValidation(cursor, "147992C8D0118BB6080009EE4E41", !DO_REWIND)) {
LOG("ERROR: Fail to validate Line Fill pattern header...");
throw std::string("Validation.");
}
bytesHopper(cursor, 18);
// decode the line pattern for the filling lines.
decodeLinePattern(cursor, jstring, 0, level, "Filling Line");
// decode the line pattern for the outline.
decodeLinePattern(cursor, jstring, 0, level, "Outline");
} catch (std::string err) {
throw err;
}
// decode the line fill angle. (the angle of the line inclination)
decodeDouble(cursor, jstring, level, "angle");
// decode the line fill offset. (the horizontal displacement of the lines)
decodeDouble(cursor, jstring, level, "offset");
// decode the line fill separation (the distance between each line)
decodeDouble(cursor, jstring, level, "separation");
}
void decodeMarkerFill(char **cursor, std::string &jstring, int level) {
LOG("Filling type: Marker Fill");
write_to_json(jstring, "fillingType", "\"Marker Fill\",", level);
try {
// Validate if the header is there.
if (0 != hexValidation(cursor, "147992C8D0118BB6080009EE4E41", !DO_REWIND)) {
LOG("ERROR: Fail to validate Marker Fill pattern header...");
throw std::string("validation");
}
bytesHopper(cursor, 2);
// decode the marker types (Grid(uniform) or random distribution)
decodeMarkerTypes(cursor, jstring, level);
// decode the X and Y-axial offset (horizontal displacement of the markers)
decodeDouble(cursor, jstring, level, "fillPropertiesOffsetX");
decodeDouble(cursor, jstring, level, "fillPropertiesOffsetY");
// decode the X and Y-axial separation of the markers
decodeDouble(cursor, jstring, level, "fillPropertiesSeparationX");
decodeDouble(cursor, jstring, level, "fillPropertiesSeparationY");
bytesHopper(cursor, 16);
// decode the Marker in detail
decodeMarkerPattern(cursor, jstring, level);
// decode the outline.
decodeLinePattern(cursor, jstring, 0, level, "Outline");
} catch (std::string err) {
throw err;
}
}