u-boot/lib/gzip.c
Simon Glass 6e295186c7 Move malloc_cache_aligned() to its own header
At present malloc.h is included everywhere since it recently was added to
common.h in this commit:

   4519668 mtd/nand/ubi: assortment of alignment fixes

This seems wasteful and unnecessary. We have been trying to trim down
common.h and put separate functions into separate header files and that
change goes in the opposite direction.

Move malloc_cache_aligned() to a new header so that this can be avoided.
The header would perhaps be better named as alignmem.h but it needs to be
included after common.h and people might be confused by this. With the name
memalign.h it fits nicely after malloc() in most cases.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
2015-09-11 17:15:16 -04:00

128 lines
2.6 KiB
C

/*
* (C) Copyright 2012
* Lei Wen <leiwen@marvell.com>, Marvell Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <malloc.h>
#include <memalign.h>
#include <u-boot/zlib.h>
#include "zlib/zutil.h"
#ifndef CONFIG_GZIP_COMPRESS_DEF_SZ
#define CONFIG_GZIP_COMPRESS_DEF_SZ 0x200
#endif
#define ZALLOC_ALIGNMENT 16
static void *zalloc(void *x, unsigned items, unsigned size)
{
void *p;
size *= items;
size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
p = malloc_cache_aligned(size);
return (p);
}
static void zfree(void *x, void *addr, unsigned nb)
{
free (addr);
}
int gzip(void *dst, unsigned long *lenp,
unsigned char *src, unsigned long srclen)
{
return zzip(dst, lenp, src, srclen, 1, NULL);
}
/*
* Compress blocks with zlib
*/
int zzip(void *dst, unsigned long *lenp, unsigned char *src,
unsigned long srclen, int stoponerr,
int (*func)(unsigned long, unsigned long))
{
z_stream s;
int r, flush, orig, window;
unsigned long comp_len, left_len;
if (!srclen)
return 0;
#ifndef CONFIG_GZIP
window = MAX_WBITS;
#else
window = 2 * MAX_WBITS;
#endif
orig = *lenp;
s.zalloc = zalloc;
s.zfree = zfree;
s.opaque = Z_NULL;
r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window,
DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
ZLIB_VERSION, sizeof(z_stream));
if (r != Z_OK) {
printf ("Error: deflateInit2_() returned %d\n", r);
return -1;
}
while (srclen > 0) {
comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
CONFIG_GZIP_COMPRESS_DEF_SZ : srclen;
s.next_in = src;
s.avail_in = comp_len;
flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)?
Z_NO_FLUSH : Z_FINISH;
do {
left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp;
s.next_out = dst;
s.avail_out = left_len;
r = deflate(&s, flush);
if (r == Z_STREAM_ERROR && stoponerr == 1) {
printf("Error: deflate() returned %d\n", r);
r = -1;
goto bail;
}
if (!func) {
dst += (left_len - s.avail_out);
*lenp -= (left_len - s.avail_out);
} else if (left_len - s.avail_out > 0) {
r = func((unsigned long)dst,
left_len - s.avail_out);
if (r < 0)
goto bail;
}
} while (s.avail_out == 0 && (*lenp > 0));
if (s.avail_in) {
printf("Deflate failed to consume %u bytes", s.avail_in);
r = -1;
goto bail;
}
if (*lenp == 0) {
printf("Deflate need more space to compress "
"left %lu bytes\n", srclen);
r = -1;
goto bail;
}
srclen -= comp_len;
src += comp_len;
}
r = 0;
bail:
deflateEnd(&s);
*lenp = orig - *lenp;
return r;
}