private IList <Color> DecodeSinglePartition(BitReader br, BlockMode blockMode) { var colorEndpointMode = DecodeColorEndpointModes(br, blockMode, 1)[0]; if (colorEndpointMode.EndpointValueCount > 18 || blockMode.IsHdr != colorEndpointMode.IsHdr) { return(ErrorColors); } var colorBits = ColorHelper.CalculateColorBits(1, blockMode.WeightBitCount, blockMode.IsDualPlane); var quantizationLevel = ColorHelper.QuantizationModeTable[colorEndpointMode.EndpointValueCount >> 1][colorBits]; if (quantizationLevel < 4) { return(ErrorColors); } var colorValues = IntegerSequenceEncoding.Decode(br, quantizationLevel, colorEndpointMode.EndpointValueCount); var colorEndpoints = ColorUnquantization.DecodeColorEndpoints(colorValues, colorEndpointMode.Format, quantizationLevel); // Weights decoding br.Position = 128 - blockMode.WeightBitCount; var result = new Color[_x * _y * _z]; if (blockMode.IsDualPlane) { br.Position = 128 - blockMode.WeightBitCount - 2; var plane2ColorComponent = br.ReadBits <int>(2); var indices = IntegerSequenceEncoding.Decode(br, blockMode.QuantizationMode, blockMode.WeightCount); for (var i = 0; i < blockMode.WeightCount; i++) { var plane1Weight = WeightUnquantization.WeightUnquantizationTable[blockMode.QuantizationMode][indices[i * 2]]; var plane2Weight = WeightUnquantization.WeightUnquantizationTable[blockMode.QuantizationMode][indices[i * 2 + 1]]; result[i] = ColorHelper.InterpolateColor(colorEndpoints, plane1Weight, plane2Weight, plane2ColorComponent); } } else { var indices = IntegerSequenceEncoding.Decode(br, blockMode.QuantizationMode, blockMode.WeightCount); for (var i = 0; i < blockMode.WeightCount; i++) { var weight = WeightUnquantization.WeightUnquantizationTable[blockMode.QuantizationMode][indices[i]]; result[i] = ColorHelper.InterpolateColor(colorEndpoints, weight, -1, -1); } } return(result); }
private IList <Color> DecodeMultiPartition(BitReader br, BlockMode blockMode, int partitions) { var colorEndpointModes = DecodeColorEndpointModes(br, blockMode, partitions); var colorValueCount = colorEndpointModes.Sum(x => x.EndpointValueCount); if (colorValueCount > 18 || colorEndpointModes.Any(x => x.IsHdr != blockMode.IsHdr)) { return(ErrorColors); } var colorBits = ColorHelper.CalculateColorBits(partitions, blockMode.WeightBitCount, blockMode.IsDualPlane); var quantizationLevel = ColorHelper.QuantizationModeTable[colorValueCount >> 1][colorBits]; if (quantizationLevel < 4) { return(ErrorColors); } br.Position = 19 + Constants.PartitionBits; var colorValues = IntegerSequenceEncoding.Decode(br, quantizationLevel, colorValueCount); var colorEndpoints = new UInt4[partitions][]; for (var i = 0; i < partitions; i++) { colorEndpoints[i] = ColorUnquantization.DecodeColorEndpoints(colorValues, colorEndpointModes[i].Format, quantizationLevel); } br.Position = 13; var partitionIndex = br.ReadBits <uint>(10); var elementsInBlock = _x * _y * _z; var partitionIndices = new int[elementsInBlock]; for (int z = 0; z < _z; z++) { for (int y = 0; y < _y; y++) { for (int x = 0; x < _x; x++) { partitionIndices[x * y * z] = PartitionSelection.SelectPartition(partitionIndex, x, y, z, partitions, elementsInBlock < 32); } } } var result = new Color[elementsInBlock]; if (blockMode.IsDualPlane) { // TODO: Should those 2 bits below the weights be here for multi partition due to encodedType high part? br.Position = 128 - blockMode.WeightBitCount - 2; var plane2ColorComponent = br.ReadBits <int>(2); var indices = IntegerSequenceEncoding.Decode(br, blockMode.QuantizationMode, blockMode.WeightCount); for (var i = 0; i < blockMode.WeightCount; i++) { var plane1Weight = WeightUnquantization.WeightUnquantizationTable[blockMode.QuantizationMode][indices[i * 2]]; var plane2Weight = WeightUnquantization.WeightUnquantizationTable[blockMode.QuantizationMode][indices[i * 2 + 1]]; result[i] = ColorHelper.InterpolateColor(colorEndpoints[partitionIndices[i]], plane1Weight, plane2Weight, plane2ColorComponent); } } else { var indices = IntegerSequenceEncoding.Decode(br, blockMode.QuantizationMode, blockMode.WeightCount); for (var i = 0; i < blockMode.WeightCount; i++) { var weight = WeightUnquantization.WeightUnquantizationTable[blockMode.QuantizationMode][indices[i]]; result[i] = ColorHelper.InterpolateColor(colorEndpoints[partitionIndices[i]], weight, -1, -1); } } return(result); }