Exemple #1
0
        unsafe void DecompressBlockDXT5(int x, int y, int width, int height, byte *blockStorage, DDSBitmap image)
        {
            byte alpha0 = blockStorage[0];
            byte alpha1 = blockStorage[1];

            ushort alphaCode2 = *((ushort *)(blockStorage + 2));
            uint   alphaCode1 = *((uint *)(blockStorage + 4));


            ushort color0 = *((ushort *)(blockStorage + 8));
            ushort color1 = *((ushort *)(blockStorage + 10));

            int temp;

            temp = (color0 >> 11) * 255 + 16;
            byte r0 = (byte)((temp / 32 + temp) / 32);

            temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
            byte g0 = (byte)((temp / 64 + temp) / 64);

            temp = (color0 & 0x001F) * 255 + 16;
            byte b0 = (byte)((temp / 32 + temp) / 32);

            temp = (color1 >> 11) * 255 + 16;
            byte r1 = (byte)((temp / 32 + temp) / 32);

            temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
            byte g1 = (byte)((temp / 64 + temp) / 64);

            temp = (color1 & 0x001F) * 255 + 16;
            byte b1 = (byte)((temp / 32 + temp) / 32);

            uint code = *((uint *)(blockStorage + 12));

            for (int j = 0; j < 4; j++)
            {
                for (int i = 0; i < 4; i++)
                {
                    int alphaCodeIndex = 3 * (4 * j + i);
                    int alphaCode;

                    if (alphaCodeIndex <= 12)
                    {
                        alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07;
                    }
                    else if (alphaCodeIndex == 15)
                    {
                        alphaCode = (int)((alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06));
                    }
                    else
                    {
                        alphaCode = (int)((alphaCode1 >> (alphaCodeIndex - 16)) & 0x07);
                    }

                    byte finalAlpha;
                    if (alphaCode == 0)
                    {
                        finalAlpha = alpha0;
                    }
                    else if (alphaCode == 1)
                    {
                        finalAlpha = alpha1;
                    }
                    else
                    {
                        if (alpha0 > alpha1)
                        {
                            finalAlpha = (byte)(((8 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 7);
                        }
                        else
                        {
                            if (alphaCode == 6)
                            {
                                finalAlpha = 0;
                            }
                            else if (alphaCode == 7)
                            {
                                finalAlpha = 255;
                            }
                            else
                            {
                                finalAlpha = (byte)(((6 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 5);
                            }
                        }
                    }

                    byte colorCode = (byte)((code >> 2 * (4 * j + i)) & 0x03);

                    int finalColor = 0;
                    switch (colorCode)
                    {
                    case 0:
                        finalColor = Color.FromArgb(finalAlpha, r0, g0, b0);
                        break;

                    case 1:
                        finalColor = Color.FromArgb(finalAlpha, r1, g1, b1);
                        break;

                    case 2:
                        finalColor = Color.FromArgb(finalAlpha, (byte)((2 * r0 + r1) / 3), (byte)((2 * g0 + g1) / 3), (byte)((2 * b0 + b1) / 3));
                        break;

                    case 3:
                        finalColor = Color.FromArgb(finalAlpha, (byte)((r0 + 2 * r1) / 3), (byte)((g0 + 2 * g1) / 3), (byte)((b0 + 2 * b1) / 3));
                        break;
                    }

                    if (x + i < width && y + j < height)
                    {
                        image.SetPixel(x + i, y + j, finalColor);
                    }
                    //image[(y + j)*width + (x + i)] = finalColor;
                }
            }
        }
Exemple #2
0
        private unsafe void DecompressBlockDXT1(int x, int y, int width, int height, byte *blockStorage, DDSBitmap image)
        {
            ushort color0 = *((ushort *)(blockStorage));
            ushort color1 = *((ushort *)(blockStorage + 2));

            int temp;

            temp = (color0 >> 11) * 255 + 16;
            byte r0 = (byte)((temp / 32 + temp) / 32);

            temp = ((color0 & 0x07E0) >> 5) * 255 + 32;
            byte g0 = (byte)((temp / 64 + temp) / 64);

            temp = (color0 & 0x001F) * 255 + 16;
            byte b0 = (byte)((temp / 32 + temp) / 32);

            temp = (color1 >> 11) * 255 + 16;
            byte r1 = (byte)((temp / 32 + temp) / 32);

            temp = ((color1 & 0x07E0) >> 5) * 255 + 32;
            byte g1 = (byte)((temp / 64 + temp) / 64);

            temp = (color1 & 0x001F) * 255 + 16;
            byte b1 = (byte)((temp / 32 + temp) / 32);

            uint code = *((uint *)(blockStorage + 4));

            for (int j = 0; j < 4; j++)
            {
                for (int i = 0; i < 4; i++)
                {
                    int  finalColor   = 0;
                    byte positionCode = (byte)((code >> 2 * (4 * j + i)) & 0x03);

                    if (color0 > color1)
                    {
                        switch (positionCode)
                        {
                        case 0:
                            finalColor = Color.FromArgb(255, r0, g0, b0);
                            break;

                        case 1:
                            finalColor = Color.FromArgb(255, r1, g1, b1);
                            break;

                        case 2:
                            finalColor = Color.FromArgb(255, (byte)((2 * r0 + r1) / 3), (byte)((2 * g0 + g1) / 3), (byte)((2 * b0 + b1) / 3));
                            break;

                        case 3:
                            finalColor = Color.FromArgb(255, (byte)((r0 + 2 * r1) / 3), (byte)((g0 + 2 * g1) / 3), (byte)((b0 + 2 * b1) / 3));
                            break;
                        }
                    }
                    else
                    {
                        switch (positionCode)
                        {
                        case 0:
                            finalColor = Color.FromArgb(255, r0, g0, b0);
                            break;

                        case 1:
                            finalColor = Color.FromArgb(255, r1, g1, b1);
                            break;

                        case 2:
                            finalColor = Color.FromArgb(255, (byte)((r0 + r1) / 2), (byte)((g0 + g1) / 2), (byte)((b0 + b1) / 2));
                            break;

                        case 3:
                            finalColor = Color.FromArgb(255, 0, 0, 0);
                            break;
                        }
                    }

                    if (x + i < width && y + j < height)
                    {
                        image.SetPixel(x + i, y + j, finalColor);
                    }
                }
            }
        }