Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: Source/platform/image-decoders/png/PNGImageDecoder.cpp

Issue 774103002: Color-correct PNG images that have an sRGB chunk (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Initial pass, test failures. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); } 182 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); }
183 qcms_transform* colorTransform() const { return m_transform; } 183 qcms_transform* colorTransform() const { return m_transform; }
184 184
185 void clearColorTransform() 185 void clearColorTransform()
186 { 186 {
187 if (m_transform) 187 if (m_transform)
188 qcms_transform_release(m_transform); 188 qcms_transform_release(m_transform);
189 m_transform = 0; 189 m_transform = 0;
190 } 190 }
191 191
192 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha) 192 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha, b ool sRGB)
193 { 193 {
194 clearColorTransform(); 194 clearColorTransform();
195 195
196 if (colorProfile.isEmpty()) 196 if (colorProfile.isEmpty() && !sRGB)
197 return; 197 return;
198 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); 198 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile();
199 if (!deviceProfile) 199 if (!deviceProfile)
200 return; 200 return;
201 qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data( ), colorProfile.size()); 201 qcms_profile* inputProfile = 0;
202 if (!colorProfile.isEmpty())
Ken Russell (switch to Gerrit) 2014/12/03 23:50:02 I think this should read "if (sRGB) { ... } else {
Noel Gordon 2014/12/05 04:12:43 I think the spec says that a PNG should have an sR
Ken Russell (switch to Gerrit) 2014/12/05 19:24:53 I see. Thanks for clarifying that. This looks fine
203 inputProfile = qcms_profile_from_memory(colorProfile.data(), colorPr ofile.size());
204 else if (sRGB)
205 inputProfile = qcms_profile_sRGB();
202 if (!inputProfile) 206 if (!inputProfile)
203 return; 207 return;
204 // We currently only support color profiles for RGB and RGBA images. 208 // We currently only support color profiles for RGB and RGBA images.
205 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile)); 209 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile));
206 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8; 210 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8;
207 // FIXME: Don't force perceptual intent if the image profile contains an intent. 211 // FIXME: Don't force perceptual intent if the image profile contains an intent.
208 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL); 212 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL);
209 qcms_profile_release(inputProfile); 213 qcms_profile_release(inputProfile);
210 } 214 }
211 #endif 215 #endif
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 273
270 bool PNGImageDecoder::setFailed() 274 bool PNGImageDecoder::setFailed()
271 { 275 {
272 if (m_doNothingOnFailure) 276 if (m_doNothingOnFailure)
273 return false; 277 return false;
274 m_reader.clear(); 278 m_reader.clear();
275 return ImageDecoder::setFailed(); 279 return ImageDecoder::setFailed();
276 } 280 }
277 281
278 #if USE(QCMSLIB) 282 #if USE(QCMSLIB)
279 static void readColorProfile(png_structp png, png_infop info, ColorProfile& colo rProfile) 283 static void readColorProfile(png_structp png, png_infop info, ColorProfile& colo rProfile, bool& sRGB)
Sami 2014/12/04 12:51:23 Generally output parameters should be pointers rat
Noel Gordon 2014/12/05 04:12:43 Blink style is that output parameters are referenc
Sami 2014/12/05 11:50:43 Ah, sorry, I've spent too much time in Chromium la
280 { 284 {
281 #ifdef PNG_iCCP_SUPPORTED 285 #ifdef PNG_iCCP_SUPPORTED
282 char* profileName; 286 char* profileName;
283 int compressionType; 287 int compressionType;
284 #if (PNG_LIBPNG_VER < 10500) 288 #if (PNG_LIBPNG_VER < 10500)
285 png_charp profile; 289 png_charp profile;
286 #else 290 #else
287 png_bytep profile; 291 png_bytep profile;
288 #endif 292 #endif
289 png_uint_32 profileLength; 293 png_uint_32 profileLength;
290 if (!png_get_iCCP(png, info, &profileName, &compressionType, &profile, &prof ileLength)) 294 if (!png_get_iCCP(png, info, &profileName, &compressionType, &profile, &prof ileLength)) {
295 ASSERT(!png_get_valid(png, info, PNG_INFO_iCCP));
296 // No color profile: check the sRGB chunk.
297 // FIXME: but only if no cHRM or gAMA chunk was seen?
298 // if (info->chroma_or_gamma & (PNG_INFO_cHRM | PNG_INFO_gAMA))
299 // return;
300 sRGB = png_get_valid(png, info, PNG_INFO_sRGB);
Sami 2014/12/04 12:51:23 Could we instead encode this information in |color
Noel Gordon 2014/12/05 04:12:43 Not easily Sami. ColorProfile is not a class, it's
Sami 2014/12/05 11:50:43 Right, I was thinking it was a string identifier b
291 return; 301 return;
302 }
292 303
293 // Only accept RGB color profiles from input class devices. 304 // Only accept RGB color profiles from input class devices.
294 bool ignoreProfile = false; 305 bool ignoreProfile = false;
295 char* profileData = reinterpret_cast<char*>(profile); 306 char* profileData = reinterpret_cast<char*>(profile);
296 if (profileLength < ImageDecoder::iccColorProfileHeaderLength) 307 if (profileLength < ImageDecoder::iccColorProfileHeaderLength)
297 ignoreProfile = true; 308 ignoreProfile = true;
298 else if (!ImageDecoder::rgbColorProfile(profileData, profileLength)) 309 else if (!ImageDecoder::rgbColorProfile(profileData, profileLength))
299 ignoreProfile = true; 310 ignoreProfile = true;
300 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileLength)) 311 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileLength))
301 ignoreProfile = true; 312 ignoreProfile = true;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 png_set_gray_to_rgb(png); 367 png_set_gray_to_rgb(png);
357 368
358 #if USE(QCMSLIB) 369 #if USE(QCMSLIB)
359 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) { 370 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) {
360 // We only support color profiles for color PALETTE and RGB[A] PNG. Supp orting 371 // We only support color profiles for color PALETTE and RGB[A] PNG. Supp orting
361 // color profiles for gray-scale images is slightly tricky, at least usi ng the 372 // color profiles for gray-scale images is slightly tricky, at least usi ng the
362 // CoreGraphics ICC library, because we expand gray-scale images to RGB but we 373 // CoreGraphics ICC library, because we expand gray-scale images to RGB but we
363 // do not similarly transform the color profile. We'd either need to tra nsform 374 // do not similarly transform the color profile. We'd either need to tra nsform
364 // the color profile or we'd need to decode into a gray-scale image buff er and 375 // the color profile or we'd need to decode into a gray-scale image buff er and
365 // hand that to CoreGraphics. 376 // hand that to CoreGraphics.
377 bool sRGB = false;
366 ColorProfile colorProfile; 378 ColorProfile colorProfile;
367 readColorProfile(png, info, colorProfile); 379 readColorProfile(png, info, colorProfile, sRGB);
368 bool decodedImageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCo unt; 380 bool decodedImageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCo unt;
369 m_reader->createColorTransform(colorProfile, decodedImageHasAlpha); 381 m_reader->createColorTransform(colorProfile, decodedImageHasAlpha, sRGB) ;
370 m_hasColorProfile = !!m_reader->colorTransform(); 382 m_hasColorProfile = !!m_reader->colorTransform();
371 } 383 }
372 #endif 384 #endif
373 385
374 if (!m_hasColorProfile) { 386 if (!m_hasColorProfile) {
375 // Deal with gamma and keep it under our control. 387 // Deal with gamma and keep it under our control.
376 double gamma; 388 double gamma;
377 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { 389 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) {
378 if ((gamma <= 0.0) || (gamma > cMaxGamma)) { 390 if ((gamma <= 0.0) || (gamma > cMaxGamma)) {
379 gamma = cInverseGamma; 391 gamma = cInverseGamma;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 // has failed. 564 // has failed.
553 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) 565 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived())
554 setFailed(); 566 setFailed();
555 // If we're done decoding the image, we don't need the PNGImageReader 567 // If we're done decoding the image, we don't need the PNGImageReader
556 // anymore. (If we failed, |m_reader| has already been cleared.) 568 // anymore. (If we failed, |m_reader| has already been cleared.)
557 else if (isComplete()) 569 else if (isComplete())
558 m_reader.clear(); 570 m_reader.clear();
559 } 571 }
560 572
561 } // namespace blink 573 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698