void jvxlReadColorData(Mesh mesh) {

		// standard jvxl file read for color

		fractionPtr = 0;
		int vertexCount = mesh.vertexCount;
		short[] colixes = mesh.vertexColixes;
		fractionData = new StringBuffer();
		strFractionTemp = (isJvxl ? jvxlColorDataRead : "");
		fractionPtr = 0;
		Logger.info("JVXL reading color data base/range: " + mappedDataMin + "/" + mappedDataMax + " for "
				+ vertexCount + " vertices." + " using encoding keys " + colorFractionBase + " " + colorFractionRange);
		Logger.info("mapping red-->blue for " + valueMappedToRed + " to " + valueMappedToBlue + " colorPrecision:"
				+ jvxlDataIsPrecisionColor);

		float min = (mappedDataMin == Float.MAX_VALUE ? defaultMappedDataMin : mappedDataMin);
		float range = (mappedDataMin == Float.MAX_VALUE ? defaultMappedDataMax : mappedDataMax) - min;
		float colorRange = valueMappedToBlue - valueMappedToRed;
		contourPlaneMinimumValue = Float.MAX_VALUE;
		contourPlaneMaximumValue = -Float.MAX_VALUE;
		if (colixes == null || colixes.length < vertexCount)
			mesh.vertexColixes = colixes = new short[vertexCount];
		int n = (isContoured ? contourVertexCount : vertexCount);
		String data = jvxlColorDataRead;
		int cpt = 0;
		for (int i = 0; i < n; i++) {
			float fraction, value;
			if (jvxlDataIsPrecisionColor) {
				// this COULD be an option for mapped surfaces;
				// necessary for planes.
				// precision is used for FULL-data range encoding, allowing full
				// treatment of JVXL files as though they were CUBE files.
				fraction = jvxlFractionFromCharacter2(data.charAt(cpt), data.charAt(cpt + n), colorFractionBase,
						colorFractionRange);
				value = min + fraction * range;
			}
			else {
				// my original encoding scheme
				// low precision only allows for mapping relative to the defined color range
				fraction = jvxlFractionFromCharacter(data.charAt(cpt), colorFractionBase, colorFractionRange, 0.5f);
				value = valueMappedToRed + fraction * colorRange;
			}
			++cpt;
			if (value < contourPlaneMinimumValue)
				contourPlaneMinimumValue = value;
			if (value > contourPlaneMaximumValue)
				contourPlaneMaximumValue = value;

			if (isContoured) {
				contourVertexes[i].setValue(value);
			}
			else if (colorBySign) {
				colixes[i] = Graphics3D.getColix((isColorReversed ? value > 0 : value <= 0) ? colorNeg : colorPos);
			}
			else {
				colixes[i] = viewer.getColixFromPalette(isColorReversed ? valueMappedToRed + valueMappedToBlue - value
						: value, valueMappedToRed, valueMappedToBlue, colorScheme);
				if (logMessages)
					Logger.info("readColor " + i + ": " + fraction + " " + value + " " + valueMappedToRed + " "
							+ valueMappedToBlue + " " + colixes[i]);
				if (mesh.hasGridPoints) {
					colixes[++i] = viewer.getColixFromPalette(0.2f, 0f, 1f, colorScheme);
					colixes[++i] = viewer.getColixFromPalette(0.8f, 0f, 1f, colorScheme);
				}
			}
		}
		if (mappedDataMin == Float.MAX_VALUE) {
			mappedDataMin = contourPlaneMinimumValue;
			mappedDataMax = contourPlaneMaximumValue;
		}
		mesh.jvxlColorData = data + "\n";
	}