| OLD | NEW |
| 1 /* vim: set ts=8 sw=8 noexpandtab: */ | 1 /* vim: set ts=8 sw=8 noexpandtab: */ |
| 2 // qcms | 2 // qcms |
| 3 // Copyright (C) 2009 Mozilla Foundation | 3 // Copyright (C) 2009 Mozilla Foundation |
| 4 // Copyright (C) 1998-2007 Marti Maria | 4 // Copyright (C) 1998-2007 Marti Maria |
| 5 // | 5 // |
| 6 // Permission is hereby granted, free of charge, to any person obtaining | 6 // Permission is hereby granted, free of charge, to any person obtaining |
| 7 // a copy of this software and associated documentation files (the "Software"), | 7 // a copy of this software and associated documentation files (the "Software"), |
| 8 // to deal in the Software without restriction, including without limitation | 8 // to deal in the Software without restriction, including without limitation |
| 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, | 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 10 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e | 10 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 for (i = 0; i < index.count; i++) { | 246 for (i = 0; i < index.count; i++) { |
| 247 index.tags[i].signature = read_u32(mem, 128 + 4 + 4*i*3)
; | 247 index.tags[i].signature = read_u32(mem, 128 + 4 + 4*i*3)
; |
| 248 index.tags[i].offset = read_u32(mem, 128 + 4 + 4*i*3
+ 4); | 248 index.tags[i].offset = read_u32(mem, 128 + 4 + 4*i*3
+ 4); |
| 249 index.tags[i].size = read_u32(mem, 128 + 4 + 4*i*3
+ 8); | 249 index.tags[i].size = read_u32(mem, 128 + 4 + 4*i*3
+ 8); |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 | 252 |
| 253 return index; | 253 return index; |
| 254 } | 254 } |
| 255 | 255 |
| 256 // Checks a profile for obvious inconsistencies and returns | 256 /* Checks a profile for obvious inconsistencies and return true if the |
| 257 // true if the profile looks bogus and should probably be | 257 * profile looks bogus and should probably be ignored. |
| 258 // ignored. | 258 */ |
| 259 qcms_bool qcms_profile_is_bogus(qcms_profile *profile) | 259 qcms_bool qcms_profile_is_bogus(qcms_profile *profile) |
| 260 { | 260 { |
| 261 float sum[3], target[3], tolerance[3]; | 261 float rX, rY, rZ, gX, gY, gZ, bX, bY, bZ; |
| 262 float rX, rY, rZ, gX, gY, gZ, bX, bY, bZ; | 262 float target[3], tolerance[3], sum[3]; |
| 263 bool negative; | 263 unsigned i; |
| 264 unsigned i; | |
| 265 | 264 |
| 266 // We currently only check the bogosity of RGB profiles | 265 // We currently only check the bogosity of RGB profiles. |
| 267 if (profile->color_space != RGB_SIGNATURE) | 266 if (profile->color_space != RGB_SIGNATURE) |
| 268 » return false; | |
| 269 | |
| 270 if (qcms_supports_iccv4 && (profile->A2B0 || profile->B2A0)) | |
| 271 return false; | 267 return false; |
| 272 | 268 |
| 273 rX = s15Fixed16Number_to_float(profile->redColorant.X); | 269 if (qcms_supports_iccv4 && (profile->A2B0 || profile->B2A0)) |
| 274 rY = s15Fixed16Number_to_float(profile->redColorant.Y); | 270 return false; |
| 275 rZ = s15Fixed16Number_to_float(profile->redColorant.Z); | |
| 276 | 271 |
| 277 gX = s15Fixed16Number_to_float(profile->greenColorant.X); | 272 rX = s15Fixed16Number_to_float(profile->redColorant.X); |
| 278 gY = s15Fixed16Number_to_float(profile->greenColorant.Y); | 273 rY = s15Fixed16Number_to_float(profile->redColorant.Y); |
| 279 gZ = s15Fixed16Number_to_float(profile->greenColorant.Z); | 274 rZ = s15Fixed16Number_to_float(profile->redColorant.Z); |
| 280 | 275 |
| 281 bX = s15Fixed16Number_to_float(profile->blueColorant.X); | 276 gX = s15Fixed16Number_to_float(profile->greenColorant.X); |
| 282 bY = s15Fixed16Number_to_float(profile->blueColorant.Y); | 277 gY = s15Fixed16Number_to_float(profile->greenColorant.Y); |
| 283 bZ = s15Fixed16Number_to_float(profile->blueColorant.Z); | 278 gZ = s15Fixed16Number_to_float(profile->greenColorant.Z); |
| 284 | 279 |
| 285 // Check if any of the XYZ values are negative (see mozilla bug 498245) | 280 bX = s15Fixed16Number_to_float(profile->blueColorant.X); |
| 286 // CIEXYZ tristimulus values cannot be negative according to the spec. | 281 bY = s15Fixed16Number_to_float(profile->blueColorant.Y); |
| 287 negative = | 282 bZ = s15Fixed16Number_to_float(profile->blueColorant.Z); |
| 288 » (rX < 0) || (rY < 0) || (rZ < 0) || | |
| 289 » (gX < 0) || (gY < 0) || (gZ < 0) || | |
| 290 » (bX < 0) || (bY < 0) || (bZ < 0); | |
| 291 | 283 |
| 292 if (negative) | 284 // Build our target vector: CIE D50 white. See also mozilla bug 460629, |
| 293 » return true; | 285 // and http://www.color.org/whyd50.xalter "Why is the media white point |
| 286 // of a display profile always D50?" |
| 294 | 287 |
| 288 target[0] = (float) 0.96420; |
| 289 target[1] = (float) 1.00000; |
| 290 target[2] = (float) 0.82491; |
| 295 | 291 |
| 296 // Sum the values; they should add up to something close to white | 292 // Our tolerance vector - Recommended by Chris Murphy [1] based on |
| 297 sum[0] = rX + gX + bX; | 293 // conversion from the L*a*b space criterion of no more than 3 in any |
| 298 sum[1] = rY + gY + bY; | 294 // one channel. This is similar to, but slightly more tolerant than |
| 299 sum[2] = rZ + gZ + bZ; | 295 // Adobe's criterion. [1] https://bugzil.la/460629#c10 |
| 300 | 296 |
| 301 #if defined (_MSC_VER) | 297 tolerance[0] = (float) 0.02; |
| 302 #pragma warning(push) | 298 tolerance[1] = (float) 0.02; |
| 303 /* Disable double to float truncation warning 4305 */ | 299 tolerance[2] = (float) 0.04; |
| 304 #pragma warning(disable:4305) | 300 |
| 301 // Sum the XYZ values: they should add to D50 white, within tolerance. |
| 302 |
| 303 // FIXME: this test assumes the TRC RGB curves equal 1.0 for the white |
| 304 // input (255,255,255) RGB test color. For user display profiles, that |
| 305 // is the normal case. Profiles with abnormal TRC exist. A better test |
| 306 // would transform 255,255,255 white through the profile to either XYZ |
| 307 // or L*a*b color and compare the result to D50 in XYZ or L*a*b color. |
| 308 |
| 309 sum[0] = rX + gX + bX; |
| 310 sum[1] = rY + gY + bY; |
| 311 sum[2] = rZ + gZ + bZ; |
| 312 |
| 313 for (i = 0; i < 3; ++i) { |
| 314 if (!(((sum[i] - tolerance[i]) <= target[i]) && |
| 315 ((sum[i] + tolerance[i]) >= target[i]))) { |
| 316 return true; // out of tolerance: bogus |
| 317 } |
| 318 } |
| 319 |
| 320 #ifndef __APPLE__ |
| 321 |
| 322 // Check if any of the XYZ values are negative (see mozilla bug 498245) |
| 323 // CIEXYZ tristimulus values cannot be negative according to the spec. |
| 324 |
| 325 bool negative = |
| 326 (rX < 0) || (rY < 0) || (rZ < 0) || |
| 327 (gX < 0) || (gY < 0) || (gZ < 0) || |
| 328 (bX < 0) || (bY < 0) || (bZ < 0); |
| 329 |
| 330 if (negative) |
| 331 return true; // bogus |
| 332 #else |
| 333 // Chromatic adaption to D50 can result in negative XYZ, but the white |
| 334 // point D50 tolerance test has passed. Accept negative values herein. |
| 335 // See https://bugzilla.mozilla.org/show_bug.cgi?id=498245#c18 onwards |
| 336 // for discussion about whether profile XYZ can or cannot be negative, |
| 337 // per the spec. Also the https://bugzil.la/450923 user report. |
| 338 |
| 339 // FIXME: allow this relaxation on all ports? |
| 305 #endif | 340 #endif |
| 306 // Build our target vector (see mozilla bug 460629) | 341 // All good. |
| 307 target[0] = 0.96420; | 342 return false; |
| 308 target[1] = 1.00000; | |
| 309 target[2] = 0.82491; | |
| 310 | |
| 311 // Our tolerance vector - Recommended by Chris Murphy based on | |
| 312 // conversion from the LAB space criterion of no more than 3 in any one | |
| 313 // channel. This is similar to, but slightly more tolerant than Adobe's | |
| 314 // criterion. | |
| 315 tolerance[0] = 0.02; | |
| 316 tolerance[1] = 0.02; | |
| 317 tolerance[2] = 0.04; | |
| 318 | |
| 319 #if defined (_MSC_VER) | |
| 320 /* Restore warnings */ | |
| 321 #pragma warning(pop) | |
| 322 #endif | |
| 323 // Compare with our tolerance | |
| 324 for (i = 0; i < 3; ++i) { | |
| 325 if (!(((sum[i] - tolerance[i]) <= target[i]) && | |
| 326 ((sum[i] + tolerance[i]) >= target[i]))) | |
| 327 return true; | |
| 328 } | |
| 329 | |
| 330 // All Good | |
| 331 return false; | |
| 332 } | 343 } |
| 333 | 344 |
| 334 #define TAG_bXYZ 0x6258595a | 345 #define TAG_bXYZ 0x6258595a |
| 335 #define TAG_gXYZ 0x6758595a | 346 #define TAG_gXYZ 0x6758595a |
| 336 #define TAG_rXYZ 0x7258595a | 347 #define TAG_rXYZ 0x7258595a |
| 337 #define TAG_rTRC 0x72545243 | 348 #define TAG_rTRC 0x72545243 |
| 338 #define TAG_bTRC 0x62545243 | 349 #define TAG_bTRC 0x62545243 |
| 339 #define TAG_gTRC 0x67545243 | 350 #define TAG_gTRC 0x67545243 |
| 340 #define TAG_kTRC 0x6b545243 | 351 #define TAG_kTRC 0x6b545243 |
| 341 #define TAG_A2B0 0x41324230 | 352 #define TAG_A2B0 0x41324230 |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 { | 1557 { |
| 1547 qcms_profile *profile = NULL; | 1558 qcms_profile *profile = NULL; |
| 1548 FILE *file = _wfopen(path, L"rb"); | 1559 FILE *file = _wfopen(path, L"rb"); |
| 1549 if (file) { | 1560 if (file) { |
| 1550 profile = qcms_profile_from_file(file); | 1561 profile = qcms_profile_from_file(file); |
| 1551 fclose(file); | 1562 fclose(file); |
| 1552 } | 1563 } |
| 1553 return profile; | 1564 return profile; |
| 1554 } | 1565 } |
| 1555 #endif | 1566 #endif |
| OLD | NEW |