mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
808 lines
22 KiB
C++
808 lines
22 KiB
C++
/******************************************************************************
|
|
** libDXFrw - Library to read/write DXF files (ascii & binary) **
|
|
** **
|
|
** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com **
|
|
** **
|
|
** This library is free software, licensed under the terms of the GNU **
|
|
** General Public License as published by the Free Software Foundation, **
|
|
** either version 2 of the License, or (at your option) any later version. **
|
|
** You should have received a copy of the GNU General Public License **
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
|
|
******************************************************************************/
|
|
|
|
#include <sstream>
|
|
#include "drw_dbg.h"
|
|
#include "dwgutil.h"
|
|
#include "rscodec.h"
|
|
#include "../libdwgr.h"
|
|
|
|
#if __cplusplus >= 201500
|
|
#define FALLTHROUGH [[fallthrough]];
|
|
#elif defined(__clang__)
|
|
#define FALLTHROUGH //[[clang::fallthrough]]
|
|
#elif defined(__GNUC__) && __GNUC__ >= 7
|
|
#define FALLTHROUGH [[gnu::fallthrough]];
|
|
#else
|
|
#define FALLTHROUGH
|
|
#endif
|
|
|
|
#include "qgslogger.h"
|
|
|
|
/** Utility function
|
|
* convert a int to string in hex
|
|
**/
|
|
namespace DRW
|
|
{
|
|
std::string toHexStr( int n )
|
|
{
|
|
#if defined(__APPLE__)
|
|
char buffer[9] = {'\0'};
|
|
snprintf( buffer, 9, "%X", n );
|
|
return std::string( buffer );
|
|
#else
|
|
std::ostringstream Convert;
|
|
Convert << std::uppercase << std::hex << n;
|
|
return Convert.str();
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief dwgRSCodec::decode239I
|
|
* @param in : input data (at least 255*blk bytes)
|
|
* @param out : output data (at least 239*blk bytes)
|
|
* @param blk number of codewords ( 1 cw == 255 bytes)
|
|
*/
|
|
void dwgRSCodec::decode239I( unsigned char *in, unsigned char *out, duint32 blk )
|
|
{
|
|
int k = 0;
|
|
unsigned char data[255];
|
|
RScodec rsc( 0x96, 8, 8 ); //(255, 239)
|
|
for ( duint32 i = 0; i < blk; i++ )
|
|
{
|
|
k = i;
|
|
for ( int j = 0; j < 255; j++ )
|
|
{
|
|
data[j] = in[k];
|
|
k += blk;
|
|
}
|
|
int r = rsc.decode( data );
|
|
if ( r < 0 )
|
|
{
|
|
QgsDebugMsg( "WARNING: dwgRSCodec::decode239I, can't correct all errors" );
|
|
}
|
|
k = i * 239;
|
|
for ( int j = 0; j < 239; j++ )
|
|
{
|
|
out[k++] = data[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief dwgRSCodec::decode251I
|
|
* @param in : input data (at least 255*blk bytes)
|
|
* @param out : output data (at least 251*blk bytes)
|
|
* @param blk number of codewords ( 1 cw == 255 bytes)
|
|
*/
|
|
void dwgRSCodec::decode251I( unsigned char *in, unsigned char *out, duint32 blk )
|
|
{
|
|
int k = 0;
|
|
unsigned char data[255];
|
|
RScodec rsc( 0xB8, 8, 2 ); //(255, 251)
|
|
for ( duint32 i = 0; i < blk; i++ )
|
|
{
|
|
k = i;
|
|
for ( int j = 0; j < 255; j++ )
|
|
{
|
|
data[j] = in[k];
|
|
k += blk;
|
|
}
|
|
int r = rsc.decode( data );
|
|
if ( r < 0 )
|
|
{
|
|
QgsDebugMsg( "WARNING: dwgRSCodec::decode251I, can't correct all errors" );
|
|
}
|
|
k = i * 251;
|
|
for ( int j = 0; j < 251; j++ )
|
|
{
|
|
out[k++] = data[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
duint32 dwgCompressor::twoByteOffset( duint32 *ll )
|
|
{
|
|
duint32 cont = 0;
|
|
duint8 fb = bufC[pos++];
|
|
cont = ( fb >> 2 ) | ( bufC[pos++] << 6 );
|
|
*ll = ( fb & 0x03 );
|
|
return cont;
|
|
}
|
|
|
|
duint32 dwgCompressor::longCompressionOffset()
|
|
{
|
|
duint32 cont = 0;
|
|
duint8 ll = bufC[pos++];
|
|
while ( ll == 0x00 )
|
|
{
|
|
cont += 0xFF;
|
|
ll = bufC[pos++];
|
|
}
|
|
cont += ll;
|
|
return cont;
|
|
}
|
|
|
|
duint32 dwgCompressor::long20CompressionOffset()
|
|
{
|
|
// duint32 cont = 0;
|
|
duint32 cont = 0x0F;
|
|
duint8 ll = bufC[pos++];
|
|
while ( ll == 0x00 )
|
|
{
|
|
// cont += 0xFF;
|
|
ll = bufC[pos++];
|
|
}
|
|
cont += ll;
|
|
return cont;
|
|
}
|
|
|
|
duint32 dwgCompressor::litLength18()
|
|
{
|
|
duint32 cont = 0;
|
|
duint8 ll = bufC[pos++];
|
|
//no literal length, this byte is next opCode
|
|
if ( ll > 0x0F )
|
|
{
|
|
pos--;
|
|
return 0;
|
|
}
|
|
|
|
if ( ll == 0x00 )
|
|
{
|
|
cont = 0x0F;
|
|
ll = bufC[pos++];
|
|
while ( ll == 0x00 ) //repeat until ll != 0x00
|
|
{
|
|
cont += 0xFF;
|
|
ll = bufC[pos++];
|
|
}
|
|
}
|
|
cont += ll;
|
|
cont += 3; //already sum 3
|
|
return cont;
|
|
}
|
|
|
|
void dwgCompressor::decompress18( duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize )
|
|
{
|
|
bufC = cbuf;
|
|
bufD = dbuf;
|
|
sizeC = csize - 2;
|
|
sizeD = dsize;
|
|
QgsDebugMsgLevel( QString( "last 2 bytes: 0x%1 0x%2" ).arg( bufC[sizeC], 0, 16 ).arg( bufC[sizeC + 1], 0, 16 ), 5 );
|
|
sizeC = csize;
|
|
|
|
duint32 compBytes;
|
|
duint32 compOffset;
|
|
duint32 litCount;
|
|
|
|
pos = 0; //current position in compressed buffer
|
|
rpos = 0; //current position in resulting decompressed buffer
|
|
litCount = litLength18();
|
|
//copy first literal length
|
|
for ( duint32 i = 0; i < litCount; ++i )
|
|
{
|
|
bufD[rpos++] = bufC[pos++];
|
|
}
|
|
|
|
while ( pos < csize && ( rpos < dsize + 1 ) ) //rpos < dsize to prevent crash more robust are needed
|
|
{
|
|
duint8 oc = bufC[pos++]; //next opcode
|
|
if ( oc == 0x10 )
|
|
{
|
|
compBytes = longCompressionOffset() + 9;
|
|
compOffset = twoByteOffset( &litCount ) + 0x3FFF;
|
|
if ( litCount == 0 )
|
|
litCount = litLength18();
|
|
}
|
|
else if ( oc > 0x11 && oc < 0x20 )
|
|
{
|
|
compBytes = ( oc & 0x0F ) + 2;
|
|
compOffset = twoByteOffset( &litCount ) + 0x3FFF;
|
|
if ( litCount == 0 )
|
|
litCount = litLength18();
|
|
}
|
|
else if ( oc == 0x20 )
|
|
{
|
|
compBytes = longCompressionOffset() + 0x21;
|
|
compOffset = twoByteOffset( &litCount );
|
|
if ( litCount == 0 )
|
|
litCount = litLength18();
|
|
else
|
|
oc = 0x00;
|
|
}
|
|
else if ( oc > 0x20 && oc < 0x40 )
|
|
{
|
|
compBytes = oc - 0x1E;
|
|
compOffset = twoByteOffset( &litCount );
|
|
if ( litCount == 0 )
|
|
litCount = litLength18();
|
|
}
|
|
else if ( oc > 0x3F )
|
|
{
|
|
compBytes = ( ( oc & 0xF0 ) >> 4 ) - 1;
|
|
duint8 ll2 = bufC[pos++];
|
|
compOffset = ( ll2 << 2 ) | ( ( oc & 0x0C ) >> 2 );
|
|
litCount = oc & 0x03;
|
|
if ( litCount < 1 )
|
|
{
|
|
litCount = litLength18();
|
|
}
|
|
}
|
|
else if ( oc == 0x11 )
|
|
{
|
|
QgsDebugMsgLevel( QString( "end of input stream, Cpos:%1, Dpos:%2" ).arg( pos ).arg( rpos ), 5 );
|
|
return; //end of input stream
|
|
}
|
|
else //ll < 0x10
|
|
{
|
|
QgsDebugMsg( QString( "failed illegal char, Cpos:%1, Dpos:%2" ).arg( pos ).arg( rpos ) );
|
|
return; //fails, not valid
|
|
}
|
|
//copy "compressed data", TODO Needed verify out of bounds
|
|
duint32 remaining = sizeD - ( litCount + rpos );
|
|
if ( remaining < compBytes )
|
|
{
|
|
compBytes = remaining;
|
|
QgsDebugMsg( QString( "bad compBytes size, Cpos:%1, Dpos:%2" ).arg( pos ).arg( rpos ) );
|
|
}
|
|
for ( duint32 i = 0, j = rpos - compOffset - 1; i < compBytes; i++ )
|
|
{
|
|
bufD[rpos++] = bufD[j++];
|
|
}
|
|
//copy "uncompressed data", TODO Needed verify out of bounds
|
|
for ( duint32 i = 0; i < litCount; i++ )
|
|
{
|
|
bufD[rpos++] = bufC[pos++];
|
|
}
|
|
}
|
|
QgsDebugMsg( QString( "bad out, Cpos:%1, Dpos:%2" ).arg( pos ).arg( rpos ) );
|
|
}
|
|
|
|
|
|
void dwgCompressor::decrypt18Hdr( duint8 *buf, duint32 size, duint32 offset )
|
|
{
|
|
duint8 max = size / 4;
|
|
duint32 secMask = 0x4164536b ^ offset;
|
|
duint32 *pHdr = ( duint32 * )buf;
|
|
for ( duint8 j = 0; j < max; j++ )
|
|
*pHdr++ ^= secMask;
|
|
}
|
|
|
|
/*void dwgCompressor::decrypt18Data(duint8 *buf, duint32 size, duint32 offset){
|
|
duint8 max = size / 4;
|
|
duint32 secMask = 0x4164536b ^ offset;
|
|
duint32* pHdr = (duint32*)buf;
|
|
for (duint8 j = 0; j < max; j++)
|
|
*pHdr++ ^= secMask;
|
|
}*/
|
|
|
|
duint32 dwgCompressor::litLength21( duint8 *cbuf, duint8 oc, duint32 *si )
|
|
{
|
|
|
|
duint32 srcIndex = *si;
|
|
|
|
duint32 length = oc + 8;
|
|
if ( length == 0x17 )
|
|
{
|
|
duint32 n = cbuf[srcIndex++];
|
|
length += n;
|
|
if ( n == 0xff )
|
|
{
|
|
do
|
|
{
|
|
n = cbuf[srcIndex++];
|
|
n |= ( duint32 )( cbuf[srcIndex++] << 8 );
|
|
length += n;
|
|
}
|
|
while ( n == 0xffff );
|
|
}
|
|
}
|
|
|
|
*si = srcIndex;
|
|
return length;
|
|
}
|
|
|
|
void dwgCompressor::decompress21( duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize )
|
|
{
|
|
duint32 srcIndex = 0;
|
|
duint32 dstIndex = 0;
|
|
duint32 length = 0;
|
|
duint32 sourceOffset;
|
|
duint8 opCode;
|
|
|
|
opCode = cbuf[srcIndex++];
|
|
if ( ( opCode >> 4 ) == 2 )
|
|
{
|
|
srcIndex = srcIndex + 2;
|
|
length = cbuf[srcIndex++] & 0x07;
|
|
}
|
|
|
|
while ( srcIndex < csize && ( dstIndex < dsize + 1 ) ) //dstIndex < dsize to prevent crash more robust are needed
|
|
{
|
|
if ( length == 0 )
|
|
length = litLength21( cbuf, opCode, &srcIndex );
|
|
copyCompBytes21( cbuf, dbuf, length, srcIndex, dstIndex );
|
|
srcIndex += length;
|
|
dstIndex += length;
|
|
if ( dstIndex >= dsize ) break; //check if last chunk are compressed & terminate
|
|
|
|
length = 0;
|
|
opCode = cbuf[srcIndex++];
|
|
readInstructions21( cbuf, &srcIndex, &opCode, &sourceOffset, &length );
|
|
while ( true )
|
|
{
|
|
//prevent crash with corrupted data
|
|
if ( sourceOffset > dstIndex )
|
|
{
|
|
QgsDebugMsg( QString( "WARNING sourceOffset > dstIndex: csize=%1, srcIndex=%2 dsize=%3 dstIndex=%4" )
|
|
.arg( csize ).arg( srcIndex ).arg( dsize ).arg( dstIndex )
|
|
);
|
|
sourceOffset = dstIndex;
|
|
}
|
|
//prevent crash with corrupted data
|
|
if ( length > dsize - dstIndex )
|
|
{
|
|
QgsDebugMsg( QString( "WARNING length > dsize - dstIndex: csize=%1, srcIndex=%2 dsize=%3 dstIndex=%4" )
|
|
.arg( csize ).arg( srcIndex ).arg( dsize ).arg( dstIndex )
|
|
);
|
|
length = dsize - dstIndex;
|
|
srcIndex = csize;//force exit
|
|
}
|
|
sourceOffset = dstIndex - sourceOffset;
|
|
for ( duint32 i = 0; i < length; i++ )
|
|
dbuf[dstIndex++] = dbuf[sourceOffset + i];
|
|
|
|
length = opCode & 7;
|
|
if ( ( length != 0 ) || ( srcIndex >= csize ) )
|
|
{
|
|
break;
|
|
}
|
|
opCode = cbuf[srcIndex++];
|
|
if ( ( opCode >> 4 ) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
if ( ( opCode >> 4 ) == 15 )
|
|
{
|
|
opCode &= 15;
|
|
}
|
|
readInstructions21( cbuf, &srcIndex, &opCode, &sourceOffset, &length );
|
|
}
|
|
}
|
|
QgsDebugMsg( QString( "csize=%1, srcIndex=%2 dsize=%3 dstIndex=%4" )
|
|
.arg( csize ).arg( srcIndex ).arg( dsize ).arg( dstIndex )
|
|
);
|
|
}
|
|
|
|
void dwgCompressor::readInstructions21( duint8 *cbuf, duint32 *si, duint8 *oc, duint32 *so, duint32 *l )
|
|
{
|
|
duint32 length;
|
|
duint32 srcIndex = *si;
|
|
duint32 sourceOffset;
|
|
unsigned char opCode = *oc;
|
|
switch ( ( opCode >> 4 ) )
|
|
{
|
|
case 0:
|
|
length = ( opCode & 0xf ) + 0x13;
|
|
sourceOffset = cbuf[srcIndex++];
|
|
opCode = cbuf[srcIndex++];
|
|
length = ( ( opCode >> 3 ) & 0x10 ) + length;
|
|
sourceOffset = ( ( opCode & 0x78 ) << 5 ) + 1 + sourceOffset;
|
|
break;
|
|
case 1:
|
|
length = ( opCode & 0xf ) + 3;
|
|
sourceOffset = cbuf[srcIndex++];
|
|
opCode = cbuf[srcIndex++];
|
|
sourceOffset = ( ( opCode & 0xf8 ) << 5 ) + 1 + sourceOffset;
|
|
break;
|
|
case 2:
|
|
sourceOffset = cbuf[srcIndex++];
|
|
sourceOffset = ( ( cbuf[srcIndex++] << 8 ) & 0xff00 ) | sourceOffset;
|
|
length = opCode & 7;
|
|
if ( ( opCode & 8 ) == 0 )
|
|
{
|
|
opCode = cbuf[srcIndex++];
|
|
length = ( opCode & 0xf8 ) + length;
|
|
}
|
|
else
|
|
{
|
|
sourceOffset++;
|
|
length = ( cbuf[srcIndex++] << 3 ) + length;
|
|
opCode = cbuf[srcIndex++];
|
|
length = ( ( ( opCode & 0xf8 ) << 8 ) + length ) + 0x100;
|
|
}
|
|
break;
|
|
default:
|
|
length = opCode >> 4;
|
|
sourceOffset = opCode & 15;
|
|
opCode = cbuf[srcIndex++];
|
|
sourceOffset = ( ( ( opCode & 0xf8 ) << 1 ) + sourceOffset ) + 1;
|
|
break;
|
|
}
|
|
*oc = opCode;
|
|
*si = srcIndex;
|
|
*so = sourceOffset;
|
|
*l = length;
|
|
}
|
|
|
|
|
|
void dwgCompressor::copyCompBytes21( duint8 *cbuf, duint8 *dbuf, duint32 l, duint32 si, duint32 di )
|
|
{
|
|
duint32 length = l;
|
|
duint32 dix = di;
|
|
duint32 six = si;
|
|
|
|
while ( length > 31 )
|
|
{
|
|
//in doc: 16-31, 0-15
|
|
for ( duint32 i = six + 24; i < six + 32; i++ )
|
|
dbuf[dix++] = cbuf[i];
|
|
for ( duint32 i = six + 16; i < six + 24; i++ )
|
|
dbuf[dix++] = cbuf[i];
|
|
for ( duint32 i = six + 8; i < six + 16; i++ )
|
|
dbuf[dix++] = cbuf[i];
|
|
for ( duint32 i = six; i < six + 8; i++ )
|
|
dbuf[dix++] = cbuf[i];
|
|
six = six + 32;
|
|
length = length - 32;
|
|
}
|
|
|
|
switch ( length )
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1: //OK
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 2: //OK
|
|
dbuf[dix++] = cbuf[six + 1];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 3: //OK
|
|
dbuf[dix++] = cbuf[six + 2];
|
|
dbuf[dix++] = cbuf[six + 1];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 4: //OK
|
|
for ( int i = 0; i < 4; i++ ) //RLZ is OK, or are inverse?, OK
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 5: //OK
|
|
dbuf[dix++] = cbuf[six + 4];
|
|
for ( int i = 0; i < 4; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 6: //OK
|
|
dbuf[dix++] = cbuf[six + 5];
|
|
for ( int i = 1; i < 5; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 7:
|
|
//in doc: six+5, six+6, 1-5, six+0
|
|
dbuf[dix++] = cbuf[six + 6];
|
|
dbuf[dix++] = cbuf[six + 5];
|
|
for ( int i = 1; i < 5; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix] = cbuf[six];
|
|
|
|
FALLTHROUGH
|
|
|
|
case 8: //OK
|
|
for ( int i = 0; i < 8; i++ ) //RLZ 4[0],4[4] or 4[4],4[0]
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 9: //OK
|
|
dbuf[dix++] = cbuf[six + 8];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 10: //OK
|
|
dbuf[dix++] = cbuf[six + 9];
|
|
for ( int i = 1; i < 9; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 11:
|
|
//in doc: six+9, six+10, 1-9, six+0
|
|
dbuf[dix++] = cbuf[six + 10];
|
|
dbuf[dix++] = cbuf[six + 9];
|
|
for ( int i = 1; i < 9; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 12: //OK
|
|
for ( int i = 8; i < 12; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 13: //OK
|
|
dbuf[dix++] = cbuf[six + 12];
|
|
for ( int i = 8; i < 12; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 14: //OK
|
|
dbuf[dix++] = cbuf[six + 13];
|
|
for ( int i = 9; i < 13; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 1; i < 9; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 15:
|
|
//in doc: six+13, six+14, 9-12, 1-8, six+0
|
|
dbuf[dix++] = cbuf[six + 14];
|
|
dbuf[dix++] = cbuf[six + 13];
|
|
for ( int i = 9; i < 13; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 1; i < 9; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 16: //OK
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 17: //Seems OK
|
|
for ( int i = 9; i < 17; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix++] = cbuf[six + 8];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 18:
|
|
//in doc: six+17, 1-16, six+0
|
|
dbuf[dix++] = cbuf[six + 17];
|
|
for ( int i = 9; i < 17; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 1; i < 9; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
case 19:
|
|
//in doc: 16-18, 0-15
|
|
dbuf[dix++] = cbuf[six + 18];
|
|
dbuf[dix++] = cbuf[six + 17];
|
|
dbuf[dix++] = cbuf[six + 16];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 20:
|
|
//in doc: 16-19, 0-15
|
|
for ( int i = 16; i < 20; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 21:
|
|
//in doc: six+20, 16-19, 0-15
|
|
dbuf[dix++] = cbuf[six + 20];
|
|
for ( int i = 16; i < 20; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
break;
|
|
case 22:
|
|
//in doc: six+20, six+21, 16-19, 0-15
|
|
dbuf[dix++] = cbuf[six + 21];
|
|
dbuf[dix++] = cbuf[six + 20];
|
|
for ( int i = 16; i < 20; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 23:
|
|
//in doc: six+20, six+21, six+22, 16-19, 0-15
|
|
dbuf[dix++] = cbuf[six + 22];
|
|
dbuf[dix++] = cbuf[six + 21];
|
|
dbuf[dix++] = cbuf[six + 20];
|
|
for ( int i = 16; i < 20; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
break;
|
|
case 24:
|
|
//in doc: 16-23, 0-15
|
|
for ( int i = 16; i < 24; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 25:
|
|
//in doc: 17-24, six+16, 0-15
|
|
for ( int i = 17; i < 25; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix++] = cbuf[six + 16];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 26:
|
|
//in doc: six+25, 17-24, six+16, 0-15
|
|
dbuf[dix++] = cbuf[six + 25];
|
|
for ( int i = 17; i < 25; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix++] = cbuf[six + 16];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 27:
|
|
//in doc: six+25, six+26, 17-24, six+16, 0-15
|
|
dbuf[dix++] = cbuf[six + 26];
|
|
dbuf[dix++] = cbuf[six + 25];
|
|
for ( int i = 17; i < 25; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix++] = cbuf[six + 16];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 28:
|
|
//in doc: 24-27, 16-23, 0-15
|
|
for ( int i = 24; i < 28; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 16; i < 24; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 29:
|
|
//in doc: six+28, 24-27, 16-23, 0-15
|
|
dbuf[dix++] = cbuf[six + 28];
|
|
for ( int i = 24; i < 28; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 16; i < 24; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 30:
|
|
//in doc: six+28, six+29, 24-27, 16-23, 0-15
|
|
dbuf[dix++] = cbuf[six + 29];
|
|
dbuf[dix++] = cbuf[six + 28];
|
|
for ( int i = 24; i < 28; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 16; i < 24; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 8; i < 16; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 0; i < 8; i++ )
|
|
dbuf[dix++] = cbuf[six++];
|
|
break;
|
|
case 31:
|
|
//in doc: six+30, 26-29, 18-25, 2-17, 0-1
|
|
dbuf[dix++] = cbuf[six + 30];
|
|
for ( int i = 26; i < 30; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 18; i < 26; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
/* for (int i = 2; i<18; i++)
|
|
dbuf[dix++] = cbuf[six+i];*/
|
|
for ( int i = 10; i < 18; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
for ( int i = 2; i < 10; i++ )
|
|
dbuf[dix++] = cbuf[six + i];
|
|
dbuf[dix++] = cbuf[six + 1];
|
|
dbuf[dix] = cbuf[six];
|
|
break;
|
|
default:
|
|
QgsDebugMsg( "WARNING bad output." );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
secEnum::DWGSection secEnum::getEnum( std::string nameSec )
|
|
{
|
|
//TODO: complete it
|
|
if ( nameSec == "AcDb:Header" )
|
|
{
|
|
return HEADER;
|
|
}
|
|
else if ( nameSec == "AcDb:Classes" )
|
|
{
|
|
return CLASSES;
|
|
}
|
|
else if ( nameSec == "AcDb:SummaryInfo" )
|
|
{
|
|
return SUMMARYINFO;
|
|
}
|
|
else if ( nameSec == "AcDb:Preview" )
|
|
{
|
|
return PREVIEW;
|
|
}
|
|
else if ( nameSec == "AcDb:VBAProject" )
|
|
{
|
|
return VBAPROY;
|
|
}
|
|
else if ( nameSec == "AcDb:AppInfo" )
|
|
{
|
|
return APPINFO;
|
|
}
|
|
else if ( nameSec == "AcDb:FileDepList" )
|
|
{
|
|
return FILEDEP;
|
|
}
|
|
else if ( nameSec == "AcDb:RevHistory" )
|
|
{
|
|
return REVHISTORY;
|
|
}
|
|
else if ( nameSec == "AcDb:Security" )
|
|
{
|
|
return SECURITY;
|
|
}
|
|
else if ( nameSec == "AcDb:AcDbObjects" )
|
|
{
|
|
return OBJECTS;
|
|
}
|
|
else if ( nameSec == "AcDb:ObjFreeSpace" )
|
|
{
|
|
return OBJFREESPACE;
|
|
}
|
|
else if ( nameSec == "AcDb:Template" )
|
|
{
|
|
return TEMPLATE;
|
|
}
|
|
else if ( nameSec == "AcDb:Handles" )
|
|
{
|
|
return HANDLES;
|
|
}
|
|
else if ( nameSec == "AcDb:AcDsPrototype_1b" )
|
|
{
|
|
return PROTOTYPE;
|
|
}
|
|
else if ( nameSec == "AcDb:AuxHeader" )
|
|
{
|
|
return AUXHEADER;
|
|
}
|
|
else if ( nameSec == "AcDb:Signature" )
|
|
{
|
|
return SIGNATURE;
|
|
}
|
|
else if ( nameSec == "AcDb:AppInfoHistory" ) //in ac1021
|
|
{
|
|
return APPINFOHISTORY;
|
|
// } else if (nameSec=="AcDb:Extended Entity Data"){
|
|
// return EXTEDATA;
|
|
// } else if (nameSec=="AcDb:PROXY ENTITY GRAPHICS"){
|
|
// return PROXYGRAPHICS;
|
|
}
|
|
return UNKNOWNS;
|
|
}
|