mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1207378 (Part 1) - Add support for a frame rect to Downscaler. r=tn
This commit is contained in:
parent
2648aa6251
commit
ba99adc235
@ -57,6 +57,7 @@ Downscaler::ReleaseWindow()
|
||||
|
||||
nsresult
|
||||
Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||
const Maybe<nsIntRect>& aFrameRect,
|
||||
uint8_t* aOutputBuffer,
|
||||
bool aHasAlpha,
|
||||
bool aFlipVertically /* = false */)
|
||||
@ -71,6 +72,17 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||
MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0,
|
||||
"Invalid original size");
|
||||
|
||||
mFrameRect = aFrameRect.valueOr(nsIntRect(nsIntPoint(), aOriginalSize));
|
||||
MOZ_ASSERT(mFrameRect.x >= 0 && mFrameRect.y >= 0 &&
|
||||
mFrameRect.width > 0 && mFrameRect.height > 0,
|
||||
"Frame rect must have positive components");
|
||||
MOZ_ASSERT(nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
|
||||
.Contains(mFrameRect),
|
||||
"Frame rect must fit inside image");
|
||||
MOZ_ASSERT_IF(!nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
|
||||
.IsEqualEdges(mFrameRect),
|
||||
aHasAlpha);
|
||||
|
||||
mOriginalSize = aOriginalSize;
|
||||
mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width,
|
||||
double(mOriginalSize.height) / mTargetSize.height);
|
||||
@ -78,7 +90,6 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||
mHasAlpha = aHasAlpha;
|
||||
mFlipVertically = aFlipVertically;
|
||||
|
||||
ResetForNextProgressivePass();
|
||||
ReleaseWindow();
|
||||
|
||||
auto resizeMethod = skia::ImageOperations::RESIZE_LANCZOS3;
|
||||
@ -124,9 +135,22 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
ResetForNextProgressivePass();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Downscaler::SkipToRow(int32_t aRow)
|
||||
{
|
||||
if (mCurrentInLine < aRow) {
|
||||
ClearRow();
|
||||
do {
|
||||
CommitRow();
|
||||
} while (mCurrentInLine < aRow);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Downscaler::ResetForNextProgressivePass()
|
||||
{
|
||||
@ -134,6 +158,9 @@ Downscaler::ResetForNextProgressivePass()
|
||||
mCurrentOutLine = 0;
|
||||
mCurrentInLine = 0;
|
||||
mLinesInBuffer = 0;
|
||||
|
||||
// If we have a vertical offset, commit rows to shift us past it.
|
||||
SkipToRow(mFrameRect.y);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -193,6 +220,12 @@ Downscaler::CommitRow()
|
||||
}
|
||||
|
||||
mCurrentInLine += 1;
|
||||
|
||||
// If we're at the end of the part of the original image that has data, commit
|
||||
// rows to shift us to the end.
|
||||
if (mCurrentInLine == (mFrameRect.y + mFrameRect.height)) {
|
||||
SkipToRow(mOriginalSize.height - 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -12,10 +12,10 @@
|
||||
#ifndef mozilla_image_Downscaler_h
|
||||
#define mozilla_image_Downscaler_h
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
|
||||
namespace skia {
|
||||
class ConvolutionFilter1D;
|
||||
} // namespace skia
|
||||
@ -64,6 +64,9 @@ public:
|
||||
* Begins a new frame and reinitializes the Downscaler.
|
||||
*
|
||||
* @param aOriginalSize The original size of this frame, before scaling.
|
||||
* @param aFrameRect The region of the original image which has data.
|
||||
* Every pixel outside @aFrameRect is considered blank and
|
||||
* has zero alpha.
|
||||
* @param aOutputBuffer The buffer to which the Downscaler should write its
|
||||
* output; this is the same buffer where the Decoder
|
||||
* would write its output when not downscaling during
|
||||
@ -75,12 +78,16 @@ public:
|
||||
* the way they are stored in some image formats.
|
||||
*/
|
||||
nsresult BeginFrame(const nsIntSize& aOriginalSize,
|
||||
const Maybe<nsIntRect>& aFrameRect,
|
||||
uint8_t* aOutputBuffer,
|
||||
bool aHasAlpha,
|
||||
bool aFlipVertically = false);
|
||||
|
||||
/// Retrieves the buffer into which the Decoder should write each row.
|
||||
uint8_t* RowBuffer() { return mRowBuffer.get(); }
|
||||
uint8_t* RowBuffer()
|
||||
{
|
||||
return mRowBuffer.get() + mFrameRect.x * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/// Clears the current row buffer (optionally starting at @aStartingAtCol).
|
||||
void ClearRow(uint32_t aStartingAtCol = 0);
|
||||
@ -104,9 +111,11 @@ public:
|
||||
private:
|
||||
void DownscaleInputLine();
|
||||
void ReleaseWindow();
|
||||
void SkipToRow(int32_t aRow);
|
||||
|
||||
nsIntSize mOriginalSize;
|
||||
nsIntSize mTargetSize;
|
||||
nsIntRect mFrameRect;
|
||||
gfxSize mScale;
|
||||
|
||||
uint8_t* mOutputBuffer;
|
||||
|
@ -461,7 +461,8 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
if (mDownscaler) {
|
||||
// BMPs store their rows in reverse order, so the downscaler needs to
|
||||
// reverse them again when writing its output.
|
||||
rv = mDownscaler->BeginFrame(GetSize(), mImageData, hasTransparency,
|
||||
rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
||||
mImageData, hasTransparency,
|
||||
/* aFlipVertically = */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
|
@ -279,7 +279,7 @@ nsGIFDecoder2::BeginImageFrame(uint16_t aDepth)
|
||||
}
|
||||
|
||||
if (mDownscaler) {
|
||||
rv = mDownscaler->BeginFrame(frameRect.Size(), mImageData,
|
||||
rv = mDownscaler->BeginFrame(frameRect.Size(), Nothing(), mImageData,
|
||||
mGIFStruct.is_transparent);
|
||||
}
|
||||
|
||||
|
@ -553,7 +553,7 @@ nsICODecoder::PrepareForMask()
|
||||
mDownscaler->TargetSize().height *
|
||||
sizeof(uint32_t));
|
||||
mMaskBuffer = MakeUnique<uint8_t[]>(bmpDecoder->GetImageDataLength());
|
||||
nsresult rv = mDownscaler->BeginFrame(GetRealSize(),
|
||||
nsresult rv = mDownscaler->BeginFrame(GetRealSize(), Nothing(),
|
||||
mMaskBuffer.get(),
|
||||
/* aHasAlpha = */ true,
|
||||
/* aFlipVertically = */ true);
|
||||
|
@ -93,7 +93,7 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||
|
||||
if (mDownscaler) {
|
||||
nsresult rv = mDownscaler->BeginFrame(GetSize(),
|
||||
nsresult rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
||||
mImageData,
|
||||
/* aHasAlpha = */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -398,7 +398,7 @@ nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||
|
||||
if (mDownscaler) {
|
||||
nsresult rv = mDownscaler->BeginFrame(GetSize(),
|
||||
nsresult rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
||||
mImageData,
|
||||
/* aHasAlpha = */ false);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -209,7 +209,8 @@ nsPNGDecoder::CreateFrame(png_uint_32 aXOffset, png_uint_32 aYOffset,
|
||||
|
||||
if (mDownscaler) {
|
||||
bool hasAlpha = aFormat != SurfaceFormat::B8G8R8X8;
|
||||
rv = mDownscaler->BeginFrame(frameRect.Size(), mImageData, hasAlpha);
|
||||
rv = mDownscaler->BeginFrame(frameRect.Size(), Nothing(),
|
||||
mImageData, hasAlpha);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user