Commit c52cc17a authored by Janne Grunau's avatar Janne Grunau Committed by Jean-Baptiste Kempf

API: constify Dav1dData and dav1d_data_wrap()

Fix #120.
parent 9f17489c
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "common.h" #include "common.h"
typedef struct Dav1dData { typedef struct Dav1dData {
uint8_t *data; ///< data pointer const uint8_t *data; ///< data pointer
size_t sz; ///< data size size_t sz; ///< data size
struct Dav1dRef *ref; ///< allocation origin struct Dav1dRef *ref; ///< allocation origin
} Dav1dData; } Dav1dData;
...@@ -45,9 +45,9 @@ typedef struct Dav1dData { ...@@ -45,9 +45,9 @@ typedef struct Dav1dData {
* @param data Input context. * @param data Input context.
* @param sz Size of the data that should be allocated. * @param sz Size of the data that should be allocated.
* *
* @return 0 on success. A negative errno value on error. * @return Pointer to the allocated bufferon success. NULL on error.
*/ */
DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz); DAV1D_API uint8_t * dav1d_data_create(Dav1dData *data, size_t sz);
/** /**
* Wrap an existing data array. * Wrap an existing data array.
...@@ -63,8 +63,8 @@ DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz); ...@@ -63,8 +63,8 @@ DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz);
* *
* @return 0 on success. A negative errno value on error. * @return 0 on success. A negative errno value on error.
*/ */
DAV1D_API int dav1d_data_wrap(Dav1dData *data, uint8_t *buf, size_t sz, DAV1D_API int dav1d_data_wrap(Dav1dData *data, const uint8_t *buf, size_t sz,
void (*free_callback)(uint8_t *buf, void *user_data), void (*free_callback)(const uint8_t *buf, void *user_data),
void *user_data); void *user_data);
/** /**
......
...@@ -37,19 +37,19 @@ ...@@ -37,19 +37,19 @@
#include "src/ref.h" #include "src/ref.h"
int dav1d_data_create(Dav1dData *const buf, const size_t sz) { uint8_t * dav1d_data_create(Dav1dData *const buf, const size_t sz) {
validate_input_or_ret(buf != NULL, -EINVAL); validate_input_or_ret(buf != NULL, NULL);
buf->ref = dav1d_ref_create(sz); buf->ref = dav1d_ref_create(sz);
if (!buf->ref) return -ENOMEM; if (!buf->ref) return NULL;
buf->data = buf->ref->data; buf->data = buf->ref->const_data;
buf->sz = sz; buf->sz = sz;
return 0; return buf->ref->data;
} }
int dav1d_data_wrap(Dav1dData *const buf, uint8_t *const ptr, const size_t sz, int dav1d_data_wrap(Dav1dData *const buf, const uint8_t *const ptr, const size_t sz,
void (*free_callback)(uint8_t *data, void *user_data), void (*free_callback)(const uint8_t *data, void *user_data),
void *user_data) void *user_data)
{ {
validate_input_or_ret(buf != NULL, -EINVAL); validate_input_or_ret(buf != NULL, -EINVAL);
......
...@@ -86,14 +86,15 @@ void default_picture_release(uint8_t *const data, void *const allocator_data, ...@@ -86,14 +86,15 @@ void default_picture_release(uint8_t *const data, void *const allocator_data,
struct pic_ctx_context { struct pic_ctx_context {
Dav1dPicAllocator allocator; Dav1dPicAllocator allocator;
void *allocator_data; void *allocator_data;
uint8_t *data;
void *extra_ptr; /* MUST BE AT THE END */ void *extra_ptr; /* MUST BE AT THE END */
}; };
static void free_buffer(uint8_t *data, void *user_data) static void free_buffer(const uint8_t *data, void *user_data)
{ {
struct pic_ctx_context *pic_ctx = user_data; struct pic_ctx_context *pic_ctx = user_data;
pic_ctx->allocator.release_picture_callback(data, pic_ctx->allocator.release_picture_callback(pic_ctx->data,
pic_ctx->allocator_data, pic_ctx->allocator_data,
pic_ctx->allocator.cookie); pic_ctx->allocator.cookie);
free(pic_ctx); free(pic_ctx);
...@@ -133,6 +134,7 @@ static int picture_alloc_with_edges(Dav1dPicture *const p, ...@@ -133,6 +134,7 @@ static int picture_alloc_with_edges(Dav1dPicture *const p,
pic_ctx->allocator = *p_allocator; pic_ctx->allocator = *p_allocator;
pic_ctx->allocator_data = p->allocator_data; pic_ctx->allocator_data = p->allocator_data;
pic_ctx->data = p->data[0];
if (!(p->ref = dav1d_ref_wrap(p->data[0], free_buffer, pic_ctx))) { if (!(p->ref = dav1d_ref_wrap(p->data[0], free_buffer, pic_ctx))) {
p_allocator->release_picture_callback(p->data[0], p->allocator_data, p_allocator->release_picture_callback(p->data[0], p->allocator_data,
......
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
#include "src/ref.h" #include "src/ref.h"
static void default_free_callback(uint8_t *const data, void *const user_data) { static void default_free_callback(const uint8_t *const data, void *const user_data) {
dav1d_free_aligned(data); assert(data == user_data);
dav1d_free_aligned(user_data);
} }
Dav1dRef *dav1d_ref_create(const size_t size) { Dav1dRef *dav1d_ref_create(const size_t size) {
...@@ -42,7 +43,7 @@ Dav1dRef *dav1d_ref_create(const size_t size) { ...@@ -42,7 +43,7 @@ Dav1dRef *dav1d_ref_create(const size_t size) {
return NULL; return NULL;
} }
res = dav1d_ref_wrap(data, default_free_callback, NULL); res = dav1d_ref_wrap(data, default_free_callback, data);
if (!res) { if (!res) {
free(data); free(data);
} }
...@@ -50,14 +51,16 @@ Dav1dRef *dav1d_ref_create(const size_t size) { ...@@ -50,14 +51,16 @@ Dav1dRef *dav1d_ref_create(const size_t size) {
return res; return res;
} }
Dav1dRef *dav1d_ref_wrap(uint8_t *const ptr, Dav1dRef *dav1d_ref_wrap(const uint8_t *const ptr,
void (*free_callback)(uint8_t *data, void *user_data), void (*free_callback)(const uint8_t *data, void *user_data),
void *user_data) void *user_data)
{ {
Dav1dRef *res = malloc(sizeof(Dav1dRef)); Dav1dRef *res = malloc(sizeof(Dav1dRef));
if (!res) return NULL; if (!res) return NULL;
res->data = ptr; if (ptr == user_data)
res->data = user_data;
res->const_data = ptr;
atomic_init(&res->ref_cnt, 1); atomic_init(&res->ref_cnt, 1);
res->free_callback = free_callback; res->free_callback = free_callback;
res->user_data = user_data; res->user_data = user_data;
...@@ -71,7 +74,7 @@ void dav1d_ref_inc(Dav1dRef *const ref) { ...@@ -71,7 +74,7 @@ void dav1d_ref_inc(Dav1dRef *const ref) {
void dav1d_ref_dec(Dav1dRef *const ref) { void dav1d_ref_dec(Dav1dRef *const ref) {
if (atomic_fetch_sub(&ref->ref_cnt, 1) == 1) { if (atomic_fetch_sub(&ref->ref_cnt, 1) == 1) {
ref->free_callback(ref->data, ref->user_data); ref->free_callback(ref->const_data, ref->user_data);
free(ref); free(ref);
} }
} }
...@@ -35,14 +35,15 @@ ...@@ -35,14 +35,15 @@
struct Dav1dRef { struct Dav1dRef {
void *data; void *data;
const void *const_data;
atomic_int ref_cnt; atomic_int ref_cnt;
void (*free_callback)(uint8_t *data, void *user_data); void (*free_callback)(const uint8_t *data, void *user_data);
void *user_data; void *user_data;
}; };
Dav1dRef *dav1d_ref_create(size_t size); Dav1dRef *dav1d_ref_create(size_t size);
Dav1dRef *dav1d_ref_wrap(uint8_t *ptr, Dav1dRef *dav1d_ref_wrap(const uint8_t *ptr,
void (*free_callback)(uint8_t *data, void *user_data), void (*free_callback)(const uint8_t *data, void *user_data),
void *user_data); void *user_data);
void dav1d_ref_inc(Dav1dRef *ref); void dav1d_ref_inc(Dav1dRef *ref);
void dav1d_ref_dec(Dav1dRef *ref); void dav1d_ref_dec(Dav1dRef *ref);
......
...@@ -65,6 +65,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) ...@@ -65,6 +65,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
while (ptr <= data + size - 12) { while (ptr <= data + size - 12) {
Dav1dData buf; Dav1dData buf;
uint8_t *p;
size_t frame_size = r32le(ptr); size_t frame_size = r32le(ptr);
ptr += 12; ptr += 12;
...@@ -73,9 +74,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) ...@@ -73,9 +74,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
break; break;
// copy frame data to a new buffer to catch reads past the end of input // copy frame data to a new buffer to catch reads past the end of input
err = dav1d_data_create(&buf, frame_size); p = dav1d_data_create(&buf, frame_size);
if (err) goto cleanup; if (!p) goto cleanup;
memcpy(buf.data, ptr, frame_size); memcpy(p, ptr, frame_size);
ptr += frame_size; ptr += frame_size;
do { do {
......
...@@ -86,14 +86,16 @@ static int ivf_open(IvfInputContext *const c, const char *const file, ...@@ -86,14 +86,16 @@ static int ivf_open(IvfInputContext *const c, const char *const file,
static int ivf_read(IvfInputContext *const c, Dav1dData *const buf) { static int ivf_read(IvfInputContext *const c, Dav1dData *const buf) {
uint8_t data[4]; uint8_t data[4];
uint8_t *ptr;
int res; int res;
if ((res = fread(data, 4, 1, c->f)) != 1) if ((res = fread(data, 4, 1, c->f)) != 1)
return -1; // EOF return -1; // EOF
fseek(c->f, 8, SEEK_CUR); // skip timestamp fseek(c->f, 8, SEEK_CUR); // skip timestamp
const ptrdiff_t sz = rl32(data); const ptrdiff_t sz = rl32(data);
dav1d_data_create(buf, sz); ptr = dav1d_data_create(buf, sz);
if ((res = fread(buf->data, sz, 1, c->f)) != 1) { if (!ptr) return -1;
if ((res = fread(ptr, sz, 1, c->f)) != 1) {
fprintf(stderr, "Failed to read frame data: %s\n", strerror(errno)); fprintf(stderr, "Failed to read frame data: %s\n", strerror(errno));
dav1d_data_unref(buf); dav1d_data_unref(buf);
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment