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

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: Adjust tables/mozilla/marvin/backgr_* Mac and Win. 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 | « LayoutTests/TestExpectations ('k') | 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); } 161 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); }
162 qcms_transform* colorTransform() const { return m_transform; } 162 qcms_transform* colorTransform() const { return m_transform; }
163 163
164 void clearColorTransform() 164 void clearColorTransform()
165 { 165 {
166 if (m_transform) 166 if (m_transform)
167 qcms_transform_release(m_transform); 167 qcms_transform_release(m_transform);
168 m_transform = 0; 168 m_transform = 0;
169 } 169 }
170 170
171 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha) 171 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha, b ool sRGB)
172 { 172 {
173 clearColorTransform(); 173 clearColorTransform();
174 174
175 if (colorProfile.isEmpty()) 175 if (colorProfile.isEmpty() && !sRGB)
176 return; 176 return;
177 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); 177 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile();
178 if (!deviceProfile) 178 if (!deviceProfile)
179 return; 179 return;
180 qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data( ), colorProfile.size()); 180 qcms_profile* inputProfile = 0;
181 if (!colorProfile.isEmpty())
182 inputProfile = qcms_profile_from_memory(colorProfile.data(), colorPr ofile.size());
183 else
184 inputProfile = qcms_profile_sRGB();
181 if (!inputProfile) 185 if (!inputProfile)
182 return; 186 return;
183 // We currently only support color profiles for RGB and RGBA images. 187 // We currently only support color profiles for RGB and RGBA images.
184 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile)); 188 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile));
185 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8; 189 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8;
186 // FIXME: Don't force perceptual intent if the image profile contains an intent. 190 // FIXME: Don't force perceptual intent if the image profile contains an intent.
187 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL); 191 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL);
188 qcms_profile_release(inputProfile); 192 qcms_profile_release(inputProfile);
189 } 193 }
190 #endif 194 #endif
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 PlatformInstrumentation::willDecodeImage("PNG"); 241 PlatformInstrumentation::willDecodeImage("PNG");
238 decode(false); 242 decode(false);
239 PlatformInstrumentation::didDecodeImage(); 243 PlatformInstrumentation::didDecodeImage();
240 } 244 }
241 245
242 frame.notifyBitmapIfPixelsChanged(); 246 frame.notifyBitmapIfPixelsChanged();
243 return &frame; 247 return &frame;
244 } 248 }
245 249
246 #if USE(QCMSLIB) 250 #if USE(QCMSLIB)
247 static void readColorProfile(png_structp png, png_infop info, ColorProfile& colo rProfile) 251 static void getColorProfile(png_structp png, png_infop info, ColorProfile& color Profile, bool& sRGB)
248 { 252 {
249 #ifdef PNG_iCCP_SUPPORTED 253 #ifdef PNG_iCCP_SUPPORTED
254 ASSERT(colorProfile.isEmpty());
255 if (png_get_valid(png, info, PNG_INFO_sRGB)) {
256 sRGB = true;
257 return;
258 }
259
250 char* profileName; 260 char* profileName;
251 int compressionType; 261 int compressionType;
252 #if (PNG_LIBPNG_VER < 10500) 262 #if (PNG_LIBPNG_VER < 10500)
253 png_charp profile; 263 png_charp profile;
254 #else 264 #else
255 png_bytep profile; 265 png_bytep profile;
256 #endif 266 #endif
257 png_uint_32 profileLength; 267 png_uint_32 profileLength;
258 if (!png_get_iCCP(png, info, &profileName, &compressionType, &profile, &prof ileLength)) 268 if (!png_get_iCCP(png, info, &profileName, &compressionType, &profile, &prof ileLength))
259 return; 269 return;
260 270
261 // Only accept RGB color profiles from input class devices. 271 // Only accept RGB color profiles from input class devices.
262 bool ignoreProfile = false; 272 bool ignoreProfile = false;
263 char* profileData = reinterpret_cast<char*>(profile); 273 char* profileData = reinterpret_cast<char*>(profile);
264 if (profileLength < ImageDecoder::iccColorProfileHeaderLength) 274 if (profileLength < ImageDecoder::iccColorProfileHeaderLength)
265 ignoreProfile = true; 275 ignoreProfile = true;
266 else if (!ImageDecoder::rgbColorProfile(profileData, profileLength)) 276 else if (!ImageDecoder::rgbColorProfile(profileData, profileLength))
267 ignoreProfile = true; 277 ignoreProfile = true;
268 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileLength)) 278 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileLength))
269 ignoreProfile = true; 279 ignoreProfile = true;
270 280
271 ASSERT(colorProfile.isEmpty());
272 if (!ignoreProfile) 281 if (!ignoreProfile)
273 colorProfile.append(profileData, profileLength); 282 colorProfile.append(profileData, profileLength);
274 #endif 283 #endif
275 } 284 }
276 #endif 285 #endif
277 286
278 void PNGImageDecoder::headerAvailable() 287 void PNGImageDecoder::headerAvailable()
279 { 288 {
280 png_structp png = m_reader->pngPtr(); 289 png_structp png = m_reader->pngPtr();
281 png_infop info = m_reader->infoPtr(); 290 png_infop info = m_reader->infoPtr();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 png_set_gray_to_rgb(png); 327 png_set_gray_to_rgb(png);
319 328
320 #if USE(QCMSLIB) 329 #if USE(QCMSLIB)
321 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) { 330 if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) {
322 // We only support color profiles for color PALETTE and RGB[A] PNG. Supp orting 331 // We only support color profiles for color PALETTE and RGB[A] PNG. Supp orting
323 // color profiles for gray-scale images is slightly tricky, at least usi ng the 332 // color profiles for gray-scale images is slightly tricky, at least usi ng the
324 // CoreGraphics ICC library, because we expand gray-scale images to RGB but we 333 // CoreGraphics ICC library, because we expand gray-scale images to RGB but we
325 // do not similarly transform the color profile. We'd either need to tra nsform 334 // do not similarly transform the color profile. We'd either need to tra nsform
326 // the color profile or we'd need to decode into a gray-scale image buff er and 335 // the color profile or we'd need to decode into a gray-scale image buff er and
327 // hand that to CoreGraphics. 336 // hand that to CoreGraphics.
337 bool sRGB = false;
328 ColorProfile colorProfile; 338 ColorProfile colorProfile;
329 readColorProfile(png, info, colorProfile); 339 getColorProfile(png, info, colorProfile, sRGB);
330 bool decodedImageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCo unt; 340 bool imageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCount;
331 m_reader->createColorTransform(colorProfile, decodedImageHasAlpha); 341 m_reader->createColorTransform(colorProfile, imageHasAlpha, sRGB);
332 m_hasColorProfile = !!m_reader->colorTransform(); 342 m_hasColorProfile = !!m_reader->colorTransform();
333 } 343 }
334 #endif 344 #endif
335 345
336 if (!m_hasColorProfile) { 346 if (!m_hasColorProfile) {
337 // Deal with gamma and keep it under our control. 347 // Deal with gamma and keep it under our control.
338 const double inverseGamma = 0.45455; 348 const double inverseGamma = 0.45455;
339 const double defaultGamma = 2.2; 349 const double defaultGamma = 2.2;
340 double gamma; 350 double gamma;
341 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { 351 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // has failed. 541 // has failed.
532 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) 542 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived())
533 setFailed(); 543 setFailed();
534 544
535 // If decoding is done or failed, we don't need the PNGImageReader anymore. 545 // If decoding is done or failed, we don't need the PNGImageReader anymore.
536 if (isComplete() || failed()) 546 if (isComplete() || failed())
537 m_reader.clear(); 547 m_reader.clear();
538 } 548 }
539 549
540 } // namespace blink 550 } // namespace blink
OLDNEW
« no previous file with comments | « LayoutTests/TestExpectations ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698