1 /******************************************************************************
2 **  libDXFrw - Library to read/write DXF files (ascii & binary)              **
3 **                                                                           **
4 **  Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com               **
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 2 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 #include <sstream>
14 #include "drw_dbg.h"
15 #include "dwgutil.h"
16 #include "rscodec.h"
17 #include "../libdwgr.h"
18 
19 /** utility function
20  * convert a int to string in hex
21  **/
22 namespace DRW {
toHexStr(int n)23 std::string toHexStr(int n){
24 #if defined(__APPLE__)
25     char buffer[9]= {'\0'};
26     snprintf(buffer,9, "%X", n);
27     return std::string(buffer);
28 #else
29     std::ostringstream Convert;
30     Convert << std::uppercase << std::hex << n;
31     return Convert.str();
32 #endif
33 }
34 }
35 
36 /**
37  * @brief dwgRSCodec::decode239I
38  * @param in : input data (at least 255*blk bytes)
39  * @param out : output data (at least 239*blk bytes)
40  * @param blk number of codewords ( 1 cw == 255 bytes)
41  */
decode239I(unsigned char * in,unsigned char * out,duint32 blk)42 void dwgRSCodec::decode239I(unsigned char *in, unsigned char *out, duint32 blk){
43     int k=0;
44     unsigned char data[255];
45     RScodec rsc(0x96, 8, 8); //(255, 239)
46     for (duint32 i=0; i<blk; i++){
47         k = i;
48         for (int j=0; j<255; j++) {
49             data[j] = in[k];
50             k +=blk;
51         }
52         int r = rsc.decode(data);
53         if (r<0)
54             DRW_DBG("\nWARNING: dwgRSCodec::decode239I, can't correct all errors");
55         k = i*239;
56         for (int j=0; j<239; j++) {
57             out[k++] = data[j];
58         }
59     }
60 }
61 
62 /**
63  * @brief dwgRSCodec::decode251I
64  * @param in : input data (at least 255*blk bytes)
65  * @param out : output data (at least 251*blk bytes)
66  * @param blk number of codewords ( 1 cw == 255 bytes)
67  */
decode251I(unsigned char * in,unsigned char * out,duint32 blk)68 void dwgRSCodec::decode251I(unsigned char *in, unsigned char *out, duint32 blk){
69     int k=0;
70     unsigned char data[255];
71     RScodec rsc(0xB8, 8, 2); //(255, 251)
72     for (duint32 i=0; i<blk; i++){
73         k = i;
74         for (int j=0; j<255; j++) {
75             data[j] = in[k];
76             k +=blk;
77         }
78         int r = rsc.decode(data);
79         if (r<0)
80             DRW_DBG("\nWARNING: dwgRSCodec::decode251I, can't correct all errors");
81         k = i*251;
82         for (int j=0; j<251; j++) {
83             out[k++] = data[j];
84         }
85     }
86 }
87 
twoByteOffset(duint32 * ll)88 duint32 dwgCompressor::twoByteOffset(duint32 *ll){
89     duint32 cont = 0;
90     duint8 fb = bufC[pos++];
91     cont = (fb >> 2) | (bufC[pos++] << 6);
92     *ll = (fb & 0x03);
93     return cont;
94 }
95 
longCompressionOffset()96 duint32 dwgCompressor::longCompressionOffset(){
97     duint32 cont = 0;
98     duint8 ll = bufC[pos++];
99     while (ll == 0x00){
100         cont += 0xFF;
101         ll = bufC[pos++];
102     }
103     cont += ll;
104     return cont;
105 }
106 
long20CompressionOffset()107 duint32 dwgCompressor::long20CompressionOffset(){
108 //    duint32 cont = 0;
109     duint32 cont = 0x0F;
110     duint8 ll = bufC[pos++];
111     while (ll == 0x00){
112 //        cont += 0xFF;
113         ll = bufC[pos++];
114     }
115     cont += ll;
116     return cont;
117 }
118 
litLength18()119 duint32 dwgCompressor::litLength18(){
120     duint32 cont=0;
121     duint8 ll = bufC[pos++];
122     //no literal length, this byte is next opCode
123     if (ll > 0x0F) {
124         pos--;
125         return 0;
126     }
127 
128     if (ll == 0x00) {
129         cont = 0x0F;
130         ll = bufC[pos++];
131         while (ll == 0x00){//repeat until ll != 0x00
132             cont +=0xFF;
133             ll = bufC[pos++];
134         }
135     }
136     cont +=ll;
137     cont +=3; //already sum 3
138     return cont;
139 }
140 
decompress18(duint8 * cbuf,duint8 * dbuf,duint32 csize,duint32 dsize)141 void dwgCompressor::decompress18(duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize){
142     bufC = cbuf;
143     bufD = dbuf;
144     sizeC = csize -2;
145     sizeD = dsize;
146     DRW_DBG("dwgCompressor::decompress, last 2 bytes: ");
147     DRW_DBGH(bufC[sizeC]);DRW_DBGH(bufC[sizeC+1]);DRW_DBG("\n");
148     sizeC = csize;
149 
150     duint32 compBytes;
151     duint32 compOffset;
152     duint32 litCount;
153 
154     pos=0; //current position in compresed buffer
155     rpos=0; //current position in resulting decompresed buffer
156     litCount = litLength18();
157     //copy first lileral lenght
158     for (duint32 i=0; i < litCount; ++i) {
159         bufD[rpos++] = bufC[pos++];
160     }
161 
162     while (pos < csize && (rpos < dsize+1)){//rpos < dsize to prevent crash more robust are needed
163         duint8 oc = bufC[pos++]; //next opcode
164         if (oc == 0x10){
165             compBytes = longCompressionOffset()+ 9;
166             compOffset = twoByteOffset(&litCount) + 0x3FFF;
167             if (litCount == 0)
168                 litCount= litLength18();
169         } else if (oc > 0x11 && oc< 0x20){
170             compBytes = (oc & 0x0F) + 2;
171             compOffset = twoByteOffset(&litCount) + 0x3FFF;
172             if (litCount == 0)
173                 litCount= litLength18();
174         } else if (oc == 0x20){
175             compBytes = longCompressionOffset() + 0x21;
176             compOffset = twoByteOffset(&litCount);
177             if (litCount == 0)
178                 litCount= litLength18();
179 //            else
180 //                oc = 0x00;
181         } else if (oc > 0x20 && oc< 0x40){
182             compBytes = oc - 0x1E;
183             compOffset = twoByteOffset(&litCount);
184             if (litCount == 0)
185                 litCount= litLength18();
186         } else if ( oc > 0x3F){
187             compBytes = ((oc & 0xF0) >> 4) - 1;
188             duint8 ll2 = bufC[pos++];
189             compOffset =  (ll2 << 2) | ((oc & 0x0C) >> 2);
190             litCount = oc & 0x03;
191             if (litCount < 1){
192                 litCount= litLength18();}
193         } else if (oc == 0x11){
194             DRW_DBG("dwgCompressor::decompress, end of input stream, Cpos: ");
195             DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n");
196             return; //end of input stream
197         } else { //ll < 0x10
198             DRW_DBG("WARNING dwgCompressor::decompress, failed, illegal char, Cpos: ");
199             DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n");
200             return; //fails, not valid
201         }
202         //copy "compresed data", TODO Needed verify out of bounds
203         duint32 remaining = sizeD - (litCount+rpos);
204         if (remaining < compBytes){
205             compBytes = remaining;
206             DRW_DBG("WARNING dwgCompressor::decompress, bad compBytes size, Cpos: ");
207             DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n");
208         }
209         for (duint32 i=0, j= rpos - compOffset -1; i < compBytes; i++) {
210             bufD[rpos++] = bufD[j++];
211         }
212         //copy "uncompresed data", TODO Needed verify out of bounds
213         for (duint32 i=0; i < litCount; i++) {
214             bufD[rpos++] = bufC[pos++];
215         }
216     }
217     DRW_DBG("WARNING dwgCompressor::decompress, bad out, Cpos: ");DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n");
218 }
219 
220 
decrypt18Hdr(duint8 * buf,duint32 size,duint32 offset)221 void dwgCompressor::decrypt18Hdr(duint8 *buf, duint32 size, duint32 offset){
222     duint8 max = size / 4;
223     duint32 secMask = 0x4164536b ^ offset;
224     duint32* pHdr = (duint32*)buf;
225     for (duint8 j = 0; j < max; j++)
226         *pHdr++ ^= secMask;
227 }
228 
229 /*void dwgCompressor::decrypt18Data(duint8 *buf, duint32 size, duint32 offset){
230     duint8 max = size / 4;
231     duint32 secMask = 0x4164536b ^ offset;
232     duint32* pHdr = (duint32*)buf;
233     for (duint8 j = 0; j < max; j++)
234         *pHdr++ ^= secMask;
235 }*/
236 
litLength21(duint8 * cbuf,duint8 oc,duint32 * si)237 duint32 dwgCompressor::litLength21(duint8 *cbuf, duint8 oc, duint32 *si){
238 
239     duint32 srcIndex=*si;
240 
241     duint32 length = oc + 8;
242     if (length == 0x17) {
243         duint32 n = cbuf[srcIndex++];
244         length += n;
245         if (n == 0xff) {
246             do {
247                 n = cbuf[srcIndex++];
248                 n |= (duint32)(cbuf[srcIndex++] << 8);
249                 length += n;
250             } while (n == 0xffff);
251         }
252     }
253 
254     *si = srcIndex;
255     return length;
256 }
257 
decompress21(duint8 * cbuf,duint8 * dbuf,duint32 csize,duint32 dsize)258 void dwgCompressor::decompress21(duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize){
259     duint32 srcIndex=0;
260     duint32 dstIndex=0;
261     duint32 length=0;
262     duint32 sourceOffset;
263     duint8 opCode;
264 
265     opCode = cbuf[srcIndex++];
266     if ((opCode >> 4) == 2){
267         srcIndex = srcIndex +2;
268         length = cbuf[srcIndex++] & 0x07;
269     }
270 
271     while (srcIndex < csize && (dstIndex < dsize+1)){//dstIndex < dsize to prevent crash more robust are needed
272         if (length == 0)
273             length = litLength21(cbuf, opCode, &srcIndex);
274         copyCompBytes21(cbuf, dbuf, length, srcIndex, dstIndex);
275         srcIndex += length;
276         dstIndex += length;
277         if (dstIndex >=dsize) break; //check if last chunk are compresed & terminate
278 
279         length = 0;
280         opCode = cbuf[srcIndex++];
281         readInstructions21(cbuf, &srcIndex, &opCode, &sourceOffset, &length);
282         while (true) {
283             //prevent crash with corrupted data
284             if (sourceOffset > dstIndex){
285                 DRW_DBG("\nWARNING dwgCompressor::decompress21 => sourceOffset> dstIndex.\n");
286                 DRW_DBG("csize = "); DRW_DBG(csize); DRW_DBG("  srcIndex = "); DRW_DBG(srcIndex);
287                 DRW_DBG("\ndsize = "); DRW_DBG(dsize); DRW_DBG("  dstIndex = "); DRW_DBG(dstIndex);
288                 sourceOffset = dstIndex;
289             }
290             //prevent crash with corrupted data
291             if (length > dsize - dstIndex){
292                 DRW_DBG("\nWARNING dwgCompressor::decompress21 => length > dsize - dstIndex.\n");
293                 DRW_DBG("csize = "); DRW_DBG(csize); DRW_DBG("  srcIndex = "); DRW_DBG(srcIndex);
294                 DRW_DBG("\ndsize = "); DRW_DBG(dsize); DRW_DBG("  dstIndex = "); DRW_DBG(dstIndex);
295                 length = dsize - dstIndex;
296                 srcIndex = csize;//force exit
297             }
298             sourceOffset = dstIndex-sourceOffset;
299             for (duint32 i=0; i< length; i++)
300                 dbuf[dstIndex++] = dbuf[sourceOffset+i];
301 
302             length = opCode & 7;
303             if ((length != 0) || (srcIndex >= csize)) {
304                 break;
305             }
306             opCode = cbuf[srcIndex++];
307             if ((opCode >> 4) == 0) {
308                 break;
309             }
310             if ((opCode >> 4) == 15) {
311                 opCode &= 15;
312             }
313             readInstructions21(cbuf, &srcIndex, &opCode, &sourceOffset, &length);
314         }
315     }
316     DRW_DBG("\ncsize = "); DRW_DBG(csize); DRW_DBG("  srcIndex = "); DRW_DBG(srcIndex);
317     DRW_DBG("\ndsize = "); DRW_DBG(dsize); DRW_DBG("  dstIndex = "); DRW_DBG(dstIndex);DRW_DBG("\n");
318 }
319 
readInstructions21(duint8 * cbuf,duint32 * si,duint8 * oc,duint32 * so,duint32 * l)320 void dwgCompressor::readInstructions21(duint8 *cbuf, duint32 *si, duint8 *oc, duint32 *so, duint32 *l){
321     duint32 length;
322     duint32 srcIndex = *si;
323     duint32 sourceOffset;
324     unsigned char opCode = *oc;
325     switch ((opCode >> 4)) {
326     case 0:
327         length = (opCode & 0xf) + 0x13;
328         sourceOffset = cbuf[srcIndex++];
329         opCode = cbuf[srcIndex++];
330         length = ((opCode >> 3) & 0x10) + length;
331         sourceOffset = ((opCode & 0x78) << 5) + 1 + sourceOffset;
332         break;
333     case 1:
334         length = (opCode & 0xf) + 3;
335         sourceOffset = cbuf[srcIndex++];
336         opCode = cbuf[srcIndex++];
337         sourceOffset = ((opCode & 0xf8) << 5) + 1 + sourceOffset;
338         break;
339     case 2:
340         sourceOffset = cbuf[srcIndex++];
341         sourceOffset = ((cbuf[srcIndex++] << 8) & 0xff00) | sourceOffset;
342         length = opCode & 7;
343         if ((opCode & 8) == 0) {
344             opCode = cbuf[srcIndex++];
345             length = (opCode & 0xf8) + length;
346         } else {
347             sourceOffset++;
348             length = (cbuf[srcIndex++] << 3) + length;
349             opCode = cbuf[srcIndex++];
350             length = (((opCode & 0xf8) << 8) + length) + 0x100;
351         }
352         break;
353     default:
354         length = opCode >> 4;
355         sourceOffset = opCode & 15;
356         opCode = cbuf[srcIndex++];
357         sourceOffset = (((opCode & 0xf8) << 1) + sourceOffset) + 1;
358         break;
359     }
360     *oc = opCode;
361     *si = srcIndex;
362     *so = sourceOffset;
363     *l = length;
364 }
365 
366 
copyCompBytes21(duint8 * cbuf,duint8 * dbuf,duint32 l,duint32 si,duint32 di)367 void dwgCompressor::copyCompBytes21(duint8 *cbuf, duint8 *dbuf, duint32 l, duint32 si, duint32 di){
368     duint32 length =l;
369     duint32 dix = di;
370     duint32 six = si;
371 
372     while (length > 31){
373         //in doc: 16-31, 0-15
374         for (duint32 i = six+24; i<six+32; i++)
375             dbuf[dix++] = cbuf[i];
376         for (duint32 i = six+16; i<six+24; i++)
377             dbuf[dix++] = cbuf[i];
378         for (duint32 i = six+8; i<six+16; i++)
379             dbuf[dix++] = cbuf[i];
380         for (duint32 i = six; i<six+8; i++)
381             dbuf[dix++] = cbuf[i];
382         six = six + 32;
383         length = length -32;
384     }
385 
386     switch (length) {
387     case 0:
388         break;
389     case 1: //Ok
390         dbuf[dix] = cbuf[six];
391         break;
392     case 2: //Ok
393         dbuf[dix++] = cbuf[six+1];
394         dbuf[dix] = cbuf[six];
395         break;
396     case 3: //Ok
397         dbuf[dix++] = cbuf[six+2];
398         dbuf[dix++] = cbuf[six+1];
399         dbuf[dix] = cbuf[six];
400         break;
401     case 4: //Ok
402         for (int i = 0; i<4;i++) //RLZ is OK, or are inverse?, OK
403             dbuf[dix++] = cbuf[six++];
404         break;
405     case 5: //Ok
406         dbuf[dix++] = cbuf[six+4];
407         for (int i = 0; i<4;i++)
408             dbuf[dix++] = cbuf[six++];
409         break;
410     case 6: //Ok
411         dbuf[dix++] = cbuf[six+5];
412         for (int i = 1; i<5;i++)
413             dbuf[dix++] = cbuf[six+i];
414         dbuf[dix] = cbuf[six];
415         break;
416     case 7:
417         //in doc: six+5, six+6, 1-5, six+0
418         dbuf[dix++] = cbuf[six+6];
419         dbuf[dix++] = cbuf[six+5];
420         for (int i = 1; i<5;i++)
421             dbuf[dix++] = cbuf[six+i];
422         dbuf[dix] = cbuf[six];
423     case 8: //Ok
424         for (int i = 0; i<8;i++) //RLZ 4[0],4[4] or 4[4],4[0]
425             dbuf[dix++] = cbuf[six++];
426         break;
427     case 9: //Ok
428         dbuf[dix++] = cbuf[six+8];
429         for (int i = 0; i<8;i++)
430             dbuf[dix++] = cbuf[six++];
431         break;
432     case 10: //Ok
433         dbuf[dix++] = cbuf[six+9];
434         for (int i = 1; i<9;i++)
435             dbuf[dix++] = cbuf[six+i];
436         dbuf[dix] = cbuf[six];
437         break;
438     case 11:
439         //in doc: six+9, six+10, 1-9, six+0
440         dbuf[dix++] = cbuf[six+10];
441         dbuf[dix++] = cbuf[six+9];
442         for (int i = 1; i<9;i++)
443             dbuf[dix++] = cbuf[six+i];
444         dbuf[dix] = cbuf[six];
445         break;
446     case 12: //Ok
447         for (int i = 8; i<12;i++)
448             dbuf[dix++] = cbuf[six+i];
449         for (int i = 0; i<8;i++)
450             dbuf[dix++] = cbuf[six++];
451         break;
452     case 13: //Ok
453         dbuf[dix++] = cbuf[six+12];
454         for (int i = 8; i<12;i++)
455             dbuf[dix++] = cbuf[six+i];
456         for (int i = 0; i<8;i++)
457             dbuf[dix++] = cbuf[six++];
458         break;
459     case 14: //Ok
460         dbuf[dix++] = cbuf[six+13];
461         for (int i = 9; i<13; i++)
462             dbuf[dix++] = cbuf[six+i];
463         for (int i = 1; i<9; i++)
464             dbuf[dix++] = cbuf[six+i];
465         dbuf[dix] = cbuf[six];
466         break;
467     case 15:
468         //in doc: six+13, six+14, 9-12, 1-8, six+0
469         dbuf[dix++] = cbuf[six+14];
470         dbuf[dix++] = cbuf[six+13];
471         for (int i = 9; i<13; i++)
472             dbuf[dix++] = cbuf[six+i];
473         for (int i = 1; i<9; i++)
474             dbuf[dix++] = cbuf[six+i];
475         dbuf[dix] = cbuf[six];
476         break;
477     case 16: //Ok
478         for (int i = 8; i<16;i++)
479             dbuf[dix++] = cbuf[six+i];
480         for (int i = 0; i<8;i++)
481             dbuf[dix++] = cbuf[six++];
482         break;
483     case 17: //Seems Ok
484         for (int i = 9; i<17;i++)
485             dbuf[dix++] = cbuf[six+i];
486         dbuf[dix++] = cbuf[six+8];
487         for (int i = 0; i<8;i++)
488             dbuf[dix++] = cbuf[six++];
489         break;
490     case 18:
491         //in doc: six+17, 1-16, six+0
492         dbuf[dix++] = cbuf[six+17];
493         for (int i = 9; i<17;i++)
494             dbuf[dix++] = cbuf[six+i];
495         for (int i = 1; i<9;i++)
496             dbuf[dix++] = cbuf[six+i];
497         dbuf[dix] = cbuf[six];
498         break;
499     case 19:
500         //in doc: 16-18, 0-15
501         dbuf[dix++] = cbuf[six+18];
502         dbuf[dix++] = cbuf[six+17];
503         dbuf[dix++] = cbuf[six+16];
504         for (int i = 8; i<16;i++)
505             dbuf[dix++] = cbuf[six+i];
506         for (int i = 0; i<8;i++)
507             dbuf[dix++] = cbuf[six++];
508         break;
509     case 20:
510         //in doc: 16-19, 0-15
511         for (int i = 16; i<20;i++)
512             dbuf[dix++] = cbuf[six+i];
513         for (int i = 8; i<16;i++)
514             dbuf[dix++] = cbuf[six+i];
515         for (int i = 0; i<8;i++)
516             dbuf[dix++] = cbuf[six++];
517         break;
518     case 21:
519         //in doc: six+20, 16-19, 0-15
520         dbuf[dix++] = cbuf[six+20];
521         for (int i = 16; i<20;i++)
522             dbuf[dix++] = cbuf[six+i];
523         for (int i = 8; i<16;i++)
524             dbuf[dix++] = cbuf[six+i];
525         for (int i = 0; i<8;i++)
526             dbuf[dix++] = cbuf[six+i];
527         break;
528     case 22:
529         //in doc: six+20, six+21, 16-19, 0-15
530         dbuf[dix++] = cbuf[six+21];
531         dbuf[dix++] = cbuf[six+20];
532         for (int i = 16; i<20;i++)
533             dbuf[dix++] = cbuf[six+i];
534         for (int i = 8; i<16;i++)
535             dbuf[dix++] = cbuf[six+i];
536         for (int i = 0; i<8;i++)
537             dbuf[dix++] = cbuf[six++];
538         break;
539     case 23:
540         //in doc: six+20, six+21, six+22, 16-19, 0-15
541         dbuf[dix++] = cbuf[six+22];
542         dbuf[dix++] = cbuf[six+21];
543         dbuf[dix++] = cbuf[six+20];
544         for (int i = 16; i<20;i++)
545             dbuf[dix++] = cbuf[six+i];
546         for (int i = 8; i<16;i++)
547             dbuf[dix++] = cbuf[six+i];
548         for (int i = 0; i<8;i++)
549             dbuf[dix++] = cbuf[six+i];
550         break;
551     case 24:
552         //in doc: 16-23, 0-15
553         for (int i = 16; i<24;i++)
554             dbuf[dix++] = cbuf[six+i];
555         for (int i = 8; i<16;i++)
556             dbuf[dix++] = cbuf[six+i];
557         for (int i = 0; i<8; i++)
558             dbuf[dix++] = cbuf[six++];
559         break;
560     case 25:
561         //in doc: 17-24, six+16, 0-15
562         for (int i = 17; i<25;i++)
563             dbuf[dix++] = cbuf[six+i];
564         dbuf[dix++] = cbuf[six+16];
565         for (int i = 8; i<16; i++)
566             dbuf[dix++] = cbuf[six+i];
567         for (int i = 0; i<8; i++)
568             dbuf[dix++] = cbuf[six++];
569         break;
570     case 26:
571         //in doc: six+25, 17-24, six+16, 0-15
572         dbuf[dix++] = cbuf[six+25];
573         for (int i = 17; i<25;i++)
574             dbuf[dix++] = cbuf[six+i];
575         dbuf[dix++] = cbuf[six+16];
576         for (int i = 8; i<16;i++)
577             dbuf[dix++] = cbuf[six+i];
578         for (int i = 0; i<8; i++)
579             dbuf[dix++] = cbuf[six++];
580         break;
581     case 27:
582         //in doc: six+25, six+26, 17-24, six+16, 0-15
583         dbuf[dix++] = cbuf[six+26];
584         dbuf[dix++] = cbuf[six+25];
585         for (int i = 17; i<25;i++)
586             dbuf[dix++] = cbuf[six+i];
587         dbuf[dix++] = cbuf[six+16];
588         for (int i = 8; i<16;i++)
589             dbuf[dix++] = cbuf[six+i];
590         for (int i = 0; i<8; i++)
591             dbuf[dix++] = cbuf[six++];
592         break;
593     case 28:
594         //in doc: 24-27, 16-23, 0-15
595         for (int i = 24; i<28; i++)
596             dbuf[dix++] = cbuf[six+i];
597         for (int i = 16; i<24;i++)
598             dbuf[dix++] = cbuf[six+i];
599         for (int i = 8; i<16; i++)
600             dbuf[dix++] = cbuf[six+i];
601         for (int i = 0; i<8; i++)
602             dbuf[dix++] = cbuf[six++];
603         break;
604     case 29:
605         //in doc: six+28, 24-27, 16-23, 0-15
606         dbuf[dix++] = cbuf[six+28];
607         for (int i = 24; i<28; i++)
608             dbuf[dix++] = cbuf[six+i];
609         for (int i = 16; i<24;i++)
610             dbuf[dix++] = cbuf[six+i];
611         for (int i = 8; i<16;i++)
612             dbuf[dix++] = cbuf[six+i];
613         for (int i = 0; i<8; i++)
614             dbuf[dix++] = cbuf[six++];
615         break;
616     case 30:
617         //in doc: six+28, six+29, 24-27, 16-23, 0-15
618         dbuf[dix++] = cbuf[six+29];
619         dbuf[dix++] = cbuf[six+28];
620         for (int i = 24; i<28; i++)
621             dbuf[dix++] = cbuf[six+i];
622         for (int i = 16; i<24;i++)
623             dbuf[dix++] = cbuf[six+i];
624         for (int i = 8; i<16;i++)
625             dbuf[dix++] = cbuf[six+i];
626         for (int i = 0; i<8; i++)
627             dbuf[dix++] = cbuf[six++];
628         break;
629     case 31:
630         //in doc: six+30, 26-29, 18-25, 2-17, 0-1
631         dbuf[dix++] = cbuf[six+30];
632         for (int i = 26; i<30;i++)
633             dbuf[dix++] = cbuf[six+i];
634         for (int i = 18; i<26;i++)
635             dbuf[dix++] = cbuf[six+i];
636 /*        for (int i = 2; i<18; i++)
637             dbuf[dix++] = cbuf[six+i];*/
638         for (int i = 10; i<18; i++)
639             dbuf[dix++] = cbuf[six+i];
640         for (int i = 2; i<10; i++)
641             dbuf[dix++] = cbuf[six+i];
642         dbuf[dix++] = cbuf[six+1];
643         dbuf[dix] = cbuf[six];
644         break;
645     default:
646         DRW_DBG("WARNING dwgCompressor::copyCompBytes21, bad output.\n");
647         break;
648     }
649 }
650 
651 
getEnum(std::string nameSec)652 secEnum::DWGSection secEnum::getEnum(std::string nameSec){
653     //TODO: complete it
654     if (nameSec=="AcDb:Header"){
655         return HEADER;
656     } else if (nameSec=="AcDb:Classes"){
657         return CLASSES;
658     } else if (nameSec=="AcDb:SummaryInfo"){
659         return SUMARYINFO;
660     } else if (nameSec=="AcDb:Preview"){
661         return PREVIEW;
662     } else if (nameSec=="AcDb:VBAProject"){
663         return VBAPROY;
664     } else if (nameSec=="AcDb:AppInfo"){
665         return APPINFO;
666     } else if (nameSec=="AcDb:FileDepList"){
667         return FILEDEP;
668     } else if (nameSec=="AcDb:RevHistory"){
669         return REVHISTORY;
670     } else if (nameSec=="AcDb:Security"){
671         return SECURITY;
672     } else if (nameSec=="AcDb:AcDbObjects"){
673         return OBJECTS;
674     } else if (nameSec=="AcDb:ObjFreeSpace"){
675         return OBJFREESPACE;
676     } else if (nameSec=="AcDb:Template"){
677         return TEMPLATE;
678     } else if (nameSec=="AcDb:Handles"){
679         return HANDLES;
680     } else if (nameSec=="AcDb:AcDsPrototype_1b"){
681         return PROTOTYPE;
682     } else if (nameSec=="AcDb:AuxHeader"){
683         return AUXHEADER;
684     } else if (nameSec=="AcDb:Signature"){
685         return SIGNATURE;
686     } else if (nameSec=="AcDb:AppInfoHistory"){ //in ac1021
687         return APPINFOHISTORY;
688 //    } else if (nameSec=="AcDb:Extended Entity Data"){
689 //        return EXTEDATA;
690 //    } else if (nameSec=="AcDb:PROXY ENTITY GRAPHICS"){
691 //        return PROXYGRAPHICS;
692     }
693     return UNKNOWNS;
694 }
695