Bug 1645920 [wpt PR 24157] - [AspectRatio] Make intrinsic sizes respect aspect-ratio...
[gecko.git] / image / SurfacePipe.cpp
blob1fbb25470d40bff3b2efdd1320767a689cc03425
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "SurfacePipe.h"
9 #include <algorithm> // for min
11 #include "Decoder.h"
13 namespace mozilla {
14 namespace image {
16 using namespace gfx;
18 using std::min;
20 Maybe<SurfaceInvalidRect> AbstractSurfaceSink::TakeInvalidRect() {
21 if (mInvalidRect.IsEmpty()) {
22 return Nothing();
25 SurfaceInvalidRect invalidRect;
26 invalidRect.mInputSpaceRect = invalidRect.mOutputSpaceRect = mInvalidRect;
28 // Forget about the invalid rect we're returning.
29 mInvalidRect = IntRect();
31 return Some(invalidRect);
34 uint8_t* AbstractSurfaceSink::DoResetToFirstRow() {
35 mRow = 0;
36 return GetRowPointer();
39 uint8_t* AbstractSurfaceSink::DoAdvanceRowFromBuffer(const uint8_t* aInputRow) {
40 CopyInputRow(aInputRow);
41 return DoAdvanceRow();
44 uint8_t* AbstractSurfaceSink::DoAdvanceRow() {
45 if (mRow >= uint32_t(InputSize().height)) {
46 return nullptr;
49 // If we're vertically flipping the output, we need to flip the invalid rect.
50 // Since we're dealing with an axis-aligned rect, only the y coordinate needs
51 // to change.
52 int32_t invalidY = mFlipVertically ? InputSize().height - (mRow + 1) : mRow;
53 mInvalidRect.UnionRect(mInvalidRect,
54 IntRect(0, invalidY, InputSize().width, 1));
56 mRow = min(uint32_t(InputSize().height), mRow + 1);
58 return mRow < uint32_t(InputSize().height) ? GetRowPointer() : nullptr;
61 nsresult SurfaceSink::Configure(const SurfaceConfig& aConfig) {
62 IntSize surfaceSize = aConfig.mOutputSize;
64 // Allocate the frame.
65 // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
66 // to allocate the frame directly here and get rid of Decoder::AllocateFrame
67 // altogether.
68 nsresult rv = aConfig.mDecoder->AllocateFrame(surfaceSize, aConfig.mFormat,
69 aConfig.mAnimParams);
70 if (NS_FAILED(rv)) {
71 return rv;
74 mImageData = aConfig.mDecoder->mImageData;
75 mImageDataLength = aConfig.mDecoder->mImageDataLength;
76 mFlipVertically = aConfig.mFlipVertically;
78 MOZ_ASSERT(mImageData);
79 MOZ_ASSERT(uint64_t(mImageDataLength) == uint64_t(surfaceSize.width) *
80 uint64_t(surfaceSize.height) *
81 sizeof(uint32_t));
83 ConfigureFilter(surfaceSize, sizeof(uint32_t));
84 return NS_OK;
87 uint8_t* SurfaceSink::GetRowPointer() const {
88 // If we're flipping vertically, reverse the order in which we traverse the
89 // rows.
90 uint32_t row = mFlipVertically ? InputSize().height - (mRow + 1) : mRow;
92 uint8_t* rowPtr = mImageData + row * InputSize().width * sizeof(uint32_t);
94 MOZ_ASSERT(rowPtr >= mImageData);
95 MOZ_ASSERT(rowPtr < mImageData + mImageDataLength);
96 MOZ_ASSERT(rowPtr + InputSize().width * sizeof(uint32_t) <=
97 mImageData + mImageDataLength);
99 return rowPtr;
102 } // namespace image
103 } // namespace mozilla