mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
13934d9866
- Bug 1184996 (Part 1) - Create decoders with a DecoderFactory. r=tn (dacf21ed2) - Bug 1184996 (Part 2) - Clean up RasterImage's decoding API. r=tn (c127af0b3) - Bug 1184996 (Part 3) - Replace all remaining references to 'size decodes' with 'metadata decodes'. r=tn (3744e5df4) - Bug 1184996 (Part 4) - Forbid instantiation of decoders except via DecoderFactory. r=tn (588d56d84) - No bug - Remove extra printf left over from bug 1127618. r=smaug (b02f7bfe1) - Bug 1187386 (Part 1) - Make most decoder state private. r=tn (328dbc605) - Bug 1187386 (Part 2) - Rework decoder code to avoid calling Decode::GetImage(). r=tn (9a94096f9) - Bug 1187386 (Part 3) - Don't destroy Decoder::mImage if Decoder::mImage is null. r=tn (cbb6738cd) - Bug 1187386 (Part 4) - Make imgFrame::SetOptimizable() callable from off-main-thread. r=tn (f03478b28) - Bug 1187386 (Part 5) - Merge Decoder::SetSizeOnImage() into ImageMetadata::SetOnImage(). r=tn (8afb5d4a3) - Bug 1033090 - Truncate a large URI in the user message about it. r=seth (7bd4b447b) - Bug 1187386 (Part 6) - Merge Decoder::Finish() and RasterImage::OnDecodingComplete() into RasterImage::FinalizeDecoder(). r=tn (f342dd5db) - Bug 1181863 (Part 1) - Add support for reading from nsIInputStreams directly to SourceBuffer. r=tn (74748dad9) - Bug 1181863 (Part 2) - Add ImageOps::DecodeToSurface() to allow image decoding without involving any main-thread-only objects. r=tn (25b86eb50) - Bug 1181863 (Part 3) - Add tests for DecodeToSurface(). r=tn (9506eb2f6) - Bug 1181863 - Part 4: Fix the build bustage (aee05bdc9) - Bug 1187546 - Make it possible to ask image decoders to only decode the first frame. r=tn (1beeeefb6) - Bug 1191100 - Remove XPIDL signature comments in .cpp files. r=ehsan (ee75fe3b5)
245 lines
6.9 KiB
C++
245 lines
6.9 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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/. */
|
|
|
|
#include "DecoderFactory.h"
|
|
|
|
#include "nsMimeTypes.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "nsString.h"
|
|
|
|
#include "Decoder.h"
|
|
#include "nsPNGDecoder.h"
|
|
#include "nsGIFDecoder2.h"
|
|
#include "nsJPEGDecoder.h"
|
|
#ifdef MOZ_JXR
|
|
#include "nsJXRDecoder.h"
|
|
#endif
|
|
#include "nsBMPDecoder.h"
|
|
#include "nsICODecoder.h"
|
|
#include "nsIconDecoder.h"
|
|
#include "nsWEBPDecoder.h"
|
|
|
|
namespace mozilla {
|
|
|
|
using namespace gfx;
|
|
|
|
namespace image {
|
|
|
|
/* static */ DecoderType
|
|
DecoderFactory::GetDecoderType(const char* aMimeType)
|
|
{
|
|
// By default we don't know.
|
|
DecoderType type = DecoderType::UNKNOWN;
|
|
|
|
// PNG
|
|
if (!strcmp(aMimeType, IMAGE_PNG)) {
|
|
type = DecoderType::PNG;
|
|
} else if (!strcmp(aMimeType, IMAGE_X_PNG)) {
|
|
type = DecoderType::PNG;
|
|
|
|
// GIF
|
|
} else if (!strcmp(aMimeType, IMAGE_GIF)) {
|
|
type = DecoderType::GIF;
|
|
|
|
// JPEG
|
|
} else if (!strcmp(aMimeType, IMAGE_JPEG)) {
|
|
type = DecoderType::JPEG;
|
|
} else if (!strcmp(aMimeType, IMAGE_PJPEG)) {
|
|
type = DecoderType::JPEG;
|
|
} else if (!strcmp(aMimeType, IMAGE_JPG)) {
|
|
type = DecoderType::JPEG;
|
|
|
|
// BMP
|
|
} else if (!strcmp(aMimeType, IMAGE_BMP)) {
|
|
type = DecoderType::BMP;
|
|
} else if (!strcmp(aMimeType, IMAGE_BMP_MS)) {
|
|
type = DecoderType::BMP;
|
|
|
|
// ICO
|
|
} else if (!strcmp(aMimeType, IMAGE_ICO)) {
|
|
type = DecoderType::ICO;
|
|
} else if (!strcmp(aMimeType, IMAGE_ICO_MS)) {
|
|
type = DecoderType::ICO;
|
|
|
|
// Icon
|
|
} else if (!strcmp(aMimeType, IMAGE_ICON_MS)) {
|
|
type = DecoderType::ICON;
|
|
|
|
// WebP
|
|
} else if (!strcmp(aMimeType, IMAGE_WEBP) &&
|
|
gfxPrefs::ImageWebPEnabled()) {
|
|
type = DecoderType::WEBP;
|
|
|
|
#ifdef MOZ_JXR
|
|
} else if (!strcmp(aMimeType, IMAGE_JXR) || !strcmp(aMimeType, IMAGE_MS_PHOTO)) {
|
|
if (gfxPrefs::MediaJXREnabled()) {
|
|
type = DecoderType::JXR;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
/* static */ already_AddRefed<Decoder>
|
|
DecoderFactory::GetDecoder(DecoderType aType,
|
|
RasterImage* aImage,
|
|
bool aIsRedecode)
|
|
{
|
|
nsRefPtr<Decoder> decoder;
|
|
|
|
switch (aType) {
|
|
case DecoderType::PNG:
|
|
decoder = new nsPNGDecoder(aImage);
|
|
break;
|
|
case DecoderType::GIF:
|
|
decoder = new nsGIFDecoder2(aImage);
|
|
break;
|
|
case DecoderType::JPEG:
|
|
// If we have all the data we don't want to waste cpu time doing
|
|
// a progressive decode.
|
|
decoder = new nsJPEGDecoder(aImage,
|
|
aIsRedecode ? Decoder::SEQUENTIAL
|
|
: Decoder::PROGRESSIVE);
|
|
break;
|
|
case DecoderType::BMP:
|
|
decoder = new nsBMPDecoder(aImage);
|
|
break;
|
|
case DecoderType::ICO:
|
|
decoder = new nsICODecoder(aImage);
|
|
break;
|
|
case DecoderType::ICON:
|
|
decoder = new nsIconDecoder(aImage);
|
|
break;
|
|
case DecoderType::WEBP:
|
|
decoder = new nsWEBPDecoder(aImage);
|
|
break;
|
|
#ifdef MOZ_JXR
|
|
case DecoderType::JXR:
|
|
decoder = new nsJXRDecoder(aImage, aIsRedecode);
|
|
break;
|
|
#endif
|
|
default:
|
|
MOZ_ASSERT_UNREACHABLE("Unknown decoder type");
|
|
}
|
|
|
|
return decoder.forget();
|
|
}
|
|
|
|
/* static */ already_AddRefed<Decoder>
|
|
DecoderFactory::CreateDecoder(DecoderType aType,
|
|
RasterImage* aImage,
|
|
SourceBuffer* aSourceBuffer,
|
|
const Maybe<IntSize>& aTargetSize,
|
|
uint32_t aFlags,
|
|
int aSampleSize,
|
|
const IntSize& aResolution,
|
|
bool aIsRedecode,
|
|
bool aImageIsTransient,
|
|
bool aImageIsLocked)
|
|
{
|
|
if (aType == DecoderType::UNKNOWN) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<Decoder> decoder = GetDecoder(aType, aImage, aIsRedecode);
|
|
MOZ_ASSERT(decoder, "Should have a decoder now");
|
|
|
|
// Initialize the decoder.
|
|
decoder->SetMetadataDecode(false);
|
|
decoder->SetIterator(aSourceBuffer->Iterator());
|
|
decoder->SetFlags(aFlags);
|
|
decoder->SetSampleSize(aSampleSize);
|
|
decoder->SetResolution(aResolution);
|
|
decoder->SetSendPartialInvalidations(!aIsRedecode);
|
|
decoder->SetImageIsTransient(aImageIsTransient);
|
|
|
|
if (aImageIsLocked) {
|
|
decoder->SetImageIsLocked();
|
|
}
|
|
|
|
// Set a target size for downscale-during-decode if applicable.
|
|
if (aTargetSize) {
|
|
DebugOnly<nsresult> rv = decoder->SetTargetSize(*aTargetSize);
|
|
MOZ_ASSERT(nsresult(rv) != NS_ERROR_NOT_AVAILABLE,
|
|
"We're downscale-during-decode but decoder doesn't support it?");
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?");
|
|
}
|
|
|
|
decoder->Init();
|
|
if (NS_FAILED(decoder->GetDecoderError())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return decoder.forget();
|
|
}
|
|
|
|
/* static */ already_AddRefed<Decoder>
|
|
DecoderFactory::CreateMetadataDecoder(DecoderType aType,
|
|
RasterImage* aImage,
|
|
SourceBuffer* aSourceBuffer,
|
|
int aSampleSize,
|
|
const IntSize& aResolution)
|
|
{
|
|
if (aType == DecoderType::UNKNOWN) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<Decoder> decoder =
|
|
GetDecoder(aType, aImage, /* aIsRedecode = */ false);
|
|
MOZ_ASSERT(decoder, "Should have a decoder now");
|
|
|
|
// Initialize the decoder.
|
|
decoder->SetMetadataDecode(true);
|
|
decoder->SetIterator(aSourceBuffer->Iterator());
|
|
decoder->SetSampleSize(aSampleSize);
|
|
decoder->SetResolution(aResolution);
|
|
|
|
decoder->Init();
|
|
if (NS_FAILED(decoder->GetDecoderError())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return decoder.forget();
|
|
}
|
|
|
|
/* static */ already_AddRefed<Decoder>
|
|
DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
|
|
SourceBuffer* aSourceBuffer,
|
|
uint32_t aFlags)
|
|
{
|
|
if (aType == DecoderType::UNKNOWN) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<Decoder> decoder =
|
|
GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false);
|
|
MOZ_ASSERT(decoder, "Should have a decoder now");
|
|
|
|
// Initialize the decoder.
|
|
decoder->SetMetadataDecode(false);
|
|
decoder->SetIterator(aSourceBuffer->Iterator());
|
|
decoder->SetFlags(aFlags);
|
|
decoder->SetImageIsTransient(true);
|
|
|
|
// Without an image, the decoder can't store anything in the SurfaceCache, so
|
|
// callers will only be able to retrieve the most recent frame via
|
|
// Decoder::GetCurrentFrame(). That means that anonymous decoders should
|
|
// always be first-frame-only decoders, because nobody ever wants the *last*
|
|
// frame.
|
|
decoder->SetIsFirstFrameDecode();
|
|
|
|
decoder->Init();
|
|
if (NS_FAILED(decoder->GetDecoderError())) {
|
|
return nullptr;
|
|
}
|
|
|
|
return decoder.forget();
|
|
}
|
|
|
|
} // namespace image
|
|
} // namespace mozilla
|