1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file block_header.c 4207753Smm/// \brief Utility functions to handle lzma_block 5207753Smm// 6207753Smm// Author: Lasse Collin 7207753Smm// 8207753Smm// This file has been put into the public domain. 9207753Smm// You can do whatever you want with this file. 10207753Smm// 11207753Smm/////////////////////////////////////////////////////////////////////////////// 12207753Smm 13207753Smm#include "common.h" 14207753Smm#include "index.h" 15207753Smm 16207753Smm 17207753Smmextern LZMA_API(lzma_ret) 18213700Smmlzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size) 19207753Smm{ 20207753Smm // Validate everything but Uncompressed Size and filters. 21207753Smm if (lzma_block_unpadded_size(block) == 0) 22207753Smm return LZMA_PROG_ERROR; 23207753Smm 24207753Smm const uint32_t container_size = block->header_size 25207753Smm + lzma_check_size(block->check); 26207753Smm 27207753Smm // Validate that Compressed Size will be greater than zero. 28213700Smm if (unpadded_size <= container_size) 29207753Smm return LZMA_DATA_ERROR; 30207753Smm 31207753Smm // Calculate what Compressed Size is supposed to be. 32207753Smm // If Compressed Size was present in Block Header, 33207753Smm // compare that the new value matches it. 34213700Smm const lzma_vli compressed_size = unpadded_size - container_size; 35207753Smm if (block->compressed_size != LZMA_VLI_UNKNOWN 36207753Smm && block->compressed_size != compressed_size) 37207753Smm return LZMA_DATA_ERROR; 38207753Smm 39207753Smm block->compressed_size = compressed_size; 40207753Smm 41207753Smm return LZMA_OK; 42207753Smm} 43207753Smm 44207753Smm 45207753Smmextern LZMA_API(lzma_vli) 46207753Smmlzma_block_unpadded_size(const lzma_block *block) 47207753Smm{ 48207753Smm // Validate the values that we are interested in i.e. all but 49207753Smm // Uncompressed Size and the filters. 50207753Smm // 51207753Smm // NOTE: This function is used for validation too, so it is 52207753Smm // essential that these checks are always done even if 53207753Smm // Compressed Size is unknown. 54207753Smm if (block == NULL || block->version != 0 55207753Smm || block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN 56207753Smm || block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX 57207753Smm || (block->header_size & 3) 58207753Smm || !lzma_vli_is_valid(block->compressed_size) 59207753Smm || block->compressed_size == 0 60207753Smm || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX) 61207753Smm return 0; 62207753Smm 63207753Smm // If Compressed Size is unknown, return that we cannot know 64207753Smm // size of the Block either. 65207753Smm if (block->compressed_size == LZMA_VLI_UNKNOWN) 66207753Smm return LZMA_VLI_UNKNOWN; 67207753Smm 68207753Smm // Calculate Unpadded Size and validate it. 69207753Smm const lzma_vli unpadded_size = block->compressed_size 70207753Smm + block->header_size 71207753Smm + lzma_check_size(block->check); 72207753Smm 73207753Smm assert(unpadded_size >= UNPADDED_SIZE_MIN); 74207753Smm if (unpadded_size > UNPADDED_SIZE_MAX) 75207753Smm return 0; 76207753Smm 77207753Smm return unpadded_size; 78207753Smm} 79207753Smm 80207753Smm 81207753Smmextern LZMA_API(lzma_vli) 82207753Smmlzma_block_total_size(const lzma_block *block) 83207753Smm{ 84207753Smm lzma_vli unpadded_size = lzma_block_unpadded_size(block); 85207753Smm 86207753Smm if (unpadded_size != LZMA_VLI_UNKNOWN) 87207753Smm unpadded_size = vli_ceil4(unpadded_size); 88207753Smm 89207753Smm return unpadded_size; 90207753Smm} 91