示例#1
0
文件: BC7.cs 项目: natsu-k/XbTool
        public static DX10_Helpers.LDRColour[] DecompressBC7(byte[] source, int sourceStart)
        {
            int start = 0;

            while (start < 128 && DX10_Helpers.GetBit(source, sourceStart, ref start) == 0)
            {
            }
            int  modeVal = start - 1;
            Mode mode    = Modes[modeVal];

            var outColours = new DX10_Helpers.LDRColour[DX10_Helpers.NUM_PIXELS_PER_BLOCK];

            if (modeVal < 8)
            {
                int   partitions     = mode.Partitions;
                int   numEndPoints   = (partitions + 1) << 1;
                int   indexPrecision = mode.IndexPrecision;
                int   APrecision     = mode.APrecision;
                int   i;
                int[] P         = new int[mode.PBits];
                int   shape     = DX10_Helpers.GetBits(source, sourceStart, ref start, mode.PartitionBits);
                int   rotation  = DX10_Helpers.GetBits(source, sourceStart, ref start, mode.RotationBits);
                int   indexMode = DX10_Helpers.GetBits(source, sourceStart, ref start, mode.IndexModeBits);

                DX10_Helpers.LDRColour[] c                 = new DX10_Helpers.LDRColour[6];
                DX10_Helpers.LDRColour   RGBPrecision      = mode.RawRGBPrecision;
                DX10_Helpers.LDRColour   RGBPrecisionWithP = mode.RGBPrecisionWithP;

                // Red
                for (i = 0; i < numEndPoints; i++)
                {
                    if (start + RGBPrecision.R > 128)
                    {
                        Debugger.Break();  // Error
                    }
                    c[i].R = DX10_Helpers.GetBits(source, sourceStart, ref start, RGBPrecision.R);
                }

                // Green
                for (i = 0; i < numEndPoints; i++)
                {
                    if (start + RGBPrecision.G > 128)
                    {
                        Debugger.Break();  // Error
                    }
                    c[i].G = DX10_Helpers.GetBits(source, sourceStart, ref start, RGBPrecision.G);
                }

                // Blue
                for (i = 0; i < numEndPoints; i++)
                {
                    if (start + RGBPrecision.B > 128)
                    {
                        Debugger.Break();  // Error
                    }
                    c[i].B = DX10_Helpers.GetBits(source, sourceStart, ref start, RGBPrecision.B);
                }

                // Alpha
                for (i = 0; i < numEndPoints; i++)
                {
                    if (start + RGBPrecision.A > 128)
                    {
                        Debugger.Break();  // Error
                    }
                    c[i].A = RGBPrecision.A == 0 ? 255 : DX10_Helpers.GetBits(source, sourceStart, ref start, RGBPrecision.A);
                }

                // P Bits
                for (i = 0; i < mode.PBits; i++)
                {
                    if (start > 127)
                    {
                        Debugger.Break();
                        // Error
                    }

                    P[i] = DX10_Helpers.GetBit(source, sourceStart, ref start);
                }


                // Adjust for P bits
                bool rDiff = RGBPrecision.R != RGBPrecisionWithP.R;
                bool gDiff = RGBPrecision.G != RGBPrecisionWithP.B;
                bool bDiff = RGBPrecision.G != RGBPrecisionWithP.G;
                bool aDiff = RGBPrecision.A != RGBPrecisionWithP.A;
                if (mode.PBits != 0)
                {
                    for (i = 0; i < numEndPoints; i++)
                    {
                        int pi = i * mode.PBits / numEndPoints;
                        if (rDiff)
                        {
                            c[i].R = (c[i].R << 1) | P[pi];
                        }

                        if (gDiff)
                        {
                            c[i].G = (c[i].G << 1) | P[pi];
                        }

                        if (bDiff)
                        {
                            c[i].B = (c[i].B << 1) | P[pi];
                        }

                        if (aDiff)
                        {
                            c[i].A = (c[i].A << 1) | P[pi];
                        }
                    }
                }

                for (i = 0; i < numEndPoints; i++)
                {
                    c[i] = DX10_Helpers.Unquantise(c[i], RGBPrecisionWithP);
                }

                int[] w1 = new int[DX10_Helpers.NUM_PIXELS_PER_BLOCK];
                int[] w2 = new int[DX10_Helpers.NUM_PIXELS_PER_BLOCK];

                // Read colour indicies
                for (i = 0; i < DX10_Helpers.NUM_PIXELS_PER_BLOCK; i++)
                {
                    int numBits = DX10_Helpers.IsFixUpOffset(partitions, shape, i) ? indexPrecision - 1 : indexPrecision;
                    if (start + numBits > 128)
                    {
                        Debugger.Break();
                        // Error
                    }
                    w1[i] = DX10_Helpers.GetBits(source, sourceStart, ref start, numBits);
                }

                // Read Alpha
                if (APrecision != 0)
                {
                    for (i = 0; i < DX10_Helpers.NUM_PIXELS_PER_BLOCK; i++)
                    {
                        int numBits = i != 0 ? APrecision : APrecision - 1;
                        if (start + numBits > 128)
                        {
                            Debugger.Break();
                            // Error
                        }
                        w2[i] = DX10_Helpers.GetBits(source, sourceStart, ref start, numBits);
                    }
                }


                for (i = 0; i < DX10_Helpers.NUM_PIXELS_PER_BLOCK; i++)
                {
                    int region = DX10_Helpers.PartitionTable[partitions][shape][i];
                    DX10_Helpers.LDRColour outPixel;
                    if (APrecision == 0)
                    {
                        outPixel = Interpolate(c[region << 1], c[(region << 1) + 1], w1[i], w1[i], indexPrecision, indexPrecision);
                    }
                    else
                    {
                        if (indexMode == 0)
                        {
                            outPixel = Interpolate(c[region << 1], c[(region << 1) + 1], w1[i], w2[i], indexPrecision, APrecision);
                        }
                        else
                        {
                            outPixel = Interpolate(c[region << 1], c[(region << 1) + 1], w2[i], w1[i], APrecision, indexPrecision);
                        }
                    }

                    switch (rotation)
                    {
                    case 1:
                        int temp = outPixel.R;
                        outPixel.R = outPixel.A;
                        outPixel.A = temp;
                        break;

                    case 2:
                        temp       = outPixel.G;
                        outPixel.G = outPixel.A;
                        outPixel.A = temp;
                        break;

                    case 3:
                        temp       = outPixel.B;
                        outPixel.B = outPixel.A;
                        outPixel.A = temp;
                        break;
                    }

                    outColours[i] = outPixel;
                }
                return(outColours);
            }

            return(outColours);
        }
示例#2
0
文件: BC7.cs 项目: natsu-k/XbTool
 private static DX10_Helpers.LDRColour Interpolate(DX10_Helpers.LDRColour lDRColour1, DX10_Helpers.LDRColour lDRColour2, int wc, int wa, int wcPrec, int waPrec)
 {
     DX10_Helpers.LDRColour temp = DX10_Helpers.InterpolateRGB(lDRColour1, lDRColour2, wc, wcPrec);
     temp.A = DX10_Helpers.InterpolateA(lDRColour1, lDRColour2, wa, waPrec);
     return(temp);
 }