• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 
9 #include "SkImageDecoder.h"
10 #include "SkBitmap.h"
11 #include "SkImagePriv.h"
12 #include "SkPixelRef.h"
13 #include "SkStream.h"
14 #include "SkTemplates.h"
15 #include "SkCanvas.h"
16 
SkImageDecoder()17 SkImageDecoder::SkImageDecoder()
18     : fPeeker(nullptr)
19     , fAllocator(nullptr)
20     , fSampleSize(1)
21     , fDefaultPref(kUnknown_SkColorType)
22     , fPreserveSrcDepth(false)
23     , fDitherImage(true)
24     , fSkipWritingZeroes(false)
25     , fPreferQualityOverSpeed(false)
26     , fRequireUnpremultipliedColors(false) {
27 }
28 
~SkImageDecoder()29 SkImageDecoder::~SkImageDecoder() {
30     SkSafeUnref(fPeeker);
31     SkSafeUnref(fAllocator);
32 }
33 
copyFieldsToOther(SkImageDecoder * other)34 void SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) {
35     if (nullptr == other) {
36         return;
37     }
38     other->setPeeker(fPeeker);
39     other->setAllocator(fAllocator);
40     other->setSampleSize(fSampleSize);
41     other->setPreserveSrcDepth(fPreserveSrcDepth);
42     other->setDitherImage(fDitherImage);
43     other->setSkipWritingZeroes(fSkipWritingZeroes);
44     other->setPreferQualityOverSpeed(fPreferQualityOverSpeed);
45     other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors);
46 }
47 
getFormat() const48 SkImageDecoder::Format SkImageDecoder::getFormat() const {
49     return kUnknown_Format;
50 }
51 
getFormatName() const52 const char* SkImageDecoder::getFormatName() const {
53     return GetFormatName(this->getFormat());
54 }
55 
GetFormatName(Format format)56 const char* SkImageDecoder::GetFormatName(Format format) {
57     switch (format) {
58         case kUnknown_Format:
59             return "Unknown Format";
60         case kBMP_Format:
61             return "BMP";
62         case kGIF_Format:
63             return "GIF";
64         case kICO_Format:
65             return "ICO";
66         case kPKM_Format:
67             return "PKM";
68         case kKTX_Format:
69             return "KTX";
70         case kASTC_Format:
71             return "ASTC";
72         case kJPEG_Format:
73             return "JPEG";
74         case kPNG_Format:
75             return "PNG";
76         case kWBMP_Format:
77             return "WBMP";
78         case kWEBP_Format:
79             return "WEBP";
80         default:
81             SkDEBUGFAIL("Invalid format type!");
82     }
83     return "Unknown Format";
84 }
85 
setPeeker(SkPngChunkReader * peeker)86 SkPngChunkReader* SkImageDecoder::setPeeker(SkPngChunkReader* peeker) {
87     SkRefCnt_SafeAssign(fPeeker, peeker);
88     return peeker;
89 }
90 
setAllocator(SkBitmap::Allocator * alloc)91 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
92     SkRefCnt_SafeAssign(fAllocator, alloc);
93     return alloc;
94 }
95 
setSampleSize(int size)96 void SkImageDecoder::setSampleSize(int size) {
97     if (size < 1) {
98         size = 1;
99     }
100     fSampleSize = size;
101 }
102 
allocPixelRef(SkBitmap * bitmap,SkColorTable * ctable) const103 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
104                                    SkColorTable* ctable) const {
105     return bitmap->tryAllocPixels(fAllocator, ctable);
106 }
107 
108 ///////////////////////////////////////////////////////////////////////////////
109 
getPrefColorType(SrcDepth srcDepth,bool srcHasAlpha) const110 SkColorType SkImageDecoder::getPrefColorType(SrcDepth srcDepth, bool srcHasAlpha) const {
111     SkColorType ct = fDefaultPref;
112     if (fPreserveSrcDepth) {
113         switch (srcDepth) {
114             case kIndex_SrcDepth:
115                 ct = kIndex_8_SkColorType;
116                 break;
117             case k8BitGray_SrcDepth:
118                 ct = kN32_SkColorType;
119                 break;
120             case k32Bit_SrcDepth:
121                 ct = kN32_SkColorType;
122                 break;
123         }
124     }
125     return ct;
126 }
127 
decode(SkStream * stream,SkBitmap * bm,SkColorType pref,Mode mode)128 SkImageDecoder::Result SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref,
129                                               Mode mode) {
130     // we reset this to false before calling onDecode
131     fShouldCancelDecode = false;
132     // assign this, for use by getPrefColorType(), in case fUsePrefTable is false
133     fDefaultPref = pref;
134 
135     // pass a temporary bitmap, so that if we return false, we are assured of
136     // leaving the caller's bitmap untouched.
137     SkBitmap tmp;
138     const Result result = this->onDecode(stream, &tmp, mode);
139     if (kFailure != result) {
140         bm->swap(tmp);
141     }
142     return result;
143 }
144 
145 ///////////////////////////////////////////////////////////////////////////////
146 
DecodeFile(const char file[],SkBitmap * bm,SkColorType pref,Mode mode,Format * format)147 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, SkColorType pref,  Mode mode,
148                                 Format* format) {
149     SkASSERT(file);
150     SkASSERT(bm);
151 
152     SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(file));
153     if (stream.get()) {
154         if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) {
155             if (SkPixelRef* pr = bm->pixelRef()) {
156                 pr->setURI(file);
157             }
158             return true;
159         }
160     }
161     return false;
162 }
163 
DecodeMemory(const void * buffer,size_t size,SkBitmap * bm,SkColorType pref,Mode mode,Format * format)164 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, SkColorType pref,
165                                   Mode mode, Format* format) {
166     if (0 == size) {
167         return false;
168     }
169     SkASSERT(buffer);
170 
171     SkMemoryStream  stream(buffer, size);
172     return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
173 }
174 
DecodeStream(SkStreamRewindable * stream,SkBitmap * bm,SkColorType pref,Mode mode,Format * format)175 bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, SkColorType pref,
176                                   Mode mode, Format* format) {
177     SkASSERT(stream);
178     SkASSERT(bm);
179 
180     bool success = false;
181     SkImageDecoder* codec = SkImageDecoder::Factory(stream);
182 
183     if (codec) {
184         success = codec->decode(stream, bm, pref, mode) != kFailure;
185         if (success && format) {
186             *format = codec->getFormat();
187             if (kUnknown_Format == *format) {
188                 if (stream->rewind()) {
189                     *format = GetStreamFormat(stream);
190                 }
191             }
192         }
193         delete codec;
194     }
195     return success;
196 }
197 
decodeYUV8Planes(SkStream * stream,SkISize componentSizes[3],void * planes[3],size_t rowBytes[3],SkYUVColorSpace * colorSpace)198 bool SkImageDecoder::decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3],
199                                       size_t rowBytes[3], SkYUVColorSpace* colorSpace) {
200     // we reset this to false before calling onDecodeYUV8Planes
201     fShouldCancelDecode = false;
202 
203     return this->onDecodeYUV8Planes(stream, componentSizes, planes, rowBytes, colorSpace);
204 }
205