@ -33,6 +33,9 @@
int ( * dmg_uncompress_bz2 ) ( char * next_in , unsigned int avail_in ,
char * next_out , unsigned int avail_out ) ;
int ( * dmg_uncompress_lzfse ) ( char * next_in , unsigned int avail_in ,
char * next_out , unsigned int avail_out ) ;
enum {
/* Limit chunk sizes to prevent unreasonable amounts of memory being used
* or truncating when converting to 32 - bit types
@ -107,6 +110,7 @@ static void update_max_chunk_size(BDRVDMGState *s, uint32_t chunk,
switch ( s - > types [ chunk ] ) {
case 0x80000005 : /* zlib compressed */
case 0x80000006 : /* bzip2 compressed */
case 0x80000007 : /* lzfse compressed */
compressed_size = s - > lengths [ chunk ] ;
uncompressed_sectors = s - > sectorcounts [ chunk ] ;
break ;
@ -188,6 +192,8 @@ static bool dmg_is_known_block_type(uint32_t entry_type)
return true ;
case 0x80000006 : /* bzip2 */
return ! ! dmg_uncompress_bz2 ;
case 0x80000007 : /* lzfse */
return ! ! dmg_uncompress_lzfse ;
default :
return false ;
}
@ -425,6 +431,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
}
block_module_load_one ( " dmg-bz2 " ) ;
block_module_load_one ( " dmg-lzfse " ) ;
s - > n_chunks = 0 ;
s - > offsets = s - > lengths = s - > sectors = s - > sectorcounts = NULL ;
@ -623,6 +630,27 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
return ret ;
}
break ;
case 0x80000007 :
if ( ! dmg_uncompress_lzfse ) {
break ;
}
/* we need to buffer, because only the chunk as whole can be
* inflated . */
ret = bdrv_pread ( bs - > file , s - > offsets [ chunk ] ,
s - > compressed_chunk , s - > lengths [ chunk ] ) ;
if ( ret ! = s - > lengths [ chunk ] ) {
return - 1 ;
}
ret = dmg_uncompress_lzfse ( ( char * ) s - > compressed_chunk ,
( unsigned int ) s - > lengths [ chunk ] ,
( char * ) s - > uncompressed_chunk ,
( unsigned int )
( 512 * s - > sectorcounts [ chunk ] ) ) ;
if ( ret < 0 ) {
return ret ;
}
break ;
case 1 : /* copy */
ret = bdrv_pread ( bs - > file , s - > offsets [ chunk ] ,
s - > uncompressed_chunk , s - > lengths [ chunk ] ) ;