/****************************************************************************** ** 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 . ** ******************************************************************************/ #include #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; }