[libbluray-devel] Reduce inline file entry memory footprint
Petri Hintukainen
git at videolan.org
Fri Jun 9 12:33:39 CEST 2017
libudfread | branch: master | Petri Hintukainen <phintuka at gmail.com> | 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;
}
More information about the libbluray-devel
mailing list