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