mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-06 22:29:34 +00:00
#501: functional decoder wrapper
This commit is contained in:
parent
ac0300a558
commit
3396881353
195
image/decoders/nsWEBPDecoder.cpp
Normal file
195
image/decoders/nsWEBPDecoder.cpp
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=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/. */
|
||||||
|
/* Contributor(s):
|
||||||
|
* Vikas Arora <vikasa@google.com> */
|
||||||
|
|
||||||
|
#include "nsWEBPDecoder.h"
|
||||||
|
|
||||||
|
#include "ImageLogging.h"
|
||||||
|
#include "gfxColor.h"
|
||||||
|
#include "gfxPlatform.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace image {
|
||||||
|
|
||||||
|
#if defined(PR_LOGGING)
|
||||||
|
static PRLogModuleInfo* gWEBPDecoderAccountingLog =
|
||||||
|
PR_NewLogModule("WEBPDecoderAccounting");
|
||||||
|
#else
|
||||||
|
#define gWEBPDecoderAccountingLog
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsWEBPDecoder::nsWEBPDecoder(RasterImage* aImage)
|
||||||
|
: Decoder(aImage)
|
||||||
|
, mDecoder(nullptr)
|
||||||
|
, mLastLine(0)
|
||||||
|
, mWidth(0)
|
||||||
|
, mHeight(0)
|
||||||
|
, haveSize(false)
|
||||||
|
{
|
||||||
|
MOZ_LOG(gWEBPDecoderAccountingLog, LogLevel::Debug,
|
||||||
|
("nsWEBPDecoder::nsWEBPDecoder: Creating WEBP decoder %p",
|
||||||
|
this));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsWEBPDecoder::~nsWEBPDecoder()
|
||||||
|
{
|
||||||
|
MOZ_LOG(gWEBPDecoderAccountingLog, LogLevel::Debug,
|
||||||
|
("nsWEBPDecoder::~nsWEBPDecoder: Destroying WEBP decoder %p",
|
||||||
|
this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWEBPDecoder::InitInternal()
|
||||||
|
{
|
||||||
|
if (!WebPInitDecBuffer(&mDecBuf)) {
|
||||||
|
PostDecoderError(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsMetadataDecode()) {
|
||||||
|
return; // don't need a decoder yet
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(!mImageData, "Shouldn't have a buffer yet");
|
||||||
|
|
||||||
|
mDecBuf.colorspace = MODE_bgrA;
|
||||||
|
mDecBuf.is_external_memory = 1;
|
||||||
|
mDecBuf.u.RGBA.rgba = mImageData; // nullptr right now
|
||||||
|
mDecoder = WebPINewDecoder(&mDecBuf);
|
||||||
|
if (!mDecoder) {
|
||||||
|
PostDecoderError(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWEBPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||||
|
{
|
||||||
|
const uint8_t* buf = (const uint8_t*)aBuffer;
|
||||||
|
|
||||||
|
if (IsMetadataDecode() || !haveSize) {
|
||||||
|
WebPBitstreamFeatures features;
|
||||||
|
const VP8StatusCode rv = WebPGetFeatures(buf, aCount, &features);
|
||||||
|
|
||||||
|
if (rv == VP8_STATUS_OK) {
|
||||||
|
if (features.has_animation) {
|
||||||
|
PostDecoderError(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (features.has_alpha) {
|
||||||
|
PostHasTransparency();
|
||||||
|
}
|
||||||
|
// Post our size to the superclass
|
||||||
|
if (IsMetadataDecode()) {
|
||||||
|
PostSize(features.width, features.height);
|
||||||
|
}
|
||||||
|
mWidth = features.width;
|
||||||
|
mHeight = features.height;
|
||||||
|
mDecBuf.width = mWidth;
|
||||||
|
mDecBuf.height = mHeight;
|
||||||
|
mDecBuf.u.RGBA.stride = mWidth * sizeof(uint32_t);
|
||||||
|
mDecBuf.u.RGBA.size = mDecBuf.u.RGBA.stride * mHeight;
|
||||||
|
haveSize = true;
|
||||||
|
} else if (rv != VP8_STATUS_NOT_ENOUGH_DATA) {
|
||||||
|
PostDecoderError(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
#if DEBUG
|
||||||
|
fprintf(stderr, "WebP had unexpected return code: %d\n", rv);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're doing a size decode, we're done.
|
||||||
|
if (IsMetadataDecode()) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
|
||||||
|
MOZ_ASSERT(haveSize, "Didn't fetch metadata?");
|
||||||
|
PostSize(mWidth, mHeight);
|
||||||
|
nsresult rv_ = AllocateBasicFrame();
|
||||||
|
if (NS_FAILED(rv_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||||
|
MOZ_ASSERT(mDecoder, "Should have a decoder now");
|
||||||
|
mDecBuf.u.RGBA.rgba = mImageData; // no longer null
|
||||||
|
const VP8StatusCode rv = WebPIAppend(mDecoder, buf, aCount);
|
||||||
|
|
||||||
|
if (rv == VP8_STATUS_OUT_OF_MEMORY) {
|
||||||
|
PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return;
|
||||||
|
} else if (rv == VP8_STATUS_INVALID_PARAM ||
|
||||||
|
rv == VP8_STATUS_BITSTREAM_ERROR) {
|
||||||
|
PostDataError();
|
||||||
|
return;
|
||||||
|
} else if (rv == VP8_STATUS_UNSUPPORTED_FEATURE ||
|
||||||
|
rv == VP8_STATUS_USER_ABORT) {
|
||||||
|
PostDecoderError(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catch any remaining erroneous return value.
|
||||||
|
if (rv != VP8_STATUS_OK && rv != VP8_STATUS_SUSPENDED) {
|
||||||
|
PostDecoderError(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastLineRead = -1;
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
int stride = 0;
|
||||||
|
|
||||||
|
const uint8_t* data =
|
||||||
|
WebPIDecGetRGB(mDecoder, &lastLineRead, &width, &height, &stride);
|
||||||
|
|
||||||
|
// WebP encoded image data hasn't been read yet, return.
|
||||||
|
if (lastLineRead == -1 || !data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure valid image height & width.
|
||||||
|
if (width <= 0 || height <= 0) {
|
||||||
|
PostDataError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mImageData) {
|
||||||
|
PostDecoderError(NS_ERROR_FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastLineRead > mLastLine) {
|
||||||
|
// Invalidate
|
||||||
|
nsIntRect r(0, mLastLine, width, lastLineRead - mLastLine);
|
||||||
|
PostInvalidation(r);
|
||||||
|
mLastLine = lastLineRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsWEBPDecoder::FinishInternal()
|
||||||
|
{
|
||||||
|
// We should never make multiple frames
|
||||||
|
MOZ_ASSERT(GetFrameCount() <= 1, "Multiple WebP frames?");
|
||||||
|
|
||||||
|
// Send notifications if appropriate
|
||||||
|
if (!IsMetadataDecode() && (GetFrameCount() == 1)) {
|
||||||
|
// Flush the decoder
|
||||||
|
WebPIDelete(mDecoder);
|
||||||
|
WebPFreeDecBuffer(&mDecBuf);
|
||||||
|
|
||||||
|
PostFrameStop();
|
||||||
|
PostDecodeDone();
|
||||||
|
|
||||||
|
mDecoder = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace image
|
||||||
|
} // namespace mozilla
|
78
image/decoders/nsWEBPDecoder.h
Normal file
78
image/decoders/nsWEBPDecoder.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
*
|
||||||
|
* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Vikas Arora <vikasa@google.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef nsWEBPDecoder_h
|
||||||
|
#define nsWEBPDecoder_h
|
||||||
|
|
||||||
|
#include "Decoder.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "webp/decode.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace image {
|
||||||
|
class RasterImage;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// nsWEBPDecoder Definition
|
||||||
|
|
||||||
|
class nsWEBPDecoder : public Decoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit nsWEBPDecoder(RasterImage* aImage);
|
||||||
|
virtual ~nsWEBPDecoder();
|
||||||
|
|
||||||
|
virtual void InitInternal() override;
|
||||||
|
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override;
|
||||||
|
virtual void FinishInternal() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
WebPIDecoder* mDecoder; // Pointer to Incremental WebP Decoder.
|
||||||
|
WebPDecBuffer mDecBuf; // Decoder buffer for output RGBA data.
|
||||||
|
int mLastLine; // Last image scan-line read so far.
|
||||||
|
int mWidth; // Image Width
|
||||||
|
int mHeight; // Image Height
|
||||||
|
bool haveSize; // True if mDecBuf contains image dimension
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace image
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // nsWEBPDecoder_h
|
Loading…
Reference in New Issue
Block a user