зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 5 changesets (bug 1290292, bug 1290293) for gfx assertions
CLOSED TREE Backed out changeset 652c909b75ad (bug 1290293) Backed out changeset 90a284ea19e3 (bug 1290292) Backed out changeset 8401d12fe936 (bug 1290293) Backed out changeset d87488b69c18 (bug 1290293) Backed out changeset 7368aa665fae (bug 1290293)
This commit is contained in:
Родитель
33173f619b
Коммит
c7b01ecbda
|
@ -31,7 +31,6 @@ Downscaler::Downscaler(const nsIntSize& aTargetSize)
|
|||
, mXFilter(MakeUnique<skia::ConvolutionFilter1D>())
|
||||
, mYFilter(MakeUnique<skia::ConvolutionFilter1D>())
|
||||
, mWindowCapacity(0)
|
||||
, mClearValue(0)
|
||||
, mHasAlpha(true)
|
||||
, mFlipVertically(false)
|
||||
{
|
||||
|
@ -100,7 +99,6 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
|||
mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width,
|
||||
double(mOriginalSize.height) / mTargetSize.height);
|
||||
mOutputBuffer = aOutputBuffer;
|
||||
mClearValue = aHasAlpha ? 0 : 0xFF;
|
||||
mHasAlpha = aHasAlpha;
|
||||
mFlipVertically = aFlipVertically;
|
||||
|
||||
|
@ -208,15 +206,6 @@ GetFilterOffsetAndLength(UniquePtr<skia::ConvolutionFilter1D>& aFilter,
|
|||
aFilterLengthOut);
|
||||
}
|
||||
|
||||
void
|
||||
Downscaler::ClearRemainingRows()
|
||||
{
|
||||
while (!IsFrameComplete()) {
|
||||
ClearRow();
|
||||
CommitRow();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Downscaler::ClearRestOfRow(uint32_t aStartingAtCol)
|
||||
{
|
||||
|
@ -224,7 +213,7 @@ Downscaler::ClearRestOfRow(uint32_t aStartingAtCol)
|
|||
uint32_t bytesToClear = (mOriginalSize.width - aStartingAtCol)
|
||||
* sizeof(uint32_t);
|
||||
memset(mRowBuffer.get() + (aStartingAtCol * sizeof(uint32_t)),
|
||||
mClearValue, bytesToClear);
|
||||
0, bytesToClear);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -93,9 +93,6 @@ public:
|
|||
return mRowBuffer.get() + mFrameRect.x * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/// Clears the remaining unset rows.
|
||||
void ClearRemainingRows();
|
||||
|
||||
/// Clears the current row buffer.
|
||||
void ClearRow() { ClearRestOfRow(0); }
|
||||
|
||||
|
@ -142,7 +139,6 @@ private:
|
|||
int32_t mPrevInvalidatedLine;
|
||||
int32_t mCurrentOutLine;
|
||||
int32_t mCurrentInLine;
|
||||
uint8_t mClearValue;
|
||||
|
||||
bool mHasAlpha : 1;
|
||||
bool mFlipVertically : 1;
|
||||
|
|
|
@ -72,7 +72,6 @@ class DownscalingFilter final : public SurfaceFilter
|
|||
{
|
||||
public:
|
||||
Maybe<SurfaceInvalidRect> TakeInvalidRect() override { return Nothing(); }
|
||||
bool GetClearValue(uint8_t& aValue) const override { return false; }
|
||||
|
||||
template <typename... Rest>
|
||||
nsresult Configure(const DownscalingConfig& aConfig, Rest... aRest)
|
||||
|
@ -81,7 +80,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void DoZeroOutRestOfSurface() override { }
|
||||
uint8_t* DoResetToFirstRow() override { MOZ_CRASH(); return nullptr; }
|
||||
uint8_t* DoAdvanceRow() override { MOZ_CRASH(); return nullptr; }
|
||||
};
|
||||
|
@ -173,9 +171,7 @@ public:
|
|||
}
|
||||
|
||||
// Clear the buffer to avoid writing uninitialized memory to the output.
|
||||
uint8_t clear = 0;
|
||||
GetClearValue(clear);
|
||||
memset(mRowBuffer.get(), clear, PaddedWidthInBytes(mInputSize.width));
|
||||
memset(mRowBuffer.get(), 0, PaddedWidthInBytes(mInputSize.width));
|
||||
|
||||
// Allocate the window, which contains horizontally downscaled scanlines. (We
|
||||
// can store scanlines which are already downscaled because our downscaling
|
||||
|
@ -218,19 +214,7 @@ public:
|
|||
return invalidRect;
|
||||
}
|
||||
|
||||
bool GetClearValue(uint8_t& aValue) const override
|
||||
{
|
||||
return mNext.GetClearValue(aValue);
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoZeroOutRestOfSurface() override
|
||||
{
|
||||
mNext.ZeroOutRestOfSurface();
|
||||
mInputRow = mInputSize.height;
|
||||
mOutputRow = mNext.InputSize().height;
|
||||
}
|
||||
|
||||
uint8_t* DoResetToFirstRow() override
|
||||
{
|
||||
mNext.ResetToFirstRow();
|
||||
|
|
|
@ -113,9 +113,7 @@ public:
|
|||
}
|
||||
|
||||
// Clear the buffer to avoid writing uninitialized memory to the output.
|
||||
uint8_t clear = 0;
|
||||
GetClearValue(clear);
|
||||
memset(mBuffer.get(), clear, bufferSize);
|
||||
memset(mBuffer.get(), 0, bufferSize);
|
||||
|
||||
ConfigureFilter(outputSize, sizeof(PixelType));
|
||||
return NS_OK;
|
||||
|
@ -131,19 +129,7 @@ public:
|
|||
return mNext.TakeInvalidRect();
|
||||
}
|
||||
|
||||
bool GetClearValue(uint8_t& aValue) const override
|
||||
{
|
||||
return mNext.GetClearValue(aValue);
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoZeroOutRestOfSurface() override
|
||||
{
|
||||
mNext.ZeroOutRestOfSurface();
|
||||
mInputRow = InputSize().height;
|
||||
mPass = 4;
|
||||
}
|
||||
|
||||
uint8_t* DoResetToFirstRow() override
|
||||
{
|
||||
mNext.ResetToFirstRow();
|
||||
|
@ -416,9 +402,7 @@ public:
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
uint8_t clear = 0;
|
||||
GetClearValue(clear);
|
||||
memset(mBuffer.get(), clear, mUnclampedFrameRect.width * sizeof(uint32_t));
|
||||
memset(mBuffer.get(), 0, mUnclampedFrameRect.width * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
ConfigureFilter(mUnclampedFrameRect.Size(), sizeof(uint32_t));
|
||||
|
@ -430,18 +414,7 @@ public:
|
|||
return mNext.TakeInvalidRect();
|
||||
}
|
||||
|
||||
bool GetClearValue(uint8_t& aValue) const override
|
||||
{
|
||||
return mNext.GetClearValue(aValue);
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoZeroOutRestOfSurface() override
|
||||
{
|
||||
mNext.ZeroOutRestOfSurface();
|
||||
mRow = mFrameRect.YMost();
|
||||
}
|
||||
|
||||
uint8_t* DoResetToFirstRow() override
|
||||
{
|
||||
uint8_t* rowPtr = mNext.ResetToFirstRow();
|
||||
|
@ -495,7 +468,7 @@ protected:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// If we had to buffer, copy the data.
|
||||
// If we had to buffer, copy the data. Otherwise, just advance the row.
|
||||
if (mBuffer) {
|
||||
// We write from the beginning of the buffer unless |mUnclampedFrameRect.x|
|
||||
// is negative; if that's the case, we have to skip the portion of the
|
||||
|
@ -512,21 +485,6 @@ protected:
|
|||
rowPtr = state == WriteState::NEED_MORE_DATA ? mBuffer.get()
|
||||
: nullptr;
|
||||
} else {
|
||||
// We need to manually clear the pixels that are not written to before we
|
||||
// advance the row.
|
||||
uint8_t* currentRowPtr = CurrentRowPointer();
|
||||
if (currentRowPtr) {
|
||||
uint8_t clear = 0;
|
||||
if (GetClearValue(clear)) {
|
||||
gfx::IntSize outputSize = mNext.InputSize();
|
||||
const size_t pixelSize = sizeof(uint32_t);
|
||||
const size_t prefixOffset = mFrameRect.x * pixelSize;
|
||||
const size_t postfixOffset = mFrameRect.width * pixelSize;
|
||||
const size_t postfixLength = (outputSize.width - mFrameRect.XMost()) * pixelSize;
|
||||
memset(currentRowPtr - prefixOffset, clear, prefixOffset);
|
||||
memset(currentRowPtr + postfixOffset, clear, postfixLength);
|
||||
}
|
||||
}
|
||||
rowPtr = mNext.AdvanceRow();
|
||||
}
|
||||
|
||||
|
@ -658,10 +616,8 @@ public:
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
uint8_t clear = 0;
|
||||
GetClearValue(clear);
|
||||
memset(mPreviousRow.get(), clear, inputWidthInBytes);
|
||||
memset(mCurrentRow.get(), clear, inputWidthInBytes);
|
||||
memset(mPreviousRow.get(), 0, inputWidthInBytes);
|
||||
memset(mCurrentRow.get(), 0, inputWidthInBytes);
|
||||
|
||||
ConfigureFilter(mNext.InputSize(), sizeof(uint32_t));
|
||||
return NS_OK;
|
||||
|
@ -672,19 +628,7 @@ public:
|
|||
return mNext.TakeInvalidRect();
|
||||
}
|
||||
|
||||
bool GetClearValue(uint8_t& aValue) const override
|
||||
{
|
||||
return mNext.GetClearValue(aValue);
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoZeroOutRestOfSurface() override
|
||||
{
|
||||
mNext.ZeroOutRestOfSurface();
|
||||
mRow = InputSize().height;
|
||||
mPass = 7;
|
||||
}
|
||||
|
||||
uint8_t* DoResetToFirstRow() override
|
||||
{
|
||||
mRow = 0;
|
||||
|
|
|
@ -62,59 +62,6 @@ AbstractSurfaceSink::TakeInvalidRect()
|
|||
return Some(invalidRect);
|
||||
}
|
||||
|
||||
void
|
||||
AbstractSurfaceSink::DoZeroOutRestOfSurface()
|
||||
{
|
||||
// If there is no explicit clear value, we know the surface was already
|
||||
// zeroed out by default.
|
||||
if (!mClearRequired) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The reason we do not use the typical WritePixels methods here is
|
||||
// because if it is a progressively decoded image, we know that we
|
||||
// already have valid data written to the buffer, just not the final
|
||||
// result. There is no need to clear the buffers in that case.
|
||||
const int32_t width = InputSize().width;
|
||||
const int32_t height = InputSize().height;
|
||||
const int32_t pixelSize = IsValidPalettedPipe() ? sizeof(uint8_t)
|
||||
: sizeof(uint32_t);
|
||||
const int32_t stride = width * pixelSize;
|
||||
|
||||
// In addition to fully unwritten rows, the current row may be partially
|
||||
// written (i.e. mCol > 0). Since the row was not advanced, we have yet to
|
||||
// update mWrittenRect so it would be cleared without the exception below.
|
||||
const int32_t col = CurrentColumn();
|
||||
if (MOZ_UNLIKELY(col > 0 && col <= width)) {
|
||||
uint8_t* rowPtr = CurrentRowPointer();
|
||||
MOZ_ASSERT(rowPtr);
|
||||
memset(rowPtr + col * pixelSize, mClearValue, (width - col) * pixelSize);
|
||||
AdvanceRow(); // updates mInvalidRect and mWrittenRect
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mWrittenRect.x == 0);
|
||||
MOZ_ASSERT(mWrittenRect.width == 0 || mWrittenRect.width == width);
|
||||
|
||||
if (MOZ_UNLIKELY(mWrittenRect.y > 0)) {
|
||||
const uint32_t length = mWrittenRect.y * stride;
|
||||
auto updateRect = IntRect(0, 0, width, mWrittenRect.y);
|
||||
MOZ_ASSERT(mImageDataLength >= length);
|
||||
memset(mImageData, mClearValue, length);
|
||||
mInvalidRect.UnionRect(mInvalidRect, updateRect);
|
||||
mWrittenRect.UnionRect(mWrittenRect, updateRect);
|
||||
}
|
||||
|
||||
const int32_t top = mWrittenRect.y + mWrittenRect.height;
|
||||
if (MOZ_UNLIKELY(top < height)) {
|
||||
const int32_t remainder = height - top;
|
||||
auto updateRect = IntRect(0, top, width, remainder);
|
||||
MOZ_ASSERT(mImageDataLength >= (uint32_t)(height * stride));
|
||||
memset(mImageData + top * stride, mClearValue, remainder * stride);
|
||||
mInvalidRect.UnionRect(mInvalidRect, updateRect);
|
||||
mWrittenRect.UnionRect(mWrittenRect, updateRect);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
AbstractSurfaceSink::DoResetToFirstRow()
|
||||
{
|
||||
|
@ -136,7 +83,6 @@ AbstractSurfaceSink::DoAdvanceRow()
|
|||
: mRow;
|
||||
mInvalidRect.UnionRect(mInvalidRect,
|
||||
IntRect(0, invalidY, InputSize().width, 1));
|
||||
mWrittenRect.UnionRect(mWrittenRect, mInvalidRect);
|
||||
|
||||
mRow = min(uint32_t(InputSize().height), mRow + 1);
|
||||
|
||||
|
@ -170,14 +116,6 @@ SurfaceSink::Configure(const SurfaceConfig& aConfig)
|
|||
mImageDataLength = aConfig.mDecoder->mImageDataLength;
|
||||
mFlipVertically = aConfig.mFlipVertically;
|
||||
|
||||
if (aConfig.mFormat == SurfaceFormat::B8G8R8X8) {
|
||||
mClearRequired = true;
|
||||
mClearValue = 0xFF;
|
||||
} else if (aConfig.mDecoder->mCurrentFrame->OnHeap()) {
|
||||
mClearRequired = true;
|
||||
mClearValue = 0;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mImageData);
|
||||
MOZ_ASSERT(mImageDataLength ==
|
||||
uint32_t(surfaceSize.width * surfaceSize.height * sizeof(uint32_t)));
|
||||
|
@ -210,7 +148,6 @@ nsresult
|
|||
PalettedSurfaceSink::Configure(const PalettedSurfaceConfig& aConfig)
|
||||
{
|
||||
MOZ_ASSERT(aConfig.mFormat == SurfaceFormat::B8G8R8A8);
|
||||
MOZ_ASSERT(mClearValue == 0);
|
||||
|
||||
// For paletted surfaces, the surface size is the size of the frame rect.
|
||||
IntSize surfaceSize = aConfig.mFrameRect.Size();
|
||||
|
@ -232,7 +169,6 @@ PalettedSurfaceSink::Configure(const PalettedSurfaceConfig& aConfig)
|
|||
mImageDataLength = aConfig.mDecoder->mImageDataLength;
|
||||
mFlipVertically = aConfig.mFlipVertically;
|
||||
mFrameRect = aConfig.mFrameRect;
|
||||
mClearRequired = true;
|
||||
|
||||
MOZ_ASSERT(mImageData);
|
||||
MOZ_ASSERT(mImageDataLength ==
|
||||
|
|
|
@ -105,17 +105,6 @@ public:
|
|||
|
||||
virtual ~SurfaceFilter() { }
|
||||
|
||||
/**
|
||||
* Called when there are no more pixels from the caller to write. It will
|
||||
* ensure that any unwritten pixels are cleared with an appropriate value.
|
||||
*/
|
||||
void ZeroOutRestOfSurface()
|
||||
{
|
||||
DoZeroOutRestOfSurface();
|
||||
mCol = 0;
|
||||
mRowPointer = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset this surface to the first row. It's legal for this filter to throw
|
||||
* away any previously written data at this point, as all rows must be written
|
||||
|
@ -310,11 +299,7 @@ public:
|
|||
NS_WARNING("Provided starting column is out-of-bounds in WriteBuffer");
|
||||
}
|
||||
|
||||
uint8_t clear = 0;
|
||||
bool clearRequired = GetClearValue(clear);
|
||||
if (clearRequired) {
|
||||
memset(dest, clear, mInputSize.width * sizeof(PixelType));
|
||||
}
|
||||
memset(dest, 0, mInputSize.width * sizeof(PixelType));
|
||||
dest += prefixLength;
|
||||
|
||||
// Write |aLength| pixels from |aSource| into the row, with bounds checking.
|
||||
|
@ -329,9 +314,7 @@ public:
|
|||
|
||||
// Clear the rest of the row.
|
||||
const size_t suffixLength = mInputSize.width - (prefixLength + bufferLength);
|
||||
if (clearRequired) {
|
||||
memset(dest, clear, suffixLength * sizeof(PixelType));
|
||||
}
|
||||
memset(dest, 0, suffixLength * sizeof(PixelType));
|
||||
|
||||
AdvanceRow();
|
||||
|
||||
|
@ -352,18 +335,13 @@ public:
|
|||
return WriteState::FINISHED; // Already done.
|
||||
}
|
||||
|
||||
uint8_t clear = 0;
|
||||
if (GetClearValue(clear)) {
|
||||
memset(mRowPointer, clear, mInputSize.width * mPixelSize);
|
||||
}
|
||||
memset(mRowPointer, 0, mInputSize.width * mPixelSize);
|
||||
AdvanceRow();
|
||||
|
||||
return IsSurfaceFinished() ? WriteState::FINISHED
|
||||
: WriteState::NEED_MORE_DATA;
|
||||
}
|
||||
|
||||
virtual bool GetClearValue(uint8_t& aValue) const = 0;
|
||||
|
||||
/**
|
||||
* Write a row to the surface by calling a lambda that uses a pointer to
|
||||
* directly write to the row. This is unsafe because SurfaceFilter can't
|
||||
|
@ -428,13 +406,6 @@ public:
|
|||
virtual Maybe<SurfaceInvalidRect> TakeInvalidRect() = 0;
|
||||
|
||||
protected:
|
||||
/// @return the column for the next pixel to be written in the current row.
|
||||
int32_t CurrentColumn() const { return mCol; }
|
||||
|
||||
/* Called by ZeroOutRestOfSurface() to actually perform the clearing of the
|
||||
* unwritten pixels.
|
||||
*/
|
||||
virtual void DoZeroOutRestOfSurface() = 0;
|
||||
|
||||
/**
|
||||
* Called by ResetToFirstRow() to actually perform the reset. It's legal to
|
||||
|
@ -451,6 +422,7 @@ protected:
|
|||
*/
|
||||
virtual uint8_t* DoAdvanceRow() = 0;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Methods For Internal Use By Subclasses
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -512,7 +484,7 @@ private:
|
|||
return Some(WriteState::NEED_MORE_DATA);
|
||||
|
||||
case WriteState::FINISHED:
|
||||
ZeroOutRestOfSurface();
|
||||
ZeroOutRestOfSurface<PixelType>();
|
||||
return Some(WriteState::FINISHED);
|
||||
|
||||
case WriteState::FAILURE:
|
||||
|
@ -530,6 +502,12 @@ private:
|
|||
: Nothing();
|
||||
}
|
||||
|
||||
template <typename PixelType>
|
||||
void ZeroOutRestOfSurface()
|
||||
{
|
||||
WritePixels<PixelType>([]{ return AsVariant(PixelType(0)); });
|
||||
}
|
||||
|
||||
gfx::IntSize mInputSize; /// The size of the input this filter expects.
|
||||
uint8_t* mRowPointer; /// Pointer to the current row or null if finished.
|
||||
int32_t mCol; /// The current column we're writing to. (0-indexed)
|
||||
|
@ -565,10 +543,7 @@ public:
|
|||
|
||||
Maybe<SurfaceInvalidRect> TakeInvalidRect() override { return Nothing(); }
|
||||
|
||||
bool GetClearValue(uint8_t& aValue) const override { return false; }
|
||||
|
||||
protected:
|
||||
void DoZeroOutRestOfSurface() override { }
|
||||
uint8_t* DoResetToFirstRow() override { return nullptr; }
|
||||
uint8_t* DoAdvanceRow() override { return nullptr; }
|
||||
|
||||
|
@ -688,22 +663,6 @@ public:
|
|||
return mHead->WriteEmptyRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write all remaining unset rows to an empty row to the surface. If some pixels
|
||||
* have already been written to this row, they'll be discarded.
|
||||
*
|
||||
* @see SurfaceFilter::WriteEmptyRow() for the canonical documentation.
|
||||
*/
|
||||
void ZeroOutRestOfSurface()
|
||||
{
|
||||
mHead->ZeroOutRestOfSurface();
|
||||
}
|
||||
|
||||
bool GetClearValue(uint8_t& aValue) const
|
||||
{
|
||||
return mHead->GetClearValue(aValue);
|
||||
}
|
||||
|
||||
/// @return true if we've finished writing to the surface.
|
||||
bool IsSurfaceFinished() const { return mHead->IsSurfaceFinished(); }
|
||||
|
||||
|
@ -739,34 +698,21 @@ public:
|
|||
, mImageDataLength(0)
|
||||
, mRow(0)
|
||||
, mFlipVertically(false)
|
||||
, mClearRequired(false)
|
||||
, mClearValue(0)
|
||||
{ }
|
||||
|
||||
Maybe<SurfaceInvalidRect> TakeInvalidRect() override final;
|
||||
|
||||
bool GetClearValue(uint8_t& aValue) const override final
|
||||
{
|
||||
aValue = mClearValue;
|
||||
return mClearRequired;
|
||||
}
|
||||
|
||||
protected:
|
||||
void DoZeroOutRestOfSurface() override final;
|
||||
uint8_t* DoResetToFirstRow() override final;
|
||||
uint8_t* DoAdvanceRow() override final;
|
||||
virtual uint8_t* GetRowPointer() const = 0;
|
||||
|
||||
gfx::IntRect mInvalidRect; /// The region of the surface that has been written
|
||||
/// to since the last call to TakeInvalidRect().
|
||||
gfx::IntRect mWrittenRect; /// The region of the surface that has been written
|
||||
/// to at least once.
|
||||
uint8_t* mImageData; /// A pointer to the beginning of the surface data.
|
||||
uint32_t mImageDataLength; /// The length of the surface data.
|
||||
uint32_t mRow; /// The row to which we're writing. (0-indexed)
|
||||
bool mFlipVertically; /// If true, write the rows from top to bottom.
|
||||
bool mClearRequired; /// If true, pixels need to be cleared to given.
|
||||
uint8_t mClearValue; /// Value written to cleared pixels.
|
||||
};
|
||||
|
||||
class SurfaceSink;
|
||||
|
|
|
@ -994,36 +994,33 @@ nsBMPDecoder::ReadRLEDelta(const char* aData)
|
|||
MOZ_ASSERT(mMayHaveTransparency);
|
||||
mDoesHaveTransparency = true;
|
||||
|
||||
// Handle the XDelta. This clears to the end of the row, which
|
||||
// which is perfect if there's a Y delta and harmless if not.
|
||||
uint8_t xDelta = uint8_t(aData[0]);
|
||||
int32_t finalPos = std::min<int32_t>(mH.mWidth, mCurrentPos + xDelta);
|
||||
uint32_t* dst = RowBuffer();
|
||||
while (mCurrentPos < mH.mWidth) {
|
||||
SetPixel(dst, 0, 0, 0, 0);
|
||||
++mCurrentPos;
|
||||
if (mDownscaler) {
|
||||
// Clear the skipped pixels. (This clears to the end of the row,
|
||||
// which is perfect if there's a Y delta and harmless if not).
|
||||
mDownscaler->ClearRestOfRow(/* aStartingAtCol = */ mCurrentPos);
|
||||
}
|
||||
|
||||
// Handle the XDelta.
|
||||
mCurrentPos += uint8_t(aData[0]);
|
||||
if (mCurrentPos > mH.mWidth) {
|
||||
mCurrentPos = mH.mWidth;
|
||||
}
|
||||
|
||||
// Handle the Y Delta.
|
||||
int32_t yDelta = std::min<int32_t>(uint8_t(aData[1]), mCurrentRow);
|
||||
if (yDelta > 0) {
|
||||
mCurrentRow -= yDelta;
|
||||
|
||||
if (mDownscaler && yDelta > 0) {
|
||||
// Commit the current row (the first of the skipped rows).
|
||||
mCurrentPos = 0;
|
||||
FinishRow();
|
||||
mDownscaler->CommitRow();
|
||||
|
||||
// Clear and commit the remaining skipped rows.
|
||||
for (int32_t line = 1; line < yDelta; line++) {
|
||||
dst = RowBuffer();
|
||||
while (mCurrentPos < mH.mWidth) {
|
||||
SetPixel(dst, 0, 0, 0, 0);
|
||||
++mCurrentPos;
|
||||
}
|
||||
mCurrentPos = 0;
|
||||
FinishRow();
|
||||
mDownscaler->ClearRow();
|
||||
mDownscaler->CommitRow();
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentPos = finalPos;
|
||||
return mCurrentRow == 0
|
||||
? Transition::TerminateSuccess()
|
||||
: Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
|
||||
|
|
|
@ -105,7 +105,6 @@ nsresult
|
|||
nsGIFDecoder2::FinishInternal()
|
||||
{
|
||||
MOZ_ASSERT(!HasError(), "Shouldn't call FinishInternal after error!");
|
||||
mPipe.ZeroOutRestOfSurface();
|
||||
|
||||
// If the GIF got cut off, handle it anyway
|
||||
if (!IsMetadataDecode() && mGIFOpen) {
|
||||
|
@ -236,7 +235,6 @@ nsGIFDecoder2::BeginImageFrame(const IntRect& aFrameRect,
|
|||
void
|
||||
nsGIFDecoder2::EndImageFrame()
|
||||
{
|
||||
mPipe.ZeroOutRestOfSurface();
|
||||
Opacity opacity = Opacity::SOME_TRANSPARENCY;
|
||||
|
||||
if (mGIFStruct.images_decoded == 0) {
|
||||
|
|
|
@ -27,13 +27,6 @@ nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
|||
nsIconDecoder::~nsIconDecoder()
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
nsIconDecoder::FinishInternal()
|
||||
{
|
||||
mPipe.ZeroOutRestOfSurface();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LexerResult
|
||||
nsIconDecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
|
||||
{
|
||||
|
|
|
@ -37,10 +37,8 @@ class nsIconDecoder : public Decoder
|
|||
public:
|
||||
virtual ~nsIconDecoder();
|
||||
|
||||
protected:
|
||||
LexerResult DoDecode(SourceBufferIterator& aIterator,
|
||||
IResumable* aOnResume) override;
|
||||
nsresult FinishInternal() override;
|
||||
|
||||
private:
|
||||
friend class DecoderFactory;
|
||||
|
|
|
@ -169,51 +169,9 @@ nsJPEGDecoder::InitInternal()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsJPEGDecoder::ClearRemainingRows()
|
||||
{
|
||||
if (mDownscaler) {
|
||||
mDownscaler->ClearRemainingRows();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mImageData) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t offset = 0;
|
||||
switch (mState) {
|
||||
case JPEG_DECOMPRESS_PROGRESSIVE:
|
||||
// If we already made one progressive pass, then we know we have written
|
||||
// something valid to the output buffer.
|
||||
if (mInfo.output_scan_number > 0) {
|
||||
return;
|
||||
}
|
||||
MOZ_FALLTHROUGH;
|
||||
case JPEG_DECOMPRESS_SEQUENTIAL:
|
||||
case JPEG_HEADER:
|
||||
case JPEG_START_DECOMPRESS:
|
||||
offset = mInfo.output_scanline * mInfo.output_width * sizeof(uint32_t);
|
||||
if (offset < mImageDataLength) {
|
||||
break;
|
||||
}
|
||||
MOZ_FALLTHROUGH;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t length = mImageDataLength - offset;
|
||||
MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
|
||||
("nsJPEGDecoder::ClearRemainingRows: %p clear %u unset bytes",
|
||||
this, length));
|
||||
memset(mImageData + offset, 0xFF, length);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJPEGDecoder::FinishInternal()
|
||||
{
|
||||
ClearRemainingRows();
|
||||
|
||||
// If we're not in any sort of error case, force our state to JPEG_DONE.
|
||||
if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) &&
|
||||
(mState != JPEG_ERROR) &&
|
||||
|
|
|
@ -80,7 +80,6 @@ private:
|
|||
|
||||
LexerTransition<State> ReadJPEGData(const char* aData, size_t aLength);
|
||||
LexerTransition<State> FinishedJPEGData();
|
||||
void ClearRemainingRows();
|
||||
|
||||
StreamingLexer<State> mLexer;
|
||||
|
||||
|
|
|
@ -255,7 +255,6 @@ nsPNGDecoder::EndImageFrame()
|
|||
return;
|
||||
}
|
||||
|
||||
mPipe.ZeroOutRestOfSurface();
|
||||
mNumFrames++;
|
||||
|
||||
Opacity opacity = mFormat == SurfaceFormat::B8G8R8X8
|
||||
|
@ -361,13 +360,6 @@ nsPNGDecoder::InitInternal()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPNGDecoder::FinishInternal()
|
||||
{
|
||||
mPipe.ZeroOutRestOfSurface();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LexerResult
|
||||
nsPNGDecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,6 @@ protected:
|
|||
nsresult InitInternal() override;
|
||||
LexerResult DoDecode(SourceBufferIterator& aIterator,
|
||||
IResumable* aOnResume) override;
|
||||
nsresult FinishInternal() override;
|
||||
|
||||
Maybe<Telemetry::ID> SpeedHistogram() const override;
|
||||
|
||||
|
|
|
@ -254,6 +254,12 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize,
|
|||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!ClearSurface(mRawSurface, mFrameRect.Size(), mFormat)) {
|
||||
NS_WARNING("Could not clear allocated buffer");
|
||||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -652,13 +658,6 @@ imgFrame::GetImageData() const
|
|||
return data;
|
||||
}
|
||||
|
||||
bool
|
||||
imgFrame::OnHeap() const
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
return mRawSurface ? mRawSurface->OnHeap() : true;
|
||||
}
|
||||
|
||||
bool
|
||||
imgFrame::GetIsPaletted() const
|
||||
{
|
||||
|
|
|
@ -329,8 +329,6 @@ public:
|
|||
void GetImageData(uint8_t** aData, uint32_t* length) const;
|
||||
uint8_t* GetImageData() const;
|
||||
|
||||
bool OnHeap() const;
|
||||
|
||||
bool GetIsPaletted() const;
|
||||
void GetPaletteData(uint32_t** aPalette, uint32_t* length) const;
|
||||
uint32_t* GetPaletteData() const;
|
||||
|
|
|
@ -285,8 +285,7 @@ AssertCorrectPipelineFinalState(SurfaceFilter* aFilter,
|
|||
void
|
||||
CheckGeneratedImage(Decoder* aDecoder,
|
||||
const IntRect& aRect,
|
||||
uint8_t aFuzz /* = 0 */,
|
||||
bool aPartial /* = false */)
|
||||
uint8_t aFuzz /* = 0 */)
|
||||
{
|
||||
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
|
||||
RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
|
||||
|
@ -307,11 +306,6 @@ CheckGeneratedImage(Decoder* aDecoder,
|
|||
// Check that the output rect itself is green. (Region 'C'.)
|
||||
EXPECT_TRUE(RectIsSolidColor(surface, aRect, BGRAColor::Green(), aFuzz));
|
||||
|
||||
// We only assume everything is written if it is a complete image.
|
||||
if (aPartial) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that the area above the output rect is transparent. (Region 'A'.)
|
||||
EXPECT_TRUE(RectIsSolidColor(surface,
|
||||
IntRect(0, 0, surfaceSize.width, aRect.y),
|
||||
|
@ -336,7 +330,7 @@ CheckGeneratedImage(Decoder* aDecoder,
|
|||
}
|
||||
|
||||
void
|
||||
CheckGeneratedPalettedImage(Decoder* aDecoder, const IntRect& aRect, bool aPartial /* = false */)
|
||||
CheckGeneratedPalettedImage(Decoder* aDecoder, const IntRect& aRect)
|
||||
{
|
||||
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
|
||||
IntSize imageSize = currentFrame->GetImageSize();
|
||||
|
@ -356,10 +350,6 @@ CheckGeneratedPalettedImage(Decoder* aDecoder, const IntRect& aRect, bool aParti
|
|||
// Check that the output rect itself is all 255's. (Region 'C'.)
|
||||
EXPECT_TRUE(PalettedRectIsSolidColor(aDecoder, aRect, 255));
|
||||
|
||||
if (aPartial) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that the area above the output rect is all 0's. (Region 'A'.)
|
||||
EXPECT_TRUE(PalettedRectIsSolidColor(aDecoder,
|
||||
IntRect(0, 0, imageSize.width, aRect.y),
|
||||
|
@ -688,57 +678,5 @@ ImageTestCase TruncatedSmallGIFTestCase()
|
|||
return ImageTestCase("green-1x1-truncated.gif", "image/gif", IntSize(1, 1));
|
||||
}
|
||||
|
||||
ImageTestCase TruncatedJPGTestCase()
|
||||
{
|
||||
auto test = ImageTestCase("green.jpg", "image/jpeg", IntSize(100, 100),
|
||||
TEST_CASE_IS_TRANSPARENT | TEST_CASE_IS_FUZZY);
|
||||
test.Truncate(1, IntRect(0, 0, 100, 94));
|
||||
return test;
|
||||
}
|
||||
|
||||
ImageTestCase TruncatedPNGTestCase()
|
||||
{
|
||||
auto test = ImageTestCase("green.png", "image/png", IntSize(100, 100),
|
||||
TEST_CASE_IS_TRANSPARENT);
|
||||
test.Truncate(32, IntRect(0, 0, 100, 91));
|
||||
return test;
|
||||
}
|
||||
|
||||
ImageTestCase TruncatedGIFTestCase()
|
||||
{
|
||||
auto test = GreenGIFTestCase();
|
||||
test.Truncate(32, IntRect(0, 0, 100, 62),
|
||||
IntRect(0, 62, 16, 1));
|
||||
return test;
|
||||
}
|
||||
|
||||
ImageTestCase TruncatedIconTestCase()
|
||||
{
|
||||
auto test = GreenIconTestCase();
|
||||
test.Truncate(32, IntRect(0, 0, 100, 99));
|
||||
return test;
|
||||
}
|
||||
|
||||
ImageTestCase TruncatedBMPTestCase()
|
||||
{
|
||||
auto test = ImageTestCase("green.bmp", "image/bmp", IntSize(100, 100),
|
||||
TEST_CASE_HAS_TRUNCATED_COLOR);
|
||||
test.Truncate(32, IntRect(0, 1, 100, 99),
|
||||
IntRect(), BGRAColor::Black());
|
||||
return test;
|
||||
}
|
||||
|
||||
ImageTestCase TruncatedICOTestCase()
|
||||
{
|
||||
// This ICO contains a 32-bit BMP, and we use a BMP's alpha data by default
|
||||
// when the BMP is embedded in an ICO, so it's transparent.
|
||||
auto test = ImageTestCase("green.ico", "image/x-icon", IntSize(100, 100),
|
||||
TEST_CASE_IS_TRANSPARENT |
|
||||
TEST_CASE_HAS_TRUNCATED_COLOR);
|
||||
test.Truncate(2048, IntRect(0, 2, 100, 98),
|
||||
IntRect(), BGRAColor::Black());
|
||||
return test;
|
||||
}
|
||||
|
||||
} // namespace image
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -31,13 +31,44 @@ namespace image {
|
|||
|
||||
enum TestCaseFlags
|
||||
{
|
||||
TEST_CASE_DEFAULT_FLAGS = 0,
|
||||
TEST_CASE_IS_FUZZY = 1 << 0,
|
||||
TEST_CASE_HAS_ERROR = 1 << 1,
|
||||
TEST_CASE_IS_TRANSPARENT = 1 << 2,
|
||||
TEST_CASE_IS_ANIMATED = 1 << 3,
|
||||
TEST_CASE_IGNORE_OUTPUT = 1 << 4,
|
||||
TEST_CASE_HAS_TRUNCATED_COLOR = 1 << 5,
|
||||
TEST_CASE_DEFAULT_FLAGS = 0,
|
||||
TEST_CASE_IS_FUZZY = 1 << 0,
|
||||
TEST_CASE_HAS_ERROR = 1 << 1,
|
||||
TEST_CASE_IS_TRANSPARENT = 1 << 2,
|
||||
TEST_CASE_IS_ANIMATED = 1 << 3,
|
||||
TEST_CASE_IGNORE_OUTPUT = 1 << 4,
|
||||
};
|
||||
|
||||
struct ImageTestCase
|
||||
{
|
||||
ImageTestCase(const char* aPath,
|
||||
const char* aMimeType,
|
||||
gfx::IntSize aSize,
|
||||
uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
|
||||
: mPath(aPath)
|
||||
, mMimeType(aMimeType)
|
||||
, mSize(aSize)
|
||||
, mOutputSize(aSize)
|
||||
, mFlags(aFlags)
|
||||
{ }
|
||||
|
||||
ImageTestCase(const char* aPath,
|
||||
const char* aMimeType,
|
||||
gfx::IntSize aSize,
|
||||
gfx::IntSize aOutputSize,
|
||||
uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
|
||||
: mPath(aPath)
|
||||
, mMimeType(aMimeType)
|
||||
, mSize(aSize)
|
||||
, mOutputSize(aOutputSize)
|
||||
, mFlags(aFlags)
|
||||
{ }
|
||||
|
||||
const char* mPath;
|
||||
const char* mMimeType;
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntSize mOutputSize;
|
||||
uint32_t mFlags;
|
||||
};
|
||||
|
||||
struct BGRAColor
|
||||
|
@ -54,8 +85,6 @@ struct BGRAColor
|
|||
static BGRAColor Green() { return BGRAColor(0x00, 0xFF, 0x00, 0xFF); }
|
||||
static BGRAColor Red() { return BGRAColor(0x00, 0x00, 0xFF, 0xFF); }
|
||||
static BGRAColor Blue() { return BGRAColor(0xFF, 0x00, 0x00, 0xFF); }
|
||||
static BGRAColor White() { return BGRAColor(0xFF, 0xFF, 0xFF, 0xFF); }
|
||||
static BGRAColor Black() { return BGRAColor(0x00, 0x00, 0x00, 0xFF); }
|
||||
static BGRAColor Transparent() { return BGRAColor(0x00, 0x00, 0x00, 0x00); }
|
||||
|
||||
uint32_t AsPixel() const { return gfxPackedPixel(mAlpha, mRed, mGreen, mBlue); }
|
||||
|
@ -66,55 +95,6 @@ struct BGRAColor
|
|||
uint8_t mAlpha;
|
||||
};
|
||||
|
||||
struct ImageTestCase
|
||||
{
|
||||
ImageTestCase(const char* aPath,
|
||||
const char* aMimeType,
|
||||
gfx::IntSize aSize,
|
||||
uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
|
||||
: mPath(aPath)
|
||||
, mMimeType(aMimeType)
|
||||
, mSize(aSize)
|
||||
, mOutputSize(aSize)
|
||||
, mTruncatedBytes(0)
|
||||
, mFlags(aFlags)
|
||||
{ }
|
||||
|
||||
ImageTestCase(const char* aPath,
|
||||
const char* aMimeType,
|
||||
gfx::IntSize aSize,
|
||||
gfx::IntSize aOutputSize,
|
||||
uint32_t aFlags = TEST_CASE_DEFAULT_FLAGS)
|
||||
: mPath(aPath)
|
||||
, mMimeType(aMimeType)
|
||||
, mSize(aSize)
|
||||
, mOutputSize(aOutputSize)
|
||||
, mTruncatedBytes(0)
|
||||
, mFlags(aFlags)
|
||||
{ }
|
||||
|
||||
void Truncate(uint32_t aTruncatedBytes,
|
||||
gfx::IntRect aTruncatedRect,
|
||||
gfx::IntRect aTruncatedPartialRow = gfx::IntRect(),
|
||||
BGRAColor aTruncatedColor = BGRAColor::Transparent())
|
||||
{
|
||||
mTruncatedBytes = aTruncatedBytes;
|
||||
mTruncatedRect = aTruncatedRect;
|
||||
mTruncatedPartialRow = aTruncatedPartialRow;
|
||||
mTruncatedColor = aTruncatedColor;
|
||||
}
|
||||
|
||||
const char* mPath;
|
||||
const char* mMimeType;
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntSize mOutputSize;
|
||||
gfx::IntRect mTruncatedRect;
|
||||
gfx::IntRect mTruncatedPartialRow;
|
||||
BGRAColor mTruncatedColor;
|
||||
uint32_t mTruncatedBytes;
|
||||
uint32_t mFlags;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// General Helpers
|
||||
|
@ -326,13 +306,10 @@ void AssertCorrectPipelineFinalState(SurfaceFilter* aFilter,
|
|||
* this region are green, while pixels outside this region are
|
||||
* transparent.
|
||||
* @param aFuzz The amount of fuzz to use in pixel comparisons.
|
||||
* @param aPartial Whether or not to assume the transparent / incomplete regions
|
||||
* have been written to yet.
|
||||
*/
|
||||
void CheckGeneratedImage(Decoder* aDecoder,
|
||||
const gfx::IntRect& aRect,
|
||||
uint8_t aFuzz = 0,
|
||||
bool aPartial = false);
|
||||
uint8_t aFuzz = 0);
|
||||
|
||||
/**
|
||||
* Checks a generated paletted image for correctness. Reports any unexpected
|
||||
|
@ -344,12 +321,8 @@ void CheckGeneratedImage(Decoder* aDecoder,
|
|||
* pipeline will actually write to. It's expected that pixels in
|
||||
* this region have a palette index of 255, while pixels outside
|
||||
* this region have a palette index of 0.
|
||||
* @param aPartial Whether or not to assume the transparent / incomplete regions
|
||||
* have been written to yet.
|
||||
*/
|
||||
void CheckGeneratedPalettedImage(Decoder* aDecoder,
|
||||
const gfx::IntRect& aRect,
|
||||
bool aPartial = false);
|
||||
void CheckGeneratedPalettedImage(Decoder* aDecoder, const gfx::IntRect& aRect);
|
||||
|
||||
/**
|
||||
* Tests the result of calling WritePixels() using the provided SurfaceFilter
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -87,35 +85,8 @@ CheckDecoderResults(const ImageTestCase& aTestCase, Decoder* aDecoder)
|
|||
}
|
||||
|
||||
// Check the output.
|
||||
uint8_t fuzz = aTestCase.mFlags & TEST_CASE_IS_FUZZY ? 1 : 0;
|
||||
IntRect truncRect = aTestCase.mTruncatedRect;
|
||||
auto colored = BGRAColor::Green();
|
||||
if (truncRect.IsEmpty()) {
|
||||
EXPECT_TRUE(IsSolidColor(surface, colored, fuzz));
|
||||
} else {
|
||||
IntSize size = surface->GetSize();
|
||||
IntRect partialRow = aTestCase.mTruncatedPartialRow;
|
||||
auto cleared = BGRAColor::Transparent();
|
||||
if (aTestCase.mFlags & TEST_CASE_HAS_TRUNCATED_COLOR) {
|
||||
cleared = aTestCase.mTruncatedColor;
|
||||
} else if (surface->GetFormat() == SurfaceFormat::B8G8R8X8) {
|
||||
cleared = BGRAColor::White();
|
||||
}
|
||||
|
||||
EXPECT_TRUE(RowsAreSolidColor(surface, 0, truncRect.y, cleared, 0));
|
||||
EXPECT_TRUE(RowsAreSolidColor(surface, truncRect.y, truncRect.height,
|
||||
colored, fuzz));
|
||||
EXPECT_TRUE(RowsAreSolidColor(surface,
|
||||
truncRect.y + truncRect.height +
|
||||
partialRow.height,
|
||||
size.height, cleared, 0));
|
||||
if (!partialRow.IsEmpty()) {
|
||||
EXPECT_TRUE(RectIsSolidColor(surface, partialRow, colored, fuzz));
|
||||
partialRow.x += partialRow.width;
|
||||
partialRow.width = size.width - partialRow.x;
|
||||
EXPECT_TRUE(RectIsSolidColor(surface, partialRow, cleared, 0));
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green(),
|
||||
aTestCase.mFlags & TEST_CASE_IS_FUZZY ? 1 : 0));
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
|
@ -131,8 +102,6 @@ void WithSingleChunkDecode(const ImageTestCase& aTestCase,
|
|||
nsresult rv = inputStream->Available(&length);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
length -= aTestCase.mTruncatedBytes;
|
||||
|
||||
// Write the data into a SourceBuffer.
|
||||
NotNull<RefPtr<SourceBuffer>> sourceBuffer = WrapNotNull(new SourceBuffer());
|
||||
sourceBuffer->ExpectLength(length);
|
||||
|
@ -255,11 +224,6 @@ TEST_F(ImageDecoders, PNGDownscaleDuringDecode)
|
|||
CheckDownscaleDuringDecode(DownscaledPNGTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, PNGTruncated)
|
||||
{
|
||||
CheckDecoderSingleChunk(TruncatedPNGTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, GIFSingleChunk)
|
||||
{
|
||||
CheckDecoderSingleChunk(GreenGIFTestCase());
|
||||
|
@ -275,11 +239,6 @@ TEST_F(ImageDecoders, GIFDownscaleDuringDecode)
|
|||
CheckDownscaleDuringDecode(DownscaledGIFTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, GIFTruncated)
|
||||
{
|
||||
CheckDecoderSingleChunk(TruncatedGIFTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, JPGSingleChunk)
|
||||
{
|
||||
CheckDecoderSingleChunk(GreenJPGTestCase());
|
||||
|
@ -290,11 +249,6 @@ TEST_F(ImageDecoders, JPGMultiChunk)
|
|||
CheckDecoderMultiChunk(GreenJPGTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, JPGTruncated)
|
||||
{
|
||||
CheckDecoderSingleChunk(TruncatedJPGTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, JPGDownscaleDuringDecode)
|
||||
{
|
||||
CheckDownscaleDuringDecode(DownscaledJPGTestCase());
|
||||
|
@ -315,11 +269,6 @@ TEST_F(ImageDecoders, BMPDownscaleDuringDecode)
|
|||
CheckDownscaleDuringDecode(DownscaledBMPTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, BMPTruncated)
|
||||
{
|
||||
CheckDecoderSingleChunk(TruncatedBMPTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, ICOSingleChunk)
|
||||
{
|
||||
CheckDecoderSingleChunk(GreenICOTestCase());
|
||||
|
@ -340,11 +289,6 @@ TEST_F(ImageDecoders, ICOWithANDMaskDownscaleDuringDecode)
|
|||
CheckDownscaleDuringDecode(DownscaledTransparentICOWithANDMaskTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, ICOTruncated)
|
||||
{
|
||||
CheckDecoderSingleChunk(TruncatedICOTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, IconSingleChunk)
|
||||
{
|
||||
CheckDecoderSingleChunk(GreenIconTestCase());
|
||||
|
@ -360,11 +304,6 @@ TEST_F(ImageDecoders, IconDownscaleDuringDecode)
|
|||
CheckDownscaleDuringDecode(DownscaledIconTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, IconTruncated)
|
||||
{
|
||||
CheckDecoderSingleChunk(TruncatedIconTestCase());
|
||||
}
|
||||
|
||||
TEST_F(ImageDecoders, AnimatedGIFSingleChunk)
|
||||
{
|
||||
CheckDecoderSingleChunk(GreenFirstFrameAnimatedGIFTestCase());
|
||||
|
|
|
@ -85,8 +85,7 @@ template <typename WriteFunc> void
|
|||
CheckIterativeWrite(Decoder* aDecoder,
|
||||
SurfaceSink* aSink,
|
||||
const IntRect& aOutputRect,
|
||||
WriteFunc aWriteFunc,
|
||||
bool aPartial = false)
|
||||
WriteFunc aWriteFunc)
|
||||
{
|
||||
// Ignore the row passed to WriteFunc, since no callers use it.
|
||||
auto writeFunc = [&](uint32_t) {
|
||||
|
@ -94,7 +93,7 @@ CheckIterativeWrite(Decoder* aDecoder,
|
|||
};
|
||||
|
||||
DoCheckIterativeWrite(aSink, writeFunc, [&]{
|
||||
CheckGeneratedImage(aDecoder, aOutputRect, 0, aPartial);
|
||||
CheckGeneratedImage(aDecoder, aOutputRect);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -192,7 +191,6 @@ TEST(ImageSurfaceSink, SurfaceSinkInitialization)
|
|||
// anyway (i.e., we wrote to the empty rect); it will then expect the entire
|
||||
// surface to be transparent, which is what it should be if it was
|
||||
// zero-initialied.
|
||||
aSink->ZeroOutRestOfSurface();
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 0, 0));
|
||||
});
|
||||
}
|
||||
|
@ -255,7 +253,7 @@ TEST(ImageSurfaceSink, SurfaceSinkWritePixelsEarlyExit)
|
|||
|
||||
EXPECT_EQ(aState, result);
|
||||
EXPECT_EQ(50u, count);
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1), 0, true);
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1));
|
||||
|
||||
if (aState != WriteState::FINISHED) {
|
||||
// We should still be able to write more at this point.
|
||||
|
@ -274,7 +272,7 @@ TEST(ImageSurfaceSink, SurfaceSinkWritePixelsEarlyExit)
|
|||
EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
|
||||
EXPECT_EQ(50u, count);
|
||||
EXPECT_FALSE(aSink->IsSurfaceFinished());
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 1), 0, true);
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 1));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -334,7 +332,7 @@ TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRow)
|
|||
EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mInputSpaceRect);
|
||||
EXPECT_EQ(IntRect(0, row, 100, 1), invalidRect->mOutputSpaceRect);
|
||||
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, row + 1), 0, true);
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, row + 1));
|
||||
}
|
||||
|
||||
// Write the final line, which should finish the surface.
|
||||
|
@ -390,7 +388,7 @@ TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRowEarlyExit)
|
|||
|
||||
EXPECT_EQ(aState, result);
|
||||
EXPECT_EQ(50u, count);
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1), 0, true);
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 50, 1));
|
||||
|
||||
if (aState != WriteState::FINISHED) {
|
||||
// We should still be able to write more at this point.
|
||||
|
@ -406,7 +404,7 @@ TEST(ImageSurfaceSink, SurfaceSinkWritePixelsToRowEarlyExit)
|
|||
EXPECT_EQ(WriteState::NEED_MORE_DATA, result);
|
||||
EXPECT_EQ(50u, count);
|
||||
EXPECT_FALSE(aSink->IsSurfaceFinished());
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 1), 0, true);
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 100, 1));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -570,7 +568,6 @@ TEST(ImageSurfaceSink, SurfaceSinkWriteBufferFromNullSource)
|
|||
EXPECT_TRUE(invalidRect.isNothing());
|
||||
|
||||
// Check that nothing got written to the surface.
|
||||
aSink->ZeroOutRestOfSurface();
|
||||
CheckGeneratedImage(aDecoder, IntRect(0, 0, 0, 0));
|
||||
});
|
||||
}
|
||||
|
@ -666,7 +663,7 @@ TEST(ImageSurfaceSink, SurfaceSinkWriteUnsafeComputedRow)
|
|||
EXPECT_EQ(100u, aLength );
|
||||
memcpy(aRow + 50, buffer, 50 * sizeof(uint32_t));
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче