OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 167 } |
168 | 168 |
169 static float png_fixed_point_to_float(png_fixed_point x) { | 169 static float png_fixed_point_to_float(png_fixed_point x) { |
170 // We multiply by the same factor that libpng used to convert | 170 // We multiply by the same factor that libpng used to convert |
171 // fixed point -> double. Since we want floats, we choose to | 171 // fixed point -> double. Since we want floats, we choose to |
172 // do the conversion ourselves rather than convert | 172 // do the conversion ourselves rather than convert |
173 // fixed point -> double -> float. | 173 // fixed point -> double -> float. |
174 return ((float) x) * 0.00001f; | 174 return ((float) x) * 0.00001f; |
175 } | 175 } |
176 | 176 |
| 177 static float png_inverted_fixed_point_to_float(png_fixed_point x) { |
| 178 // This is necessary because the gAMA chunk actually stores 1/gamma. |
| 179 return 1.0f / png_fixed_point_to_float(x); |
| 180 } |
| 181 |
177 // Returns a colorSpace object that represents any color space information in | 182 // Returns a colorSpace object that represents any color space information in |
178 // the encoded data. If the encoded data contains no color space, this will | 183 // the encoded data. If the encoded data contains no color space, this will |
179 // return NULL. | 184 // return NULL. |
180 sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) { | 185 sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) { |
181 | 186 |
182 #if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_M
INOR >= 6) | 187 #if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_M
INOR >= 6) |
183 | 188 |
184 // First check for an ICC profile | 189 // First check for an ICC profile |
185 png_bytep profile; | 190 png_bytep profile; |
186 png_uint_32 length; | 191 png_uint_32 length; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 // FIXME (msarett): Here we are treating XYZ values as D50 even though t
he color | 224 // FIXME (msarett): Here we are treating XYZ values as D50 even though t
he color |
220 // temperature is unspecified. I suspect that this ass
umption | 225 // temperature is unspecified. I suspect that this ass
umption |
221 // is most often ok, but we could also calculate the co
lor | 226 // is most often ok, but we could also calculate the co
lor |
222 // temperature (D value) and then convert the XYZ to D5
0. Maybe | 227 // temperature (D value) and then convert the XYZ to D5
0. Maybe |
223 // we should add a new constructor to SkColorSpace that
accepts | 228 // we should add a new constructor to SkColorSpace that
accepts |
224 // XYZ with D-Unkown? | 229 // XYZ with D-Unkown? |
225 for (int i = 0; i < 9; i++) { | 230 for (int i = 0; i < 9; i++) { |
226 toXYZD50.fMat[i] = png_fixed_point_to_float(XYZ[i]); | 231 toXYZD50.fMat[i] = png_fixed_point_to_float(XYZ[i]); |
227 } | 232 } |
228 | 233 |
229 if (PNG_INFO_gAMA != png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { | 234 if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { |
230 | 235 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = |
| 236 png_inverted_fixed_point_to_float(gamma); |
| 237 } else { |
231 // If the image does not specify gamma, let's choose linear. Should
we default | 238 // If the image does not specify gamma, let's choose linear. Should
we default |
232 // to sRGB? Most images are intended to be sRGB (gamma = 2.2f). | 239 // to sRGB? Most images are intended to be sRGB (gamma = 2.2f). |
233 gamma = PNG_GAMMA_LINEAR; | 240 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = 1.0f; |
234 } | 241 } |
235 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = png_fixed_point_to_fl
oat(gamma); | 242 |
236 | 243 |
237 return SkColorSpace::NewRGB(toXYZD50, gammas); | 244 return SkColorSpace::NewRGB(toXYZD50, gammas); |
238 } | 245 } |
239 | 246 |
240 // Last, check for gamma. | 247 // Last, check for gamma. |
241 if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { | 248 if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { |
242 | 249 |
243 // Guess a default value for cHRM? Or should we just give up? | 250 // Guess a default value for cHRM? Or should we just give up? |
244 // Here we use the identity matrix as a default. | 251 // Here we use the identity matrix as a default. |
245 // FIXME (msarett): Should SkFloat3x3 have a method to set the identity
matrix? | 252 // FIXME (msarett): Should SkFloat3x3 have a method to set the identity
matrix? |
246 memset(toXYZD50.fMat, 0, 9 * sizeof(float)); | 253 memset(toXYZD50.fMat, 0, 9 * sizeof(float)); |
247 toXYZD50.fMat[0] = toXYZD50.fMat[4] = toXYZD50.fMat[8] = 1.0f; | 254 toXYZD50.fMat[0] = toXYZD50.fMat[4] = toXYZD50.fMat[8] = 1.0f; |
248 | 255 |
249 // Set the gammas. | 256 // Set the gammas. |
250 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = png_fixed_point_to_fl
oat(gamma); | 257 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = png_inverted_fixed_po
int_to_float(gamma); |
251 | 258 |
252 return SkColorSpace::NewRGB(toXYZD50, gammas); | 259 return SkColorSpace::NewRGB(toXYZD50, gammas); |
253 } | 260 } |
254 | 261 |
255 #endif // LIBPNG >= 1.6 | 262 #endif // LIBPNG >= 1.6 |
256 | 263 |
257 // Finally, what should we do if there is no color space information in the
PNG? | 264 // Finally, what should we do if there is no color space information in the
PNG? |
258 // The specification says that this indicates "gamma is unknown" and that th
e | 265 // The specification says that this indicates "gamma is unknown" and that th
e |
259 // "color is device dependent". I'm assuming we can represent this with NUL
L. | 266 // "color is device dependent". I'm assuming we can represent this with NUL
L. |
260 // But should we guess sRGB? Most images are sRGB, even if they don't speci
fy. | 267 // But should we guess sRGB? Most images are sRGB, even if they don't speci
fy. |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 | 849 |
843 if (1 == numberPasses) { | 850 if (1 == numberPasses) { |
844 return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chun
kReader, | 851 return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chun
kReader, |
845 png_ptr, info_ptr, bitDepth, colorSpace)
; | 852 png_ptr, info_ptr, bitDepth, colorSpace)
; |
846 } | 853 } |
847 | 854 |
848 return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release()
, chunkReader, | 855 return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release()
, chunkReader, |
849 png_ptr, info_ptr, bitDepth, numbe
rPasses, | 856 png_ptr, info_ptr, bitDepth, numbe
rPasses, |
850 colorSpace); | 857 colorSpace); |
851 } | 858 } |
OLD | NEW |