New API call int iso_node_zf_by_magic() for marking pre-compressed data
file nodes which were originally produced by program mkzftree.
This commit is contained in:
parent
9a873ed693
commit
1f2fd259ae
@ -468,6 +468,29 @@ int ziso_stream_compress(IsoStream *stream, void *buf, size_t desired)
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int ziso_parse_zisofs_head(IsoStream *stream, int *header_size_div4,
|
||||
int *block_size_log2, uint32_t *uncompressed_size,
|
||||
int flag)
|
||||
{
|
||||
int ret;
|
||||
char zisofs_head[16];
|
||||
|
||||
ret = iso_stream_read(stream, zisofs_head, 16);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*header_size_div4 = ((unsigned char *) zisofs_head)[12];
|
||||
*block_size_log2 = ((unsigned char *) zisofs_head)[13];
|
||||
if (ret != 16 || memcmp(zisofs_head, zisofs_magic, 8) != 0 ||
|
||||
*header_size_div4 < 4 ||
|
||||
*block_size_log2 < 15 || *block_size_log2 > 17) {
|
||||
return ISO_ZISOFS_WRONG_INPUT;
|
||||
}
|
||||
*uncompressed_size = iso_read_lsb(((uint8_t *) zisofs_head) + 8, 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Note: A call with desired==0 directly after .open() only checks the file
|
||||
head and loads the uncompressed size from that head.
|
||||
*/
|
||||
@ -484,7 +507,12 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
||||
size_t fill = 0;
|
||||
char *cbuf = buf;
|
||||
uLongf buf_len;
|
||||
|
||||
#ifndef NIX
|
||||
uint32_t uncompressed_size;
|
||||
#else
|
||||
char zisofs_head[16];
|
||||
#endif
|
||||
|
||||
if (stream == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -502,6 +530,16 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
||||
while (1) {
|
||||
if (rng->state == 0) {
|
||||
/* Reading file header */
|
||||
|
||||
#ifndef NIX
|
||||
ret = ziso_parse_zisofs_head(data->orig, &header_size, &bs_log2,
|
||||
&uncompressed_size, 0);
|
||||
if (ret < 0)
|
||||
return (rng->error_ret = ret);
|
||||
nstd->header_size_div4 = header_size;
|
||||
header_size *= 4;
|
||||
data->size = uncompressed_size;
|
||||
#else
|
||||
ret = iso_stream_read(data->orig, zisofs_head, 16);
|
||||
if (ret < 0)
|
||||
return (rng->error_ret = ret);
|
||||
@ -511,18 +549,25 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
||||
header_size < 16 || bs_log2 < 15 || bs_log2 > 17) {
|
||||
return (rng->error_ret = ISO_ZISOFS_WRONG_INPUT);
|
||||
}
|
||||
data->size = iso_read_lsb(((uint8_t *) zisofs_head) + 8, 4);
|
||||
nstd->header_size_div4 = header_size / 4;
|
||||
#endif /* NIX */
|
||||
|
||||
nstd->block_size_log2 = bs_log2;
|
||||
rng->block_size = 1 << bs_log2;
|
||||
if (header_size > 16) {
|
||||
/* Skip surplus header bytes */
|
||||
|
||||
/* >>> This must be a loop
|
||||
ret = iso_stream_read(data->orig, zisofs_head, header_size-16);
|
||||
if (ret < 0)
|
||||
return (rng->error_ret = ret);
|
||||
if (ret != header_size - 16)
|
||||
*/
|
||||
return (rng->error_ret = ISO_ZISOFS_WRONG_INPUT);
|
||||
|
||||
|
||||
}
|
||||
data->size = iso_read_lsb(((uint8_t *) zisofs_head) + 8, 4);
|
||||
nstd->header_size_div4 = header_size / 4;
|
||||
nstd->block_size_log2 = bs_log2;
|
||||
|
||||
if (desired == 0) {
|
||||
return 0;
|
||||
@ -1012,26 +1057,29 @@ int ziso_add_osiz_filter(IsoFile *file, uint8_t header_size_div4,
|
||||
|
||||
|
||||
|
||||
/* Determine stream type : 1=ziso , -1=osiz , 0=other
|
||||
/* Determine stream type : 1=ziso , -1=osiz , 0=other , 2=ziso_by_content
|
||||
and eventual ZF field parameters
|
||||
@param flag bit0= allow ziso_by_content which is based on content reading
|
||||
bit1= do not inquire stream->class for filters
|
||||
*/
|
||||
int ziso_is_zisofs_stream(IsoStream *stream, int *stream_type,
|
||||
int *header_size_div4, int *block_size_log2,
|
||||
uint32_t *uncompressed_size, int flag)
|
||||
{
|
||||
int ret, close_ret;
|
||||
ZisofsFilterStreamData *data;
|
||||
ZisofsComprStreamData *cnstd;
|
||||
ZisofsUncomprStreamData *unstd;
|
||||
|
||||
*stream_type = 0;
|
||||
if (stream->class == &ziso_stream_compress_class) {
|
||||
if (stream->class == &ziso_stream_compress_class && !(flag & 2)) {
|
||||
*stream_type = 1;
|
||||
cnstd = stream->data;
|
||||
*header_size_div4 = 4;
|
||||
*block_size_log2 = ziso_block_size_log2;
|
||||
*uncompressed_size = cnstd->orig_size;
|
||||
return 1;
|
||||
} else if(stream->class == &ziso_stream_uncompress_class) {
|
||||
} else if(stream->class == &ziso_stream_uncompress_class && !(flag & 2)) {
|
||||
*stream_type = -1;
|
||||
data = stream->data;
|
||||
unstd = stream->data;
|
||||
@ -1040,7 +1088,24 @@ int ziso_is_zisofs_stream(IsoStream *stream, int *stream_type,
|
||||
*uncompressed_size = data->size;
|
||||
return 1;
|
||||
}
|
||||
if (!(flag & 1))
|
||||
return 0;
|
||||
|
||||
ret = iso_stream_open(stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ziso_parse_zisofs_head(stream, header_size_div4,
|
||||
block_size_log2, uncompressed_size, 0);
|
||||
if (ret == 1) {
|
||||
*stream_type = 2;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
close_ret = iso_stream_close(stream);
|
||||
if (close_ret < 0)
|
||||
return close_ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1421,33 +1421,38 @@ int iso_write_opts_set_always_gmt(IsoWriteOpts *opts, int gmt);
|
||||
int iso_write_opts_set_output_charset(IsoWriteOpts *opts, const char *charset);
|
||||
|
||||
/**
|
||||
* Set the type of the image to create. Libisofs support two kind of images:
|
||||
* stand-alone and appendable.
|
||||
* Set the type of image creation in case there was already an existing
|
||||
* image imported. Libisofs supports two types of creation:
|
||||
* stand-alone and appended.
|
||||
*
|
||||
* A stand-alone image is an image that is valid alone, and that can be
|
||||
* mounted by its own. This is the kind of image you will want to create
|
||||
* in most cases. A stand-alone image can be burned in an empty CD or DVD,
|
||||
* or write to an .iso file for future burning or distribution.
|
||||
* A stand-alone image is an image that does not need the old image any more
|
||||
* for being mounted by the operating system or imported by libisofs. It may
|
||||
* be written beginning with byte 0 of optical media or disk file objects.
|
||||
* There will be no distinction between files from the old image and those
|
||||
* which have been added by the new image generation.
|
||||
*
|
||||
* On the other side, an appendable image is not self contained, it refers
|
||||
* to serveral files that are stored outside the image. Its usage is for
|
||||
* multisession discs, where you add data in a new session, while the
|
||||
* previous session data can still be accessed. In those cases, the old
|
||||
* data is not written again. Instead, the new image refers to it, and thus
|
||||
* it's only valid when appended to the original. Note that in those cases
|
||||
* the image will be written after the original, and thus you will want
|
||||
* to use a ms_block greater than 0.
|
||||
* On the other side, an appended image is not self contained. It may refer
|
||||
* to files that stay stored in the imported existing image.
|
||||
* This usage model is inspired by CD multi-session. It demands that the
|
||||
* appended image is finally written to the same media resp. disk file
|
||||
* as the imported image at an address behind the end of that imported image.
|
||||
* The exact address may depend on media peculiarities and thus has to be
|
||||
* announced by the application via iso_write_opts_set_ms_block().
|
||||
* The real address where the data will be written is under control of the
|
||||
* consumer of the struct burn_source which takes the output of libisofs
|
||||
* image generation. It may be the one announced to libisofs or an intermediate
|
||||
* one. Nevertheless, the image will be readable only at the announced address.
|
||||
*
|
||||
* Note that if you haven't import a previous image (by means of
|
||||
* iso_image_import()), the image will always be a stand-alone image, as
|
||||
* there is no previous data to refer to.
|
||||
* If you have not imported a previous image by iso_image_import(), then the
|
||||
* image will always be a stand-alone image, as there is no previous data to
|
||||
* refer to.
|
||||
*
|
||||
* @param appendable
|
||||
* 1 to create an appendable image, 0 for an stand-alone one.
|
||||
* @param append
|
||||
* 1 to create an appended image, 0 for an stand-alone one.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
int iso_write_opts_set_appendable(IsoWriteOpts *opts, int appendable);
|
||||
int iso_write_opts_set_appendable(IsoWriteOpts *opts, int append);
|
||||
|
||||
/**
|
||||
* Set the start block of the image. It is supposed to be the lba where the
|
||||
@ -1540,7 +1545,8 @@ int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
|
||||
/**
|
||||
* Create a burn_source and a thread which immediately begins to generate
|
||||
* the image. That burn_source can be used with libburn as a data source
|
||||
* for a track. For its public declaration see libburn.h.
|
||||
* for a track. A copy of its public declaration in libburn.h can be found
|
||||
* further below in this text.
|
||||
*
|
||||
* If image generation shall be aborted by the application program, then
|
||||
* the .cancel() method of the burn_source must be called to end the
|
||||
@ -4727,7 +4733,7 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
||||
/* --------------------------- Filters in General -------------------------- */
|
||||
|
||||
/*
|
||||
* A filter is an IsoStreams which uses another IsoStream as input. It gets
|
||||
* A filter is an IsoStream which uses another IsoStream as input. It gets
|
||||
* attached to an IsoFile by specialized calls iso_file_add_*_filter() which
|
||||
* replace its current IsoStream by the filter stream which takes over the
|
||||
* current IsoStream as input.
|
||||
@ -4745,6 +4751,10 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
||||
* iso_file_add_zisofs_filter()
|
||||
* which may or may not be available depending on compile time settings and
|
||||
* installed software packages like libz.
|
||||
*
|
||||
* During image generation filters get not in effect if the original IsoStream
|
||||
* is an "fsrc" stream based on a file in the loaded ISO image and if the
|
||||
* image generation type is set to 1 by iso_write_opts_set_appendable().
|
||||
*/
|
||||
|
||||
/* ts A90328 */
|
||||
@ -4983,7 +4993,6 @@ struct iso_zisofs_ctrl {
|
||||
*/
|
||||
int iso_zisofs_set_params(struct iso_zisofs_ctrl *params, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Get the current global parameters for zisofs filtering.
|
||||
* @param params
|
||||
@ -4998,6 +5007,39 @@ int iso_zisofs_set_params(struct iso_zisofs_ctrl *params, int flag);
|
||||
int iso_zisofs_get_params(struct iso_zisofs_ctrl *params, int flag);
|
||||
|
||||
|
||||
/* ts A90413 */
|
||||
/**
|
||||
* Check for the given node or for its subtree whether the data file content
|
||||
* effectively bears zisofs file headers and eventually mark the outcome
|
||||
* by an xinfo data record if not already marked by a zisofs compressor filter.
|
||||
* This does not install any filter but only a hint for image generation
|
||||
* that the already compressed files shall get written with zisofs ZF entries.
|
||||
* Use this if you insert the compressed reults of program mkzftree from disk
|
||||
* into the image.
|
||||
* @param node
|
||||
* The node which shall be checked and eventually marked.
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* bit0= prepare for a run with iso_write_opts_set_appendable(,1).
|
||||
* Take into account that files from the imported image
|
||||
* do not get their content filtered.
|
||||
* bit1= permission to overwrite existing zisofs_zf_info
|
||||
* bit2= if no zisofs header is found:
|
||||
* create xinfo with parameters which indicate no zisofs
|
||||
* bit3= no tree recursion if node is a directory
|
||||
* bit4= skip files which stem from the imported image
|
||||
* @return
|
||||
* 0= no zisofs data found
|
||||
* 1= zf xinfo added
|
||||
* 2= found existing zf xinfo and flag bit1 was not set
|
||||
* 3= both encountered: 1 and 2
|
||||
* <0 means error
|
||||
*
|
||||
* @since 0.6.18
|
||||
*/
|
||||
int iso_node_zf_by_magic(IsoNode *node, int flag);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef LIBISOFS_WITHOUT_LIBBURN
|
||||
|
126
libisofs/node.c
126
libisofs/node.c
@ -11,6 +11,8 @@
|
||||
#include "node.h"
|
||||
#include "stream.h"
|
||||
#include "aaip_0_2.h"
|
||||
#include "messages.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -2115,3 +2117,127 @@ ex:;
|
||||
return st_mode;
|
||||
}
|
||||
|
||||
|
||||
/* Function to identify and manage ZF parameters.
|
||||
* data is supposed to be a pointer to struct zisofs_zf_info
|
||||
*/
|
||||
int zisofs_zf_xinfo_func(void *data, int flag)
|
||||
{
|
||||
if (flag & 1) {
|
||||
free(data);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Checks whether a file effectively bears a zisofs file header and eventually
|
||||
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
||||
* @param flag bit0= inquire the most original stream of the file
|
||||
* bit1= permission to overwrite existing zisofs_zf_info
|
||||
* bit2= if no zisofs header is found:
|
||||
* create xinfo with parameters which indicate no zisofs
|
||||
* @return 1= zf xinfo added, 0= no zisofs data found ,
|
||||
* 2= found existing zf xinfo and flag bit1 was not set
|
||||
* <0 means error
|
||||
*/
|
||||
int iso_file_zf_by_magic(IsoFile *file, int flag)
|
||||
{
|
||||
int ret, stream_type, header_size_div4, block_size_log2;
|
||||
uint32_t uncompressed_size;
|
||||
IsoStream *stream, *input_stream;
|
||||
struct zisofs_zf_info *zf = NULL;
|
||||
void *xipt;
|
||||
|
||||
/* Intimate friendship with this function in filters/zisofs.c */
|
||||
int ziso_is_zisofs_stream(IsoStream *stream, int *stream_type,
|
||||
int *header_size_div4, int *block_size_log2,
|
||||
uint32_t *uncompressed_size, int flag);
|
||||
|
||||
ret = iso_node_get_xinfo((IsoNode *) file, zisofs_zf_xinfo_func, &xipt);
|
||||
if (ret == 1) {
|
||||
if (!(flag & 2))
|
||||
return 2;
|
||||
ret = iso_node_remove_xinfo((IsoNode *) file, zisofs_zf_xinfo_func);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
input_stream = stream = iso_file_get_stream(file);
|
||||
while (flag & 1) {
|
||||
input_stream = iso_stream_get_input_stream(stream, 0);
|
||||
if (input_stream == NULL)
|
||||
break;
|
||||
stream = input_stream;
|
||||
}
|
||||
ret = ziso_is_zisofs_stream(stream, &stream_type, &header_size_div4,
|
||||
&block_size_log2, &uncompressed_size, 3);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret != 1 || stream_type != 2) {
|
||||
if (flag & 4)
|
||||
return 0;
|
||||
header_size_div4 = 0;
|
||||
block_size_log2 = 0;
|
||||
uncompressed_size = 0;
|
||||
}
|
||||
zf = calloc(1, sizeof(struct zisofs_zf_info));
|
||||
if (zf == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
zf->uncompressed_size = uncompressed_size;
|
||||
zf->header_size_div4 = header_size_div4;
|
||||
zf->block_size_log2 = block_size_log2;
|
||||
ret = iso_node_add_xinfo((IsoNode *) file, zisofs_zf_xinfo_func, zf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_node_zf_by_magic(IsoNode *node, int flag)
|
||||
{
|
||||
int ret = 1, total_ret = 0, hflag;
|
||||
IsoFile *file;
|
||||
IsoNode *pos;
|
||||
IsoDir *dir;
|
||||
|
||||
if (node->type == LIBISO_FILE)
|
||||
return iso_file_zf_by_magic((IsoFile *) node, flag);
|
||||
if (node->type != LIBISO_DIR || (flag & 8))
|
||||
return 0;
|
||||
|
||||
dir = (IsoDir *) node;
|
||||
pos = dir->children;
|
||||
while (pos) {
|
||||
ret = 1;
|
||||
if (pos->type == LIBISO_FILE) {
|
||||
file = (IsoFile *) pos;
|
||||
if ((flag & 16) && file->from_old_session)
|
||||
return 0;
|
||||
if (!((flag & 1) && file->from_old_session)) {
|
||||
if (strncmp(file->stream->class->type, "ziso", 4) == 0)
|
||||
return 1; /* The stream is enough of marking */
|
||||
if (strncmp(file->stream->class->type, "osiz", 4) == 0) {
|
||||
if (flag & 2)
|
||||
iso_node_remove_xinfo(pos, zisofs_zf_xinfo_func);
|
||||
return 0; /* Will not be zisofs format */
|
||||
}
|
||||
}
|
||||
hflag = flag & ~6;
|
||||
if ((flag & 1) && file->from_old_session)
|
||||
hflag |= 1;
|
||||
ret = iso_file_zf_by_magic(file, hflag);
|
||||
} else if (pos->type == LIBISO_DIR) {
|
||||
ret = iso_node_zf_by_magic(pos, flag);
|
||||
}
|
||||
if (ret < 0) {
|
||||
total_ret = ret;
|
||||
ret = iso_msg_submit(-1, ret, 0, NULL);
|
||||
if (ret < 0) {
|
||||
return ret; /* cancel due error threshold */
|
||||
}
|
||||
} else if (total_ret >= 0) {
|
||||
total_ret |= ret;
|
||||
}
|
||||
pos = pos->next;
|
||||
}
|
||||
return total_ret;
|
||||
}
|
||||
|
||||
|
@ -366,4 +366,37 @@ int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
|
||||
size_t *value_length, char **value, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Function to identify and manage ZF parameters which do not stem from ZF
|
||||
* fields (those are known to the FileSource) and do not stem from filters
|
||||
* ("ziso" knows them globally, "osiz" knows them individually) but rather
|
||||
* from an inspection of the file content header for zisofs magic number and
|
||||
* plausible parameters.
|
||||
* The parameters get attached in struct zisofs_zf_info as xinfo to an IsoNode.
|
||||
*/
|
||||
int zisofs_zf_xinfo_func(void *data, int flag);
|
||||
|
||||
/**
|
||||
* Parameter structure which is to be managed by zisofs_zf_xinfo_func.
|
||||
*/
|
||||
struct zisofs_zf_info {
|
||||
uint32_t uncompressed_size;
|
||||
uint8_t header_size_div4;
|
||||
uint8_t block_size_log2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether a file effectively bears a zisofs file header and eventually
|
||||
* marks this by a struct zisofs_zf_info as xinfo of the file node.
|
||||
* @param flag bit0= inquire the most original stream of the file
|
||||
* bit1= permission to overwrite existing zisofs_zf_info
|
||||
* bit2= if no zisofs header is found:
|
||||
create xinfo with parameters which indicate no zisofs
|
||||
* @return 1= zf xinfo added, 0= no zisofs data found ,
|
||||
* 2= found existing zf xinfo and flag bit1 was not set
|
||||
* <0 means error
|
||||
*/
|
||||
int iso_file_zf_by_magic(IsoFile *file, int flag);
|
||||
|
||||
|
||||
#endif /*LIBISO_NODE_H_*/
|
||||
|
@ -809,6 +809,8 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
IsoStream *stream = NULL, *input_stream, *last_stream, *first_stream;
|
||||
IsoStream *first_filter = NULL;
|
||||
IsoFile *file;
|
||||
void *xipt;
|
||||
struct zisofs_zf_info *zf;
|
||||
|
||||
/* Intimate friendship with this function in filters/zisofs.c */
|
||||
int ziso_is_zisofs_stream(IsoStream *stream, int *stream_type,
|
||||
@ -867,22 +869,19 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
if (ret == 1 && header_size_div4 > 0)
|
||||
do_zf = 1;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_not_yeT
|
||||
if (t->zisofs_magic && (flag & 1) && !do_zf) {
|
||||
|
||||
if (will_copy) {
|
||||
stream = last_stream;
|
||||
} else {
|
||||
stream = first_stream;
|
||||
if (!do_zf) {
|
||||
/* Look for an xinfo mark of a zisofs header */
|
||||
ret = iso_node_get_xinfo((IsoNode *) file, zisofs_zf_xinfo_func,
|
||||
&xipt);
|
||||
if (ret == 1) {
|
||||
zf = xipt;
|
||||
header_size_div4 = zf->header_size_div4;
|
||||
block_size_log2 = zf->block_size_log2;
|
||||
uncompressed_size = zf->uncompressed_size;
|
||||
if (header_size_div4 > 0)
|
||||
do_zf = 1;
|
||||
}
|
||||
/* >>> open stream via temporary osiz filter and read 0 bytes.
|
||||
If no error: do_zf = 1; */;
|
||||
/* >>> obtain
|
||||
header_size_div4, block_size_log2, uncompressed_size */;
|
||||
/* >>> record info for runs with !(flag&1) : as n->node->xinfo */;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!do_zf)
|
||||
return 2;
|
||||
|
Loading…
Reference in New Issue
Block a user