libudfread | branch: master | Petri Hintukainen <[email protected]> | Wed Jun 7 23:04:51 2017 +0300| [1a4788b34e1e14a6c8c204a6f2f9d9ae895633b9] | committer: Petri Hintukainen
Reduce inline file entry memory footprint > http://git.videolan.org/gitweb.cgi/libudfread.git/?a=commit;h=1a4788b34e1e14a6c8c204a6f2f9d9ae895633b9 --- src/ecma167.c | 12 ++++++------ src/ecma167.h | 15 +++++++++++---- src/udfread.c | 26 +++++++++++++------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/ecma167.c b/src/ecma167.c index 6c694f9..00c4a4d 100644 --- a/src/ecma167.c +++ b/src/ecma167.c @@ -300,16 +300,16 @@ static struct file_entry *_decode_file_entry(const uint8_t *p, size_t size, fe->file_type = tag.file_type; fe->length = _get_u64(p + 56); - fe->num_ad = num_ad; fe->ad_type = tag.flags & 7; if (content_inline) { /* data of small files can be embedded in file entry */ /* copy embedded file data */ fe->content_inline = 1; - memcpy(fe->data.content, p + p_ad, l_ad); + memcpy(fe->u.data.content, p + p_ad, l_ad); } else { - _decode_file_ads(p + p_ad, fe->ad_type, partition, &fe->data.ad[0], num_ad); + fe->u.ads.num_ad = num_ad; + _decode_file_ads(p + p_ad, fe->ad_type, partition, &fe->u.ads.ad[0], num_ad); } return fe; @@ -339,15 +339,15 @@ int decode_allocation_extent(struct file_entry **p_fe, const uint8_t *p, size_t return 0; } - fe = (struct file_entry *)realloc(fe, sizeof(struct file_entry) + sizeof(struct long_ad) * (fe->num_ad + num_ad)); + fe = (struct file_entry *)realloc(fe, sizeof(struct file_entry) + sizeof(struct long_ad) * (fe->u.ads.num_ad + num_ad)); if (!fe) { return -1; } *p_fe = fe; /* decode new allocation descriptors */ - _decode_file_ads(p + 24, fe->ad_type, partition, &fe->data.ad[fe->num_ad], num_ad); - fe->num_ad += num_ad; + _decode_file_ads(p + 24, fe->ad_type, partition, &fe->u.ads.ad[fe->u.ads.num_ad], num_ad); + fe->u.ads.num_ad += num_ad; return 0; } diff --git a/src/ecma167.h b/src/ecma167.h index e483f05..38b73a2 100644 --- a/src/ecma167.h +++ b/src/ecma167.h @@ -214,11 +214,18 @@ struct file_entry { uint8_t content_inline; /* 1 if file data is embedded in file entry */ uint8_t ad_type; /* from icb_flags; used when parsing allocation extents */ - uint32_t num_ad; union { - struct long_ad ad[1]; /* Most files have only single extent, files in 3D BDs can have 100+. */ - uint8_t content[1]; /* content of small files is embedded here */ - } data; + /* "normal" file */ + struct { + uint32_t num_ad; + struct long_ad ad[1]; /* Most files have only single extent, files in 3D BDs can have 100+. */ + } ads; + + /* inline file */ + struct { + uint8_t content[1]; /* content of small files is embedded here */ + } data; + } u; }; struct file_entry *decode_file_entry (const uint8_t *p, size_t size, uint16_t partition); diff --git a/src/udfread.c b/src/udfread.c index 936e415..a0f050b 100644 --- a/src/udfread.c +++ b/src/udfread.c @@ -514,13 +514,13 @@ static int _map_metadata_partition(udfread_block_input *input, if (fe->content_inline) { udf_error("invalid metadata file (content inline)\n"); - } else if (!fe->num_ad) { + } else if (!fe->u.ads.num_ad) { udf_error("invalid metadata file (no allocation descriptors)\n"); } else if (fe->file_type == UDF_FT_METADATA) { - part->p[1].lba = pd->start_block + fe->data.ad[0].lba; + part->p[1].lba = pd->start_block + fe->u.ads.ad[0].lba; udf_log("metadata file at lba %u\n", part->p[1].lba); } else if (fe->file_type == UDF_FT_METADATA_MIRROR) { - part->p[1].mirror_lba = pd->start_block + fe->data.ad[0].lba; + part->p[1].mirror_lba = pd->start_block + fe->u.ads.ad[0].lba; udf_log("metadata mirror file at lba %u\n", part->p[1].mirror_lba); } else { udf_error("unknown metadata file type %u\n", fe->file_type); @@ -839,13 +839,13 @@ static struct file_entry *_read_file_entry(udfread *udf, /* read possible additional allocation extents */ if (fe) { - while (fe->num_ad > 0 && - fe->data.ad[fe->num_ad - 1].extent_type == ECMA_AD_EXTENT_AD) { + while (fe->u.ads.num_ad > 0 && + fe->u.ads.ad[fe->u.ads.num_ad - 1].extent_type == ECMA_AD_EXTENT_AD) { /* drop pointer to this extent from the end of AD list */ - fe->num_ad--; + fe->u.ads.num_ad--; - icb = &fe->data.ad[fe->num_ad]; + icb = &fe->u.ads.ad[fe->u.ads.num_ad]; udf_log("_read_file_entry: reading allocation extent @%u\n", icb->lba); buf = _read_metadata(udf, icb, &tag_id); @@ -963,16 +963,16 @@ static struct udf_dir *_read_dir(udfread *udf, const struct long_ad *icb) if (fe->content_inline) { dir = (struct udf_dir *)calloc(1, sizeof(struct udf_dir)); if (dir) { - if (_parse_dir(&fe->data.content[0], fe->length, dir) < 0) { + if (_parse_dir(&fe->u.data.content[0], fe->length, dir) < 0) { udf_error("failed parsing inline directory file\n"); _free_dir(&dir); } } - } else if (fe->num_ad == 0) { + } else if (fe->u.ads.num_ad == 0) { udf_error("empty directory file"); } else { - dir = _read_dir_file(udf, &fe->data.ad[0]); + dir = _read_dir_file(udf, &fe->u.ads.ad[0]); } free_file_entry(&fe); @@ -1400,8 +1400,8 @@ static uint32_t _file_lba(UDFFILE *p, uint32_t file_block) fe = p->fe; - for (i = 0; i < fe->num_ad; i++) { - const struct long_ad *ad = &fe->data.ad[0]; + for (i = 0; i < fe->u.ads.num_ad; i++) { + const struct long_ad *ad = &fe->u.ads.ad[0]; ad_size = (ad[i].length + UDF_BLOCK_SIZE - 1) / UDF_BLOCK_SIZE; if (file_block < ad_size) { @@ -1560,7 +1560,7 @@ ssize_t udfread_file_read(UDFFILE *p, void *buf, size_t bytes) /* small files may be stored inline in file entry */ if (p->fe->content_inline) { - memcpy(buf, &p->fe->data.content + p->pos, bytes); + memcpy(buf, &p->fe->u.data.content + p->pos, bytes); p->pos += bytes; return bytes; } _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
