Fix the wrong calculation of buffer of AVIF image which cause memory peak by dreampiggy · Pull Request #66 · SDWebImage/SDWebImageAVIFCoder · GitHub
Skip to content

Fix the wrong calculation of buffer of AVIF image which cause memory peak - #66

Merged
dreampiggy merged 1 commit into
masterfrom
bugfix/calculation_buffer_size
Sep 15, 2025
Merged

dreampiggy merged 1 commit into
masterfrom
bugfix/calculation_buffer_size

Conversation

@dreampiggy

@dreampiggy dreampiggy commented Sep 15, 2025 •

Copy link
Copy Markdown
Collaborator

This close #65
This close #63

Summary by CodeRabbit

  • Bug Fixes

    • Corrected buffer sizing in AVIF image processing to match actual per-row data, preventing over-allocation that could cause elevated memory usage or occasional crashes with certain images.
  • Performance

    • Reduced memory footprint during AVIF decoding, improving efficiency and stability, especially on memory-constrained devices.
    • More consistent memory behavior when handling large or high-resolution AVIF images.

@coderabbitai

coderabbitai Bot commented Sep 15, 2025 •

Copy link
Copy Markdown

@dreampiggy
dreampiggy merged commit ae96dca into master Sep 15, 2025
0 of 3 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
SDWebImageAVIFCoder/Classes/Conversion.m (1)

176-181: Add overflow guard and reuse rowBytes for consistency.

  • Guard against size_t overflow when computing total allocation.
  • Reuse the computed rowBytes when initializing resultBuffer.rowBytes to avoid duplication and drift.

Apply this diff:

@@
-    size_t const rowBytes = components * sizeof(uint8_t) * avif->width;
+    size_t const rowBytes = avif->width * components;
@@
-    resultBufferData = calloc(rowBytes * avif->height, sizeof(uint8_t));
+    // Guard against overflow in allocation
+    if (avif->height != 0 && rowBytes > SIZE_MAX / avif->height) {
+        err = kvImageMemoryAllocationError;
+        goto end_all;
+    }
+    resultBufferData = calloc(avif->height, rowBytes);
@@
-        .rowBytes = avif->width * components,
+        .rowBytes = rowBytes,

Add this include once at the top of the file to use SIZE_MAX:

+#include <stdint.h>

Also applies to: 189-191, 203-208

🧹 Nitpick comments (2)
SDWebImageAVIFCoder/Classes/Conversion.m (2)

29-31: Avoid recomputing stride inside CreateImageFromBuffer.

Rely on the caller-provided vImage stride to reduce mismatch risk if future callers use aligned/packed rows.

Apply this diff:

@@
-    size_t bitsPerComponent = usesU16 ? 16 : 8;
-    size_t bitsPerPixel = components * bitsPerComponent;
-    size_t rowBytes = result->width * components * (usesU16 ? sizeof(uint16_t) : sizeof(uint8_t));
+    size_t bitsPerComponent = usesU16 ? 16 : 8;
+    size_t bitsPerPixel = components * bitsPerComponent;
+    size_t rowBytes = result->rowBytes; // trust provided stride

Also applies to: 43-47


171-171: Remove unused variable.

scaledAlphaBufferData in the 8-bit path is never written/used. Safe to drop to reduce noise.

Apply this diff:

-    uint8_t* scaledAlphaBufferData = NULL;
@@
-    if (scaledAlphaBufferData) free(scaledAlphaBufferData);

Also applies to: 541-541

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f784fcf and da93d8f.

📒 Files selected for processing (1)
  • SDWebImageAVIFCoder/Classes/Conversion.m (1 hunks)
🔇 Additional comments (1)
SDWebImageAVIFCoder/Classes/Conversion.m (1)

189-189: Correct buffer sizing fix — resolves 4x overallocation.

Allocating resultBufferData as rowBytes * height is the correct size for 8-bit paths. This should remove the inflated peak memory observed in #65 for animated frames.

If possible, profile an animated AVIF before/after this change and share the peak RSS/VM numbers to confirm the improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant