Remove file_size overloads
The code logic behind *WithSize() versions can be done by the user.
Simplifying avifinfo's API is better.
Change-Id: I51387032018a1fcbf703ba2ffb5981c7f08b78b8
diff --git a/avifinfo.c b/avifinfo.c
index 9630732..ba6f75d 100644
--- a/avifinfo.c
+++ b/avifinfo.c
@@ -25,7 +25,7 @@
} AvifInfoInternalStatus;
// uint32_t is used everywhere in this file. It is unlikely to be insufficient
-// to parse AVIF headers. Clamp any input to 2^32-1 for simplicity.
+// to parse AVIF headers.
#define AVIFINFO_MAX_SIZE UINT32_MAX
// AvifInfoInternalFeatures uses uint8_t to store values and the number of
// values is clamped to 32 to limit the stack size.
@@ -619,12 +619,11 @@
// Parses a file 'stream'. The file type is checked through the "ftyp" box and
// 'features' are extracted through the "meta" box.
static AvifInfoInternalStatus ParseFile(AvifInfoInternalStream* stream,
- uint32_t num_remaining_bytes,
uint32_t* num_parsed_boxes,
AvifInfoInternalFeatures* features) {
- do {
+ while (1) {
AvifInfoInternalBox box;
- AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, num_remaining_bytes,
+ AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, AVIFINFO_MAX_SIZE,
num_parsed_boxes, &box));
// The first box must be "ftyp" and no other box at root can be "ftyp".
AVIFINFO_CHECK((*num_parsed_boxes == 1) == !memcmp(box.type, "ftyp", 4),
@@ -652,8 +651,7 @@
} else {
AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, box.content_size));
}
- num_remaining_bytes -= box.size;
- } while (num_remaining_bytes != 0);
+ }
AVIFINFO_RETURN(kInvalid); // No "meta" no good.
}
@@ -687,21 +685,13 @@
AvifInfoStatus AvifInfoGet(const uint8_t* data, size_t data_size,
AvifInfoFeatures* features) {
- // Consider the file to be of maximum size.
- return AvifInfoGetWithSize(data, data_size, features,
- /*file_size=*/AVIFINFO_MAX_SIZE);
-}
-
-AvifInfoStatus AvifInfoGetWithSize(const uint8_t* data, size_t data_size,
- AvifInfoFeatures* features,
- size_t file_size) {
AvifInfoInternalForward stream;
stream.data = data;
stream.data_size = data_size;
// Forward null 'data' as a null 'stream' to handle it the same way.
- return AvifInfoReadWithSize(
- (void*)&stream, (data == NULL) ? NULL : AvifInfoInternalForwardRead,
- AvifInfoInternalForwardSkip, features, file_size);
+ return AvifInfoRead((void*)&stream,
+ (data == NULL) ? NULL : AvifInfoInternalForwardRead,
+ AvifInfoInternalForwardSkip, features);
}
//------------------------------------------------------------------------------
@@ -709,15 +699,6 @@
AvifInfoStatus AvifInfoRead(void* stream, read_stream_t read,
skip_stream_t skip, AvifInfoFeatures* features) {
- // Consider the file to be of maximum size.
- return AvifInfoReadWithSize(stream, read, skip, features,
- /*file_size=*/AVIFINFO_MAX_SIZE);
-}
-
-AvifInfoStatus AvifInfoReadWithSize(void* stream, read_stream_t read,
- skip_stream_t skip,
- AvifInfoFeatures* features,
- size_t file_size) {
if (features != NULL) memset(features, 0, sizeof(*features));
if (read == NULL) return kAvifInfoNotEnoughData;
@@ -726,20 +707,15 @@
internal_stream.read = read;
internal_stream.skip = skip; // Fallbacks to 'read' if null.
internal_stream.num_read_bytes = 0;
- const uint32_t size = (file_size >= AVIFINFO_MAX_SIZE) ? AVIFINFO_MAX_SIZE
- : (uint32_t)file_size;
uint32_t num_parsed_boxes = 0;
AvifInfoInternalFeatures internal_features;
memset(&internal_features, AVIFINFO_UNDEFINED, sizeof(internal_features));
// Go through all relevant boxes sequentially.
const AvifInfoInternalStatus status =
- ParseFile(&internal_stream, size, &num_parsed_boxes, &internal_features);
+ ParseFile(&internal_stream, &num_parsed_boxes, &internal_features);
- if (status == kNotFound) {
- return (internal_stream.num_read_bytes < file_size) ? kAvifInfoNotEnoughData
- : kAvifInfoInvalidFile;
- }
+ if (status == kNotFound) return kAvifInfoNotEnoughData;
if (status == kTruncated) return kAvifInfoNotEnoughData;
if (status == kInvalid) return kAvifInfoInvalidFile;
if (status == kAborted) return kAvifInfoTooComplex;
diff --git a/avifinfo.h b/avifinfo.h
index 414f52e..a940ea7 100644
--- a/avifinfo.h
+++ b/avifinfo.h
@@ -52,12 +52,6 @@
AvifInfoStatus AvifInfoGet(const uint8_t* data, size_t data_size,
AvifInfoFeatures* features);
-// Same as above with an extra argument 'file_size'. If the latter is known,
-// please use this version for extra bitstream validation.
-AvifInfoStatus AvifInfoGetWithSize(const uint8_t* data, size_t data_size,
- AvifInfoFeatures* features,
- size_t file_size);
-
//------------------------------------------------------------------------------
// Streamed input API
// Use this API if the input bytes must be fetched and/or if the AVIF payload
@@ -75,25 +69,14 @@
// Maximum number of bytes requested per read. There is no limit per skip.
#define AVIFINFO_MAX_NUM_READ_BYTES 64
-// Same as AvifInfoGet*() but takes a 'stream' as input. AvifInfoRead*() does
-// not access the 'stream' directly but passes it as is to 'read' and 'skip'.
+// Same as AvifInfoGet() but takes a 'stream' as input. AvifInfoRead() does not
+// access the 'stream' directly but passes it as is to 'read' and 'skip'.
// 'read' cannot be null. If 'skip' is null, 'read' is called instead.
AvifInfoStatus AvifInfoRead(void* stream, read_stream_t read,
skip_stream_t skip, AvifInfoFeatures* features);
-AvifInfoStatus AvifInfoReadWithSize(void* stream, read_stream_t read,
- skip_stream_t skip,
- AvifInfoFeatures* features,
- size_t file_size);
//------------------------------------------------------------------------------
-// If needed, avifinfo.h and avifinfo.c can be merged into a single file:
-// 1. Replace this block comment by the content of avifinfo.c
-// 2. Discard #include "./avifinfo.h" and move other includes to the top
-// 3. Mark AvifInfo*() declarations and definitions as static
-// This procedure can be useful when only one translation unit uses avifinfo,
-// whether it includes the merged .h or the merged code is inserted into a file.
-
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/tests/avifinfo_fuzz.cc b/tests/avifinfo_fuzz.cc
index bc9cb0b..d4a6526 100644
--- a/tests/avifinfo_fuzz.cc
+++ b/tests/avifinfo_fuzz.cc
@@ -56,8 +56,8 @@
for (size_t size = 0; size < data_size; ++size) {
StreamData stream = {data, size};
AvifInfoFeatures features;
- const AvifInfoStatus status = AvifInfoReadWithSize(
- &stream, StreamRead, StreamSkip, &features, data_size);
+ const AvifInfoStatus status =
+ AvifInfoRead(&stream, StreamRead, StreamSkip, &features);
if (previous_status != kAvifInfoNotEnoughData &&
status != previous_status) {
diff --git a/tests/avifinfo_test.cc b/tests/avifinfo_test.cc
index 381a8e8..108881d 100644
--- a/tests/avifinfo_test.cc
+++ b/tests/avifinfo_test.cc
@@ -32,7 +32,7 @@
//------------------------------------------------------------------------------
// Positive tests
-TEST(AvifInfoGetTest, WithoutFileSize) {
+TEST(AvifInfoGetTest, Ok) {
const Data input = LoadFile("avifinfo_test_1x1.avif");
ASSERT_FALSE(input.empty());
@@ -60,36 +60,6 @@
EXPECT_EQ(features.num_channels, 3u);
}
-TEST(AvifInfoGetTest, WithFileSize) {
- const Data input = LoadFile("avifinfo_test_1x1.avif");
- ASSERT_FALSE(input.empty());
-
- AvifInfoFeatures features;
- EXPECT_EQ(AvifInfoGetWithSize(input.data(), /*data_size=*/input.size(),
- &features, /*file_size=*/input.size()),
- kAvifInfoOk);
- EXPECT_EQ(features.width, 1u);
- EXPECT_EQ(features.height, 1u);
- EXPECT_EQ(features.bit_depth, 8u);
- EXPECT_EQ(features.num_channels, 3u);
-}
-
-TEST(AvifInfoGetTest, WithShorterSize) {
- const Data input = LoadFile("avifinfo_test_1x1.avif");
- ASSERT_FALSE(input.empty());
-
- AvifInfoFeatures features;
- // No more than 'file_size' bytes should be read, even if more are passed.
- EXPECT_EQ(AvifInfoGetWithSize(input.data(), /*data_size=*/input.size() * 10,
- &features,
- /*file_size=*/input.size()),
- kAvifInfoOk);
- EXPECT_EQ(features.width, 1u);
- EXPECT_EQ(features.height, 1u);
- EXPECT_EQ(features.bit_depth, 8u);
- EXPECT_EQ(features.num_channels, 3u);
-}
-
TEST(AvifInfoGetTest, EnoughBytes) {
Data input = LoadFile("avifinfo_test_1x1.avif");
ASSERT_FALSE(input.empty());
@@ -111,9 +81,6 @@
ASSERT_FALSE(input.empty());
EXPECT_EQ(AvifInfoGet(input.data(), input.size(), nullptr), kAvifInfoOk);
- EXPECT_EQ(
- AvifInfoGetWithSize(input.data(), input.size(), nullptr, input.size()),
- kAvifInfoOk);
}
//------------------------------------------------------------------------------
diff --git a/tools/avifinfo_tool.cc b/tools/avifinfo_tool.cc
index b16281c..0d0dc13 100644
--- a/tools/avifinfo_tool.cc
+++ b/tools/avifinfo_tool.cc
@@ -17,8 +17,8 @@
#include <unordered_map>
#include <vector>
-#include "avifinfo.h"
#include "avif/avif.h"
+#include "avifinfo.h"
namespace {
@@ -70,8 +70,7 @@
// Parses the AVIF at 'data' of 'data_size' bytes using libavifinfo.
Result ParseAvif(const uint8_t data[], size_t data_size) {
Result result;
- const AvifInfoStatus status = AvifInfoGetWithSize(
- data, data_size, &result.features, /*file_size=*/data_size);
+ const AvifInfoStatus status = AvifInfoGet(data, data_size, &result.features);
result.success = (status == kAvifInfoOk);
return result;
}
@@ -89,8 +88,7 @@
size_t max_data_size = data_size;
while (min_data_size < max_data_size) {
const size_t middle = (min_data_size + max_data_size) / 2;
- if (AvifInfoGetWithSize(data, middle, nullptr, /*file_size=*/data_size) ==
- kAvifInfoOk) {
+ if (AvifInfoGet(data, middle, nullptr) == kAvifInfoOk) {
max_data_size = middle;
} else {
min_data_size = middle + 1;