diff options
author | robert.bradford <robert.bradford@intel.com> | 2015-11-06 12:46:47 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-06 20:48:24 +0000 |
commit | 24c9850a32ba2f2c4b1e8617671a89ce60b1ff49 (patch) | |
tree | 55b5b36d1d7afb2fed10f400dbb417552d187e1c /third_party/qcms | |
parent | e8ce45cb1927ce332400db4f593bc31b2bccf9f9 (diff) | |
download | chromium_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.chromium | 2 | ||||
-rw-r--r-- | third_party/qcms/src/iccread.c | 110 |
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; |