зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1207378 (Part 1) - Add support for a frame rect to Downscaler. r=tn
This commit is contained in:
Родитель
2648aa6251
Коммит
ba99adc235
|
@ -57,6 +57,7 @@ Downscaler::ReleaseWindow()
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||||
|
const Maybe<nsIntRect>& aFrameRect,
|
||||||
uint8_t* aOutputBuffer,
|
uint8_t* aOutputBuffer,
|
||||||
bool aHasAlpha,
|
bool aHasAlpha,
|
||||||
bool aFlipVertically /* = false */)
|
bool aFlipVertically /* = false */)
|
||||||
|
@ -71,6 +72,17 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||||
MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0,
|
MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0,
|
||||||
"Invalid original size");
|
"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;
|
mOriginalSize = aOriginalSize;
|
||||||
mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width,
|
mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width,
|
||||||
double(mOriginalSize.height) / mTargetSize.height);
|
double(mOriginalSize.height) / mTargetSize.height);
|
||||||
|
@ -78,7 +90,6 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||||
mHasAlpha = aHasAlpha;
|
mHasAlpha = aHasAlpha;
|
||||||
mFlipVertically = aFlipVertically;
|
mFlipVertically = aFlipVertically;
|
||||||
|
|
||||||
ResetForNextProgressivePass();
|
|
||||||
ReleaseWindow();
|
ReleaseWindow();
|
||||||
|
|
||||||
auto resizeMethod = skia::ImageOperations::RESIZE_LANCZOS3;
|
auto resizeMethod = skia::ImageOperations::RESIZE_LANCZOS3;
|
||||||
|
@ -124,9 +135,22 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResetForNextProgressivePass();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Downscaler::SkipToRow(int32_t aRow)
|
||||||
|
{
|
||||||
|
if (mCurrentInLine < aRow) {
|
||||||
|
ClearRow();
|
||||||
|
do {
|
||||||
|
CommitRow();
|
||||||
|
} while (mCurrentInLine < aRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Downscaler::ResetForNextProgressivePass()
|
Downscaler::ResetForNextProgressivePass()
|
||||||
{
|
{
|
||||||
|
@ -134,6 +158,9 @@ Downscaler::ResetForNextProgressivePass()
|
||||||
mCurrentOutLine = 0;
|
mCurrentOutLine = 0;
|
||||||
mCurrentInLine = 0;
|
mCurrentInLine = 0;
|
||||||
mLinesInBuffer = 0;
|
mLinesInBuffer = 0;
|
||||||
|
|
||||||
|
// If we have a vertical offset, commit rows to shift us past it.
|
||||||
|
SkipToRow(mFrameRect.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -193,6 +220,12 @@ Downscaler::CommitRow()
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentInLine += 1;
|
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
|
bool
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
#ifndef mozilla_image_Downscaler_h
|
#ifndef mozilla_image_Downscaler_h
|
||||||
#define mozilla_image_Downscaler_h
|
#define mozilla_image_Downscaler_h
|
||||||
|
|
||||||
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
|
|
||||||
|
|
||||||
namespace skia {
|
namespace skia {
|
||||||
class ConvolutionFilter1D;
|
class ConvolutionFilter1D;
|
||||||
} // namespace skia
|
} // namespace skia
|
||||||
|
@ -64,6 +64,9 @@ public:
|
||||||
* Begins a new frame and reinitializes the Downscaler.
|
* Begins a new frame and reinitializes the Downscaler.
|
||||||
*
|
*
|
||||||
* @param aOriginalSize The original size of this frame, before scaling.
|
* @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
|
* @param aOutputBuffer The buffer to which the Downscaler should write its
|
||||||
* output; this is the same buffer where the Decoder
|
* output; this is the same buffer where the Decoder
|
||||||
* would write its output when not downscaling during
|
* would write its output when not downscaling during
|
||||||
|
@ -75,12 +78,16 @@ public:
|
||||||
* the way they are stored in some image formats.
|
* the way they are stored in some image formats.
|
||||||
*/
|
*/
|
||||||
nsresult BeginFrame(const nsIntSize& aOriginalSize,
|
nsresult BeginFrame(const nsIntSize& aOriginalSize,
|
||||||
|
const Maybe<nsIntRect>& aFrameRect,
|
||||||
uint8_t* aOutputBuffer,
|
uint8_t* aOutputBuffer,
|
||||||
bool aHasAlpha,
|
bool aHasAlpha,
|
||||||
bool aFlipVertically = false);
|
bool aFlipVertically = false);
|
||||||
|
|
||||||
/// Retrieves the buffer into which the Decoder should write each row.
|
/// 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).
|
/// Clears the current row buffer (optionally starting at @aStartingAtCol).
|
||||||
void ClearRow(uint32_t aStartingAtCol = 0);
|
void ClearRow(uint32_t aStartingAtCol = 0);
|
||||||
|
@ -104,9 +111,11 @@ public:
|
||||||
private:
|
private:
|
||||||
void DownscaleInputLine();
|
void DownscaleInputLine();
|
||||||
void ReleaseWindow();
|
void ReleaseWindow();
|
||||||
|
void SkipToRow(int32_t aRow);
|
||||||
|
|
||||||
nsIntSize mOriginalSize;
|
nsIntSize mOriginalSize;
|
||||||
nsIntSize mTargetSize;
|
nsIntSize mTargetSize;
|
||||||
|
nsIntRect mFrameRect;
|
||||||
gfxSize mScale;
|
gfxSize mScale;
|
||||||
|
|
||||||
uint8_t* mOutputBuffer;
|
uint8_t* mOutputBuffer;
|
||||||
|
|
|
@ -461,7 +461,8 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||||
if (mDownscaler) {
|
if (mDownscaler) {
|
||||||
// BMPs store their rows in reverse order, so the downscaler needs to
|
// BMPs store their rows in reverse order, so the downscaler needs to
|
||||||
// reverse them again when writing its output.
|
// reverse them again when writing its output.
|
||||||
rv = mDownscaler->BeginFrame(GetSize(), mImageData, hasTransparency,
|
rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
||||||
|
mImageData, hasTransparency,
|
||||||
/* aFlipVertically = */ true);
|
/* aFlipVertically = */ true);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -279,7 +279,7 @@ nsGIFDecoder2::BeginImageFrame(uint16_t aDepth)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDownscaler) {
|
if (mDownscaler) {
|
||||||
rv = mDownscaler->BeginFrame(frameRect.Size(), mImageData,
|
rv = mDownscaler->BeginFrame(frameRect.Size(), Nothing(), mImageData,
|
||||||
mGIFStruct.is_transparent);
|
mGIFStruct.is_transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -553,7 +553,7 @@ nsICODecoder::PrepareForMask()
|
||||||
mDownscaler->TargetSize().height *
|
mDownscaler->TargetSize().height *
|
||||||
sizeof(uint32_t));
|
sizeof(uint32_t));
|
||||||
mMaskBuffer = MakeUnique<uint8_t[]>(bmpDecoder->GetImageDataLength());
|
mMaskBuffer = MakeUnique<uint8_t[]>(bmpDecoder->GetImageDataLength());
|
||||||
nsresult rv = mDownscaler->BeginFrame(GetRealSize(),
|
nsresult rv = mDownscaler->BeginFrame(GetRealSize(), Nothing(),
|
||||||
mMaskBuffer.get(),
|
mMaskBuffer.get(),
|
||||||
/* aHasAlpha = */ true,
|
/* aHasAlpha = */ true,
|
||||||
/* aFlipVertically = */ true);
|
/* aFlipVertically = */ true);
|
||||||
|
|
|
@ -93,7 +93,7 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||||
|
|
||||||
if (mDownscaler) {
|
if (mDownscaler) {
|
||||||
nsresult rv = mDownscaler->BeginFrame(GetSize(),
|
nsresult rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
||||||
mImageData,
|
mImageData,
|
||||||
/* aHasAlpha = */ true);
|
/* aHasAlpha = */ true);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
|
@ -398,7 +398,7 @@ nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||||
|
|
||||||
if (mDownscaler) {
|
if (mDownscaler) {
|
||||||
nsresult rv = mDownscaler->BeginFrame(GetSize(),
|
nsresult rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
||||||
mImageData,
|
mImageData,
|
||||||
/* aHasAlpha = */ false);
|
/* aHasAlpha = */ false);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|
|
@ -209,7 +209,8 @@ nsPNGDecoder::CreateFrame(png_uint_32 aXOffset, png_uint_32 aYOffset,
|
||||||
|
|
||||||
if (mDownscaler) {
|
if (mDownscaler) {
|
||||||
bool hasAlpha = aFormat != SurfaceFormat::B8G8R8X8;
|
bool hasAlpha = aFormat != SurfaceFormat::B8G8R8X8;
|
||||||
rv = mDownscaler->BeginFrame(frameRect.Size(), mImageData, hasAlpha);
|
rv = mDownscaler->BeginFrame(frameRect.Size(), Nothing(),
|
||||||
|
mImageData, hasAlpha);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче