gunzip.c 2.1 KB

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