OLD | NEW |
| (Empty) |
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 | |
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 | |
29 SkImageDecoder::~SkImageDecoder() { | |
30 SkSafeUnref(fPeeker); | |
31 SkSafeUnref(fAllocator); | |
32 } | |
33 | |
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 | |
48 SkImageDecoder::Format SkImageDecoder::getFormat() const { | |
49 return kUnknown_Format; | |
50 } | |
51 | |
52 const char* SkImageDecoder::getFormatName() const { | |
53 return GetFormatName(this->getFormat()); | |
54 } | |
55 | |
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 | |
86 SkPngChunkReader* SkImageDecoder::setPeeker(SkPngChunkReader* peeker) { | |
87 SkRefCnt_SafeAssign(fPeeker, peeker); | |
88 return peeker; | |
89 } | |
90 | |
91 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { | |
92 SkRefCnt_SafeAssign(fAllocator, alloc); | |
93 return alloc; | |
94 } | |
95 | |
96 void SkImageDecoder::setSampleSize(int size) { | |
97 if (size < 1) { | |
98 size = 1; | |
99 } | |
100 fSampleSize = size; | |
101 } | |
102 | |
103 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, | |
104 SkColorTable* ctable) const { | |
105 return bitmap->tryAllocPixels(fAllocator, ctable); | |
106 } | |
107 | |
108 /////////////////////////////////////////////////////////////////////////////// | |
109 | |
110 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 | |
128 SkImageDecoder::Result SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, Sk
ColorType 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 fals
e | |
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 | |
147 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, SkColorType pre
f, 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 | |
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 | |
175 bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, SkCo
lorType 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 | |
198 bool SkImageDecoder::decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3
], void* planes[3], | |
199 size_t rowBytes[3], SkYUVColorSpace* color
Space) { | |
200 // we reset this to false before calling onDecodeYUV8Planes | |
201 fShouldCancelDecode = false; | |
202 | |
203 return this->onDecodeYUV8Planes(stream, componentSizes, planes, rowBytes, co
lorSpace); | |
204 } | |
OLD | NEW |