| 5216 | } |
| 5217 | |
| 5218 | static avifResult avifDecoderPrepareSample(avifDecoder * decoder, avifDecodeSample * sample, size_t partialByteCount) |
| 5219 | { |
| 5220 | if (!sample->data.size || sample->partialData) { |
| 5221 | // This sample hasn't been read from IO or had its extents fully merged yet. |
| 5222 | |
| 5223 | size_t bytesToRead = sample->size; |
| 5224 | if (partialByteCount && (bytesToRead > partialByteCount)) { |
| 5225 | bytesToRead = partialByteCount; |
| 5226 | } |
| 5227 | |
| 5228 | if (sample->itemID) { |
| 5229 | // The data comes from an item. Let avifDecoderItemRead() do the heavy lifting. |
| 5230 | |
| 5231 | avifDecoderItem * item; |
| 5232 | AVIF_CHECKRES(avifMetaFindOrCreateItem(decoder->data->meta, sample->itemID, &item)); |
| 5233 | avifROData itemContents; |
| 5234 | #if UINT64_MAX > SIZE_MAX |
| 5235 | if (sample->offset > SIZE_MAX) { |
| 5236 | return AVIF_RESULT_BMFF_PARSE_FAILED; |
| 5237 | } |
| 5238 | #endif |
| 5239 | size_t offset = (size_t)sample->offset; |
| 5240 | avifResult readResult = avifDecoderItemRead(item, decoder->io, &itemContents, offset, bytesToRead, &decoder->diag); |
| 5241 | if (readResult != AVIF_RESULT_OK) { |
| 5242 | return readResult; |
| 5243 | } |
| 5244 | |
| 5245 | // avifDecoderItemRead is guaranteed to already be persisted by either the underlying IO |
| 5246 | // or by mergedExtents; just reuse the buffer here. |
| 5247 | sample->data = itemContents; |
| 5248 | sample->ownsData = AVIF_FALSE; |
| 5249 | sample->partialData = item->partialMergedExtents; |
| 5250 | } else { |
| 5251 | // The data likely comes from a sample table. Pull the sample and make a copy if necessary. |
| 5252 | |
| 5253 | avifROData sampleContents; |
| 5254 | if ((decoder->io->sizeHint > 0) && (sample->offset > decoder->io->sizeHint)) { |
| 5255 | return AVIF_RESULT_BMFF_PARSE_FAILED; |
| 5256 | } |
| 5257 | avifResult readResult = decoder->io->read(decoder->io, 0, sample->offset, bytesToRead, &sampleContents); |
| 5258 | if (readResult != AVIF_RESULT_OK) { |
| 5259 | return readResult; |
| 5260 | } |
| 5261 | if (sampleContents.size != bytesToRead) { |
| 5262 | return AVIF_RESULT_TRUNCATED_DATA; |
| 5263 | } |
| 5264 | |
| 5265 | sample->ownsData = !decoder->io->persistent; |
| 5266 | sample->partialData = (bytesToRead != sample->size); |
| 5267 | if (decoder->io->persistent) { |
| 5268 | sample->data = sampleContents; |
| 5269 | } else { |
| 5270 | AVIF_CHECKRES(avifRWDataSet((avifRWData *)&sample->data, sampleContents.data, sampleContents.size)); |
| 5271 | } |
| 5272 | } |
| 5273 | } |
| 5274 | return AVIF_RESULT_OK; |
| 5275 | } |
no test coverage detected