GithubHelp home page GithubHelp logo

libredwg / libredwg Goto Github PK

View Code? Open in Web Editor NEW
851.0 48.0 215.0 93.29 MB

Official mirror of libredwg. With CI hooks and nightly releases. PR's ok

Home Page: https://savannah.gnu.org/projects/libredwg/

License: GNU General Public License v3.0

Makefile 0.21% Shell 0.70% Batchfile 0.01% M4 0.68% C 97.48% Roff 0.05% Python 0.04% HTML 0.01% Perl 0.48% Common Lisp 0.01% SWIG 0.23% Dockerfile 0.01% CMake 0.10%
dwg cad

libredwg's Introduction

LibreDWG - free implementation of the DWG file format

LibreDWG is a free C library to read and write DWG files.  This program is
part of the GNU project, released under the aegis of GNU.  It is licensed
under the terms of the GNU General Public License version 3 (or at you option
any later version).

DWG is a file format created in the 70's for the emerging CAD applications.
Currently it is the native file format of AutoCAD, a proprietary CAD program 
developed by AutoDesk.

LibreDWG is a fork from LibDWG due to its usage of Esperanto, which we
think is not the best strategy for a free software project which aims
to get lots of contributors. LibreDWG is written in English. At the
moment our decoder (i.e. reader) is done, it can read all DWG
versions, just some very advanced R2010+ objects fail to read and are
skipped over. The writer is good enough for R1.4 - R2000. Among the
example applications we wrote using LibreDWG is a reader, a writer, a
rewriter (i.e. saveas), an initial SVG and Postscript conversion, dxf
and json converters, dwggrep to search for text, and dwglayer to print
the list of layers. More are in the pipeline. Please contact us if you
want to help.

The strings API is UTF-8 (WTF8 really, Windows UCS-2 has no surrogate
pairs), and encodes to the internal 8-bit or UCS-2 strings, depending
on the DWG version. Older DWG's are encoded in ~30 codepages, which we
convert to unicode/UTF-8.

We also maintain a diff document for our internal fixed ODA-5.4.1 spec
at doc/ODA-5.4.2-libredwg-diff.pdf

For contact file a ticket or email the package maintainers:

Reini Urban <rurban AT cpan.org>

The now inactive founders and previous maintainers were:

Felipe Corrêa da Silva Sanches <juca AT members.fsf.org>
Rodrigo Rodrigues da Silva <pitanga AT members.fsf.org>
Hardeep Singh Rai <hardeep.rai AT gmail DOT com>

If you are looking for general information about the project, check our website:
http://www.gnu.org/software/libredwg/

== Building and installing the library ==

You need the following dependencies:
- Basic development tools (a C99 compiler like gcc/clang, make, autoconf, automake
  and libtool)

Optionally:

- libiconv: optional codepage conversion. without it's just a bit slower.
- libmimalloc: faster memory allocation, but usually not worth the hassle.
- pslib for dwg2ps: http://pslib.sourceforge.net/doc/pslib.html
- pcre2 with 8bit and 16bit libraries for dwggrep regexp support.
- gperf to update static hashes for several API's
  Only needed when you added objects or changed the dwg.spec significantly
- cmake, ninja
- TeXinfo for building the docs
- SWIG 1.7+
- Python 2.7 or 3.x development headers (debian: python-dev; yum: python-devel)
  and the libxml2 python bindings.
- Perl 5 for the perl bindings
- doxygen to generate the reference manual
- jq to check json validity, and as dwgfilter backend
- shellcheck to check shell scripts
- rpmlint to check the spec validity
- jinq with some svg11 relaxng to check SVG validity.
  LaTeXML used to have a broken svg11-basic.rng. If so
  the zip from http://yupotan.sppd.ne.jp/relax-ng/svg11/ is correct.
  Needs to be installed into /usr/local/share/relaxng/svg11/
  sudo unzip ~/Downloads/svg11-relaxng-20060604.zip -d  /usr/local/share/relaxng/
  On Ubuntu I needed:
  apt install jing libjaxp1.3-java libbatik-java libavalon-framework-java
- mapbox/geojsonhint as geojson linter
  npm install -g @mapbox/geojsonhint
- geojson-validation as 2nd geojson fallback linter
  npm install -g geojson-validation
- shfmt to format shell scripts
- clang-format to format the C source code
- clang-tidy to check source code
- valgrind to find leaks and memory bugs
- timeout to help tests with large or hanging DWG's
- GNU parallel to speed up special tests (not the moreutils parallel!)
- picat to find unknown fields, a better prolog. http://picat-lang.org/

See INSTALL for generic instructions.  Basically, you do:

$ sh ./autogen.sh (if you checked out the source code from git)
$ ./configure [--enable-trace] [--disable-write] [--disable-shared]
$ make
$ make check
$ sudo make install

This builds and installs various files in the "installation dirs":
  $libdir     ($exec_prefix/lib)   -- library files (libredwg.*)
  $includedir ($prefix/include)    -- dwg.h dwg_api.h
  $libdir/pkgconfig                -- libredwg.pc
  $infodir    ($datarootdir/info)  -- LibreDWG.info

Use "./configure --help" to see a full list of options you can use to
customize the installation dirs.  Other options recognized by configure are:

  --enable-release

    Recommended for packagers and fuzzers. Disables all features
    which will not be enabled in official tarball releases. Like skipping
    unstable DWG features or objects, unknown DWG versions and objects.

  --enable-trace

    Enable runtime tracing (default: no).  When enabled, the environment
    variable LIBREDWG_TRACE is consulted on the first decode/encode attempt.
    Its value is an integer: 0 (no output) through 9 (full verbosity).
    Most tools do support a --verbosity|-v flag instead.

  --with-dxf-precision=rfc

   How many after-comma places in DXF doubles. 6 is the recommended
   value (e.g. use rfc), max and the default is 16.

  --with-geojson-precision=rfc

   How many after-comma places in GeoJSON doubles. 6 is the
   recommended value by RFC 7946, max and the default is 16.

  --disable-write

    Disable DWG write support (default: no).
    Write support only works for earlier versions until r2004. Rewriting most DWG's
    <= r2004 usually works fine.

  --disable-bindings

    Disable SWIG bindings for python and perl5.

  --disable-dxf

    Disables all in and out modules: DXF, DXFB, JSON, GeoJSON.

  --disable-json

    Disables the json in and out modules: JSON, GeoJSON.

  --disable-python

    Disable python bindings and tests.
    Related: --enable-python=python3.6
    Enforce a specific version.

  --enable-debug

    Activates support for unstable classes. For testing only.

  --enable-gcov

    Activates support for GNU gcov, test coverage reporting.

  --with-perl-install=vendor

   Where to install the perl bindings: vendor,arch,yes,no,site.
   Default is perl-install=site

== Windows ==

See the following scripts how we build on Windows:

* .github/workflows/main.yml: via msys/autotools, or cmake. gcc, clang-cl or VS2019.
* build-aux/smoke.sh: cross-compilation recipes
* build-aux/msys2.bat: msys2 deps
* .appveyor.yml: windows smoker

We do support mingw, clang-cl and now also Visual Studio 2019 via cmake.
stdint.h and inttypes.h must be available.
Pre-compiled Windows binaries are here: https://github.com/LibreDWG/libredwg/releases

== Example usage of the library ==

The programs and examples directories contains some application code
that uses our lib:

* dwgread -- A DWG reader supporting various output formats, such as
  JSON, DXF, DXFB, GeoJSON. Later also YAML, XML/OGR, GPX, SVG, PS.

* dwgwrite -- A DWG writer supporting various input formats, such as DXF, DXFB, JSON.
  GeoJSON, YAML, XML/OGR, GPX are under construction.

* dwg2dxf -- Converts a DWG to a DXF (ascii or binary, minimal or full), optionally
  under a different version. About 90% coverage.

* dxf2dwg -- Converts a ascii or binary DXF to a DWG (r2000 only so far).
  About 80% coverage.

* dwglayers -- Prints the list of layers in a DWG. Optionally with --extnames

* dwggrep -- Searches DWG files for a text string, via regular expressions.

* dwg2ps -- Opens a DWG file and outputs an PostScript file.  This code
  depends on the PSlib library.  On Debian-based systems this is usually
  available as a package named pslib-dev. This is very limited so far.

* dwgfilter -- Applies JSON filters via JQ. Either as structured grep,
  or to mass change certain values.

* dwg2SVG -- Opens a DWG file and outputs an SVG (Scalable Vector Graphics)
  file.  SVG is a W3C standard for 2d vector graphics.  You can open these
  files on several free software tools.  We recommend Inkscape, a free software
  vector graphics editor.  The dwg2SVG program will not handle 3d content
  from DWG since SVG only supports 2-dimensional images. Handles only some
  entities.

* dwgbmp -- Extracts the bmp thumbnail of a dwg file when it is available.

* dwgadd -- the easiest way to create DWG's (or DXF, JSON) from scratch or
  add entities to an existing DWG. It accepts a very simple file with commands
  to create entities or objects and set its properties.

* dwgrewrite -- Reads a DWG, writes it back under a different name and optionally
  under a different version (default r2000), and re-reads it back for confirmation.

* load_dwg -- This is a skeleton code, reading the DWG and adding an entity.
  Look there if you want to have a quickly glance on how to use the library.

* dwg2svg2 -- Another example how to use the DWG API, bypassing direct access to
  the DWG struct.

* xmlsuite -- an extensive example library to use XML to compare against prepared
  features is in the test/xmlsuite directory. It also features code to output entities
  in XML, but does not use the python bindings.

Copyright (C) 2009, 2010, 2015, 2018-2024 Free Software Foundation, Inc.

This library is free software, licensed under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

libredwg's People

Contributors

andersoncardoso avatar carmethene avatar chunibyo-wly avatar cranexhu avatar davidkorczynski avatar denispryt avatar duvisit avatar esobolev321 avatar felipesanches avatar fr-an-k avatar gentilinigm avatar gongxy-sh avatar jossefaz avatar kreguieg avatar looooo avatar luzpaz avatar michal-josef-spacek avatar papazoga avatar piyushparkash avatar pojark avatar rbvermaa avatar risicle avatar rodrigopitanga avatar rurban avatar sashashura avatar tjanez avatar wshclth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libredwg's Issues

double free object_ref item

In some reasons, 2 pointers refer in single object, and free this object twice.
Object is created in dwg_decode_handleref_with_code and stored in dwg->object_ref array. Then it return from function and assigned to object's subentity field.
In dwg_free at first some object is destroyed with his subentity, and then all object_ref is destroyed with thouse subentity one more time.
Can you help me fix this bug? Maybe you are know how this problem can be solved?

DBCOLOR reference

See #27
An entity with color flag 0x40 needs to decode the DBCOLOR ref.
testcases: 2004/dbcolor and 2004/CascoUrbano

Warning Unknown Classes

There are a bunch of unknown classes for entities, if this is something I can help with please let me know and point me in the direction of the files I need to edit

Warning: Unknown Class object 541 AEC_DISP_PROPS_MASS_ELEM_MODEL (0x81)
Warning: Unknown Class object 542 AEC_DISP_REP_MASS_GROUP_MODEL (0x81)
Warning: Unknown Class object 544 AEC_DISP_REP_MASS_ELEM_MODEL (0x81)
Warning: Unknown Class object 545 AEC_DISP_REP_MASS_GROUP_PLAN (0x81)
Warning: Unknown Class object 543 AEC_DISP_PROPS_MASS_GROUP (0x81)
Warning: Unknown Class object 546 AEC_DISP_REP_CLIP_VOLUME_MODEL (0x81)
Warning: Unknown Class object 547 AEC_DISP_PROPS_CLIP_VOLUME (0x81)
Warning: Unknown Class object 548 AEC_DISP_REP_CLIP_VOLUME_RESULT (0x81)
Warning: Unknown Class object 549 AEC_DISP_REP_ANCHOR_EXT_TAG_TO_ENT (0x81)
Warning: Unknown Class object 550 AEC_DISP_PROPS_ENT (0x81)
Warning: Unknown Class object 551 AEC_DISP_REP_ANCHOR (0x81)
Warning: Unknown Class object 552 AEC_DISP_REP_CLIP_VOLUME_RESULT_SUBDIV (0x81)
Warning: Unknown Class object 553 AEC_DISP_PROPS_CLIP_VOLUME_RESULT (0x81)
Warning: Unknown Class object 554 AEC_DISP_REP_ANCHOR_TAG_TO_ENT (0x81)
Warning: Unknown Class object 555 AEC_DISP_REP_ANCHOR_ENT_TO_NODE (0x81)
Warning: Unknown Class object 556 AEC_DISP_REP_2D_SECTION (0x81)
Warning: Unknown Class object 557 AEC_DISP_PROPS_2D_SECTION (0x81)
Warning: Unknown Class object 558 AEC_DISP_REP_CLIP_VOLUME_PLAN (0x81)
Warning: Unknown Class object 559 AEC_DISP_REP_POLYGON_TRUECOLOUR (0x81)
Warning: Unknown Class object 560 AEC_DISP_PROPS_POLYGON_TRUECOLOUR (0x81)
Warning: Unknown Class object 561 AEC_DISP_REP_ENT_REF (0x81)
Warning: Unknown Class object 562 AEC_DISP_PROPS_ENT_REF (0x81)
Warning: Unknown Class object 563 AEC_DISP_REP_POLYGON_MODEL (0x81)
Warning: Unknown Class object 564 AEC_DISP_PROPS_POLYGON_MODEL (0x81)
Warning: Unknown Class object 565 AEC_DISP_REP_EDITINPLACEPROFILE (0x81)
Warning: Unknown Class object 566 AEC_DISP_PROPS_EDITINPLACEPROFILE_MODEL (0x81)
Warning: Unknown Class object 567 AEC_DISP_REP_MATERIAL (0x81)
Warning: Unknown Class object 568 AEC_DISP_PROPS_MATERIAL (0x81)
Warning: Unknown Class object 569 AEC_DISP_REP_MVBLOCK_REF (0x81)
Warning: Unknown Class object 570 AEC_DISP_REP_MASKBLOCK_REF (0x81)
Warning: Unknown Class object 571 AEC_DISP_PROPS_MASKBLOCK (0x81)
Warning: Unknown Class object 572 AEC_DISP_REP_DISPLAYTHEME (0x81)
Warning: Unknown Class object 573 AEC_DISP_PROPS_DISPLAYTHEME (0x81)
Warning: Unknown Class object 574 AEC_DISP_REP_LAYOUT_GRID2D (0x81)
Warning: Unknown Class object 575 AEC_DISP_PROPS_LAYOUT_GRID2D (0x81)
Warning: Unknown Class object 576 AEC_DISP_REP_LAYOUT_GRID3D (0x81)
Warning: Unknown Class object 577 AEC_DISP_PROPS_LAYOUT_GRID3D (0x81)
Warning: Unknown Class object 578 AEC_DISP_REP_LAYOUT_CURVE (0x81)
Warning: Unknown Class object 579 AEC_DISP_PROPS_LAYOUT_CURVE (0x81)
Warning: Unknown Class object 580 AEC_DISP_REP_MVBLOCK_REF_MODEL (0x81)
Warning: Unknown Class object 581 AEC_DISP_REP_SLICE (0x81)
Warning: Unknown Class object 582 AEC_DISP_PROPS_SLICE (0x81)
Warning: Unknown Class object 583 AEC_DISP_REP_CEILING_GRID (0x37d)
Warning: Unknown Class object 584 AEC_DISP_REP_CURTAIN_WALL_LAYOUT_PLAN (0x81)
Warning: Unknown Class object 585 AEC_DISP_PROPS_GRID_ASSEMBLY_PLAN (0x81)
Warning: Unknown Class object 586 AEC_DISP_REP_COLUMN_GRID (0x81)

add python 3.6 support

I've add a --enable-python=<python path> flag for a --enable-python=python3.6 cfg arg, but the probe fails.

add TABLE TABLECONTENT subclassing

  • either as now, via calling the specialized TABLECONTENT method for r2010+ but leaving out RECORD, handle and other prefix methods.
  • or by adding the TABLECONTENT struct to TABLE, obj->tc.FIELDS (easiest to implement)
  • or inlining it as obj->FIELDS completely (less work for saveas). leave out old duplicate fields.

Segmentation fault in dwg_model_space_ref()

I've been converting DWG files made with some quite old version of AutoCAD, like 2004 or even 2002, I'm not sure, and discovered that the library (I've tried recently released v0.6) segfaults on some of them inside dwg_model_space_ref() in dwg.c, apparently while accessing dwg->header_vars.BLOCK_RECORD_PSPACE (stack trace is trivial so I'd waive it). This happens both on i386 and amd64.

Example of problematic file.

maybe add dwg2dxf --low

Low precision DXF. Or call it --basic, but there -b is already taken to --binary.

Like the --minimal flag, but output more like with dxfrw. i.e. no SUBCLASS markers and handles, no dictionaries, reactors, ...

Creates smaller DXF files, and should still be readable by acad.

Looked at this again, it is wrong. Most checks needs to be versioned, not some arbitrary --low or minimal check.

TODO: down-conversions from unsupported entities on older DXF versions:

Since r13: Entities: LWPOLYLINE, HATCH, SPLINE, LEADER, DIMENSION, MTEXT, IMAGE,
BLOCK_RECORD.
Table BLOCK_RECORD.
add CLASSES for those
handle 5, 100, 105
non-all caps table names.

Since r14: handle 330

fix GET_DWG_ENTITY

Either the last member of the array needs to be NULL, or we need to return the count.
Since we don't want to change the API, we NULL-terminate it.

We also need to guard from an empty BLOCK_HEADER argument

32bit crashes: dwg2svg2

someone, maybe CRC, is overwriting the Dwg_Struct after num_classes,
32bit only. with dwg2svg2 only.

  CRC = 36953}, num_classes = 4,
  dwg_class = 0x8153100, num_objects = 61, object = 0x8158398, num_layers = 0,
  num_entities = 12, num_object_refs = 154, object_ref = 0x8155b78, layer_control = 0x81532a0,
  mspace_block = 0x8154ff0, pspace_block = 0x8156560,
=>
  CRC = 65028}, num_classes = 3086986712,
  dwg_class = 0xad9f3224, num_objects = 1336173547, object = 0x9059, num_layers = 4,
  num_entities = 135606528, num_object_refs = 61, object_ref = 0x8158398,
  layer_control = 0x0, mspace_block = 0xc, pspace_block = 0x9a,

CRC ... num_entities is wrong.

add a binary text type, look at the DXF code.

dxf and json out need to treat some binary data different than text.
e.g. encode chars as %02x
json also needs to encode unprintable chars via +U and escape \ properly.

either add a FIELD_TB to the spec or check the dxf code in FIELD_T
in DXF we already have VALUE_BINARY

dwgfilter: XPath-like query expr

In principle like osmfilter, but with a sane query expression language.
Something like XPath or JSONPath with the dot. notation seem to be the best fit.

By default pure, only display the result of the filter query.
It also needs to handle destructive changes: --delete and --keep for simple boolean queries
and maybe also changes (renames, transform) by assignment ops (+=) or s///.

depends on: #59

Not working on 2018 CAD files

I have just compiled the lib, tried to load in a 2018 dwg file, and it outputs the following:

ERROR: This version of LibreDWG is only capable of safely decoding version R13-R2007 (code: AC1012-AC1021) DWG files.
Support for this version is still experimental. We don't decode all objects yet.
It will probably crash and/or give you invalid output.
ERROR: bit_read_BD: unexpected 2-bit code: '11'
ERROR: bit_read_BD: unexpected 2-bit code: '11'
ERROR: bit_read_BD: unexpected 2-bit code: '11'
ERROR: bit_read_BL: unexpected 2-bit code: '11'
Warning: Invalid handle pointer code 14
ERROR: Invalid handle-reference, longer than 4 bytes: 13.12.0
ERROR: Could not read handleref in the header variables section
ERROR: Invalid handle-reference, longer than 4 bytes: 5.6.0
ERROR: Could not read handleref in the header variables section
Warning: dwg_decode_handleref_with_code: Missing obj arg
Segmentation fault: 11

dxf polyline coordinates

Hi, during conversion from dwg to dxf, there is wrong polyline coordinates. such as :
Thanks for help.

testdata.zip

ORİGİNAL :
AcDbPolyline
90
4
70
129
43
0.0
10
-10.0
20
50.0
10
-10.0
20
60.0
10
0.0
20
60.0
10
0.0
20
50.0

exported by libredwg :

AcDbPolyline
90
4
70
1
10
-10.00000000000000
20
50.00000000000000
10
-10.00000000000000
20
60.00000000000000
10
0.0
20
-10.00000000000000 (must be 60)
10
0.0
20
50.00000000000000

dwg2dxf fails

When running the command dwg2dxf test.dwg on the .dwg sent to @rurban you get the following output

Warning: Object handle not found, 80 in 11073 objects
Warning: Object handle not found, 208 in 11073 objects
Warning: Object handle not found, 208 in 11073 objects
Warning: Object handle not found, 82 in 11073 objects
Writing DXF file test.dxf
Segmentation fault (core dumped)

When opening the resulting dxf in librecad it recognises some of the layers but no lines or any other drawing elements

api: add parent field to each _dwg_{entity,object}_ENTITY

we have to jump through absurd hurdles in the API to get around that.
the parent points to the _dwg_object_{entity, object}, which points via the object field to the _dwg_object.

But beware that adding objects (realloc) moves and invalidates all internal cross pointers to Dwg_Object*, but not Dwg_Object_OBJECT*. Those are not realloced. Also not the object substructs.
They only problem I see are the dwg_{obj,ent}_obj->object links to the dwg_object*.
They need to be replaced by an objid.

Either scan the objects twice for the final size (but then we cannot add objects later, when writing), or make the parent link a handle or objid index.

Also when adding objects and a realloc happened, we need to re-resolve all handles/links. this btw is a release blocker, as we already added the add API.
for better performance alloc in bigger chunks, so we can skip the scan most of the times.
dwg_add needs to trigger a rescan flag btw.

add a dynamic object/field API

It's required for interfacing dynamic languages to provide a better dynamic API, and for the importers, a precompiled list or hash of all known elements, objects and subtypes with all its properties.
These can be generated via processing the dwg.h or dwg.spec into gperf hashes or arrays.
The needed info per field would be: name, type, offsetof(), (dxf).

Then we could also implement a dwgfilter program (#64), which allows filtering on user-defined, dynamic objects and it's properties. e.g. dwglayer, dwgxrefs, ...
analog to osmfilter

we could also get rid of the massively big and unmaintainable dwg_api functions, replacing it with the dynamic versions, separated by type. and add a reflective api, e.g. return the VERTEX_2D fields, the type of the VERTEX_3D.point field, ...

  • rename dwg_get_OBJECT(dwg) to dwg_getall_OBJECT(dwg)
  • rename dwg_get_ENTITY(blkhdr) to dwg_getall_ENTITY(blkhdr)
  • add dwg_get_OBJECT(obj, field) field getters by string (single field only)
  • add dwg_set_HEADER(dwg, field, value, ...), dwg_set_OBJECT(obj, field, value, ...) set multiple fields.
    e.g. for 3RD: dwg_set_VERTEX_2D(obj, "point", 0.0, 0.0, 1.0);

BITCODE_MC needs to read from 5 bytes, not 4

With large DWG's with large offsets from handles, some offsets were misrepresented due to underflow. The last byte (4 bits actually) was not read.

MC:
Read 1 modular char (max 5 bytes, signed).
Read bytes until the high bit of the byte is 0, drop the highest bit and pad with 0.
If the last byte has 0x40 set, it's negative. (since the 0x80 bit is dropped, 0x40 becomes the highest bit then)
Since the result is int32_t (4 byte) but there needs to be the high/follow bit set,
the stream can be max 5 byte long (5*7 = 35 bit)

    10000000 10000000 10000000 10000000 00000100
 =>  0000000  0000000  0000000  0000000  0000100 (5*7 = 35)
 => 00001000 00000000 00000000 00000000          (4*8 = 32)

With 4 byte only 4*7=28 bit can be represented, the highest 4 (from 32) are missing for large offsets >= 0x1000000 (0b0001000000000000000000000000)

Detected and fixed by @DenisPryt in #65

The very same error came originally from libdwg, and is also present in all other open source dwg libs:
libdwg, libdxfrw, pythoncad

Decode objects handles map incorrectly

I found another interesting issue with decoding handles and offsets for objects :
2004.zip
I may be wrong but it looks like for long handle address ModularChar reading can use more than 4 bytes, up to 8. Although the handles are read, some section pages contains large values that are not fully decoded and all handle references from header to block controls (layers, etc.) are not matching.

rename SHAPEFILE object/table to STYLE

nobody else names it SHAPEFILE, only the ODA.

dxf names it STYLE and $TEXTSTYLE,
AutoCAD names it AcDbTextStyleTable,
libdxfrw names it STYLE and TEXTSTYLE

double free in dwg_free

When open the crafted dwg file , it could tigger double free in dwg2svg2

Let's see the program error output

15:20 haclh@ubuntu:examples $ ./dwg2svg2 dfree_poc_155 
......................................................................
......................................................................
......................................................................
=================================================================
*** Error in `./dwg2svg2': double free or corruption (fasttop): 0x0000000001336430 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f18b82547e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f18b825d37a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f18b826153c]
./dwg2svg2[0x499e0b]
./dwg2svg2[0x49a31a]
./dwg2svg2[0x4a18e9]
./dwg2svg2[0x4a239d]
./dwg2svg2[0x40d13f]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f18b81fd830]
./dwg2svg2[0x40d3a9]
======= Memory map: ========
00400000-00569000 r-xp 00000000 08:10 1140093                            /home/haclh/vmdk/fuzz_workplace/libredwg-0.5.1048/examples/dwg2svg2
00768000-00769000 r--p 00168000 08:10 1140093                            /home/haclh/vmdk/fuzz_workplace/libredwg-0.5.1048/examples/dwg2svg2
00769000-0076a000 rw-p 00169000 08:10 1140093                            /home/haclh/vmdk/fuzz_workplace/libredwg-0.5.1048/examples/dwg2svg2
0076a000-0076c000 rw-p 00000000 00:00 0 
01319000-0135b000 rw-p 00000000 00:00 0                                  [heap]
7f18b3dea000-7f18b3e00000 r-xp 00000000 08:01 1315919                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f18b3e00000-7f18b3fff000 ---p 00016000 08:01 1315919                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f18b3fff000-7f18b4000000 rw-p 00015000 08:01 1315919                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f18b4000000-7f18b4021000 rw-p 00000000 00:00 0 
7f18b4021000-7f18b8000000 ---p 00000000 00:00 0 
7f18b81dd000-7f18b839d000 r-xp 00000000 08:01 1366856                    /lib/x86_64-linux-gnu/libc-2.23.so
7f18b839d000-7f18b859d000 ---p 001c0000 08:01 1366856                    /lib/x86_64-linux-gnu/libc-2.23.so
7f18b859d000-7f18b85a1000 r--p 001c0000 08:01 1366856                    /lib/x86_64-linux-gnu/libc-2.23.so
7f18b85a1000-7f18b85a3000 rw-p 001c4000 08:01 1366856                    /lib/x86_64-linux-gnu/libc-2.23.so
7f18b85a3000-7f18b85a7000 rw-p 00000000 00:00 0 
7f18b85a7000-7f18b86af000 r-xp 00000000 08:01 1315583                    /lib/x86_64-linux-gnu/libm-2.23.so
7f18b86af000-7f18b88ae000 ---p 00108000 08:01 1315583                    /lib/x86_64-linux-gnu/libm-2.23.so
7f18b88ae000-7f18b88af000 r--p 00107000 08:01 1315583                    /lib/x86_64-linux-gnu/libm-2.23.so
7f18b88af000-7f18b88b0000 rw-p 00108000 08:01 1315583                    /lib/x86_64-linux-gnu/libm-2.23.so
7f18b88b0000-7f18b88d6000 r-xp 00000000 08:01 1366854                    /lib/x86_64-linux-gnu/ld-2.23.so
7f18b8aaf000-7f18b8ab3000 rw-p 00000000 00:00 0 
7f18b8ad4000-7f18b8ad5000 rw-p 00000000 00:00 0 
7f18b8ad5000-7f18b8ad6000 r--p 00025000 08:01 1366854                    /lib/x86_64-linux-gnu/ld-2.23.so
7f18b8ad6000-7f18b8ad7000 rw-p 00026000 08:01 1366854                    /lib/x86_64-linux-gnu/ld-2.23.so
7f18b8ad7000-7f18b8ad8000 rw-p 00000000 00:00 0 
7fff6f0da000-7fff6f0fb000 rw-p 00000000 00:00 0                          [stack]
7fff6f127000-7fff6f12a000 r--p 00000000 00:00 0                          [vvar]
7fff6f12a000-7fff6f12c000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

And the output with asan

15:20 haclh@ubuntu:examples $ ./dwg2svg2 dfree_poc_155 
......................................................................
......................................................................
......................................................................
=================================================================
==101914==ERROR: AddressSanitizer: attempting double-free on 0x60400000dbd0 in thread T0:
    #0 0x7f9dcd3e32ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)
    #1 0x642d83 in dwg_free_eed /home/haclh/workplace/libredwg-0.5.1048/src/free.c:283
    #2 0x6513db in dwg_free_UNKNOWN_OBJ /home/haclh/workplace/libredwg-0.5.1048/src/dwg.spec:5437
    #3 0x6513db in dwg_free_BLOCK_HEADER /home/haclh/workplace/libredwg-0.5.1048/src/dwg.spec:2177
    #4 0x664f98 in dwg_free_object /home/haclh/workplace/libredwg-0.5.1048/src/free.c:471
    #5 0x667d2a in dwg_free /home/haclh/workplace/libredwg-0.5.1048/src/free.c:640
    #6 0x42d81d in test_SVG /home/haclh/workplace/libredwg-0.5.1048/examples/dwg2svg2.c:92
    #7 0x42d81d in main /home/haclh/workplace/libredwg-0.5.1048/examples/dwg2svg2.c:482
    #8 0x7f9dccfa182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x42de88 in _start (/home/haclh/workplace/libredwg-0.5.1048/examples/dwg2svg2+0x42de88)

0x60400000dbd0 is located 0 bytes inside of 40-byte region [0x60400000dbd0,0x60400000dbf8)
freed by thread T0 here:
    #0 0x7f9dcd3e32ca in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)
    #1 0x47ee9f in dwg_decode_eed /home/haclh/workplace/libredwg-0.5.1048/src/decode.c:2311

previously allocated by thread T0 here:
    #0 0x7f9dcd3e379a in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9879a)
    #1 0x47e349 in dwg_decode_eed /home/haclh/workplace/libredwg-0.5.1048/src/decode.c:2304

SUMMARY: AddressSanitizer: double-free ??:0 __interceptor_free
==101914==ABORTING

According debuging, I found that When open the crafted dwg file , dwg_free could call dwg_decode_eed , in dwg_free_object first, it could call dwg_free_BLOCK_HEADER to free a pointer (for example : 0x789430 )

void
dwg_free_object(Dwg_Object *obj)
{
  switch (obj->type)
    {
    case DWG_TYPE_TEXT:
    ........................
    ........................
    ........................
    case DWG_TYPE_BLOCK_HEADER:
      dwg_free_BLOCK_HEADER(dat, obj);
      break;

The backtrace are as below

   f 0     7ffff77884f0 free
 ► f 1           49a1c4 dwg_free_BLOCK_HEADER.isra.7+68
   f 2           4a18e9 dwg_free_object+1161
   f 3           4a239d dwg_free+157
   f 4           40d13f main+575
   f 5           40d13f main+575
   f 6     7ffff7724830 __libc_start_main+240

And then it could call dwg_free_BLOCK_HEADER again , it could call dwg_free_eed to free 0x789430 again.

The backtrace are as below

pwndbg> bt
#0  __GI___libc_free (mem=0x789430) at malloc.c:2934
#1  0x0000000000499e0b in dwg_free_eed (obj=0x7988e8, obj=0x7988e8) at free.c:283
#2  0x000000000049a31a in dwg_free_BLOCK_HEADER (obj=0x7988e8, _dat=<optimized out>) at dwg.spec:2285
#3  0x00000000004a18e9 in dwg_free_object (obj=0x7988e8) at free.c:471
#4  0x00000000004a239d in dwg_free (dwg=dwg@entry=0x769400 <g_dwg>) at free.c:640
#5  0x000000000040d13f in test_SVG (filename=<optimized out>) at dwg2svg2.c:92
#6  main (argc=argc@entry=2, argv=argv@entry=0x7fffffffe4c8) at dwg2svg2.c:479
#7  0x00007ffff7724830 in __libc_start_main (main=0x40cf00 <main>, argc=2, argv=0x7fffffffe4c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe4b8) at ../csu/libc-start.c:291
#8  0x000000000040d3a9 in _start ()

The poc file

https://gitee.com/hac425/fuzz_data/blob/master/double_free_on_libredwg_155

ERROR: Invalid LTYPE.dash x 61

When running over some dwgs from the same project I get the errors

Warning: Invalid handleref: wanted code 4, got (1.7.0)
ERROR: Invalid LTYPE.dash x 61

ERROR: Invalid LTYPE.dash x 215

ERROR: num_inserts [RC 0]: 136!

Warning: Invalid handleref: wanted code 4, got (1.7.0)
ERROR: Invalid LTYPE.dash x 61

ERROR: Invalid LTYPE.dash x 215

add a seperate signed BLd type

We just changed BL to signed. revert that and add a seperate BLd to represent the two such dxf ranges.
BL as signed is a problem for vcount/rcount overflow detection with negative values.

null pointer dereference in dwg_obj_block_control_get_block_headers

When open the crafted dwg file , it could tigger null point dereference in dwg2svg2

Let's see the gdb output


Program received signal SIGSEGV, Segmentation fault.
0x00000000005fc91c in dwg_obj_block_control_get_block_headers (ctrl=0xa51e30 <g_dwg+3088>, error=<optimized out>) at dwg_api.c:17897
17897	          ptx[i] = ctrl->block_headers[i];
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────────
*RAX  0x7ffff7f6c800 ◂— 0xbebebebebebebebe
*RBX  0xa51e30 (g_dwg+3088) —▸ 0x60800000bfa0 ◂— 0x0
*RCX  0x7ffff7f6c800 ◂— 0xbebebebebebebebe
 RDX  0x0
 RDI  0x0
 RSI  0x0
 R8   0x0
*R9   0xa51e50 (g_dwg+3120) ◂— 0x0
*R10  0x14a3ca
*R11  0x7ffff7f8c818 ◂— 0x0
*R12  0x7ffff7f6c800 ◂— 0xbebebebebebebebe
*R13  0x4002
*R14  0x7fffffffe280 ◂— 0x41b58ab3
 R15  0x0
*RBP  0x7fffffffe210 —▸ 0x7fffffffe300 —▸ 0x7fffffffe330 —▸ 0x7fffffffe3e0 —▸ 0x71ed30 (__libc_csu_init) ◂— ...
*RSP  0x7fffffffe1f0 ◂— 0x0
*RIP  0x5fc91c (dwg_obj_block_control_get_block_headers+217) ◂— mov    rdx, qword ptr [rdx]
──────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]───────────────────────────────────────────────────────────────────────────────────────────
 ► 0x5fc91c <dwg_obj_block_control_get_block_headers+217>    mov    rdx, qword ptr [rdx]
   0x5fc91f <dwg_obj_block_control_get_block_headers+220>    mov    rdi, rcx
   0x5fc922 <dwg_obj_block_control_get_block_headers+223>    mov    r8, rcx
   0x5fc925 <dwg_obj_block_control_get_block_headers+226>    shr    r8, 3
   0x5fc929 <dwg_obj_block_control_get_block_headers+230>    cmp    byte ptr [r8 + 0x7fff8000], 0
   0x5fc931 <dwg_obj_block_control_get_block_headers+238>    je     dwg_obj_block_control_get_block_headers+245 <0x5fc938>
    ↓
   0x5fc938 <dwg_obj_block_control_get_block_headers+245>    mov    qword ptr [rcx], rdx
   0x5fc93b <dwg_obj_block_control_get_block_headers+248>    add    rcx, 8
   0x5fc93f <dwg_obj_block_control_get_block_headers+252>    cmp    rcx, r11
   0x5fc942 <dwg_obj_block_control_get_block_headers+255>    jne    dwg_obj_block_control_get_block_headers+164 <0x5fc8e7>
    ↓
   0x5fc8e7 <dwg_obj_block_control_get_block_headers+164>    mov    rdx, rcx
───────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────────────────────────────────────────────────
   17892     {
   17893       BITCODE_BS i;
   17894       *error = 0;
   17895       for (i=0; i < ctrl->num_entries; i++)
   17896         {
 ► 17897           ptx[i] = ctrl->block_headers[i];
   17898         }
   17899       return ptx;
   17900     }
   17901   else
   17902     {
───────────────────────────────────────────────────────────────────────────────────────────[
pwndbg> p ptx
$1 = (dwg_object_ref **) 0x7ffff7f6c800
pwndbg> p ctrl->block_headers 
$2 = (Dwg_Object_Ref **) 0x0
pwndbg> bt
#0  0x00000000005fc91c in dwg_obj_block_control_get_block_headers (ctrl=0xa51e30 <g_dwg+3088>, error=<optimized out>) at dwg_api.c:17897
#1  0x0000000000403d88 in output_SVG (dwg=0xa51220 <g_dwg>) at dwg2svg2.c:358
#2  0x0000000000401af9 in test_SVG (filename=0x7fffffffe73a "segment_poc") at dwg2svg2.c:90
#3  0x0000000000404656 in main (argc=2, argv=0x7fffffffe4c8) at dwg2svg2.c:479
#4  0x00007ffff67b7830 in __libc_start_main (main=0x403fa3 <main>, argc=2, argv=0x7fffffffe4c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe4b8) at ../csu/libc-start.c:291
#5  0x0000000000401919 in _start ()
pwndbg> 

As you can see , crash in

ptx[i] = ctrl->block_headers[i];

and null point dereference is 0 , so null point dereference

The Vulnerability is that dwg_obj_block_control_get_block_headers in dwg_api.c don't check the ctrl->block_headers .

dwg_object_ref **
dwg_obj_block_control_get_block_headers(const dwg_obj_block_control *restrict ctrl,
                                        int *restrict error)
{
  dwg_object_ref **ptx = (dwg_object_ref**)
    malloc(ctrl->num_entries * sizeof(Dwg_Object_Ref *));
  if (ptx)
    {
      BITCODE_BS i;
      *error = 0;
      for (i=0; i < ctrl->num_entries; i++)
        {
          ptx[i] = ctrl->block_headers[i];
        }
      return ptx;
    }
  else
    {
      *error = 1;
      LOG_ERROR("%s: null malloc", __FUNCTION__)
      return NULL;
    }
}

To fix it, please verify the ctrl->block_headers before use it.

The poc file

https://gitee.com/hac425/fuzz_data/blob/master/poc.dwg

new/delete/free API fixup

The few new/delete/free functions from the dwg_api are basically useless,
as they don't add/delete the entity to the DWG. We need to add a Dwg_Object
and the associated Dwg_Object_Entity and then the Dwg_Entity_CIRCLE.
Same for delete.

See encode.c for dwg_add_##ENTITY for the proper API, but these are untested (waiting for dwgwrite/dxf2dwg).

Use dwg_add_##ENTITY and dwg_free_object() instead.

Add these to the header, and document it.

skip free optionally

with cmdline programs acting on really big files, free needs longer than processing the file.
e.g. with a 42MB DWG file, decode needs 40s and free >3m.

Add a flag to opts to skip it (0x20 is the next), used by the cmdline apps. The kernel is much faster and better freeing it.

Additionally think of replacing the linear search in object_refs with a hashmap, like in the benegon branch. But write it by myself for LICENSE reasons, and it can be much better then the simple Android hashmap.
Timings: -O2 linear: > 2m, hash: 5s.

limit exported symbols -fvisibility=hidden

add -fvisibility=hidden, and explicitly mark the public functions as EXPORT via
__attribute__((visibility("default"))) resp. __declspec(dllexport)

mimics windows default visibility

otherwise we might get into trouble later when changing internal functions.

HEADER.HANDSEED as HEX, and DXF off value

The HANDSEED DXF value never matches the HANDSEED DWG value.
See also https://sourceforge.net/p/libdwg/tickets/8/

$ grep -A2 HANDSEED td/Drawing_2000.dxf | tail -n1
6DF
$ grep HANDSEED Drawing_2000.log
HANDSEED: 0x5bc [RL 0]
HANDSEED: HANDLE(0.2.5BC) absolute:5BC [0]

printf "%x", 0x6df - 0x5bc => 0x123

This is libredwg unrelated and seems to be a DwgFiler/DxfFiler oddity.

But HANDSEED is a handle and needs to printed as hex.

api: separate dwg_decode_OBJECT and dwg_add_OBJECT

make it two functions, add as public API, which initializes the empty object. go away with the current add functions, which reads fields from an empty zero stream.

If possible add default values already at add, like from a DEFAULT { FIELD_VALUE(field) = 1.0; } block. rename IF_ENCODE_FROM_EARLIER to DEFAULT. It must be the first block in a spec, and probably it needs to be mandatory to close the add function and start the decode function.

Then reading the fields from the dwg is a separate function. This is needed for all in_* modules and dwg_encode.

This separation is also needed for ACAD_TABLE, jumping with r2010+ to dwg_ ##action _TABLECONTENT(dat,obj); without the initialization (add) code.

cygwin, ubuntu fails to link dejagnu

dejagnu itself is probed fine.

[00:01:15] checking dejagnu.h usability... yes
[00:01:15] checking dejagnu.h presence... yes
[00:01:15] checking for dejagnu.h... yes

e.g. https://ci.appveyor.com/project/rurban/libredwg/build/0.4.25/job/cprh3drj2u830jnm#L2249

libtool: link: gcc -fno-strict-aliasing -Wall -Wextra -Wundef -Wwrite-strings -Wpointer-arith -Wmissing-declarations -Wredundant-decls -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-missing-field-initializers -Wno-cast-align -Wformat=2 -Wformat-nonliteral -Wformat-security -Wsign-compare -Wstrict-aliasing -Wshadow -Winline -Wpacked -Wmissing-format-attribute -Wmissing-noreturn -Winit-self -Wmissing-include-dirs -Warray-bounds -Wreturn-type -Wswitch-enum -Wswitch-default -Wduplicated-cond -Wlogical-op -Wnull-dereference -Wdouble-promotion -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes -Wdeclaration-after-statement -Wimplicit-function-declaration -Wold-style-definition -Wjump-misses-init -Wno-error=unused-variable -Wno-error=unused-parameter -Wno-error=unused-but-set-variable -Wno-error=missing-field-initializers -Wno-error=cast-align -g -o .libs/3dsolid.exe 3dsolid.o ../../src/.libs/libredwg.dll.a -L/usr/local/lib

3dsolid.o: In function `api_process':
/cygdrive/c/projects/libredwg/testsuite/testcases/3dsolid.c:26: undefined reference to `pass'
/cygdrive/c/projects/libredwg/testsuite/testcases/3dsolid.c:28: undefined reference to `fail'
/cygdrive/c/projects/libredwg/testsuite/testcases/3dsolid.c:34: undefined reference to `pass'
/cygdrive/c/projects/libredwg/testsuite/testcases/3dsolid.c:36: undefined reference to `fail'
...

See https://gcc.gnu.org/bugzilla//show_bug.cgi?id=63613
we need to add -fgnu89-inline

rename *_count fields to num*

for consistency

include/dwg.h:  BITCODE_BL frozen_layer_count;
include/dwg.h:  BITCODE_BL instance_count; /* 91 Instance count for a custom class */
include/dwg.h:  BITCODE_BL owned_obj_count;
include/dwg.h:  BITCODE_BL owned_object_count;
include/dwg.h:  BITCODE_BS attr_def_count;
include/dwg.h:  BITCODE_BS m_vert_count;
include/dwg.h:  BITCODE_BS n_vert_count;
include/dwg.h:  BITCODE_RL insert_count;
include/dwg.h:dwg_get_entity_count(const Dwg_Data *);
include/dwg.h:dwg_get_layer_count(const Dwg_Data *);
include/dwg.h:dwg_get_object_count(const Dwg_Data *dwg);
include/dwg.h:dwg_get_object_object_count(const Dwg_Data *dwg);

e.g. dwg_get_numobjects, dwg_get_numentities, numfrozen_layers, ...

we have way more num* fields than _count.

configure failed

Hi, I installed all the dependencies the README mentioned, but when I excute "./configure --enable-trace --disable--write --disable-shared", still an error occured, please check it below:

checking for swig... /usr/bin/swig
checking SWIG version... 2.0.12
checking for SWIG library... /usr/share/swig2.0
checking for a Python interpreter with version >= 2.7... python
checking for python... /root/.pyenv/shims/python
checking for python version... 2.7
checking for python platform... linux2
checking for python script directory... ${prefix}/lib/python2.7/site-packages
checking for python extension module directory... ${exec_prefix}/lib/python2.7/site-packages
checking for python2.7... (cached) /root/.pyenv/shims/python
checking for a version of Python >= '2.1.0'... yes
checking for the distutils Python package... yes
checking for Python include path... -I/root/.pyenv/versions/2.7.9/include/python2.7
checking for Python library path...
ac_python_libdir=/root/.pyenv/versions/2.7.9/lib/python2.7/config
ac_python_library=libpython2.7.a
ac_python_soname=libpython2.7.a
use the --enable-frameworked shared library
-L/root/.pyenv/versions/2.7.9/lib/python2.7/config -lpython2.7
checking for Python site-packages path... /root/.pyenv/versions/2.7.9/lib/python2.7/site-packages
checking python extra libraries...  -lpthread -ldl  -lutil
checking python extra linking flags... -Xlinker -export-dynamic
checking consistency of all components of python development environment... no
configure: error: in `/home/odoo/new/libredwg-0.5.0.1176':
configure: error:
  Could not link test program to Python. Maybe the main Python library has been
  installed in some non-standard library path. If so, pass it to configure,
  via the LDFLAGS environment variable.
  Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
  ============================================================================
   ERROR!
   You probably have to install the development version of the Python package
   for your distribution.  The exact name of this package varies among them.
  ============================================================================

but I already installed python-dev, and I excute "./configure LDFLAGS="-L/root/.pyenv/versions/2.7.9/lib/python2.7" PYTHON="/root/.pyenv/shims/python" --enable-trace", same error still happed. Here's my config.log, anything wrong about it?
config.log

reduce codesize

it's getting absurd, 50MB for the lib.

use more generic helper functions, instead of inlining everything.

Excuse me, after I downloaded the file libredwg-0.4.900-win64, what should I do to use the libredwg?

I has downloaded the zip, I want to use this library in windows. I created a C++ project and add the dwg.h into the head like this:

extern "C"{
  #include <dwg.h>
}

and I copyed codes like this:

void main(){
	const char * inputFilename = "XXXX.dwg";
	Dwg_Data dwg = new Dwg_Data();
	int errno = dwg_read_file((char *)inputFilename, dwg);
	if (errno) {
		fprintf(stderr, "Could not open DWG. Returned error code: $d\n", errno);
		delete dwg;
	}

	Dwg_Object_BLOCK_CONTROL * ctrl = dwg->object[0].tio.object->tio.BLOCK_CONTROL;
	dumpBlock(ctrl->model_space);
	dumpBlock(ctrl->paper_space);

	for (int i = 0; i < ctrl->num_entries; i++) {
		dumpBlock(ctrl->block_headers[i]);
	}
	dwg_free(dwg);

}

but there are many bugs. what's wrong? Is that I can't add the dwg.h directly??? I'm not practice in writing codes.

fix SWIG bindings/switch to valabind

They are created fine, for python and perl (in branch work/perl), but then they seem to miss even the most basic functionality.

I'd like to use them for some basic UI DWG viewer of the internal structures.
Maybe switch over to valabind vapi bindings for most scripting languages and C#/C++: c++, rust, go, node, java, python, perl, ruby, php, autolisp (via ARX). With a proper vapi file the generated swig file also looks much better than now.

api: remove array num setters, add add/delete api

there exist various api functions to change the number of some elements without changing the associated array itself, e.g. dwg_ent_polyline_mesh_set_num_n_verts without setting the n_verts array.

all the set_num_ api functions need to go, and maybe add array add (at the end) and delete (at some index).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.