1
2 /******************************************************************************
3 ** libDXFrw - Library to read/write DXF files (ascii & binary) **
4 ** **
5 ** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com **
6 ** **
7 ** This library is free software, licensed under the terms of the GNU **
8 ** General Public License as published by the Free Software Foundation, **
9 ** either version 2 of the License, or (at your option) any later version. **
10 ** You should have received a copy of the GNU General Public License **
11 ** along with this program. If not, see <http://www.gnu.org/licenses/>. **
12 ******************************************************************************/
13
14 #include <cstdlib>
15 #include <iostream>
16 #include <fstream>
17 #include <string>
18 #include <sstream>
19
20 #include "dwgreader15.h"
21 #include "drw_textcodec.h"
22
23 #include "../libdwgr.h"
24
25 #include "qgslogger.h"
26
readMetaData()27 bool dwgReader15::readMetaData()
28 {
29 QgsDebugMsg( "Entering." );
30 version = parent->getVersion();
31 decoder.setVersion( version, false );
32
33 if ( ! fileBuf->setPosition( 13 ) )
34 return false;
35 previewImagePos = fileBuf->getRawLong32();
36 QgsDebugMsg( QString( "previewImagePos (seekerImageData) = %1" ).arg( previewImagePos ) );
37 /* MEASUREMENT system variable 2 bytes*/
38 duint16 meas = fileBuf->getRawShort16();
39 QgsDebugMsg( QString( "MEASUREMENT (0 = English, 1 = Metric)= %1" ).arg( meas ) );
40 Q_UNUSED( meas );
41 duint16 cp = fileBuf->getRawShort16();
42 QgsDebugMsg( QString( "codepage= %1" ).arg( cp ) );
43
44 if ( cp == 29 ) //TODO RLZ: locate wath code page and correct this
45 decoder.setCodePage( "ANSI_1252", false );
46 if ( cp == 30 )
47 decoder.setCodePage( "ANSI_1252", false );
48 return true;
49 }
50
readFileHeader()51 bool dwgReader15::readFileHeader()
52 {
53 QgsDebugMsg( "Entering." );
54 bool ret = true;
55 if ( ! fileBuf->setPosition( 21 ) )
56 return false;
57 duint32 count = fileBuf->getRawLong32();
58 QgsDebugMsg( QString( "count records=%1" ).arg( count ) );
59
60 for ( unsigned int i = 0; i < count; i++ )
61 {
62 duint8 rec = fileBuf->getRawChar8();
63 duint32 address = fileBuf->getRawLong32();
64 duint32 size = fileBuf->getRawLong32();
65 dwgSectionInfo si;
66 si.Id = rec;
67 si.size = size;
68 si.address = address;
69 if ( rec == 0 )
70 {
71 QgsDebugMsg( QString( "Section HEADERS address=%1 size=%2" ).arg( address ).arg( size ) );
72 sections[secEnum::HEADER] = si;
73 }
74 else if ( rec == 1 )
75 {
76 QgsDebugMsg( QString( "Section CLASSES address=%1 size=%2" ).arg( address ).arg( size ) );
77 sections[secEnum::CLASSES] = si;
78 }
79 else if ( rec == 2 )
80 {
81 QgsDebugMsg( QString( "Section OBJECTS (handles) address=%1 size=%2" ).arg( address ).arg( size ) );
82 sections[secEnum::HANDLES] = si;
83 }
84 else if ( rec == 3 )
85 {
86 QgsDebugMsg( QString( "Section UNKNOWN address=%1 size=%2" ).arg( address ).arg( size ) );
87 sections[secEnum::UNKNOWNS] = si;
88 }
89 else if ( rec == 4 )
90 {
91 QgsDebugMsg( QString( "Section R14DATA (AcDb::Template) address=%1 size=%2" ).arg( address ).arg( size ) );
92 sections[secEnum::TEMPLATE] = si;
93 }
94 else if ( rec == 5 )
95 {
96 QgsDebugMsg( QString( "Section R14REC5 (AcDb::AuxHeader) address=%1 size=%2" ).arg( address ).arg( size ) );
97 sections[secEnum::AUXHEADER] = si;
98 }
99 else
100 {
101 std::cerr << "\nUnsupported section number\n";
102 }
103 }
104 if ( ! fileBuf->isGood() )
105 return false;
106
107 QgsDebugMsg( QString( "position after read section locator records=%1, bit are=%2" ).arg( fileBuf->getPosition() ).arg( fileBuf->getBitPos() ) );
108 duint32 ckcrc = fileBuf->crc8( 0, 0, fileBuf->getPosition() );
109 QgsDebugMsg( QString( "file header crc8 0 result=%1" ).arg( ckcrc ) );
110 switch ( count )
111 {
112 case 3:
113 ckcrc = ckcrc ^ 0xA598;
114 break;
115 case 4:
116 ckcrc = ckcrc ^ 0x8101;
117 break;
118 case 5:
119 ckcrc = ckcrc ^ 0x3CC4;
120 break;
121 case 6:
122 ckcrc = ckcrc ^ 0x8461;
123 }
124
125 int headercrc = fileBuf->getRawShort16();
126 QgsDebugMsg( QString( "file header crc8 xor result=%1, file header CRC=%2" ).arg( ckcrc ).arg( headercrc ) );
127 Q_UNUSED( headercrc );
128
129 checkSentinel( fileBuf, secEnum::FILEHEADER, false );
130
131 QgsDebugMsg( QString( "position after read file header sentinel=%1, bit pos=%2" ).arg( fileBuf->getPosition() ).arg( fileBuf->getBitPos() ) );
132
133 QgsDebugMsg( "Leaving." );
134
135 return ret;
136 }
137
readDwgHeader(DRW_Header & hdr)138 bool dwgReader15::readDwgHeader( DRW_Header &hdr )
139 {
140 QgsDebugMsg( "Entering." );
141
142 dwgSectionInfo si = sections[secEnum::HEADER];
143 if ( si.Id < 0 )//not found, ends
144 return false;
145 if ( !fileBuf->setPosition( si.address ) )
146 return false;
147 duint8 *tmpByteStr = new duint8[si.size];
148 fileBuf->getBytes( tmpByteStr, si.size );
149 dwgBuffer buff( tmpByteStr, si.size, &decoder );
150
151 QgsDebugMsg( "checksentinel" );
152 checkSentinel( &buff, secEnum::HEADER, true );
153 bool ret = dwgReader::readDwgHeader( hdr, &buff, &buff );
154 delete[]tmpByteStr;
155 return ret;
156 }
157
158
readDwgClasses()159 bool dwgReader15::readDwgClasses()
160 {
161 QgsDebugMsg( "Entering." );
162
163 dwgSectionInfo si = sections[secEnum::CLASSES];
164 if ( si.Id < 0 )//not found, ends
165 return false;
166 if ( !fileBuf->setPosition( si.address ) )
167 return false;
168
169 QgsDebugMsg( "classes section sentinel" );
170 checkSentinel( fileBuf, secEnum::CLASSES, true );
171
172 duint32 size = fileBuf->getRawLong32();
173 if ( size != ( si.size - 38 ) )
174 {
175 QgsDebugMsg( QString( "size is %1 and secSize - 38 are %1" ).arg( size ).arg( si.size - 38 ) );
176 }
177 duint8 *tmpByteStr = new duint8[size];
178 fileBuf->getBytes( tmpByteStr, size );
179 dwgBuffer buff( tmpByteStr, size, &decoder );
180 size--; //reduce 1 byte instead of check pos + bitPos
181 while ( size > buff.getPosition() )
182 {
183 DRW_Class *cl = new DRW_Class();
184 cl->parseDwg( version, &buff, &buff );
185 classesmap[cl->classNum] = cl;
186 }
187 int crc = fileBuf->getRawShort16();
188 QgsDebugMsg( QString( "crc=%1, classes section end sentinel" ).arg( crc ) );
189 Q_UNUSED( crc );
190
191 checkSentinel( fileBuf, secEnum::CLASSES, false );
192
193 bool ret = buff.isGood();
194 delete[]tmpByteStr;
195 return ret;
196 }
197
readDwgHandles()198 bool dwgReader15::readDwgHandles()
199 {
200 QgsDebugMsg( "Entering." );
201 dwgSectionInfo si = sections[secEnum::HANDLES];
202 if ( si.Id < 0 )//not found, ends
203 return false;
204
205 bool ret = dwgReader::readDwgHandles( fileBuf, si.address, si.size );
206 return ret;
207 }
208
209 /*********** objects ************************/
210
211 /**
212 * Reads all the object referenced in the object map section of the DWG file
213 * (using their object file offsets)
214 */
readDwgTables(DRW_Header & hdr)215 bool dwgReader15::readDwgTables( DRW_Header &hdr )
216 {
217 bool ret = dwgReader::readDwgTables( hdr, fileBuf );
218
219 return ret;
220 }
221
222 /**
223 * Reads all the object referenced in the object map section of the DWG file
224 * (using their object file offsets)
225 */
readDwgBlocks(DRW_Interface & intfa)226 bool dwgReader15::readDwgBlocks( DRW_Interface &intfa )
227 {
228 bool ret = true;
229 ret = dwgReader::readDwgBlocks( intfa, fileBuf );
230 return ret;
231 }
232
233