#define ZUTIL_H
#define ZLIB_INTERNAL
+#include <common.h>
+#include <compiler.h>
+#include <asm/unaligned.h>
#include "u-boot/zlib.h"
+#undef OFF /* avoid conflicts */
+
/* To avoid a build time warning */
#ifdef STDC
#include <malloc.h>
/* Diagnostic functions */
#ifdef DEBUG
-#include <stdio.h>
extern int z_verbose;
extern void z_error OF((char *m));
#define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#define fprintf(fp,...) printf(__VA_ARGS__)
#define Trace(x) {if (z_verbose>=0) fprintf x ;}
#define Tracev(x) {if (z_verbose>0) fprintf x ;}
#define Tracevv(x) {if (z_verbose>1) fprintf x ;}
*/
#define OFF 1
#define PUP(a) *++(a)
+#define UP_UNALIGNED(a) get_unaligned(++(a))
/*
Decode literal, length, and distance codes and write out the resulting
}
}
else {
+ unsigned short *sout;
+ unsigned long loops;
+
from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
+ /* minimum length is three */
+ /* Align out addr */
+ if (!((long)(out - 1 + OFF) & 1)) {
+ PUP(out) = PUP(from);
+ len--;
+ }
+ sout = (unsigned short *)(out - OFF);
+ if (dist > 2 ) {
+ unsigned short *sfrom;
+
+ sfrom = (unsigned short *)(from - OFF);
+ loops = len >> 1;
+ do
+ PUP(sout) = UP_UNALIGNED(sfrom);
+ while (--loops);
+ out = (unsigned char *)sout + OFF;
+ from = (unsigned char *)sfrom + OFF;
+ } else { /* dist == 1 or dist == 2 */
+ unsigned short pat16;
+
+ pat16 = *(sout-2+2*OFF);
+ if (dist == 1)
+#if defined(__BIG_ENDIAN)
+ pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
+#elif defined(__LITTLE_ENDIAN)
+ pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00 ) >> 8);
+#else
+#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
+#endif
+ loops = len >> 1;
+ do
+ PUP(sout) = pat16;
+ while (--loops);
+ out = (unsigned char *)sout + OFF;
+ }
+ if (len & 1)
+ PUP(out) = PUP(from);
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
state->hold = 0;
state->bits = 0;
state->lencode = state->distcode = state->next = state->codes;
+ if (strm->outcb != Z_NULL)
+ (*strm->outcb)(Z_NULL, 0);
Tracev((stderr, "inflate: reset\n"));
return Z_OK;
}
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
- if (state->window != Z_NULL) ZFREE(strm, state->window);
+ if (state->window != Z_NULL) {
+ if (strm->outcb != Z_NULL)
+ (*strm->outcb)(Z_NULL, 0);
+ ZFREE(strm, state->window);
+ }
ZFREE(strm, strm->state);
strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
char *m;
{
fprintf(stderr, "%s\n", m);
- exit(1);
+ hang ();
}
#endif