Skip to content

Commit

Permalink
Split objfreespace and second header
Browse files Browse the repository at this point in the history
  • Loading branch information
michal-josef-spacek committed Mar 18, 2024
1 parent 417dfee commit 7c75779
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 41 deletions.
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

0 comments on commit 7c75779

Please sign in to comment.