CrystalMpq.DataFormats.ArgbColor.DxtMergeThirds C# (CSharp) Method

DxtMergeThirds() static private method

Merges two colors for DXT decompression.
static private DxtMergeThirds ( ArgbColor result, ArgbColor minColor, ArgbColor maxColor ) : void
result ArgbColor The storage to be used for the result.
minColor ArgbColor The color whose weight will be 1/3.
maxColor ArgbColor The color whose weight will be 2/3.
return void
        internal static unsafe void DxtMergeThirds(ArgbColor* result, ArgbColor* minColor, ArgbColor* maxColor)
        {
            // Formula used here:
            // x / 3 = x * 683 >> 11 (for 0 ≤ x ≤ 3 * 255)
            // Need to verify that this is indeed faster, but it'll do the work for now.
            result->B = (byte)((minColor->B + maxColor->B + maxColor->B) * 683 >> 11);
            result->G = (byte)((minColor->G + maxColor->G + maxColor->G) * 683 >> 11);
            result->R = (byte)((minColor->R + maxColor->R + maxColor->R) * 683 >> 11);
            result->A = 255;
        }

Usage Example

示例#1
0
        protected unsafe override void CopyToArgbInternal(SurfaceData surfaceData)
        {
            var colors = stackalloc ArgbColor[4];

            fixed(byte *dataPointer = data)
            {
                var destinationRowPointer = (byte *)surfaceData.DataPointer;
                var sourcePointer         = dataPointer;
                int rowBlockStride        = surfaceData.Stride << 2;

                for (int i = Height; i > 0; i -= 4, destinationRowPointer += rowBlockStride)
                {
                    var destinationPointer = destinationRowPointer;

                    for (int j = Width; j > 0; j -= 4)
                    {
                        var alphaPointer = (ushort *)sourcePointer; // Save the alpha block pointer for later

                        sourcePointer += 8;                         // Get to the color block

                        ushort color0 = (ushort)(*sourcePointer++ | *sourcePointer++ << 8);
                        ushort color1 = (ushort)(*sourcePointer++ | *sourcePointer++ << 8);

                        colors[0] = new ArgbColor(color0);
                        colors[1] = new ArgbColor(color1);
                        ArgbColor.DxtMergeThirds(colors + 2, colors + 1, colors);
                        ArgbColor.DxtMergeThirds(colors + 3, colors, colors + 1);

                        // Handle the case where the surface's width is not a multiple of 4.
                        int inverseBlockWidth = j > 4 ? 0 : 4 - j;

                        var blockRowDestinationPointer = destinationPointer;

                        for (int k = 4; k-- != 0; blockRowDestinationPointer += surfaceData.Stride)
                        {
                            byte rowData = *sourcePointer++;

                            if (i + k < 4)
                            {
                                continue;                                        // Handle the case where the surface's height is not a multiple of 4.
                            }
                            var blockDestinationPointer = (ArgbColor *)blockRowDestinationPointer;

                            // The small loop here has been unrolled, which should be well worth it:
                            //  - No loop variable is needed.
                            //  - No useless shift and incrementation for the last step.
                            //  - Only one conditional jump.
                            //  - The loop will be executed very often, as the blocks are very small.
                            switch (inverseBlockWidth)
                            {
                            case 0:
                                ArgbColor.CopyWithAlpha(blockDestinationPointer++, &colors[rowData & 3], (byte)(*alphaPointer << 4));
                                rowData >>= 2;
                                goto case 1;

                            case 1:
                                ArgbColor.CopyWithAlpha(blockDestinationPointer++, &colors[rowData & 3], (byte)(*alphaPointer & 0xF0));
                                rowData >>= 2;
                                goto case 2;

                            case 2:
                                ArgbColor.CopyWithAlpha(blockDestinationPointer++, &colors[rowData & 3], (byte)((*alphaPointer >> 4) & 0xF0));
                                rowData >>= 2;
                                goto case 3;

                            case 3:
                                ArgbColor.CopyWithAlpha(blockDestinationPointer, &colors[rowData & 3], (byte)((*alphaPointer++ >> 8) & 0xF0));
                                break;
                            }
                        }

                        destinationPointer += 4 * sizeof(uint);                         // Skip the 4 processed pixels
                    }
                }
            }
        }
All Usage Examples Of CrystalMpq.DataFormats.ArgbColor::DxtMergeThirds