OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCodecPriv.h" | 8 #include "SkCodecPriv.h" |
9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
10 #include "SkColorTable.h" | 10 #include "SkColorTable.h" |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 192 |
193 if (nullptr != codecOut) { | 193 if (nullptr != codecOut) { |
194 SkISize size; | 194 SkISize size; |
195 SkIRect frameRect; | 195 SkIRect frameRect; |
196 if (!GetDimensions(gif, &size, &frameRect)) { | 196 if (!GetDimensions(gif, &size, &frameRect)) { |
197 gif_error("Invalid gif size.\n"); | 197 gif_error("Invalid gif size.\n"); |
198 return false; | 198 return false; |
199 } | 199 } |
200 bool frameIsSubset = (size != frameRect.size()); | 200 bool frameIsSubset = (size != frameRect.size()); |
201 | 201 |
202 // Determine the encoded alpha type. The transIndex might be valid if i
t less | 202 // Determine the recommended alpha type. The transIndex might be valid
if it less |
203 // than 256. We are not certain that the index is valid until we proces
s the color | 203 // than 256. We are not certain that the index is valid until we proces
s the color |
204 // table, since some gifs have color tables with less than 256 colors.
If | 204 // table, since some gifs have color tables with less than 256 colors.
If |
205 // there might be a valid transparent index, we must indicate that the i
mage has | 205 // there might be a valid transparent index, we must indicate that the i
mage has |
206 // alpha. | 206 // alpha. |
207 // In the case where we must support alpha, we indicate kBinary, since e
very | 207 // In the case where we must support alpha, we have the option to set th
e |
208 // pixel will either be fully opaque or fully transparent. | 208 // suggested alpha type to kPremul or kUnpremul. Both are valid since t
he alpha |
209 SkEncodedInfo::Alpha alpha = (transIndex < 256) ? SkEncodedInfo::kBinary
_Alpha : | 209 // component will always be 0xFF or the entire 32-bit pixel will be set
to zero. |
210 SkEncodedInfo::kOpaque_Alpha; | 210 // We prefer kPremul because we support kPremul, and it is more efficien
t to use |
| 211 // kPremul directly even when kUnpremul is supported. |
| 212 SkAlphaType alphaType = (transIndex < 256) ? kPremul_SkAlphaType : kOpaq
ue_SkAlphaType; |
211 | 213 |
212 // Return the codec | 214 // Return the codec |
213 // Use kPalette since Gifs are encoded with a color table. | 215 // kIndex is the most natural color type for gifs, so we set this as |
214 // Use 8-bits per component, since this is the output we get from giflib
. | 216 // the default. |
215 // FIXME: Gifs can actually be encoded with 4-bits per pixel. Can we su
pport this? | 217 SkImageInfo imageInfo = SkImageInfo::Make(size.width(), size.height(), k
Index_8_SkColorType, |
216 SkEncodedInfo info = SkEncodedInfo::Make(SkEncodedInfo::kPalette_Color,
alpha, 8); | 218 alphaType); |
217 *codecOut = new SkGifCodec(size.width(), size.height(), info, streamDele
ter.release(), | 219 *codecOut = new SkGifCodec(imageInfo, streamDeleter.release(), gif.relea
se(), transIndex, |
218 gif.release(), transIndex, frameRect, frameIsSubset); | 220 frameRect, frameIsSubset); |
219 } else { | 221 } else { |
220 SkASSERT(nullptr != gifOut); | 222 SkASSERT(nullptr != gifOut); |
221 streamDeleter.release(); | 223 streamDeleter.release(); |
222 *gifOut = gif.release(); | 224 *gifOut = gif.release(); |
223 } | 225 } |
224 return true; | 226 return true; |
225 } | 227 } |
226 | 228 |
227 /* | 229 /* |
228 * Assumes IsGif was called and returned true | 230 * Assumes IsGif was called and returned true |
229 * Creates a gif decoder | 231 * Creates a gif decoder |
230 * Reads enough of the stream to determine the image format | 232 * Reads enough of the stream to determine the image format |
231 */ | 233 */ |
232 SkCodec* SkGifCodec::NewFromStream(SkStream* stream) { | 234 SkCodec* SkGifCodec::NewFromStream(SkStream* stream) { |
233 SkCodec* codec = nullptr; | 235 SkCodec* codec = nullptr; |
234 if (ReadHeader(stream, &codec, nullptr)) { | 236 if (ReadHeader(stream, &codec, nullptr)) { |
235 return codec; | 237 return codec; |
236 } | 238 } |
237 return nullptr; | 239 return nullptr; |
238 } | 240 } |
239 | 241 |
240 SkGifCodec::SkGifCodec(int width, int height, const SkEncodedInfo& info, SkStrea
m* stream, | 242 SkGifCodec::SkGifCodec(const SkImageInfo& srcInfo, SkStream* stream, GifFileType
* gif, |
241 GifFileType* gif, uint32_t transIndex, const SkIRect& frameRect, bool fr
ameIsSubset) | 243 uint32_t transIndex, const SkIRect& frameRect, bool frameIsSubset) |
242 : INHERITED(width, height, info, stream) | 244 : INHERITED(srcInfo, stream) |
243 , fGif(gif) | 245 , fGif(gif) |
244 , fSrcBuffer(new uint8_t[this->getInfo().width()]) | 246 , fSrcBuffer(new uint8_t[this->getInfo().width()]) |
245 , fFrameRect(frameRect) | 247 , fFrameRect(frameRect) |
246 // If it is valid, fTransIndex will be used to set fFillIndex. We don't kno
w if | 248 // If it is valid, fTransIndex will be used to set fFillIndex. We don't kno
w if |
247 // fTransIndex is valid until we process the color table, since fTransIndex
may | 249 // fTransIndex is valid until we process the color table, since fTransIndex
may |
248 // be greater than the size of the color table. | 250 // be greater than the size of the color table. |
249 , fTransIndex(transIndex) | 251 , fTransIndex(transIndex) |
250 // Default fFillIndex is 0. We will overwrite this if fTransIndex is valid,
or if | 252 // Default fFillIndex is 0. We will overwrite this if fTransIndex is valid,
or if |
251 // there is a valid background color. | 253 // there is a valid background color. |
252 , fFillIndex(0) | 254 , fFillIndex(0) |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 int SkGifCodec::onOutputScanline(int inputScanline) const { | 599 int SkGifCodec::onOutputScanline(int inputScanline) const { |
598 if (fGif->Image.Interlace) { | 600 if (fGif->Image.Interlace) { |
599 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott
om()) { | 601 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott
om()) { |
600 return inputScanline; | 602 return inputScanline; |
601 } | 603 } |
602 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram
eRect.height()) + | 604 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram
eRect.height()) + |
603 fFrameRect.top(); | 605 fFrameRect.top(); |
604 } | 606 } |
605 return inputScanline; | 607 return inputScanline; |
606 } | 608 } |
OLD | NEW |