/src/libredwg/src/dwg_spec_shared.h
Line | Count | Source |
1 | | /* -*- c -*- */ |
2 | | /*****************************************************************************/ |
3 | | /* LibreDWG - free implementation of the DWG file format */ |
4 | | /* */ |
5 | | /* Copyright (C) 2009-2010,2018-2026 Free Software Foundation, Inc. */ |
6 | | /* */ |
7 | | /* This library is free software, licensed under the terms of the GNU */ |
8 | | /* General Public License as published by the Free Software Foundation, */ |
9 | | /* either version 3 of the License, or (at your option) any later version. */ |
10 | | /* You should have received a copy of the GNU General Public License */ |
11 | | /* along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
12 | | /*****************************************************************************/ |
13 | | |
14 | | /* |
15 | | * dwg_spec_shaed.h: Shared macros and helper functions used by both dwg.spec |
16 | | and dwg2.spec |
17 | | * written by Reini Urban |
18 | | * Extracted from dwg.spec during the spec split. |
19 | | */ |
20 | | #ifndef DWG_SPEC_SHARED_H |
21 | | #define DWG_SPEC_SHARED_H |
22 | | |
23 | | /** |
24 | | * DIMENSION_common declaration |
25 | | */ |
26 | | // clang-format off |
27 | | #define COMMON_ENTITY_DIMENSION \ |
28 | 38.3k | SUBCLASS (AcDbDimension) \ |
29 | 348k | SINCE (R_2010b) \ |
30 | 62.4k | { \ |
31 | 3.80k | FIELD_RC (class_version, 280); /* 0=r2010 */ \ |
32 | 3.80k | VALUEOUTOFBOUNDS (class_version, 10) \ |
33 | 0 | } \ |
34 | 348k | PRE (R_13b1) \ |
35 | 348k | { \ |
36 | 176k | FIELD_HANDLE (block, 2, 2); \ |
37 | 176k | if (dat->version >= R_10) { \ |
38 | 104k | FIELD_3RD (def_pt, 10); \ |
39 | 72.6k | } else { /* ANG2LN */ \ |
40 | 72.6k | FIELD_2RD (def_pt, 10); \ |
41 | 30.7k | } \ |
42 | 176k | FIELD_2RD (text_midpt, 11); \ |
43 | 165k | if (R11OPTS (1)) \ |
44 | 150k | FIELD_2RD (clone_ins_pt, 12); \ |
45 | 162k | if (R11OPTS (2)) \ |
46 | 162k | FIELD_RC (flag, 70); \ |
47 | 162k | if (R11OPTS (4)) \ |
48 | 144k | FIELD_TV (user_text, 1); \ |
49 | 812 | } \ |
50 | 348k | LATER_VERSIONS \ |
51 | 348k | { \ |
52 | 171k | DXF \ |
53 | 171k | { /* converted to utf8 */ \ |
54 | 6.31k | char *blockname = dwg_dim_blockname (dwg, obj); \ |
55 | 6.31k | VALUE_TV0 (blockname, 2); \ |
56 | 6.31k | if (blockname) \ |
57 | 6.31k | free (blockname); \ |
58 | 6.31k | FIELD_3BD (def_pt, 10); \ |
59 | 0 | } \ |
60 | 171k | else { FIELD_3BD (extrusion, 210); } \ |
61 | 171k | FIELD_2RD (text_midpt, 11); \ |
62 | 168k | FIELD_BD (elevation, 31); \ |
63 | 168k | DXF { FIELD_RC0 (flag, 70); } \ |
64 | 162k | else { FIELD_RC (flag1, 0); } \ |
65 | 59.4k | } \ |
66 | 348k | DECODER \ |
67 | 136k | { \ |
68 | 129k | SINCE (R_13b1) { /* clear the upper flag bits, and fix them: */ \ |
69 | 59.4k | BITCODE_RC flag = FIELD_VALUE (flag1) & 0xe0; \ |
70 | 59.4k | /* bit 7 (non-default) is inverse of bit 0 */ \ |
71 | 59.4k | flag = (FIELD_VALUE (flag1) & 1) ? flag & 0x7F : flag | 0x80; \ |
72 | 59.4k | /* set bit 5 (use block) to bit 1. always set since r13 */ \ |
73 | 59.4k | flag = (FIELD_VALUE (flag1) & 2) ? flag | 0x20 : flag & 0xDF; \ |
74 | 59.4k | if (obj->fixedtype == DWG_TYPE_DIMENSION_ALIGNED) \ |
75 | 59.4k | flag |= 1; \ |
76 | 59.4k | else if (obj->fixedtype == DWG_TYPE_DIMENSION_ANG2LN) \ |
77 | 55.4k | flag |= 2; \ |
78 | 55.4k | else if (obj->fixedtype == DWG_TYPE_DIMENSION_DIAMETER) \ |
79 | 50.4k | flag |= 3; \ |
80 | 50.4k | else if (obj->fixedtype == DWG_TYPE_DIMENSION_RADIUS) \ |
81 | 48.6k | flag |= 4; \ |
82 | 48.6k | else if (obj->fixedtype == DWG_TYPE_DIMENSION_ANG3PT) \ |
83 | 43.1k | flag |= 5; \ |
84 | 43.1k | else if (obj->fixedtype == DWG_TYPE_ARC_DIMENSION) \ |
85 | 37.9k | flag |= 5; \ |
86 | 37.9k | else if (obj->fixedtype == DWG_TYPE_DIMENSION_ORDINATE) \ |
87 | 37.9k | flag |= 6; \ |
88 | 59.4k | FIELD_VALUE (flag) = flag; \ |
89 | 59.4k | LOG_TRACE ("flag => 0x%x [RC 70]\n", flag); \ |
90 | 59.4k | } \ |
91 | 129k | } \ |
92 | 330k | DXF \ |
93 | 136k | { \ |
94 | 7.12k | /* PRE (R_13b1) above already wrote user_text for pre-R13. avoid a \ |
95 | 7.12k | duplicate code 1 here */ \ |
96 | 7.12k | if (dat->version >= R_13b1) \ |
97 | 7.12k | { \ |
98 | 6.31k | if (dat->from_version >= R_2007) \ |
99 | 6.31k | { \ |
100 | 0 | FIELD_T (user_text, 1); \ |
101 | 0 | } \ |
102 | 6.31k | else if (_obj->user_text && strlen (_obj->user_text)) \ |
103 | 6.31k | { \ |
104 | 1.08k | FIELD_TV (user_text, 1); \ |
105 | 1.08k | } \ |
106 | 6.31k | } \ |
107 | 7.12k | } \ |
108 | 136k | else \ |
109 | 323k | { \ |
110 | 323k | SINCE (R_13b1) \ |
111 | 323k | { \ |
112 | 162k | FIELD_T (user_text, 1); \ |
113 | 162k | FIELD_BD0 (text_rotation, 53); \ |
114 | 161k | FIELD_BD0 (horiz_dir, 51); \ |
115 | 161k | FIELD_3BD_1 (ins_scale, 0); \ |
116 | 161k | FIELD_BD0 (ins_rotation, 54); \ |
117 | 58.6k | } \ |
118 | 323k | } \ |
119 | 329k | SINCE (R_2000b) \ |
120 | 128k | { \ |
121 | 91.0k | FIELD_BS (attachment, 71); \ |
122 | 91.0k | FIELD_BS1 (lspace_style, 72); \ |
123 | 90.8k | FIELD_BD1 (lspace_factor, 41); \ |
124 | 90.8k | FIELD_BD (act_measurement, 42); \ |
125 | 31.1k | } \ |
126 | 329k | SINCE (R_2007a) \ |
127 | 135k | { \ |
128 | 3.80k | FIELD_B (unknown, 73); /* always 0 */ \ |
129 | 3.80k | FIELD_B (flip_arrow1, 74); \ |
130 | 3.80k | FIELD_B (flip_arrow2, 75); \ |
131 | 0 | } \ |
132 | 329k | SINCE (R_13b1) { \ |
133 | 167k | FIELD_2RD0 (clone_ins_pt, 12); \ |
134 | 55.3k | } \ |
135 | 326k | DXF \ |
136 | 124k | { \ |
137 | 7.12k | FIELD_BD0 (ins_rotation, 54); \ |
138 | 7.12k | FIELD_BD0 (horiz_dir, 51); \ |
139 | 7.12k | FIELD_BE (extrusion, 210); \ |
140 | 7.12k | FIELD_BD0 (text_rotation, 53); \ |
141 | 7.12k | FIELD_HANDLE0 (dimstyle, 5, 3); \ |
142 | 0 | } \ |
143 | 326k | JSON { FIELD_RC (flag, 0); } |
144 | | // clang-format on |
145 | | |
146 | | // 37, 38 and 39 are ACIS entities |
147 | | #define WIRESTRUCT_fields(name) \ |
148 | 1.92M | SUB_FIELD_RC (name, type, 0); \ |
149 | 1.92M | SUB_FIELD_BLd (name, selection_marker, 0); \ |
150 | 1.92M | FIELD_CAST (name.color, BS, BL, 0); \ |
151 | 1.92M | SUB_FIELD_BLd (name, acis_index, 0); /* TODO: align num_points to 255 */ \ |
152 | 1.92M | SUB_FIELD_BL (name, num_points, 0); \ |
153 | 1.92M | FIELD_3DPOINT_VECTOR (name.points, name.num_points, 0); \ |
154 | 1.92M | SUB_FIELD_B (name, transform_present, 0); \ |
155 | 1.92M | if (FIELD_VALUE (name.transform_present)) \ |
156 | 135k | { \ |
157 | 135k | SUB_FIELD_3BD (name, axis_x, 0); \ |
158 | 134k | SUB_FIELD_3BD (name, axis_y, 0); \ |
159 | 134k | SUB_FIELD_3BD (name, axis_z, 0); \ |
160 | 134k | SUB_FIELD_3BD (name, translation, 0); \ |
161 | 133k | SUB_FIELD_3BD (name, scale, 0); \ |
162 | 133k | SUB_FIELD_B (name, has_rotation, 0); \ |
163 | 133k | SUB_FIELD_B (name, has_reflection, 0); \ |
164 | 133k | SUB_FIELD_B (name, has_shear, 0); \ |
165 | 233 | } |
166 | | |
167 | | #if defined(IS_DECODER) |
168 | | |
169 | | # define DECODE_3DSOLID \ |
170 | 21.5k | decode_3dsolid (dat, hdl_dat, obj, (Dwg_Entity_3DSOLID *)_obj); \ |
171 | 21.5k | if (FIELD_VALUE (encr_sat_data) && !FIELD_VALUE (encr_sat_data[0])) \ |
172 | 21.5k | FIELD_VALUE (block_size[0]) = 0; |
173 | | |
174 | | static int |
175 | | decode_3dsolid (Bit_Chain *dat, Bit_Chain *hdl_dat, Dwg_Object *restrict obj, |
176 | | Dwg_Entity_3DSOLID *restrict _obj) |
177 | 21.5k | { |
178 | 21.5k | Dwg_Data *dwg = obj->parent; |
179 | 21.5k | BITCODE_BL j; |
180 | 21.5k | BITCODE_BL vcount; |
181 | 21.5k | BITCODE_BL i = 0; |
182 | 21.5k | BITCODE_BL total_size = 0; |
183 | 21.5k | BITCODE_BL num_blocks = 0; |
184 | 21.5k | int acis_data_idx; |
185 | 21.5k | int error = 0; |
186 | | |
187 | 21.5k | FIELD_B (acis_empty, 290); |
188 | 21.5k | if (dat->byte >= dat->size) |
189 | 1.42k | return DWG_ERR_VALUEOUTOFBOUNDS; |
190 | 20.0k | if (!FIELD_VALUE (acis_empty)) |
191 | 15.2k | { |
192 | 15.2k | FIELD_B (unknown, 0); |
193 | 15.2k | IF_ENCODE_FROM_EARLIER { FIELD_VALUE (version) = 1; } |
194 | 15.2k | FIELD_BS (version, 70); |
195 | | // which is SAT format ACIS 4.0 (since r2000+) |
196 | 15.2k | if (FIELD_VALUE (version) == 1) |
197 | 316 | { |
198 | 316 | do |
199 | 580 | { |
200 | 580 | FIELD_VALUE (encr_sat_data) = (char **)realloc ( |
201 | 580 | FIELD_VALUE (encr_sat_data), (i + 1) * sizeof (char *)); |
202 | 580 | FIELD_VALUE (block_size) = (BITCODE_BL *)realloc ( |
203 | 580 | FIELD_VALUE (block_size), (i + 1) * sizeof (BITCODE_BL)); |
204 | 580 | if (!FIELD_VALUE (encr_sat_data) || !FIELD_VALUE (block_size)) |
205 | 0 | return DWG_ERR_OUTOFMEM; |
206 | 580 | FIELD_BL (block_size[i], 0); |
207 | 580 | if (FIELD_VALUE (block_size[i]) > 0 |
208 | 528 | && FIELD_VALUE (block_size[i]) < MAX_SIZE_TF |
209 | 356 | && AVAIL_BITS (dat) |
210 | 356 | > (int64_t)FIELD_VALUE (block_size[i]) * 8) |
211 | 264 | { |
212 | 264 | BITCODE_BL len = FIELD_VALUE (block_size[i]); |
213 | 528 | FIELD_TFv (encr_sat_data[i], len, 1); |
214 | 528 | if (!FIELD_VALUE (encr_sat_data) |
215 | 264 | || !FIELD_VALUE (encr_sat_data[i])) |
216 | 0 | FIELD_VALUE (block_size[i]) = 0; |
217 | 528 | FIELD_VALUE (encr_sat_data[i][len]) = 0; |
218 | 528 | total_size += FIELD_VALUE (block_size[i]); |
219 | 528 | } |
220 | 316 | else |
221 | 316 | { |
222 | 316 | FIELD_VALUE (encr_sat_data[i]) = (char *)calloc (1, 1); |
223 | 316 | FIELD_VALUE (block_size[i]) = 0; |
224 | 316 | } |
225 | 580 | } |
226 | 580 | while (FIELD_VALUE (block_size[i++]) > 0 |
227 | 264 | && AVAIL_BITS (dat) >= 16); // crc RS |
228 | 316 | if (!FIELD_VALUE (encr_sat_data) || !FIELD_VALUE (block_size)) |
229 | 0 | { |
230 | 0 | free (FIELD_VALUE (block_size)); |
231 | 0 | free (FIELD_VALUE (encr_sat_data)); |
232 | 0 | return DWG_ERR_VALUEOUTOFBOUNDS; |
233 | 0 | } |
234 | | |
235 | | // de-obfuscate SAT data |
236 | 316 | FIELD_VALUE (acis_data) = (BITCODE_RC *)malloc (total_size + 1); |
237 | 316 | num_blocks = i - 1; |
238 | 316 | FIELD_VALUE (num_blocks) = num_blocks; |
239 | 316 | LOG_TRACE ("num_blocks: " FORMAT_BL "\n", FIELD_VALUE (num_blocks)); |
240 | 316 | acis_data_idx = 0; |
241 | 580 | for (i = 0; i < num_blocks; i++) |
242 | 264 | { |
243 | 17.8k | for (j = 0; j < FIELD_VALUE (block_size[i]); j++) |
244 | 17.5k | { |
245 | 17.5k | if ((BITCODE_RC)FIELD_VALUE (encr_sat_data[i][j]) <= 32) |
246 | 8.46k | { |
247 | 8.46k | FIELD_VALUE (acis_data) |
248 | 8.46k | [acis_data_idx++] |
249 | 8.46k | = (BITCODE_RC)FIELD_VALUE (encr_sat_data[i][j]); |
250 | 8.46k | } |
251 | 9.07k | else |
252 | 9.07k | { |
253 | 9.07k | FIELD_VALUE (acis_data) |
254 | 9.07k | [acis_data_idx++] |
255 | 9.07k | = 159 |
256 | 9.07k | - (BITCODE_RC)FIELD_VALUE (encr_sat_data[i][j]); |
257 | 9.07k | } |
258 | 17.5k | } |
259 | 264 | } |
260 | 316 | FIELD_VALUE (acis_data)[acis_data_idx] = '\0'; |
261 | | // DXF 1 + 3 if >255 |
262 | 316 | LOG_TRACE ("acis_data:\n%s\n", FIELD_VALUE (acis_data)); |
263 | 316 | } |
264 | 14.9k | else if (FIELD_VALUE (version) == 2) |
265 | | /* version 2, SAB: binary, unencrypted SAT format for |
266 | | ACIS 7.0/ShapeManager. ACIS versions: R14 release 106 |
267 | | (ACIS 1.6) R15 (2000) release 400 (ACIS 4.0) R18 (2004) |
268 | | release 20800 (ASM ShapeManager, forked from ACIS 7.0) R21 |
269 | | (2007) release 21200 R24 (2010) release 21500 R27 (2013) |
270 | | release 21800 R?? (2018) release 223.0.1.1930 |
271 | | */ |
272 | 45 | { |
273 | 45 | FIELD_VALUE (block_size) |
274 | 45 | = (BITCODE_BL *)calloc (2, sizeof (BITCODE_BL)); |
275 | 45 | FIELD_VALUE (encr_sat_data) = NULL; |
276 | | // TODO string in strhdl, even <r2007 |
277 | | // either has_ds_data (r2013+) or the blob is here |
278 | 45 | if (!obj->tio.entity->has_ds_data && dat->size > dat->byte + 1) |
279 | 45 | { |
280 | 45 | char *p; |
281 | | // Note that r2013+ has End-of-ASM-data (not ACIS anymore, but |
282 | | // their fork) |
283 | 45 | const char end[] = "\016\003End\016\002of\016\004ACIS\r\004data"; |
284 | 45 | const char end1[] = "\016\003End\016\002of\016\003ASM\r\004data"; |
285 | 45 | size_t pos = dat->byte; |
286 | 45 | size_t size = dat->size - pos - 1; |
287 | 45 | FIELD_VALUE (acis_data) = (unsigned char *)calloc (size, 1); |
288 | | // Binary SAB. unencrypted, documented format until |
289 | | // "End-of-ACIS-data" |
290 | | // TODO There exist also SAB streams with a given number of |
291 | | // records, but I haven't seen them here. See |
292 | | // dwg_convert_SAB_to_SAT1 Better read the first header line |
293 | | // here, to check for num_records 0. Or even parse the whole SAB |
294 | | // format here, and store the SAB different to the ASCII |
295 | | // acis_data. |
296 | 45 | FIELD_TFF (acis_data, size, 1); // SAB "ACIS BinaryFile" |
297 | 45 | LOG_TRACE ("Unknown ACIS 2 SAB sab_size %" PRIuSIZE |
298 | 45 | " starting at %" PRIuSIZE "\n", |
299 | 45 | size, pos); |
300 | 45 | if ((p = (char *)memmem (_obj->acis_data, size, end, |
301 | 45 | strlen (end)))) |
302 | 0 | { |
303 | 0 | size = p - (char *)_obj->acis_data; |
304 | 0 | size += strlen (end); |
305 | 0 | dat->byte = pos + size; |
306 | 0 | _obj->sab_size = size & 0xFFFFFFFF; |
307 | 0 | LOG_TRACE ("Found End-of-ACIS-data. sab_size: %" PRIuSIZE |
308 | 0 | ", new pos: %" PRIuSIZE "\n", |
309 | 0 | size, dat->byte); |
310 | 0 | } |
311 | 45 | else if ((p = (char *)memmem (_obj->acis_data, size, end1, |
312 | 45 | strlen (end1)))) |
313 | 0 | { |
314 | 0 | size = p - (char *)_obj->acis_data; |
315 | 0 | size += strlen (end1); |
316 | 0 | dat->byte = pos + size; |
317 | 0 | _obj->sab_size = size & 0xFFFFFFFF; |
318 | 0 | LOG_TRACE ("Found End-of-ASM-data. sab_size: %" PRIuSIZE |
319 | 0 | ", new pos: %" PRIuSIZE "\n", |
320 | 0 | size, dat->byte); |
321 | 0 | } |
322 | 45 | else |
323 | 45 | LOG_TRACE ("No End-of-ACIS or ASM data marker found\n"); |
324 | 45 | _obj->block_size[0] = _obj->sab_size = size & 0xFFFFFFFF; |
325 | 45 | } |
326 | 0 | else |
327 | 0 | LOG_WARN ("SAB from AcDs blob not yet implemented"); |
328 | | // total_size = FIELD_VALUE (_obj->block_size[0]); |
329 | 45 | } |
330 | 15.2k | } |
331 | 20.0k | return error; |
332 | 20.0k | } Line | Count | Source | 177 | 21.5k | { | 178 | 21.5k | Dwg_Data *dwg = obj->parent; | 179 | 21.5k | BITCODE_BL j; | 180 | 21.5k | BITCODE_BL vcount; | 181 | 21.5k | BITCODE_BL i = 0; | 182 | 21.5k | BITCODE_BL total_size = 0; | 183 | 21.5k | BITCODE_BL num_blocks = 0; | 184 | 21.5k | int acis_data_idx; | 185 | 21.5k | int error = 0; | 186 | | | 187 | 21.5k | FIELD_B (acis_empty, 290); | 188 | 21.5k | if (dat->byte >= dat->size) | 189 | 1.42k | return DWG_ERR_VALUEOUTOFBOUNDS; | 190 | 20.0k | if (!FIELD_VALUE (acis_empty)) | 191 | 15.2k | { | 192 | 15.2k | FIELD_B (unknown, 0); | 193 | 15.2k | IF_ENCODE_FROM_EARLIER { FIELD_VALUE (version) = 1; } | 194 | 15.2k | FIELD_BS (version, 70); | 195 | | // which is SAT format ACIS 4.0 (since r2000+) | 196 | 15.2k | if (FIELD_VALUE (version) == 1) | 197 | 316 | { | 198 | 316 | do | 199 | 580 | { | 200 | 580 | FIELD_VALUE (encr_sat_data) = (char **)realloc ( | 201 | 580 | FIELD_VALUE (encr_sat_data), (i + 1) * sizeof (char *)); | 202 | 580 | FIELD_VALUE (block_size) = (BITCODE_BL *)realloc ( | 203 | 580 | FIELD_VALUE (block_size), (i + 1) * sizeof (BITCODE_BL)); | 204 | 580 | if (!FIELD_VALUE (encr_sat_data) || !FIELD_VALUE (block_size)) | 205 | 0 | return DWG_ERR_OUTOFMEM; | 206 | 580 | FIELD_BL (block_size[i], 0); | 207 | 580 | if (FIELD_VALUE (block_size[i]) > 0 | 208 | 528 | && FIELD_VALUE (block_size[i]) < MAX_SIZE_TF | 209 | 356 | && AVAIL_BITS (dat) | 210 | 356 | > (int64_t)FIELD_VALUE (block_size[i]) * 8) | 211 | 264 | { | 212 | 264 | BITCODE_BL len = FIELD_VALUE (block_size[i]); | 213 | 528 | FIELD_TFv (encr_sat_data[i], len, 1); | 214 | 528 | if (!FIELD_VALUE (encr_sat_data) | 215 | 264 | || !FIELD_VALUE (encr_sat_data[i])) | 216 | 0 | FIELD_VALUE (block_size[i]) = 0; | 217 | 528 | FIELD_VALUE (encr_sat_data[i][len]) = 0; | 218 | 528 | total_size += FIELD_VALUE (block_size[i]); | 219 | 528 | } | 220 | 316 | else | 221 | 316 | { | 222 | 316 | FIELD_VALUE (encr_sat_data[i]) = (char *)calloc (1, 1); | 223 | 316 | FIELD_VALUE (block_size[i]) = 0; | 224 | 316 | } | 225 | 580 | } | 226 | 580 | while (FIELD_VALUE (block_size[i++]) > 0 | 227 | 264 | && AVAIL_BITS (dat) >= 16); // crc RS | 228 | 316 | if (!FIELD_VALUE (encr_sat_data) || !FIELD_VALUE (block_size)) | 229 | 0 | { | 230 | 0 | free (FIELD_VALUE (block_size)); | 231 | 0 | free (FIELD_VALUE (encr_sat_data)); | 232 | 0 | return DWG_ERR_VALUEOUTOFBOUNDS; | 233 | 0 | } | 234 | | | 235 | | // de-obfuscate SAT data | 236 | 316 | FIELD_VALUE (acis_data) = (BITCODE_RC *)malloc (total_size + 1); | 237 | 316 | num_blocks = i - 1; | 238 | 316 | FIELD_VALUE (num_blocks) = num_blocks; | 239 | 316 | LOG_TRACE ("num_blocks: " FORMAT_BL "\n", FIELD_VALUE (num_blocks)); | 240 | 316 | acis_data_idx = 0; | 241 | 580 | for (i = 0; i < num_blocks; i++) | 242 | 264 | { | 243 | 17.8k | for (j = 0; j < FIELD_VALUE (block_size[i]); j++) | 244 | 17.5k | { | 245 | 17.5k | if ((BITCODE_RC)FIELD_VALUE (encr_sat_data[i][j]) <= 32) | 246 | 8.46k | { | 247 | 8.46k | FIELD_VALUE (acis_data) | 248 | 8.46k | [acis_data_idx++] | 249 | 8.46k | = (BITCODE_RC)FIELD_VALUE (encr_sat_data[i][j]); | 250 | 8.46k | } | 251 | 9.07k | else | 252 | 9.07k | { | 253 | 9.07k | FIELD_VALUE (acis_data) | 254 | 9.07k | [acis_data_idx++] | 255 | 9.07k | = 159 | 256 | 9.07k | - (BITCODE_RC)FIELD_VALUE (encr_sat_data[i][j]); | 257 | 9.07k | } | 258 | 17.5k | } | 259 | 264 | } | 260 | 316 | FIELD_VALUE (acis_data)[acis_data_idx] = '\0'; | 261 | | // DXF 1 + 3 if >255 | 262 | 316 | LOG_TRACE ("acis_data:\n%s\n", FIELD_VALUE (acis_data)); | 263 | 316 | } | 264 | 14.9k | else if (FIELD_VALUE (version) == 2) | 265 | | /* version 2, SAB: binary, unencrypted SAT format for | 266 | | ACIS 7.0/ShapeManager. ACIS versions: R14 release 106 | 267 | | (ACIS 1.6) R15 (2000) release 400 (ACIS 4.0) R18 (2004) | 268 | | release 20800 (ASM ShapeManager, forked from ACIS 7.0) R21 | 269 | | (2007) release 21200 R24 (2010) release 21500 R27 (2013) | 270 | | release 21800 R?? (2018) release 223.0.1.1930 | 271 | | */ | 272 | 45 | { | 273 | 45 | FIELD_VALUE (block_size) | 274 | 45 | = (BITCODE_BL *)calloc (2, sizeof (BITCODE_BL)); | 275 | 45 | FIELD_VALUE (encr_sat_data) = NULL; | 276 | | // TODO string in strhdl, even <r2007 | 277 | | // either has_ds_data (r2013+) or the blob is here | 278 | 45 | if (!obj->tio.entity->has_ds_data && dat->size > dat->byte + 1) | 279 | 45 | { | 280 | 45 | char *p; | 281 | | // Note that r2013+ has End-of-ASM-data (not ACIS anymore, but | 282 | | // their fork) | 283 | 45 | const char end[] = "\016\003End\016\002of\016\004ACIS\r\004data"; | 284 | 45 | const char end1[] = "\016\003End\016\002of\016\003ASM\r\004data"; | 285 | 45 | size_t pos = dat->byte; | 286 | 45 | size_t size = dat->size - pos - 1; | 287 | 45 | FIELD_VALUE (acis_data) = (unsigned char *)calloc (size, 1); | 288 | | // Binary SAB. unencrypted, documented format until | 289 | | // "End-of-ACIS-data" | 290 | | // TODO There exist also SAB streams with a given number of | 291 | | // records, but I haven't seen them here. See | 292 | | // dwg_convert_SAB_to_SAT1 Better read the first header line | 293 | | // here, to check for num_records 0. Or even parse the whole SAB | 294 | | // format here, and store the SAB different to the ASCII | 295 | | // acis_data. | 296 | 45 | FIELD_TFF (acis_data, size, 1); // SAB "ACIS BinaryFile" | 297 | 45 | LOG_TRACE ("Unknown ACIS 2 SAB sab_size %" PRIuSIZE | 298 | 45 | " starting at %" PRIuSIZE "\n", | 299 | 45 | size, pos); | 300 | 45 | if ((p = (char *)memmem (_obj->acis_data, size, end, | 301 | 45 | strlen (end)))) | 302 | 0 | { | 303 | 0 | size = p - (char *)_obj->acis_data; | 304 | 0 | size += strlen (end); | 305 | 0 | dat->byte = pos + size; | 306 | 0 | _obj->sab_size = size & 0xFFFFFFFF; | 307 | 0 | LOG_TRACE ("Found End-of-ACIS-data. sab_size: %" PRIuSIZE | 308 | 0 | ", new pos: %" PRIuSIZE "\n", | 309 | 0 | size, dat->byte); | 310 | 0 | } | 311 | 45 | else if ((p = (char *)memmem (_obj->acis_data, size, end1, | 312 | 45 | strlen (end1)))) | 313 | 0 | { | 314 | 0 | size = p - (char *)_obj->acis_data; | 315 | 0 | size += strlen (end1); | 316 | 0 | dat->byte = pos + size; | 317 | 0 | _obj->sab_size = size & 0xFFFFFFFF; | 318 | 0 | LOG_TRACE ("Found End-of-ASM-data. sab_size: %" PRIuSIZE | 319 | 0 | ", new pos: %" PRIuSIZE "\n", | 320 | 0 | size, dat->byte); | 321 | 0 | } | 322 | 45 | else | 323 | 45 | LOG_TRACE ("No End-of-ACIS or ASM data marker found\n"); | 324 | 45 | _obj->block_size[0] = _obj->sab_size = size & 0xFFFFFFFF; | 325 | 45 | } | 326 | 0 | else | 327 | 0 | LOG_WARN ("SAB from AcDs blob not yet implemented"); | 328 | | // total_size = FIELD_VALUE (_obj->block_size[0]); | 329 | 45 | } | 330 | 15.2k | } | 331 | 20.0k | return error; | 332 | 20.0k | } |
Unexecuted instantiation: decode2.c:decode_3dsolid |
333 | | #else |
334 | 0 | # define DECODE_3DSOLID {} |
335 | | # define FREE_3DSOLID {} |
336 | | #endif // #if IS_DECODER |
337 | | |
338 | | #ifdef IS_ENCODER |
339 | | # define ENCODE_3DSOLID \ |
340 | 3.78k | encode_3dsolid (dat, hdl_dat, obj, (Dwg_Entity_3DSOLID *)_obj); |
341 | | static int |
342 | | encode_3dsolid (Bit_Chain *dat, Bit_Chain *hdl_dat, Dwg_Object *restrict obj, |
343 | | Dwg_Entity_3DSOLID *restrict _obj) |
344 | 3.78k | { |
345 | 3.78k | Dwg_Data *dwg = obj->parent; |
346 | 3.78k | BITCODE_BL i = 0; |
347 | 3.78k | BITCODE_BL num_blocks = FIELD_VALUE (num_blocks); |
348 | 3.78k | int acis_data_idx = 0; |
349 | 3.78k | int error = 0; |
350 | | |
351 | 3.78k | FIELD_B (acis_empty, 290); |
352 | 3.78k | if (!FIELD_VALUE (acis_empty)) |
353 | 3.04k | { |
354 | 3.04k | FIELD_B (unknown, 0); |
355 | 3.04k | FIELD_BS (version, 70); |
356 | | // which is SAT format ACIS 4.0 (since r2000+) |
357 | 3.04k | if (FIELD_VALUE (version) == 1) |
358 | 114 | { |
359 | | // from decode and indxf we already have all fields. |
360 | | // from other importers we have acis_data, but maybe not |
361 | | // encr_sat_data. |
362 | 114 | if (!FIELD_VALUE (block_size)) |
363 | 0 | { |
364 | 0 | if (!FIELD_VALUE (acis_data)) |
365 | 0 | { |
366 | 0 | VALUE_RL (0, 0); |
367 | 0 | return error; |
368 | 0 | } |
369 | | // Later split into 4096 byte sized blocks |
370 | 0 | FIELD_VALUE (block_size) |
371 | 0 | = (BITCODE_BL *)calloc (2, sizeof (BITCODE_BL)); |
372 | 0 | FIELD_VALUE (block_size[0]) |
373 | 0 | = strlen ((char *)FIELD_VALUE (acis_data)) & 0xFFFFFFFF; |
374 | 0 | FIELD_VALUE (block_size[1]) = 0; |
375 | 0 | LOG_TRACE ("default block_size[0] = %d\n", |
376 | 0 | (int)FIELD_VALUE (block_size[0])); |
377 | 0 | num_blocks = 1; |
378 | 0 | } |
379 | | /* insecure. e.g. oss-fuzz issue 32165 |
380 | | all inputs: dwg, injson and indxf have correct num_blocks values |
381 | | else if (!num_blocks) |
382 | | { |
383 | | num_blocks = 0; |
384 | | for (i = 0; FIELD_VALUE (block_size[i]); i++) |
385 | | num_blocks++; |
386 | | } |
387 | | */ |
388 | 114 | LOG_TRACE ("acis_data:\n%s\n", FIELD_VALUE (acis_data)); |
389 | 215 | for (i = 0; FIELD_VALUE (block_size[i]) && i < num_blocks; i++) |
390 | 101 | { |
391 | 101 | if (!FIELD_VALUE (encr_sat_data[i])) |
392 | 0 | { |
393 | 0 | if (!FIELD_VALUE (acis_data)) |
394 | 0 | { |
395 | 0 | VALUE_RL (0, 0); |
396 | 0 | return error; |
397 | 0 | } |
398 | | // global acis_data_idx is needed for the global acis_data |
399 | 0 | FIELD_VALUE (encr_sat_data[i]) = dwg_encrypt_SAT1 ( |
400 | 0 | FIELD_VALUE (block_size[i]), FIELD_VALUE (acis_data), |
401 | 0 | &acis_data_idx); |
402 | 0 | LOG_TRACE ("dwg_encrypt_SAT1 %d\n", i); |
403 | 0 | } |
404 | 101 | FIELD_BL (block_size[i], 0); |
405 | 101 | FIELD_TF (encr_sat_data[i], FIELD_VALUE (block_size[i]), 1); |
406 | 101 | } |
407 | | /* |
408 | | if (num_blocks > FIELD_VALUE (num_blocks)) |
409 | | { |
410 | | FIELD_VALUE (block_size) = (BITCODE_BL*)realloc (FIELD_VALUE |
411 | | (block_size), (num_blocks + 1) * sizeof (BITCODE_BL)); FIELD_VALUE |
412 | | (num_blocks) = num_blocks; |
413 | | } |
414 | | */ |
415 | 114 | FIELD_BL (block_size[num_blocks], 0); |
416 | 114 | } |
417 | 2.93k | else // if (FIELD_VALUE (version)==2) |
418 | 2.93k | { |
419 | 2.93k | if (_obj->acis_data && _obj->sab_size) |
420 | 5 | { |
421 | 5 | LOG_TRACE ("acis_data [TF %u 1]:\n%.*s\n", |
422 | 5 | (unsigned)FIELD_VALUE (sab_size), 15, |
423 | 5 | FIELD_VALUE (acis_data)); |
424 | | // Binary SAB, unencrypted |
425 | 5 | if (obj->tio.entity->has_ds_data) |
426 | 0 | { |
427 | 0 | LOG_WARN ("Disable SAB from AcDs blob"); // TODO AcDs support |
428 | 0 | obj->tio.entity->has_ds_data = 0; |
429 | 0 | } |
430 | 5 | bit_write_TF (dat, _obj->acis_data, _obj->sab_size); |
431 | 5 | LOG_TRACE_TF (&_obj->acis_data[15], (int)(_obj->sab_size - 15)); |
432 | 5 | } |
433 | 2.93k | } |
434 | 3.04k | } |
435 | 3.78k | return error; |
436 | 3.78k | } Line | Count | Source | 344 | 3.78k | { | 345 | 3.78k | Dwg_Data *dwg = obj->parent; | 346 | 3.78k | BITCODE_BL i = 0; | 347 | 3.78k | BITCODE_BL num_blocks = FIELD_VALUE (num_blocks); | 348 | 3.78k | int acis_data_idx = 0; | 349 | 3.78k | int error = 0; | 350 | | | 351 | 3.78k | FIELD_B (acis_empty, 290); | 352 | 3.78k | if (!FIELD_VALUE (acis_empty)) | 353 | 3.04k | { | 354 | 3.04k | FIELD_B (unknown, 0); | 355 | 3.04k | FIELD_BS (version, 70); | 356 | | // which is SAT format ACIS 4.0 (since r2000+) | 357 | 3.04k | if (FIELD_VALUE (version) == 1) | 358 | 114 | { | 359 | | // from decode and indxf we already have all fields. | 360 | | // from other importers we have acis_data, but maybe not | 361 | | // encr_sat_data. | 362 | 114 | if (!FIELD_VALUE (block_size)) | 363 | 0 | { | 364 | 0 | if (!FIELD_VALUE (acis_data)) | 365 | 0 | { | 366 | 0 | VALUE_RL (0, 0); | 367 | 0 | return error; | 368 | 0 | } | 369 | | // Later split into 4096 byte sized blocks | 370 | 0 | FIELD_VALUE (block_size) | 371 | 0 | = (BITCODE_BL *)calloc (2, sizeof (BITCODE_BL)); | 372 | 0 | FIELD_VALUE (block_size[0]) | 373 | 0 | = strlen ((char *)FIELD_VALUE (acis_data)) & 0xFFFFFFFF; | 374 | 0 | FIELD_VALUE (block_size[1]) = 0; | 375 | 0 | LOG_TRACE ("default block_size[0] = %d\n", | 376 | 0 | (int)FIELD_VALUE (block_size[0])); | 377 | 0 | num_blocks = 1; | 378 | 0 | } | 379 | | /* insecure. e.g. oss-fuzz issue 32165 | 380 | | all inputs: dwg, injson and indxf have correct num_blocks values | 381 | | else if (!num_blocks) | 382 | | { | 383 | | num_blocks = 0; | 384 | | for (i = 0; FIELD_VALUE (block_size[i]); i++) | 385 | | num_blocks++; | 386 | | } | 387 | | */ | 388 | 114 | LOG_TRACE ("acis_data:\n%s\n", FIELD_VALUE (acis_data)); | 389 | 215 | for (i = 0; FIELD_VALUE (block_size[i]) && i < num_blocks; i++) | 390 | 101 | { | 391 | 101 | if (!FIELD_VALUE (encr_sat_data[i])) | 392 | 0 | { | 393 | 0 | if (!FIELD_VALUE (acis_data)) | 394 | 0 | { | 395 | 0 | VALUE_RL (0, 0); | 396 | 0 | return error; | 397 | 0 | } | 398 | | // global acis_data_idx is needed for the global acis_data | 399 | 0 | FIELD_VALUE (encr_sat_data[i]) = dwg_encrypt_SAT1 ( | 400 | 0 | FIELD_VALUE (block_size[i]), FIELD_VALUE (acis_data), | 401 | 0 | &acis_data_idx); | 402 | 0 | LOG_TRACE ("dwg_encrypt_SAT1 %d\n", i); | 403 | 0 | } | 404 | 101 | FIELD_BL (block_size[i], 0); | 405 | 101 | FIELD_TF (encr_sat_data[i], FIELD_VALUE (block_size[i]), 1); | 406 | 101 | } | 407 | | /* | 408 | | if (num_blocks > FIELD_VALUE (num_blocks)) | 409 | | { | 410 | | FIELD_VALUE (block_size) = (BITCODE_BL*)realloc (FIELD_VALUE | 411 | | (block_size), (num_blocks + 1) * sizeof (BITCODE_BL)); FIELD_VALUE | 412 | | (num_blocks) = num_blocks; | 413 | | } | 414 | | */ | 415 | 114 | FIELD_BL (block_size[num_blocks], 0); | 416 | 114 | } | 417 | 2.93k | else // if (FIELD_VALUE (version)==2) | 418 | 2.93k | { | 419 | 2.93k | if (_obj->acis_data && _obj->sab_size) | 420 | 5 | { | 421 | 5 | LOG_TRACE ("acis_data [TF %u 1]:\n%.*s\n", | 422 | 5 | (unsigned)FIELD_VALUE (sab_size), 15, | 423 | 5 | FIELD_VALUE (acis_data)); | 424 | | // Binary SAB, unencrypted | 425 | 5 | if (obj->tio.entity->has_ds_data) | 426 | 0 | { | 427 | 0 | LOG_WARN ("Disable SAB from AcDs blob"); // TODO AcDs support | 428 | 0 | obj->tio.entity->has_ds_data = 0; | 429 | 0 | } | 430 | 5 | bit_write_TF (dat, _obj->acis_data, _obj->sab_size); | 431 | 5 | LOG_TRACE_TF (&_obj->acis_data[15], (int)(_obj->sab_size - 15)); | 432 | 5 | } | 433 | 2.93k | } | 434 | 3.04k | } | 435 | 3.78k | return error; | 436 | 3.78k | } |
Unexecuted instantiation: encode2.c:encode_3dsolid |
437 | | #else |
438 | 0 | # define ENCODE_3DSOLID {} |
439 | | # define FREE_3DSOLID {} |
440 | | #endif // #if IS_ENCODER |
441 | | |
442 | | #ifdef IS_FREE |
443 | | # undef FREE_3DSOLID |
444 | 21.9k | # define FREE_3DSOLID {} free_3dsolid (obj, (Dwg_Entity_3DSOLID *)_obj); |
445 | | static int |
446 | | free_3dsolid (Dwg_Object *restrict obj, Dwg_Entity_3DSOLID *restrict _obj) |
447 | 21.9k | { |
448 | 21.9k | int error = 0; |
449 | 21.9k | Bit_Chain *dat = &pdat; |
450 | | |
451 | 21.9k | if (!FIELD_VALUE (acis_empty)) |
452 | 17.0k | { |
453 | 17.0k | if (FIELD_VALUE (encr_sat_data)) |
454 | 316 | { |
455 | 316 | LOG_HANDLE ("Free %s.num_blocks %u\n", obj->name, _obj->num_blocks); |
456 | 896 | for (BITCODE_BL i = 0; i <= FIELD_VALUE (num_blocks); i++) |
457 | 580 | { |
458 | 580 | if (FIELD_VALUE (encr_sat_data[i]) != NULL) |
459 | 580 | FIELD_TF (encr_sat_data[i], block_size[i], 0); |
460 | 580 | } |
461 | 316 | } |
462 | 17.0k | FREE_IF (FIELD_VALUE (encr_sat_data)); |
463 | 17.0k | FREE_IF (FIELD_VALUE (block_size)); |
464 | 17.0k | } |
465 | 21.9k | FREE_IF (FIELD_VALUE (acis_data)); |
466 | 21.9k | return error; |
467 | 21.9k | } |
468 | | #else |
469 | 36.8k | # define FREE_3DSOLID {} |
470 | | #endif |
471 | | |
472 | | #define COMMON_3DSOLID \ |
473 | 58.7k | FIELD_B (wireframe_data_present, 0); \ |
474 | 58.7k | if (FIELD_VALUE (wireframe_data_present)) \ |
475 | 36.3k | { \ |
476 | 36.3k | FIELD_B (point_present, 0); \ |
477 | 36.3k | if (FIELD_VALUE (point_present)) \ |
478 | 15.0k | { \ |
479 | 15.0k | FIELD_3BD (point, 0); \ |
480 | 5.42k | } \ |
481 | 299 | else \ |
482 | 21.3k | { \ |
483 | 21.3k | FIELD_VALUE (point.x) = 0; \ |
484 | 21.3k | FIELD_VALUE (point.y) = 0; \ |
485 | 21.3k | FIELD_VALUE (point.z) = 0; \ |
486 | 21.3k | } \ |
487 | 36.2k | FIELD_BL (isolines, 0); \ |
488 | 36.2k | FIELD_B (isoline_present, 0); \ |
489 | 36.2k | if (FIELD_VALUE (isoline_present)) \ |
490 | 29.1k | { \ |
491 | 29.1k | FIELD_BL (num_wires, 0); \ |
492 | 316k | REPEAT (num_wires, wires, Dwg_3DSOLID_wire) \ |
493 | 1.06M | REPEAT_BLOCK \ |
494 | 1.06M | WIRESTRUCT_fields (wires[rcount1]) \ |
495 | 315k | SET_PARENT (wires[rcount1], (Dwg_Entity__3DSOLID *)_obj); \ |
496 | 1.05M | END_REPEAT_BLOCK \ |
497 | 309k | END_REPEAT (wires); \ |
498 | 24.8k | FIELD_BL (num_silhouettes, 0); \ |
499 | 228k | REPEAT (num_silhouettes, silhouettes, Dwg_3DSOLID_silhouette) \ |
500 | 639k | REPEAT_BLOCK \ |
501 | 639k | SUB_FIELD_BL (silhouettes[rcount1], vp_id, 0); \ |
502 | 639k | SUB_FIELD_3BD (silhouettes[rcount1], vp_target, 0); /* ?? */ \ |
503 | 639k | SUB_FIELD_3BD (silhouettes[rcount1], vp_dir_from_target, 0); \ |
504 | 639k | SUB_FIELD_3BD (silhouettes[rcount1], vp_up_dir, 0); \ |
505 | 639k | SUB_FIELD_B (silhouettes[rcount1], vp_perspective, 0); \ |
506 | 639k | SUB_FIELD_B (silhouettes[rcount1], has_wires, 0); \ |
507 | 639k | if (_obj->silhouettes[rcount1].has_wires) \ |
508 | 22.0k | { \ |
509 | 22.0k | SUB_FIELD_BL (silhouettes[rcount1], num_wires, 0); \ |
510 | 295k | REPEAT2 (silhouettes[rcount1].num_wires, \ |
511 | 1.96k | silhouettes[rcount1].wires, Dwg_3DSOLID_wire) \ |
512 | 862k | REPEAT_BLOCK \ |
513 | 862k | WIRESTRUCT_fields (silhouettes[rcount1].wires[rcount2]) \ |
514 | 217k | SET_PARENT (silhouettes[rcount1].wires[rcount2], \ |
515 | 172k | (Dwg_Entity__3DSOLID *)_obj); \ |
516 | 861k | END_REPEAT_BLOCK \ |
517 | 294k | END_REPEAT (silhouettes[rcount1].wires); \ |
518 | 7.77k | } \ |
519 | 316k | SET_PARENT (silhouettes[rcount1], (Dwg_Entity__3DSOLID *)_obj); \ |
520 | 637k | END_REPEAT_BLOCK \ |
521 | 232k | END_REPEAT (silhouettes); \ |
522 | 4.41k | } \ |
523 | 299 | } \ |
524 | 50.4k | FIELD_B (acis_empty_bit, 0); /* ?? */ \ |
525 | 50.4k | if (FIELD_VALUE (version) > 1) \ |
526 | 26.2k | { \ |
527 | 26.2k | SINCE (R_2007a) \ |
528 | 26.2k | { \ |
529 | 1.15k | FIELD_BL (num_materials, 0); \ |
530 | 0 | REPEAT (num_materials, materials, Dwg_3DSOLID_material) \ |
531 | 0 | REPEAT_BLOCK \ |
532 | 0 | SUB_FIELD_BL (materials[rcount1], array_index, 0); \ |
533 | 0 | SUB_FIELD_BL (materials[rcount1], mat_absref, 0); /* ?? */ \ |
534 | 0 | SUB_FIELD_HANDLE (materials[rcount1], material_handle, 5, 0); \ |
535 | 0 | SET_PARENT (materials[rcount1], (Dwg_Entity__3DSOLID *)_obj); \ |
536 | 0 | END_REPEAT_BLOCK \ |
537 | 11 | END_REPEAT (materials); \ |
538 | 0 | } \ |
539 | 26.2k | } \ |
540 | 50.4k | SINCE (R_2013b) \ |
541 | 40.2k | { \ |
542 | 988 | FIELD_B (has_revision_guid, 0); \ |
543 | 988 | DXF { \ |
544 | 0 | if (!_obj->revision_guid[0]) \ |
545 | 0 | { \ |
546 | 0 | VALUE_TFF ("{00000000-0000-0000-0000-000000000000}", 2) \ |
547 | 0 | LOG_WARN ("empty revision_guid"); \ |
548 | 0 | } \ |
549 | 0 | else \ |
550 | 0 | { \ |
551 | 0 | FIELD_TFF (revision_guid, 38, 2); \ |
552 | 0 | } \ |
553 | 0 | } \ |
554 | 0 | else \ |
555 | 988 | { \ |
556 | 988 | FIELD_BL (revision_major, 0); \ |
557 | 988 | FIELD_BS (revision_minor1, 0); \ |
558 | 988 | FIELD_BS (revision_minor2, 0); \ |
559 | 988 | FIELD_TFFx (revision_bytes, 8, 0); \ |
560 | 988 | DECODER { dxf_3dsolid_revisionguid ((Dwg_Entity_3DSOLID *)_obj); } \ |
561 | 0 | } \ |
562 | 988 | FIELD_BL (end_marker, 0); \ |
563 | 0 | } \ |
564 | 50.4k | DXF { \ |
565 | 1.41k | SINCE (R_2007a) { \ |
566 | 0 | SUBCLASS (AcDb3dSolid); \ |
567 | 0 | FIELD_HANDLE (history_id, 4, 350); \ |
568 | 0 | } \ |
569 | 49.0k | } else if (FIELD_VALUE (version) > 1 \ |
570 | 49.0k | && (!IF_IS_DECODER || AVAIL_BITS (hdl_dat) >= 8)) { \ |
571 | 25.7k | FIELD_HANDLE (history_id, 4, 350); \ |
572 | 25.7k | } \ |
573 | 50.4k | FREE { FIELD_HANDLE (history_id, 4, 350); } |
574 | | |
575 | | #define ACTION_3DSOLID \ |
576 | 21.5k | SUBCLASS (AcDbModelerGeometry); \ |
577 | 58.7k | DXF_OR_PRINT { \ |
578 | 11.5k | DXF_3DSOLID \ |
579 | 11.5k | } \ |
580 | 58.7k | DECODER { \ |
581 | 21.5k | DECODE_3DSOLID \ |
582 | 21.5k | } \ |
583 | 58.7k | ENCODER { \ |
584 | 3.78k | ENCODE_3DSOLID \ |
585 | 3.78k | } \ |
586 | 58.7k | JSON { \ |
587 | 10.1k | JSON_3DSOLID \ |
588 | 10.1k | } \ |
589 | 58.7k | FREE_3DSOLID \ |
590 | 59.0k | COMMON_3DSOLID |
591 | | |
592 | | #define TABLE_value_fields(value) \ |
593 | 295 | PRE (R_2007a) { FIELD_VALUE (value.data_type) &= ~0x200; } \ |
594 | 295 | LATER_VERSIONS { FIELD_BL (value.format_flags, 93); } \ |
595 | 295 | FIELD_BL (value.data_type, 90); \ |
596 | 295 | if (!(dat->version >= R_2007 && (FIELD_VALUE (value.format_flags) & 3))) \ |
597 | 295 | { \ |
598 | 295 | switch (FIELD_VALUE (value.data_type)) \ |
599 | 295 | { \ |
600 | 295 | case 0: /* kUnknown */ \ |
601 | 295 | FIELD_BL (value.data_long, 91); \ |
602 | 0 | break; \ |
603 | 0 | case 1: /* kLong */ \ |
604 | 0 | FIELD_BL (value.data_long, 91); \ |
605 | 0 | break; \ |
606 | 0 | case 2: /* kDouble */ \ |
607 | 0 | FIELD_BD (value.data_double, 140); \ |
608 | 0 | break; \ |
609 | 0 | case 4: /* kString */ \ |
610 | 0 | FIELD_T (value.data_string, 1); /* and 2. TODO multiple lines */ \ |
611 | 0 | break; \ |
612 | 0 | case 8: /* kDate */ \ |
613 | 0 | FIELD_BL (value.data_size, 92); \ |
614 | 0 | FIELD_BINARY (value.data_date, FIELD_VALUE (value.data_size), 310); \ |
615 | 0 | break; \ |
616 | 0 | case 16: /* kPoint */ \ |
617 | 0 | FIELD_BL (value.data_size, 92); \ |
618 | 0 | FIELD_2RD (value.data_point, 11); \ |
619 | 0 | break; \ |
620 | 0 | case 32: /* k3dPoint */ \ |
621 | 0 | FIELD_BL (value.data_size, 92); \ |
622 | 0 | FIELD_3RD (value.data_3dpoint, 11); \ |
623 | 0 | break; \ |
624 | 0 | case 64: /* kObjectId */ \ |
625 | 0 | FIELD_HANDLE (value.data_handle, -1, 330); \ |
626 | 0 | break; \ |
627 | 0 | case 128: /* kBuffer */ \ |
628 | 0 | LOG_ERROR ("Unknown data type in TABLE_value_fields: kBuffer"); \ |
629 | 0 | break; \ |
630 | 0 | case 256: /* kResBuf */ \ |
631 | 0 | LOG_ERROR ("Unknown data type in TABLE_value_fields: kResBuf"); \ |
632 | 0 | break; \ |
633 | 0 | case 512: /* kGeneral since r2007*/ \ |
634 | 0 | SINCE (R_2007a) { FIELD_BL (value.data_size, 0); } \ |
635 | 0 | else \ |
636 | 0 | LOG_ERROR ("Unknown data type in TABLE_value_fields: kGeneral <r2007"); \ |
637 | 0 | break; \ |
638 | 0 | default: \ |
639 | 0 | LOG_ERROR ("Invalid data type in TABLE_value_fields"); \ |
640 | 0 | DEBUG_HERE_OBJ \ |
641 | 0 | FIELD_VALUE (value.format_flags) = 0; \ |
642 | 0 | FIELD_VALUE (value.data_type) = 0; \ |
643 | 0 | error |= DWG_ERR_INVALIDTYPE; \ |
644 | 0 | break; /*return DWG_ERR_INVALIDTYPE; */ \ |
645 | 295 | } \ |
646 | 295 | } \ |
647 | 295 | SINCE (R_2007a) \ |
648 | 295 | { \ |
649 | 0 | FIELD_BL (value.unit_type, 94); \ |
650 | 0 | FIELD_T (value.format_string, 300); \ |
651 | 0 | if (FIELD_VALUE (value.unit_type) != 12) \ |
652 | 0 | FIELD_T (value.value_string, 302); \ |
653 | 0 | } |
654 | | |
655 | | #ifdef IS_JSON |
656 | 118 | # define JSON_END_REPEAT(f) ENDHASH; ENDARRAY; |
657 | | #else |
658 | 256 | # define JSON_END_REPEAT(f) END_REPEAT (f) |
659 | | #endif |
660 | | |
661 | | // R2010+ Subclass of ATTRIB, ATTDEF, GEOPOSITIONMARKER. |
662 | | // Similar to MTEXTOBJECTCONTEXTDATA? |
663 | | // TODO: this really should use dwg_##action##_entity + |
664 | | // dwg_##action##_MTEXT_private |
665 | | // clang-format off |
666 | | #define AcDbMTextObjectEmbedded_fields \ |
667 | 0 | SUB_FIELD_BB (mtext, entmode, 0); \ |
668 | 0 | SUB_FIELD_BL (mtext, num_reactors, 0); \ |
669 | 0 | SUB_FIELD_B (mtext, is_xdic_missing, 0); \ |
670 | 0 | SUB_FIELD_B (mtext, has_ds_data, 0); \ |
671 | 0 | SUB_FIELD_BSx (mtext, color.raw, 0); \ |
672 | 0 | SUB_FIELD_BD (mtext, ltype_scale, 48); \ |
673 | 0 | SUB_FIELD_BB (mtext, ltype_flags, 0); \ |
674 | 0 | SUB_FIELD_BB (mtext, plotstyle_flags, 0); \ |
675 | 0 | SUB_FIELD_BB (mtext, material_flags, 0); \ |
676 | 0 | SUB_FIELD_RC (mtext, shadow_flags, 0); \ |
677 | 0 | SUB_FIELD_B (mtext, has_full_visualstyle, 0); \ |
678 | 0 | SUB_FIELD_B (mtext, has_face_visualstyle, 0); \ |
679 | 0 | SUB_FIELD_B (mtext, has_edge_visualstyle, 0); \ |
680 | 0 | SUB_FIELD_BS (mtext, invisible, 60); \ |
681 | 0 | SUB_FIELD_RC (mtext, linewt, 370); \ |
682 | 0 | SUB_FIELD_HANDLE (mtext, layer, 5, 8); \ |
683 | 0 | \ |
684 | 0 | DXF { VALUE_TFF ("Embedded Object", 101); } \ |
685 | 0 | SUB_FIELD_3BD (mtext, ins_pt, 10); \ |
686 | 0 | SUB_FIELD_3BD (mtext, extrusion, 210); \ |
687 | 0 | SUB_FIELD_3BD (mtext, x_axis_dir, 11); \ |
688 | 0 | DXF { \ |
689 | 0 | SUB_FIELD_BD (mtext, text_height, 40); \ |
690 | 0 | SUB_FIELD_BD (mtext, rect_width, 40); \ |
691 | 0 | SUB_FIELD_BD (mtext, rect_height, 41); \ |
692 | 0 | } else { \ |
693 | 0 | SUB_FIELD_BD (mtext, rect_width, 40); \ |
694 | 0 | SUB_FIELD_BD (mtext, rect_height, 41); \ |
695 | 0 | SUB_FIELD_BD (mtext, text_height, 40); \ |
696 | 0 | } \ |
697 | 0 | SUB_FIELD_BS (mtext, attachment, 71); \ |
698 | 0 | SUB_FIELD_BS (mtext, flow_dir, 72); \ |
699 | 0 | SUB_FIELD_BD (mtext, extents_width, 42); \ |
700 | 0 | SUB_FIELD_BD (mtext, extents_height, 43); \ |
701 | 0 | SUB_FIELD_T (mtext, text, 1); \ |
702 | 0 | SUB_FIELD_HANDLE0 (mtext, style, 5, 7); \ |
703 | 0 | SUB_FIELD_BS (mtext, linespace_style, 73); \ |
704 | 0 | SUB_FIELD_BD (mtext, linespace_factor, 44); \ |
705 | 0 | SUB_FIELD_B (mtext, unknown_b0, 0); \ |
706 | 0 | SUB_FIELD_BL0 (mtext, bg_fill_flag, 90); \ |
707 | 0 | if (SUB_FIELD_VALUE (mtext, bg_fill_flag) & \ |
708 | 0 | (dat->version <= R_2018 ? 1 : 16)) \ |
709 | 0 | { \ |
710 | 0 | SUB_FIELD_BL (mtext, bg_fill_scale, 45); \ |
711 | 0 | SUB_FIELD_CMC (mtext, bg_fill_color, 63); \ |
712 | 0 | SUB_FIELD_BL (mtext, bg_fill_trans, 441); \ |
713 | 0 | } \ |
714 | 0 | SUB_FIELD_B (mtext, is_not_annotative, 0); \ |
715 | 0 | /* What about the duplicate MTEXT AnnotScaleObject \ |
716 | 0 | fields here? */ \ |
717 | 0 | FIELD_B (is_really_locked, 0); \ |
718 | 0 | DXF \ |
719 | 0 | { \ |
720 | 0 | SUB_FIELD_BL (mtext, column_type, 71); \ |
721 | 0 | SUB_VALUEOUTOFBOUNDS (mtext, column_type, 2) \ |
722 | 0 | if (SUB_FIELD_VALUE (mtext, column_type)) \ |
723 | 0 | { \ |
724 | 0 | SUB_FIELD_BL (mtext, num_column_heights, 72); \ |
725 | 0 | SUB_FIELD_BD (mtext, column_width, 44); \ |
726 | 0 | SUB_FIELD_BD (mtext, gutter, 45); \ |
727 | 0 | SUB_FIELD_B (mtext, auto_height, 73); \ |
728 | 0 | SUB_FIELD_B (mtext, flow_reversed, 74); \ |
729 | 0 | if (!SUB_FIELD_VALUE (mtext, auto_height) \ |
730 | 0 | && SUB_FIELD_VALUE (mtext, column_type) == 2) \ |
731 | 0 | { \ |
732 | 0 | SUB_FIELD_VECTOR (mtext, column_heights, BD, \ |
733 | 0 | num_column_heights, 46); \ |
734 | 0 | } \ |
735 | 0 | } \ |
736 | 0 | } \ |
737 | 0 | else \ |
738 | 0 | { \ |
739 | 0 | FIELD_BS (annotative_data_size, 70); \ |
740 | 0 | if (FIELD_VALUE (annotative_data_size) > 0) \ |
741 | 0 | { \ |
742 | 0 | FIELD_BINARY(annotative_data, \ |
743 | 0 | FIELD_VALUE (annotative_data_size), 310); \ |
744 | 0 | } \ |
745 | 0 | } |
746 | | |
747 | | // FIXME |
748 | | #if 0 |
749 | | SUB_FIELD_BL (mtext, column_type, 71); \ |
750 | | SUB_VALUEOUTOFBOUNDS (mtext, column_type, 2) \ |
751 | | if (SUB_FIELD_VALUE (mtext, column_type)) \ |
752 | | { \ |
753 | | SUB_FIELD_BL (mtext, num_column_heights, 72); \ |
754 | | SUB_FIELD_BD (mtext, column_width, 44); \ |
755 | | SUB_FIELD_BD (mtext, gutter, 45); \ |
756 | | SUB_FIELD_B (mtext, auto_height, 73); \ |
757 | | SUB_FIELD_B (mtext, flow_reversed, 74); \ |
758 | | if (!SUB_FIELD_VALUE (mtext, auto_height) && \ |
759 | | SUB_FIELD_VALUE (mtext, column_type) == 2) \ |
760 | | { \ |
761 | | SUB_FIELD_VECTOR (mtext, column_heights, BD, \ |
762 | | num_column_heights, 46); \ |
763 | | } \ |
764 | | } \ |
765 | | FIELD_BS (annotative_flag, 0); |
766 | | #endif |
767 | | |
768 | | // clang-format on |
769 | | #endif /* DWG_SPEC_SHARED_H */ |