| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |