Chromium Code Reviews| 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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); } | 150 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); } |
| 151 qcms_transform* colorTransform() const { return m_transform; } | 151 qcms_transform* colorTransform() const { return m_transform; } |
| 152 | 152 |
| 153 void clearColorTransform() | 153 void clearColorTransform() |
| 154 { | 154 { |
| 155 if (m_transform) | 155 if (m_transform) |
| 156 qcms_transform_release(m_transform); | 156 qcms_transform_release(m_transform); |
| 157 m_transform = 0; | 157 m_transform = 0; |
| 158 } | 158 } |
| 159 | 159 |
| 160 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha, b ool sRGB) | 160 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha, b ool sRGB, ColorProfileStatus* status) |
| 161 { | 161 { |
| 162 clearColorTransform(); | 162 clearColorTransform(); |
| 163 | 163 |
| 164 if (colorProfile.isEmpty() && !sRGB) | 164 if (colorProfile.isEmpty() && !sRGB) |
| 165 return; | 165 return; |
| 166 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); | |
| 167 if (!deviceProfile) | |
| 168 return; | |
| 169 qcms_profile* inputProfile = 0; | 166 qcms_profile* inputProfile = 0; |
| 170 if (!colorProfile.isEmpty()) | 167 if (!colorProfile.isEmpty()) |
| 171 inputProfile = qcms_profile_from_memory(colorProfile.data(), colorPr ofile.size()); | 168 inputProfile = qcms_profile_from_memory(colorProfile.data(), colorPr ofile.size()); |
| 172 else | 169 else |
| 173 inputProfile = qcms_profile_sRGB(); | 170 inputProfile = qcms_profile_sRGB(); |
| 174 if (!inputProfile) | 171 if (!inputProfile) { |
| 172 *status = ColorProfileFailedDecode; | |
|
Noel Gordon
2015/12/23 15:28:48
ColorProfileFailedDecode -> ColorProfileInvalidCon
| |
| 173 return; | |
| 174 } | |
| 175 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); | |
| 176 if (!deviceProfile) | |
| 175 return; | 177 return; |
| 176 // We currently only support color profiles for RGB and RGBA images. | 178 // We currently only support color profiles for RGB and RGBA images. |
| 177 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile)); | 179 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile)); |
| 178 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8; | 180 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8; |
| 179 // FIXME: Don't force perceptual intent if the image profile contains an intent. | 181 // FIXME: Don't force perceptual intent if the image profile contains an intent. |
| 180 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL); | 182 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL); |
| 181 qcms_profile_release(inputProfile); | 183 qcms_profile_release(inputProfile); |
| 182 } | 184 } |
| 183 #endif | 185 #endif |
| 184 | 186 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 202 , m_hasColorProfile(false) | 204 , m_hasColorProfile(false) |
| 203 , m_offset(offset) | 205 , m_offset(offset) |
| 204 { | 206 { |
| 205 } | 207 } |
| 206 | 208 |
| 207 PNGImageDecoder::~PNGImageDecoder() | 209 PNGImageDecoder::~PNGImageDecoder() |
| 208 { | 210 { |
| 209 } | 211 } |
| 210 | 212 |
| 211 #if USE(QCMSLIB) | 213 #if USE(QCMSLIB) |
| 212 static void getColorProfile(png_structp png, png_infop info, ColorProfile& color Profile, bool& sRGB) | 214 static void getColorProfile(png_structp png, png_infop info, ColorProfile& color Profile, bool& sRGB, ColorProfileStatus& status) |
| 213 { | 215 { |
| 214 #ifdef PNG_iCCP_SUPPORTED | 216 #ifdef PNG_iCCP_SUPPORTED |
| 215 ASSERT(colorProfile.isEmpty()); | 217 ASSERT(colorProfile.isEmpty()); |
| 216 if (png_get_valid(png, info, PNG_INFO_sRGB)) { | 218 if (png_get_valid(png, info, PNG_INFO_sRGB)) { |
| 217 sRGB = true; | 219 sRGB = true; |
| 220 status = ColorProfileSuccess_PNGsRGB; | |
|
Noel Gordon
2015/12/23 15:28:48
ColorProfileSuccess_PNGsRGB -> ColorProfileSuccess
| |
| 218 return; | 221 return; |
| 219 } | 222 } |
| 220 | 223 |
| 221 char* profileName; | 224 char* profileName; |
| 222 int compressionType; | 225 int compressionType; |
| 223 #if (PNG_LIBPNG_VER < 10500) | 226 #if (PNG_LIBPNG_VER < 10500) |
| 224 png_charp profile; | 227 png_charp profile; |
| 225 #else | 228 #else |
| 226 png_bytep profile; | 229 png_bytep profile; |
| 227 #endif | 230 #endif |
| 228 png_uint_32 profileLength; | 231 png_uint_32 profileLength; |
| 229 if (!png_get_iCCP(png, info, &profileName, &compressionType, &profile, &prof ileLength)) | 232 if (!png_get_iCCP(png, info, &profileName, &compressionType, &profile, &prof ileLength)) { |
| 233 status = ColorProfileNone; | |
|
Noel Gordon
2015/12/23 15:28:48
ColorProfileNone -> ColorProfileEmpty
| |
| 230 return; | 234 return; |
| 235 } | |
| 231 | 236 |
| 232 // Only accept RGB color profiles from input class devices. | 237 // Only accept RGB color profiles from input class devices. |
| 233 bool ignoreProfile = false; | 238 ASSERT(status == ColorProfileSuccess); |
| 234 char* profileData = reinterpret_cast<char*>(profile); | 239 char* profileData = reinterpret_cast<char*>(profile); |
|
Noel Gordon
2015/12/23 15:28:48
239-247, same as per the JPEG decoder. Lump failu
| |
| 235 if (profileLength < ImageDecoder::iccColorProfileHeaderLength) | 240 if (profileLength < ImageDecoder::iccColorProfileHeaderLength) |
| 236 ignoreProfile = true; | 241 status = ColorProfileIsCorrupted; |
| 242 else if (ImageDecoder::isICCv4(profileData, profileLength)) | |
| 243 status = ColorProfileIsV4; | |
| 237 else if (!ImageDecoder::rgbColorProfile(profileData, profileLength)) | 244 else if (!ImageDecoder::rgbColorProfile(profileData, profileLength)) |
| 238 ignoreProfile = true; | 245 status = ColorProfileIsNotRGB; |
| 239 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileLength)) | 246 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileLength)) |
| 240 ignoreProfile = true; | 247 status = ColorProfileIsNotAnInputProfile; |
| 241 | 248 |
| 242 if (!ignoreProfile) | 249 if (status == ColorProfileSuccess) |
| 243 colorProfile.append(profileData, profileLength); | 250 colorProfile.append(profileData, profileLength); |
| 244 #endif | 251 #endif |
| 245 } | 252 } |
| 246 #endif | 253 #endif |
| 247 | 254 |
| 248 void PNGImageDecoder::headerAvailable() | 255 void PNGImageDecoder::headerAvailable() |
| 249 { | 256 { |
| 250 png_structp png = m_reader->pngPtr(); | 257 png_structp png = m_reader->pngPtr(); |
| 251 png_infop info = m_reader->infoPtr(); | 258 png_infop info = m_reader->infoPtr(); |
| 252 png_uint_32 width = png_get_image_width(png, info); | 259 png_uint_32 width = png_get_image_width(png, info); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 #if USE(QCMSLIB) | 297 #if USE(QCMSLIB) |
| 291 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) { | 298 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) { |
| 292 // We only support color profiles for color PALETTE and RGB[A] PNG. Supp orting | 299 // We only support color profiles for color PALETTE and RGB[A] PNG. Supp orting |
| 293 // color profiles for gray-scale images is slightly tricky, at least usi ng the | 300 // color profiles for gray-scale images is slightly tricky, at least usi ng the |
| 294 // CoreGraphics ICC library, because we expand gray-scale images to RGB but we | 301 // CoreGraphics ICC library, because we expand gray-scale images to RGB but we |
| 295 // do not similarly transform the color profile. We'd either need to tra nsform | 302 // do not similarly transform the color profile. We'd either need to tra nsform |
| 296 // the color profile or we'd need to decode into a gray-scale image buff er and | 303 // the color profile or we'd need to decode into a gray-scale image buff er and |
| 297 // hand that to CoreGraphics. | 304 // hand that to CoreGraphics. |
| 298 bool sRGB = false; | 305 bool sRGB = false; |
| 299 ColorProfile colorProfile; | 306 ColorProfile colorProfile; |
| 300 getColorProfile(png, info, colorProfile, sRGB); | 307 ColorProfileStatus status = ColorProfileSuccess; |
| 308 getColorProfile(png, info, colorProfile, sRGB, status); | |
| 301 bool imageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCount; | 309 bool imageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCount; |
| 302 m_reader->createColorTransform(colorProfile, imageHasAlpha, sRGB); | 310 m_reader->createColorTransform(colorProfile, imageHasAlpha, sRGB, &statu s); |
| 311 Platform::current()->histogramEnumeration("ColorManagement.ColorProfileS tatus.PNG", status, ColorProfileStatus::ValueCount); | |
| 303 m_hasColorProfile = !!m_reader->colorTransform(); | 312 m_hasColorProfile = !!m_reader->colorTransform(); |
| 304 } | 313 } |
| 305 #endif | 314 #endif |
| 306 | 315 |
| 307 if (!m_hasColorProfile) { | 316 if (!m_hasColorProfile) { |
| 308 // Deal with gamma and keep it under our control. | 317 // Deal with gamma and keep it under our control. |
| 309 const double inverseGamma = 0.45455; | 318 const double inverseGamma = 0.45455; |
| 310 const double defaultGamma = 2.2; | 319 const double defaultGamma = 2.2; |
| 311 double gamma; | 320 double gamma; |
| 312 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { | 321 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 // has failed. | 504 // has failed. |
| 496 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 505 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
| 497 setFailed(); | 506 setFailed(); |
| 498 | 507 |
| 499 // If decoding is done or failed, we don't need the PNGImageReader anymore. | 508 // If decoding is done or failed, we don't need the PNGImageReader anymore. |
| 500 if (isComplete(this) || failed()) | 509 if (isComplete(this) || failed()) |
| 501 m_reader.clear(); | 510 m_reader.clear(); |
| 502 } | 511 } |
| 503 | 512 |
| 504 } // namespace blink | 513 } // namespace blink |
| OLD | NEW |