heif: Clamp display height and display width
The earlier code clamped the value of display width and display
height in FrameDecoder.cpp. This approach was incorrect because
display width and display height are allowed to be greater than
width and height respectively when being called from
MediaMetadataRetriever.getScaledFrameAtTime. It was causing the
cts tests to fail.
The correct fix is to clamp them in the HeifDecoder since the
original set of changes were to support cropping in Heif.
Bug: 316481431, 320331874
Test: atest android.security.cts.StagefrightTest CtsMediaMiscTestCases
Change-Id: I5d0fcd70a81c9d429f175b4ca529a2554f4f9883
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 085a7e4..ee4075f 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -32,6 +32,7 @@
#include <private/media/VideoFrame.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
+#include <algorithm>
#include <vector>
HeifDecoder* createHeifDecoder() {
@@ -42,7 +43,10 @@
void initFrameInfo(HeifFrameInfo *info, const VideoFrame *videoFrame) {
info->mWidth = videoFrame->mDisplayWidth;
- info->mHeight = videoFrame->mDisplayHeight;
+ // Number of scanlines is mDisplayHeight. Clamp it to mHeight to guard
+ // against malformed streams claiming that mDisplayHeight is greater than
+ // mHeight.
+ info->mHeight = std::min(videoFrame->mDisplayHeight, videoFrame->mHeight);
info->mRotationAngle = videoFrame->mRotationAngle;
info->mBytesPerPixel = videoFrame->mBytesPerPixel;
info->mDurationUs = videoFrame->mDurationUs;
@@ -746,7 +750,9 @@
(videoFrame->mRowBytes * (mCurScanline + videoFrame->mDisplayTop)) +
(videoFrame->mBytesPerPixel * videoFrame->mDisplayLeft);
mCurScanline++;
- memcpy(dst, src, videoFrame->mBytesPerPixel * videoFrame->mDisplayWidth);
+ // Do not try to copy more than |videoFrame->mWidth| pixels.
+ uint32_t width = std::min(videoFrame->mDisplayWidth, videoFrame->mWidth);
+ memcpy(dst, src, videoFrame->mBytesPerPixel * width);
return true;
}