/****************************************************************************** ** 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 #include #include #include #include "drw_dbg.h" #include "dwgreader18.h" #include "dwgutil.h" #include "drw_textcodec.h" #include "../libdwgr.h" void dwgReader18::genMagicNumber() { int size = 0x114; duint8 *tmpMagicStr = new duint8[size]; duint8 *p = tmpMagicStr; int rSeed = 1; while ( size-- ) { rSeed *= 0x343fd; rSeed += 0x269ec3; *p++ = static_cast( rSeed >> 0x10 ); } int j = 0; size = 0x114; for ( int i = 0; i < size; i++ ) { DRW_DBGH( tmpMagicStr[i] ); if ( j == 15 ) { DRW_DBG( "\n" ); j = 0; } else { DRW_DBG( ", " ); j++; } } delete[]tmpMagicStr; } duint32 dwgReader18::checksum( duint32 seed, duint8 *data, duint32 sz ) { duint32 size = sz; duint32 sum1 = seed & 0xffff; duint32 sum2 = seed >> 0x10; while ( size != 0 ) { // duint32 chunkSize = min(0x15b0, size); duint32 chunkSize = 0x15b0 < size ? 0x15b0 : size; size -= chunkSize; for ( duint32 i = 0; i < chunkSize; i++ ) { sum1 += *data++; sum2 += sum1; } sum1 %= 0xFFF1; sum2 %= 0xFFF1; } return ( sum2 << 0x10 ) | ( sum1 & 0xffff ); } //called: Section page map: 0x41630e3b void dwgReader18::parseSysPage( duint8 *decompSec, duint32 decompSize ) { DRW_DBG( "\nparseSysPage:\n " ); duint32 compSize = fileBuf->getRawLong32(); DRW_DBG( "Compressed size= " ); DRW_DBG( compSize ); DRW_DBG( ", " ); DRW_DBGH( compSize ); DRW_DBG( "\nCompression type= " ); DRW_DBGH( fileBuf->getRawLong32() ); DRW_DBG( "\nSection page checksum= " ); DRW_DBGH( fileBuf->getRawLong32() ); DRW_DBG( "\n" ); duint8 hdrData[20]; fileBuf->moveBitPos( -160 ); fileBuf->getBytes( hdrData, 20 ); for ( duint8 i = 16; i < 20; ++i ) hdrData[i] = 0; duint32 calcsH = checksum( 0, hdrData, 20 ); DRW_DBG( "Calc hdr checksum= " ); DRW_DBGH( calcsH ); duint8 *tmpCompSec = new duint8[compSize]; fileBuf->getBytes( tmpCompSec, compSize ); duint32 calcsD = checksum( calcsH, tmpCompSec, compSize ); DRW_DBG( "\nCalc data checksum= " ); DRW_DBGH( calcsD ); DRW_DBG( "\n" ); #ifdef DRW_DBG_DUMP for ( unsigned int i = 0, j = 0; i < compSize; i++ ) { DRW_DBGH( ( unsigned char )compSec[i] ); if ( j == 7 ) { DRW_DBG( "\n" ); j = 0; } else { DRW_DBG( ", " ); j++; } } DRW_DBG( "\n" ); #endif DRW_DBG( "decompressing " ); DRW_DBG( compSize ); DRW_DBG( " bytes in " ); DRW_DBG( decompSize ); DRW_DBG( " bytes\n" ); dwgCompressor comp; comp.decompress18( tmpCompSec, decompSec, compSize, decompSize ); #ifdef DRW_DBG_DUMP for ( unsigned int i = 0, j = 0; i < decompSize; i++ ) { DRW_DBGH( decompSec[i] ); if ( j == 7 ) { DRW_DBG( "\n" ); j = 0; } else { DRW_DBG( ", " ); j++; } } DRW_DBG( "\n" ); #endif delete[]tmpCompSec; } //called ???: Section map: 0x4163003b bool dwgReader18::parseDataPage( dwgSectionInfo si/*, duint8 *dData*/ ) { DRW_DBG( "\nparseDataPage\n " ); objData = new duint8 [si.pageCount * si.maxSize]; for ( std::map::iterator it = si.pages.begin(); it != si.pages.end(); ++it ) { dwgPageInfo pi = it->second; if ( !fileBuf->setPosition( pi.address ) ) return false; //decript section header duint8 hdrData[32]; fileBuf->getBytes( hdrData, 32 ); dwgCompressor::decrypt18Hdr( hdrData, 32, pi.address ); DRW_DBG( "Section " ); DRW_DBG( si.name ); DRW_DBG( " page header=\n" ); for ( unsigned int i = 0, j = 0; i < 32; i++ ) { DRW_DBGH( ( unsigned char )hdrData[i] ); if ( j == 7 ) { DRW_DBG( "\n" ); j = 0; } else { DRW_DBG( ", " ); j++; } } DRW_DBG( "\n" ); DRW_DBG( "\n Page number= " ); DRW_DBGH( pi.Id ); DRW_DBG( "\n size in file= " ); DRW_DBGH( pi.size ); DRW_DBG( "\n address in file= " ); DRW_DBGH( pi.address ); DRW_DBG( "\n Data size= " ); DRW_DBGH( pi.dataSize ); DRW_DBG( "\n Start offset= " ); DRW_DBGH( pi.startOffset ); DRW_DBG( "\n" ); dwgBuffer bufHdr( hdrData, 32, &decoder ); DRW_DBG( " section page type= " ); DRW_DBGH( bufHdr.getRawLong32() ); DRW_DBG( "\n section number= " ); DRW_DBGH( bufHdr.getRawLong32() ); pi.cSize = bufHdr.getRawLong32(); DRW_DBG( "\n data size (compressed)= " ); DRW_DBGH( pi.cSize ); DRW_DBG( " dec " ); DRW_DBG( pi.cSize ); pi.uSize = bufHdr.getRawLong32(); DRW_DBG( "\n page size (decompressed)= " ); DRW_DBGH( pi.uSize ); DRW_DBG( " dec " ); DRW_DBG( pi.uSize ); DRW_DBG( "\n start offset (in decompressed buffer)= " ); DRW_DBGH( bufHdr.getRawLong32() ); DRW_DBG( "\n unknown= " ); DRW_DBGH( bufHdr.getRawLong32() ); DRW_DBG( "\n header checksum= " ); DRW_DBGH( bufHdr.getRawLong32() ); DRW_DBG( "\n data checksum= " ); DRW_DBGH( bufHdr.getRawLong32() ); DRW_DBG( "\n" ); //get compressed data duint8 *cData = new duint8[pi.cSize]; if ( !fileBuf->setPosition( pi.address + 32 ) ) { delete [] cData; return false; } fileBuf->getBytes( cData, pi.cSize ); //calculate checksum duint32 calcsD = checksum( 0, cData, pi.cSize ); for ( duint8 i = 24; i < 28; ++i ) hdrData[i] = 0; duint32 calcsH = checksum( calcsD, hdrData, 32 ); DRW_DBG( "Calc header checksum= " ); DRW_DBGH( calcsH ); DRW_DBG( "\nCalc data checksum= " ); DRW_DBGH( calcsD ); DRW_DBG( "\n" ); duint8 *oData = objData + pi.startOffset; pi.uSize = si.maxSize; DRW_DBG( "decompressing " ); DRW_DBG( pi.cSize ); DRW_DBG( " bytes in " ); DRW_DBG( pi.uSize ); DRW_DBG( " bytes\n" ); dwgCompressor comp; comp.decompress18( cData, oData, pi.cSize, pi.uSize ); delete[]cData; } return true; } bool dwgReader18::readMetaData() { version = parent->getVersion(); decoder.setVersion( version, false ); DRW_DBG( "dwgReader18::readMetaData\n" ); if ( ! fileBuf->setPosition( 11 ) ) return false; maintenanceVersion = fileBuf->getRawChar8(); DRW_DBG( "maintenance version= " ); DRW_DBGH( maintenanceVersion ); DRW_DBG( "\nbyte at 0x0C= " ); DRW_DBGH( fileBuf->getRawChar8() ); previewImagePos = fileBuf->getRawLong32(); //+ page header size (0x20). DRW_DBG( "\npreviewImagePos (seekerImageData) = " ); DRW_DBG( previewImagePos ); DRW_DBG( "\napp Dwg version= " ); DRW_DBGH( fileBuf->getRawChar8() ); DRW_DBG( ", " ); DRW_DBG( "\napp maintenance version= " ); DRW_DBGH( fileBuf->getRawChar8() ); duint16 cp = fileBuf->getRawShort16(); DRW_DBG( "\ncodepage= " ); DRW_DBG( cp ); if ( cp == 30 ) decoder.setCodePage( "ANSI_1252", false ); DRW_DBG( "\n3 0x00 bytes(seems 0x00, appDwgV & appMaintV) = " ); DRW_DBGH( fileBuf->getRawChar8() ); DRW_DBG( ", " ); DRW_DBGH( fileBuf->getRawChar8() ); DRW_DBG( ", " ); DRW_DBGH( fileBuf->getRawChar8() ); securityFlags = fileBuf->getRawLong32(); DRW_DBG( "\nsecurity flags= " ); DRW_DBG( securityFlags ); // UNKNOWN SECTION 4 bytes duint32 uk = fileBuf->getRawLong32(); DRW_DBG( "\nUNKNOWN SECTION ( 4 bytes) = " ); DRW_DBG( uk ); duint32 sumInfoAddr = fileBuf->getRawLong32(); DRW_DBG( "\nsummary Info Address= " ); DRW_DBG( sumInfoAddr ); duint32 vbaAdd = fileBuf->getRawLong32(); DRW_DBG( "\nVBA address= " ); DRW_DBGH( vbaAdd ); DRW_DBG( "\npos 0x28 are 0x00000080= " ); DRW_DBGH( fileBuf->getRawLong32() ); DRW_DBG( "\n" ); return true; } bool dwgReader18::readFileHeader() { if ( ! fileBuf->setPosition( 0x80 ) ) return false; // genMagicNumber(); DBG("\n"); DBG("\n"); DRW_DBG( "Encrypted Header Data=\n" ); duint8 byteStr[0x6C]; int size = 0x6C; for ( int i = 0, j = 0; i < 0x6C; i++ ) { duint8 ch = fileBuf->getRawChar8(); DRW_DBGH( ch ); if ( j == 15 ) { DRW_DBG( "\n" ); j = 0; } else { DRW_DBG( ", " ); j++; } byteStr[i] = DRW_magicNum18[i] ^ ch; } DRW_DBG( "\n" ); // size =0x6C; DRW_DBG( "Decrypted Header Data=\n" ); for ( int i = 0, j = 0; i < size; i++ ) { DRW_DBGH( ( unsigned char )byteStr[i] ); if ( j == 15 ) { DRW_DBG( "\n" ); j = 0; } else { DRW_DBG( ", " ); j++; } } dwgBuffer buff( byteStr, 0x6C, &decoder ); std::string name = reinterpret_cast( byteStr ); DRW_DBG( "\nFile ID string (AcFssFcAJMB)= " ); DRW_DBG( name.c_str() ); //ID string + nullptr = 12 buff.setPosition( 12 ); DRW_DBG( "\n0x00 long= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\n0x6c long= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\n0x04 long= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nRoot tree node gap= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nLowermost left tree node gap= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nLowermost right tree node gap= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nUnknown long (1)= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nLast section page Id= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nLast section page end address 64b= " ); DRW_DBGH( buff.getRawLong64() ); DRW_DBG( "\nStart of second header data address 64b= " ); DRW_DBGH( buff.getRawLong64() ); DRW_DBG( "\nGap amount= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nSection page amount= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\n0x20 long= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\n0x80 long= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\n0x40 long= " ); DRW_DBGH( buff.getRawLong32() ); dint32 secPageMapId = buff.getRawLong32(); DRW_DBG( "\nSection Page Map Id= " ); DRW_DBGH( secPageMapId ); duint64 secPageMapAddr = buff.getRawLong64() + 0x100; DRW_DBG( "\nSection Page Map address 64b= " ); DRW_DBGH( secPageMapAddr ); DRW_DBG( "\nSection Page Map address 64b dec= " ); DRW_DBG( secPageMapAddr ); duint32 secMapId = buff.getRawLong32(); DRW_DBG( "\nSection Map Id= " ); DRW_DBGH( secMapId ); DRW_DBG( "\nSection page array size= " ); DRW_DBGH( buff.getRawLong32() ); DRW_DBG( "\nGap array size= " ); DRW_DBGH( buff.getRawLong32() ); //TODO: verify CRC DRW_DBG( "\nCRC32= " ); DRW_DBGH( buff.getRawLong32() ); for ( duint8 i = 0x68; i < 0x6c; ++i ) byteStr[i] = '\0'; // byteStr[i] = '\0'; duint32 crcCalc = buff.crc32( 0x00, 0, 0x6C ); DRW_DBG( "\nCRC32 calculated= " ); DRW_DBGH( crcCalc ); DRW_DBG( "\nEnd Encrypted Data. Reads 0x14 bytes, equal to magic number:\n" ); for ( int i = 0, j = 0; i < 0x14; i++ ) { DRW_DBG( "magic num: " ); DRW_DBGH( ( unsigned char )DRW_magicNumEnd18[i] ); DRW_DBG( ",read " ); DRW_DBGH( ( unsigned char )fileBuf->getRawChar8() ); if ( j == 3 ) { DRW_DBG( "\n" ); j = 0; } else { DRW_DBG( ", " ); j++; } } // At this point are parsed the first 256 bytes DRW_DBG( "\nJump to Section Page Map address: " ); DRW_DBGH( secPageMapAddr ); if ( ! fileBuf->setPosition( secPageMapAddr ) ) return false; duint32 pageType = fileBuf->getRawLong32(); DRW_DBG( "\nSection page type= " ); DRW_DBGH( pageType ); duint32 decompSize = fileBuf->getRawLong32(); DRW_DBG( "\nDecompressed size= " ); DRW_DBG( decompSize ); DRW_DBG( ", " ); DRW_DBGH( decompSize ); if ( pageType != 0x41630e3b ) { //bad page type, ends DRW_DBG( "Warning, bad page type, was expected 0x41630e3b instead of" ); DRW_DBGH( pageType ); DRW_DBG( "\n" ); return false; } duint8 *tmpDecompSec = new duint8[decompSize]; parseSysPage( tmpDecompSec, decompSize ); //parses "Section page map" decompressed data dwgBuffer buff2( tmpDecompSec, decompSize, &decoder ); duint32 address = 0x100; //stores temporaly info of all pages: std::mapsectionPageMapTmp; for ( unsigned int i = 0; i < decompSize; ) { dint32 id = buff2.getRawLong32();//RLZ bad can be +/- duint32 size = buff2.getRawLong32(); i += 8; DRW_DBG( "Page num= " ); DRW_DBG( id ); DRW_DBG( " size= " ); DRW_DBGH( size ); DRW_DBG( " address= " ); DRW_DBGH( address ); DRW_DBG( "\n" ); //TODO num can be negative indicating gap // duint64 ind = id > 0 ? id : -id; if ( id < 0 ) { DRW_DBG( "Parent= " ); DRW_DBG( buff2.getRawLong32() ); DRW_DBG( "\nLeft= " ); DRW_DBG( buff2.getRawLong32() ); DRW_DBG( ", Right= " ); DRW_DBG( buff2.getRawLong32() ); DRW_DBG( ", 0x00= " ); DRW_DBGH( buff2.getRawLong32() ); DRW_DBG( "\n" ); i += 16; } sectionPageMapTmp[id] = dwgPageInfo( id, address, size ); address += size; } delete[]tmpDecompSec; DRW_DBG( "\n*** dwgReader18: Processing Data Section Map ***\n" ); dwgPageInfo sectionMap = sectionPageMapTmp[secMapId]; if ( !fileBuf->setPosition( sectionMap.address ) ) return false; pageType = fileBuf->getRawLong32(); DRW_DBG( "\nSection page type= " ); DRW_DBGH( pageType ); decompSize = fileBuf->getRawLong32(); DRW_DBG( "\nDecompressed size= " ); DRW_DBG( decompSize ); DRW_DBG( ", " ); DRW_DBGH( decompSize ); if ( pageType != 0x4163003b ) { //bad page type, ends DRW_DBG( "Warning, bad page type, was expected 0x4163003b instead of" ); DRW_DBGH( pageType ); DRW_DBG( "\n" ); return false; } tmpDecompSec = new duint8[decompSize]; parseSysPage( tmpDecompSec, decompSize ); //reads sections: DRW_DBG( "\n*** dwgReader18: reads sections:" ); dwgBuffer buff3( tmpDecompSec, decompSize, &decoder ); duint32 numDescriptions = buff3.getRawLong32(); DRW_DBG( "\nnumDescriptions (sections)= " ); DRW_DBG( numDescriptions ); DRW_DBG( "\n0x02 long= " ); DRW_DBGH( buff3.getRawLong32() ); DRW_DBG( "\n0x00007400 long= " ); DRW_DBGH( buff3.getRawLong32() ); DRW_DBG( "\n0x00 long= " ); DRW_DBGH( buff3.getRawLong32() ); DRW_DBG( "\nunknown long (numDescriptions?)= " ); DRW_DBG( buff3.getRawLong32() ); DRW_DBG( "\n" ); for ( unsigned int i = 0; i < numDescriptions; i++ ) { dwgSectionInfo secInfo; secInfo.size = buff3.getRawLong64(); DRW_DBG( "\nSize of section= " ); DRW_DBGH( secInfo.size ); secInfo.pageCount = buff3.getRawLong32(); DRW_DBG( "\nPage count= " ); DRW_DBGH( secInfo.pageCount ); secInfo.maxSize = buff3.getRawLong32(); DRW_DBG( "\nMax Decompressed Size= " ); DRW_DBGH( secInfo.maxSize ); DRW_DBG( "\nunknown long= " ); DRW_DBGH( buff3.getRawLong32() ); secInfo.compressed = buff3.getRawLong32(); DRW_DBG( "\nis Compressed? 1:no, 2:yes= " ); DRW_DBGH( secInfo.compressed ); secInfo.Id = buff3.getRawLong32(); DRW_DBG( "\nSection Id= " ); DRW_DBGH( secInfo.Id ); secInfo.encrypted = buff3.getRawLong32(); //encrypted (doc: 0 no, 1 yes, 2 unkn) on read: objects 0 and encrypted yes DRW_DBG( "\nEncrypted= " ); DRW_DBGH( secInfo.encrypted ); duint8 nameCStr[64]; buff3.getBytes( nameCStr, 64 ); secInfo.name = reinterpret_cast( nameCStr ); DRW_DBG( "\nSection std::Name= " ); DRW_DBG( secInfo.name.c_str() ); DRW_DBG( "\n" ); for ( unsigned int i = 0; i < secInfo.pageCount; i++ ) { duint32 pn = buff3.getRawLong32(); dwgPageInfo pi = sectionPageMapTmp[pn]; //get a copy DRW_DBG( " reading pag num = " ); DRW_DBGH( pn ); pi.dataSize = buff3.getRawLong32(); pi.startOffset = buff3.getRawLong64(); secInfo.pages[pn] = pi;//complete copy in secInfo DRW_DBG( "\n Page number= " ); DRW_DBGH( secInfo.pages[pn].Id ); DRW_DBG( "\n size in file= " ); DRW_DBGH( secInfo.pages[pn].size ); DRW_DBG( "\n address in file= " ); DRW_DBGH( secInfo.pages[pn].address ); DRW_DBG( "\n Data size= " ); DRW_DBGH( secInfo.pages[pn].dataSize ); DRW_DBG( "\n Start offset= " ); DRW_DBGH( secInfo.pages[pn].startOffset ); DRW_DBG( "\n" ); } //do not save empty section if ( !secInfo.name.empty() ) { DRW_DBG( "Saved section Name= " ); DRW_DBG( secInfo.name.c_str() ); DRW_DBG( "\n" ); sections[secEnum::getEnum( secInfo.name )] = secInfo; } } delete[]tmpDecompSec; if ( ! fileBuf->isGood() ) return false; DRW_DBG( "\ndwgReader18::readFileHeader END\n\n" ); return true; } bool dwgReader18::readDwgHeader( DRW_Header &hdr ) { DRW_DBG( "dwgReader18::readDwgHeader\n" ); dwgSectionInfo si = sections[secEnum::HEADER]; if ( si.Id < 0 )//not found, ends return false; bool ret = parseDataPage( si/*, objData*/ ); //global store for uncompressed data of all pages uncompSize = si.size; if ( ret ) { dwgBuffer dataBuf( objData, si.size, &decoder ); DRW_DBG( "Header section sentinel= " ); checkSentinel( &dataBuf, secEnum::HEADER, true ); if ( version == DRW::AC1018 ) { ret = dwgReader::readDwgHeader( hdr, &dataBuf, &dataBuf ); } else { dwgBuffer handleBuf( objData, si.size, &decoder ); ret = dwgReader::readDwgHeader( hdr, &dataBuf, &handleBuf ); } } //Cleanup: global store for uncompressed data of all pages if ( objData ) { delete[] objData; objData = nullptr; } return ret; } bool dwgReader18::readDwgClasses() { DRW_DBG( "\ndwgReader18::readDwgClasses\n" ); dwgSectionInfo si = sections[secEnum::CLASSES]; if ( si.Id < 0 )//not found, ends return false; bool ret = parseDataPage( si/*, objData*/ ); //global store for uncompressed data of all pages uncompSize = si.size; if ( ret ) { dwgBuffer dataBuf( objData, uncompSize, &decoder ); DRW_DBG( "classes section sentinel= " ); checkSentinel( &dataBuf, secEnum::CLASSES, true ); duint32 size = dataBuf.getRawLong32(); DRW_DBG( "\ndata size in bytes " ); DRW_DBG( size ); if ( version > DRW::AC1021 && maintenanceVersion > 3 ) //2010+ { duint32 hSize = dataBuf.getRawLong32(); DRW_DBG( "\n2010+ & MV> 3, height 32b: " ); DRW_DBG( hSize ); } duint32 bitSize = 0; if ( version > DRW::AC1021 ) //2007+ { bitSize = dataBuf.getRawLong32(); DRW_DBG( "\ntotal size in bits " ); DRW_DBG( bitSize ); } duint32 maxClassNum = dataBuf.getBitShort(); DRW_DBG( "\nMaximum class number " ); DRW_DBG( maxClassNum ); DRW_DBG( "\nRc 1 " ); DRW_DBG( dataBuf.getRawChar8() ); DRW_DBG( "\nRc 2 " ); DRW_DBG( dataBuf.getRawChar8() ); DRW_DBG( "\nBit " ); DRW_DBG( dataBuf.getBit() ); /*******************************/ dwgBuffer *strBuf = &dataBuf; dwgBuffer strBuff( objData, uncompSize, &decoder ); //prepare string stream for 2007+ if ( version > DRW::AC1021 ) //2007+ { strBuf = &strBuff; duint32 strStartPos = bitSize + 191;//size in bits + 24 bytes (sn+size+hSize) - 1 bit (endbit) DRW_DBG( "\nstrStartPos: " ); DRW_DBG( strStartPos ); strBuff.setPosition( strStartPos >> 3 ); strBuff.setBitPos( strStartPos & 7 ); DRW_DBG( "\nclasses strings buff.getPosition: " ); DRW_DBG( strBuff.getPosition() ); DRW_DBG( "\nclasses strings buff.getBitPos: " ); DRW_DBG( strBuff.getBitPos() ); DRW_DBG( "\nendBit " ); DRW_DBG( strBuff.getBit() ); strStartPos -= 16;//decrement 16 bits DRW_DBG( "\nstrStartPos: " ); DRW_DBG( strStartPos ); strBuff.setPosition( strStartPos >> 3 ); strBuff.setBitPos( strStartPos & 7 ); DRW_DBG( "\nclasses strings buff.getPosition: " ); DRW_DBG( strBuff.getPosition() ); DRW_DBG( "\nclasses strings buff.getBitPos: " ); DRW_DBG( strBuff.getBitPos() ); duint32 strDataSize = strBuff.getRawShort16(); DRW_DBG( "\nstrDataSize: " ); DRW_DBG( strDataSize ); if ( strDataSize & 0x8000 ) { strStartPos -= 16;//decrement 16 bits strDataSize &= 0x7FFF; //strip 0x8000; strBuff.setPosition( strStartPos >> 3 ); strBuff.setBitPos( strStartPos & 7 ); duint32 hiSize = strBuff.getRawShort16(); strDataSize |= ( hiSize << 15 ); } strStartPos -= strDataSize; DRW_DBG( "\nstrStartPos: " ); DRW_DBG( strStartPos ); strBuff.setPosition( strStartPos >> 3 ); strBuff.setBitPos( strStartPos & 7 ); DRW_DBG( "\nclasses strings buff.getPosition: " ); DRW_DBG( strBuff.getPosition() ); DRW_DBG( "\nclasses strings buff.getBitPos: " ); DRW_DBG( strBuff.getBitPos() ); } /*******************************/ duint32 endDataPos = maxClassNum - 499; DRW_DBG( "\nbuff.getPosition: " ); DRW_DBG( dataBuf.getPosition() ); for ( duint32 i = 0; i < endDataPos; i++ ) { DRW_Class *cl = new DRW_Class(); cl->parseDwg( version, &dataBuf, strBuf ); classesmap[cl->classNum] = cl; DRW_DBG( "\nbuff.getPosition: " ); DRW_DBG( dataBuf.getPosition() ); } DRW_DBG( "\nend classes data buff.getPosition: " ); DRW_DBG( dataBuf.getPosition() ); DRW_DBG( "\nend classes data buff.getBitPos: " ); DRW_DBG( dataBuf.getBitPos() ); DRW_DBG( "\nend classes strings buff.getPosition: " ); DRW_DBG( strBuf->getPosition() ); DRW_DBG( "\nend classes strings buff.getBitPos: " ); DRW_DBG( strBuf->getBitPos() ); /***************/ strBuf->setPosition( strBuf->getPosition() + 1 );//skip remaining bits DRW_DBG( "\nCRC: " ); DRW_DBGH( strBuf->getRawShort16() ); if ( version > DRW::AC1018 ) { DRW_DBG( "\nunknown CRC: " ); DRW_DBGH( strBuf->getRawShort16() ); } DRW_DBG( "\nclasses section end sentinel= " ); checkSentinel( strBuf, secEnum::CLASSES, false ); ret = strBuf->isGood(); } //Cleanup: global store for uncompressed data of all pages if ( objData ) { delete[] objData; objData = nullptr; } return ret; } /*********** objects map ************************/ /** Note: object map are split in sections with max size 2035? * heach section are 2 bytes size + data bytes + 2 bytes crc * size value are data bytes + 2 and to calculate crc are used * 2 bytes size + data bytes * last section are 2 bytes size + 2 bytes crc (size value always 2) **/ bool dwgReader18::readDwgHandles() { DRW_DBG( "\ndwgReader18::readDwgHandles\n" ); dwgSectionInfo si = sections[secEnum::HANDLES]; if ( si.Id < 0 )//not found, ends return false; bool ret = parseDataPage( si ); //global store for uncompressed data of all pages uncompSize = si.size; if ( ret ) { dwgBuffer dataBuf( objData, uncompSize, &decoder ); ret = dwgReader::readDwgHandles( &dataBuf, 0, si.size ); } //Cleanup: global store for uncompressed data of all pages if ( objData ) { delete[] objData; objData = nullptr; uncompSize = 0; } return ret; } /*********** objects ************************/ /** * Reads all the object referenced in the object map section of the DWG file * (using their object file offsets) */ bool dwgReader18::readDwgTables( DRW_Header &hdr ) { DRW_DBG( "\ndwgReader18::readDwgTables\n" ); dwgSectionInfo si = sections[secEnum::OBJECTS]; if ( si.Id < 0 )//not found, ends return false; bool ret = parseDataPage( si/*, objData*/ ); //global store for uncompressed data of all pages uncompSize = si.size; if ( ret ) { dwgBuffer dataBuf( objData, uncompSize, &decoder ); ret = dwgReader::readDwgTables( hdr, &dataBuf ); } //Do not delete objData in this point, needed in the remaining code return ret; }