Esempio n. 1
0
 private static RLEPacketType PacketType(Color32[] _arData, int _iPacketPosition)
 {
     if ((_iPacketPosition != _arData.Length - 1) && ExtTexture.Equals(_arData[_iPacketPosition], _arData[_iPacketPosition + 1]))
     {
         return(RLEPacketType.RLE);
     }
     else
     {
         return(RLEPacketType.RAW);
     }
 }
Esempio n. 2
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="_texture2D"></param>
    /// <returns></returns>
    public static byte[] EncodeToTGA(this Texture2D _texture2D)
    {
        const int iTgaHeaderSize       = 18;
        const int iBytesPerPixelRGB24  = 3; // 1 byte per channel (rgb)
        const int iBytesPerPixelARGB32 = 4; // ~ (rgba)

        var useAlpha       = SupportsAlpha(_texture2D.format);
        int iBytesPerPixel = useAlpha ? iBytesPerPixelARGB32 : iBytesPerPixelRGB24;

        //

        using (MemoryStream memoryStream = new MemoryStream(iTgaHeaderSize + _texture2D.width * _texture2D.height * iBytesPerPixel))
        {
            using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
            {
                // Write TGA Header

                binaryWriter.Write((byte)0);                    // IDLength (not in use)
                binaryWriter.Write((byte)0);                    // ColorMapType (not in use)
                binaryWriter.Write((byte)10);                   // DataTypeCode == 10 (Runlength encoded RGB images)
                binaryWriter.Write((short)0);                   // ColorMapOrigin (not in use)
                binaryWriter.Write((short)0);                   // ColorMapLength (not in use)
                binaryWriter.Write((byte)0);                    // ColorMapDepth (not in use)
                binaryWriter.Write((short)0);                   // Origin X
                binaryWriter.Write((short)0);                   // Origin Y
                binaryWriter.Write((short)_texture2D.width);    // Width
                binaryWriter.Write((short)_texture2D.height);   // Height
                binaryWriter.Write((byte)(iBytesPerPixel * 8)); // Bits Per Pixel
                binaryWriter.Write((byte)0);                    // ImageDescriptor (not in use)

                // Write RLE Encoded Pixels

                Color32[] arPixels = _texture2D.GetPixels32();

                const int iMaxPacketLength = 128;
                int       iPacketStart     = 0;
                int       iPacketEnd       = 0;

                while (iPacketStart < arPixels.Length)
                {
                    Color32 c32PreviousPixel = arPixels[iPacketStart];

                    // Get current Packet Type
                    RLEPacketType packetType = ExtTexture.PacketType(arPixels, iPacketStart);

                    // Find Packet End
                    int iReadEnd = Mathf.Min(iPacketStart + iMaxPacketLength, arPixels.Length);
                    for (iPacketEnd = iPacketStart + 1; iPacketEnd < iReadEnd; ++iPacketEnd)
                    {
                        bool bPreviousEqualsCurrent = ExtTexture.Equals(arPixels[iPacketEnd - 1], arPixels[iPacketEnd]);

                        // Packet End if change in Packet Type or if max Packet-Size reached
                        if (packetType == RLEPacketType.RAW && bPreviousEqualsCurrent ||
                            packetType == RLEPacketType.RLE && !bPreviousEqualsCurrent)
                        {
                            break;
                        }
                    }

                    // Write Packet

                    int iPacketLength = iPacketEnd - iPacketStart;

                    switch (packetType)
                    {
                    case RLEPacketType.RLE:

                        // Add RLE-Bit to PacketLength
                        binaryWriter.Write((byte)((iPacketLength - 1) | (1 << 7)));

                        binaryWriter.Write(c32PreviousPixel.b);
                        binaryWriter.Write(c32PreviousPixel.g);
                        binaryWriter.Write(c32PreviousPixel.r);

                        if (useAlpha)
                        {
                            binaryWriter.Write(c32PreviousPixel.a);
                        }

                        break;

                    case RLEPacketType.RAW:

                        binaryWriter.Write((byte)(iPacketLength - 1));

                        for (int iPacketPosition = iPacketStart; iPacketPosition < iPacketEnd; ++iPacketPosition)
                        {
                            binaryWriter.Write(arPixels[iPacketPosition].b);
                            binaryWriter.Write(arPixels[iPacketPosition].g);
                            binaryWriter.Write(arPixels[iPacketPosition].r);

                            if (useAlpha)
                            {
                                binaryWriter.Write(arPixels[iPacketPosition].a);
                            }
                        }

                        break;
                    }

                    iPacketStart = iPacketEnd;
                }
            }

            return(memoryStream.GetBuffer());
        }
    }