Coverage Report

Created: 2026-08-31 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}
decode.c:decode_3dsolid
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
}
encode.c:encode_3dsolid
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 */