OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the Chromium LICENSE file. |
| 4 |
| 5 #include "qcms.h" |
| 6 #include "qcms_test_util.h" |
| 7 |
| 8 #include <assert.h> |
| 9 #include <math.h> // sqrt |
| 10 #include <stdio.h> |
| 11 #include <stdint.h> |
| 12 #include <stdlib.h> |
| 13 |
| 14 #ifndef DISPLAY_DEVICE_PROFILE |
| 15 #define DISPLAY_DEVICE_PROFILE 0x6d6e7472 // 'mntr' |
| 16 #endif |
| 17 |
| 18 // D50 adapted color primaries of the internal sRGB color profile. |
| 19 static s15Fixed16Number sRGB_reference[3][3] = { |
| 20 { 0x06fa0, 0x06296, 0x024a0 }, // ( 0.436035, 0.385101, 0.143066 ) |
| 21 { 0x038f2, 0x0b789, 0x00f85 }, // ( 0.222443, 0.716934, 0.060623 ) |
| 22 { 0x0038f, 0x018da, 0x0b6c4 }, // ( 0.013901, 0.097076, 0.713928 ) |
| 23 }; |
| 24 |
| 25 // Reference media white point of the sRGB IEC61966-2.1 color profile. |
| 26 static struct XYZNumber D65 = { |
| 27 0xf351, 0x10000, 0x116cc // ( 0.950455, 1.000000, 1.089050 ) |
| 28 }; |
| 29 |
| 30 static void check_profile_description(qcms_profile *profile) |
| 31 { |
| 32 printf("Test profile description:\n"); |
| 33 |
| 34 const char* description = qcms_profile_get_description(profile); |
| 35 printf("description=[%s]\n\n", description); |
| 36 } |
| 37 |
| 38 static void check_profile_pcs_white_point(const qcms_profile *profile) |
| 39 { |
| 40 float rX = s15Fixed16Number_to_float(profile->redColorant.X); |
| 41 float gX = s15Fixed16Number_to_float(profile->greenColorant.X); |
| 42 float bX = s15Fixed16Number_to_float(profile->blueColorant.X); |
| 43 float rY = s15Fixed16Number_to_float(profile->redColorant.Y); |
| 44 float gY = s15Fixed16Number_to_float(profile->greenColorant.Y); |
| 45 float bY = s15Fixed16Number_to_float(profile->blueColorant.Y); |
| 46 float rZ = s15Fixed16Number_to_float(profile->redColorant.Z); |
| 47 float gZ = s15Fixed16Number_to_float(profile->greenColorant.Z); |
| 48 float bZ = s15Fixed16Number_to_float(profile->blueColorant.Z); |
| 49 |
| 50 printf("Test PCS white point against expected D50 XYZ values\n"); |
| 51 |
| 52 float X = rX + gX + bX; |
| 53 float Y = rY + gY + bY; |
| 54 float Z = rZ + gZ + bZ; |
| 55 |
| 56 float x = X / (X + Y + Z); |
| 57 float y = Y / (X + Y + Z); |
| 58 |
| 59 printf("Computed profile D50 White point xyY = [%.6f %.6f %.6f]\n", x, y, Y)
; |
| 60 |
| 61 float xerr = x - 0.345702915; // Compute error to ICC spec D50 xyY. |
| 62 float yerr = y - 0.358538597; |
| 63 float Yerr = Y - 1.000000000; |
| 64 |
| 65 printf("D50 white point error = %.6f\n\n", (float) |
| 66 sqrt((xerr * xerr) + (yerr * yerr) + (Yerr * Yerr))); |
| 67 } |
| 68 |
| 69 static void check_profile_media_white_point(const qcms_profile *profile) |
| 70 { |
| 71 int errX = profile->mediaWhitePoint.X - D65.X; |
| 72 int errY = profile->mediaWhitePoint.Y - D65.Y; |
| 73 int errZ = profile->mediaWhitePoint.Z - D65.Z; |
| 74 |
| 75 printf("Test media white point against expected D65 XYZ values\n"); |
| 76 printf("Internal profile D65 values = [0x%X, 0x%X, 0x%X]\n", |
| 77 profile->mediaWhitePoint.X, profile->mediaWhitePoint.Y, profile->medi
aWhitePoint.Z); |
| 78 printf("D65 media white point error = [%d, %d, %d]\n\n", errX, errY, errZ); |
| 79 } |
| 80 |
| 81 static s15Fixed16Number check_profile_primaries(const qcms_profile *profile) |
| 82 { |
| 83 s15Fixed16Number sRGB_internal[3][3]; |
| 84 s15Fixed16Number primary_error; |
| 85 int i, j; |
| 86 |
| 87 printf("Test qcms internal sRGB color primaries\n"); |
| 88 |
| 89 sRGB_internal[0][0] = profile->redColorant.X; |
| 90 sRGB_internal[1][0] = profile->redColorant.Y; |
| 91 sRGB_internal[2][0] = profile->redColorant.Z; |
| 92 sRGB_internal[0][1] = profile->greenColorant.X; |
| 93 sRGB_internal[1][1] = profile->greenColorant.Y; |
| 94 sRGB_internal[2][1] = profile->greenColorant.Z; |
| 95 sRGB_internal[0][2] = profile->blueColorant.X; |
| 96 sRGB_internal[1][2] = profile->blueColorant.Y; |
| 97 sRGB_internal[2][2] = profile->blueColorant.Z; |
| 98 |
| 99 primary_error = 0; |
| 100 for (i = 0; i < 3; i++) { |
| 101 for (j = 0; j < 3; j++) { |
| 102 s15Fixed16Number tmp = sRGB_internal[i][j] - sRGB_reference[i][j]; |
| 103 printf(" %d", tmp); |
| 104 primary_error += abs(tmp); |
| 105 } |
| 106 printf("\n"); |
| 107 } |
| 108 |
| 109 return primary_error; |
| 110 } |
| 111 |
| 112 static int qcms_test_internal_srgb(size_t width, |
| 113 size_t height, |
| 114 int iterations, |
| 115 const char *in_path, |
| 116 const char *out_path, |
| 117 const int force_software) |
| 118 { |
| 119 s15Fixed16Number primary_error; |
| 120 |
| 121 qcms_profile *profile = qcms_profile_sRGB(); |
| 122 |
| 123 assert(profile->class == DISPLAY_DEVICE_PROFILE); |
| 124 assert(profile->rendering_intent == QCMS_INTENT_PERCEPTUAL); |
| 125 assert(profile->color_space == RGB_SIGNATURE); |
| 126 assert(profile->pcs == XYZ_SIGNATURE); |
| 127 |
| 128 if (qcms_profile_is_bogus(profile)) { |
| 129 fprintf(stderr, "Failure: the internal sRGB profile failed the bogus pro
file check\n"); |
| 130 qcms_profile_release(profile); |
| 131 return -1; |
| 132 } |
| 133 |
| 134 // Compute tristimulus matrix error. |
| 135 primary_error = check_profile_primaries(profile); |
| 136 printf("Total primary error = 0x%x [%.6f]\n\n", primary_error, primary_error
/ 65536.0); |
| 137 |
| 138 // Verify media white point correctness. |
| 139 check_profile_media_white_point(profile); |
| 140 |
| 141 // Verify PCS white point correctness. |
| 142 check_profile_pcs_white_point(profile); |
| 143 |
| 144 // Output profile description. |
| 145 check_profile_description(profile); |
| 146 |
| 147 qcms_profile_release(profile); |
| 148 return primary_error; |
| 149 } |
| 150 |
| 151 struct qcms_test_case qcms_test_internal_srgb_info = { |
| 152 "qcms_test_internal_srgb", |
| 153 qcms_test_internal_srgb, |
| 154 QCMS_TEST_DISABLED |
| 155 }; |
OLD | NEW |