Commit 8e7ab2be for libheif

commit 8e7ab2be2fd09f7f989bfec968e789ead1d31fd7
Author: Dirk Farin <dirk.farin@gmail.com>
Date:   Thu Jun 25 20:28:59 2026 +0200

    Scale alpha auxiliary track to main image size in sequence decoder

    The image sequence decoder attached an alpha auxiliary frame as the alpha
    channel without checking or adjusting its size, so a decoded frame could
    report a primary size that disagreed with its alpha plane size. The
    still-image decoder already scales the alpha plane to the main image size
    (ImageItem). Mirror that here so downstream consumers can rely on the alpha
    plane matching the color planes.

    Nothing in the standard requires the alpha auxiliary track to match the main
    track size, so this is normalization for consistency rather than a spec
    requirement. As in the still-image path, we may later add a decoding option
    to turn the automatic scaling off.

diff --git a/libheif/sequences/track_visual.cc b/libheif/sequences/track_visual.cc
index 66d325e0..f72ee038 100644
--- a/libheif/sequences/track_visual.cc
+++ b/libheif/sequences/track_visual.cc
@@ -298,6 +298,24 @@ Result<std::shared_ptr<HeifPixelImage> > Track_Visual::decode_next_image_sample(
     }

     auto alphaImage = *alphaResult;
+
+    // The alpha auxiliary track may have a different size than the main track. Nothing in the
+    // standard forbids this. We scale it to the main image size so that downstream consumers can
+    // rely on the alpha plane matching the color planes. This mirrors what the still-image decoder
+    // does in ImageItem (see image_item.cc). As noted there, we may later add a decoding option to
+    // turn this automatic scaling off, but that requires that libheif no longer assumes everywhere
+    // that the alpha channel has the same resolution as the color channels.
+    if (alphaImage->get_width() != image->get_width() ||
+        alphaImage->get_height() != image->get_height()) {
+      std::shared_ptr<HeifPixelImage> scaled_alpha;
+      Error err = alphaImage->scale_nearest_neighbor(scaled_alpha, image->get_width(), image->get_height(),
+                                                     m_heif_context->get_security_limits());
+      if (err) {
+        return err;
+      }
+      alphaImage = std::move(scaled_alpha);
+    }
+
     image->transfer_channel_from_image_as(alphaImage, heif_channel_Y, heif_channel_Alpha);
   }