Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.7 KiB

  1. /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
  2. 2009-08-14 : Igor Pavlov : Public domain */
  3. #include <string.h>
  4. #include "Lzma86.h"
  5. #include "Alloc.h"
  6. #include "Bra.h"
  7. #include "LzmaEnc.h"
  8. #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
  9. static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
  10. static void SzFree(void *p, void *address) { p = p; MyFree(address); }
  11. int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
  12. int level, UInt32 dictSize, int filterMode)
  13. {
  14. ISzAlloc g_Alloc = { SzAlloc, SzFree };
  15. size_t outSize2 = *destLen;
  16. Byte *filteredStream;
  17. Bool useFilter;
  18. int mainResult = SZ_ERROR_OUTPUT_EOF;
  19. CLzmaEncProps props;
  20. LzmaEncProps_Init(&props);
  21. props.level = level;
  22. props.dictSize = dictSize;
  23. *destLen = 0;
  24. if (outSize2 < LZMA86_HEADER_SIZE)
  25. return SZ_ERROR_OUTPUT_EOF;
  26. {
  27. int i;
  28. UInt64 t = srcLen;
  29. for (i = 0; i < 8; i++, t >>= 8)
  30. dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
  31. }
  32. filteredStream = 0;
  33. useFilter = (filterMode != SZ_FILTER_NO);
  34. if (useFilter)
  35. {
  36. if (srcLen != 0)
  37. {
  38. filteredStream = (Byte *)MyAlloc(srcLen);
  39. if (filteredStream == 0)
  40. return SZ_ERROR_MEM;
  41. memcpy(filteredStream, src, srcLen);
  42. }
  43. {
  44. UInt32 x86State;
  45. x86_Convert_Init(x86State);
  46. x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
  47. }
  48. }
  49. {
  50. size_t minSize = 0;
  51. Bool bestIsFiltered = False;
  52. /* passes for SZ_FILTER_AUTO:
  53. 0 - BCJ + LZMA
  54. 1 - LZMA
  55. 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
  56. */
  57. int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
  58. int i;
  59. for (i = 0; i < numPasses; i++)
  60. {
  61. size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
  62. size_t outPropsSize = 5;
  63. SRes curRes;
  64. Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
  65. if (curModeIsFiltered && !bestIsFiltered)
  66. break;
  67. if (useFilter && i == 0)
  68. curModeIsFiltered = True;
  69. curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
  70. curModeIsFiltered ? filteredStream : src, srcLen,
  71. &props, dest + 1, &outPropsSize, 0,
  72. NULL, &g_Alloc, &g_Alloc);
  73. if (curRes != SZ_ERROR_OUTPUT_EOF)
  74. {
  75. if (curRes != SZ_OK)
  76. {
  77. mainResult = curRes;
  78. break;
  79. }
  80. if (outSizeProcessed <= minSize || mainResult != SZ_OK)
  81. {
  82. minSize = outSizeProcessed;
  83. bestIsFiltered = curModeIsFiltered;
  84. mainResult = SZ_OK;
  85. }
  86. }
  87. }
  88. dest[0] = (Byte)(bestIsFiltered ? 1 : 0);
  89. *destLen = LZMA86_HEADER_SIZE + minSize;
  90. }
  91. if (useFilter)
  92. MyFree(filteredStream);
  93. return mainResult;
  94. }