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