summaryrefslogtreecommitdiffstats
path: root/third_party/qcms
diff options
context:
space:
mode:
authorrobert.bradford <robert.bradford@intel.com>2015-11-06 12:46:47 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-06 20:48:24 +0000
commit24c9850a32ba2f2c4b1e8617671a89ce60b1ff49 (patch)
tree55b5b36d1d7afb2fed10f400dbb417552d187e1c /third_party/qcms
parente8ce45cb1927ce332400db4f593bc31b2bccf9f9 (diff)
downloadchromium_src-24c9850a32ba2f2c4b1e8617671a89ce60b1ff49.zip
chromium_src-24c9850a32ba2f2c4b1e8617671a89ce60b1ff49.tar.gz
chromium_src-24c9850a32ba2f2c4b1e8617671a89ce60b1ff49.tar.bz2
[qcms] Add support for VCGT tag formula gamma
Rather than specifying a full table LUT of values for gamma in a profile VCGT tag, some ICC files use the formula format: y = min + (max-min)x^gamma, x in [0.0 .. 1.0] Add support for such VCGT profiles. Expand valid VCGT formula to an 8-bit (256 entry) gamma table per color channel. Formulas for 3 color channels are required. The formula order is assumed to be R channel, then G channel, then B channel. TEST=Boot a device with the formula ICC file and observe that the display is changed. BUG=551568 Review URL: https://codereview.chromium.org/1416093005 Cr-Commit-Position: refs/heads/master@{#358380}
Diffstat (limited to 'third_party/qcms')
-rw-r--r--third_party/qcms/README.chromium2
-rw-r--r--third_party/qcms/src/iccread.c110
2 files changed, 78 insertions, 34 deletions
diff --git a/third_party/qcms/README.chromium b/third_party/qcms/README.chromium
index e440620..0215e61 100644
--- a/third_party/qcms/README.chromium
+++ b/third_party/qcms/README.chromium
@@ -113,6 +113,8 @@ The following changes have been made since qcms was imported:
- https://code.google.com/p/chromium/issues/detail?id=532910
- Store color profile version and add a version read API
- https://code.google.com/p/chromium/issues/detail?id=532258
+ - Add support for VCGT tag formula gamma
+ - https://code.google.com/p/chromium/issues/detail?id=551568
For the Chromium changes, since the import, in a patch format run:
git diff b8456f38 src
diff --git a/third_party/qcms/src/iccread.c b/third_party/qcms/src/iccread.c
index 40cc9fc..b62f127 100644
--- a/third_party/qcms/src/iccread.c
+++ b/third_party/qcms/src/iccread.c
@@ -361,57 +361,99 @@ static struct tag *find_tag(struct tag_index index, uint32_t tag_id)
#define MMOD_TYPE 0x6D6D6F64 // 'mmod'
#define VCGT_TYPE 0x76636774 // 'vcgt'
+enum {
+ VCGT_TYPE_TABLE,
+ VCGT_TYPE_FORMULA,
+ VCGT_TYPE_LAST = VCGT_TYPE_FORMULA
+};
+
static qcms_bool read_tag_vcgtType(qcms_profile *profile, struct mem_source *src, struct tag_index index)
{
size_t tag_offset = find_tag(index, TAG_vcgt)->offset;
uint32_t tag_type = read_u32(src, tag_offset);
uint32_t vcgt_type = read_u32(src, tag_offset + 8);
- uint16_t channels = read_u16(src, tag_offset + 12);
- uint16_t elements = read_u16(src, tag_offset + 14);
- uint16_t byte_depth = read_u16(src, tag_offset + 16);
- size_t table_offset = tag_offset + 18;
- uint32_t i;
- uint16_t *dest;
if (!src->valid || tag_type != VCGT_TYPE)
goto invalid_vcgt_tag;
- // Only support 3 channels.
- if (channels != 3)
- return true;
- // Only support single or double byte values.
- if (byte_depth != 1 && byte_depth != 2)
- return true;
- // Only support table data, not equation.
- if (vcgt_type != 0)
- return true;
- // Limit the table to a sensible size; 10-bit gamma is a reasonable
- // maximum for hardware correction.
- if (elements > 1024)
+ // Only support table and equation types.
+ if (vcgt_type > VCGT_TYPE_LAST)
return true;
- // Empty table is invalid.
- if (!elements)
- goto invalid_vcgt_tag;
+ if (vcgt_type == VCGT_TYPE_TABLE) {
+ uint16_t channels = read_u16(src, tag_offset + 12);
+ uint16_t elements = read_u16(src, tag_offset + 14);
+ uint16_t byte_depth = read_u16(src, tag_offset + 16);
+ size_t table_offset = tag_offset + 18;
+ uint32_t i;
+ uint16_t *dest;
- profile->vcgt.length = elements;
- profile->vcgt.data = malloc(3 * elements * sizeof(uint16_t));
- if (!profile->vcgt.data)
- return false;
+ if (!src->valid)
+ goto invalid_vcgt_tag;
- dest = profile->vcgt.data;
+ // Only support 3 channels.
+ if (channels != 3)
+ return true;
+ // Only support single or double byte values.
+ if (byte_depth != 1 && byte_depth != 2)
+ return true;
+ // Limit the table to a sensible size; 10-bit gamma is a reasonable
+ // maximum for hardware correction.
+ if (elements > 1024)
+ return true;
+
+ // Empty table is invalid.
+ if (!elements)
+ goto invalid_vcgt_tag;
- for (i = 0; i < 3 * elements; ++i) {
- if (byte_depth == 1) {
- *dest++ = read_u8(src, table_offset) * 256;
- } else {
- *dest++ = read_u16(src, table_offset);
+ profile->vcgt.length = elements;
+ profile->vcgt.data = malloc(3 * elements * sizeof(uint16_t));
+ if (!profile->vcgt.data)
+ return false;
+
+ dest = profile->vcgt.data;
+
+ for (i = 0; i < 3 * elements; ++i) {
+ if (byte_depth == 1) {
+ *dest++ = read_u8(src, table_offset) * 256;
+ } else {
+ *dest++ = read_u16(src, table_offset);
+ }
+
+ table_offset += byte_depth;
+
+ if (!src->valid)
+ goto invalid_vcgt_tag;
}
+ } else {
+ size_t formula_offset = tag_offset + 12;
+ int i, j;
+ uint16_t *dest;
+
+ // For formula always provide an 8-bit lut.
+ profile->vcgt.length = 256;
+ profile->vcgt.data = malloc(3 * profile->vcgt.length * sizeof(uint16_t));
+ if (!profile->vcgt.data)
+ return false;
+
+ dest = profile->vcgt.data;
+ for (i = 0; i < 3; ++i) {
+ float gamma = s15Fixed16Number_to_float(
+ read_s15Fixed16Number(src, formula_offset + 12 * i));
+ float min = s15Fixed16Number_to_float(
+ read_s15Fixed16Number(src, formula_offset + 4 + 12 * i));
+ float max = s15Fixed16Number_to_float(
+ read_s15Fixed16Number(src, formula_offset + 8 + 12 * i));
+ float range = max - min;
- table_offset += byte_depth;
+ if (!src->valid)
+ goto invalid_vcgt_tag;
- if (!src->valid)
- goto invalid_vcgt_tag;
+ for (j = 0; j < profile->vcgt.length; ++j) {
+ *dest++ = 65535.f *
+ (min + range * pow((float)j / (profile->vcgt.length - 1), gamma));
+ }
+ }
}
return true;