QGIS/external/libdxfrw/intern/dwgreader18.cpp
Nyall Dawson 507ba861ea Resync some libdxfrw files with upstream
Minor code formatting changes only -- no fixes
2021-08-10 05:13:08 +10:00

600 lines
24 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 <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#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<duint8>(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("decompresing "); 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<duint32, dwgPageInfo>::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 compresed 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("decompresing "); 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 verion= "); 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("Encripted 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("Decripted 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<char*>(byteStr);
DRW_DBG("\nFile ID string (AcFssFcAJMB)= "); DRW_DBG(name.c_str());
//ID string + NULL = 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" decompresed data
dwgBuffer buff2(tmpDecompSec, decompSize, &decoder);
duint32 address = 0x100;
//stores temporaly info of all pages:
std::map<duint32, dwgPageInfo >sectionPageMapTmp;
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<char*>(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 != NULL){
delete[] objData;
objData = NULL;
}
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, higth 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 != NULL){
delete[] objData;
objData = NULL;
}
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 != NULL){
delete[] objData;
objData = NULL;
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;
}