block_util.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. /// \file block_header.c
  4. /// \brief Utility functions to handle lzma_block
  5. //
  6. // Author: Lasse Collin
  7. //
  8. // This file has been put into the public domain.
  9. // You can do whatever you want with this file.
  10. //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include "common.h"
  13. #include "index.h"
  14. extern LZMA_API(lzma_ret)
  15. lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size)
  16. {
  17. uint32_t container_size;
  18. lzma_vli compressed_size;
  19. // Validate everything but Uncompressed Size and filters.
  20. if (lzma_block_unpadded_size(block) == 0)
  21. return LZMA_PROG_ERROR;
  22. container_size = block->header_size
  23. + lzma_check_size(block->check);
  24. // Validate that Compressed Size will be greater than zero.
  25. if (unpadded_size <= container_size)
  26. return LZMA_DATA_ERROR;
  27. // Calculate what Compressed Size is supposed to be.
  28. // If Compressed Size was present in Block Header,
  29. // compare that the new value matches it.
  30. compressed_size = unpadded_size - container_size;
  31. if (block->compressed_size != LZMA_VLI_UNKNOWN
  32. && block->compressed_size != compressed_size)
  33. return LZMA_DATA_ERROR;
  34. block->compressed_size = compressed_size;
  35. return LZMA_OK;
  36. }
  37. extern LZMA_API(lzma_vli)
  38. lzma_block_unpadded_size(const lzma_block *block)
  39. {
  40. lzma_vli unpadded_size;
  41. // Validate the values that we are interested in i.e. all but
  42. // Uncompressed Size and the filters.
  43. //
  44. // NOTE: This function is used for validation too, so it is
  45. // essential that these checks are always done even if
  46. // Compressed Size is unknown.
  47. if (block == NULL || block->version != 0
  48. || block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
  49. || block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
  50. || (block->header_size & 3)
  51. || !lzma_vli_is_valid(block->compressed_size)
  52. || block->compressed_size == 0
  53. || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
  54. return 0;
  55. // If Compressed Size is unknown, return that we cannot know
  56. // size of the Block either.
  57. if (block->compressed_size == LZMA_VLI_UNKNOWN)
  58. return LZMA_VLI_UNKNOWN;
  59. // Calculate Unpadded Size and validate it.
  60. unpadded_size = block->compressed_size
  61. + block->header_size
  62. + lzma_check_size(block->check);
  63. assert(unpadded_size >= UNPADDED_SIZE_MIN);
  64. if (unpadded_size > UNPADDED_SIZE_MAX)
  65. return 0;
  66. return unpadded_size;
  67. }
  68. extern LZMA_API(lzma_vli)
  69. lzma_block_total_size(const lzma_block *block)
  70. {
  71. lzma_vli unpadded_size = lzma_block_unpadded_size(block);
  72. if (unpadded_size != LZMA_VLI_UNKNOWN)
  73. unpadded_size = vli_ceil4(unpadded_size);
  74. return unpadded_size;
  75. }