 Chromium Code Reviews
 Chromium Code Reviews Issue 2454123002:
  Refactor image decoders to use 'colorSpace' instead of 'colorProfile'  (Closed)
    
  
    Issue 2454123002:
  Refactor image decoders to use 'colorSpace' instead of 'colorProfile'  (Closed) 
  | 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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 png_set_expand(png); | 201 png_set_expand(png); | 
| 202 } | 202 } | 
| 203 | 203 | 
| 204 if (bitDepth == 16) | 204 if (bitDepth == 16) | 
| 205 png_set_strip_16(png); | 205 png_set_strip_16(png); | 
| 206 | 206 | 
| 207 if (colorType == PNG_COLOR_TYPE_GRAY || | 207 if (colorType == PNG_COLOR_TYPE_GRAY || | 
| 208 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) | 208 colorType == PNG_COLOR_TYPE_GRAY_ALPHA) | 
| 209 png_set_gray_to_rgb(png); | 209 png_set_gray_to_rgb(png); | 
| 210 | 210 | 
| 211 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) { | 211 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreColorSpace) { | 
| 212 // We only support color profiles for color PALETTE and RGB[A] PNG. | 212 // We only support color profiles for color PALETTE and RGB[A] PNG. | 
| 213 // Supporting color profiles for gray-scale images is slightly tricky, at | 213 // Supporting color profiles for gray-scale images is slightly tricky, at | 
| 214 // least using the CoreGraphics ICC library, because we expand gray-scale | 214 // least using the CoreGraphics ICC library, because we expand gray-scale | 
| 215 // images to RGB but we do not similarly transform the color profile. We'd | 215 // images to RGB but we do not similarly transform the color profile. We'd | 
| 216 // either need to transform the color profile or we'd need to decode into a | 216 // either need to transform the color profile or we'd need to decode into a | 
| 217 // gray-scale image buffer and hand that to CoreGraphics. | 217 // gray-scale image buffer and hand that to CoreGraphics. | 
| 218 #ifdef PNG_iCCP_SUPPORTED | 218 #ifdef PNG_iCCP_SUPPORTED | 
| 219 if (png_get_valid(png, info, PNG_INFO_sRGB)) { | 219 if (png_get_valid(png, info, PNG_INFO_sRGB)) { | 
| 220 setColorSpaceAndComputeTransform(nullptr, 0, true /* useSRGB */); | 220 setColorSpaceAndComputeTransform( | 
| 221 SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)); | |
| 221 } else { | 222 } else { | 
| 222 char* profileName = nullptr; | 223 char* profileName = nullptr; | 
| 223 int compressionType = 0; | 224 int compressionType = 0; | 
| 224 #if (PNG_LIBPNG_VER < 10500) | 225 #if (PNG_LIBPNG_VER < 10500) | 
| 225 png_charp profile = nullptr; | 226 png_charp profile = nullptr; | 
| 226 #else | 227 #else | 
| 227 png_bytep profile = nullptr; | 228 png_bytep profile = nullptr; | 
| 228 #endif | 229 #endif | 
| 229 png_uint_32 profileLength = 0; | 230 png_uint_32 profileLength = 0; | 
| 230 if (png_get_iCCP(png, info, &profileName, &compressionType, &profile, | 231 if (png_get_iCCP(png, info, &profileName, &compressionType, &profile, | 
| 231 &profileLength)) { | 232 &profileLength)) { | 
| 232 setColorSpaceAndComputeTransform(reinterpret_cast<char*>(profile), | 233 setColorSpaceAndComputeTransform(reinterpret_cast<char*>(profile), | 
| 233 profileLength, false /* useSRGB */); | 234 profileLength); | 
| 234 } | 235 } | 
| 235 } | 236 } | 
| 236 #endif // PNG_iCCP_SUPPORTED | 237 #endif // PNG_iCCP_SUPPORTED | 
| 237 } | 238 } | 
| 238 | 239 | 
| 239 if (!hasColorProfile()) { | 240 if (!hasColorSpace()) { | 
| 240 // TODO (msarett): | 241 // TODO (msarett): | 
| 
msarett
2016/10/27 15:43:22
I plan to follow up with this...
 | |
| 241 // Applying the transfer function (gamma) should be handled by | 242 // Applying the transfer function (gamma) should be handled by | 
| 242 // SkColorSpaceXform. Here we always convert to a transfer function that | 243 // SkColorSpaceXform. Here we always convert to a transfer function that | 
| 243 // is a 2.2 exponential. This is a little strange given that the dst | 244 // is a 2.2 exponential. This is a little strange given that the dst | 
| 244 // transfer function is not necessarily a 2.2 exponential. | 245 // transfer function is not necessarily a 2.2 exponential. | 
| 245 // TODO (msarett): | 246 // TODO (msarett): | 
| 246 // Often, PNGs that specify their transfer function with the gAMA tag will | 247 // Often, PNGs that specify their transfer function with the gAMA tag will | 
| 247 // also specify their gamut with the cHRM tag. We should read this tag | 248 // also specify their gamut with the cHRM tag. We should read this tag | 
| 248 // and do a full color space transformation if it is present. | 249 // and do a full color space transformation if it is present. | 
| 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 (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { | 253 if (!m_ignoreColorSpace && 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 } | 
| (...skipping 26 matching lines...) Expand all Loading... | |
| 289 void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, | 290 void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, | 
| 290 unsigned rowIndex, | 291 unsigned rowIndex, | 
| 291 int) { | 292 int) { | 
| 292 if (m_frameBufferCache.isEmpty()) | 293 if (m_frameBufferCache.isEmpty()) | 
| 293 return; | 294 return; | 
| 294 | 295 | 
| 295 // Initialize the framebuffer if needed. | 296 // Initialize the framebuffer if needed. | 
| 296 ImageFrame& buffer = m_frameBufferCache[0]; | 297 ImageFrame& buffer = m_frameBufferCache[0]; | 
| 297 if (buffer.getStatus() == ImageFrame::FrameEmpty) { | 298 if (buffer.getStatus() == ImageFrame::FrameEmpty) { | 
| 298 png_structp png = m_reader->pngPtr(); | 299 png_structp png = m_reader->pngPtr(); | 
| 299 if (!buffer.setSizeAndColorProfile(size().width(), size().height(), | 300 if (!buffer.setSizeAndColorSpace(size().width(), size().height(), | 
| 300 colorProfile())) { | 301 colorSpace())) { | 
| 301 longjmp(JMPBUF(png), 1); | 302 longjmp(JMPBUF(png), 1); | 
| 302 return; | 303 return; | 
| 303 } | 304 } | 
| 304 | 305 | 
| 305 unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3; | 306 unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3; | 
| 306 if (PNG_INTERLACE_ADAM7 == | 307 if (PNG_INTERLACE_ADAM7 == | 
| 307 png_get_interlace_type(png, m_reader->infoPtr())) { | 308 png_get_interlace_type(png, m_reader->infoPtr())) { | 
| 308 m_reader->createInterlaceBuffer(colorChannels * size().width() * | 309 m_reader->createInterlaceBuffer(colorChannels * size().width() * | 
| 309 size().height()); | 310 size().height()); | 
| 310 if (!m_reader->interlaceBuffer()) { | 311 if (!m_reader->interlaceBuffer()) { | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 452 // has failed. | 453 // has failed. | 
| 453 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 454 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 
| 454 setFailed(); | 455 setFailed(); | 
| 455 | 456 | 
| 456 // If decoding is done or failed, we don't need the PNGImageReader anymore. | 457 // If decoding is done or failed, we don't need the PNGImageReader anymore. | 
| 457 if (isComplete(this) || failed()) | 458 if (isComplete(this) || failed()) | 
| 458 m_reader.reset(); | 459 m_reader.reset(); | 
| 459 } | 460 } | 
| 460 | 461 | 
| 461 } // namespace blink | 462 } // namespace blink | 
| OLD | NEW |