MCPcopy Create free account
hub / github.com/AOMediaCodec/libavif / avifImageApplyExpression32b

Function avifImageApplyExpression32b

src/sampletransform.c:284–351  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

282AVIF_ARRAY_DECLARE(avifSampleTransformStack32b, int32_t, elements);
283
284static avifResult avifImageApplyExpression32b(avifImage * dstImage,
285 const avifSampleTransformExpression * expression,
286 const avifImage * inputImageItems[],
287 avifPlanesFlags planes,
288 int32_t * stack,
289 uint32_t stackCapacity)
290{
291 // This slow path could be avoided by recognizing the recipe thanks to avifSampleTransformExpressionToRecipe()
292 // and having a dedicated optimized implementation for each recipe.
293
294 const int32_t minValue = 0;
295 const int32_t maxValue = (1 << dstImage->depth) - 1;
296
297 const avifBool skipColor = !(planes & AVIF_PLANES_YUV);
298 const avifBool skipAlpha = !(planes & AVIF_PLANES_A);
299 for (int c = AVIF_CHAN_Y; c <= AVIF_CHAN_A; ++c) {
300 const avifBool alpha = c == AVIF_CHAN_A;
301 if ((skipColor && !alpha) || (skipAlpha && alpha)) {
302 continue;
303 }
304
305 const uint32_t planeWidth = avifImagePlaneWidth(dstImage, c);
306 const uint32_t planeHeight = avifImagePlaneHeight(dstImage, c);
307 for (uint32_t y = 0; y < planeHeight; ++y) {
308 for (uint32_t x = 0; x < planeWidth; ++x) {
309 uint32_t stackSize = 0;
310 for (uint32_t t = 0; t < expression->count; ++t) {
311 const avifSampleTransformToken * token = &expression->tokens[t];
312 if (token->type == AVIF_SAMPLE_TRANSFORM_CONSTANT) {
313 AVIF_ASSERT_OR_RETURN(stackSize < stackCapacity);
314 stack[stackSize++] = token->constant;
315 } else if (token->type == AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX) {
316 const avifImage * image = inputImageItems[token->inputImageItemIndex - 1]; // 1-based
317 const uint8_t * row = avifImagePlane(image, c);
318 AVIF_ASSERT_OR_RETURN(row != NULL);
319 row += (size_t)avifImagePlaneRowBytes(image, c) * y;
320 AVIF_ASSERT_OR_RETURN(stackSize < stackCapacity);
321 stack[stackSize++] = avifImageUsesU16(image) ? ((const uint16_t *)row)[x] : row[x];
322 } else if (token->type == AVIF_SAMPLE_TRANSFORM_NEGATION || token->type == AVIF_SAMPLE_TRANSFORM_ABSOLUTE ||
323 token->type == AVIF_SAMPLE_TRANSFORM_NOT || token->type == AVIF_SAMPLE_TRANSFORM_BSR) {
324 AVIF_ASSERT_OR_RETURN(stackSize >= 1);
325 stack[stackSize - 1] = avifSampleTransformOperation32bOneOperand(stack[stackSize - 1], token->type);
326 // Pop one and push one.
327 } else {
328 AVIF_ASSERT_OR_RETURN(stackSize >= 2);
329 stack[stackSize - 2] =
330 avifSampleTransformOperation32bTwoOperands(stack[stackSize - 2], stack[stackSize - 1], token->type);
331 stackSize--; // Pop two and push one.
332 }
333 }
334 AVIF_ASSERT_OR_RETURN(stackSize == 1);
335 // Fit to the range defined by the PixelInformationProperty.
336 // The limited/full range is ignored, like in other libavif encoding and decoding paths.
337 stack[0] = AVIF_CLAMP(stack[0], minValue, maxValue);
338
339 uint8_t * row = avifImagePlane(dstImage, c);
340 AVIF_ASSERT_OR_RETURN(row != NULL);
341 row += (size_t)avifImagePlaneRowBytes(dstImage, c) * y;

Callers 1

avifImageApplyExpressionFunction · 0.85

Calls 7

avifImagePlaneWidthFunction · 0.85
avifImagePlaneHeightFunction · 0.85
avifImagePlaneFunction · 0.85
avifImagePlaneRowBytesFunction · 0.85
avifImageUsesU16Function · 0.85

Tested by

no test coverage detected