Beispiel #1
0
            public int GetPackedBitSize()
            {
                // How many indices do we have?
                int Indices = Height * Width;

                if (DualPlane)
                {
                    Indices *= 2;
                }

                IntegerEncoded IntEncoded = IntegerEncoded.CreateEncoding(MaxWeight);

                return(IntEncoded.GetBitLength(Indices));
            }
Beispiel #2
0
        static void DecodeColorValues(
            int[] OutputValues,
            byte[] InputData,
            uint[] Modes,
            int NumberPartitions,
            int NumberBitsForColorData)
        {
            // First figure out how many color values we have
            int NumberValues = 0;

            for (int i = 0; i < NumberPartitions; i++)
            {
                NumberValues += (int)((Modes[i] >> 2) + 1) << 1;
            }

            // Then based on the number of values and the remaining number of bits,
            // figure out the max value for each of them...
            int Range = 256;

            while (--Range > 0)
            {
                IntegerEncoded IntEncoded = IntegerEncoded.CreateEncoding(Range);
                int            BitLength  = IntEncoded.GetBitLength(NumberValues);

                if (BitLength <= NumberBitsForColorData)
                {
                    // Find the smallest possible range that matches the given encoding
                    while (--Range > 0)
                    {
                        IntegerEncoded NewIntEncoded = IntegerEncoded.CreateEncoding(Range);
                        if (!NewIntEncoded.MatchesEncoding(IntEncoded))
                        {
                            break;
                        }
                    }

                    // Return to last matching range.
                    Range++;
                    break;
                }
            }

            // We now have enough to decode our integer sequence.
            List <IntegerEncoded> IntegerEncodedSequence = new List <IntegerEncoded>();
            BitArrayStream        ColorBitStream         = new BitArrayStream(new BitArray(InputData));

            IntegerEncoded.DecodeIntegerSequence(IntegerEncodedSequence, ColorBitStream, Range, NumberValues);

            // Once we have the decoded values, we need to dequantize them to the 0-255 range
            // This procedure is outlined in ASTC spec C.2.13
            int OutputIndices = 0;

            foreach (IntegerEncoded IntEncoded in IntegerEncodedSequence)
            {
                int BitLength = IntEncoded.NumberBits;
                int BitValue  = IntEncoded.BitValue;

                Debug.Assert(BitLength >= 1);

                int A = 0, B = 0, C = 0, D = 0;
                // A is just the lsb replicated 9 times.
                A = BitArrayStream.Replicate(BitValue & 1, 1, 9);

                switch (IntEncoded.GetEncoding())
                {
                case IntegerEncoded.EIntegerEncoding.JustBits:
                {
                    OutputValues[OutputIndices++] = BitArrayStream.Replicate(BitValue, BitLength, 8);

                    break;
                }

                case IntegerEncoded.EIntegerEncoding.Trit:
                {
                    D = IntEncoded.TritValue;

                    switch (BitLength)
                    {
                    case 1:
                    {
                        C = 204;

                        break;
                    }

                    case 2:
                    {
                        C = 93;
                        // B = b000b0bb0
                        int b = (BitValue >> 1) & 1;
                        B = (b << 8) | (b << 4) | (b << 2) | (b << 1);

                        break;
                    }

                    case 3:
                    {
                        C = 44;
                        // B = cb000cbcb
                        int cb = (BitValue >> 1) & 3;
                        B = (cb << 7) | (cb << 2) | cb;

                        break;
                    }


                    case 4:
                    {
                        C = 22;
                        // B = dcb000dcb
                        int dcb = (BitValue >> 1) & 7;
                        B = (dcb << 6) | dcb;

                        break;
                    }

                    case 5:
                    {
                        C = 11;
                        // B = edcb000ed
                        int edcb = (BitValue >> 1) & 0xF;
                        B = (edcb << 5) | (edcb >> 2);

                        break;
                    }

                    case 6:
                    {
                        C = 5;
                        // B = fedcb000f
                        int fedcb = (BitValue >> 1) & 0x1F;
                        B = (fedcb << 4) | (fedcb >> 4);

                        break;
                    }

                    default:
                        throw new ASTCDecoderException("Unsupported trit encoding for color values!");
                    }

                    break;
                }

                case IntegerEncoded.EIntegerEncoding.Quint:
                {
                    D = IntEncoded.QuintValue;

                    switch (BitLength)
                    {
                    case 1:
                    {
                        C = 113;

                        break;
                    }

                    case 2:
                    {
                        C = 54;
                        // B = b0000bb00
                        int b = (BitValue >> 1) & 1;
                        B = (b << 8) | (b << 3) | (b << 2);

                        break;
                    }

                    case 3:
                    {
                        C = 26;
                        // B = cb0000cbc
                        int cb = (BitValue >> 1) & 3;
                        B = (cb << 7) | (cb << 1) | (cb >> 1);

                        break;
                    }

                    case 4:
                    {
                        C = 13;
                        // B = dcb0000dc
                        int dcb = (BitValue >> 1) & 7;
                        B = (dcb << 6) | (dcb >> 1);

                        break;
                    }

                    case 5:
                    {
                        C = 6;
                        // B = edcb0000e
                        int edcb = (BitValue >> 1) & 0xF;
                        B = (edcb << 5) | (edcb >> 3);

                        break;
                    }

                    default:
                        throw new ASTCDecoderException("Unsupported quint encoding for color values!");
                    }
                    break;
                }
                }

                if (IntEncoded.GetEncoding() != IntegerEncoded.EIntegerEncoding.JustBits)
                {
                    int T = D * C + B;
                    T ^= A;
                    T  = (A & 0x80) | (T >> 2);

                    OutputValues[OutputIndices++] = T;
                }
            }

            // Make sure that each of our values is in the proper range...
            for (int i = 0; i < NumberValues; i++)
            {
                Debug.Assert(OutputValues[i] <= 255);
            }
        }