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 return (width <= maxPNGSize) && (height <= maxPNGSize) && |
| 217 ImageDecoder::setSize(width, height); |
| 218 } |
| 219 |
197 void PNGImageDecoder::headerAvailable() { | 220 void PNGImageDecoder::headerAvailable() { |
| 221 DCHECK(isDecodedSizeAvailable()); |
| 222 |
198 png_structp png = m_reader->pngPtr(); | 223 png_structp png = m_reader->pngPtr(); |
199 png_infop info = m_reader->infoPtr(); | 224 png_infop info = m_reader->infoPtr(); |
200 | 225 |
201 png_uint_32 width, height; | 226 png_uint_32 width, height; |
202 int bitDepth, colorType, interlaceType, compressionType; | 227 int bitDepth, colorType, interlaceType, compressionType; |
203 png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, | 228 png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, |
204 &interlaceType, &compressionType, nullptr); | 229 &interlaceType, &compressionType, nullptr); |
205 | 230 |
206 // The options we set here match what Mozilla does. | 231 // The options we set here match what Mozilla does. |
207 | 232 |
208 // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA. | 233 // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA. |
209 if (colorType == PNG_COLOR_TYPE_PALETTE || | 234 if (colorType == PNG_COLOR_TYPE_PALETTE || |
210 (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)) | 235 (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)) |
211 png_set_expand(png); | 236 png_set_expand(png); |
212 | 237 |
213 if (png_get_valid(png, info, PNG_INFO_tRNS)) | 238 if (png_get_valid(png, info, PNG_INFO_tRNS)) |
214 png_set_expand(png); | 239 png_set_expand(png); |
215 | 240 |
216 if (bitDepth == 16) | 241 if (bitDepth == 16) |
217 png_set_strip_16(png); | 242 png_set_strip_16(png); |
218 | 243 |
219 if (colorType == PNG_COLOR_TYPE_GRAY || | 244 if (colorType == PNG_COLOR_TYPE_GRAY || |
220 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) | 245 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) |
221 png_set_gray_to_rgb(png); | 246 png_set_gray_to_rgb(png); |
222 | 247 |
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()) { | 248 if (!hasEmbeddedColorSpace()) { |
249 const double inverseGamma = 0.45455; | 249 const double inverseGamma = 0.45455; |
250 const double defaultGamma = 2.2; | 250 const double defaultGamma = 2.2; |
251 double gamma; | 251 double gamma; |
252 if (!ignoresColorSpace() && png_get_gAMA(png, info, &gamma)) { | 252 if (!ignoresColorSpace() && png_get_gAMA(png, info, &gamma)) { |
253 const double maxGamma = 21474.83; | 253 const double maxGamma = 21474.83; |
254 if ((gamma <= 0.0) || (gamma > maxGamma)) { | 254 if ((gamma <= 0.0) || (gamma > maxGamma)) { |
255 gamma = inverseGamma; | 255 gamma = inverseGamma; |
256 png_set_gAMA(png, info, gamma); | 256 png_set_gAMA(png, info, gamma); |
257 } | 257 } |
258 png_set_gamma(png, defaultGamma, gamma); | 258 png_set_gamma(png, defaultGamma, gamma); |
259 } else { | 259 } else { |
260 png_set_gamma(png, defaultGamma, inverseGamma); | 260 png_set_gamma(png, defaultGamma, inverseGamma); |
261 } | 261 } |
262 } | 262 } |
263 | 263 |
264 DCHECK(isDecodedSizeAvailable()); | |
265 | |
266 // Tell libpng to send us rows for interlaced pngs. | 264 // Tell libpng to send us rows for interlaced pngs. |
267 if (interlaceType == PNG_INTERLACE_ADAM7) | 265 if (interlaceType == PNG_INTERLACE_ADAM7) |
268 png_set_interlace_handling(png); | 266 png_set_interlace_handling(png); |
269 | 267 |
270 // Update our info now (so we can get color channel info). | 268 // Update our info now (so we can get color channel info). |
271 png_read_update_info(png, info); | 269 png_read_update_info(png, info); |
272 | 270 |
273 int channels = png_get_channels(png, info); | 271 int channels = png_get_channels(png, info); |
274 DCHECK(channels == 3 || channels == 4); | 272 DCHECK(channels == 3 || channels == 4); |
275 m_hasAlphaChannel = (channels == 4); | 273 m_hasAlphaChannel = (channels == 4); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 return m_reader->frameIsReceivedAtIndex(index); | 482 return m_reader->frameIsReceivedAtIndex(index); |
485 } | 483 } |
486 | 484 |
487 float PNGImageDecoder::frameDurationAtIndex(size_t index) const { | 485 float PNGImageDecoder::frameDurationAtIndex(size_t index) const { |
488 if (index < m_frameBufferCache.size()) | 486 if (index < m_frameBufferCache.size()) |
489 return m_frameBufferCache[index].duration(); | 487 return m_frameBufferCache[index].duration(); |
490 return 0; | 488 return 0; |
491 } | 489 } |
492 | 490 |
493 } // namespace blink | 491 } // namespace blink |
OLD | NEW |