]> git.ipfire.org Git - people/ms/u-boot.git/blame - lib/gunzip.c
serial: pl01x: fix PL010 regression
[people/ms/u-boot.git] / lib / gunzip.c
CommitLineData
321359f2
MB
1/*
2 * (C) Copyright 2000-2006
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
1a459660 5 * SPDX-License-Identifier: GPL-2.0+
321359f2
MB
6 */
7
8#include <common.h>
9#include <watchdog.h>
10#include <command.h>
11#include <image.h>
12#include <malloc.h>
a31e091a 13#include <u-boot/zlib.h>
321359f2
MB
14
15#define ZALLOC_ALIGNMENT 16
16#define HEAD_CRC 2
17#define EXTRA_FIELD 4
18#define ORIG_NAME 8
19#define COMMENT 0x10
20#define RESERVED 0xe0
21#define DEFLATED 8
22
e3ed0575 23void *gzalloc(void *x, unsigned items, unsigned size)
321359f2
MB
24{
25 void *p;
26
27 size *= items;
28 size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
29
30 p = malloc (size);
31
32 return (p);
33}
34
e3ed0575 35void gzfree(void *x, void *addr, unsigned nb)
321359f2
MB
36{
37 free (addr);
38}
39
40int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
41{
35f6a943 42 int i, flags;
321359f2
MB
43
44 /* skip header */
45 i = 10;
46 flags = src[3];
47 if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
48 puts ("Error: Bad gzipped data\n");
49 return (-1);
50 }
51 if ((flags & EXTRA_FIELD) != 0)
52 i = 12 + src[10] + (src[11] << 8);
53 if ((flags & ORIG_NAME) != 0)
54 while (src[i++] != 0)
55 ;
56 if ((flags & COMMENT) != 0)
57 while (src[i++] != 0)
58 ;
59 if ((flags & HEAD_CRC) != 0)
60 i += 2;
61 if (i >= *lenp) {
62 puts ("Error: gunzip out of data in header\n");
63 return (-1);
64 }
65
35f6a943
RR
66 return zunzip(dst, dstlen, src, lenp, 1, i);
67}
68
69/*
70 * Uncompress blocks compressed with zlib without headers
71 */
72int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp,
73 int stoponerr, int offset)
74{
75 z_stream s;
9c55c54f 76 int err = 0;
35f6a943
RR
77 int r;
78
e3ed0575
MF
79 s.zalloc = gzalloc;
80 s.zfree = gzfree;
321359f2
MB
81
82 r = inflateInit2(&s, -MAX_WBITS);
83 if (r != Z_OK) {
84 printf ("Error: inflateInit2() returned %d\n", r);
35f6a943 85 return -1;
321359f2 86 }
35f6a943
RR
87 s.next_in = src + offset;
88 s.avail_in = *lenp - offset;
321359f2
MB
89 s.next_out = dst;
90 s.avail_out = dstlen;
f039ada5
CR
91 do {
92 r = inflate(&s, Z_FINISH);
b75650d8
KC
93 if (stoponerr == 1 && r != Z_STREAM_END &&
94 (s.avail_out == 0 || r != Z_BUF_ERROR)) {
f039ada5 95 printf("Error: inflate() returned %d\n", r);
9c55c54f
SG
96 err = -1;
97 break;
f039ada5
CR
98 }
99 s.avail_in = *lenp - offset - (int)(s.next_out - (unsigned char*)dst);
f039ada5 100 } while (r == Z_BUF_ERROR);
321359f2
MB
101 *lenp = s.next_out - (unsigned char *) dst;
102 inflateEnd(&s);
103
9c55c54f 104 return err;
321359f2 105}