| 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 |