Skip to content

Commit

Permalink
Non-persistent input in incremental decoding test
Browse files Browse the repository at this point in the history
  • Loading branch information
y-guyon authored Sep 18, 2022
1 parent cec4eb5 commit 7f2156d
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions tests/gtest/avifincrtest_helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,17 @@ uint32_t GetMinDecodedRowCount(uint32_t height, uint32_t cell_height,
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;
}
Expand All @@ -134,7 +138,23 @@ avifResult PartialRead(struct avifIO* io, uint32_t read_flags, uint64_t offset,
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;
}
Expand Down Expand Up @@ -258,8 +278,9 @@ void DecodeIncrementally(const avifRWData& encoded_avif, bool is_persistent,
}

// 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,
Expand All @@ -269,7 +290,7 @@ void DecodeIncrementally(const avifRWData& encoded_avif, bool is_persistent,
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());
Expand Down

0 comments on commit 7f2156d

Please sign in to comment.