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