Bug 1765871. Deal with oriented image frames in imgFrame::Finish. r=aosmond

Differential Revision: https://phabricator.services.mozilla.com/D144390
This commit is contained in:
Timothy Nikkel 2022-05-07 06:50:47 +00:00
Родитель 85f479d39b
Коммит 364d704041
5 изменённых файлов: 32 добавлений и 11 удалений

Просмотреть файл

@ -477,7 +477,10 @@ void Decoder::PostFrameStop(Opacity aFrameOpacity) {
mInFrame = false;
mFinishedNewFrame = true;
mCurrentFrame->Finish(aFrameOpacity, mFinalizeFrames);
mCurrentFrame->Finish(
aFrameOpacity, mFinalizeFrames,
/* aOrientationSwapsWidthAndHeight = */ mImageMetadata.HasOrientation() &&
mImageMetadata.GetOrientation().SwapsWidthAndHeight());
mProgress |= FLAG_FRAME_COMPLETE;

Просмотреть файл

@ -522,23 +522,39 @@ nsresult imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect) {
}
void imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */,
bool aFinalize /* = true */) {
bool aFinalize /* = true */,
bool aOrientationSwapsWidthAndHeight /* = false */) {
MonitorAutoLock lock(mMonitor);
IntRect frameRect(GetRect());
if (!mDecoded.IsEqualEdges(frameRect)) {
// The decoder should have produced rows starting from either the bottom or
// the top of the image. We need to calculate the region for which we have
// not yet invalidated.
// not yet invalidated. And if the orientation swaps width and height then
// its from the left or right.
IntRect delta(0, 0, frameRect.width, 0);
if (mDecoded.y == 0) {
delta.y = mDecoded.height;
delta.height = frameRect.height - mDecoded.height;
} else if (mDecoded.y + mDecoded.height == frameRect.height) {
delta.height = frameRect.height - mDecoded.y;
if (!aOrientationSwapsWidthAndHeight) {
delta.width = frameRect.width;
if (mDecoded.y == 0) {
delta.y = mDecoded.height;
delta.height = frameRect.height - mDecoded.height;
} else if (mDecoded.y + mDecoded.height == frameRect.height) {
delta.height = frameRect.height - mDecoded.y;
} else {
MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
delta = frameRect;
}
} else {
MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
delta = frameRect;
delta.height = frameRect.height;
if (mDecoded.x == 0) {
delta.x = mDecoded.width;
delta.width = frameRect.width - mDecoded.width;
} else if (mDecoded.x + mDecoded.width == frameRect.width) {
delta.width = frameRect.width - mDecoded.x;
} else {
MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
delta = frameRect;
}
}
ImageUpdatedInternal(delta);

Просмотреть файл

@ -109,7 +109,8 @@ class imgFrame {
* may be marked as read only if possible).
*/
void Finish(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY,
bool aFinalize = true);
bool aFinalize = true,
bool aOrientationSwapsWidthAndHeight = false);
/**
* Mark this imgFrame as aborted. This informs the imgFrame that if it isn't

Двоичные данные
image/test/crashtests/1765871-1.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.7 KiB

Просмотреть файл

@ -68,3 +68,4 @@ HTTP load 1634839-1.html
HTTP load 1634839-2.html
pref(image.animated.decode-on-demand.batch-size,1) pref(image.animated.decode-on-demand.threshold-kb,0) HTTP load 1676172-1.html
pref(browser.soft_reload.only_force_validate_top_level_document,false) HTTP load 1763581-1.html
load 1765871-1.jpg