forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			177 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
	
		
			4.8 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 "nsRefPtr.h"
 | |
| #include "nsString.h"
 | |
| 
 | |
| #include "Decoder.h"
 | |
| #include "nsPNGDecoder.h"
 | |
| #include "nsGIFDecoder2.h"
 | |
| #include "nsJPEGDecoder.h"
 | |
| #include "nsBMPDecoder.h"
 | |
| #include "nsICODecoder.h"
 | |
| #include "nsIconDecoder.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;
 | |
|   }
 | |
| 
 | |
|   return type;
 | |
| }
 | |
| 
 | |
| static already_AddRefed<Decoder>
 | |
| 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;
 | |
|     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,
 | |
|                               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->SetSizeDecode(false);
 | |
|   decoder->SetIterator(aSourceBuffer->Iterator());
 | |
|   decoder->SetFlags(aFlags);
 | |
|   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)
 | |
| {
 | |
|   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->SetSizeDecode(true);
 | |
|   decoder->SetIterator(aSourceBuffer->Iterator());
 | |
| 
 | |
|   decoder->Init();
 | |
|   if (NS_FAILED(decoder->GetDecoderError())) {
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   return decoder.forget();
 | |
| }
 | |
| 
 | |
| } // namespace image
 | |
| } // namespace mozilla
 | 
