lzma_decompress.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // #include <ustdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include "user_interface.h"
  6. #include "LzmaDec.h"
  7. #include "LzmaEnc.h"
  8. #include "7zFile.h"
  9. #include "vFile.h"
  10. #include "mylib.h"
  11. //#define LZMA_RAM_USE_DEBUG
  12. #ifdef LZMA_RAM_USE_DEBUG
  13. static int ram_used_size = 0;
  14. static int ram_used_max = 0;
  15. #endif
  16. void *lzma_alloc(ISzAllocPtr p, size_t size)
  17. {
  18. void *mp;
  19. if (size == 0)
  20. {
  21. return NULL;
  22. }
  23. mp = bs_malloc(size);
  24. #ifdef LZMA_RAM_USE_DEBUG
  25. ram_used_size += _msize(mp);
  26. if (ram_used_max < ram_used_size)ram_used_max = ram_used_size;
  27. printk("ram used: now / max = %d / %d\n", ram_used_size, ram_used_max);
  28. #endif
  29. return mp;
  30. }
  31. void lzma_free(ISzAllocPtr p, void *address)
  32. {
  33. if (address != NULL)
  34. {
  35. #ifdef LZMA_RAM_USE_DEBUG
  36. ram_used_size -= _msize(address);
  37. printk("ram used: now / max = %d / %d\n", ram_used_size, ram_used_max);
  38. #endif
  39. bs_free(address);
  40. }
  41. }
  42. ISzAlloc allocator = {lzma_alloc, lzma_free};
  43. static CLzmaDec *lz_state = NULL;
  44. static int lzma_decompress_init(vFile *pf)
  45. {
  46. if (lz_state != NULL) return 0;
  47. extern ISzAlloc allocator;
  48. UInt64 unpack_size = 0;
  49. uint8_t header[LZMA_PROPS_SIZE + 8];;
  50. size_t headerSize = sizeof(header);
  51. vfread(pf, header, headerSize);
  52. // debug_array(header, headerSize);
  53. // for (char i = 0; i < 8; i++)
  54. // {
  55. // unpack_size |= (UInt64)(header[LZMA_PROPS_SIZE + i] << (i * 8));
  56. // }
  57. /* 以下为过静态检查写法 */
  58. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 0]) << 0;
  59. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 1]) << 8;
  60. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 2]) << 16;
  61. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 3]) << 24;
  62. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 4]) << 32;
  63. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 5]) << 40;
  64. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 6]) << 48;
  65. unpack_size |= ((uint64_t)header[LZMA_PROPS_SIZE + 7]) << 56;
  66. // bs_printf("unpack_size:0X%08X", unpack_size);
  67. //分配解码内存
  68. lz_state = (CLzmaDec *)lzma_alloc(NULL, sizeof(CLzmaDec));
  69. if (lz_state != NULL)
  70. {
  71. LzmaDec_Construct(lz_state);
  72. LzmaDec_Allocate(lz_state, header, LZMA_PROPS_SIZE, &allocator);
  73. LzmaDec_Init(lz_state);
  74. return 0;
  75. }
  76. else
  77. {
  78. bs_printf("lzma_alloc err");
  79. }
  80. return -1;
  81. }
  82. int lzma_decompress_read(vFile *pf, uint8_t *buffer, int size)
  83. {
  84. /* Start to decompress file */
  85. uint32_t position, file_size;
  86. size_t dcmprs_size = 0;
  87. uint8_t *inBuf;
  88. SizeT inProcessed;
  89. SizeT outProcessed = size;
  90. ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
  91. ELzmaStatus status;
  92. SRes res;
  93. res = lzma_decompress_init(pf);
  94. if (res != 0)
  95. {
  96. bs_printf("err%d", __LINE__);
  97. }
  98. //获取当前文件读指针
  99. inBuf = vfgetpos(pf, &position);
  100. //检查文件还剩下多少字节
  101. file_size = vfgetlen(pf);
  102. // bs_printf("file_size:%d", file_size);
  103. if ((position + size) > file_size)
  104. {
  105. inProcessed = file_size - position;
  106. }
  107. else
  108. {
  109. inProcessed = size;
  110. }
  111. // bs_printf("inProcessed:%d", inProcessed);
  112. //解压数据
  113. if (inProcessed > 0 || inProcessed == 0)
  114. {
  115. res = LzmaDec_DecodeToBuf(lz_state, buffer, &outProcessed, inBuf, &inProcessed, finishMode, &status);
  116. // debug_array((uint8_t *)lz_state, 200);
  117. // debug_array(buffer, 255);
  118. // bs_printf("outProcessed: %d", outProcessed);
  119. // debug_array(inBuf, 255);
  120. // bs_printf("inProcessed: %d", inProcessed);
  121. // bs_printf("finishMode: %d", finishMode);
  122. // bs_printf("status: %d", status);
  123. // bs_printf("LzmaDec_DecodeToBuf res: %d", res);
  124. if (res)
  125. {
  126. // bs_printf("err%d,res: %d", __LINE__, res);
  127. }
  128. dcmprs_size = outProcessed;
  129. //重新设置文件读指针
  130. position += inProcessed;
  131. vfsetpos(pf, position);
  132. }
  133. // bs_printf("dcmprs_size: %d", dcmprs_size);
  134. return dcmprs_size;
  135. }
  136. void lzma_decompress_finish(void)
  137. {
  138. LzmaDec_Free(lz_state, &allocator);
  139. if (lz_state != NULL)
  140. {
  141. lzma_free(NULL, lz_state);
  142. lz_state = NULL;
  143. }
  144. }