예제 #1
0
        internal static void WriteRangedSingle(ref byte[] buf, ref int bitPos, Single val, Single min, Single max, int numberOfBits)
        {
            float range  = max - min;
            float unit   = ((val - min) / range);
            int   maxVal = (1 << numberOfBits) - 1;

            EnsureBufferSize(ref buf, bitPos + numberOfBits);

            NetBitWriter.WriteUInt32((UInt32)((float)maxVal * unit), numberOfBits, buf, bitPos);
            bitPos += numberOfBits;
        }
예제 #2
0
        internal static void WriteRangedInteger(ref byte[] buf, ref int bitPos, int val, int min, int max)
        {
            uint range        = (uint)(max - min);
            int  numberOfBits = NetUtility.BitsToHoldUInt(range);

            EnsureBufferSize(ref buf, bitPos + numberOfBits);

            uint rvalue = (uint)(val - min);

            NetBitWriter.WriteUInt32(rvalue, numberOfBits, buf, bitPos);
            bitPos += numberOfBits;
        }
예제 #3
0
        internal static void Write(ref byte[] buf, ref int bitPos, Single val)
        {
            // Use union to avoid BitConverter.GetBytes() which allocates memory on the heap
            SingleUIntUnion su;

            su.UIntValue   = 0; // must initialize every member of the union to avoid warning
            su.SingleValue = val;

            EnsureBufferSize(ref buf, bitPos + 32);

            NetBitWriter.WriteUInt32(su.UIntValue, 32, buf, bitPos);
            bitPos += 32;
        }
예제 #4
0
        /// <summary>
        /// Writes a 32 bit signed integer
        /// </summary>
        public unsafe BitWriter Write(Int32 source)
        {
            EnsureBufferSize(m_bitLength + 32);

            // can write fast?
            if (m_bitLength % 8 == 0)
            {
                fixed(byte *numRef = &Data[m_bitLength / 8])
                {
                    *((int *)numRef) = source;
                }
            }
            else
            {
                NetBitWriter.WriteUInt32((UInt32)source, 32, Data, m_bitLength);
            }
            m_bitLength += 32;

            return(this);
        }
예제 #5
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);
        }
예제 #6
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;
 }