  
  	/* don't precache if we do not have the TRC curves */
  	if (!profile->redTRC || !profile->greenTRC || !profile->blueTRC)
-@@ -1078,7 +1153,8 @@ qcms_transform* qcms_transform_precacheLUT_float(qcms_transform *transform, qcms
- 	//XXX: qcms_modular_transform_data may return either the src or dest buffer. If so it must not be free-ed
+@@ -1043,28 +1118,31 @@ qcms_transform* qcms_transform_precacheLUT_float(qcms_transform *transform, qcms
+ 	float* src = NULL;
+ 	float* dest = NULL;
+ 	float* lut = NULL;
++	float inverse;
+ 
+ 	src = malloc(lutSize*sizeof(float));
+ 	dest = malloc(lutSize*sizeof(float));
+ 
+ 	if (src && dest) {
+-		/* Prepare a list of points we want to sample */
++		/* Prepare a list of points we want to sample: x, y, z order */
+ 		l = 0;
++		inverse = 1 / (float)(samples-1);
+ 		for (x = 0; x < samples; x++) {
+ 			for (y = 0; y < samples; y++) {
+ 				for (z = 0; z < samples; z++) {
+-					src[l++] = x / (float)(samples-1);
+-					src[l++] = y / (float)(samples-1);
+-					src[l++] = z / (float)(samples-1);
++					src[l++] = x * inverse; // r
++					src[l++] = y * inverse; // g
++					src[l++] = z * inverse; // b
+ 				}
+ 			}
+ 		}
+ 
+ 		lut = qcms_chain_transform(in, out, src, dest, lutSize);
++
+ 		if (lut) {
+-			transform->r_clut = &lut[0];
+-			transform->g_clut = &lut[1];
+-			transform->b_clut = &lut[2];
++			transform->r_clut = &lut[0]; // r
++			transform->g_clut = &lut[1]; // g
++			transform->b_clut = &lut[2]; // b
+ 			transform->grid_size = samples;
+ 			if (in_type == QCMS_DATA_RGBA_8) {
+ 				transform->transform_fn = qcms_transform_data_tetra_clut_rgba;
+@@ -1074,11 +1152,12 @@ qcms_transform* qcms_transform_precacheLUT_float(qcms_transform *transform, qcms
+ 		}
+ 	}
+ 
+-
+-	//XXX: qcms_modular_transform_data may return either the src or dest buffer. If so it must not be free-ed
++	// XXX: qcms_modular_transform_data may return the lut in either the src or the
++	// dest buffer. If so, it must not be free-ed.
  	if (src && lut != src) {
  		free(src);
 -	} else if (dest && lut != src) {

 {
 	return profile->rendering_intent;
diff --git a/third_party/qcms/src/qcms.h b/third_party/qcms/src/qcms.h
index 7d83623..c69a772 100644
--- a/third_party/qcms/src/qcms.h
+++ b/third_party/qcms/src/qcms.h
@@ -40,6 +40,12 @@ sale, use or other dealings in this Software without written

+		uint32_t offset = tag->offset;
+		uint32_t type = read_u32(src, offset);
+		uint32_t length = read_u32(src, offset+8);
+		uint32_t i, description_offset;
+		bool mluc = false;
+		if (length && type == MLUC_TYPE) {
+			length = read_u32(src, offset+20);
+			if (!length || (length & 1) || (read_u32(src, offset+12) != 12))
+				goto invalid_desc_tag;
+			description_offset = offset + read_u32(src, offset+24);
+			if (!src->valid)
+				goto invalid_desc_tag;
+			mluc = true;
+		} else if (length && type == DESC_TYPE) {
+			description_offset = offset + 12;
+		} else {
+			goto invalid_desc_tag;
+		}
+		if (length >= limit)
+			length = limit - 1;
+		for (i = 0; i < length; ++i) {
+			uint8_t value = read_u8(src, description_offset + i);
+			if (!src->valid)
+				goto invalid_desc_tag;
+			if (mluc && !value)
+				value = '.';
+			profile->description[i] = value;
+		}
+		profile->description[length] = 0;
+	} else {
+		goto invalid_desc_tag;
