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