Clean up aom_image_t metadata allocation functions
aom_img_add_metadata() (a public function) and alloc_read_metadata() (a
static function in av1/decoder/obu.c) both add a new aom_metadata_t to
an aom_metadata_array_t. They differ only in
1) who owns the aom_metadata_array_t (aom_image_t vs. AV1Decoder), and
2) the error reporting method (return value vs. aom_internal_error()).
Make the logic of the two functions as similar as possible. In
particular, aom_img_add_metadata() no longer frees the img->metadata
array on failure. This rewrite also fixes the leak of the old
img->metadata->metadata_array in aom_img_add_metadata() if the realloc()
call fails.
Improve the comments for some aom_image_t metadata allocation functions.
Change-Id: I20fa46934f112b4d0727ad848ac9c8a335183bf9
diff --git a/aom/aom_image.h b/aom/aom_image.h
index bb6973f..03bc73e 100644
--- a/aom/aom_image.h
+++ b/aom/aom_image.h
@@ -360,6 +360,9 @@
* \param[in] data Metadata contents
* \param[in] sz Metadata contents size
* \param[in] insert_flag Metadata insert flag
+ *
+ * \return Returns 0 on success. If img or data is NULL, sz is 0, or memory
+ * allocation fails, it returns -1.
*/
int aom_img_add_metadata(aom_image_t *img, uint32_t type, const uint8_t *data,
size_t sz, aom_metadata_insert_flags_t insert_flag);
@@ -410,6 +413,9 @@
* \param[in] data Metadata data pointer
* \param[in] sz Metadata size
* \param[in] insert_flag Metadata insert flag
+ *
+ * \return Returns the newly allocated aom_metadata struct. If data is NULL,
+ * sz is 0, or memory allocation fails, it returns NULL.
*/
aom_metadata_t *aom_img_metadata_alloc(uint32_t type, const uint8_t *data,
size_t sz,
diff --git a/aom/internal/aom_image_internal.h b/aom/internal/aom_image_internal.h
index 7f2fd18..1b04c9e 100644
--- a/aom/internal/aom_image_internal.h
+++ b/aom/internal/aom_image_internal.h
@@ -32,8 +32,8 @@
/*!\brief Alloc memory for aom_metadata_array struct.
*
* Allocate memory for aom_metadata_array struct.
- * If sz is 0 the aom_metadata_array structs internal buffer list will be NULL,
- * but the aom_metadata_array struct itself will still be allocated.
+ * If sz is 0 the aom_metadata_array struct's internal buffer list will be
+ * NULL, but the aom_metadata_array struct itself will still be allocated.
* Returns a pointer to the allocated struct or NULL on failure.
*
* \param[in] sz Size of internal metadata list buffer
diff --git a/aom/src/aom_image.c b/aom/src/aom_image.c
index cd0b5ed..dfdee87 100644
--- a/aom/src/aom_image.c
+++ b/aom/src/aom_image.c
@@ -350,26 +350,18 @@
}
aom_metadata_t *metadata =
aom_img_metadata_alloc(type, data, sz, insert_flag);
- if (!metadata) goto fail;
- if (!img->metadata->metadata_array) {
- img->metadata->metadata_array =
- (aom_metadata_t **)calloc(1, sizeof(metadata));
- if (!img->metadata->metadata_array || img->metadata->sz != 0) {
- aom_img_metadata_free(metadata);
- goto fail;
- }
- } else {
- img->metadata->metadata_array =
- (aom_metadata_t **)realloc(img->metadata->metadata_array,
- (img->metadata->sz + 1) * sizeof(metadata));
+ if (!metadata) return -1;
+ aom_metadata_t **metadata_array =
+ (aom_metadata_t **)realloc(img->metadata->metadata_array,
+ (img->metadata->sz + 1) * sizeof(metadata));
+ if (!metadata_array) {
+ aom_img_metadata_free(metadata);
+ return -1;
}
+ img->metadata->metadata_array = metadata_array;
img->metadata->metadata_array[img->metadata->sz] = metadata;
img->metadata->sz++;
return 0;
-fail:
- aom_img_metadata_array_free(img->metadata);
- img->metadata = NULL;
- return -1;
}
void aom_img_remove_metadata(aom_image_t *img) {
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index a172e88..2fd06ce 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -576,30 +576,30 @@
const uint8_t *data, size_t sz,
aom_metadata_insert_flags_t insert_flag) {
AV1_COMMON *const cm = &pbi->common;
+ if (!pbi->metadata) {
+ pbi->metadata = aom_img_metadata_array_alloc(0);
+ if (!pbi->metadata) {
+ aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
+ "Failed to allocate metadata array");
+ }
+ }
aom_metadata_t *metadata =
aom_img_metadata_alloc(metadata_type, data, sz, insert_flag);
if (!metadata) {
aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
"Error allocating metadata");
}
- if (!pbi->metadata) {
- pbi->metadata = aom_img_metadata_array_alloc(1);
- if (!pbi->metadata) {
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Failed to allocate metadata array");
- }
- } else {
- aom_metadata_t **metadata_array =
- (aom_metadata_t **)realloc(pbi->metadata->metadata_array,
- (pbi->metadata->sz + 1) * sizeof(metadata));
- if (!metadata_array) {
- aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
- "Error allocating metadata");
- }
- pbi->metadata->metadata_array = metadata_array;
- pbi->metadata->sz++;
+ aom_metadata_t **metadata_array =
+ (aom_metadata_t **)realloc(pbi->metadata->metadata_array,
+ (pbi->metadata->sz + 1) * sizeof(metadata));
+ if (!metadata_array) {
+ aom_img_metadata_free(metadata);
+ aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
+ "Error growing metadata array");
}
- pbi->metadata->metadata_array[pbi->metadata->sz - 1] = metadata;
+ pbi->metadata->metadata_array = metadata_array;
+ pbi->metadata->metadata_array[pbi->metadata->sz] = metadata;
+ pbi->metadata->sz++;
}
// On failure, calls aom_internal_error() and does not return.