1 {
2 *****************************************************************************
3 * *
4 * This file is part of the ZCAD *
5 * *
6 * See the file COPYING.modifiedLGPL.txt, included in this distribution, *
7 * for details about the copyright. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
12 * *
13 *****************************************************************************
14 }
15 {
16 @author(Andrey Zubarev <zamtmn@yandex.ru>)
17 }
18
19 unit uzeffdwg;
20 {$INCLUDE def.inc}
21 {$MODE OBJFPC}
22 interface
23 uses LCLIntf,gdbentityfactory,zcadinterface,GDBLine,gdbobjectsconstdef,typinfo,
24 zcadstrconsts,iodxf,fileutil,varman,uzegeometry,uzcshared,gdbasetypes,//log,
25 GDBGenericSubEntry,SysInfo,gdbase, GDBManager, sysutils, memman,UGDBDescriptor,
26 UGDBOpenArrayOfByte,GDBEntity,TypeDescriptors,ugdbsimpledrawing;
27 procedure addfromdwg(name: GDBString;owner:PGDBObjGenericSubEntry;LoadMode:TLoadOpt;var drawing:TSimpleDrawing);
28 implementation
29 uses {GDBBlockDef,}UGDBLayerArray,fileformatsmanager;
30
31 type
32 PDWGByte=^DWGByte;
33 DWGByte=byte;
34 DWGLong=DWord;
35 DWG2Long=QWord;
36
37 DWGWord=word;
38 pdwg2004header=^dwg2004header;
39 dwg2004header=packed record
40 versionstring:packed array[1..6]of ansichar;
41 _bytes1:packed array[1..5]of DWGByte;
42 MaintenanceReleaseVersion:DWGByte;
43 _byte2:DWGByte;
44 PreviewAdress:DWGLong;
45 ApplicationDWGVersion:DWGByte;
46 ApplicationMaintenanceReleaseVersion:DWGByte;
47 CodePage:DWGWord;
48 _bytes3_000000:packed array[1..3]of DWGByte;
49 SecurityFlag:DWGLong;
50 UnknownLong1:DWGLong;
51 SummaryInfoAdress:DWGLong;
52 VBAProjectAdress:DWGLong;
53 _0x00000080:DWGLong;
54 _bytes4:packed array[1..$54]of DWGByte;
55 EncryptedData:packed array[1..$6c]of DWGByte;
56 end;
57 pdwg2004headerdecrypteddata=^dwg2004headerdecrypteddata;
58 dwg2004headerdecrypteddata=packed record
59 FileIDString:packed array[1..12]of ansichar;
60 _0x00:DWGLong;
61 _0x6c:DWGLong;
62 _0x04:DWGLong;
63 RootTreeNodeGap:DWGLong;
64 LowerMostLeftTreeNodeGap:DWGLong;
65 LowerMostRightTreeNodeGap:DWGLong;
66 UnknownLong1_0x01:DWGLong;
67 LastSectionPageID:DWGLong;
68 LastSectionPageEndAdress:DWG2Long;
69 SecondHeaderAdress:DWG2Long;
70 GapAmount:DWGLong;
71 SectionPageAmount:DWGLong;
72 _0x20:DWGLong;
73 _0x80:DWGLong;
74 _0x40:DWGLong;
75 SectionPageMapID:DWGLong;
76 SectionPageMapAdress:DWG2Long;
77 SectionInfoID:DWGLong;
78 SectionPageArraySize:DWGLong;
79 GAPArraySize:DWGLong;
80 CRC32:DWGLong;
81 Dummy:packed array[1..$14]of DWGByte;
82 end;
83 pdwg2004systemsection=^dwg2004systemsection;
84 dwg2004systemsection=packed record
85 _0x4163043b:DWGLong;
86 DecompSizeData:DWGLong;
87 CompSizeData:DWGLong;
88 CompType:DWGLong;
89 Checksum:DWGLong;
90 end;
91 pdwg2004sectionmap=^dwg2004sectionmap;
92 dwg2004sectionmap=packed record
93 SectionNumber:DWGLong;
94 SectionSize:DWGLong;
95 end;
96 pdwg2004sectioninfo=^dwg2004sectioninfo;
97 dwg2004sectioninfo=packed record
98 NumDescriptions:DWGLong;
99 _0x02:DWGLong;
100 _0x00007400:DWGLong;
101 _0x00:DWGLong;
102 Unknown:DWGLong;
103 end;
104 pdwg2004pageinfo=^dwg2004pageinfo;
105 PTMyDWGSectionDesc=^TMyDWGSectionDesc;
106 dwg2004pageinfo=packed record
107 PageNumber:DWGLong;
108 DataSize:DWGLong;
109 StartOffset:DWG2Long;
110 section:PTMyDWGSectionDesc;
111 decompdata:pointer;
112 end;
113 mypageinfoArray=array of dwg2004pageinfo;
114 pdwg2004sectiondesc=^dwg2004sectiondesc;
115 dwg2004sectiondesc=packed record
116 SizeOfSection:DWG2Long;
117 NumberOfSectionsThisType:DWGLong;
118 MaxDecompressedSize:DWGLong;
119 Unknown2:DWGLong;
120 Compressed:DWGLong;
121 SectionType:DWGLong;
122 Encrypted:DWGLong;
123 SectionName:packed array[1..64]of ansichar;
124 end;
125 pmysectiondesc=^mysectiondesc;
126 mysectiondesc=packed record
127 SizeOfSection:DWG2Long;
128 NumberOfSectionsThisType:DWGLong;
129 MaxDecompressedSize:DWGLong;
130 Unknown2:DWGLong;
131 Compressed:DWGLong;
132 SectionType:DWGLong;
133 Encrypted:DWGLong;
134 SectionName:string;
135 pages:mypageinfoArray;
136 end;
137 mysectiondescArray=array of mysectiondesc;
138 TMyDWGSectionDesc=packed record
139 Number:DWGLong;
140 Size:DWGLong;
141 Offset:DWGLong;
142 end;
143 TMyDWGSectionDescArray=array of TMyDWGSectionDesc;
144 {
145 #define BITCODE_DOUBLE double
146
147 #define BITCODE_RC char
148 #define FORMAT_RC "%2x"
149 #define BITCODE_MC long int
150 #define FORMAT_MC "%l"
151 #define BITCODE_MS long unsigned int
152 #define FORMAT_MS "%lu"
153 #define BITCODE_B unsigned char
154 #define FORMAT_B "%d"
155 #define BITCODE_BB unsigned char
156 #define FORMAT_BB "%d"
157 #define BITCODE_BS unsigned int
158 #define FORMAT_BS "%d"
159 #define BITCODE_RS unsigned int
160 #define FORMAT_RS "%d"
161 #define BITCODE_RL long unsigned int
162 #define FORMAT_RL "%lu"
163 #define BITCODE_RD BITCODE_DOUBLE
164 #define FORMAT_RD "%f"
165 #define BITCODE_BL long unsigned int
166 #define FORMAT_BL "%lu"
167 #define BITCODE_TV unsigned char *
168 #define FORMAT_TV "\"%s\""
169 #define BITCODE_BT BITCODE_DOUBLE
170 #define FORMAT_BT "%f"
171 #define BITCODE_DD BITCODE_DOUBLE
172 #define FORMAT_DD "%f"
173 #define BITCODE_BD BITCODE_DOUBLE
174 #define FORMAT_BD "%f"
175 #define BITCODE_BE BITCODE_3BD
176 #define BITCODE_CMC Dwg_Color
177 #define BITCODE_H Dwg_Object_Ref*
178 #define BITCODE_4BITS BITCODE_RC
179 #define FORMAT_4BITS "%1x"
180 }
181 BITCODE_RL=Longword;
182 BITCODE_RS=word;
183 BITCODE_RC=byte;
184 BITCODE_MS=Longword{word};
185 BITCODE_BS=word;
186 BITCODE_H=DWGLong;
187 BITCODE_B=Boolean;
188 BITCODE_DD=double;
189 BITCODE_RD=double;
190 BITCODE_BD=double;
191 BITCODE_BL=Longword{word};
192
193 BITCODE_CMC=byte;//error--------------------------------------------
194 BITCODE_TV=string;
195
196 BITCODE_BB=byte;
197
198 barray=array [0..100] of BITCODE_RC;
199 pbarray=^barray;
200
201 bit_chain={$IFNDEF DELPHI}packed{$ENDIF} object
202 chain:PDWGByte;
203 size:DWord;
204 byte:DWord;
205 bit:DWGByte;
206 constructor init(_chain:pointer;_size:DWord);
207 procedure setto(_chain:pointer;_size:DWord);
BitRead_rcnull208 function BitRead_rc:BITCODE_RC;
BitRead_rsnull209 function BitRead_rs:BITCODE_RS;
BitRead_rlnull210 function BitRead_rl:BITCODE_RL;
BitRead_msnull211 function BitRead_ms:BITCODE_MS;
BitRead_bbnull212 function BitRead_bb:BITCODE_BB;
BitRead_bsnull213 function BitRead_bs:BITCODE_BS;
BitRead_hnull214 function BitRead_h:BITCODE_H;
BitRead_bnull215 function BitRead_b:BITCODE_B;
BitRead_rdnull216 function BitRead_rd:BITCODE_rd;
BitRead_bdnull217 function BitRead_bd:BITCODE_bd;
BitRead_ddnull218 function BitRead_dd(default_value:BITCODE_DD):BITCODE_DD;
BitRead_blnull219 function BitRead_bl:BITCODE_BL;
BitRead_CMCnull220 function BitRead_CMC:BITCODE_CMC;
BitRead_TVnull221 function BitRead_TV:BITCODE_TV;
222 procedure scroll(scrollbit:integer);
223 end;
224 TEncryptedSectionHeader=packed record
225 case byte of
226 0:(field:packed record
227 tag:DWGLong;
228 section_type:DWGLong;
229 data_size:DWGLong;
230 section_size:DWGLong;
231 start_offset:DWGLong;
232 unknown:DWGLong;
233 checksum_1:DWGLong;
234 checksum_2:DWGLong;
235 end);
236 1:(LongData:
237 array [0..7] of DWGLong);
238 2:(ByteData:
239 array [0..31] of DWGByte);
240 end;
241 const
242 SECTION_HEADER = $01;
243 SECTION_AUXHEADER = $02;
244 SECTION_CLASSES = $03;
245 SECTION_HANDLES = $04;
246 SECTION_TEMPLATE = $05;
247 SECTION_OBJFREESPACE = $06;
248 SECTION_DBOBJECTS = $07;
249 SECTION_REVHISTORY = $08;
250 SECTION_SUMMARYINFO = $09;
251 SECTION_PREVIEW = $0a;
252 SECTION_APPINFO = $0b;
253 SECTION_APPINFOHISTORY = $0c;
254 SECTION_FILEDEPLIST = $0d;
255 //SECTION_SECURITY, //
256 //SECTION_VBAPROJECT, // not seen
257 //SECTION_SIGNATURE //
258 {$TYPEINFO ON}
259 type
260 DWG_OBJECT_TYPE=(
261 DWG_TYPE_UNUSED:= $00,
262 DWG_TYPE_TEXT:= $01,
263 DWG_TYPE_ATTRIB := $02,
264 DWG_TYPE_ATTDEF := $03,
265 DWG_TYPE_BLOCK := $04,
266 DWG_TYPE_ENDBLK := $05,
267 DWG_TYPE_SEQEND := $06,
268 DWG_TYPE_INSERT := $07,
269 DWG_TYPE_MINSERT := $08,
270 //DWG_TYPE_<UNKNOWN> := $09,
271 DWG_TYPE_VERTEX_2D := $0a,
272 DWG_TYPE_VERTEX_3D := $0b,
273 DWG_TYPE_VERTEX_MESH := $0c,
274 DWG_TYPE_VERTEX_PFACE := $0d,
275 DWG_TYPE_VERTEX_PFACE_FACE := $0e,
276 DWG_TYPE_POLYLINE_2D := $0f,
277 DWG_TYPE_POLYLINE_3D := $10,
278 DWG_TYPE_ARC := $11,
279 DWG_TYPE_CIRCLE := $12,
280 DWG_TYPE_LINE := $13,
281 DWG_TYPE_DIMENSION_ORDINATE := $14,
282 DWG_TYPE_DIMENSION_LINEAR := $15,
283 DWG_TYPE_DIMENSION_ALIGNED := $16,
284 DWG_TYPE_DIMENSION_ANG3PT := $17,
285 DWG_TYPE_DIMENSION_ANG2LN := $18,
286 DWG_TYPE_DIMENSION_RADIUS := $19,
287 DWG_TYPE_DIMENSION_DIAMETER := $1A,
288 DWG_TYPE_POINT := $1b,
289 DWG_TYPE__3DFACE := $1c,
290 DWG_TYPE_POLYLINE_PFACE := $1d,
291 DWG_TYPE_POLYLINE_MESH := $1e,
292 DWG_TYPE_SOLID := $1f,
293 DWG_TYPE_TRACE := $20,
294 DWG_TYPE_SHAPE := $21,
295 DWG_TYPE_VIEWPORT := $22,
296 DWG_TYPE_ELLIPSE := $23,
297 DWG_TYPE_SPLINE := $24,
298 DWG_TYPE_REGION := $25,
299 DWG_TYPE_3DSOLID := $26,
300 DWG_TYPE_BODY := $27,
301 DWG_TYPE_RAY := $28,
302 DWG_TYPE_XLINE := $29,
303 DWG_TYPE_DICTIONARY := $2a,
304 //DWG_TYPE_<UNKNOWN> := $2b,
305 DWG_TYPE_MTEXT := $2c,
306 DWG_TYPE_LEADER := $2d,
307 DWG_TYPE_TOLERANCE := $2e,
308 DWG_TYPE_MLINE := $2f,
309 DWG_TYPE_BLOCK_CONTROL := $30,
310 DWG_TYPE_BLOCK_HEADER := $31,
311 DWG_TYPE_LAYER_CONTROL := $32,
312 DWG_TYPE_LAYER := $33,
313 DWG_TYPE_SHAPEFILE_CONTROL := $34,
314 DWG_TYPE_SHAPEFILE := $35,
315 //DWG_TYPE_<UNKNOWN> := $36,
316 //DWG_TYPE_<UNKNOWN> := $37,
317 DWG_TYPE_LTYPE_CONTROL := $38,
318 DWG_TYPE_LTYPE := $39,
319 //DWG_TYPE_<UNKNOWN> := $3a,
320 //DWG_TYPE_<UNKNOWN> := $3b,
321 DWG_TYPE_VIEW_CONTROL := $3c,
322 DWG_TYPE_VIEW := $3d,
323 DWG_TYPE_UCS_CONTROL := $3e,
324 DWG_TYPE_UCS := $3f,
325 DWG_TYPE_VPORT_CONTROL := $40,
326 DWG_TYPE_VPORT := $41,
327 DWG_TYPE_APPID_CONTROL := $42,
328 DWG_TYPE_APPID := $43,
329 DWG_TYPE_DIMSTYLE_CONTROL := $44,
330 DWG_TYPE_DIMSTYLE := $45,
331 DWG_TYPE_VP_ENT_HDR_CONTROL := $46,
332 DWG_TYPE_VP_ENT_HDR := $47,
333 DWG_TYPE_GROUP := $48,
334 DWG_TYPE_MLINESTYLE := $49,
335 //DWG_TYPE_<UNKNOWN> := $4a
336 //DWG_TYPE_<UNKNOWN> := $4b
337 //DWG_TYPE_<UNKNOWN> := $4c
338 DWG_TYPE_LWPLINE := $4d,
339 DWG_TYPE_HATCH := $4e,
340 DWG_TYPE_XRECORD := $4f,
341 DWG_TYPE_PLACEHOLDER := $50,
342 //DWG_TYPE_<UNKNOWN> := $51,
343 DWG_TYPE_LAYOUT := $52
344 );
DWGObjectNamenull345 function DWGObjectName(ot:DWG_OBJECT_TYPE):string;
346 begin
347 result:='Unknown';
348 if integer(ot)<=$52 then
349 case ot of
350 DWG_TYPE_UNUSED:result:='DWG_TYPE_UNUSED';
351 DWG_TYPE_TEXT:result:='DWG_TYPE_TEXT';
352 DWG_TYPE_ATTRIB :result:='DWG_TYPE_ATTRIB';
353 DWG_TYPE_ATTDEF :result:='DWG_TYPE_ATTDEF';
354 DWG_TYPE_BLOCK :result:='DWG_TYPE_BLOCK';
355 DWG_TYPE_ENDBLK :result:='DWG_TYPE_ENDBLK';
356 DWG_TYPE_SEQEND :result:='DWG_TYPE_SEQEND';
357 DWG_TYPE_INSERT :result:='DWG_TYPE_INSERT';
358 DWG_TYPE_MINSERT :result:='DWG_TYPE_MINSERT';
359 //DWG_TYPE_<UNKNOWN> :result:=''; $09,
360 DWG_TYPE_VERTEX_2D :result:='DWG_TYPE_VERTEX_2D';
361 DWG_TYPE_VERTEX_3D :result:='DWG_TYPE_VERTEX_3D';
362 DWG_TYPE_VERTEX_MESH :result:='DWG_TYPE_VERTEX_MESH';
363 DWG_TYPE_VERTEX_PFACE :result:='DWG_TYPE_VERTEX_PFACE';
364 DWG_TYPE_VERTEX_PFACE_FACE :result:='DWG_TYPE_VERTEX_PFACE_FACE';
365 DWG_TYPE_POLYLINE_2D :result:='DWG_TYPE_POLYLINE_2D';
366 DWG_TYPE_POLYLINE_3D :result:='DWG_TYPE_POLYLINE_3D';
367 DWG_TYPE_ARC :result:='DWG_TYPE_ARC';
368 DWG_TYPE_CIRCLE :result:='DWG_TYPE_CIRCLE';
369 DWG_TYPE_LINE :result:='DWG_TYPE_LINE';
370 DWG_TYPE_DIMENSION_ORDINATE :result:='DWG_TYPE_DIMENSION_ORDINATE';
371 DWG_TYPE_DIMENSION_LINEAR :result:='DWG_TYPE_DIMENSION_LINEAR';
372 DWG_TYPE_DIMENSION_ALIGNED :result:='DWG_TYPE_DIMENSION_ALIGNED';
373 DWG_TYPE_DIMENSION_ANG3PT :result:='DWG_TYPE_DIMENSION_ANG3PT';
374 DWG_TYPE_DIMENSION_ANG2LN :result:='DWG_TYPE_DIMENSION_ANG2LN';
375 DWG_TYPE_DIMENSION_RADIUS :result:='DWG_TYPE_DIMENSION_RADIUS';
376 DWG_TYPE_DIMENSION_DIAMETER :result:='DWG_TYPE_DIMENSION_DIAMETER';
377 DWG_TYPE_POINT :result:='DWG_TYPE_POINT';
378 DWG_TYPE__3DFACE :result:='DWG_TYPE__3DFACE';
379 DWG_TYPE_POLYLINE_PFACE :result:='DWG_TYPE_POLYLINE_PFACE';
380 DWG_TYPE_POLYLINE_MESH :result:='DWG_TYPE_POLYLINE_MESH';
381 DWG_TYPE_SOLID :result:='DWG_TYPE_SOLID';
382 DWG_TYPE_TRACE :result:='DWG_TYPE_TRACE';
383 DWG_TYPE_SHAPE :result:='DWG_TYPE_SHAPE';
384 DWG_TYPE_VIEWPORT :result:='DWG_TYPE_VIEWPORT';
385 DWG_TYPE_ELLIPSE :result:='DWG_TYPE_ELLIPSE';
386 DWG_TYPE_SPLINE :result:='DWG_TYPE_SPLINE';
387 DWG_TYPE_REGION :result:='DWG_TYPE_REGION';
388 DWG_TYPE_3DSOLID :result:='DWG_TYPE_3DSOLID';
389 DWG_TYPE_BODY :result:='DWG_TYPE_BODY';
390 DWG_TYPE_RAY :result:='DWG_TYPE_RAY';
391 DWG_TYPE_XLINE :result:='DWG_TYPE_XLINE';
392 DWG_TYPE_DICTIONARY :result:='DWG_TYPE_DICTIONARY';
393 //DWG_TYPE_<UNKNOWN> :result:=''; $2b,
394 DWG_TYPE_MTEXT :result:='DWG_TYPE_MTEXT';
395 DWG_TYPE_LEADER :result:='DWG_TYPE_LEADER';
396 DWG_TYPE_TOLERANCE :result:='DWG_TYPE_TOLERANCE';
397 DWG_TYPE_MLINE :result:='DWG_TYPE_MLINE';
398 DWG_TYPE_BLOCK_CONTROL :result:='DWG_TYPE_BLOCK_CONTROL';
399 DWG_TYPE_BLOCK_HEADER :result:='DWG_TYPE_BLOCK_HEADER';
400 DWG_TYPE_LAYER_CONTROL :result:='DWG_TYPE_LAYER_CONTROL';
401 DWG_TYPE_LAYER :result:='DWG_TYPE_LAYER';
402 DWG_TYPE_SHAPEFILE_CONTROL :result:='DWG_TYPE_SHAPEFILE_CONTROL';
403 DWG_TYPE_SHAPEFILE :result:='DWG_TYPE_SHAPEFILE';
404 //DWG_TYPE_<UNKNOWN> :result:=''; $36,
405 //DWG_TYPE_<UNKNOWN> :result:=''; $37,
406 DWG_TYPE_LTYPE_CONTROL :result:='DWG_TYPE_LTYPE_CONTROL';
407 DWG_TYPE_LTYPE :result:='DWG_TYPE_LTYPE';
408 //DWG_TYPE_<UNKNOWN> :result:=''; $3a,
409 //DWG_TYPE_<UNKNOWN> :result:=''; $3b,
410 DWG_TYPE_VIEW_CONTROL :result:='DWG_TYPE_VIEW_CONTROL';
411 DWG_TYPE_VIEW :result:='DWG_TYPE_VIEW';
412 DWG_TYPE_UCS_CONTROL :result:='DWG_TYPE_UCS_CONTROL';
413 DWG_TYPE_UCS :result:='DWG_TYPE_UCS';
414 DWG_TYPE_VPORT_CONTROL :result:='DWG_TYPE_VPORT_CONTROL';
415 DWG_TYPE_VPORT :result:='DWG_TYPE_VPORT';
416 DWG_TYPE_APPID_CONTROL :result:='DWG_TYPE_APPID_CONTROL';
417 DWG_TYPE_APPID :result:='DWG_TYPE_APPID';
418 DWG_TYPE_DIMSTYLE_CONTROL :result:='DWG_TYPE_DIMSTYLE_CONTROL';
419 DWG_TYPE_DIMSTYLE :result:='DWG_TYPE_DIMSTYLE';
420 DWG_TYPE_VP_ENT_HDR_CONTROL :result:='DWG_TYPE_VP_ENT_HDR_CONTROL';
421 DWG_TYPE_VP_ENT_HDR :result:='DWG_TYPE_VP_ENT_HDR';
422 DWG_TYPE_GROUP :result:='DWG_TYPE_GROUP';
423 DWG_TYPE_MLINESTYLE :result:='DWG_TYPE_MLINESTYLE';
424 //DWG_TYPE_<UNKNOWN> :result:=''; $4a
425 //DWG_TYPE_<UNKNOWN> :result:=''; $4b
426 //DWG_TYPE_<UNKNOWN> :result:=''; $4c
427 DWG_TYPE_LWPLINE :result:='DWG_TYPE_LWPLINE';
428 DWG_TYPE_HATCH :result:='DWG_TYPE_HATCH';
429 DWG_TYPE_XRECORD :result:='DWG_TYPE_XRECORD';
430 DWG_TYPE_PLACEHOLDER :result:='';
431 //DWG_TYPE_<UNKNOWN> :result:=''; $51,
432 DWG_TYPE_LAYOUT :result:='DWG_TYPE_LAYOUT';
433 end;
434
435 end;
436
437 constructor bit_chain.init(_chain:pointer;_size:DWord);
438 begin
439 setto(_chain,_size);
440 end;
441 procedure bit_chain.setto(_chain:pointer;_size:DWord);
442 begin
443 chain:=_chain;
444 size:=_size;
445 byte:=0;
446 bit:=0;
447 end;
448
449 (*
450 bit_read_RC(Bit_Chain * dat)
451 {
452 unsigned char result;
453 unsigned char byte;
454
455 byte = dat->chain[dat->byte];
456 if (dat->bit == 0)
457 result = byte;
458 else
459 {
460 result = byte << dat->bit;
461 if (dat->byte < dat->size - 1)
462 {
463 byte = dat->chain[dat->byte + 1];
464 result |= byte >> (8 - dat->bit);
465 }
466 }
467
468 bit_advance_position(dat, 8);
469 return ((unsigned char) result);
470 }
471 *)
472 procedure bit_chain.scroll(scrollbit:integer);
473 var
474 endpos:integer;
475 begin
476 endpos:=bit+scrollbit;
477 if (byte>=size - 1) and (endpos > 7) then
478 begin
479 bit:=7;
480 exit;
481 end;
482 bit:=endpos mod 8;
483 byte:=byte+(endpos div 8);
484 end;
485
bit_chain.BitRead_rcnull486 function bit_chain.BitRead_rc:BITCODE_RC;
487 var
488 b:DWGByte;
489 begin
490 if bit=0 then
491 begin
492 result:=PDWGByte(PtrUInt(chain)+(byte))^;
493 inc(byte);
494 end
495 else
496 begin
497 result:=PDWGByte(PtrUInt(chain)+(byte))^ shl bit;
498 if (byte < size - 1) then
499 begin
500 b:=PDWGByte(PtrUInt(chain)+(byte+1))^;
501 result:=result or (b shr (8-bit));
502 end;
503 scroll(8);
504 end;
505 end;
bit_chain.BitRead_rlnull506 function bit_chain.BitRead_rl:BITCODE_RL;
507 var
508 b1:BITCODE_RS;
509 b2:BITCODE_RL;
510 begin
511 b1:=BitRead_rs;
512 b2:=BitRead_rs;
513 result:=((b2 shl 16) or b1);
514 end;
515 //BITCODE_MS
516 //bit_read_MS(Bit_Chain * dat)
517 {
518 int i, j;
519 unsigned int word[2];
520 long unsigned int result;
521
522 result = 0;
523 for (i = 1, j = 0; i > -1; i--, j += 15)
524 {
525 word[i] = bit_read_RS(dat);
526 if (!(word[i] & 0x8000))
527 {
528 result |= (((long unsigned int) word[i]) << j);
529 return (result);
530 }
531 else
532 word[i] &= 0x7fff;
533 result |= ((long unsigned int) word[i]) << j;
534 }
535 LOG_ERROR("bit_read_MS: error parsing modular short.")
536 return 0; /* error... */
537 }
538
bit_chain.BitRead_msnull539 function bit_chain.BitRead_ms:BITCODE_MS;
540 var
541 //b1:BITCODE_RS;
542 //b2:BITCODE_RL;
543 i, j:integer;
544 w:array [0..1] of word;
545 //long unsigned int result;
546 begin
547 result:= 0;
548 w[0]:=0;
549 w[1]:=0;
550 j:=0;
551 for i:=1 downto 0 do
552 //for (i = 1, j = 0; i > -1; i--, j += 15)
553 begin
554 w[i]:=BitRead_rs;
555 if not((w[i] and $8000)>0) then
556 begin
557 result :=result or (Longword(w[i]) shl j);
558 exit;
559 end
560 else
561 begin
562 w[i] := w[i] and $7fff;
563 result := result or (Longword(w[i]) shl j);
564 end;
565 j:=j+15;
566 end;
567 result:=0;
568 end;
bit_chain.BitRead_bbnull569 function bit_chain.BitRead_bb:BITCODE_BB;
570 var
571 b:BITCODE_RC;
572 begin
573 b:=PDWGByte(PtrUInt(chain)+(byte))^;
574 if (bit<7) then
575 result:=(b and ($c0 shr bit)) shr (6 - bit)
576 else
577 begin
578 result := (b and $01) shl 1;
579 if (byte < size-1) then
580 begin
581 b:=PDWGByte(PtrUInt(chain)+(byte+1))^;
582 result :=result or ((b and $80) shr 7);
583 end;
584 end;
585 scroll(2);
586 end;
bit_chain.BitRead_bsnull587 function bit_chain.BitRead_bs:BITCODE_BS;
588 var
589 two_bit_code:BITCODE_RC;
590 begin
591 two_bit_code:= BitRead_BB;
592
593 if (two_bit_code = 0) then
594 begin
595 result := BitRead_RS;
596 exit;
597 end
598 else if (two_bit_code = 1) then
599 begin
600 result := BitRead_RC;
601 exit;
602 end
603 else if (two_bit_code = 2) then
604 exit(0)
605 else
606 // if (two_bit_code == 3) */
607 exit(256);
608
609 end;
610
bit_chain.BitRead_rsnull611 function bit_chain.BitRead_rs:BITCODE_RS;
612 var
613 b1:BITCODE_RC;
614 b2:BITCODE_RS;
615 begin
616 b1:=BitRead_rc;
617 b2:=BitRead_rc;
618 result:=((b2 shl 8) or b1);
619 end;
620 {bit_read_H(Bit_Chain * dat, Dwg_Handle * handle)
621 {
622 unsigned char *val;
623 int i;
624
625 handle->code = bit_read_RC(dat);
626 handle->size = handle->code & 0x0f;
627 handle->code = (handle->code & 0xf0) >> 4;
628
629 handle->value = 0;
630 if (handle->size > 4)
631 {
632 LOG_ERROR(
633 "handle-reference is longer than 4 bytes: %i.%i.%lu",
634 handle->code, handle->size, handle->value)
635 handle->size = 0;
636 return (-1);
637 }
638
639 val = (unsigned char *) &handle->value;
640 for (i = handle->size - 1; i >= 0; i--)
641 val[i] = bit_read_RC(dat);
642
643 return (0);
644 }}
645
bit_chain.BitRead_hnull646 function bit_chain.BitRead_h:BITCODE_H;
647 var
648 _code:BITCODE_RC;
649 _size:BITCODE_RC;
650 pb:pbarray;
651 i:integer;
652 r:BITCODE_H;
653 begin
654 r:=0;
655 _code:=BitRead_rc;
656 _size:=_code and $0f;
657 _code:=(_code and $f0)shr 4;
658 if _size>16 then
659 begin
660 ShowError('Handle is longer than 4 bytes');
661 end
662 else
663 begin
664 pointer(pb):= @r;
665 for i:=_size-1 downto 0 do
666 {pb^[i]:=}BitRead_rc;
667 end;
668 result:=r;
669 end;
670
671 {bit_read_B(Bit_Chain * dat)
672 {
673 unsigned char result;
674 unsigned char byte;
675
676 byte = dat->chain[dat->byte];
677 result = (byte & (0x80 >> dat->bit)) >> (7 - dat->bit);
678
679 bit_advance_position(dat, 1);
680 return result;
681 }}
bit_chain.BitRead_bnull682 function bit_chain.BitRead_b:BITCODE_B;
683 var
684 _byte,b2:BITCODE_RC;
685
686 begin
687 _byte:=PDWGByte(PtrUInt(chain)+(byte))^;
688 b2:= (_byte and ($80 shr bit))shr(7-bit);
689 scroll(1);
690 if b2>0 then
691 result:=true
692 else
693 result:=false;
694 end;
bit_chain.BitRead_rdnull695 function bit_chain.BitRead_rd:BITCODE_rd;
696 var
697 i:integer;
698 ba:pbarray;
699 res:double;
700 begin
701 res:=0;
702 ba:=@res;
703 for i:=0 to 7 do
704 ba^[i]:=BitRead_rc;
705
706 result:=res;
707 end;
708 {
709 color->index = bit_read_BS(dat);
710 if (dat->version >= R_2004)
711 {
712 color->rgb = bit_read_BL(dat);
713 color->byte = bit_read_RC(dat);
714 if (color->byte & 1)
715 color->name = (char*)bit_read_TV(dat);
716 if (color->byte & 2)
717 color->book_name = (char*)bit_read_TV(dat);
718 }
719 }
720
bit_chain.BitRead_CMCnull721 function bit_chain.BitRead_CMC:BITCODE_CMC;
722 var
723 _byte:BITCODE_RC;
724 begin
725 {color->index = }BitRead_BS;
726 //if (dat->version >= R_2004)
727
728 {color->rgb = }BitRead_BL;
729 {color->byte = }_byte:=BitRead_RC;
730 if (_byte and 1)>0 then
731 {color->name = (char*)}BitRead_TV;
732 if (_byte and 2)>0 then
733 {color->book_name = (char*)}BitRead_TV;
734
735
736 end;
bit_chain.BitRead_TVnull737 function bit_chain.BitRead_TV:BITCODE_TV;
738 var i:integer;
739 begin
740 setlength(result,BitRead_BS);
741 //chain = (unsigned char *) malloc(length + 1);
742 for i:=1 to length(result) do
743 begin
744 pbyte(@result[i])^:=BitRead_RC;
745 //if (chain[i] == 0)
746 // chain[i] = '*';
747 //else if (!isprint (chain[i]))
748 // chain[i] = '~';
749 end;
750 end;
751
bit_chain.BitRead_blnull752 function bit_chain.BitRead_bl:BITCODE_BL;
753 var
754 two_bit_code:BITCODE_BB;
755 begin
756 two_bit_code:=BitRead_BB;
757 if two_bit_code=0 then
758 exit(BitRead_rl);
759 if two_bit_code=1 then
760 exit(BitRead_RC and $ff);
761 if two_bit_code=2 then
762 begin
763 exit(0);
764 end;
765 if two_bit_code=3 then
766 begin
767 ShowError('BitRead_bl: unexpected 2-bit code: "11"');
768 end;
769 end;
770
bit_chain.BitRead_ddnull771 function bit_chain.BitRead_dd(default_value:BITCODE_DD):BITCODE_DD;
772 var
773 two_bit_code:BITCODE_BB;
774 uchar_result:pbarray;
775 begin
776
777 //unsigned char two_bit_code;
778 //unsigned char *uchar_result;
779
780 two_bit_code:=BitRead_BB;
781 if two_bit_code=0 then
782 exit(default_value);
783 if two_bit_code=3 then
784 exit(BitRead_RD);
785 if two_bit_code=2 then
786 begin
787 uchar_result:=@default_value;
788 uchar_result^[4]:=BitRead_RC;
789 uchar_result^[5]:=BitRead_RC;
790 uchar_result^[0]:=BitRead_RC;
791 uchar_result^[1]:=BitRead_RC;
792 uchar_result^[2]:=BitRead_RC;
793 uchar_result^[3]:=BitRead_RC;
794
795 exit(default_value);
796 end;
797 if two_bit_code=1 then
798 begin
799 uchar_result:=@default_value;
800 uchar_result^[0]:=BitRead_RC;
801 uchar_result^[1]:=BitRead_RC;
802 uchar_result^[2]:=BitRead_RC;
803 uchar_result^[3]:=BitRead_RC;
804
805 exit(default_value);
806 end;
807 end;
bit_chain.BitRead_bdnull808 function bit_chain.BitRead_bd:BITCODE_bd;
809 var
810 two_bit_code:BITCODE_BB;
811 begin
812 two_bit_code:=BitRead_BB;
813 if two_bit_code=0 then
814 exit(BitRead_RD);
815 if two_bit_code=1 then
816 exit(1);
817 if two_bit_code=2 then
818 exit(0);
819 if two_bit_code=3 then
820 ShowError('BitRead_bd: unexpected 2-bit code: "11"');
821 result:=result;
822
823 end;
824
825 (*
826 read_literal_length(Bit_Chain* dat, unsigned char *opcode)
827 {
828 int total = 0;
829 unsigned char byte = bit_read_RC(dat);
830
831 *opcode = 0x00;
832
833 if (byte >= 0x01 && byte <= 0x0F)
834 return byte + 3;
835 else if (byte == 0)
836 {
837 total = 0x0F;
838 while ((byte = bit_read_RC(dat)) == 0x00)
839 {
840 total += 0xFF;
841 }
842 return total + byte + 3;
843 }
844 else if (byte & 0xF0)
845 *opcode = byte;
846
847 return 0;
848 }
849 *)
read_literal_lengthnull850 function read_literal_length(var bc:bit_chain;var opcode:DWGByte):integer;
851 var total:integer=0;
852 byte:DWGByte;
853 begin
854 //int total = 0;
855 //unsigned char byte = bit_read_RC(dat);
856 byte:=bc.BitRead_rc;
857
858 //*opcode = 0x00;
859 opcode:=0;
860
861 if (byte >= $01) and (byte <= $0F) then
862 begin
863 result:=byte+3;
864 exit;
865 end
866 else if (byte = 0) then
867 begin
868 total:=$0F;
869 byte:=bc.BitRead_rc;
870 while (byte=$00) do
871 begin
872 total:=total+$FF;
873 byte:=bc.BitRead_rc;
874 end;
875 result:=total+byte+3;
876 exit;
877 end
878 else if (byte and $F0)>0 then
879 opcode:=byte;
880 result:=0;
881 end;
read_two_byte_offsetnull882 function read_two_byte_offset(var bc:bit_chain;var lit_length:integer):integer;
883 var
884 firstbyte,secondbyte:DWGByte;
885 begin
886 firstByte := bc.BitRead_rc;
887 secondByte := bc.BitRead_rc;
888 result := (firstByte shr 2) or (secondByte shl 6);
889 lit_length := (firstByte and $03);
890 end;
read_long_compression_offsetnull891 function read_long_compression_offset(var bc:bit_chain):integer;
892 var
893 total:integer;
894 byte:DWGByte;
895 begin
896 total:=0;
897 byte := bc.BitRead_rc;
898 if (byte = 0) then
899 begin
900 total := $FF;
901 byte := bc.BitRead_rc;
902 while ((byte) = $00) do
903 begin
904 total := total+$FF;
905 byte := bc.BitRead_rc;
906 end;
907 end;
908 result:=total + byte;
909 end;
decompressnull910 function decompress(var pdecompdata:PDWGByte;ptr:pbyte;csize,usize:integer;var decompsize:integer):PDWGByte;
911 var
912 bc:bit_chain;
913 opcode1,opcode2:DWGByte;
914 lit_length:integer;
915 i:integer;
916 dst,src:pbyte;
917 comp_bytes,comp_offset:integer;
918 begin
919 decompsize:=-1;
920 result:=pdecompdata;
921 dst:=result;
922 bc.init(ptr,csize);
923 lit_length:=read_literal_length(bc,opcode1);
924
925 for i := 1 to lit_length do
926 begin
927 dst^:=bc.BitRead_rc;
928 inc(dst);
929 end;
930
931 opcode1:=0;
932 while bc.byte<csize do
933 begin
934 if opcode1=0 then
935 opcode1:=bc.BitRead_rc;
936 if opcode1 >= $40 then
937 begin
938 //HistoryOutStr('1 '+format('writeln %d bytes',[ptruint(dst)-ptruint(result)]));
939 comp_bytes:=((opcode1 and $F0) shr 4) - 1;
940 opcode2 := bc.BitRead_rc;
941 comp_offset := (opcode2 shl 2) or ((opcode1 and $0C) shr 2);
942 if (opcode1 and $03)>0 then
943 begin
944 lit_length := (opcode1 and $03);
945 opcode1 := $00;
946 end
947 else
948 lit_length := read_literal_length(bc, opcode1);
949 if lit_length=0 then
950 lit_length:=lit_length;
951 //HistoryOutStr(' '+format('comp_bytes=%d comp_offset=%d lit_length=%d',[comp_bytes,comp_offset,lit_length]));
952 end
953 else if (opcode1 >= $21) and (opcode1 <= $3F) then
954 begin
955 //HistoryOutStr('2');
956 comp_bytes := opcode1 - $1E;
957 comp_offset := read_two_byte_offset(bc, lit_length);
958
959 if (lit_length <> 0) then
960 opcode1 := $00
961 else
962 lit_length := read_literal_length(bc, opcode1);
963 end
964 else if (opcode1 = $20) then
965 begin
966 //HistoryOutStr('3');
967 comp_bytes := read_long_compression_offset(bc) + $21;
968 comp_offset := read_two_byte_offset(bc, lit_length);
969
970 if (lit_length <> 0) then
971 opcode1 := $00
972 else
973 lit_length := read_literal_length(bc, opcode1);
974 end
975 else if (opcode1 >= $12) and (opcode1 <= $1F) then
976 begin
977 //HistoryOutStr('4');
978 comp_bytes := (opcode1 and $0F) + 2;
979 comp_offset := read_two_byte_offset(bc, lit_length) + $3FFF;
980
981 if (lit_length <> 0) then
982 opcode1 := $00
983 else
984 lit_length := read_literal_length(bc, opcode1);
985 end
986 else if (opcode1 = $10) then
987 begin
988 //HistoryOutStr('5');
989 comp_bytes := read_long_compression_offset(bc) + 9;
990 comp_offset := read_two_byte_offset(bc, lit_length) + $3FFF;
991
992 if (lit_length <> 0)then
993 opcode1 := $00
994 else
995 lit_length := read_literal_length(bc, opcode1);
996 end
997 else if (opcode1 = $11) then
998 break // Terminates the input stream, everything is ok!
999 else
1000 begin
1001 opcode1:=opcode1;
1002 exit{(1)}; // error in input stream
1003 end;
1004
1005
1006 //LOG_TRACE("got compressed data %d\n",comp_bytes)
1007 // copy "compressed data"
1008 {src = dst - comp_offset - 1;
1009 assert(src > decomp);
1010 for (i = 0; i < comp_bytes; ++i)
1011 *dst++ = *src++;}
1012
1013 src:=pointer(PTRUINT(dst)-comp_offset-1);
1014 for i := 1 to comp_bytes do
1015 begin
1016 dst^:=src^;
1017 inc(dst);
1018 inc(src);
1019 end;
1020
1021 // copy "literal data"
1022 //LOG_TRACE("got literal data %d\n",lit_length)
1023 {for (i = 0; i < lit_length; ++i)
1024 *dst++ = bit_read_RC(dat);}
1025
1026 for i := 1 to lit_length do
1027 begin
1028 dst^:=bc.BitRead_rc;
1029 inc(dst);
1030 end;
1031
1032 end;
1033 decompsize:=dst-result;
1034 pdecompdata:=dst;
1035 end;
1036
1037
decompresssectionnull1038 function decompresssection(ptr:pbyte;csize,usize:integer;var decompsize:integer;var pdecompdata:PDWGByte):PDWGByte;
1039 begin
1040 decompsize:=-1;
1041 if pdecompdata=nil then
1042 begin
1043 GDBGetMem({$IFDEF DEBUGBUILD}'{87747A59-156F-4B1B-AD65-AEEB46995B6A}',{$ENDIF}result,usize);
1044 pdecompdata:=result;
1045 end
1046 else
1047 result:=pdecompdata;
1048 decompress(result,ptr,csize,usize,decompsize)
1049 end;
1050 procedure decodeheader(ptr:pbyte;size:integer);
1051 var
1052 randseed:integer;
1053 begin
1054 randseed:=1;
1055 repeat
1056 randseed:=randseed * $343fd;
1057 randseed:=randseed + $269ec3;
1058 ptr^:=ptr^ xor (byte(RorDword(randseed,16)));
1059 HistoryOutStr(inttohex(byte(RorDword(randseed,16)),4));
1060 inc(ptr);
1061 dec(size);
1062 until size=0;
1063 end;
FindSectionByIDnull1064 function FindSectionByID(const sarray:TMyDWGSectionDescArray;ID:integer):PTMyDWGSectionDesc;
1065 var
1066 i:integer;
1067 begin
1068 for i:=low(sarray) to High(sarray) do
1069 if sarray[i].Number=ID then
1070 begin
1071 result:=@sarray[i];
1072 exit;
1073 end;
1074 result:=nil;
1075 end;
FindInfoByTypenull1076 function FindInfoByType(const siarray:mysectiondescArray;SectionType:DWGLong):pmysectiondesc;
1077 var
1078 i:integer;
1079 begin
1080 for i:=low(siarray) to High(siarray) do
1081 if siarray[i].SectionType=SectionType then
1082 begin
1083 result:=@siarray[i];
1084 exit;
1085 end;
1086 result:=nil;
1087 end;
1088
1089 procedure addfromdwg2004(var f:GDBOpenArrayOfByte; exitGDBString: GDBString;owner:PGDBObjGenericSubEntry;LoadMode:TLoadOpt);
1090 var fh:pdwg2004header;
1091 fdh:dwg2004headerdecrypteddata;
1092 syssec,SectionMap,SectionInfo:pdwg2004systemsection;
1093 USectionMap,USectionInfo,objsection:pointer;
1094 i,j,jj,a,extdatasize,NumberOfSectionsThisType:integer;
1095 psize:dwglong;
1096 tb:boolean;
1097 sm:pdwg2004sectionmap;
1098 sid:pdwg2004sectioninfo;
1099 sd:pdwg2004sectiondesc;
1100 pi:pdwg2004pageinfo;
1101 sarray:TMyDWGSectionDescArray;
1102 siarray:mysectiondescArray;
1103
1104 objinfo:pmysectiondesc;
1105
1106 FileHandle:cardinal;
1107
1108 address:integer;
1109 bc,objbitreader:bit_chain;
1110 es:TEncryptedSectionHeader;
1111 sec_mask:DWGLong;
1112 decompsize:integer;
1113 ot:DWG_OBJECT_TYPE;
1114 ziszero:boolean;
1115 v1,v2:gdbvertex;
1116
1117 nolink:boolean;
1118 color_mode:boolean;
1119 index:word;
1120 flags:word;
1121
1122 pobj:PGDBObjEntity;
1123 begin
1124 fh:=f.PArray;
1125 fdh:=pdwg2004headerdecrypteddata(@fh^.EncryptedData)^;
1126 i:=sizeof(dwgbyte);
1127 i:=sizeof(dwgword);
1128 i:=sizeof(dwglong);
1129 i:=sizeof(dwg2004header);
1130 i:=sizeof(dwg2004headerdecrypteddata);
1131 decodeheader(@fdh,$6c);
1132 syssec:=f.PArray;
1133 inc(pointer(syssec),sizeof(dwg2004header));
1134 fh:=f.PArray;
1135 syssec:=f.PArray;
1136 inc(pointer(syssec),sizeof(dwg2004headerdecrypteddata));
1137 syssec:=f.PArray;
1138 inc(pointer(syssec),fdh.SecondHeaderAdress);
1139 syssec:=f.PArray;
1140 inc(pointer(syssec),fdh.SectionPageMapAdress);
1141 inc(pointer(syssec),$100);
1142 SectionMap:=syssec;
1143 SectionInfo:=syssec;
1144 inc(pointer(SectionInfo),SectionMap^.CompSizeData+sizeof(dwg2004systemsection));
1145 HistoryOutStr('MAP');
1146 USectionMap:=nil;
1147 decompresssection(pointer(PTRUINT(SectionMap)+sizeof(dwg2004systemsection)),SectionMap^.CompSizeData,SectionMap^.DecompSizeData,decompsize,USectionMap);
1148 setlength(sarray,fdh.SectionPageArraySize);
1149 sm:=pointer(USectionMap);
1150 for i:=0 to {SectionMap.DecompSizeData div 8}fdh.SectionPageAmount-1 do
1151 begin
1152 sarray[i].Number:=sm^.SectionNumber;
1153 sarray[i].Size:=sm^.SectionSize;
1154 if i=0 then
1155 sarray[i].Offset:=$100
1156 else
1157 sarray[i].Offset:=sarray[i-1].Offset+sarray[i-1].Size;
1158 HistoryOutStr(format('Section %d, size %d, offset %d',[sarray[i].Number,sarray[i].Size,sarray[i].Offset]));
1159 inc(sm);
1160 end;
1161 SectionInfo:=f.PArray;
1162 inc(pointer(SectionInfo),FindSectionByID(sarray,fdh.SectionInfoID)^.Offset);
1163 HistoryOutStr('INFO');
1164 USectionInfo:=nil;
1165 decompresssection(pointer(PTRUINT(SectionInfo)+sizeof(dwg2004systemsection)),SectionInfo^.CompSizeData,SectionInfo^.DecompSizeData,decompsize,USectionInfo);
1166
1167 {FileHandle:=FileCreate('log/SectionInfo');
1168 FileWrite(FileHandle,USectionInfo^,SectionInfo.DecompSizeData);
1169 fileclose(FileHandle);}
1170
1171 sid:=USectionInfo;
1172 //sid:=pointer(longint(SectionInfo)+sizeof(dwg2004systemsection));
1173 sd:=pointer(PTRUINT(sid)+sizeof(dwg2004sectioninfo){+20});
1174 setlength(siarray,sid^.NumDescriptions);
1175 for i:=0 to {SectionMap.DecompSizeData div 8}sid^.NumDescriptions-1 do
1176 begin
1177 {SizeOfSection:DWG2Long;
1178 NumberOfSectionsThisType:DWGLong;
1179 MaxDecompressedSize:DWGLong;
1180 Unknown2:DWGLong;
1181 Compressed:DWGLong;
1182 SectionType:DWGLong;
1183 Encrypted:DWGLong;
1184 SectionName:packed array[1..64]of ansichar;}
1185 HistoryOutStr('Section name: '+ pchar(@sd^.SectionName));
1186 HistoryOutStr(format(' SizeOfSection: %d, NumberOfSectionsThisType: %d, MaxDecompressedSize: %d, Unknown2: %d, Compressed: %d, SectionType: %d, Encrypted: %d',
1187 [sd^.SizeOfSection, sd^.NumberOfSectionsThisType, sd^.MaxDecompressedSize, sd^.Unknown2, sd^.Compressed, sd^.SectionType, sd^.Encrypted]));
1188 siarray[i].SizeOfSection:=sd^.SizeOfSection;
1189 siarray[i].NumberOfSectionsThisType:=sd^.NumberOfSectionsThisType;
1190 siarray[i].MaxDecompressedSize:=sd^.MaxDecompressedSize;
1191 siarray[i].Unknown2:=sd^.Unknown2;
1192 siarray[i].Compressed:=sd^.Compressed;
1193 siarray[i].SectionType:=sd^.SectionType;
1194 siarray[i].Encrypted:=sd^.Encrypted;
1195 siarray[i].SectionName:=pchar(@sd^.SectionName);
1196 setlength(siarray[i].pages,sd^.NumberOfSectionsThisType);
1197 NumberOfSectionsThisType:=sd^.NumberOfSectionsThisType;
1198 PtrUInt(sd):=PtrUInt(sd)+sizeof(dwg2004sectiondesc){32+64}{+16*sd.NumberOfSectionsThisType};
1199 pi:=pointer(sd);
1200 for a:=0 to NumberOfSectionsThisType-1 do
1201 begin
1202 siarray[i].pages[a].PageNumber:=pi^.PageNumber;
1203 siarray[i].pages[a].DataSize:=pi^.DataSize;
1204 siarray[i].pages[a].StartOffset:=pi^.StartOffset;
1205 siarray[i].pages[a].section:=FindSectionByID(sarray,pi^.PageNumber);
1206 if siarray[i].pages[a].section=nil then
1207 pi:=pi;
1208 HistoryOutStr(format(' Page: %d, DataSize: %d, StartOffset: %d,',
1209 [pi^.PageNumber, pi^.DataSize,pi^.StartOffset]));
1210 PtrUInt(pi):=PtrUInt(pi)+{sizeof(dwg2004pageinfo)}16;
1211 end;
1212 sd:=pointer(pi);
1213 //inc(longword(sd),sizeof({sd^}dwg2004sectiondesc));
1214 end;
1215 HistoryOutStr('Prepare AcDb:AcDbObjects section');
1216 objinfo:=FindInfoByType(siarray,SECTION_DBOBJECTS);
1217 GDBGetMem({$IFDEF DEBUGBUILD}'{A87A6634-F384-4414-8C8E-AD03866EE4E8}',{$ENDIF}objsection,objinfo^.MaxDecompressedSize*objinfo^.NumberOfSectionsThisType);
1218 bc.setto(f.PArray,f.size);
1219 for i:=0 to objinfo^.NumberOfSectionsThisType-1 do
1220 begin
1221 address:=objinfo^.pages[i].section^.Offset;
1222 bc.byte:=address;
1223 for j:= 0 to $20-1 do
1224 es.ByteData[j]:= bc.BitRead_rc;
1225
1226 sec_mask:= $4164536b xor address;
1227 for j:= 0 to 7 do
1228 es.LongData[j]:=es.LongData[j] xor sec_mask;
1229 objinfo^.pages[i].decompdata:=objsection;
1230 objsection:=decompresssection(pointer(PtrUInt(bc.chain)+bc.byte),es.field.data_size, $7400,decompsize,objsection);
1231 HistoryOutStr(format(' Page: %d, tag: %d, section_type: %d, data_size: %d, section_size: %d, start_offset: %d',
1232 [i, es.field.tag,es.field.section_type,es.field.data_size,es.field.section_size,es.field.start_offset]));
1233 HistoryOutStr(format(' Total decompressed size: %d',
1234 [decompsize]));
1235 end;
1236 FileHandle:=FileCreate('log/objsecmy2');
1237 FileWrite(FileHandle,objinfo^.pages[0].decompdata^,objinfo^.MaxDecompressedSize*objinfo^.NumberOfSectionsThisType);
1238 fileclose(FileHandle);
1239
1240 objbitreader.init(objinfo^.pages[0].decompdata,objinfo^.MaxDecompressedSize*objinfo^.NumberOfSectionsThisType);
1241 HistoryOutStr(format(' 0x0dca: %x',[objbitreader.BitRead_rl]));
1242
1243 while objbitreader.byte<objbitreader.size do
1244 begin
1245 //18.1 Common non-entity object format
1246 a:=objbitreader.BitRead_ms;//Size in bytes of object, not including the CRC
1247 //HistoryOutStr(format(' Size in bytes: %d',[a]));
1248 a:=objbitreader.byte+a;
1249 ot:=DWG_OBJECT_TYPE(objbitreader.BitRead_bs);//Object type
1250 //HistoryOutStr(format(' Object type: %x(%d), Name: %s',[ot,ot,DWGObjectName(ot)]));
1251 if ot=DWG_TYPE_LINE then
1252 begin
1253 objbitreader.BitRead_rl;//Size of object data in bits (number of bits before the handles), or the “endbit” of the pre-handles section.
1254 objbitreader.BitRead_h;//Object’s handle
1255 extdatasize:=objbitreader.BitRead_bs;//Size of extended object data, if any
1256 while extdatasize<>0 do
1257 begin
1258 if extdatasize<>0 then
1259 begin
1260 objbitreader.BitRead_h;
1261 extdatasize:=extdatasize;
1262 for jj:=1 to extdatasize do
1263 objbitreader.BitRead_rc;
1264 end;
1265 extdatasize:=objbitreader.BitRead_bs;//Size of extended object data, if any
1266 end;
1267 tb:=objbitreader.BitRead_b;//1 if a graphic is present
1268 if tb then
1269 begin
1270 psize:=objbitreader.BitRead_rl;
1271 for jj:=1 to psize do
1272 objbitreader.BitRead_rc;
1273 end;
1274
1275 {objbitreader.BitRead_b;
1276 objbitreader.BitRead_bs;
1277 objbitreader.BitRead_bd;
1278 objbitreader.BitRead_bb;
1279 objbitreader.BitRead_bb;
1280 objbitreader.BitRead_bs;
1281 objbitreader.BitRead_rc;}
1282
1283
1284 {common}
1285 {objbitreader.BitRead_ms;
1286 objbitreader.BitRead_bs;
1287 objbitreader.BitRead_rl;
1288 objbitreader.BitRead_h;
1289 objbitreader.BitRead_bs;}
1290 //objbitreader.BitRead_b;//1 if a graphic is present
1291
1292 objbitreader.BitRead_bb;//entity mode
1293 objbitreader.BitRead_bl;//number of persistent reactors attached to this object
1294 objbitreader.BitRead_b;//If 1, no XDictionary handle is stored for this object, otherwise XDictionary handle is stored as in R2000 and earlier.
1295 nolink:=objbitreader.BitRead_b;//1 if major links are assumed +1, -1, else 0 For R2004+ this always has value 1 (links are not used)
1296
1297
1298 //objbitreader.BitRead_cmc;//color
1299 //objbitreader.BitRead_bs;//color
1300
1301 //SINCE(R_2004)
1302 {
1303 char color_mode = 0;
1304 unsigned char index;
1305 unsigned int flags;}
1306
1307 if nolink=false then
1308 begin
1309 color_mode:=objbitreader.BitRead_b;
1310
1311 if (color_mode) then
1312 index:= objbitreader.BitRead_RC // color index
1313 else
1314 begin
1315 flags := objbitreader.BitRead_RS;
1316
1317 if (flags and $8000)>0 then
1318 begin
1319 //unsigned char c1, c2, c3, c4;
1320 //char *name=0;
1321
1322 //c1 = bit_read_RC(dat); // rgb color
1323 // c2 = bit_read_RC(dat);
1324 //c3 = bit_read_RC(dat);
1325 //c4 = bit_read_RC(dat);
1326 objbitreader.BitRead_RC;
1327 objbitreader.BitRead_RC;
1328 objbitreader.BitRead_RC;
1329 objbitreader.BitRead_RC;
1330
1331 objbitreader.BitRead_TV;
1332 end;
1333
1334 if (flags and $4000)>0then
1335 flags:=flags; // has AcDbColor reference (handle)
1336
1337 if (flags and $2000)>0 then
1338 begin
1339 objbitreader.BitRead_BL;
1340 end;
1341 end
1342 end
1343 else
1344 begin
1345 objbitreader.BitRead_B;
1346 end;
1347
1348
1349
1350
1351 objbitreader.BitRead_bd;//Ltype scale
1352 objbitreader.BitRead_bb;//00 = bylayer, 01 = byblock, 10 = continous, 11 =linetype handle present at end of object
1353 objbitreader.BitRead_bb;//00 = bylayer, 01 = byblock, 11 = plotstyle handle present at end of object
1354 objbitreader.BitRead_bs;//Invisibility
1355 objbitreader.BitRead_rc;//Lineweight
1356
1357 ziszero:=objbitreader.BitRead_b;
1358 //if (objbitreader.byte div $7400)=1 then
1359 begin
1360 if ziszero then begin
1361 v1.x:=objbitreader.BitRead_rd;
1362 v2.x:=objbitreader.BitRead_dd(v1.x);
1363 v1.y:=objbitreader.BitRead_rd;
1364 v2.y:=objbitreader.BitRead_dd(v1.y);
1365 v1.z:=0;
1366 v2.z:=0;
1367
1368 end
1369 else
1370 begin
1371 v1.x:=objbitreader.BitRead_rd;
1372 v2.x:=objbitreader.BitRead_dd(v1.x);
1373 v1.y:=objbitreader.BitRead_rd;
1374 v2.y:=objbitreader.BitRead_dd(v1.y);
1375 v1.z:=objbitreader.BitRead_rd;
1376 v2.z:=objbitreader.BitRead_dd(v1.z);
1377 end;
1378 //if (oneVertexlength(v1)<1000000)and(oneVertexlength(v2)<1000000)then
1379 begin
1380 pobj := CreateInitObjFree(GDBLineID,nil);
1381 PGDBObjLine(pobj)^.CoordInOCS.lBegin:=v1;
1382 PGDBObjLine(pobj)^.CoordInOCS.lEnd:=v2;
1383 PGDBObjLine(pobj)^.vp.Layer:=gdb.GetCurrentDWG^.LayerTable.GetSystemLayer;
1384 gdb.GetCurrentRoot^.AddMi(@pobj);
1385 PGDBObjEntity(pobj)^.BuildGeometry(gdb.GetCurrentDWG^);
1386 PGDBObjEntity(pobj)^.formatEntity(gdb.GetCurrentDWG^);
1387 end;
1388 end;
1389
1390 end;
1391
1392
1393 objbitreader.byte:=a;
1394 objbitreader.bit:=0;
1395 {HistoryOutStr(format(' CRC: %x',[}objbitreader.BitRead_rs{]))};
1396 end;
1397 end;
1398
1399 procedure addfromdwg(name: GDBString;owner:PGDBObjGenericSubEntry;LoadMode:TLoadOpt;var drawing:TSimpleDrawing);
1400 var
1401 f: GDBOpenArrayOfByte;
1402 s: GDBString;
1403 begin
1404 DebugLn('{D+}AddFromDWG');
1405 //programlog.logoutstr('AddFromDWG',lp_IncPos);
1406 HistoryOutStr(format(rsLoadingFile,[name]));
1407 f.InitFromFile(name);
1408 if f.Count<>0 then
1409 begin
1410 if assigned(StartLongProcessProc) then
1411 StartLongProcessProc(f.Count,'Load DWG file');
1412 s := f.ReadString(#0,'');
1413 if s = 'AC1018' then
1414 begin
1415 HistoryOutStr(format(rsFileFormat,['DWG2004']));
1416 addfromdwg2004(f,'EOF',owner,loadmode);
1417 end
1418 else
1419 begin
1420 ShowError(rsUnknownFileFormat);
1421 end;
1422 if assigned(EndLongProcessProc) then
1423 EndLongProcessProc;
1424 end
1425 else
1426 ShowError('IODWG.ADDFromDWG:'+format(rsUnableToOpenFile,[name]));
1427 f.done;
1428 DebugLn('{D-}end; {AddFromDWG}');
1429 //programlog.logoutstr('end; {AddFromDWG}',lp_DecPos);
1430 end;
1431 begin
1432 Ext2LoadProcMap.RegisterExt('dwg','AutoCAD DWG files (*.dwg)',@addfromdwg);
1433 end.
1434