Skip to content
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
2 changes: 1 addition & 1 deletion surface/include/pcl/surface/3rdparty/opennurbs/inffast.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
subject to change. Applications should only use zlib.h.
*/

void inflate_fast OF((z_streamp strm, unsigned start));
void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start);
162 changes: 82 additions & 80 deletions surface/src/3rdparty/opennurbs/inffast.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,9 @@
#include "pcl/surface/3rdparty/opennurbs/inflate.h"
#include "pcl/surface/3rdparty/opennurbs/inffast.h"

#ifndef ASMINF

/* Allow machine dependent optimization for post-increment or pre-increment.
Based on testing to date,
Pre-increment preferred for:
- PowerPC G3 (Adler)
- MIPS R5000 (Randers-Pehrson)
Post-increment preferred for:
- none
No measurable difference:
- Pentium III (Anderson)
- M68060 (Nikl)
*/
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
#ifdef ASMINF
# pragma message("Assembler code may have bugs -- use at your own risk")
#else
# define OFF 1
# define PUP(a) *++(a)
#endif

/*
Decode literal, length, and distance codes and write out the resulting
Expand Down Expand Up @@ -64,13 +47,10 @@
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
struct inflate_state FAR *state;
unsigned char FAR *in; /* local strm->next_in */
unsigned char FAR *last; /* while in < last, enough input available */
z_const unsigned char FAR *in; /* local strm->next_in */
z_const unsigned char FAR *last; /* have enough input while in < last */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
Expand All @@ -79,15 +59,15 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned int hold; /* local strm->hold */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
code this; /* retrieved table entry */
code const *here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
Expand All @@ -96,17 +76,17 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */

/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
in = strm->next_in - OFF;
in = strm->next_in;
last = in + (strm->avail_in - 5);
out = strm->next_out - OFF;
out = strm->next_out;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize;
whave = state->whave;
write = state->write;
wnext = state->wnext;
window = state->window;
hold = state->hold;
bits = state->bits;
Expand All @@ -119,29 +99,29 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
input data or output space */
do {
if (bits < 15) {
hold += (unsigned int)(PUP(in)) << bits;
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned int)(PUP(in)) << bits;
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
this = lcode[hold & lmask];
here = lcode + (hold & lmask);
dolen:
op = (unsigned)(this.bits);
op = (unsigned)(here->bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op);
op = (unsigned)(here->op);
if (op == 0) { /* literal */
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", this.val));
PUP(out) = (unsigned char)(this.val);
"inflate: literal 0x%02x\n", here->val));
*out++ = (unsigned char)(here->val);
}
else if (op & 16) { /* length base */
len = (unsigned)(this.val);
len = (unsigned)(here->val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
hold += (unsigned int)(PUP(in)) << bits;
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
Expand All @@ -150,25 +130,25 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
hold += (unsigned int)(PUP(in)) << bits;
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned int)(PUP(in)) << bits;
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
this = dcode[hold & dmask];
here = dcode + (hold & dmask);
dodist:
op = (unsigned)(this.bits);
op = (unsigned)(here->bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op);
op = (unsigned)(here->op);
if (op & 16) { /* distance base */
dist = (unsigned)(this.val);
dist = (unsigned)(here->val);
op &= 15; /* number of extra bits */
if (bits < op) {
hold += (unsigned int)(PUP(in)) << bits;
hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned int)(PUP(in)) << bits;
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
}
Expand All @@ -187,79 +167,101 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
if (state->sane) {
strm->msg =
(char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (len <= op - whave) {
do {
*out++ = 0;
} while (--len);
continue;
}
len -= op - whave;
do {
*out++ = 0;
} while (--op > whave);
if (op == 0) {
from = out - dist;
do {
*out++ = *from++;
} while (--len);
continue;
}
#endif
}
from = window - OFF;
if (write == 0) { /* very common case */
from = window;
if (wnext == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
else if (write < op) { /* wrap around window */
from += wsize + write - op;
op -= write;
else if (wnext < op) { /* wrap around window */
from += wsize + wnext - op;
op -= wnext;
if (op < len) { /* some from end of window */
len -= op;
do {
PUP(out) = PUP(from);
*out++ = *from++;
} while (--op);
from = window - OFF;
if (write < len) { /* some from start of window */
op = write;
from = window;
if (wnext < len) { /* some from start of window */
op = wnext;
len -= op;
do {
PUP(out) = PUP(from);
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
from += write - op;
from += wnext - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
*out++ = *from++;
*out++ = *from++;
*out++ = *from++;
len -= 3;
}
if (len) {
PUP(out) = PUP(from);
*out++ = *from++;
if (len > 1)
PUP(out) = PUP(from);
*out++ = *from++;
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
*out++ = *from++;
*out++ = *from++;
*out++ = *from++;
len -= 3;
} while (len > 2);
if (len) {
PUP(out) = PUP(from);
*out++ = *from++;
if (len > 1)
PUP(out) = PUP(from);
*out++ = *from++;
}
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
this = dcode[this.val + (hold & ((1U << op) - 1))];
here = dcode + here->val + (hold & ((1U << op) - 1));
goto dodist;
}
else {
Expand All @@ -269,7 +271,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
this = lcode[this.val + (hold & ((1U << op) - 1))];
here = lcode + here->val + (hold & ((1U << op) - 1));
goto dolen;
}
else if (op & 32) { /* end-of-block */
Expand All @@ -291,8 +293,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
hold &= (1U << bits) - 1;

/* update state and return */
strm->next_in = in + OFF;
strm->next_out = out + OFF;
strm->next_in = in;
strm->next_out = out;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
Expand All @@ -305,7 +307,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and write == 0
- Three separate decoding do-loops for direct, window, and wnext == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
Expand Down