gzip.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * (C) Copyright 2012
  3. * Lei Wen <leiwen@marvell.com>, Marvell Inc.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <watchdog.h>
  25. #include <command.h>
  26. #include <image.h>
  27. #include <malloc.h>
  28. #include <u-boot/zlib.h>
  29. #include "zlib/zutil.h"
  30. #ifndef CONFIG_GZIP_COMPRESS_DEF_SZ
  31. #define CONFIG_GZIP_COMPRESS_DEF_SZ 0x200
  32. #endif
  33. #define ZALLOC_ALIGNMENT 16
  34. static void *zalloc(void *x, unsigned items, unsigned size)
  35. {
  36. void *p;
  37. size *= items;
  38. size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
  39. p = malloc (size);
  40. return (p);
  41. }
  42. static void zfree(void *x, void *addr, unsigned nb)
  43. {
  44. free (addr);
  45. }
  46. int gzip(void *dst, unsigned long *lenp,
  47. unsigned char *src, unsigned long srclen)
  48. {
  49. return zzip(dst, lenp, src, srclen, 1, NULL);
  50. }
  51. /*
  52. * Compress blocks with zlib
  53. */
  54. int zzip(void *dst, unsigned long *lenp, unsigned char *src,
  55. unsigned long srclen, int stoponerr,
  56. int (*func)(unsigned long, unsigned long))
  57. {
  58. z_stream s;
  59. int r, flush, orig, window;
  60. unsigned long comp_len, left_len;
  61. if (!srclen)
  62. return 0;
  63. #ifndef CONFIG_GZIP
  64. window = MAX_WBITS;
  65. #else
  66. window = 2 * MAX_WBITS;
  67. #endif
  68. orig = *lenp;
  69. s.zalloc = zalloc;
  70. s.zfree = zfree;
  71. s.opaque = Z_NULL;
  72. r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window,
  73. DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  74. ZLIB_VERSION, sizeof(z_stream));
  75. if (r != Z_OK) {
  76. printf ("Error: deflateInit2_() returned %d\n", r);
  77. return -1;
  78. }
  79. while (srclen > 0) {
  80. comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ?
  81. CONFIG_GZIP_COMPRESS_DEF_SZ : srclen;
  82. s.next_in = src;
  83. s.avail_in = comp_len;
  84. flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)?
  85. Z_NO_FLUSH : Z_FINISH;
  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. r = 0;
  122. bail:
  123. deflateEnd(&s);
  124. *lenp = orig - *lenp;
  125. return r;
  126. }