Installing a zisofs uncompression filter on file from ISO image which bear

a ZF entry. Storing ZF entries during image write if that filter is found
directly on a fsrc stream from the loaded image and content does not get
copied.
This commit is contained in:
2009-04-11 14:15:34 +02:00
parent 77591e4546
commit 6886777ea0
7 changed files with 187 additions and 25 deletions

View File

@ -886,8 +886,9 @@ int ziso_create_context(FilterContext **filter, int flag)
* @param flag bit0= if_block_reduction rather than if_reduction
* bit1= Install a decompression filter
* bit2= only inquire availability of zisofs filtering
* bit3= do not inquire size
*/
int iso_file_add_zisofs_filter(IsoFile *file, int flag)
int ziso_add_filter(IsoFile *file, int flag)
{
#ifdef Libisofs_with_zliB
@ -919,6 +920,9 @@ int iso_file_add_zisofs_filter(IsoFile *file, int flag)
if (ret < 0) {
return ret;
}
if (flag & 8) /* size will be filled in by caller */
return ISO_SUCCESS;
/* Run a full filter process getsize so that the size is cached */
stream = iso_file_get_stream(file);
filtered_size = iso_stream_get_size(stream);
@ -946,6 +950,41 @@ int iso_file_add_zisofs_filter(IsoFile *file, int flag)
}
int iso_file_add_zisofs_filter(IsoFile *file, int flag)
{
return ziso_add_filter(file, flag & ~8);
}
int ziso_add_osiz_filter(IsoFile *file, uint8_t header_size_div4,
uint8_t block_size_log2, uint32_t uncompressed_size,
int flag)
{
#ifdef Libisofs_with_zliB
int ret;
ZisofsUncomprStreamData *unstd;
ret = ziso_add_filter(file, 2 | 8);
if (ret < 0)
return ret;
unstd = iso_file_get_stream(file)->data;
unstd->header_size_div4 = header_size_div4;
unstd->block_size_log2 = block_size_log2;
unstd->std.size = uncompressed_size;
return ISO_SUCCESS;
#else
return ISO_ZLIB_NOT_ENABLED;
#endif /* ! Libisofs_with_zliB */
}
/* Determine stream type : 1=ziso , -1=osiz , 0=other
and eventual ZF field parameters
*/

View File

@ -287,6 +287,12 @@ struct image_fs_data
unsigned int opened : 2; /**< 0 not opened, 1 opened file, 2 opened dir */
#ifdef Libisofs_with_zliB
uint8_t header_size_div4;
uint8_t block_size_log2;
uint32_t uncompressed_size;
#endif
/* info for content reading */
struct
{
@ -1109,6 +1115,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
size_t cs_value_length = 0;
char msg[160];
uint8_t zisofs_alg[2], zisofs_hs4 = 0, zisofs_bsl2 = 0;
uint32_t zisofs_usize = 0;
if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) {
return ISO_NULL_POINTER;
@ -1375,6 +1383,21 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
continue;
}
#ifdef Libisofs_with_zliB
} else if (SUSP_SIG(sue, 'Z', 'F')) {
ret = read_zisofs_ZF(sue, zisofs_alg, &zisofs_hs4,
&zisofs_bsl2, &zisofs_usize, 0);
if (ret < 0 || zisofs_alg[0] != 'p' || zisofs_alg[1] != 'z') {
/* notify and continue */
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
"Invalid ZF entry");
zisofs_hs4 = 0;
continue;
}
#endif /* Libisofs_with_zliB */
/* This message is inflationary */
/*
@ -1653,7 +1676,11 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ifsdata = (*src)->data;
ifsrc = (*src);
free(ifsdata->name); /* we will assign a new one */
ifsdata->name = NULL;
atts.st_size += (off_t)ifsdata->info.st_size;
if (ifsdata->aa_string != NULL)
free(ifsdata->aa_string);
ifsdata->aa_string = NULL;
}
/* fill data */
@ -1667,6 +1694,16 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ifsdata->name = name;
ifsdata->aa_string = aa_string;
#ifdef Libisofs_with_zliB
if (zisofs_hs4 > 0) {
ifsdata->header_size_div4 = zisofs_hs4;
ifsdata->block_size_log2 = zisofs_bsl2;
ifsdata->uncompressed_size = zisofs_usize;
} else {
ifsdata->header_size_div4 = 0;
}
#endif
/* save extents */
ifsdata->sections = realloc(ifsdata->sections,
(1 + ifsdata->nsections) * sizeof(struct iso_file_section));
@ -2466,6 +2503,14 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
char *name;
ImageFileSourceData *data;
#ifdef Libisofs_with_zliB
/* Intimate friendship with this function in filters/zisofs.c */
int ziso_add_osiz_filter(IsoFile *file, uint8_t header_size_div4,
uint8_t block_size_log2,
uint32_t uncompressed_size, int flag);
#endif /* Libisofs_with_zliB */
if (builder == NULL || src == NULL || node == NULL || src->data == NULL) {
return ISO_NULL_POINTER;
}
@ -2544,6 +2589,22 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
file->stream = stream;
file->node.type = LIBISO_FILE;
#ifdef Libisofs_with_zliB
if (data->header_size_div4 > 0) {
ret = ziso_add_osiz_filter(file, data->header_size_div4,
data->block_size_log2,
data->uncompressed_size, 0);
if (ret < 0) {
free(name);
iso_stream_unref(stream);
return ret;
}
}
#endif /* Libisofs_with_zliB */
new = (IsoNode*) file;
new->refcount = 0;

View File

@ -4913,6 +4913,7 @@ int iso_stream_get_external_filter(IsoStream *stream,
* bit1= Install a decompression filter rather than one for compression.
* bit2= Only inquire availability of zisofs filtering. file may be NULL.
* If available return 2, else return error.
* bit3= is reserved for internal use and will be forced to 0
* @return
* 1 on success, 2 if filter available but installation revoked
* <0 on error, e.g. ISO_ZLIB_NOT_ENABLED

View File

@ -806,7 +806,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
int ret, will_copy = 1, stream_type = 0, do_zf = 0;
int header_size_div4 = 0, block_size_log2 = 0;
uint32_t uncompressed_size = 0;
IsoStream *stream = NULL, *input_stream;
IsoStream *stream = NULL, *input_stream, *next_stream;
IsoFile *file;
/* Intimate friendship with this function in filters/zisofs.c */
@ -822,12 +822,15 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
if (t->appendable && file->from_old_session)
will_copy = 0;
stream = iso_file_get_stream(file);
while (!will_copy) { /* Obtain most original stream (image stream) */
input_stream = iso_stream_get_input_stream(stream, 0);
next_stream = stream = iso_file_get_stream(file);
while (!will_copy) { /* Obtain second-most original stream
(the eventual osiz filter on the image stream) */
input_stream = iso_stream_get_input_stream(next_stream, 0);
if (input_stream == NULL)
break;
stream = input_stream;
stream = next_stream;
next_stream = input_stream;
}
/* Determine stream type : 1=ziso , -1=osiz , 0=other */
@ -1048,7 +1051,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
if (t->aaip) {
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
if (ret == 1) {
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
}
}
/* let the expert decide where to add num_aapt */

View File

@ -10,18 +10,29 @@
/**
* This header defines the functions and structures needed to add RockRidge
* extensions to an ISO image.
* extensions to an ISO image. It also handles AAIP and zisofs extensions.
*
* References:
*
* - SUSP (IEEE 1281).
* System Use Sharing Protocol, draft standard version 1.12.
* See ftp://ftp.ymi.com/pub/rockridge/susp112.ps
*
* - RRIP (IEEE 1282)
* Rock Ridge Interchange Protocol, Draft Standard version 1.12.
* See ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
*
* - ECMA-119 (ISO-9660)
* Volume and File Structure of CDROM for Information Interchange.
* Volume and File Structure of CDROM for Information Interchange. See
* http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
*
* - AAIP
* Arbitrary Attribute Interchange Protocol. See doc/susp_aaip_2_0.txt
*
* - zisofs
* Blockwise compression of data file content with transparent read support
* in the Linux kernel. See doc/zisofs_format.txt
*
*/
#ifndef LIBISO_ROCKRIDGE_H
@ -133,6 +144,12 @@ struct aaip_AL {
};
/** zisofs entry (see doc/zisofs_format.txt) */
struct zisofs_ZF {
uint8_t parameters[1]; /* begins with BP 5 */
};
/**
* Struct for a SUSP System User Entry (SUSP, 4.1)
*/
@ -153,6 +170,7 @@ struct susp_sys_user_entry
struct rr_SL SL;
struct aaip_AA AA;
struct aaip_AL AL;
struct zisofs_ZF ZF;
} data; /* 5 to 4+len_sue */
};
@ -315,5 +333,14 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
size_t *prev_field, int *is_done, int flag);
/**
* Reads the zisofs parameters from a ZF field (see doc/zisofs_format.txt).
*
* @return
* 1 on success, < 0 on error
*/
int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
uint8_t *header_size_div4, uint8_t *block_size_log2,
uint32_t *uncompressed_size, int flag);
#endif /* LIBISO_ROCKRIDGE_H */

View File

@ -579,4 +579,31 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
return ISO_SUCCESS;
}
/**
* Reads the zisofs parameters from a ZF field (see doc/zisofs_format.txt).
*
* @return
* 1 on success, < 0 on error
*/
int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
uint8_t *header_size_div4, uint8_t *block_size_log2,
uint32_t *uncompressed_size, int flag)
{
if (zf == NULL) {
return ISO_NULL_POINTER;
}
if (zf->sig[0] != 'Z' || zf->sig[1] != 'F') {
return ISO_WRONG_ARG_VALUE;
}
if (zf->len_sue[0] != 16) {
return ISO_WRONG_RR;
}
algorithm[0] = zf->data.ZF.parameters[0];
algorithm[1] = zf->data.ZF.parameters[1];
*header_size_div4 = zf->data.ZF.parameters[2];
*block_size_log2 = zf->data.ZF.parameters[3];
*uncompressed_size = iso_read_bb(&(zf->data.ZF.parameters[4]), 4, NULL);
return ISO_SUCCESS;
}