12940b44dSPeter Avalos /////////////////////////////////////////////////////////////////////////////// 22940b44dSPeter Avalos // 3*e151908bSDaniel Fojt /// \file block_util.c 42940b44dSPeter Avalos /// \brief Utility functions to handle lzma_block 52940b44dSPeter Avalos // 62940b44dSPeter Avalos // Author: Lasse Collin 72940b44dSPeter Avalos // 82940b44dSPeter Avalos // This file has been put into the public domain. 92940b44dSPeter Avalos // You can do whatever you want with this file. 102940b44dSPeter Avalos // 112940b44dSPeter Avalos /////////////////////////////////////////////////////////////////////////////// 122940b44dSPeter Avalos 132940b44dSPeter Avalos #include "common.h" 142940b44dSPeter Avalos #include "index.h" 152940b44dSPeter Avalos 162940b44dSPeter Avalos 172940b44dSPeter Avalos extern LZMA_API(lzma_ret) lzma_block_compressed_size(lzma_block * block,lzma_vli unpadded_size)182940b44dSPeter Avaloslzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size) 192940b44dSPeter Avalos { 202940b44dSPeter Avalos // Validate everything but Uncompressed Size and filters. 212940b44dSPeter Avalos if (lzma_block_unpadded_size(block) == 0) 222940b44dSPeter Avalos return LZMA_PROG_ERROR; 232940b44dSPeter Avalos 242940b44dSPeter Avalos const uint32_t container_size = block->header_size 252940b44dSPeter Avalos + lzma_check_size(block->check); 262940b44dSPeter Avalos 272940b44dSPeter Avalos // Validate that Compressed Size will be greater than zero. 282940b44dSPeter Avalos if (unpadded_size <= container_size) 292940b44dSPeter Avalos return LZMA_DATA_ERROR; 302940b44dSPeter Avalos 312940b44dSPeter Avalos // Calculate what Compressed Size is supposed to be. 322940b44dSPeter Avalos // If Compressed Size was present in Block Header, 332940b44dSPeter Avalos // compare that the new value matches it. 342940b44dSPeter Avalos const lzma_vli compressed_size = unpadded_size - container_size; 352940b44dSPeter Avalos if (block->compressed_size != LZMA_VLI_UNKNOWN 362940b44dSPeter Avalos && block->compressed_size != compressed_size) 372940b44dSPeter Avalos return LZMA_DATA_ERROR; 382940b44dSPeter Avalos 392940b44dSPeter Avalos block->compressed_size = compressed_size; 402940b44dSPeter Avalos 412940b44dSPeter Avalos return LZMA_OK; 422940b44dSPeter Avalos } 432940b44dSPeter Avalos 442940b44dSPeter Avalos 452940b44dSPeter Avalos extern LZMA_API(lzma_vli) lzma_block_unpadded_size(const lzma_block * block)462940b44dSPeter Avaloslzma_block_unpadded_size(const lzma_block *block) 472940b44dSPeter Avalos { 482940b44dSPeter Avalos // Validate the values that we are interested in i.e. all but 492940b44dSPeter Avalos // Uncompressed Size and the filters. 502940b44dSPeter Avalos // 512940b44dSPeter Avalos // NOTE: This function is used for validation too, so it is 522940b44dSPeter Avalos // essential that these checks are always done even if 532940b44dSPeter Avalos // Compressed Size is unknown. 5415ab8c86SJohn Marino if (block == NULL || block->version > 1 552940b44dSPeter Avalos || block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN 562940b44dSPeter Avalos || block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX 572940b44dSPeter Avalos || (block->header_size & 3) 582940b44dSPeter Avalos || !lzma_vli_is_valid(block->compressed_size) 592940b44dSPeter Avalos || block->compressed_size == 0 602940b44dSPeter Avalos || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX) 612940b44dSPeter Avalos return 0; 622940b44dSPeter Avalos 632940b44dSPeter Avalos // If Compressed Size is unknown, return that we cannot know 642940b44dSPeter Avalos // size of the Block either. 652940b44dSPeter Avalos if (block->compressed_size == LZMA_VLI_UNKNOWN) 662940b44dSPeter Avalos return LZMA_VLI_UNKNOWN; 672940b44dSPeter Avalos 682940b44dSPeter Avalos // Calculate Unpadded Size and validate it. 692940b44dSPeter Avalos const lzma_vli unpadded_size = block->compressed_size 702940b44dSPeter Avalos + block->header_size 712940b44dSPeter Avalos + lzma_check_size(block->check); 722940b44dSPeter Avalos 732940b44dSPeter Avalos assert(unpadded_size >= UNPADDED_SIZE_MIN); 742940b44dSPeter Avalos if (unpadded_size > UNPADDED_SIZE_MAX) 752940b44dSPeter Avalos return 0; 762940b44dSPeter Avalos 772940b44dSPeter Avalos return unpadded_size; 782940b44dSPeter Avalos } 792940b44dSPeter Avalos 802940b44dSPeter Avalos 812940b44dSPeter Avalos extern LZMA_API(lzma_vli) lzma_block_total_size(const lzma_block * block)822940b44dSPeter Avaloslzma_block_total_size(const lzma_block *block) 832940b44dSPeter Avalos { 842940b44dSPeter Avalos lzma_vli unpadded_size = lzma_block_unpadded_size(block); 852940b44dSPeter Avalos 862940b44dSPeter Avalos if (unpadded_size != LZMA_VLI_UNKNOWN) 872940b44dSPeter Avalos unpadded_size = vli_ceil4(unpadded_size); 882940b44dSPeter Avalos 892940b44dSPeter Avalos return unpadded_size; 902940b44dSPeter Avalos } 91