示例#1
0
        private static void CompressDxt5Block(byte[] data, int offset, int width, System.IO.Stream output)
        {
            int r1 = 255, g1 = 255, b1 = 255, a1 = 255;
            int r2 = 0, g2 = 0, b2 = 0, a2 = 0;

            //determine the two colors to interpolate between:
            //color 1 represents lowest luma, color 2 represents highest luma
            for (int i = 0; i < 16; i++)
            {
                int pixelOffset = offset + (4 * ((i % 4) + (width * (i >> 2))));
                int r, g, b, a;
                r = data[pixelOffset + 0];
                g = data[pixelOffset + 1];
                b = data[pixelOffset + 2];
                a = data[pixelOffset + 3];
                if (r * 299 + g * 587 + b * 114 < r1 * 299 + g1 * 587 + b1 * 114)
                {
                    r1 = r; g1 = g; b1 = b;
                }
                if (r * 299 + g * 587 + b * 114 > r2 * 299 + g2 * 587 + b2 * 114)
                {
                    r2 = r; g2 = g; b2 = b;
                }
                if (a < a1)
                {
                    a1 = a;
                }
                if (a > a2)
                {
                    a2 = a;
                }
            }

            //convert the colors to rgb565 (16-bit rgb)
            int r1_565 = (r1 * 0x1f) / 0xff; if (r1_565 > 0x1f)
            {
                r1_565 = 0x1f;
            }
            int g1_565 = (g1 * 0x3f) / 0xff; if (g1_565 > 0x3f)
            {
                g1_565 = 0x3f;
            }
            int b1_565 = (b1 * 0x1f) / 0xff; if (b1_565 > 0x1f)
            {
                b1_565 = 0x1f;
            }

            int r2_565 = (r2 * 0x1f) / 0xff; if (r2_565 > 0x1f)
            {
                r2_565 = 0x1f;
            }
            int g2_565 = (g2 * 0x3f) / 0xff; if (g2_565 > 0x3f)
            {
                g2_565 = 0x3f;
            }
            int b2_565 = (b2 * 0x1f) / 0xff; if (b2_565 > 0x1f)
            {
                b2_565 = 0x1f;
            }

            //luma is also used to determine which color on the palette
            //most closely resembles each pixel to compress, so we
            //calculate this here
            int y1 = r1 * 299 + g1 * 587 + b1 * 114;
            int y2 = r2 * 299 + g2 * 587 + b2 * 114;

            byte[] newData = new byte[16];
            for (int i = 0; i < 16; i++)
            {
                int pixelOffset = offset + (4 * ((i % 4) + (width * (i >> 2))));
                int r, g, b, a;
                r = data[pixelOffset + 0];
                g = data[pixelOffset + 1];
                b = data[pixelOffset + 2];
                a = data[pixelOffset + 3];

                if (a1 < a2)
                {
                    a -= a1;
                    a  = (a * 0x7) / (a2 - a1);
                    if (a > 0x7)
                    {
                        a = 0x7;
                    }

                    switch (a)
                    {
                    case 0:
                        a = 1;
                        break;

                    case 1:
                        a = 7;
                        break;

                    case 2:
                        a = 6;
                        break;

                    case 3:
                        a = 5;
                        break;

                    case 4:
                        a = 4;
                        break;

                    case 5:
                        a = 3;
                        break;

                    case 6:
                        a = 2;
                        break;

                    case 7:
                        a = 0;
                        break;
                    }
                }
                else
                {
                    a = 0;
                }

                NetBitWriter.WriteUInt32((uint)a, 3, newData, 16 + (i * 3));

                int y = r * 299 + g * 587 + b * 114;

                int max   = y2 - y1;
                int diffY = y - y1;

                int paletteIndex;
                if (diffY < max / 4)
                {
                    paletteIndex = 0;
                }
                else if (diffY < max / 2)
                {
                    paletteIndex = 2;
                }
                else if (diffY < max * 3 / 4)
                {
                    paletteIndex = 3;
                }
                else
                {
                    paletteIndex = 1;
                }
                newData[12 + (i / 4)] |= (byte)(paletteIndex << (2 * (i % 4)));
            }

            newData[0] = (byte)a2;
            newData[1] = (byte)a1;

            newData[9]  = (byte)((r1_565 << 3) | (g1_565 >> 3));
            newData[8]  = (byte)((g1_565 << 5) | b1_565);
            newData[11] = (byte)((r2_565 << 3) | (g2_565 >> 3));
            newData[10] = (byte)((g2_565 << 5) | b2_565);

            output.Write(newData, 0, 16);
        }
示例#2
0
 internal static void Write(ref byte[] buf, ref int bitPos, UInt32 val)
 {
     EnsureBufferSize(ref buf, bitPos + 32);
     NetBitWriter.WriteUInt32(val, 32, buf, bitPos);
     bitPos += 32;
 }
示例#3
0
 internal static void Write(ref byte[] buf, ref int bitPos, Int16 val)
 {
     EnsureBufferSize(ref buf, bitPos + 16);
     NetBitWriter.WriteUInt16((UInt16)val, 16, buf, bitPos);
     bitPos += 16;
 }
示例#4
0
 internal static void Write(ref byte[] buf, ref int bitPos, byte val)
 {
     EnsureBufferSize(ref buf, bitPos + 8);
     NetBitWriter.WriteByte(val, 8, buf, bitPos);
     bitPos += 8;
 }
示例#5
0
 internal static void WriteBytes(ref byte[] buf, ref int bitPos, byte[] val, int pos, int length)
 {
     EnsureBufferSize(ref buf, bitPos + length * 8);
     NetBitWriter.WriteBytes(val, pos, length, buf, bitPos);
     bitPos += length * 8;
 }
示例#6
0
 internal static void Write(ref byte[] buf, ref int bitPos, Int64 val)
 {
     EnsureBufferSize(ref buf, bitPos + 64);
     NetBitWriter.WriteUInt64((UInt64)val, 64, buf, bitPos);
     bitPos += 64;
 }