LzmaTools.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.57
  3. *
  4. * Copyright (C) 2007-2008 Industrie Dial Face S.p.A.
  5. * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com)
  6. *
  7. * Copyright (C) 1999-2005 Igor Pavlov
  8. *
  9. * See file CREDITS for list of people who contributed to this
  10. * project.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License as
  14. * published by the Free Software Foundation; either version 2 of
  15. * the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25. * MA 02111-1307 USA
  26. */
  27. /*
  28. * LZMA_Alone stream format:
  29. *
  30. * uchar Properties[5]
  31. * uint64 Uncompressed size
  32. * uchar data[*]
  33. *
  34. */
  35. #include <config.h>
  36. #include <common.h>
  37. #ifdef CONFIG_LZMA
  38. #define LZMA_PROPERTIES_OFFSET 0
  39. #define LZMA_SIZE_OFFSET LZMA_PROPERTIES_SIZE
  40. #define LZMA_DATA_OFFSET LZMA_SIZE_OFFSET+sizeof(uint64_t)
  41. #include "LzmaTools.h"
  42. #include "LzmaDecode.h"
  43. #include <linux/string.h>
  44. #include <malloc.h>
  45. int lzmaBuffToBuffDecompress (unsigned char *outStream, SizeT *uncompressedSize,
  46. unsigned char *inStream, SizeT length)
  47. {
  48. int res = LZMA_RESULT_DATA_ERROR;
  49. int i;
  50. SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */
  51. SizeT inProcessed;
  52. SizeT outProcessed;
  53. SizeT outSize;
  54. SizeT outSizeHigh;
  55. CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
  56. unsigned char properties[LZMA_PROPERTIES_SIZE];
  57. SizeT compressedSize = (SizeT)(length - LZMA_DATA_OFFSET);
  58. debug ("LZMA: Image address............... 0x%lx\n", inStream);
  59. debug ("LZMA: Properties address.......... 0x%lx\n", inStream + LZMA_PROPERTIES_OFFSET);
  60. debug ("LZMA: Uncompressed size address... 0x%lx\n", inStream + LZMA_SIZE_OFFSET);
  61. debug ("LZMA: Compressed data address..... 0x%lx\n", inStream + LZMA_DATA_OFFSET);
  62. debug ("LZMA: Destination address......... 0x%lx\n", outStream);
  63. memcpy(properties, inStream + LZMA_PROPERTIES_OFFSET, LZMA_PROPERTIES_SIZE);
  64. memset(&state, 0, sizeof(state));
  65. res = LzmaDecodeProperties(&state.Properties,
  66. properties,
  67. LZMA_PROPERTIES_SIZE);
  68. if (res != LZMA_RESULT_OK) {
  69. return res;
  70. }
  71. outSize = 0;
  72. outSizeHigh = 0;
  73. /* Read the uncompressed size */
  74. for (i = 0; i < 8; i++) {
  75. unsigned char b = inStream[LZMA_SIZE_OFFSET + i];
  76. if (i < 4) {
  77. outSize += (UInt32)(b) << (i * 8);
  78. } else {
  79. outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
  80. }
  81. }
  82. outSizeFull = (SizeT)outSize;
  83. if (sizeof(SizeT) >= 8) {
  84. /*
  85. * SizeT is a 64 bit uint => We can manage files larger than 4GB!
  86. *
  87. */
  88. outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
  89. } else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) {
  90. /*
  91. * SizeT is a 32 bit uint => We cannot manage files larger than
  92. * 4GB!
  93. *
  94. */
  95. debug ("LZMA: 64bit support not enabled.\n");
  96. return LZMA_RESULT_DATA_ERROR;
  97. }
  98. debug ("LZMA: Uncompresed size............ 0x%lx\n", outSizeFull);
  99. debug ("LZMA: Compresed size.............. 0x%lx\n", compressedSize);
  100. debug ("LZMA: Dynamic memory needed....... 0x%lx", LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
  101. state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
  102. if (state.Probs == 0
  103. || (outStream == 0 && outSizeFull != 0)
  104. || (inStream == 0 && compressedSize != 0)) {
  105. free(state.Probs);
  106. debug ("\n");
  107. return LZMA_RESULT_DATA_ERROR;
  108. }
  109. debug (" allocated.\n");
  110. /* Decompress */
  111. res = LzmaDecode(&state,
  112. inStream + LZMA_DATA_OFFSET, compressedSize, &inProcessed,
  113. outStream, outSizeFull, &outProcessed);
  114. if (res != LZMA_RESULT_OK) {
  115. return res;
  116. }
  117. *uncompressedSize = outProcessed;
  118. free(state.Probs);
  119. return res;
  120. }
  121. #endif