예제 #1
0
        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);
        }
예제 #2
0
        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);
        }