uboot/lib/gzip.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2012
   3 * Lei Wen <leiwen@marvell.com>, Marvell Inc.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <watchdog.h>
  10#include <command.h>
  11#include <image.h>
  12#include <malloc.h>
  13#include <memalign.h>
  14#include <u-boot/zlib.h>
  15#include "zlib/zutil.h"
  16
  17#ifndef CONFIG_GZIP_COMPRESS_DEF_SZ
  18#define CONFIG_GZIP_COMPRESS_DEF_SZ     0x200
  19#endif
  20#define ZALLOC_ALIGNMENT                16
  21
  22static void *zalloc(void *x, unsigned items, unsigned size)
  23{
  24        void *p;
  25
  26        size *= items;
  27        size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
  28
  29        p = malloc_cache_aligned(size);
  30
  31        return (p);
  32}
  33
  34static void zfree(void *x, void *addr, unsigned nb)
  35{
  36        free (addr);
  37}
  38
  39int gzip(void *dst, unsigned long *lenp,
  40                unsigned char *src, unsigned long srclen)
  41{
  42        return zzip(dst, lenp, src, srclen, 1, NULL);
  43}
  44
  45/*
  46 * Compress blocks with zlib
  47 */
  48int zzip(void *dst, unsigned long *lenp, unsigned char *src,
  49                unsigned long srclen, int stoponerr,
  50                int (*func)(unsigned long, unsigned long))
  51{
  52        z_stream s;
  53        int r, flush, orig, window;
  54        unsigned long comp_len, left_len;
  55
  56        if (!srclen)
  57                return 0;
  58
  59#ifndef CONFIG_GZIP
  60        window = MAX_WBITS;
  61#else
  62        window = 2 * MAX_WBITS;
  63#endif
  64        orig = *lenp;
  65        s.zalloc = zalloc;
  66        s.zfree = zfree;
  67        s.opaque = Z_NULL;
  68
  69        r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window,
  70                        DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  71                        ZLIB_VERSION, sizeof(z_stream));
  72        if (r != Z_OK) {
  73                printf ("Error: deflateInit2_() returned %d\n", r);
  74                return -1;
  75        }
  76
  77        while (srclen > 0) {
  78                comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
  79                                CONFIG_GZIP_COMPRESS_DEF_SZ : srclen;
  80
  81                s.next_in = src;
  82                s.avail_in = comp_len;
  83                flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)?
  84                        Z_NO_FLUSH : Z_FINISH;
  85
  86                do {
  87                        left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
  88                                        CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp;
  89                        s.next_out = dst;
  90                        s.avail_out = left_len;
  91                        r = deflate(&s, flush);
  92                        if (r == Z_STREAM_ERROR && stoponerr == 1) {
  93                                printf("Error: deflate() returned %d\n", r);
  94                                r = -1;
  95                                goto bail;
  96                        }
  97                        if (!func) {
  98                                dst += (left_len - s.avail_out);
  99                                *lenp -= (left_len - s.avail_out);
 100                        } else if (left_len - s.avail_out > 0) {
 101                                r = func((unsigned long)dst,
 102                                        left_len - s.avail_out);
 103                                if (r < 0)
 104                                        goto bail;
 105                        }
 106                } while (s.avail_out == 0 && (*lenp > 0));
 107                if (s.avail_in) {
 108                        printf("Deflate failed to consume %u bytes", s.avail_in);
 109                        r = -1;
 110                        goto bail;
 111                }
 112                if (*lenp == 0) {
 113                        printf("Deflate need more space to compress "
 114                                "left %lu bytes\n", srclen);
 115                        r = -1;
 116                        goto bail;
 117                }
 118                srclen -= comp_len;
 119                src += comp_len;
 120        }
 121
 122        r = 0;
 123bail:
 124        deflateEnd(&s);
 125        *lenp = orig - *lenp;
 126        return r;
 127}
 128