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

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

Issue 1309393007: [poc] redecode Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: resetColorProfileForTesting rename Created 5 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
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 21 matching lines...) Expand all
32 * version of this file under the LGPL, indicate your decision by 32 * version of this file under the LGPL, indicate your decision by
33 * deletingthe provisions above and replace them with the notice and 33 * deletingthe provisions above and replace them with the notice and
34 * other provisions required by the MPL or the GPL, as the case may be. 34 * other provisions required by the MPL or the GPL, as the case may be.
35 * If you do not delete the provisions above, a recipient may use your 35 * If you do not delete the provisions above, a recipient may use your
36 * version of this file under any of the LGPL, the MPL or the GPL. 36 * version of this file under any of the LGPL, the MPL or the GPL.
37 */ 37 */
38 38
39 #include "config.h" 39 #include "config.h"
40 #include "platform/image-decoders/png/PNGImageDecoder.h" 40 #include "platform/image-decoders/png/PNGImageDecoder.h"
41 41
42 #include "platform/graphics/GraphicsScreen.h"
43
42 #include "png.h" 44 #include "png.h"
43 #if !defined(PNG_LIBPNG_VER_MAJOR) || !defined(PNG_LIBPNG_VER_MINOR) 45 #if !defined(PNG_LIBPNG_VER_MAJOR) || !defined(PNG_LIBPNG_VER_MINOR)
44 #error version error: compile against a versioned libpng. 46 #error version error: compile against a versioned libpng.
45 #endif 47 #endif
46 #if USE(QCMSLIB) 48 #if USE(QCMSLIB)
47 #include "qcms.h" 49 #include "qcms.h"
48 #endif 50 #endif
49 51
50 #if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MIN OR >= 4) 52 #if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MIN OR >= 4)
51 #define JMPBUF(png_ptr) png_jmpbuf(png_ptr) 53 #define JMPBUF(png_ptr) png_jmpbuf(png_ptr)
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); } 152 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si ze]); }
151 qcms_transform* colorTransform() const { return m_transform; } 153 qcms_transform* colorTransform() const { return m_transform; }
152 154
153 void clearColorTransform() 155 void clearColorTransform()
154 { 156 {
155 if (m_transform) 157 if (m_transform)
156 qcms_transform_release(m_transform); 158 qcms_transform_release(m_transform);
157 m_transform = 0; 159 m_transform = 0;
158 } 160 }
159 161
160 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha, b ool sRGB) 162 PassRefPtr<ColorSpaceProfile> createColorTransform(const ColorProfile& color Profile, bool hasAlpha, bool sRGB)
161 { 163 {
162 clearColorTransform(); 164 clearColorTransform();
163 165
166 fprintf(stderr, "PNG decoder %p createColorTransform ", m_decoder);
167 if (m_decoder->deviceProfile())
168 fprintf(stderr, ": device %p\n", m_decoder->deviceProfile().get());
169 else
170 fprintf(stderr, ": %p\n", nullptr);
171 fprintf(stderr, "image color profiles enabled: %d\n", imageColorProfiles Enabled());
172 fflush(stderr);
173
164 if (colorProfile.isEmpty() && !sRGB) 174 if (colorProfile.isEmpty() && !sRGB)
165 return; 175 return nullptr;
176
166 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); 177 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile();
178 if (m_decoder->deviceProfile())
179 deviceProfile = m_decoder->deviceProfile()->profile();
167 if (!deviceProfile) 180 if (!deviceProfile)
168 return; 181 return nullptr;
169 qcms_profile* inputProfile = 0; 182
183 qcms_profile* inputProfile = nullptr;
170 if (!colorProfile.isEmpty()) 184 if (!colorProfile.isEmpty())
171 inputProfile = qcms_profile_from_memory(colorProfile.data(), colorPr ofile.size()); 185 inputProfile = qcms_profile_from_memory(colorProfile.data(), colorPr ofile.size());
172 else 186 else
173 inputProfile = qcms_profile_sRGB(); 187 inputProfile = qcms_profile_sRGB();
174 if (!inputProfile) 188 if (!inputProfile)
175 return; 189 return nullptr;
190
191 fprintf(stderr, " from source profile [%s]", qcms_profile_get_descriptio n(inputProfile));
192 fprintf(stderr, " to [%s]\n", qcms_profile_get_description(deviceProfile ));
193 fflush(stderr);
194
195 // There is no need to create a color transform if the color profiles ma tch.
196 if (imageColorProfilesEnabled() && qcms_profile_match(inputProfile, devi ceProfile))
197 return ColorSpaceProfile::create(inputProfile);
198
176 // We currently only support color profiles for RGB and RGBA images. 199 // We currently only support color profiles for RGB and RGBA images.
177 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile)); 200 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile));
178 qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_ 8; 201 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. 202 // 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); 203 m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProf ile, dataFormat, QCMS_INTENT_PERCEPTUAL);
204 if (m_transform)
205 return ColorSpaceProfile::create(inputProfile);
206
181 qcms_profile_release(inputProfile); 207 qcms_profile_release(inputProfile);
208 return nullptr;
182 } 209 }
183 #endif 210 #endif
184 211
185 private: 212 private:
186 png_structp m_png; 213 png_structp m_png;
187 png_infop m_info; 214 png_infop m_info;
188 PNGImageDecoder* m_decoder; 215 PNGImageDecoder* m_decoder;
189 unsigned m_readOffset; 216 unsigned m_readOffset;
190 unsigned m_currentBufferSize; 217 unsigned m_currentBufferSize;
191 bool m_decodingSizeOnly; 218 bool m_decodingSizeOnly;
192 bool m_hasAlpha; 219 bool m_hasAlpha;
193 OwnPtr<png_byte[]> m_interlaceBuffer; 220 OwnPtr<png_byte[]> m_interlaceBuffer;
194 #if USE(QCMSLIB) 221 #if USE(QCMSLIB)
195 qcms_transform* m_transform; 222 qcms_transform* m_transform;
196 OwnPtr<png_byte[]> m_rowBuffer; 223 OwnPtr<png_byte[]> m_rowBuffer;
197 #endif 224 #endif
198 }; 225 };
199 226
200 PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOp tion colorOptions, size_t maxDecodedBytes, unsigned offset) 227 PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOp tion colorOptions, size_t maxDecodedBytes, unsigned offset)
201 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes) 228 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes)
202 , m_hasColorProfile(false) 229 , m_hasColorProfile(false)
203 , m_offset(offset) 230 , m_offset(offset)
204 { 231 {
232 fprintf(stderr, "PNG decoder %p created %s\n", this, !isMainThread() ? "impl -side-thread" : "");
205 } 233 }
206 234
207 PNGImageDecoder::~PNGImageDecoder() 235 PNGImageDecoder::~PNGImageDecoder()
208 { 236 {
237 fprintf(stderr, "PNG decoder %p ~PNGImageDecoder() %s\n", this, !isMainThrea d() ? "impl-side-thread" : "");
209 } 238 }
210 239
211 #if USE(QCMSLIB) 240 #if USE(QCMSLIB)
212 static void getColorProfile(png_structp png, png_infop info, ColorProfile& color Profile, bool& sRGB) 241 static void getColorProfile(png_structp png, png_infop info, ColorProfile& color Profile, bool& sRGB)
213 { 242 {
214 #ifdef PNG_iCCP_SUPPORTED 243 #ifdef PNG_iCCP_SUPPORTED
215 ASSERT(colorProfile.isEmpty()); 244 ASSERT(colorProfile.isEmpty());
216 if (png_get_valid(png, info, PNG_INFO_sRGB)) { 245 if (png_get_valid(png, info, PNG_INFO_sRGB)) {
217 sRGB = true; 246 sRGB = true;
218 return; 247 return;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 // We only support color profiles for color PALETTE and RGB[A] PNG. Supp orting 321 // 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 322 // 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 323 // 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 324 // 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 325 // the color profile or we'd need to decode into a gray-scale image buff er and
297 // hand that to CoreGraphics. 326 // hand that to CoreGraphics.
298 bool sRGB = false; 327 bool sRGB = false;
299 ColorProfile colorProfile; 328 ColorProfile colorProfile;
300 getColorProfile(png, info, colorProfile, sRGB); 329 getColorProfile(png, info, colorProfile, sRGB);
301 bool imageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCount; 330 bool imageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCount;
302 m_reader->createColorTransform(colorProfile, imageHasAlpha, sRGB); 331 RefPtr<ColorSpaceProfile> imageColorProfile = m_reader->createColorTrans form(colorProfile, imageHasAlpha, sRGB);
303 m_hasColorProfile = !!m_reader->colorTransform(); 332 m_hasColorProfile = !!imageColorProfile.get();
333 if (m_hasColorProfile && imageColorProfilesEnabled()) {
334 RELEASE_ASSERT(imageColorProfile->profile());
335 m_colorProfile = imageColorProfile;
336 }
304 } 337 }
305 #endif 338 #endif
306 339
307 if (!m_hasColorProfile) { 340 if (!m_hasColorProfile) {
308 // Deal with gamma and keep it under our control. 341 // Deal with gamma and keep it under our control.
309 const double inverseGamma = 0.45455; 342 const double inverseGamma = 0.45455;
310 const double defaultGamma = 2.2; 343 const double defaultGamma = 2.2;
311 double gamma; 344 double gamma;
312 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { 345 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) {
313 const double maxGamma = 21474.83; 346 const double maxGamma = 21474.83;
(...skipping 11 matching lines...) Expand all
325 if (interlaceType == PNG_INTERLACE_ADAM7) 358 if (interlaceType == PNG_INTERLACE_ADAM7)
326 png_set_interlace_handling(png); 359 png_set_interlace_handling(png);
327 360
328 // Update our info now. 361 // Update our info now.
329 png_read_update_info(png, info); 362 png_read_update_info(png, info);
330 channels = png_get_channels(png, info); 363 channels = png_get_channels(png, info);
331 ASSERT(channels == 3 || channels == 4); 364 ASSERT(channels == 3 || channels == 4);
332 365
333 m_reader->setHasAlpha(channels == 4); 366 m_reader->setHasAlpha(channels == 4);
334 367
368 fprintf(stderr, "PNG decoder %p headerAvailable %lux%lu %s\n", this, width, height, m_reader->decodingSizeOnly() ? "size-only-decode" : "");
369
335 if (m_reader->decodingSizeOnly()) { 370 if (m_reader->decodingSizeOnly()) {
336 // If we only needed the size, halt the reader. 371 // If we only needed the size, halt the reader.
337 #if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MIN OR >= 5) 372 #if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MIN OR >= 5)
338 // '0' argument to png_process_data_pause means: Do not cache unprocesse d data. 373 // '0' argument to png_process_data_pause means: Do not cache unprocesse d data.
339 m_reader->setReadOffset(m_reader->currentBufferSize() - png_process_data _pause(png, 0)); 374 m_reader->setReadOffset(m_reader->currentBufferSize() - png_process_data _pause(png, 0));
340 #else 375 #else
341 m_reader->setReadOffset(m_reader->currentBufferSize() - png->buffer_size ); 376 m_reader->setReadOffset(m_reader->currentBufferSize() - png->buffer_size );
342 png->buffer_size = 0; 377 png->buffer_size = 0;
343 #endif 378 #endif
344 } 379 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 png_bytep row = rowBuffer; 462 png_bytep row = rowBuffer;
428 463
429 if (png_bytep interlaceBuffer = m_reader->interlaceBuffer()) { 464 if (png_bytep interlaceBuffer = m_reader->interlaceBuffer()) {
430 unsigned colorChannels = hasAlpha ? 4 : 3; 465 unsigned colorChannels = hasAlpha ? 4 : 3;
431 row = interlaceBuffer + (rowIndex * colorChannels * size().width()); 466 row = interlaceBuffer + (rowIndex * colorChannels * size().width());
432 png_progressive_combine_row(m_reader->pngPtr(), row, rowBuffer); 467 png_progressive_combine_row(m_reader->pngPtr(), row, rowBuffer);
433 } 468 }
434 469
435 #if USE(QCMSLIB) 470 #if USE(QCMSLIB)
436 if (qcms_transform* transform = m_reader->colorTransform()) { 471 if (qcms_transform* transform = m_reader->colorTransform()) {
472 if (rowIndex < 3 || rowIndex >= (unsigned)size().height() - 1)
473 fprintf(stderr, "PNG decoder %p %dx%d color transform row %d\n", thi s, size().width(), size().height(), rowIndex);
437 qcms_transform_data(transform, row, m_reader->rowBuffer(), size().width( )); 474 qcms_transform_data(transform, row, m_reader->rowBuffer(), size().width( ));
438 row = m_reader->rowBuffer(); 475 row = m_reader->rowBuffer();
439 } 476 }
440 #endif 477 #endif
441 478
479 if (rowIndex < 3)
480 fprintf(stderr, "PNG decoder %p %dx%d row %d\n", this, size().width(), s ize().height(), rowIndex);
481 if (rowIndex >= (unsigned)size().height() - 1) {
482 fprintf(stderr, "PNG decoder %p %dx%d row %d\n", this, size().width(), s ize().height(), rowIndex);
483 fflush(stderr);
484 }
485
442 // Write the decoded row pixels to the frame buffer. The repetitive 486 // Write the decoded row pixels to the frame buffer. The repetitive
443 // form of the row write loops is for speed. 487 // form of the row write loops is for speed.
444 ImageFrame::PixelData* address = buffer.getAddr(0, y); 488 ImageFrame::PixelData* address = buffer.getAddr(0, y);
445 unsigned alphaMask = 255; 489 unsigned alphaMask = 255;
446 int width = size().width(); 490 int width = size().width();
447 491
448 png_bytep pixel = row; 492 png_bytep pixel = row;
449 if (hasAlpha) { 493 if (hasAlpha) {
450 if (buffer.premultiplyAlpha()) { 494 if (buffer.premultiplyAlpha()) {
451 for (int x = 0; x < width; ++x, pixel += 4) { 495 for (int x = 0; x < width; ++x, pixel += 4) {
(...skipping 13 matching lines...) Expand all
465 } 509 }
466 510
467 if (alphaMask != 255 && !buffer.hasAlpha()) 511 if (alphaMask != 255 && !buffer.hasAlpha())
468 buffer.setHasAlpha(true); 512 buffer.setHasAlpha(true);
469 513
470 buffer.setPixelsChanged(true); 514 buffer.setPixelsChanged(true);
471 } 515 }
472 516
473 void PNGImageDecoder::complete() 517 void PNGImageDecoder::complete()
474 { 518 {
519 fflush(stderr);
520
475 if (m_frameBufferCache.isEmpty()) 521 if (m_frameBufferCache.isEmpty())
476 return; 522 return;
477 523
478 m_frameBufferCache[0].setStatus(ImageFrame::FrameComplete); 524 m_frameBufferCache[0].setStatus(ImageFrame::FrameComplete);
479 } 525 }
480 526
481 inline bool isComplete(const PNGImageDecoder* decoder) 527 inline bool isComplete(const PNGImageDecoder* decoder)
482 { 528 {
483 return decoder->frameIsCompleteAtIndex(0); 529 return decoder->frameIsCompleteAtIndex(0);
484 } 530 }
(...skipping 10 matching lines...) Expand all
495 // has failed. 541 // has failed.
496 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) 542 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived())
497 setFailed(); 543 setFailed();
498 544
499 // 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.
500 if (isComplete(this) || failed()) 546 if (isComplete(this) || failed())
501 m_reader.clear(); 547 m_reader.clear();
502 } 548 }
503 549
504 } // namespace blink 550 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698