Non-persistent input in incremental decoding test
diff --git a/tests/gtest/avifincrtest_helpers.cc b/tests/gtest/avifincrtest_helpers.cc
index da26e09..4149b61 100644
--- a/tests/gtest/avifincrtest_helpers.cc
+++ b/tests/gtest/avifincrtest_helpers.cc
@@ -118,13 +118,17 @@
struct PartialData {
avifROData available;
size_t full_size;
+
+ // Only used as nonpersistent input.
+ std::unique_ptr<uint8_t[]> nonpersistent_bytes;
+ size_t num_nonpersistent_bytes;
};
// Implementation of avifIOReadFunc simulating a stream from an array. See
// avifIOReadFunc documentation. io->data is expected to point to PartialData.
avifResult PartialRead(struct avifIO* io, uint32_t read_flags, uint64_t offset,
size_t size, avifROData* out) {
- const PartialData* data = (PartialData*)io->data;
+ PartialData* data = reinterpret_cast<PartialData*>(io->data);
if ((read_flags != 0) || !data || (data->full_size < offset)) {
return AVIF_RESULT_IO_ERROR;
}
@@ -134,7 +138,23 @@
if (data->available.size < (offset + size)) {
return AVIF_RESULT_WAITING_ON_IO;
}
- out->data = data->available.data + offset;
+ if (io->persistent) {
+ out->data = data->available.data + offset;
+ } else {
+ // Dedicated buffer containing just the available bytes and nothing more.
+ std::unique_ptr<uint8_t[]> bytes(new uint8_t[size]);
+ std::copy(data->available.data + offset,
+ data->available.data + offset + size, bytes.get());
+ out->data = bytes.get();
+ // Flip the previously returned bytes to make sure the values changed.
+ for (size_t i = 0; i < data->num_nonpersistent_bytes; ++i) {
+ data->nonpersistent_bytes[i] = ~data->nonpersistent_bytes[i];
+ }
+ // Free the memory to invalidate the old pointer. Only do that after
+ // allocating the new bytes to make sure to have a different pointer.
+ data->nonpersistent_bytes = std::move(bytes);
+ data->num_nonpersistent_bytes = size;
+ }
out->size = size;
return AVIF_RESULT_OK;
}
@@ -258,8 +278,9 @@
}
// Emulate a byte-by-byte stream.
- PartialData data = {/*available=*/{encoded_avif.data, 0},
- /*fullSize=*/encoded_avif.size};
+ PartialData data = {
+ /*available=*/{encoded_avif.data, 0}, /*fullSize=*/encoded_avif.size,
+ /*nonpersistent_bytes=*/nullptr, /*num_nonpersistent_bytes=*/0};
avifIO io = {
/*destroy=*/nullptr, PartialRead,
/*write=*/nullptr, give_size_hint ? encoded_avif.size : 0,
@@ -269,7 +290,7 @@
ASSERT_NE(decoder, nullptr);
avifDecoderSetIO(decoder.get(), &io);
decoder->allowIncremental = AVIF_TRUE;
- const size_t step = std::max(static_cast<size_t>(1), data.full_size / 10000);
+ const size_t step = std::max<size_t>(1, data.full_size / 10000);
// Parsing is not incremental.
avifResult parse_result = avifDecoderParse(decoder.get());