Index: third_party/qcms/google.patch |
diff --git a/third_party/qcms/google.patch b/third_party/qcms/google.patch |
index dea54fc41303d01fa328b0ecb5fb99720ba7e9a3..cf8b7c229328c26eb52e2088d9649ba70431555e 100644 |
--- a/third_party/qcms/google.patch |
+++ b/third_party/qcms/google.patch |
@@ -1,5 +1,5 @@ |
diff --git a/third_party/qcms/src/iccread.c b/third_party/qcms/src/iccread.c |
-index 36b7011..6cec34a 100644 |
+index 36b7011..208ebee 100644 |
--- a/third_party/qcms/src/iccread.c |
+++ b/third_party/qcms/src/iccread.c |
@@ -266,7 +266,7 @@ qcms_bool qcms_profile_is_bogus(qcms_profile *profile) |
@@ -230,7 +230,36 @@ index 36b7011..6cec34a 100644 |
} |
static void mAB_release(struct lutmABType *lut) |
-@@ -657,7 +817,7 @@ static struct lutType *read_tag_lutType(struct mem_source *src, struct tag_index |
+@@ -540,7 +700,7 @@ static struct lutmABType *read_tag_lutmABType(struct mem_source *src, struct tag |
+ // We require 3in/out channels since we only support RGB->XYZ (or RGB->LAB) |
+ // XXX: If we remove this restriction make sure that the number of channels |
+ // is less or equal to the maximum number of mAB curves in qcmsint.h |
+- // also check for clut_size overflow. |
++ // also check for clut_size overflow. Also make sure it's != 0 |
+ if (num_in_channels != 3 || num_out_channels != 3) |
+ return NULL; |
+ |
+@@ -570,6 +730,9 @@ static struct lutmABType *read_tag_lutmABType(struct mem_source *src, struct tag |
+ // clut_size can not overflow since lg(256^num_in_channels) = 24 bits. |
+ for (i = 0; i < num_in_channels; i++) { |
+ clut_size *= read_u8(src, clut_offset + i); |
++ if (clut_size == 0) { |
++ invalid_source(src, "bad clut_size"); |
++ } |
+ } |
+ } else { |
+ clut_size = 0; |
+@@ -590,6 +753,9 @@ static struct lutmABType *read_tag_lutmABType(struct mem_source *src, struct tag |
+ |
+ for (i = 0; i < num_in_channels; i++) { |
+ lut->num_grid_points[i] = read_u8(src, clut_offset + i); |
++ if (lut->num_grid_points[i] == 0) { |
++ invalid_source(src, "bad grid_points"); |
++ } |
+ } |
+ |
+ // Reverse the processing of transformation elements for mBA type. |
+@@ -657,7 +823,7 @@ static struct lutType *read_tag_lutType(struct mem_source *src, struct tag_index |
uint16_t num_input_table_entries; |
uint16_t num_output_table_entries; |
uint8_t in_chan, grid_points, out_chan; |
@@ -239,7 +268,50 @@ index 36b7011..6cec34a 100644 |
uint32_t clut_size; |
size_t entry_size; |
struct lutType *lut; |
-@@ -979,6 +1139,9 @@ qcms_profile* qcms_profile_sRGB(void) |
+@@ -672,6 +838,10 @@ static struct lutType *read_tag_lutType(struct mem_source *src, struct tag_index |
+ } else if (type == LUT16_TYPE) { |
+ num_input_table_entries = read_u16(src, offset + 48); |
+ num_output_table_entries = read_u16(src, offset + 50); |
++ if (num_input_table_entries == 0 || num_output_table_entries == 0) { |
++ invalid_source(src, "Bad channel count"); |
++ return NULL; |
++ } |
+ entry_size = 2; |
+ } else { |
+ assert(0); // the caller checks that this doesn't happen |
+@@ -685,15 +855,18 @@ static struct lutType *read_tag_lutType(struct mem_source *src, struct tag_index |
+ |
+ clut_size = pow(grid_points, in_chan); |
+ if (clut_size > MAX_CLUT_SIZE) { |
++ invalid_source(src, "CLUT too large"); |
+ return NULL; |
+ } |
+ |
+ if (in_chan != 3 || out_chan != 3) { |
++ invalid_source(src, "CLUT only supports RGB"); |
+ return NULL; |
+ } |
+ |
+ lut = malloc(sizeof(struct lutType) + (num_input_table_entries * in_chan + clut_size*out_chan + num_output_table_entries * out_chan)*sizeof(float)); |
+ if (!lut) { |
++ invalid_source(src, "CLUT too large"); |
+ return NULL; |
+ } |
+ |
+@@ -704,9 +877,9 @@ static struct lutType *read_tag_lutType(struct mem_source *src, struct tag_index |
+ |
+ lut->num_input_table_entries = num_input_table_entries; |
+ lut->num_output_table_entries = num_output_table_entries; |
+- lut->num_input_channels = read_u8(src, offset + 8); |
+- lut->num_output_channels = read_u8(src, offset + 9); |
+- lut->num_clut_grid_points = read_u8(src, offset + 10); |
++ lut->num_input_channels = in_chan; |
++ lut->num_output_channels = out_chan; |
++ lut->num_clut_grid_points = grid_points; |
+ lut->e00 = read_s15Fixed16Number(src, offset+12); |
+ lut->e01 = read_s15Fixed16Number(src, offset+16); |
+ lut->e02 = read_s15Fixed16Number(src, offset+20); |
+@@ -979,6 +1152,9 @@ qcms_profile* qcms_profile_sRGB(void) |
return NO_MEM_PROFILE; |
profile = qcms_profile_create_rgb_with_table(D65, Rec709Primaries, table, 1024); |
@@ -249,7 +321,7 @@ index 36b7011..6cec34a 100644 |
free(table); |
return profile; |
} |
-@@ -997,6 +1160,9 @@ qcms_profile* qcms_profile_from_memory(const void *mem, size_t size) |
+@@ -997,6 +1173,9 @@ qcms_profile* qcms_profile_from_memory(const void *mem, size_t size) |
source.size = size; |
source.valid = true; |
@@ -259,7 +331,7 @@ index 36b7011..6cec34a 100644 |
length = read_u32(src, 0); |
if (length <= size) { |
// shrink the area that we can read if appropriate |
-@@ -1028,6 +1194,15 @@ qcms_profile* qcms_profile_from_memory(const void *mem, size_t size) |
+@@ -1028,6 +1207,15 @@ qcms_profile* qcms_profile_from_memory(const void *mem, size_t size) |
if (!src->valid || !index.tags) |
goto invalid_tag_table; |
@@ -275,7 +347,7 @@ index 36b7011..6cec34a 100644 |
if (find_tag(index, TAG_CHAD)) { |
profile->chromaticAdaption = read_tag_s15Fixed16ArrayType(src, index, TAG_CHAD); |
} else { |
-@@ -1098,6 +1273,16 @@ invalid_profile: |
+@@ -1098,6 +1286,16 @@ invalid_profile: |
return INVALID_PROFILE; |
} |
@@ -1282,7 +1354,7 @@ index 9a6562b..f669a6b 100644 |
qcms_bool qcms_supports_iccv4; |
diff --git a/third_party/qcms/src/transform_util.c b/third_party/qcms/src/transform_util.c |
-index e8447e5..f4338b2 100644 |
+index e8447e5..f616c3f 100644 |
--- a/third_party/qcms/src/transform_util.c |
+++ b/third_party/qcms/src/transform_util.c |
@@ -36,7 +36,7 @@ |
@@ -1365,7 +1437,88 @@ index e8447e5..f4338b2 100644 |
} |
struct matrix build_colorant_matrix(qcms_profile *p) |
-@@ -390,7 +408,7 @@ uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int len |
+@@ -295,7 +313,7 @@ uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int len |
+ |
+ NumZeroes = 0; |
+ while (LutTable[NumZeroes] == 0 && NumZeroes < length-1) |
+- NumZeroes++; |
++ NumZeroes++; |
+ |
+ // There are no zeros at the beginning and we are trying to find a zero, so |
+ // return anything. It seems zero would be the less destructive choice |
+@@ -305,22 +323,22 @@ uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int len |
+ |
+ NumPoles = 0; |
+ while (LutTable[length-1- NumPoles] == 0xFFFF && NumPoles < length-1) |
+- NumPoles++; |
++ NumPoles++; |
+ |
+ // Does the curve belong to this case? |
+ if (NumZeroes > 1 || NumPoles > 1) |
+- { |
++ { |
+ int a, b; |
+ |
+- // Identify if value fall downto 0 or FFFF zone |
++ // Identify if value fall downto 0 or FFFF zone |
+ if (Value == 0) return 0; |
+ // if (Value == 0xFFFF) return 0xFFFF; |
+ |
+ // else restrict to valid zone |
+ |
+- a = ((NumZeroes-1) * 0xFFFF) / (length-1); |
++ a = ((NumZeroes-1) * 0xFFFF) / (length-1); |
+ b = ((length-1 - NumPoles) * 0xFFFF) / (length-1); |
+- |
++ |
+ l = a - 1; |
+ r = b + 1; |
+ } |
+@@ -332,12 +350,12 @@ uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int len |
+ |
+ x = (l + r) / 2; |
+ |
+- res = (int) lut_interp_linear16((uint16_fract_t) (x-1), LutTable, length); |
++ res = (int) lut_interp_linear16((uint16_fract_t) (x-1), LutTable, length); |
+ |
+ if (res == Value) { |
+ |
+- // Found exact match. |
+- |
++ // Found exact match. |
++ |
+ return (uint16_fract_t) (x - 1); |
+ } |
+ |
+@@ -347,14 +365,14 @@ uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int len |
+ |
+ // Not found, should we interpolate? |
+ |
+- |
++ |
+ // Get surrounding nodes |
+- |
++ |
+ val2 = (length-1) * ((double) (x - 1) / 65535.0); |
+ |
+ cell0 = (int) floor(val2); |
+ cell1 = (int) ceil(val2); |
+- |
++ |
+ if (cell0 == cell1) return (uint16_fract_t) x; |
+ |
+ y0 = LutTable[cell0] ; |
+@@ -373,8 +391,7 @@ uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int len |
+ if (f < 0.0) return (uint16_fract_t) 0; |
+ if (f >= 65535.0) return (uint16_fract_t) 0xFFFF; |
+ |
+- return (uint16_fract_t) floor(f + 0.5); |
+- |
++ return (uint16_fract_t) floor(f + 0.5); |
+ } |
+ |
+ /* |
+@@ -390,7 +407,7 @@ uint16_fract_t lut_inverse_interp16(uint16_t Value, uint16_t LutTable[], int len |
which has an maximum error of about 9855 (pixel difference of ~38.346) |
For now, we punt the decision of output size to the caller. */ |