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 // Multiply by the inverse of the factor used by libpng. | |
179 // This is necessary because the gAMA chunk actually stores 1/gamma. | |
180 return ((float) x) * 100000.0f; | |
Brian Osman
2016/03/23 13:01:50
I think you want 1.0f / (png_fixed_point_to_float(
msarett
2016/03/23 13:16:19
Doh thanks. Tough day for algebra yesterday.
| |
181 } | |
182 | |
177 // Returns a colorSpace object that represents any color space information in | 183 // 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 | 184 // the encoded data. If the encoded data contains no color space, this will |
179 // return NULL. | 185 // return NULL. |
180 sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) { | 186 sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) { |
181 | 187 |
182 #if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_M INOR >= 6) | 188 #if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_M INOR >= 6) |
183 | 189 |
184 // First check for an ICC profile | 190 // First check for an ICC profile |
185 png_bytep profile; | 191 png_bytep profile; |
186 png_uint_32 length; | 192 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 | 225 // 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 | 226 // temperature is unspecified. I suspect that this ass umption |
221 // is most often ok, but we could also calculate the co lor | 227 // 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 | 228 // temperature (D value) and then convert the XYZ to D5 0. Maybe |
223 // we should add a new constructor to SkColorSpace that accepts | 229 // we should add a new constructor to SkColorSpace that accepts |
224 // XYZ with D-Unkown? | 230 // XYZ with D-Unkown? |
225 for (int i = 0; i < 9; i++) { | 231 for (int i = 0; i < 9; i++) { |
226 toXYZD50.fMat[i] = png_fixed_point_to_float(XYZ[i]); | 232 toXYZD50.fMat[i] = png_fixed_point_to_float(XYZ[i]); |
227 } | 233 } |
228 | 234 |
229 if (PNG_INFO_gAMA != png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { | 235 if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { |
230 | 236 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = |
237 png_inverted_fixed_point_to_float(gamma); | |
238 } else { | |
231 // If the image does not specify gamma, let's choose linear. Should we default | 239 // 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). | 240 // to sRGB? Most images are intended to be sRGB (gamma = 2.2f). |
233 gamma = PNG_GAMMA_LINEAR; | 241 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = 1.0f; |
234 } | 242 } |
235 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = png_fixed_point_to_fl oat(gamma); | 243 |
236 | 244 |
237 return SkColorSpace::NewRGB(toXYZD50, gammas); | 245 return SkColorSpace::NewRGB(toXYZD50, gammas); |
238 } | 246 } |
239 | 247 |
240 // Last, check for gamma. | 248 // Last, check for gamma. |
241 if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { | 249 if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) { |
242 | 250 |
243 // Guess a default value for cHRM? Or should we just give up? | 251 // Guess a default value for cHRM? Or should we just give up? |
244 // Here we use the identity matrix as a default. | 252 // Here we use the identity matrix as a default. |
245 // FIXME (msarett): Should SkFloat3x3 have a method to set the identity matrix? | 253 // FIXME (msarett): Should SkFloat3x3 have a method to set the identity matrix? |
246 memset(toXYZD50.fMat, 0, 9 * sizeof(float)); | 254 memset(toXYZD50.fMat, 0, 9 * sizeof(float)); |
247 toXYZD50.fMat[0] = toXYZD50.fMat[4] = toXYZD50.fMat[8] = 1.0f; | 255 toXYZD50.fMat[0] = toXYZD50.fMat[4] = toXYZD50.fMat[8] = 1.0f; |
248 | 256 |
249 // Set the gammas. | 257 // Set the gammas. |
250 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = png_fixed_point_to_fl oat(gamma); | 258 gammas.fVec[0] = gammas.fVec[1] = gammas.fVec[2] = png_inverted_fixed_po int_to_float(gamma); |
251 | 259 |
252 return SkColorSpace::NewRGB(toXYZD50, gammas); | 260 return SkColorSpace::NewRGB(toXYZD50, gammas); |
253 } | 261 } |
254 | 262 |
255 #endif // LIBPNG >= 1.6 | 263 #endif // LIBPNG >= 1.6 |
256 | 264 |
257 // Finally, what should we do if there is no color space information in the PNG? | 265 // 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 | 266 // 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. | 267 // "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. | 268 // 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 | 850 |
843 if (1 == numberPasses) { | 851 if (1 == numberPasses) { |
844 return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chun kReader, | 852 return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chun kReader, |
845 png_ptr, info_ptr, bitDepth, colorSpace) ; | 853 png_ptr, info_ptr, bitDepth, colorSpace) ; |
846 } | 854 } |
847 | 855 |
848 return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release() , chunkReader, | 856 return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release() , chunkReader, |
849 png_ptr, info_ptr, bitDepth, numbe rPasses, | 857 png_ptr, info_ptr, bitDepth, numbe rPasses, |
850 colorSpace); | 858 colorSpace); |
851 } | 859 } |
OLD | NEW |