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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 { | 122 { |
123 close(); | 123 close(); |
124 } | 124 } |
125 | 125 |
126 void close() | 126 void close() |
127 { | 127 { |
128 if (m_png && m_info) | 128 if (m_png && m_info) |
129 // This will zero the pointers. | 129 // This will zero the pointers. |
130 png_destroy_read_struct(&m_png, &m_info, 0); | 130 png_destroy_read_struct(&m_png, &m_info, 0); |
131 #if USE(QCMSLIB) | 131 #if USE(QCMSLIB) |
132 if (m_transform) | 132 clearColorTransform(); |
133 qcms_transform_release(m_transform); | |
134 m_transform = 0; | |
135 #endif | 133 #endif |
136 delete[] m_interlaceBuffer; | 134 delete[] m_interlaceBuffer; |
137 m_interlaceBuffer = 0; | 135 m_interlaceBuffer = 0; |
138 m_readOffset = 0; | 136 m_readOffset = 0; |
139 } | 137 } |
140 | 138 |
141 bool decode(const SharedBuffer& data, bool sizeOnly) | 139 bool decode(const SharedBuffer& data, bool sizeOnly) |
142 { | 140 { |
143 m_decodingSizeOnly = sizeOnly; | 141 m_decodingSizeOnly = sizeOnly; |
144 PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progres
sive_ptr(m_png)); | 142 PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progres
sive_ptr(m_png)); |
(...skipping 25 matching lines...) Expand all Loading... |
170 void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; } | 168 void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; } |
171 bool hasAlpha() const { return m_hasAlpha; } | 169 bool hasAlpha() const { return m_hasAlpha; } |
172 | 170 |
173 png_bytep interlaceBuffer() const { return m_interlaceBuffer; } | 171 png_bytep interlaceBuffer() const { return m_interlaceBuffer; } |
174 void createInterlaceBuffer(int size) { m_interlaceBuffer = new png_byte[size
]; } | 172 void createInterlaceBuffer(int size) { m_interlaceBuffer = new png_byte[size
]; } |
175 #if USE(QCMSLIB) | 173 #if USE(QCMSLIB) |
176 png_bytep rowBuffer() const { return m_rowBuffer.get(); } | 174 png_bytep rowBuffer() const { return m_rowBuffer.get(); } |
177 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si
ze]); } | 175 void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[si
ze]); } |
178 qcms_transform* colorTransform() const { return m_transform; } | 176 qcms_transform* colorTransform() const { return m_transform; } |
179 | 177 |
180 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha) | 178 void clearColorTransform() |
181 { | 179 { |
182 if (m_transform) | 180 if (m_transform) |
183 qcms_transform_release(m_transform); | 181 qcms_transform_release(m_transform); |
184 m_transform = 0; | 182 m_transform = 0; |
| 183 } |
185 | 184 |
| 185 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha) |
| 186 { |
| 187 clearColorTransform(); |
186 if (colorProfile.isEmpty()) | 188 if (colorProfile.isEmpty()) |
187 return; | 189 return; |
188 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); | 190 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); |
189 if (!deviceProfile) | 191 if (!deviceProfile) |
190 return; | 192 return; |
191 qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data(
), colorProfile.size()); | 193 qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data(
), colorProfile.size()); |
192 if (!inputProfile) | 194 if (!inputProfile) |
193 return; | 195 return; |
194 // We currently only support color profiles for RGB and RGBA images. | 196 // We currently only support color profiles for RGB and RGBA images. |
195 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile)); | 197 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 } | 259 } |
258 | 260 |
259 bool PNGImageDecoder::setFailed() | 261 bool PNGImageDecoder::setFailed() |
260 { | 262 { |
261 if (m_doNothingOnFailure) | 263 if (m_doNothingOnFailure) |
262 return false; | 264 return false; |
263 m_reader.clear(); | 265 m_reader.clear(); |
264 return ImageDecoder::setFailed(); | 266 return ImageDecoder::setFailed(); |
265 } | 267 } |
266 | 268 |
| 269 PassRefPtr<ColorSpaceProfile> PNGImageDecoder::colorProfile() const |
| 270 { |
| 271 #if USE(QCMSLIB) |
| 272 return m_colorProfile; |
| 273 #else |
| 274 return nullptr; |
| 275 #endif |
| 276 } |
| 277 |
267 #if USE(QCMSLIB) | 278 #if USE(QCMSLIB) |
268 static void readColorProfile(png_structp png, png_infop info, ColorProfile& colo
rProfile) | 279 static void readColorProfile(png_structp png, png_infop info, ColorProfile& colo
rProfile) |
269 { | 280 { |
270 #ifdef PNG_iCCP_SUPPORTED | 281 #ifdef PNG_iCCP_SUPPORTED |
271 char* profileName; | 282 char* profileName; |
272 int compressionType; | 283 int compressionType; |
273 #if (PNG_LIBPNG_VER < 10500) | 284 #if (PNG_LIBPNG_VER < 10500) |
274 png_charp profile; | 285 png_charp profile; |
275 #else | 286 #else |
276 png_bytep profile; | 287 png_bytep profile; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 // color profiles for gray-scale images is slightly tricky, at least usi
ng the | 361 // color profiles for gray-scale images is slightly tricky, at least usi
ng the |
351 // CoreGraphics ICC library, because we expand gray-scale images to RGB
but we | 362 // CoreGraphics ICC library, because we expand gray-scale images to RGB
but we |
352 // do not similarly transform the color profile. We'd either need to tra
nsform | 363 // do not similarly transform the color profile. We'd either need to tra
nsform |
353 // the color profile or we'd need to decode into a gray-scale image buff
er and | 364 // the color profile or we'd need to decode into a gray-scale image buff
er and |
354 // hand that to CoreGraphics. | 365 // hand that to CoreGraphics. |
355 ColorProfile colorProfile; | 366 ColorProfile colorProfile; |
356 readColorProfile(png, info, colorProfile); | 367 readColorProfile(png, info, colorProfile); |
357 bool decodedImageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCo
unt; | 368 bool decodedImageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCo
unt; |
358 m_reader->createColorTransform(colorProfile, decodedImageHasAlpha); | 369 m_reader->createColorTransform(colorProfile, decodedImageHasAlpha); |
359 m_hasColorProfile = !!m_reader->colorTransform(); | 370 m_hasColorProfile = !!m_reader->colorTransform(); |
| 371 if (m_hasColorProfile) { |
| 372 // FIXME: paint-time color correction is assumed here. |
| 373 qcms_profile* profile = qcms_profile_from_memory(colorProfile.data()
, colorProfile.size()); |
| 374 RefPtr<ColorSpaceProfile> imageColorProfile = ColorSpaceProfile::cre
ate(profile); |
| 375 m_hasColorProfile = !!imageColorProfile->profile(); |
| 376 m_colorProfile = m_hasColorProfile ? imageColorProfile : nullptr; |
| 377 // Don't color correct decoded frames during decoding. |
| 378 m_reader->clearColorTransform(); |
| 379 ASSERT(!m_reader->colorTransform()); |
| 380 } |
360 } | 381 } |
361 #endif | 382 #endif |
362 | 383 |
363 // Deal with gamma and keep it under our control. | 384 // Deal with gamma and keep it under our control. |
364 double gamma; | 385 double gamma; |
365 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { | 386 if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { |
366 if ((gamma <= 0.0) || (gamma > cMaxGamma)) { | 387 if ((gamma <= 0.0) || (gamma > cMaxGamma)) { |
367 gamma = cInverseGamma; | 388 gamma = cInverseGamma; |
368 png_set_gAMA(png, info, gamma); | 389 png_set_gAMA(png, info, gamma); |
369 } | 390 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 // has failed. | 559 // has failed. |
539 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 560 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
540 setFailed(); | 561 setFailed(); |
541 // If we're done decoding the image, we don't need the PNGImageReader | 562 // If we're done decoding the image, we don't need the PNGImageReader |
542 // anymore. (If we failed, |m_reader| has already been cleared.) | 563 // anymore. (If we failed, |m_reader| has already been cleared.) |
543 else if (isComplete()) | 564 else if (isComplete()) |
544 m_reader.clear(); | 565 m_reader.clear(); |
545 } | 566 } |
546 | 567 |
547 } // namespace WebCore | 568 } // namespace WebCore |
OLD | NEW |