| 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 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 #include "platform/image-decoders/png/PNGImageReader.h" | 41 #include "platform/image-decoders/png/PNGImageReader.h" |
| 42 #include "png.h" | 42 #include "png.h" |
| 43 #include "wtf/PtrUtil.h" | 43 #include "wtf/PtrUtil.h" |
| 44 #include <memory> | 44 #include <memory> |
| 45 | 45 |
| 46 namespace blink { | 46 namespace blink { |
| 47 | 47 |
| 48 PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, | 48 PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, |
| 49 ColorSpaceOption colorOptions, | 49 ColorSpaceOption colorOptions, |
| 50 sk_sp<SkColorSpace> targetColorSpace, |
| 50 size_t maxDecodedBytes, | 51 size_t maxDecodedBytes, |
| 51 size_t offset) | 52 size_t offset) |
| 52 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes), | 53 : ImageDecoder(alphaOption, |
| 54 colorOptions, |
| 55 std::move(targetColorSpace), |
| 56 maxDecodedBytes), |
| 53 m_offset(offset) {} | 57 m_offset(offset) {} |
| 54 | 58 |
| 55 PNGImageDecoder::~PNGImageDecoder() {} | 59 PNGImageDecoder::~PNGImageDecoder() {} |
| 56 | 60 |
| 57 inline float pngFixedToFloat(png_fixed_point x) { | 61 inline float pngFixedToFloat(png_fixed_point x) { |
| 58 return ((float)x) * 0.00001f; | 62 return ((float)x) * 0.00001f; |
| 59 } | 63 } |
| 60 | 64 |
| 61 inline sk_sp<SkColorSpace> readColorSpace(png_structp png, png_infop info) { | 65 inline sk_sp<SkColorSpace> readColorSpace(png_structp png, png_infop info) { |
| 62 if (png_get_valid(png, info, PNG_INFO_sRGB)) { | 66 if (png_get_valid(png, info, PNG_INFO_sRGB)) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 png_set_expand(png); | 149 png_set_expand(png); |
| 146 } | 150 } |
| 147 | 151 |
| 148 if (bitDepth == 16) | 152 if (bitDepth == 16) |
| 149 png_set_strip_16(png); | 153 png_set_strip_16(png); |
| 150 | 154 |
| 151 if (colorType == PNG_COLOR_TYPE_GRAY || | 155 if (colorType == PNG_COLOR_TYPE_GRAY || |
| 152 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) | 156 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) |
| 153 png_set_gray_to_rgb(png); | 157 png_set_gray_to_rgb(png); |
| 154 | 158 |
| 155 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreColorSpace) { | 159 if ((colorType & PNG_COLOR_MASK_COLOR) && !ignoresColorSpace()) { |
| 156 // We only support color profiles for color PALETTE and RGB[A] PNG. | 160 // We only support color profiles for color PALETTE and RGB[A] PNG. |
| 157 // Supporting color profiles for gray-scale images is slightly tricky, at | 161 // Supporting color profiles for gray-scale images is slightly tricky, at |
| 158 // least using the CoreGraphics ICC library, because we expand gray-scale | 162 // least using the CoreGraphics ICC library, because we expand gray-scale |
| 159 // images to RGB but we do not similarly transform the color profile. We'd | 163 // images to RGB but we do not similarly transform the color profile. We'd |
| 160 // either need to transform the color profile or we'd need to decode into a | 164 // either need to transform the color profile or we'd need to decode into a |
| 161 // gray-scale image buffer and hand that to CoreGraphics. | 165 // gray-scale image buffer and hand that to CoreGraphics. |
| 162 sk_sp<SkColorSpace> colorSpace = readColorSpace(png, info); | 166 sk_sp<SkColorSpace> colorSpace = readColorSpace(png, info); |
| 163 if (colorSpace) { | 167 if (colorSpace) { |
| 164 setEmbeddedColorSpace(colorSpace); | 168 setEmbeddedColorSpace(colorSpace); |
| 165 } | 169 } |
| 166 } | 170 } |
| 167 | 171 |
| 168 if (!hasEmbeddedColorSpace()) { | 172 if (!hasEmbeddedColorSpace()) { |
| 169 // TODO (msarett): | 173 // TODO (msarett): |
| 170 // Applying the transfer function (gamma) should be handled by | 174 // Applying the transfer function (gamma) should be handled by |
| 171 // SkColorSpaceXform. Here we always convert to a transfer function that | 175 // SkColorSpaceXform. Here we always convert to a transfer function that |
| 172 // is a 2.2 exponential. This is a little strange given that the dst | 176 // is a 2.2 exponential. This is a little strange given that the dst |
| 173 // transfer function is not necessarily a 2.2 exponential. | 177 // transfer function is not necessarily a 2.2 exponential. |
| 174 // TODO (msarett): | 178 // TODO (msarett): |
| 175 // Often, PNGs that specify their transfer function with the gAMA tag will | 179 // Often, PNGs that specify their transfer function with the gAMA tag will |
| 176 // also specify their gamut with the cHRM tag. We should read this tag | 180 // also specify their gamut with the cHRM tag. We should read this tag |
| 177 // and do a full color space transformation if it is present. | 181 // and do a full color space transformation if it is present. |
| 178 const double inverseGamma = 0.45455; | 182 const double inverseGamma = 0.45455; |
| 179 const double defaultGamma = 2.2; | 183 const double defaultGamma = 2.2; |
| 180 double gamma; | 184 double gamma; |
| 181 if (!m_ignoreColorSpace && png_get_gAMA(png, info, &gamma)) { | 185 if (!ignoresColorSpace() && png_get_gAMA(png, info, &gamma)) { |
| 182 const double maxGamma = 21474.83; | 186 const double maxGamma = 21474.83; |
| 183 if ((gamma <= 0.0) || (gamma > maxGamma)) { | 187 if ((gamma <= 0.0) || (gamma > maxGamma)) { |
| 184 gamma = inverseGamma; | 188 gamma = inverseGamma; |
| 185 png_set_gAMA(png, info, gamma); | 189 png_set_gAMA(png, info, gamma); |
| 186 } | 190 } |
| 187 png_set_gamma(png, defaultGamma, gamma); | 191 png_set_gamma(png, defaultGamma, gamma); |
| 188 } else { | 192 } else { |
| 189 png_set_gamma(png, defaultGamma, inverseGamma); | 193 png_set_gamma(png, defaultGamma, inverseGamma); |
| 190 } | 194 } |
| 191 } | 195 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 219 unsigned rowIndex, | 223 unsigned rowIndex, |
| 220 int) { | 224 int) { |
| 221 if (m_frameBufferCache.isEmpty()) | 225 if (m_frameBufferCache.isEmpty()) |
| 222 return; | 226 return; |
| 223 | 227 |
| 224 // Initialize the framebuffer if needed. | 228 // Initialize the framebuffer if needed. |
| 225 ImageFrame& buffer = m_frameBufferCache[0]; | 229 ImageFrame& buffer = m_frameBufferCache[0]; |
| 226 if (buffer.getStatus() == ImageFrame::FrameEmpty) { | 230 if (buffer.getStatus() == ImageFrame::FrameEmpty) { |
| 227 png_structp png = m_reader->pngPtr(); | 231 png_structp png = m_reader->pngPtr(); |
| 228 if (!buffer.setSizeAndColorSpace(size().width(), size().height(), | 232 if (!buffer.setSizeAndColorSpace(size().width(), size().height(), |
| 229 colorSpace())) { | 233 colorSpaceForSkImages())) { |
| 230 longjmp(JMPBUF(png), 1); | 234 longjmp(JMPBUF(png), 1); |
| 231 return; | 235 return; |
| 232 } | 236 } |
| 233 | 237 |
| 234 unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3; | 238 unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3; |
| 235 if (PNG_INTERLACE_ADAM7 == | 239 if (PNG_INTERLACE_ADAM7 == |
| 236 png_get_interlace_type(png, m_reader->infoPtr())) { | 240 png_get_interlace_type(png, m_reader->infoPtr())) { |
| 237 m_reader->createInterlaceBuffer(colorChannels * size().width() * | 241 m_reader->createInterlaceBuffer(colorChannels * size().width() * |
| 238 size().height()); | 242 size().height()); |
| 239 if (!m_reader->interlaceBuffer()) { | 243 if (!m_reader->interlaceBuffer()) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 // has failed. | 385 // has failed. |
| 382 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 386 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
| 383 setFailed(); | 387 setFailed(); |
| 384 | 388 |
| 385 // If decoding is done or failed, we don't need the PNGImageReader anymore. | 389 // If decoding is done or failed, we don't need the PNGImageReader anymore. |
| 386 if (isComplete(this) || failed()) | 390 if (isComplete(this) || failed()) |
| 387 m_reader.reset(); | 391 m_reader.reset(); |
| 388 } | 392 } |
| 389 | 393 |
| 390 } // namespace blink | 394 } // namespace blink |
| OLD | NEW |