< Summary

Class:UniGif
Assembly:UniGif
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGif.cs
/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGifConst.cs
/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGifDecoder.cs
/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGifFormatter.cs
Covered lines:331
Uncovered lines:201
Coverable lines:532
Total lines:1512
Line coverage:62.2% (331 of 532)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
GetTextureListCoroutine()0%12.899063.64%
Dump()0%20400%
DecodeTextureCoroutine()0%1010096.67%
GetDecodedData(...)0%4.014092.31%
GetColorTableAndSetBgColor(...)0%8.198085.71%
GetGraphicCtrlExt(...)0%3.333066.67%
GetTransparentIndex(...)0%330100%
GetDelaySec(...)0%4.254075%
GetDisposalMethod(...)0%220100%
CreateTexture2D(...)0%13.3712078.79%
SetTexturePixelRow(...)0%68.3719048.48%
DecodeGifLZW(...)0%39.4333081.93%
InitDictionary(...)0%220100%
SortInterlaceGifData(...)0%3801900%
SetGifData(...)0%15.727043.75%
SetGifHeader(...)0%44.7821062.22%
SetGifBlock(...)0%12.9910068.97%
SetImageBlock(...)0%7.127086.67%
SetGraphicControlExtension(...)0%5.165081.48%
SetCommentExtension(...)0%30500%
SetPlainTextExtension(...)0%30500%
SetApplicationExtension(...)0%440100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGif.cs

#LineLine coverage
 1/*
 2UniGif
 3Copyright (c) 2015 WestHillApps (Hironari Nishioka)
 4This software is released under the MIT License.
 5http://opensource.org/licenses/mit-license.php
 6*/
 7
 8using System;
 9using System.Collections;
 10using System.Collections.Generic;
 11using UnityEngine;
 12
 13public static partial class UniGif
 14{
 15    /// <summary>
 16    /// Get GIF texture list Coroutine
 17    /// </summary>
 18    /// <param name="bytes">GIF file byte data</param>
 19    /// <param name="callback">Callback method(param is GIF texture list, Animation loop count, GIF image width (px), GI
 20    /// <param name="filterMode">Textures filter mode</param>
 21    /// <param name="wrapMode">Textures wrap mode</param>
 22    /// <param name="debugLog">Debug Log Flag</param>
 23    /// <returns>IEnumerator</returns>
 24    public static IEnumerator GetTextureListCoroutine(
 25        byte[] bytes,
 26        Action<GifFrameData[], int, int, int> callback,
 27        FilterMode filterMode = FilterMode.Bilinear,
 28        TextureWrapMode wrapMode = TextureWrapMode.Clamp,
 29        bool debugLog = false)
 30    {
 431        int loopCount = -1;
 432        int width = 0;
 433        int height = 0;
 34
 35        // Set GIF data
 436        var gifData = new GifData();
 437        if (SetGifData(bytes, ref gifData, debugLog) == false)
 38        {
 039            Debug.LogError("GIF file data set error.");
 040            if (callback != null)
 41            {
 042                callback(null, loopCount, width, height);
 43            }
 044            yield break;
 45        }
 46
 47        // Decode to textures from GIF data
 448        GifFrameData[] gifTexList = null;
 849        yield return DecodeTextureCoroutine(gifData, result => gifTexList = result, filterMode, wrapMode);
 50
 451        if (gifTexList == null || gifTexList.Length <= 0)
 52        {
 053            Debug.LogError("GIF texture decode error.");
 054            if (callback != null)
 55            {
 056                callback(null, loopCount, width, height);
 57            }
 058            yield break;
 59        }
 60
 461        loopCount = gifData.m_appEx.loopCount;
 462        width = gifData.m_logicalScreenWidth;
 463        height = gifData.m_logicalScreenHeight;
 64
 465        if (callback != null)
 66        {
 467            callback(gifTexList, loopCount, width, height);
 68        }
 69
 470        yield break;
 71    }
 72}

/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGifConst.cs

#LineLine coverage
 1/*
 2UniGif
 3Copyright (c) 2015 WestHillApps (Hironari Nishioka)
 4This software is released under the MIT License.
 5http://opensource.org/licenses/mit-license.php
 6*/
 7
 8using System;
 9using System.Collections.Generic;
 10using System.Text;
 11using UnityEngine;
 12
 13public static partial class UniGif
 14{
 15    /// <summary>
 16    /// GIF Data Format
 17    /// </summary>
 18    private struct GifData
 19    {
 20        // Signature
 21        public byte m_sig0, m_sig1, m_sig2;
 22        // Version
 23        public byte m_ver0, m_ver1, m_ver2;
 24        // Logical Screen Width
 25        public ushort m_logicalScreenWidth;
 26        // Logical Screen Height
 27        public ushort m_logicalScreenHeight;
 28        // Global Color Table Flag
 29        public bool m_globalColorTableFlag;
 30        // Color Resolution
 31        public int m_colorResolution;
 32        // Sort Flag
 33        public bool m_sortFlag;
 34        // Size of Global Color Table
 35        public int m_sizeOfGlobalColorTable;
 36        // Background Color Index
 37        public byte m_bgColorIndex;
 38        // Pixel Aspect Ratio
 39        public byte m_pixelAspectRatio;
 40        // Global Color Table
 41        public List<byte[]> m_globalColorTable;
 42        // ImageBlock
 43        public List<ImageBlock> m_imageBlockList;
 44        // GraphicControlExtension
 45        public List<GraphicControlExtension> m_graphicCtrlExList;
 46        // Comment Extension
 47        public List<CommentExtension> m_commentExList;
 48        // Plain Text Extension
 49        public List<PlainTextExtension> m_plainTextExList;
 50        // Application Extension
 51        public ApplicationExtension m_appEx;
 52        // Trailer
 53        public byte m_trailer;
 54
 55        public string signature
 56        {
 57            get
 58            {
 059                char[] c = { (char)m_sig0, (char)m_sig1, (char)m_sig2 };
 060                return new string(c);
 61            }
 62        }
 63
 64        public string version
 65        {
 66            get
 67            {
 068                char[] c = { (char)m_ver0, (char)m_ver1, (char)m_ver2 };
 069                return new string(c);
 70            }
 71        }
 72
 73        public void Dump()
 74        {
 075            Debug.Log("GIF Type: " + signature + "-" + version);
 076            Debug.Log("Image Size: " + m_logicalScreenWidth + "x" + m_logicalScreenHeight);
 077            Debug.Log("Animation Image Count: " + m_imageBlockList.Count);
 078            Debug.Log("Animation Loop Count (0 is infinite): " + m_appEx.loopCount);
 079            if (m_graphicCtrlExList != null && m_graphicCtrlExList.Count > 0)
 80            {
 081                var sb = new StringBuilder("Animation Delay Time (1/100sec)");
 082                for (int i = 0; i < m_graphicCtrlExList.Count; i++)
 83                {
 084                    sb.Append(", ");
 085                    sb.Append(m_graphicCtrlExList[i].m_delayTime);
 86                }
 087                Debug.Log(sb.ToString());
 88            }
 089            Debug.Log("Application Identifier: " + m_appEx.applicationIdentifier);
 090            Debug.Log("Application Authentication Code: " + m_appEx.applicationAuthenticationCode);
 091        }
 92    }
 93
 94    /// <summary>
 95    /// Image Block
 96    /// </summary>
 97    private struct ImageBlock
 98    {
 99        // Image Separator
 100        public byte m_imageSeparator;
 101        // Image Left Position
 102        public ushort m_imageLeftPosition;
 103        // Image Top Position
 104        public ushort m_imageTopPosition;
 105        // Image Width
 106        public ushort m_imageWidth;
 107        // Image Height
 108        public ushort m_imageHeight;
 109        // Local Color Table Flag
 110        public bool m_localColorTableFlag;
 111        // Interlace Flag
 112        public bool m_interlaceFlag;
 113        // Sort Flag
 114        public bool m_sortFlag;
 115        // Size of Local Color Table
 116        public int m_sizeOfLocalColorTable;
 117        // Local Color Table
 118        public List<byte[]> m_localColorTable;
 119        // LZW Minimum Code Size
 120        public byte m_lzwMinimumCodeSize;
 121        // Block Size & Image Data List
 122        public List<ImageDataBlock> m_imageDataList;
 123
 124        public struct ImageDataBlock
 125        {
 126            // Block Size
 127            public byte m_blockSize;
 128            // Image Data
 129            public byte[] m_imageData;
 130        }
 131    }
 132
 133    /// <summary>
 134    /// Graphic Control Extension
 135    /// </summary>
 136    private struct GraphicControlExtension
 137    {
 138        // Extension Introducer
 139        public byte m_extensionIntroducer;
 140        // Graphic Control Label
 141        public byte m_graphicControlLabel;
 142        // Block Size
 143        public byte m_blockSize;
 144        // Disposal Mothod
 145        public ushort m_disposalMethod;
 146        // Transparent Color Flag
 147        public bool m_transparentColorFlag;
 148        // Delay Time
 149        public ushort m_delayTime;
 150        // Transparent Color Index
 151        public byte m_transparentColorIndex;
 152        // Block Terminator
 153        public byte m_blockTerminator;
 154    }
 155
 156    /// <summary>
 157    /// Comment Extension
 158    /// </summary>
 159    private struct CommentExtension
 160    {
 161        // Extension Introducer
 162        public byte m_extensionIntroducer;
 163        // Comment Label
 164        public byte m_commentLabel;
 165        // Block Size & Comment Data List
 166        public List<CommentDataBlock> m_commentDataList;
 167
 168        public struct CommentDataBlock
 169        {
 170            // Block Size
 171            public byte m_blockSize;
 172            // Image Data
 173            public byte[] m_commentData;
 174        }
 175    }
 176
 177    /// <summary>
 178    /// Plain Text Extension
 179    /// </summary>
 180    private struct PlainTextExtension
 181    {
 182        // Extension Introducer
 183        public byte m_extensionIntroducer;
 184        // Plain Text Label
 185        public byte m_plainTextLabel;
 186        // Block Size
 187        public byte m_blockSize;
 188        // Block Size & Plain Text Data List
 189        public List<PlainTextDataBlock> m_plainTextDataList;
 190
 191        public struct PlainTextDataBlock
 192        {
 193            // Block Size
 194            public byte m_blockSize;
 195            // Plain Text Data
 196            public byte[] m_plainTextData;
 197        }
 198    }
 199
 200    /// <summary>
 201    /// Application Extension
 202    /// </summary>
 203    private struct ApplicationExtension
 204    {
 205        // Extension Introducer
 206        public byte m_extensionIntroducer;
 207        // Extension Label
 208        public byte m_extensionLabel;
 209        // Block Size
 210        public byte m_blockSize;
 211        // Application Identifier
 212        public byte m_appId1, m_appId2, m_appId3, m_appId4, m_appId5, m_appId6, m_appId7, m_appId8;
 213        // Application Authentication Code
 214        public byte m_appAuthCode1, m_appAuthCode2, m_appAuthCode3;
 215        // Block Size & Application Data List
 216        public List<ApplicationDataBlock> m_appDataList;
 217
 218        public struct ApplicationDataBlock
 219        {
 220            // Block Size
 221            public byte m_blockSize;
 222            // Application Data
 223            public byte[] m_applicationData;
 224        }
 225
 226        public string applicationIdentifier
 227        {
 228            get
 229            {
 0230                char[] c = { (char)m_appId1, (char)m_appId2, (char)m_appId3, (char)m_appId4, (char)m_appId5, (char)m_app
 0231                return new string(c);
 232            }
 233        }
 234
 235        public string applicationAuthenticationCode
 236        {
 237            get
 238            {
 0239                char[] c = { (char)m_appAuthCode1, (char)m_appAuthCode2, (char)m_appAuthCode3 };
 0240                return new string(c);
 241            }
 242        }
 243
 244        public int loopCount
 245        {
 246            get
 247            {
 4248                if (m_appDataList == null || m_appDataList.Count < 1 ||
 249                    m_appDataList[0].m_applicationData.Length < 3 ||
 250                    m_appDataList[0].m_applicationData[0] != 0x01)
 251                {
 0252                    return 0;
 253                }
 4254                return BitConverter.ToUInt16(m_appDataList[0].m_applicationData, 1);
 255            }
 256        }
 257    }
 258}

/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGifDecoder.cs

#LineLine coverage
 1/*
 2UniGif
 3Copyright (c) 2015 WestHillApps (Hironari Nishioka)
 4This software is released under the MIT License.
 5http://opensource.org/licenses/mit-license.php
 6*/
 7
 8using System;
 9using System.Collections;
 10using System.Collections.Generic;
 11using System.Text;
 12using UnityEngine;
 13
 14public static partial class UniGif
 15{
 16    /// <summary>
 17    /// Decode to textures from GIF data
 18    /// </summary>
 19    /// <param name="gifData">GIF data</param>
 20    /// <param name="callback">Callback method(param is GIF texture list)</param>
 21    /// <param name="filterMode">Textures filter mode</param>
 22    /// <param name="wrapMode">Textures wrap mode</param>
 23    /// <returns>IEnumerator</returns>
 24    private static IEnumerator DecodeTextureCoroutine(GifData gifData, Action<GifFrameData[]> callback, FilterMode filte
 25    {
 426        if (gifData.m_imageBlockList == null || gifData.m_imageBlockList.Count < 1)
 27        {
 028            yield break;
 29        }
 30
 431        GifFrameData[] gifTexList = new GifFrameData[gifData.m_imageBlockList.Count];
 432        List<ushort> disposalMethodList = new List<ushort>(gifData.m_imageBlockList.Count);
 33
 434        int imgIndex = 0;
 35
 36836        for (int i = 0; i < gifData.m_imageBlockList.Count; i++)
 37        {
 18038            byte[] decodedData = GetDecodedData(gifData.m_imageBlockList[i]);
 39
 18040            GraphicControlExtension? graphicCtrlEx = GetGraphicCtrlExt(gifData, imgIndex);
 41
 18042            int transparentIndex = GetTransparentIndex(graphicCtrlEx);
 43
 18044            disposalMethodList.Add(GetDisposalMethod(graphicCtrlEx));
 45
 46            Color32 bgColor;
 18047            List<byte[]> colorTable = GetColorTableAndSetBgColor(gifData, gifData.m_imageBlockList[i], transparentIndex,
 48
 18049            yield return 0;
 50
 51            bool filledTexture;
 18052            Texture2D tex = CreateTexture2D(gifData, gifTexList, imgIndex, disposalMethodList, bgColor, filterMode, wrap
 53
 18054            yield return 0;
 55
 56            // Set pixel data
 18057            int dataIndex = 0;
 58            // Reverse set pixels. because GIF data starts from the top left.
 4104059            for (int y = tex.height - 1; y >= 0; y--)
 60            {
 2034061                SetTexturePixelRow(tex, y, gifData.m_imageBlockList[i], decodedData, ref dataIndex, colorTable, bgColor,
 62            }
 18063            tex.Apply();
 64
 18065            yield return 0;
 66
 18067            float delaySec = GetDelaySec(graphicCtrlEx);
 68
 69            // Add to GIF texture list
 18070            gifTexList[imgIndex] = new GifFrameData() {texture = tex, delay = delaySec};
 71
 18072            imgIndex++;
 18073        }
 74
 475        if (callback != null)
 76        {
 477            callback(gifTexList);
 78        }
 79
 480        yield break;
 81    }
 82
 83    #region Call from DecodeTexture methods
 84
 85    /// <summary>
 86    /// Get decoded image data from ImageBlock
 87    /// </summary>
 88    private static byte[] GetDecodedData(ImageBlock imgBlock)
 89    {
 90        // Combine LZW compressed data
 18091        List<byte> lzwData = new List<byte>();
 2124092        for (int i = 0; i < imgBlock.m_imageDataList.Count; i++)
 93        {
 529960894            for (int k = 0; k < imgBlock.m_imageDataList[i].m_imageData.Length; k++)
 95            {
 263936496                lzwData.Add(imgBlock.m_imageDataList[i].m_imageData[k]);
 97            }
 98        }
 99
 100        // LZW decode
 180101        int needDataSize = imgBlock.m_imageHeight * imgBlock.m_imageWidth;
 180102        byte[] decodedData = DecodeGifLZW(lzwData, imgBlock.m_lzwMinimumCodeSize, needDataSize);
 103
 104        // Sort interlace GIF
 180105        if (imgBlock.m_interlaceFlag)
 106        {
 0107            decodedData = SortInterlaceGifData(decodedData, imgBlock.m_imageWidth);
 108        }
 180109        return decodedData;
 110    }
 111
 112    /// <summary>
 113    /// Get color table and set background color (local or global)
 114    /// </summary>
 115    private static List<byte[]> GetColorTableAndSetBgColor(GifData gifData, ImageBlock imgBlock, int transparentIndex, o
 116    {
 180117        List<byte[]> colorTable = imgBlock.m_localColorTableFlag ? imgBlock.m_localColorTable : gifData.m_globalColorTab
 118
 180119        if (colorTable != null)
 120        {
 121            // Set background color from color table
 180122            byte[] bgRgb = colorTable[gifData.m_bgColorIndex];
 180123            bgColor = new Color32(bgRgb[0], bgRgb[1], bgRgb[2], (byte)(transparentIndex == gifData.m_bgColorIndex ? 0 : 
 180124        }
 125        else
 126        {
 0127            bgColor = Color.black;
 128        }
 129
 180130        return colorTable;
 131    }
 132
 133    /// <summary>
 134    /// Get GraphicControlExtension from GifData
 135    /// </summary>
 136    private static GraphicControlExtension? GetGraphicCtrlExt(GifData gifData, int imgBlockIndex)
 137    {
 180138        if (gifData.m_graphicCtrlExList != null && gifData.m_graphicCtrlExList.Count > imgBlockIndex)
 139        {
 180140            return gifData.m_graphicCtrlExList[imgBlockIndex];
 141        }
 0142        return null;
 143    }
 144
 145    /// <summary>
 146    /// Get transparent color index from GraphicControlExtension
 147    /// </summary>
 148    private static int GetTransparentIndex(GraphicControlExtension? graphicCtrlEx)
 149    {
 180150        int transparentIndex = -1;
 180151        if (graphicCtrlEx != null && graphicCtrlEx.Value.m_transparentColorFlag)
 152        {
 180153            transparentIndex = graphicCtrlEx.Value.m_transparentColorIndex;
 154        }
 180155        return transparentIndex;
 156    }
 157
 158    /// <summary>
 159    /// Get delay seconds from GraphicControlExtension
 160    /// </summary>
 161    private static float GetDelaySec(GraphicControlExtension? graphicCtrlEx)
 162    {
 163        // Get delay sec from GraphicControlExtension
 180164        float delaySec = graphicCtrlEx != null ? graphicCtrlEx.Value.m_delayTime / 100f : (1f / 60f);
 180165        if (delaySec <= 0f)
 166        {
 0167            delaySec = 0.1f;
 168        }
 180169        return delaySec;
 170    }
 171
 172    /// <summary>
 173    /// Get disposal method from GraphicControlExtension
 174    /// </summary>
 175    private static ushort GetDisposalMethod(GraphicControlExtension? graphicCtrlEx)
 176    {
 180177        return graphicCtrlEx != null ? graphicCtrlEx.Value.m_disposalMethod : (ushort)2;
 178    }
 179
 180    /// <summary>
 181    /// Create Texture2D object and initial settings
 182    /// </summary>
 183    private static Texture2D CreateTexture2D(GifData gifData, GifFrameData[] gifTexList, int imgIndex, List<ushort> disp
 184    {
 180185        filledTexture = false;
 186
 187        // Create texture
 180188        Texture2D tex = new Texture2D(gifData.m_logicalScreenWidth, gifData.m_logicalScreenHeight, TextureFormat.ARGB32,
 180189        tex.filterMode = filterMode;
 180190        tex.wrapMode = wrapMode;
 191
 192        // Check dispose
 180193        ushort disposalMethod = imgIndex > 0 ? disposalMethodList[imgIndex - 1] : (ushort)2;
 180194        int useBeforeIndex = -1;
 180195        if (disposalMethod == 0)
 196        {
 197            // 0 (No disposal specified)
 198        }
 180199        else if (disposalMethod == 1)
 200        {
 201            // 1 (Do not dispose)
 176202            useBeforeIndex = imgIndex - 1;
 176203        }
 4204        else if (disposalMethod == 2)
 205        {
 206            // 2 (Restore to background color)
 4207            filledTexture = true;
 4208            Color32[] pix = new Color32[tex.width * tex.height];
 180808209            for (int i = 0; i < pix.Length; i++)
 210            {
 90400211                pix[i] = bgColor;
 212            }
 4213            tex.SetPixels32(pix);
 4214            tex.Apply();
 4215        }
 0216        else if (disposalMethod == 3)
 217        {
 218            // 3 (Restore to previous)
 0219            for (int i = imgIndex - 1; i >= 0; i--)
 220            {
 0221                if (disposalMethodList[i] == 0 || disposalMethodList[i] == 1)
 222                {
 0223                    useBeforeIndex = i;
 0224                    break;
 225                }
 226            }
 227        }
 228
 180229        if (useBeforeIndex >= 0)
 230        {
 176231            filledTexture = true;
 176232            Color32[] pix = gifTexList[useBeforeIndex].texture.GetPixels32();
 176233            tex.SetPixels32(pix);
 176234            tex.Apply();
 235        }
 236
 180237        return tex;
 238    }
 239
 240    /// <summary>
 241    /// Set texture pixel row
 242    /// </summary>
 243    private static void SetTexturePixelRow(Texture2D tex, int y, ImageBlock imgBlock, byte[] decodedData, ref int dataIn
 244    {
 245        // Row no (0~)
 20340246        int row = tex.height - 1 - y;
 247
 8176680248        for (int x = 0; x < tex.width; x++)
 249        {
 250            // Line no (0~)
 4068000251            int line = x;
 252
 253            // Out of image blocks
 4068000254            if (row < imgBlock.m_imageTopPosition ||
 255                row >= imgBlock.m_imageTopPosition + imgBlock.m_imageHeight ||
 256                line < imgBlock.m_imageLeftPosition ||
 257                line >= imgBlock.m_imageLeftPosition + imgBlock.m_imageWidth)
 258            {
 259                // Get pixel color from bg color
 0260                if (filledTexture == false)
 261                {
 0262                    tex.SetPixel(x, y, bgColor);
 263                }
 0264                continue;
 265            }
 266
 267            // Out of decoded data
 4068000268            if (dataIndex >= decodedData.Length)
 269            {
 0270                if (filledTexture == false)
 271                {
 0272                    tex.SetPixel(x, y, bgColor);
 0273                    if (dataIndex == decodedData.Length)
 274                    {
 0275                        Debug.LogError("dataIndex exceeded the size of decodedData. dataIndex:" + dataIndex + " decodedD
 276                    }
 277                }
 0278                dataIndex++;
 0279                continue;
 280            }
 281
 282            // Get pixel color from color table
 283            {
 4068000284                byte colorIndex = decodedData[dataIndex];
 4068000285                if (colorTable == null || colorTable.Count <= colorIndex)
 286                {
 0287                    if (filledTexture == false)
 288                    {
 0289                        tex.SetPixel(x, y, bgColor);
 0290                        if (colorTable == null)
 291                        {
 0292                            Debug.LogError("colorIndex exceeded the size of colorTable. colorTable is null. colorIndex:"
 0293                        }
 294                        else
 295                        {
 0296                            Debug.LogError("colorIndex exceeded the size of colorTable. colorTable.Count:" + colorTable.
 297                        }
 298                    }
 0299                    dataIndex++;
 0300                    continue;
 301                }
 4068000302                byte[] rgb = colorTable[colorIndex];
 303
 304                // Set alpha
 4068000305                byte alpha = transparentIndex >= 0 && transparentIndex == colorIndex ? (byte)0 : (byte)255;
 306
 4068000307                if (filledTexture == false || alpha != 0)
 308                {
 309                    // Set color
 3836440310                    Color32 col = new Color32(rgb[0], rgb[1], rgb[2], alpha);
 3836440311                    tex.SetPixel(x, y, col);
 312                }
 313            }
 314
 4068000315            dataIndex++;
 316        }
 20340317    }
 318
 319    #endregion
 320
 321    #region Decode LZW & Sort interrace methods
 322
 323    /// <summary>
 324    /// GIF LZW decode
 325    /// </summary>
 326    /// <param name="compData">LZW compressed data</param>
 327    /// <param name="lzwMinimumCodeSize">LZW minimum code size</param>
 328    /// <param name="needDataSize">Need decoded data size</param>
 329    /// <returns>Decoded data array</returns>
 330    private static byte[] DecodeGifLZW(List<byte> compData, int lzwMinimumCodeSize, int needDataSize)
 331    {
 180332        int clearCode = 0;
 180333        int finishCode = 0;
 334
 335        // Initialize dictionary
 180336        Dictionary<int, string> dic = new Dictionary<int, string>();
 180337        int lzwCodeSize = 0;
 180338        InitDictionary(dic, lzwMinimumCodeSize, out lzwCodeSize, out clearCode, out finishCode);
 339
 340        // Convert to bit array
 180341        byte[] compDataArr = compData.ToArray();
 180342        var bitData = new BitArray(compDataArr);
 343
 180344        byte[] output = new byte[needDataSize];
 180345        int outputAddIndex = 0;
 346
 180347        string prevEntry = null;
 348
 180349        bool dicInitFlag = false;
 350
 180351        int bitDataIndex = 0;
 352
 353        // LZW decode loop
 1563024354        while (bitDataIndex < bitData.Length)
 355        {
 1563024356            if (dicInitFlag)
 357            {
 548358                InitDictionary(dic, lzwMinimumCodeSize, out lzwCodeSize, out clearCode, out finishCode);
 548359                dicInitFlag = false;
 360            }
 361
 1563024362            int key = bitData.GetNumeral(bitDataIndex, lzwCodeSize);
 363
 1563024364            string entry = null;
 365
 1563024366            if (key == clearCode)
 367            {
 368                // Clear (Initialize dictionary)
 496369                dicInitFlag = true;
 496370                bitDataIndex += lzwCodeSize;
 496371                prevEntry = null;
 496372                continue;
 373            }
 1562528374            else if (key == finishCode)
 375            {
 376                // Exit
 52377                Debug.LogWarning("early stop code. bitDataIndex:" + bitDataIndex + " lzwCodeSize:" + lzwCodeSize + " key
 52378                break;
 379            }
 1562476380            else if (dic.ContainsKey(key))
 381            {
 382                // Output from dictionary
 1540196383                entry = dic[key];
 1540196384            }
 22280385            else if (key >= dic.Count)
 386            {
 22280387                if (prevEntry != null)
 388                {
 389                    // Output from estimation
 22228390                    entry = prevEntry + prevEntry[0];
 22228391                }
 392                else
 393                {
 52394                    Debug.LogWarning("It is strange that come here. bitDataIndex:" + bitDataIndex + " lzwCodeSize:" + lz
 52395                    bitDataIndex += lzwCodeSize;
 52396                    continue;
 397                }
 398            }
 399            else
 400            {
 0401                Debug.LogWarning("It is strange that come here. bitDataIndex:" + bitDataIndex + " lzwCodeSize:" + lzwCod
 0402                bitDataIndex += lzwCodeSize;
 0403                continue;
 404            }
 405
 406            // Output
 407            // Take out 8 bits from the string.
 1562424408            byte[] temp = Encoding.Unicode.GetBytes(entry);
 16654784409            for (int i = 0; i < temp.Length; i++)
 410            {
 6764968411                if (i % 2 == 0)
 412                {
 3382484413                    output[outputAddIndex] = temp[i];
 3382484414                    outputAddIndex++;
 415                }
 416            }
 417
 1562424418            if (outputAddIndex >= needDataSize)
 419            {
 420                // Exit
 421                break;
 422            }
 423
 1562296424            if (prevEntry != null)
 425            {
 426                // Add to dictionary
 1561800427                dic.Add(dic.Count, prevEntry + entry[0]);
 428            }
 429
 1562296430            prevEntry = entry;
 431
 1562296432            bitDataIndex += lzwCodeSize;
 433
 1562296434            if (lzwCodeSize == 3 && dic.Count >= 8)
 435            {
 0436                lzwCodeSize = 4;
 0437            }
 1562296438            else if (lzwCodeSize == 4 && dic.Count >= 16)
 439            {
 0440                lzwCodeSize = 5;
 0441            }
 1562296442            else if (lzwCodeSize == 5 && dic.Count >= 32)
 443            {
 0444                lzwCodeSize = 6;
 0445            }
 1562296446            else if (lzwCodeSize == 6 && dic.Count >= 64)
 447            {
 0448                lzwCodeSize = 7;
 0449            }
 1562296450            else if (lzwCodeSize == 7 && dic.Count >= 128)
 451            {
 0452                lzwCodeSize = 8;
 0453            }
 1562296454            else if (lzwCodeSize == 8 && dic.Count >= 256)
 455            {
 0456                lzwCodeSize = 9;
 0457            }
 1562296458            else if (lzwCodeSize == 9 && dic.Count >= 512)
 459            {
 456460                lzwCodeSize = 10;
 456461            }
 1561840462            else if (lzwCodeSize == 10 && dic.Count >= 1024)
 463            {
 440464                lzwCodeSize = 11;
 440465            }
 1561400466            else if (lzwCodeSize == 11 && dic.Count >= 2048)
 467            {
 436468                lzwCodeSize = 12;
 436469            }
 1560964470            else if (lzwCodeSize == 12 && dic.Count >= 4096)
 471            {
 52472                int nextKey = bitData.GetNumeral(bitDataIndex, lzwCodeSize);
 52473                if (nextKey != clearCode)
 474                {
 52475                    dicInitFlag = true;
 476                }
 477            }
 478        }
 479
 180480        return output;
 481    }
 482
 483    /// <summary>
 484    /// Initialize dictionary
 485    /// </summary>
 486    /// <param name="dic">Dictionary</param>
 487    /// <param name="lzwMinimumCodeSize">LZW minimum code size</param>
 488    /// <param name="lzwCodeSize">out LZW code size</param>
 489    /// <param name="clearCode">out Clear code</param>
 490    /// <param name="finishCode">out Finish code</param>
 491    private static void InitDictionary(Dictionary<int, string> dic, int lzwMinimumCodeSize, out int lzwCodeSize, out int
 492    {
 728493        int dicLength = (int)Math.Pow(2, lzwMinimumCodeSize);
 494
 728495        clearCode = dicLength;
 728496        finishCode = clearCode + 1;
 497
 728498        dic.Clear();
 499
 377104500        for (int i = 0; i < dicLength + 2; i++)
 501        {
 187824502            dic.Add(i, ((char)i).ToString());
 503        }
 504
 728505        lzwCodeSize = lzwMinimumCodeSize + 1;
 728506    }
 507
 508    /// <summary>
 509    /// Sort interlace GIF data
 510    /// </summary>
 511    /// <param name="decodedData">Decoded GIF data</param>
 512    /// <param name="xNum">Pixel number of horizontal row</param>
 513    /// <returns>Sorted data</returns>
 514    private static byte[] SortInterlaceGifData(byte[] decodedData, int xNum)
 515    {
 0516        int rowNo = 0;
 0517        int dataIndex = 0;
 0518        var newArr = new byte[decodedData.Length];
 519        // Every 8th. row, starting with row 0.
 0520        for (int i = 0; i < newArr.Length; i++)
 521        {
 0522            if (rowNo % 8 == 0)
 523            {
 0524                newArr[i] = decodedData[dataIndex];
 0525                dataIndex++;
 526            }
 0527            if (i != 0 && i % xNum == 0)
 528            {
 0529                rowNo++;
 530            }
 531        }
 0532        rowNo = 0;
 533        // Every 8th. row, starting with row 4.
 0534        for (int i = 0; i < newArr.Length; i++)
 535        {
 0536            if (rowNo % 8 == 4)
 537            {
 0538                newArr[i] = decodedData[dataIndex];
 0539                dataIndex++;
 540            }
 0541            if (i != 0 && i % xNum == 0)
 542            {
 0543                rowNo++;
 544            }
 545        }
 0546        rowNo = 0;
 547        // Every 4th. row, starting with row 2.
 0548        for (int i = 0; i < newArr.Length; i++)
 549        {
 0550            if (rowNo % 4 == 2)
 551            {
 0552                newArr[i] = decodedData[dataIndex];
 0553                dataIndex++;
 554            }
 0555            if (i != 0 && i % xNum == 0)
 556            {
 0557                rowNo++;
 558            }
 559        }
 0560        rowNo = 0;
 561        // Every 2nd. row, starting with row 1.
 0562        for (int i = 0; i < newArr.Length; i++)
 563        {
 0564            if (rowNo % 8 != 0 && rowNo % 8 != 4 && rowNo % 4 != 2)
 565            {
 0566                newArr[i] = decodedData[dataIndex];
 0567                dataIndex++;
 568            }
 0569            if (i != 0 && i % xNum == 0)
 570            {
 0571                rowNo++;
 572            }
 573        }
 574
 0575        return newArr;
 576    }
 577
 578    #endregion
 579}

/tmp/workspace/unity-renderer/unity-renderer/Assets/Plugins/UniGif/UniGifFormatter.cs

#LineLine coverage
 1/*
 2UniGif
 3Copyright (c) 2015 WestHillApps (Hironari Nishioka)
 4This software is released under the MIT License.
 5http://opensource.org/licenses/mit-license.php
 6*/
 7
 8using System;
 9using System.Collections.Generic;
 10using UnityEngine;
 11
 12public static partial class UniGif
 13{
 14    /// <summary>
 15    /// Set GIF data
 16    /// </summary>
 17    /// <param name="gifBytes">GIF byte data</param>
 18    /// <param name="gifData">ref GIF data</param>
 19    /// <param name="debugLog">Debug log flag</param>
 20    /// <returns>Result</returns>
 21    private static bool SetGifData(byte[] gifBytes, ref GifData gifData, bool debugLog)
 22    {
 423        if (debugLog)
 24        {
 025            Debug.Log("SetGifData Start.");
 26        }
 27
 428        if (gifBytes == null || gifBytes.Length <= 0)
 29        {
 030            Debug.LogError("bytes is nothing.");
 031            return false;
 32        }
 33
 434        int byteIndex = 0;
 35
 436        if (SetGifHeader(gifBytes, ref byteIndex, ref gifData) == false)
 37        {
 038            Debug.LogError("GIF header set error.");
 039            return false;
 40        }
 41
 442        if (SetGifBlock(gifBytes, ref byteIndex, ref gifData) == false)
 43        {
 044            Debug.LogError("GIF block set error.");
 045            return false;
 46        }
 47
 448        if (debugLog)
 49        {
 050            gifData.Dump();
 051            Debug.Log("SetGifData Finish.");
 52        }
 453        return true;
 54    }
 55
 56    private static bool SetGifHeader(byte[] gifBytes, ref int byteIndex, ref GifData gifData)
 57    {
 58        // Signature(3 Bytes)
 59        // 0x47 0x49 0x46 (GIF)
 460        if (gifBytes[0] != 'G' || gifBytes[1] != 'I' || gifBytes[2] != 'F')
 61        {
 062            Debug.LogError("This is not GIF image.");
 063            return false;
 64        }
 465        gifData.m_sig0 = gifBytes[0];
 466        gifData.m_sig1 = gifBytes[1];
 467        gifData.m_sig2 = gifBytes[2];
 68
 69        // Version(3 Bytes)
 70        // 0x38 0x37 0x61 (87a) or 0x38 0x39 0x61 (89a)
 471        if ((gifBytes[3] != '8' || gifBytes[4] != '7' || gifBytes[5] != 'a') &&
 72            (gifBytes[3] != '8' || gifBytes[4] != '9' || gifBytes[5] != 'a'))
 73        {
 074            Debug.LogError("GIF version error.\nSupported only GIF87a or GIF89a.");
 075            return false;
 76        }
 477        gifData.m_ver0 = gifBytes[3];
 478        gifData.m_ver1 = gifBytes[4];
 479        gifData.m_ver2 = gifBytes[5];
 80
 81        // Logical Screen Width(2 Bytes)
 482        gifData.m_logicalScreenWidth = BitConverter.ToUInt16(gifBytes, 6);
 83
 84        // Logical Screen Height(2 Bytes)
 485        gifData.m_logicalScreenHeight = BitConverter.ToUInt16(gifBytes, 8);
 86
 87        // 1 Byte
 88        {
 89            // Global Color Table Flag(1 Bit)
 490            gifData.m_globalColorTableFlag = (gifBytes[10] & 128) == 128; // 0b10000000
 91
 92            // Color Resolution(3 Bits)
 493            switch (gifBytes[10] & 112)
 94            {
 95                case 112: // 0b01110000
 496                    gifData.m_colorResolution = 8;
 497                    break;
 98                case 96: // 0b01100000
 099                    gifData.m_colorResolution = 7;
 0100                    break;
 101                case 80: // 0b01010000
 0102                    gifData.m_colorResolution = 6;
 0103                    break;
 104                case 64: // 0b01000000
 0105                    gifData.m_colorResolution = 5;
 0106                    break;
 107                case 48: // 0b00110000
 0108                    gifData.m_colorResolution = 4;
 0109                    break;
 110                case 32: // 0b00100000
 0111                    gifData.m_colorResolution = 3;
 0112                    break;
 113                case 16: // 0b00010000
 0114                    gifData.m_colorResolution = 2;
 0115                    break;
 116                default:
 0117                    gifData.m_colorResolution = 1;
 118                    break;
 119            }
 120
 121            // Sort Flag(1 Bit)
 4122            gifData.m_sortFlag = (gifBytes[10] & 8) == 8; // 0b00001000
 123
 124            // Size of Global Color Table(3 Bits)
 4125            int val = (gifBytes[10] & 7) + 1;
 4126            gifData.m_sizeOfGlobalColorTable = (int)Math.Pow(2, val);
 127        }
 128
 129        // Background Color Index(1 Byte)
 4130        gifData.m_bgColorIndex = gifBytes[11];
 131
 132        // Pixel Aspect Ratio(1 Byte)
 4133        gifData.m_pixelAspectRatio = gifBytes[12];
 134
 4135        byteIndex = 13;
 4136        if (gifData.m_globalColorTableFlag)
 137        {
 138            // Global Color Table(0~255×3 Bytes)
 4139            gifData.m_globalColorTable = new List<byte[]>();
 2056140            for (int i = byteIndex; i < byteIndex + (gifData.m_sizeOfGlobalColorTable * 3); i += 3)
 141            {
 1024142                gifData.m_globalColorTable.Add(new byte[] { gifBytes[i], gifBytes[i + 1], gifBytes[i + 2] });
 143            }
 4144            byteIndex = byteIndex + (gifData.m_sizeOfGlobalColorTable * 3);
 145        }
 146
 4147        return true;
 148    }
 149
 150    private static bool SetGifBlock(byte[] gifBytes, ref int byteIndex, ref GifData gifData)
 151    {
 152        try
 153        {
 4154            int lastIndex = 0;
 364155            while (true)
 156            {
 368157                int nowIndex = byteIndex;
 158
 368159                if (gifBytes[nowIndex] == 0x2c)
 160                {
 161                    // Image Block(0x2c)
 180162                    SetImageBlock(gifBytes, ref byteIndex, ref gifData);
 163
 180164                }
 188165                else if (gifBytes[nowIndex] == 0x21)
 166                {
 167                    // Extension
 184168                    switch (gifBytes[nowIndex + 1])
 169                    {
 170                        case 0xf9:
 171                            // Graphic Control Extension(0x21 0xf9)
 180172                            SetGraphicControlExtension(gifBytes, ref byteIndex, ref gifData);
 180173                            break;
 174                        case 0xfe:
 175                            // Comment Extension(0x21 0xfe)
 0176                            SetCommentExtension(gifBytes, ref byteIndex, ref gifData);
 0177                            break;
 178                        case 0x01:
 179                            // Plain Text Extension(0x21 0x01)
 0180                            SetPlainTextExtension(gifBytes, ref byteIndex, ref gifData);
 0181                            break;
 182                        case 0xff:
 183                            // Application Extension(0x21 0xff)
 4184                            SetApplicationExtension(gifBytes, ref byteIndex, ref gifData);
 4185                            break;
 186                        default:
 187                            break;
 188                    }
 189                }
 4190                else if (gifBytes[nowIndex] == 0x3b)
 191                {
 192                    // Trailer(1 Byte)
 4193                    gifData.m_trailer = gifBytes[byteIndex];
 4194                    byteIndex++;
 4195                    break;
 196                }
 197
 364198                if (lastIndex == nowIndex)
 199                {
 0200                    Debug.LogError("Infinite loop error.");
 0201                    return false;
 202                }
 203
 364204                lastIndex = nowIndex;
 205            }
 4206        }
 207        catch (Exception ex)
 208        {
 0209            Debug.LogError(ex.Message);
 0210            return false;
 211        }
 212
 4213        return true;
 0214    }
 215
 216    private static void SetImageBlock(byte[] gifBytes, ref int byteIndex, ref GifData gifData)
 217    {
 180218        ImageBlock ib = new ImageBlock();
 219
 220        // Image Separator(1 Byte)
 221        // 0x2c
 180222        ib.m_imageSeparator = gifBytes[byteIndex];
 180223        byteIndex++;
 224
 225        // Image Left Position(2 Bytes)
 180226        ib.m_imageLeftPosition = BitConverter.ToUInt16(gifBytes, byteIndex);
 180227        byteIndex += 2;
 228
 229        // Image Top Position(2 Bytes)
 180230        ib.m_imageTopPosition = BitConverter.ToUInt16(gifBytes, byteIndex);
 180231        byteIndex += 2;
 232
 233        // Image Width(2 Bytes)
 180234        ib.m_imageWidth = BitConverter.ToUInt16(gifBytes, byteIndex);
 180235        byteIndex += 2;
 236
 237        // Image Height(2 Bytes)
 180238        ib.m_imageHeight = BitConverter.ToUInt16(gifBytes, byteIndex);
 180239        byteIndex += 2;
 240
 241        // 1 Byte
 242        {
 243            // Local Color Table Flag(1 Bit)
 180244            ib.m_localColorTableFlag = (gifBytes[byteIndex] & 128) == 128; // 0b10000000
 245
 246            // Interlace Flag(1 Bit)
 180247            ib.m_interlaceFlag = (gifBytes[byteIndex] & 64) == 64; // 0b01000000
 248
 249            // Sort Flag(1 Bit)
 180250            ib.m_sortFlag = (gifBytes[byteIndex] & 32) == 32; // 0b00100000
 251
 252            // Reserved(2 Bits)
 253            // Unused
 254
 255            // Size of Local Color Table(3 Bits)
 180256            int val = (gifBytes[byteIndex] & 7) + 1;
 180257            ib.m_sizeOfLocalColorTable = (int)Math.Pow(2, val);
 258
 180259            byteIndex++;
 260        }
 261
 180262        if (ib.m_localColorTableFlag)
 263        {
 264            // Local Color Table(0~255×3 Bytes)
 0265            ib.m_localColorTable = new List<byte[]>();
 0266            for (int i = byteIndex; i < byteIndex + (ib.m_sizeOfLocalColorTable * 3); i += 3)
 267            {
 0268                ib.m_localColorTable.Add(new byte[] { gifBytes[i], gifBytes[i + 1], gifBytes[i + 2] });
 269            }
 0270            byteIndex = byteIndex + (ib.m_sizeOfLocalColorTable * 3);
 271        }
 272
 273        // LZW Minimum Code Size(1 Byte)
 180274        ib.m_lzwMinimumCodeSize = gifBytes[byteIndex];
 180275        byteIndex++;
 276
 277        // Block Size & Image Data List
 10440278        while (true)
 279        {
 280            // Block Size(1 Byte)
 10620281            byte blockSize = gifBytes[byteIndex];
 10620282            byteIndex++;
 283
 10620284            if (blockSize == 0x00)
 285            {
 286                // Block Terminator(1 Byte)
 287                break;
 288            }
 289
 10440290            var imageDataBlock = new ImageBlock.ImageDataBlock();
 10440291            imageDataBlock.m_blockSize = blockSize;
 292
 293            // Image Data(? Bytes)
 10440294            imageDataBlock.m_imageData = new byte[imageDataBlock.m_blockSize];
 5299608295            for (int i = 0; i < imageDataBlock.m_imageData.Length; i++)
 296            {
 2639364297                imageDataBlock.m_imageData[i] = gifBytes[byteIndex];
 2639364298                byteIndex++;
 299            }
 300
 10440301            if (ib.m_imageDataList == null)
 302            {
 180303                ib.m_imageDataList = new List<ImageBlock.ImageDataBlock>();
 304            }
 10440305            ib.m_imageDataList.Add(imageDataBlock);
 306        }
 307
 180308        if (gifData.m_imageBlockList == null)
 309        {
 4310            gifData.m_imageBlockList = new List<ImageBlock>();
 311        }
 180312        gifData.m_imageBlockList.Add(ib);
 180313    }
 314
 315    private static void SetGraphicControlExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData)
 316    {
 180317        GraphicControlExtension gcEx = new GraphicControlExtension();
 318
 319        // Extension Introducer(1 Byte)
 320        // 0x21
 180321        gcEx.m_extensionIntroducer = gifBytes[byteIndex];
 180322        byteIndex++;
 323
 324        // Graphic Control Label(1 Byte)
 325        // 0xf9
 180326        gcEx.m_graphicControlLabel = gifBytes[byteIndex];
 180327        byteIndex++;
 328
 329        // Block Size(1 Byte)
 330        // 0x04
 180331        gcEx.m_blockSize = gifBytes[byteIndex];
 180332        byteIndex++;
 333
 334        // 1 Byte
 335        {
 336            // Reserved(3 Bits)
 337            // Unused
 338
 339            // Disposal Mothod(3 Bits)
 340            // 0 (No disposal specified)
 341            // 1 (Do not dispose)
 342            // 2 (Restore to background color)
 343            // 3 (Restore to previous)
 180344            switch (gifBytes[byteIndex] & 28)
 345            { // 0b00011100
 346                case 4:     // 0b00000100
 180347                    gcEx.m_disposalMethod = 1;
 180348                    break;
 349                case 8:     // 0b00001000
 0350                    gcEx.m_disposalMethod = 2;
 0351                    break;
 352                case 12:    // 0b00001100
 0353                    gcEx.m_disposalMethod = 3;
 0354                    break;
 355                default:
 0356                    gcEx.m_disposalMethod = 0;
 357                    break;
 358            }
 359
 360            // User Input Flag(1 Bit)
 361            // Unknown
 362
 363            // Transparent Color Flag(1 Bit)
 180364            gcEx.m_transparentColorFlag = (gifBytes[byteIndex] & 1) == 1; // 0b00000001
 365
 180366            byteIndex++;
 367        }
 368
 369        // Delay Time(2 Bytes)
 180370        gcEx.m_delayTime = BitConverter.ToUInt16(gifBytes, byteIndex);
 180371        byteIndex += 2;
 372
 373        // Transparent Color Index(1 Byte)
 180374        gcEx.m_transparentColorIndex = gifBytes[byteIndex];
 180375        byteIndex++;
 376
 377        // Block Terminator(1 Byte)
 180378        gcEx.m_blockTerminator = gifBytes[byteIndex];
 180379        byteIndex++;
 380
 180381        if (gifData.m_graphicCtrlExList == null)
 382        {
 4383            gifData.m_graphicCtrlExList = new List<GraphicControlExtension>();
 384        }
 180385        gifData.m_graphicCtrlExList.Add(gcEx);
 180386    }
 387
 388    private static void SetCommentExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData)
 389    {
 0390        CommentExtension commentEx = new CommentExtension();
 391
 392        // Extension Introducer(1 Byte)
 393        // 0x21
 0394        commentEx.m_extensionIntroducer = gifBytes[byteIndex];
 0395        byteIndex++;
 396
 397        // Comment Label(1 Byte)
 398        // 0xfe
 0399        commentEx.m_commentLabel = gifBytes[byteIndex];
 0400        byteIndex++;
 401
 402        // Block Size & Comment Data List
 0403        while (true)
 404        {
 405            // Block Size(1 Byte)
 0406            byte blockSize = gifBytes[byteIndex];
 0407            byteIndex++;
 408
 0409            if (blockSize == 0x00)
 410            {
 411                // Block Terminator(1 Byte)
 412                break;
 413            }
 414
 0415            var commentDataBlock = new CommentExtension.CommentDataBlock();
 0416            commentDataBlock.m_blockSize = blockSize;
 417
 418            // Comment Data(n Byte)
 0419            commentDataBlock.m_commentData = new byte[commentDataBlock.m_blockSize];
 0420            for (int i = 0; i < commentDataBlock.m_commentData.Length; i++)
 421            {
 0422                commentDataBlock.m_commentData[i] = gifBytes[byteIndex];
 0423                byteIndex++;
 424            }
 425
 0426            if (commentEx.m_commentDataList == null)
 427            {
 0428                commentEx.m_commentDataList = new List<CommentExtension.CommentDataBlock>();
 429            }
 0430            commentEx.m_commentDataList.Add(commentDataBlock);
 431        }
 432
 0433        if (gifData.m_commentExList == null)
 434        {
 0435            gifData.m_commentExList = new List<CommentExtension>();
 436        }
 0437        gifData.m_commentExList.Add(commentEx);
 0438    }
 439
 440    private static void SetPlainTextExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData)
 441    {
 0442        PlainTextExtension plainTxtEx = new PlainTextExtension();
 443
 444        // Extension Introducer(1 Byte)
 445        // 0x21
 0446        plainTxtEx.m_extensionIntroducer = gifBytes[byteIndex];
 0447        byteIndex++;
 448
 449        // Plain Text Label(1 Byte)
 450        // 0x01
 0451        plainTxtEx.m_plainTextLabel = gifBytes[byteIndex];
 0452        byteIndex++;
 453
 454        // Block Size(1 Byte)
 455        // 0x0c
 0456        plainTxtEx.m_blockSize = gifBytes[byteIndex];
 0457        byteIndex++;
 458
 459        // Text Grid Left Position(2 Bytes)
 460        // Not supported
 0461        byteIndex += 2;
 462
 463        // Text Grid Top Position(2 Bytes)
 464        // Not supported
 0465        byteIndex += 2;
 466
 467        // Text Grid Width(2 Bytes)
 468        // Not supported
 0469        byteIndex += 2;
 470
 471        // Text Grid Height(2 Bytes)
 472        // Not supported
 0473        byteIndex += 2;
 474
 475        // Character Cell Width(1 Bytes)
 476        // Not supported
 0477        byteIndex++;
 478
 479        // Character Cell Height(1 Bytes)
 480        // Not supported
 0481        byteIndex++;
 482
 483        // Text Foreground Color Index(1 Bytes)
 484        // Not supported
 0485        byteIndex++;
 486
 487        // Text Background Color Index(1 Bytes)
 488        // Not supported
 0489        byteIndex++;
 490
 491        // Block Size & Plain Text Data List
 0492        while (true)
 493        {
 494            // Block Size(1 Byte)
 0495            byte blockSize = gifBytes[byteIndex];
 0496            byteIndex++;
 497
 0498            if (blockSize == 0x00)
 499            {
 500                // Block Terminator(1 Byte)
 501                break;
 502            }
 503
 0504            var plainTextDataBlock = new PlainTextExtension.PlainTextDataBlock();
 0505            plainTextDataBlock.m_blockSize = blockSize;
 506
 507            // Plain Text Data(n Byte)
 0508            plainTextDataBlock.m_plainTextData = new byte[plainTextDataBlock.m_blockSize];
 0509            for (int i = 0; i < plainTextDataBlock.m_plainTextData.Length; i++)
 510            {
 0511                plainTextDataBlock.m_plainTextData[i] = gifBytes[byteIndex];
 0512                byteIndex++;
 513            }
 514
 0515            if (plainTxtEx.m_plainTextDataList == null)
 516            {
 0517                plainTxtEx.m_plainTextDataList = new List<PlainTextExtension.PlainTextDataBlock>();
 518            }
 0519            plainTxtEx.m_plainTextDataList.Add(plainTextDataBlock);
 520        }
 521
 0522        if (gifData.m_plainTextExList == null)
 523        {
 0524            gifData.m_plainTextExList = new List<PlainTextExtension>();
 525        }
 0526        gifData.m_plainTextExList.Add(plainTxtEx);
 0527    }
 528
 529    private static void SetApplicationExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData)
 530    {
 531        // Extension Introducer(1 Byte)
 532        // 0x21
 4533        gifData.m_appEx.m_extensionIntroducer = gifBytes[byteIndex];
 4534        byteIndex++;
 535
 536        // Extension Label(1 Byte)
 537        // 0xff
 4538        gifData.m_appEx.m_extensionLabel = gifBytes[byteIndex];
 4539        byteIndex++;
 540
 541        // Block Size(1 Byte)
 542        // 0x0b
 4543        gifData.m_appEx.m_blockSize = gifBytes[byteIndex];
 4544        byteIndex++;
 545
 546        // Application Identifier(8 Bytes)
 4547        gifData.m_appEx.m_appId1 = gifBytes[byteIndex];
 4548        byteIndex++;
 4549        gifData.m_appEx.m_appId2 = gifBytes[byteIndex];
 4550        byteIndex++;
 4551        gifData.m_appEx.m_appId3 = gifBytes[byteIndex];
 4552        byteIndex++;
 4553        gifData.m_appEx.m_appId4 = gifBytes[byteIndex];
 4554        byteIndex++;
 4555        gifData.m_appEx.m_appId5 = gifBytes[byteIndex];
 4556        byteIndex++;
 4557        gifData.m_appEx.m_appId6 = gifBytes[byteIndex];
 4558        byteIndex++;
 4559        gifData.m_appEx.m_appId7 = gifBytes[byteIndex];
 4560        byteIndex++;
 4561        gifData.m_appEx.m_appId8 = gifBytes[byteIndex];
 4562        byteIndex++;
 563
 564        // Application Authentication Code(3 Bytes)
 4565        gifData.m_appEx.m_appAuthCode1 = gifBytes[byteIndex];
 4566        byteIndex++;
 4567        gifData.m_appEx.m_appAuthCode2 = gifBytes[byteIndex];
 4568        byteIndex++;
 4569        gifData.m_appEx.m_appAuthCode3 = gifBytes[byteIndex];
 4570        byteIndex++;
 571
 572        // Block Size & Application Data List
 4573        while (true)
 574        {
 575            // Block Size (1 Byte)
 8576            byte blockSize = gifBytes[byteIndex];
 8577            byteIndex++;
 578
 8579            if (blockSize == 0x00)
 580            {
 581                // Block Terminator(1 Byte)
 582                break;
 583            }
 584
 4585            var appDataBlock = new ApplicationExtension.ApplicationDataBlock();
 4586            appDataBlock.m_blockSize = blockSize;
 587
 588            // Application Data(n Byte)
 4589            appDataBlock.m_applicationData = new byte[appDataBlock.m_blockSize];
 32590            for (int i = 0; i < appDataBlock.m_applicationData.Length; i++)
 591            {
 12592                appDataBlock.m_applicationData[i] = gifBytes[byteIndex];
 12593                byteIndex++;
 594            }
 595
 4596            if (gifData.m_appEx.m_appDataList == null)
 597            {
 4598                gifData.m_appEx.m_appDataList = new List<ApplicationExtension.ApplicationDataBlock>();
 599            }
 4600            gifData.m_appEx.m_appDataList.Add(appDataBlock);
 601        }
 4602    }
 603}

Methods/Properties

GetTextureListCoroutine()
signature()
version()
Dump()
applicationIdentifier()
applicationAuthenticationCode()
loopCount()
DecodeTextureCoroutine()
GetDecodedData(UniGif/ImageBlock)
GetColorTableAndSetBgColor(UniGif/GifData, UniGif/ImageBlock, System.Int32, UnityEngine.Color32&)
GetGraphicCtrlExt(UniGif/GifData, System.Int32)
GetTransparentIndex(System.Nullable[GraphicControlExtension])
GetDelaySec(System.Nullable[GraphicControlExtension])
GetDisposalMethod(System.Nullable[GraphicControlExtension])
CreateTexture2D(UniGif/GifData, GifFrameData[], System.Int32, System.Collections.Generic.List[UInt16], UnityEngine.Color32, UnityEngine.FilterMode, UnityEngine.TextureWrapMode, System.Boolean&)
SetTexturePixelRow(UnityEngine.Texture2D, System.Int32, UniGif/ImageBlock, System.Byte[], System.Int32&, System.Collections.Generic.List[Byte[]], UnityEngine.Color32, System.Int32, System.Boolean)
DecodeGifLZW(System.Collections.Generic.List[Byte], System.Int32, System.Int32)
InitDictionary(System.Collections.Generic.Dictionary[Int32,String], System.Int32, System.Int32&, System.Int32&, System.Int32&)
SortInterlaceGifData(System.Byte[], System.Int32)
SetGifData(System.Byte[], UniGif/GifData&, System.Boolean)
SetGifHeader(System.Byte[], System.Int32&, UniGif/GifData&)
SetGifBlock(System.Byte[], System.Int32&, UniGif/GifData&)
SetImageBlock(System.Byte[], System.Int32&, UniGif/GifData&)
SetGraphicControlExtension(System.Byte[], System.Int32&, UniGif/GifData&)
SetCommentExtension(System.Byte[], System.Int32&, UniGif/GifData&)
SetPlainTextExtension(System.Byte[], System.Int32&, UniGif/GifData&)
SetApplicationExtension(System.Byte[], System.Int32&, UniGif/GifData&)