Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split objfreespace and second header #929

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions include/dwg.h
Original file line number Diff line number Diff line change
Expand Up @@ -9054,10 +9054,11 @@ typedef enum DWG_SECTION_TYPE_R13
SECTION_HEADER_R13 = 0,
SECTION_CLASSES_R13 = 1,
SECTION_HANDLES_R13 = 2,
SECTION_OBJFREESPACE_R13 = 3, /* including the 2ndheader */
SECTION_OBJFREESPACE_R13 = 3,
SECTION_TEMPLATE_R13 = 4,
SECTION_AUXHEADER_R2000 = 5,
SECTION_THUMBNAIL_R13 = 6,
SECTION_SECOND_HEADER_R13 = 7,
} Dwg_Section_Type_r13;

typedef enum DWG_SECTION_TYPE_R11 /* tables */
Expand Down Expand Up @@ -9396,7 +9397,7 @@ typedef struct _dwg_header
BITCODE_RL summaryinfo_address; /* R2004+ */
BITCODE_RL vbaproj_address; /* R2004+ */
BITCODE_RL r2004_header_address; /* R2004+ */
BITCODE_RL sections; // as in the header, 5 or 6 usually
BITCODE_RL sections; // as in the header, 3 .. 6 usually
BITCODE_RL num_sections; // as allocated, many more
Dwg_Section *section;
Dwg_Section_InfoHdr section_infohdr; /* R2004+ */
Expand Down
1 change: 0 additions & 1 deletion src/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,6 @@ decode_R13_R2000 (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
* 1: class section
* 2: Handles (object map)
* 3: optional: ObjFreeSpace
* -: 2ndHeader and its sentinels
* 4: optional: Template (MEASUREMENT)
* 5: optional: AuxHeader (no sentinels, since R13c3)
*/
Expand Down
36 changes: 21 additions & 15 deletions src/dwg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3473,30 +3473,36 @@ dwg_sections_init (Dwg_Data *dwg)
/* section 0: header vars
* 1: class section
* 2: object map (i.e. handles)
* 3: optional ObjFreeSpace (r13+, no sentinels) + 2ndheader (r13+, sentinels)
* 3: optional ObjFreeSpace (r13c3+, no sentinels)
* 7: 2ndheader (not a section, r13+, sentinels)
* 4: optional: Template (MEASUREMENT)
* 5: optional: AuxHeader (no sentinels, since R_2000b)
* 6: optional: THUMBNAIL (not a section, but treated as one)
*/
if (!dwg->header.num_sections ||
(dwg->header.from_version > R_2000 && dwg->header.version <= R_2000))
{
dwg->header.num_sections = dwg->header.version < R_13c3 ? 3
: dwg->header.version < R_2000b ? 5
: 6;
if (dwg->header.num_sections == 3 && dwg->objfreespace.numnums)
dwg->header.num_sections = 5;
if (dwg->header.sections)
{
// Plus thumbnail and second header
dwg->header.num_sections = dwg->header.sections + 2;
}
else
{
dwg->header.num_sections = dwg->header.version < R_13c3 ? 5
: dwg->header.version < R_2000b ? 7
: 8;
if (dwg->header.num_sections == 5 && dwg->objfreespace.numnums)
dwg->header.num_sections = 6;
}
}
if (!dwg->header.sections ||
(dwg->header.from_version > R_2000 && dwg->header.version <= R_2000))
// ODA writes zeros
dwg->header.sections = dwg->header.num_sections;
// newer DWG's have proper HEADER.sections
if (dwg->header.num_sections != dwg->header.sections)
dwg->header.num_sections = dwg->header.sections;
// ODA writes zeros
dwg->header.sections = dwg->header.num_sections - 2;
}
LOG_TRACE ("num_sections => " FORMAT_RL "\n", dwg->header.num_sections);
if (dwg->header.num_sections < 3)
if (dwg->header.num_sections < 5)
{
LOG_ERROR ("Not enough sections: " FORMAT_RL, dwg->header.num_sections);
return DWG_ERR_INVALIDDWG;
Expand All @@ -3508,12 +3514,12 @@ dwg_sections_init (Dwg_Data *dwg)
}

if (dwg->header.section)
// zero-based, including THUMBNAIL
// zero-based, including THUMBNAIL and Second Header
dwg->header.section = (Dwg_Section *)realloc (
dwg->header.section,
sizeof (Dwg_Section) * (dwg->header.num_sections + 2));
sizeof (Dwg_Section) * (dwg->header.num_sections));
else
dwg->header.section = (Dwg_Section *)calloc (dwg->header.num_sections + 2,
dwg->header.section = (Dwg_Section *)calloc (dwg->header.num_sections,
sizeof (Dwg_Section));
if (!dwg->header.section)
{
Expand Down
58 changes: 35 additions & 23 deletions src/encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static BITCODE_BL rcount1 = 0, rcount2 = 0;
/* section_order: A static array of section types.
SECTION_R13_SIZE is the size and the sentinel.
*/
#define SECTION_R13_SIZE 7U
#define SECTION_R13_SIZE 8U
static Dwg_Section_Type_r13 section_order[SECTION_R13_SIZE] = { 0 };

#ifdef USE_TRACING
Expand Down Expand Up @@ -1998,7 +1998,7 @@ find_section_info_type (const Dwg_Data *restrict dwg, Dwg_Section_Type type)
return NULL;
}

/* Ordering of r13-r2000 sections 0-6 */
/* Ordering of r13-r2000 sections 0-7 */
static void
section_order_trace (const Dwg_Data *dwg,
const BITCODE_BL numsections,
Expand Down Expand Up @@ -3080,13 +3080,12 @@ encode_objects_handles (Dwg_Data *restrict dwg, Bit_Chain *restrict dat,
}

static int
encode_objfreespace_2ndheader (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
encode_objfreespace (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
{
int error = 0;

/*------------------------------------------------------------
* ObjFreeSpace and Second header - r13-r2000 only.
* Note: partially also since r2004.
* ObjFreeSpace - r13c3-r2000 only.
*/
if (dwg->header.version >= R_13 && dwg->header.version < R_2004
&& dwg->header.num_sections > 3)
Expand All @@ -3105,8 +3104,18 @@ encode_objfreespace_2ndheader (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
}
}

if (dwg->header.version >= R_13 && dwg->header.version < R_2004 &&
dwg->secondheader.codepage)
return error;
}

static int
encode_2ndheader (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
{
int error = 0;

/*------------------------------------------------------------
* Second Header - r13-r2000 only.
*/
if (dwg->header.version >= R_13 && dwg->header.version < R_2004)
{
struct _dwg_secondheader *_obj = &dwg->secondheader;
Dwg_Object *obj = NULL;
Expand Down Expand Up @@ -3733,15 +3742,15 @@ dwg_encode (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
THUMBNAIL
* 2: Handles
* 3: ObjFreeSpace (r13c3+, optional)
+ 2NDHEADER (r13-r2000)
* 7: 2NDHEADER (r13-r2000, not a section)
* 4: Template (r14-r2000, optional)
* 5: AuxHeader (r2000, no sentinels)
* 6: THUMBNAIL (r13c3+, not a section)
*/

/* Usually 3-5, max 6 */
/* Usually 5-7, max 8 */
if (!dwg->header.num_sections
|| (dat->from_version >= R_2004 && dwg->header.num_sections > 6))
|| (dat->from_version >= R_2004 && dwg->header.num_sections > 8))
{
if (dwg->header.version <= R_2000)
{
Expand All @@ -3750,11 +3759,11 @@ dwg_encode (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
else
dwg->header.num_sections
= dwg->auxheader.dwg_version && dwg->header.version == R_2000
? 6
: 5;
? 7
: 6;
}
else
dwg->header.num_sections = 6;
dwg->header.num_sections = 7;
// minimal DXF:
// if (dwg->opts & (DWG_OPTS_INDXF | DWG_OPTS_MINIMAL)
// && (!dwg->header_vars.HANDSEED ||
Expand Down Expand Up @@ -3784,19 +3793,23 @@ dwg_encode (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
if (dwg->header.sections > 3)
{
section_order[3] = SECTION_OBJFREESPACE_R13;
section_order[4] = SECTION_TEMPLATE_R13;
section_order[4] = SECTION_SECOND_HEADER_R13;
section_order[5] = SECTION_TEMPLATE_R13;
if (dwg->header.sections > 5)
{
section_order[5] = SECTION_AUXHEADER_R2000;
section_order[6] = SECTION_THUMBNAIL_R13;
section_order[6] = SECTION_AUXHEADER_R2000;
section_order[7] = SECTION_THUMBNAIL_R13;
}
else
{
section_order[5] = SECTION_THUMBNAIL_R13;
section_order[6] = SECTION_THUMBNAIL_R13;
}
}
else
section_order[3] = SECTION_THUMBNAIL_R13;
{
section_order[3] = SECTION_THUMBNAIL_R13;
section_order[4] = SECTION_SECOND_HEADER_R13;
}

if (DWG_LOGLEVEL >= DWG_LOGLEVEL_TRACE)
section_order_trace (dwg, dwg->header.num_sections,
Expand Down Expand Up @@ -3915,7 +3928,10 @@ dwg_encode (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
error |= encode_objects_handles (dwg, dat, (Bit_Chain **)&sec_dat);
break;
case SECTION_OBJFREESPACE_R13:
error |= encode_objfreespace_2ndheader (dwg, dat);
error |= encode_objfreespace (dwg, dat);
break;
case SECTION_SECOND_HEADER_R13:
error |= encode_2ndheader (dwg, dat);
break;
case SECTION_TEMPLATE_R13:
error |= encode_template (dwg, dat);
Expand All @@ -3932,10 +3948,6 @@ dwg_encode (Dwg_Data *restrict dwg, Bit_Chain *restrict dat)
}
}
}
if (dwg->header.sections == 3 && dwg->secondheader.codepage)
{
error |= encode_objfreespace_2ndheader (dwg, dat);
}
} // VERSIONS (R_13b1, R_2004)

VERSIONS (R_2007a, R_2007)
Expand Down
Loading