OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006 Apple Computer, Inc. | 2 * Copyright (C) 2006 Apple Computer, Inc. |
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
4 * | 4 * |
5 * Portions are Copyright (C) 2001 mozilla.org | 5 * Portions are Copyright (C) 2001 mozilla.org |
6 * | 6 * |
7 * Other contributors: | 7 * Other contributors: |
8 * Stuart Parmenter <stuart@mozilla.com> | 8 * Stuart Parmenter <stuart@mozilla.com> |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 return nullptr; | 187 return nullptr; |
188 | 188 |
189 SkColorSpaceTransferFn fn; | 189 SkColorSpaceTransferFn fn; |
190 fn.fG = 1.0f / pngFixedToFloat(inverseGamma); | 190 fn.fG = 1.0f / pngFixedToFloat(inverseGamma); |
191 fn.fA = 1.0f; | 191 fn.fA = 1.0f; |
192 fn.fB = fn.fC = fn.fD = fn.fE = fn.fF = 0.0f; | 192 fn.fB = fn.fC = fn.fD = fn.fE = fn.fF = 0.0f; |
193 | 193 |
194 return SkColorSpace::MakeRGB(fn, toXYZD50); | 194 return SkColorSpace::MakeRGB(fn, toXYZD50); |
195 } | 195 } |
196 | 196 |
197 void PNGImageDecoder::setColorSpace() { | |
198 if (ignoresColorSpace()) | |
199 return; | |
200 png_structp png = m_reader->pngPtr(); | |
201 png_infop info = m_reader->infoPtr(); | |
202 const int colorType = png_get_color_type(png, info); | |
203 if (!(colorType & PNG_COLOR_MASK_COLOR)) | |
204 return; | |
205 // We only support color profiles for color PALETTE and RGB[A] PNG. | |
206 // TODO(msarett): Add GRAY profile support, block CYMK? | |
207 sk_sp<SkColorSpace> colorSpace = readColorSpace(png, info); | |
208 if (colorSpace) | |
209 setEmbeddedColorSpace(colorSpace); | |
210 } | |
211 | |
212 bool PNGImageDecoder::setSize(unsigned width, unsigned height) { | |
213 DCHECK(!isDecodedSizeAvailable()); | |
214 // Protect against large PNGs. See http://bugzil.la/251381 for more details. | |
215 const unsigned long maxPNGSize = 1000000UL; | |
216 if (width > maxPNGSize || height > maxPNGSize) | |
217 return false; | |
218 return ImageDecoder::setSize(width, height); | |
Peter Kasting
2017/03/22 21:59:52
Nit: Or:
return (width <= maxPNGSize) && (heigh
scroggo_chromium
2017/03/23 12:24:41
Done.
| |
219 } | |
220 | |
197 void PNGImageDecoder::headerAvailable() { | 221 void PNGImageDecoder::headerAvailable() { |
222 DCHECK(isDecodedSizeAvailable()); | |
223 | |
198 png_structp png = m_reader->pngPtr(); | 224 png_structp png = m_reader->pngPtr(); |
199 png_infop info = m_reader->infoPtr(); | 225 png_infop info = m_reader->infoPtr(); |
200 | 226 |
201 png_uint_32 width, height; | 227 png_uint_32 width, height; |
202 int bitDepth, colorType, interlaceType, compressionType; | 228 int bitDepth, colorType, interlaceType, compressionType; |
203 png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, | 229 png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, |
204 &interlaceType, &compressionType, nullptr); | 230 &interlaceType, &compressionType, nullptr); |
205 | 231 |
206 // The options we set here match what Mozilla does. | 232 // The options we set here match what Mozilla does. |
207 | 233 |
208 // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA. | 234 // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA. |
209 if (colorType == PNG_COLOR_TYPE_PALETTE || | 235 if (colorType == PNG_COLOR_TYPE_PALETTE || |
210 (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)) | 236 (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)) |
211 png_set_expand(png); | 237 png_set_expand(png); |
212 | 238 |
213 if (png_get_valid(png, info, PNG_INFO_tRNS)) | 239 if (png_get_valid(png, info, PNG_INFO_tRNS)) |
214 png_set_expand(png); | 240 png_set_expand(png); |
215 | 241 |
216 if (bitDepth == 16) | 242 if (bitDepth == 16) |
217 png_set_strip_16(png); | 243 png_set_strip_16(png); |
218 | 244 |
219 if (colorType == PNG_COLOR_TYPE_GRAY || | 245 if (colorType == PNG_COLOR_TYPE_GRAY || |
220 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) | 246 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) |
221 png_set_gray_to_rgb(png); | 247 png_set_gray_to_rgb(png); |
222 | 248 |
223 // Only set the size and the color space of the image once since non-first | |
224 // frames also use this method: there is no per-frame color space, and the | |
225 // image size is determined from the header width and height. | |
226 if (!isDecodedSizeAvailable()) { | |
227 // Protect against large PNGs. See http://bugzil.la/251381 for more details. | |
228 const unsigned long maxPNGSize = 1000000UL; | |
229 if (width > maxPNGSize || height > maxPNGSize) { | |
230 longjmp(JMPBUF(png), 1); | |
231 return; | |
232 } | |
233 | |
234 // Set the image size now that the image header is available. | |
235 if (!setSize(width, height)) { | |
236 longjmp(JMPBUF(png), 1); | |
237 return; | |
238 } | |
239 | |
240 if ((colorType & PNG_COLOR_MASK_COLOR) && !ignoresColorSpace()) { | |
241 // We only support color profiles for color PALETTE and RGB[A] PNG. | |
242 // TODO(msarret): Add GRAY profile support, block CYMK? | |
243 if (sk_sp<SkColorSpace> colorSpace = readColorSpace(png, info)) | |
244 setEmbeddedColorSpace(colorSpace); | |
245 } | |
246 } | |
247 | |
248 if (!hasEmbeddedColorSpace()) { | 249 if (!hasEmbeddedColorSpace()) { |
249 const double inverseGamma = 0.45455; | 250 const double inverseGamma = 0.45455; |
250 const double defaultGamma = 2.2; | 251 const double defaultGamma = 2.2; |
251 double gamma; | 252 double gamma; |
252 if (!ignoresColorSpace() && png_get_gAMA(png, info, &gamma)) { | 253 if (!ignoresColorSpace() && png_get_gAMA(png, info, &gamma)) { |
253 const double maxGamma = 21474.83; | 254 const double maxGamma = 21474.83; |
254 if ((gamma <= 0.0) || (gamma > maxGamma)) { | 255 if ((gamma <= 0.0) || (gamma > maxGamma)) { |
255 gamma = inverseGamma; | 256 gamma = inverseGamma; |
256 png_set_gAMA(png, info, gamma); | 257 png_set_gAMA(png, info, gamma); |
257 } | 258 } |
258 png_set_gamma(png, defaultGamma, gamma); | 259 png_set_gamma(png, defaultGamma, gamma); |
259 } else { | 260 } else { |
260 png_set_gamma(png, defaultGamma, inverseGamma); | 261 png_set_gamma(png, defaultGamma, inverseGamma); |
261 } | 262 } |
262 } | 263 } |
263 | 264 |
264 DCHECK(isDecodedSizeAvailable()); | |
265 | |
266 // Tell libpng to send us rows for interlaced pngs. | 265 // Tell libpng to send us rows for interlaced pngs. |
267 if (interlaceType == PNG_INTERLACE_ADAM7) | 266 if (interlaceType == PNG_INTERLACE_ADAM7) |
268 png_set_interlace_handling(png); | 267 png_set_interlace_handling(png); |
269 | 268 |
270 // Update our info now (so we can get color channel info). | 269 // Update our info now (so we can get color channel info). |
271 png_read_update_info(png, info); | 270 png_read_update_info(png, info); |
272 | 271 |
273 int channels = png_get_channels(png, info); | 272 int channels = png_get_channels(png, info); |
274 DCHECK(channels == 3 || channels == 4); | 273 DCHECK(channels == 3 || channels == 4); |
275 m_hasAlphaChannel = (channels == 4); | 274 m_hasAlphaChannel = (channels == 4); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 return m_reader->frameIsReceivedAtIndex(index); | 483 return m_reader->frameIsReceivedAtIndex(index); |
485 } | 484 } |
486 | 485 |
487 float PNGImageDecoder::frameDurationAtIndex(size_t index) const { | 486 float PNGImageDecoder::frameDurationAtIndex(size_t index) const { |
488 if (index < m_frameBufferCache.size()) | 487 if (index < m_frameBufferCache.size()) |
489 return m_frameBufferCache[index].duration(); | 488 return m_frameBufferCache[index].duration(); |
490 return 0; | 489 return 0; |
491 } | 490 } |
492 | 491 |
493 } // namespace blink | 492 } // namespace blink |
OLD | NEW |