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 Corporation | 3 // Copyright (C) 2009 Mozilla Corporation |
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 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 continue; | 890 continue; |
891 } | 891 } |
892 return transform; | 892 return transform; |
893 } | 893 } |
894 */ | 894 */ |
895 | 895 |
896 static struct qcms_modular_transform* qcms_modular_transform_create(qcms_profile
*in, qcms_profile *out) | 896 static struct qcms_modular_transform* qcms_modular_transform_create(qcms_profile
*in, qcms_profile *out) |
897 { | 897 { |
898 struct qcms_modular_transform *first_transform = NULL; | 898 struct qcms_modular_transform *first_transform = NULL; |
899 struct qcms_modular_transform **next_transform = &first_transform; | 899 struct qcms_modular_transform **next_transform = &first_transform; |
| 900 qcms_bool transform_to_pcs_xyz_only = (out == NULL); |
900 | 901 |
901 if (in->color_space == RGB_SIGNATURE) { | 902 if (in->color_space == RGB_SIGNATURE) { |
902 struct qcms_modular_transform* rgb_to_pcs; | 903 struct qcms_modular_transform* rgb_to_pcs; |
903 rgb_to_pcs = qcms_modular_transform_create_input(in); | 904 rgb_to_pcs = qcms_modular_transform_create_input(in); |
904 if (!rgb_to_pcs) | 905 if (!rgb_to_pcs) |
905 goto fail; | 906 goto fail; |
906 append_transform(rgb_to_pcs, &next_transform); | 907 append_transform(rgb_to_pcs, &next_transform); |
907 } else { | 908 } else { |
908 assert(0 && "input color space not supported"); | 909 assert(0 && "input color space not supported"); |
909 goto fail; | 910 goto fail; |
910 } | 911 } |
911 | 912 |
912 » if (in->pcs == LAB_SIGNATURE && out->pcs == XYZ_SIGNATURE) { | 913 » if (in->pcs == LAB_SIGNATURE && (transform_to_pcs_xyz_only || out->pcs =
= XYZ_SIGNATURE)) { |
913 struct qcms_modular_transform* lab_to_pcs; | 914 struct qcms_modular_transform* lab_to_pcs; |
914 lab_to_pcs = qcms_modular_transform_alloc(); | 915 lab_to_pcs = qcms_modular_transform_alloc(); |
915 if (!lab_to_pcs) | 916 if (!lab_to_pcs) |
916 goto fail; | 917 goto fail; |
917 append_transform(lab_to_pcs, &next_transform); | 918 append_transform(lab_to_pcs, &next_transform); |
918 lab_to_pcs->transform_module_fn = qcms_transform_module_LAB_to_X
YZ; | 919 lab_to_pcs->transform_module_fn = qcms_transform_module_LAB_to_X
YZ; |
919 } | 920 } |
920 | 921 |
| 922 if (transform_to_pcs_xyz_only) |
| 923 return first_transform; |
| 924 |
921 // This does not improve accuracy in practice, something is wrong here. | 925 // This does not improve accuracy in practice, something is wrong here. |
922 //if (in->chromaticAdaption.invalid == false) { | 926 //if (in->chromaticAdaption.invalid == false) { |
923 // struct qcms_modular_transform* chromaticAdaption; | 927 // struct qcms_modular_transform* chromaticAdaption; |
924 // chromaticAdaption = qcms_modular_transform_alloc(); | 928 // chromaticAdaption = qcms_modular_transform_alloc(); |
925 // if (!chromaticAdaption) | 929 // if (!chromaticAdaption) |
926 // goto fail; | 930 // goto fail; |
927 // append_transform(chromaticAdaption, &next_transform); | 931 // append_transform(chromaticAdaption, &next_transform); |
928 // chromaticAdaption->matrix = matrix_invert(in->chromaticAdaption)
; | 932 // chromaticAdaption->matrix = matrix_invert(in->chromaticAdaption)
; |
929 // chromaticAdaption->transform_module_fn = qcms_transform_module_m
atrix; | 933 // chromaticAdaption->transform_module_fn = qcms_transform_module_m
atrix; |
930 //} | 934 //} |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 float* qcms_chain_transform(qcms_profile *in, qcms_profile *out, float *src, flo
at *dest, size_t lutSize) | 989 float* qcms_chain_transform(qcms_profile *in, qcms_profile *out, float *src, flo
at *dest, size_t lutSize) |
986 { | 990 { |
987 struct qcms_modular_transform *transform_list = qcms_modular_transform_c
reate(in, out); | 991 struct qcms_modular_transform *transform_list = qcms_modular_transform_c
reate(in, out); |
988 if (transform_list != NULL) { | 992 if (transform_list != NULL) { |
989 float *lut = qcms_modular_transform_data(transform_list, src, de
st, lutSize/3); | 993 float *lut = qcms_modular_transform_data(transform_list, src, de
st, lutSize/3); |
990 qcms_modular_transform_release(transform_list); | 994 qcms_modular_transform_release(transform_list); |
991 return lut; | 995 return lut; |
992 } | 996 } |
993 return NULL; | 997 return NULL; |
994 } | 998 } |
| 999 |
| 1000 qcms_bool qcms_profile_white_transform(qcms_profile *profile, float XYZ[3]) |
| 1001 { |
| 1002 const float inverse_internal_scale = 1.999969482421875f; |
| 1003 |
| 1004 // Set the output profile to NULL to request a color transform to PCS XY
Z only. |
| 1005 struct qcms_modular_transform *transform_list = qcms_modular_transform_c
reate(profile, NULL); |
| 1006 |
| 1007 // Now calculate how the profile transforms white input color to PCS XYZ
space. |
| 1008 if (transform_list != NULL) { |
| 1009 XYZ[0] = XYZ[1] = XYZ[2] = 1.0f; // white input |
| 1010 qcms_modular_transform_data(transform_list, XYZ, XYZ, 1); |
| 1011 // qcms_modular_transform_create internally scales input by 1/1.
999969482421875f |
| 1012 // but no qcms changelog describes why / how that number was cho
osen. junov@ "it |
| 1013 // might be related to the epsilon of the fixed-point type 2*(1-
1/(2^16)), but |
| 1014 // there is no explanation, which is disconcerting." Meanwhile,
undo the internal |
| 1015 // scaling so we return a normalized CIEXYZ value viz., where Y
is scaled to 1.0. |
| 1016 // A properly created color profile should produce Y=~1.0 in PCS
XYZ with white |
| 1017 // input (the D50 test). If it does not, then the profile is lik
ely bogus. |
| 1018 XYZ[0] *= inverse_internal_scale; |
| 1019 XYZ[1] *= inverse_internal_scale; |
| 1020 XYZ[2] *= inverse_internal_scale; |
| 1021 qcms_modular_transform_release(transform_list); |
| 1022 return true; |
| 1023 } |
| 1024 |
| 1025 return false; |
| 1026 } |
OLD | NEW |