Skip to content

Commit

Permalink
bits: fix bit_read_BLL esp. for preview_size
Browse files Browse the repository at this point in the history
fixes the MESH problems from GH #1019
  • Loading branch information
rurban committed Sep 27, 2024
1 parent 2930c32 commit 771e7cd
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 88 deletions.
168 changes: 90 additions & 78 deletions src/bits.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,58 +244,6 @@ bit_write_BB (Bit_Chain *dat, unsigned char value)
bit_advance_position (dat, 2);
}

/** Read 1-3 bits
* Keep reading bits until a zero bit is encountered, => 0,2,6,7.
* 0: 0, 10: 2, 110: 6, 111: 7. 100 for 4 or 101 for 5 is invalid.
*/
BITCODE_3B
bit_read_3B (Bit_Chain *dat)
{
BITCODE_3B result = bit_read_B (dat);
if (result)
{
BITCODE_3B next = bit_read_B (dat);
if (next)
{
next = bit_read_B (dat);
return next ? 7 : 6;
}
else
{
return 2;
}
}
else
{
return 0;
}
}

/** Write 1-3 bits
*/
void
bit_write_3B (Bit_Chain *dat, unsigned char value)
{
if (value > 7)
{
loglevel = dat->opts & DWG_OPTS_LOGLEVEL;
LOG_ERROR ("Invalid bit_write_3B value %u > 7", value)
bit_write_B (dat, 0);
return;
}
bit_write_B (dat, value & 1);
if (value)
{
value >>= 1;
bit_write_B (dat, value & 1);
if (value)
{
value >>= 1;
bit_write_B (dat, value & 1);
}
}
}

/** Read 4 bits.
*/
BITCODE_4BITS
Expand Down Expand Up @@ -750,7 +698,7 @@ bit_write_BOT (Bit_Chain *dat, BITCODE_BS value)
}

/** Read 1 bitlonglong (compacted uint64_t) for REQUIREDVERSIONS, preview_size.
* ODA doc bug. ODA say 1-3 bits until the first 0 bit. See 3BLL.
* ODA doc bug. ODA say 1-3 bits until the first 0 bit. See 3BLL below.
* The first 3 bits indicate the length len (see paragraph 2.1). Then
* len bytes follow, which represent the number (the least significant
* byte is first).
Expand All @@ -771,35 +719,16 @@ bit_read_BLL (Bit_Chain *dat)
return bit_read_RL (dat);
default:
CHK_OVERFLOW (__FUNCTION__, 0)
for (i = 0; i < len; i++)
for (i = 0; i < 8; i++)
{
result <<= 8;
result |= bit_read_RC (dat);
if (i < len)
result |= bit_read_RC (dat);
}
return result;
return be64toh (result);
}
}

/** Read 1 bitlonglong (compacted uint64_t) as documented (but unused).
* The first 1-3 bits indicate the length l (see paragraph 2.1). Then
* l bytes follow, which represent the number (the least significant
* byte is first).
*/
BITCODE_BLL
bit_read_3BLL (Bit_Chain *dat)
{
unsigned int i, len;
BITCODE_BLL result = 0ULL;
len = bit_read_3B (dat);
CHK_OVERFLOW (__FUNCTION__, 0)
for (i = 0; i < len; i++)
{
result <<= 8;
result |= bit_read_RC (dat);
}
return result;
}

/** Write 1 bitlonglong (compacted data).
*/
void
Expand All @@ -821,10 +750,94 @@ bit_write_BLL (Bit_Chain *dat, BITCODE_BLL value)
bit_write_B (dat, len & 1);
for (i = 0; i < len; i++)
{
// least significant byte first
bit_write_RC (dat, value & 0xFF);
value >>= 8;
}
}

#if 0
/** Read 1-3 bits. As falsely documented in ODA for BLL, but unused.
* Keep reading bits until a zero bit is encountered, => 0,2,6,7.
* 0: 0, 10: 2, 110: 6, 111: 7. 100 for 4 or 101 for 5 is invalid.
*/
BITCODE_3B
bit_read_3B (Bit_Chain *dat)
{
BITCODE_3B result = bit_read_B (dat);
if (result)
{
BITCODE_3B next = bit_read_B (dat);
if (next)
{
next = bit_read_B (dat);
return next ? 7 : 6;
}
else
{
return 2;
}
}
else
{
return 0;
}
}
/** Write 1-3 bits
*/
void
bit_write_3B (Bit_Chain *dat, unsigned char value)
{
if (value > 7)
{
loglevel = dat->opts & DWG_OPTS_LOGLEVEL;
LOG_ERROR ("Invalid bit_write_3B value %u > 7", value)
bit_write_B (dat, 0);
return;
}
bit_write_B (dat, value & 1);
if (value)
{
value >>= 1;
bit_write_B (dat, value & 1);
if (value)
{
value >>= 1;
bit_write_B (dat, value & 1);
}
}
}
/** Read 1 bitlonglong (compacted uint64_t) as documented (but unused).
* The first 1-3 bits indicate the length l (see paragraph 2.1). Then
* l bytes follow, which represent the number (the least significant
* byte is first).
*/
BITCODE_BLL
bit_read_3BLL (Bit_Chain *dat)
{
unsigned int i, len;
BITCODE_BLL result = 0ULL;
len = bit_read_3B (dat);
CHK_OVERFLOW (__FUNCTION__, 0)
switch (len)
{
case 1:
return bit_read_RC (dat);
case 2:
return bit_read_RS (dat);
case 4:
return bit_read_RL (dat);
default:
for (i = 0; i < len; i++)
{
// least significant byte first
result |= bit_read_RC (dat);
result >>= 8;
}
return result;
}
}

void
bit_write_3BLL (Bit_Chain *dat, BITCODE_BLL value)
{
Expand All @@ -848,6 +861,7 @@ bit_write_3BLL (Bit_Chain *dat, BITCODE_BLL value)
value >>= 8;
}
}
#endif

/** Read 1 bitdouble (compacted data).
*/
Expand Down Expand Up @@ -1614,9 +1628,7 @@ bit_read_fixed (Bit_Chain *restrict dat, BITCODE_RC *restrict dest,
else
{
for (size_t i = 0; i < length; i++)
{
dest[i] = bit_read_RC (dat);
}
}
return 0;
}
Expand Down
10 changes: 6 additions & 4 deletions src/bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ void bit_write_B (Bit_Chain *dat, unsigned char value);
BITCODE_BB bit_read_BB (Bit_Chain *dat);
void bit_write_BB (Bit_Chain *dat, unsigned char value);

BITCODE_3B bit_read_3B (Bit_Chain *dat);
void bit_write_3B (Bit_Chain *dat, unsigned char value);

BITCODE_4BITS bit_read_4BITS (Bit_Chain *dat);
void bit_write_4BITS (Bit_Chain *dat, unsigned char value);

Expand Down Expand Up @@ -145,9 +142,14 @@ BITCODE_BS bit_read_BOT (Bit_Chain *dat);
void bit_write_BOT (Bit_Chain *dat, BITCODE_BS value);

BITCODE_BLL bit_read_BLL (Bit_Chain *dat);
BITCODE_BLL bit_read_3BLL (Bit_Chain *dat); /*unused but as documented*/
void bit_write_BLL (Bit_Chain *dat, BITCODE_BLL value);

#if 0
BITCODE_3B bit_read_3B (Bit_Chain *dat);
void bit_write_3B (Bit_Chain *dat, unsigned char value);
BITCODE_BLL bit_read_3BLL (Bit_Chain *dat); /*unused but as documented*/
void bit_write_3BLL (Bit_Chain *dat, BITCODE_BLL value);
#endif

BITCODE_BD bit_read_BD (Bit_Chain *dat);
void bit_write_BD (Bit_Chain *dat, BITCODE_BD value);
Expand Down
7 changes: 4 additions & 3 deletions src/common_entity_data.spec
Original file line number Diff line number Diff line change
Expand Up @@ -321,16 +321,17 @@
FIELD_BLL (preview_size, 160);
}
#endif
if ((long)_ent->preview_size >= 0 &&
if ((int64_t)_ent->preview_size >= 0 &&
_ent->preview_size < (obj->size ? obj->size : dat->size))
{
FIELD_BINARY (preview, _ent->preview_size, 310);
}
#ifndef IS_FREE
else
{
LOG_ERROR ("Invalid preview_size: " FORMAT_BLL " kB",
_ent->preview_size / 1000);
LOG_ERROR ("Invalid preview_size: " FORMAT_BLL " > %lu",
_ent->preview_size,
(unsigned long)(obj->size ? obj->size : dat->size));
error |= DWG_ERR_VALUEOUTOFBOUNDS;
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/dwg.spec
Original file line number Diff line number Diff line change
Expand Up @@ -8763,7 +8763,7 @@ DWG_ENTITY (MESH)
SET_PARENT_OBJ (edges[rcount1]);
END_REPEAT_BLOCK
END_REPEAT (edges);
//FIELD_VECTOR (edges, BL, num_edges * 2, 90);
// or FIELD_VECTOR (edges, BL, num_edges * 2, 90);
FIELD_BL (num_crease, 95); // edge creases 19
FIELD_VECTOR (crease, BD, num_crease, 140);
FIELD_B (unknown_b1, 0);
Expand Down
6 changes: 4 additions & 2 deletions test/unit-testing/bits_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ bit_write_BB_tests (void)
bitfree (&bitchain);
}

#if 0
static void
bit_read_3B_tests (void)
{
Expand Down Expand Up @@ -106,6 +107,7 @@ bit_write_3B_tests (void)
fail ("bit_write_3B %d", bitchain.chain[0]);
bitfree (&bitchain);
}
#endif

/* This function calls tests for bit_write_4BITS_tests()
Used in VIEW view_mode, type 71
Expand Down Expand Up @@ -1364,8 +1366,8 @@ main (int argc, char const *argv[])
bit_advance_position_tests ();
bit_read_BB_tests ();
bit_write_BB_tests ();
bit_read_3B_tests ();
bit_write_3B_tests ();
// bit_read_3B_tests ();
// bit_write_3B_tests ();
bit_read_4BITS_tests ();
bit_write_4BITS_tests ();
bit_read_BLL_tests ();
Expand Down

0 comments on commit 771e7cd

Please sign in to comment.