1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2009-2020 Free Software Foundation, Inc. */
5 /* */
6 /* This library is free software, licensed under the terms of the GNU */
7 /* General Public License as published by the Free Software Foundation, */
8 /* either version 3 of the License, or (at your option) any later version. */
9 /* You should have received a copy of the GNU General Public License */
10 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
11 /*****************************************************************************/
12
13 /*
14 * common.c: common data arrays
15 * written by Felipe Castro
16 * modified by Felipe Corrêa da Silva Sances
17 * modified by Rodrigo Rodrigues da Silva
18 * modified by Reini Urban
19 */
20
21 #include "config.h"
22 #include <stdlib.h>
23 #include "common.h"
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
27 #include "logging.h"
28
29 unsigned char *
dwg_sentinel(Dwg_Sentinel s)30 dwg_sentinel (Dwg_Sentinel s)
31 {
32 static unsigned char sentinels[9][16] = {
33 // DWG_SENTINEL_HEADER_END
34 { 0x95, 0xA0, 0x4E, 0x28, 0x99, 0x82, 0x1A, 0xE5, 0x5E, 0x41, 0xE0, 0x5F,
35 0x9D, 0x3A, 0x4D, 0x00 },
36 // DWG_SENTINEL_THUMBNAIL_BEGIN
37 { 0x1F, 0x25, 0x6D, 0x07, 0xD4, 0x36, 0x28, 0x28, 0x9D, 0x57, 0xCA, 0x3F,
38 0x9D, 0x44, 0x10, 0x2B },
39 // DWG_SENTINEL_THUMBNAIL_END
40 { 0xE0, 0xDA, 0x92, 0xF8, 0x2B, 0xc9, 0xD7, 0xD7, 0x62, 0xA8, 0x35, 0xC0,
41 0x62, 0xBB, 0xEF, 0xD4 },
42 // DWG_SENTINEL_VARIABLE_BEGIN
43 { 0xCF, 0x7B, 0x1F, 0x23, 0xFD, 0xDE, 0x38, 0xA9, 0x5F, 0x7C, 0x68, 0xB8,
44 0x4E, 0x6D, 0x33, 0x5F },
45 // DWG_SENTINEL_VARIABLE_END
46 { 0x30, 0x84, 0xE0, 0xDC, 0x02, 0x21, 0xC7, 0x56, 0xA0, 0x83, 0x97, 0x47,
47 0xB1, 0x92, 0xCC, 0xA0 },
48 // DWG_SENTINEL_CLASS_BEGIN
49 { 0x8D, 0xA1, 0xC4, 0xB8, 0xC4, 0xA9, 0xF8, 0xC5, 0xC0, 0xDC, 0xF4, 0x5F,
50 0xE7, 0xCF, 0xB6, 0x8A },
51 // DWG_SENTINEL_CLASS_END
52 { 0x72, 0x5E, 0x3B, 0x47, 0x3B, 0x56, 0x07, 0x3A, 0x3F, 0x23, 0x0B, 0xA0,
53 0x18, 0x30, 0x49, 0x75 },
54 // DWG_SENTINEL_SECOND_HEADER_BEGIN
55 { 0xD4, 0x7B, 0x21, 0xCE, 0x28, 0x93, 0x9F, 0xBF, 0x53, 0x24, 0x40, 0x09,
56 0x12, 0x3C, 0xAA, 0x01 },
57 // DWG_SENTINEL_SECOND_HEADER_END
58 { 0x2B, 0x84, 0xDE, 0x31, 0xD7, 0x6C, 0x60, 0x40, 0xAC, 0xDB, 0xBF, 0xF6,
59 0xED, 0xC3, 0x55, 0xFE },
60 };
61 return (sentinels[s]);
62 }
63
64 const char version_codes[DWG_VERSIONS][7] = {
65 "INVALI", // R_INVALID
66 "MC0.0", /* DWG Release 1.1 (as MicroCAD) */
67 "AC1.2", /* DWG Release 1.2 (as AutoCAD) */
68 "AC1.3", /* DWG Release 1.3 */
69 "AC1.40", /* DWG Release 1.4 */
70 "AC402b", /* 1.402b */
71 "AC1.50", /* DWG Release 2.0 */
72 "AC2.10", /* DWG Release 2.10*/
73 "AC2.21", /* DWG Release 2.21 */
74 "AC2.22", /* DWG Release 2.22 dwg_version: */
75 "AC1001", // DWG Release 2.4 (?) 8
76 "AC1002", // DWG Release 2.5 9
77 "AC1003", // DWG Release 2.6 10
78 "AC1004", // R_9 DWG Release 9 0x0b
79 "AC1005", // R_9 DWG Release 9c1 0x0c
80 "AC1006", // R_10 DWG Release 10 0x0d
81 "AC1007", // R_10 DWG Release 10c1 0x0e
82 "AC1008", // R_10 DWG Release 10c2 0x0f
83 "AC1009", // R_11 DWG Release 11/12 (LT R1/R2) 0x10
84 "AC1010", // R_11 DWG Release 12 (LT R1/R2) 0x11
85 "AC1011", // R_11 DWG Release 12c1 0x12
86 "AC1012", // R_13 and LT95, beware of R13c3 0x13
87 "AC1013", // R_13c3 0x14
88 "AC1014", // R_14 0x15
89 "AC1015", // R_2000 (r15) 0x17
90 "AC1018", // R_2004 0x18, 0x19, 0x1a
91 "AC1021", // R_2007 0x1b
92 "AC1024", // R_2010 0x1d
93 "AC1027", // R_2013 0x1f
94 "AC1032", // R_2018 0x21
95 "------" // R_AFTER
96 };
97
98 // keep in sync with common.h DWG_BITS
99 const char *dwg_bits_name[] = {
100 "UNKNOWN", "RC", "RS", "RL", "B", "BB", "3B", "4BITS",
101 "BS", "BL", "BLd", "RLL", "RD", "BD", "MC", "UMC",
102 "MS", "TV", "TU", "T", "TF", "T32", "HANDLE", "BE",
103 "DD", "BT", "BOT", "BLL", "TIMEBLL", "CMC", "ENC", "2RD",
104 "3RD", "2BD", "3BD", "2DD", "3DD", "CRC", "CRC64",
105 };
106
107 // minimal size of type in bits
108 // keep in sync with above
109 const unsigned char dwg_bits_size[] = {
110 0, //"UNKNOWN",
111 8, //"RC",
112 16, //"RS",
113 32, //"RL",
114 1, //"B",
115 2, //"BB",
116 3, //"3B",
117 4, //"4BITS",
118 2, //"BS", 10,18
119 2, //"BL", 10,34
120 2, //"BLd", 10,34
121 64, //"RLL",
122 64, //"RD",
123 2, //"BD", 66
124 1, //"MC", 1-4
125 1, //"UMC", 1-4
126 16, //"MS", 32
127 2, //"TV",
128 18, //"TU",
129 2, //"T",
130 1, //"TF",
131 2, //"T32",
132 4, //"TU32",
133 8, //"HANDLE",
134 1, //"BE", or 3BD
135 2, //"DD",
136 1, //"BT",
137 10, //"BOT",
138 3, //"BLL",
139 4, //"TIMEBLL", 2xBL
140 2, //"CMC", r2004+: +2
141 4, //"ENC", r2004+
142 128, //"2RD",
143 196, //"3RD",
144 4, //"2BD",
145 6, //"3BD",
146 4, //"2DD",
147 6, //"3DD",
148 8, //"CRC",
149 64, //"CRC64",
150 };
151
152 /* replace from ("[rcount1]") with to ("[%d]") in s (e.g.
153 "ref[rcount1].classname"). s is a global constant (#nam), so we cannot
154 change it in-place.
155 */
156 char *
strrplc(const char * s,const char * from,const char * to)157 strrplc (const char *s, const char *from, const char *to)
158 {
159 const char *p = strstr (s, from);
160 if (p)
161 {
162 int len = strlen (s) - (strlen (from) - strlen (to));
163 char *dest = (char *)calloc (1, 80);
164 int i = p - s;
165 assert (len < 80);
166 memcpy (dest, s, i);
167 strcat (dest, to);
168 strcat (dest, s + i + strlen (from));
169 return dest;
170 }
171 else
172 return NULL;
173 }
174
175 #if !defined(HAVE_MEMMEM) || defined(COMMON_TEST_C)
176 // naive from scratch implementation, not from glibc.
177 // see also examples/unknown.c:membits
178 void * __nonnull((1, 3))
my_memmem(const void * h0,size_t k,const void * n0,size_t l)179 my_memmem (const void *h0, size_t k, const void *n0, size_t l)
180 {
181 const unsigned char *h = h0, *n = n0;
182 unsigned char *plast;
183
184 if (!l)
185 return (void *)h; // empty needle
186 if (k < l)
187 return NULL; // needle longer than haystack
188 h = memchr (h0, *n, k);
189 if (!h || l == 1)
190 return (void *)h; // first needle char not found
191 k -= h - (const unsigned char *)h0;
192 if (k < l)
193 return NULL; // no room for needle
194
195 plast = (unsigned char*)h + (k - l);
196 do // naive 2 loops: O(n^2)
197 {
198 size_t i = 0;
199 while (h[i] == n[i])
200 {
201 if (++i == l)
202 return (void *)h;
203 }
204 }
205 while (++h <= plast);
206 return NULL;
207 }
208 #endif
209
210 /*
211 32 types, with 3 categories: Face, Edge, Display, plus 58 props r2013+
212 */
213 const char *const _dwg_VISUALSTYLE_types[32] = { "Flat",
214 "FlatWithEdges",
215 "Gouraud",
216 "GouraudWithEdges",
217 "2DWireframe",
218 "3DWireFrame",
219 "Hidden",
220 "Basic",
221 "Realistic",
222 "Conceptual",
223 "Dim",
224 "Brighten",
225 "Thicken",
226 "LinePattern",
227 "Facepattern",
228 "ColorChange",
229 "FaceOnly",
230 "EdgeOnly",
231 "DisplayOnly",
232 "JitterOff",
233 "OverhangOff",
234 "EdgeColorOff",
235 "Shades of Gray",
236 "Sketchy",
237 "X-Ray",
238 "Shaded with edges",
239 "Shaded",
240 "ByViewport",
241 "ByLayer",
242 "ByBlock",
243 "ForEmptyStyle" };
244
245 /* types of the 58 rest r2013+ properties.
246 * 1:
247 * 2:
248 * 3:
249 * 4:
250 * 5:
251 */
252 const unsigned char _dwg_VISUALSTYLE_proptypes[58] =
253 {
254 /* [0] */ 2, 2, 2, 2,
255 /* [4] */ 3, 3, 4, 2,
256 /* [8] */ 2, 4, 4, 2,
257 /* [12] */ 2, 3, 2, 4,
258 /* [16] */ 3, 2, 2, 2,
259 /* [20] */ 4, 2, 2, 2,
260 /* [24] */ 1, 2, 3, 2,
261 /* [28] */ 1, 1, 1, 1,
262 /* [32] */ 1, 1, 1, 1,
263 /* [36] */ 1, 2, 3, 3,
264 /* [40] */ 2, 4, 2, 2,
265 /* [44] */ 4, 1, 2, 2,
266 /* [48] */ 2, 1, 2, 4,
267 /* [52] */ 3, 2, 5, 1,
268 /* [56] */ 3, 3
269 };
270
271 // need to return the first ref from the handle vector.
272 BITCODE_H
shift_hv(BITCODE_H * hv,BITCODE_BL * num_p)273 shift_hv (BITCODE_H *hv, BITCODE_BL *num_p)
274 {
275 BITCODE_H ref = hv[0];
276 *num_p = *num_p - 1;
277 memmove (&hv[0], &hv[1], *num_p * sizeof (BITCODE_H));
278 return ref;
279 }
280