| | 1 | | /* |
| | 2 | | UniGif |
| | 3 | | Copyright (c) 2015 WestHillApps (Hironari Nishioka) |
| | 4 | | This software is released under the MIT License. |
| | 5 | | http://opensource.org/licenses/mit-license.php |
| | 6 | | */ |
| | 7 | |
|
| | 8 | | using System; |
| | 9 | | using System.Collections.Generic; |
| | 10 | | using UnityEngine; |
| | 11 | |
|
| | 12 | | public 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 | | { |
| 4 | 23 | | if (debugLog) |
| | 24 | | { |
| 0 | 25 | | Debug.Log("SetGifData Start."); |
| | 26 | | } |
| | 27 | |
|
| 4 | 28 | | if (gifBytes == null || gifBytes.Length <= 0) |
| | 29 | | { |
| 0 | 30 | | Debug.LogError("bytes is nothing."); |
| 0 | 31 | | return false; |
| | 32 | | } |
| | 33 | |
|
| 4 | 34 | | int byteIndex = 0; |
| | 35 | |
|
| 4 | 36 | | if (SetGifHeader(gifBytes, ref byteIndex, ref gifData) == false) |
| | 37 | | { |
| 0 | 38 | | Debug.LogError("GIF header set error."); |
| 0 | 39 | | return false; |
| | 40 | | } |
| | 41 | |
|
| 4 | 42 | | if (SetGifBlock(gifBytes, ref byteIndex, ref gifData) == false) |
| | 43 | | { |
| 0 | 44 | | Debug.LogError("GIF block set error."); |
| 0 | 45 | | return false; |
| | 46 | | } |
| | 47 | |
|
| 4 | 48 | | if (debugLog) |
| | 49 | | { |
| 0 | 50 | | gifData.Dump(); |
| 0 | 51 | | Debug.Log("SetGifData Finish."); |
| | 52 | | } |
| 4 | 53 | | 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) |
| 4 | 60 | | if (gifBytes[0] != 'G' || gifBytes[1] != 'I' || gifBytes[2] != 'F') |
| | 61 | | { |
| 0 | 62 | | Debug.LogError("This is not GIF image."); |
| 0 | 63 | | return false; |
| | 64 | | } |
| 4 | 65 | | gifData.m_sig0 = gifBytes[0]; |
| 4 | 66 | | gifData.m_sig1 = gifBytes[1]; |
| 4 | 67 | | gifData.m_sig2 = gifBytes[2]; |
| | 68 | |
|
| | 69 | | // Version(3 Bytes) |
| | 70 | | // 0x38 0x37 0x61 (87a) or 0x38 0x39 0x61 (89a) |
| 4 | 71 | | if ((gifBytes[3] != '8' || gifBytes[4] != '7' || gifBytes[5] != 'a') && |
| | 72 | | (gifBytes[3] != '8' || gifBytes[4] != '9' || gifBytes[5] != 'a')) |
| | 73 | | { |
| 0 | 74 | | Debug.LogError("GIF version error.\nSupported only GIF87a or GIF89a."); |
| 0 | 75 | | return false; |
| | 76 | | } |
| 4 | 77 | | gifData.m_ver0 = gifBytes[3]; |
| 4 | 78 | | gifData.m_ver1 = gifBytes[4]; |
| 4 | 79 | | gifData.m_ver2 = gifBytes[5]; |
| | 80 | |
|
| | 81 | | // Logical Screen Width(2 Bytes) |
| 4 | 82 | | gifData.m_logicalScreenWidth = BitConverter.ToUInt16(gifBytes, 6); |
| | 83 | |
|
| | 84 | | // Logical Screen Height(2 Bytes) |
| 4 | 85 | | gifData.m_logicalScreenHeight = BitConverter.ToUInt16(gifBytes, 8); |
| | 86 | |
|
| | 87 | | // 1 Byte |
| | 88 | | { |
| | 89 | | // Global Color Table Flag(1 Bit) |
| 4 | 90 | | gifData.m_globalColorTableFlag = (gifBytes[10] & 128) == 128; // 0b10000000 |
| | 91 | |
|
| | 92 | | // Color Resolution(3 Bits) |
| 4 | 93 | | switch (gifBytes[10] & 112) |
| | 94 | | { |
| | 95 | | case 112: // 0b01110000 |
| 4 | 96 | | gifData.m_colorResolution = 8; |
| 4 | 97 | | break; |
| | 98 | | case 96: // 0b01100000 |
| 0 | 99 | | gifData.m_colorResolution = 7; |
| 0 | 100 | | break; |
| | 101 | | case 80: // 0b01010000 |
| 0 | 102 | | gifData.m_colorResolution = 6; |
| 0 | 103 | | break; |
| | 104 | | case 64: // 0b01000000 |
| 0 | 105 | | gifData.m_colorResolution = 5; |
| 0 | 106 | | break; |
| | 107 | | case 48: // 0b00110000 |
| 0 | 108 | | gifData.m_colorResolution = 4; |
| 0 | 109 | | break; |
| | 110 | | case 32: // 0b00100000 |
| 0 | 111 | | gifData.m_colorResolution = 3; |
| 0 | 112 | | break; |
| | 113 | | case 16: // 0b00010000 |
| 0 | 114 | | gifData.m_colorResolution = 2; |
| 0 | 115 | | break; |
| | 116 | | default: |
| 0 | 117 | | gifData.m_colorResolution = 1; |
| | 118 | | break; |
| | 119 | | } |
| | 120 | |
|
| | 121 | | // Sort Flag(1 Bit) |
| 4 | 122 | | gifData.m_sortFlag = (gifBytes[10] & 8) == 8; // 0b00001000 |
| | 123 | |
|
| | 124 | | // Size of Global Color Table(3 Bits) |
| 4 | 125 | | int val = (gifBytes[10] & 7) + 1; |
| 4 | 126 | | gifData.m_sizeOfGlobalColorTable = (int)Math.Pow(2, val); |
| | 127 | | } |
| | 128 | |
|
| | 129 | | // Background Color Index(1 Byte) |
| 4 | 130 | | gifData.m_bgColorIndex = gifBytes[11]; |
| | 131 | |
|
| | 132 | | // Pixel Aspect Ratio(1 Byte) |
| 4 | 133 | | gifData.m_pixelAspectRatio = gifBytes[12]; |
| | 134 | |
|
| 4 | 135 | | byteIndex = 13; |
| 4 | 136 | | if (gifData.m_globalColorTableFlag) |
| | 137 | | { |
| | 138 | | // Global Color Table(0~255×3 Bytes) |
| 4 | 139 | | gifData.m_globalColorTable = new List<byte[]>(); |
| 2056 | 140 | | for (int i = byteIndex; i < byteIndex + (gifData.m_sizeOfGlobalColorTable * 3); i += 3) |
| | 141 | | { |
| 1024 | 142 | | gifData.m_globalColorTable.Add(new byte[] { gifBytes[i], gifBytes[i + 1], gifBytes[i + 2] }); |
| | 143 | | } |
| 4 | 144 | | byteIndex = byteIndex + (gifData.m_sizeOfGlobalColorTable * 3); |
| | 145 | | } |
| | 146 | |
|
| 4 | 147 | | return true; |
| | 148 | | } |
| | 149 | |
|
| | 150 | | private static bool SetGifBlock(byte[] gifBytes, ref int byteIndex, ref GifData gifData) |
| | 151 | | { |
| | 152 | | try |
| | 153 | | { |
| 4 | 154 | | int lastIndex = 0; |
| 364 | 155 | | while (true) |
| | 156 | | { |
| 368 | 157 | | int nowIndex = byteIndex; |
| | 158 | |
|
| 368 | 159 | | if (gifBytes[nowIndex] == 0x2c) |
| | 160 | | { |
| | 161 | | // Image Block(0x2c) |
| 180 | 162 | | SetImageBlock(gifBytes, ref byteIndex, ref gifData); |
| | 163 | |
|
| 180 | 164 | | } |
| 188 | 165 | | else if (gifBytes[nowIndex] == 0x21) |
| | 166 | | { |
| | 167 | | // Extension |
| 184 | 168 | | switch (gifBytes[nowIndex + 1]) |
| | 169 | | { |
| | 170 | | case 0xf9: |
| | 171 | | // Graphic Control Extension(0x21 0xf9) |
| 180 | 172 | | SetGraphicControlExtension(gifBytes, ref byteIndex, ref gifData); |
| 180 | 173 | | break; |
| | 174 | | case 0xfe: |
| | 175 | | // Comment Extension(0x21 0xfe) |
| 0 | 176 | | SetCommentExtension(gifBytes, ref byteIndex, ref gifData); |
| 0 | 177 | | break; |
| | 178 | | case 0x01: |
| | 179 | | // Plain Text Extension(0x21 0x01) |
| 0 | 180 | | SetPlainTextExtension(gifBytes, ref byteIndex, ref gifData); |
| 0 | 181 | | break; |
| | 182 | | case 0xff: |
| | 183 | | // Application Extension(0x21 0xff) |
| 4 | 184 | | SetApplicationExtension(gifBytes, ref byteIndex, ref gifData); |
| 4 | 185 | | break; |
| | 186 | | default: |
| | 187 | | break; |
| | 188 | | } |
| | 189 | | } |
| 4 | 190 | | else if (gifBytes[nowIndex] == 0x3b) |
| | 191 | | { |
| | 192 | | // Trailer(1 Byte) |
| 4 | 193 | | gifData.m_trailer = gifBytes[byteIndex]; |
| 4 | 194 | | byteIndex++; |
| 4 | 195 | | break; |
| | 196 | | } |
| | 197 | |
|
| 364 | 198 | | if (lastIndex == nowIndex) |
| | 199 | | { |
| 0 | 200 | | Debug.LogError("Infinite loop error."); |
| 0 | 201 | | return false; |
| | 202 | | } |
| | 203 | |
|
| 364 | 204 | | lastIndex = nowIndex; |
| | 205 | | } |
| 4 | 206 | | } |
| | 207 | | catch (Exception ex) |
| | 208 | | { |
| 0 | 209 | | Debug.LogError(ex.Message); |
| 0 | 210 | | return false; |
| | 211 | | } |
| | 212 | |
|
| 4 | 213 | | return true; |
| 0 | 214 | | } |
| | 215 | |
|
| | 216 | | private static void SetImageBlock(byte[] gifBytes, ref int byteIndex, ref GifData gifData) |
| | 217 | | { |
| 180 | 218 | | ImageBlock ib = new ImageBlock(); |
| | 219 | |
|
| | 220 | | // Image Separator(1 Byte) |
| | 221 | | // 0x2c |
| 180 | 222 | | ib.m_imageSeparator = gifBytes[byteIndex]; |
| 180 | 223 | | byteIndex++; |
| | 224 | |
|
| | 225 | | // Image Left Position(2 Bytes) |
| 180 | 226 | | ib.m_imageLeftPosition = BitConverter.ToUInt16(gifBytes, byteIndex); |
| 180 | 227 | | byteIndex += 2; |
| | 228 | |
|
| | 229 | | // Image Top Position(2 Bytes) |
| 180 | 230 | | ib.m_imageTopPosition = BitConverter.ToUInt16(gifBytes, byteIndex); |
| 180 | 231 | | byteIndex += 2; |
| | 232 | |
|
| | 233 | | // Image Width(2 Bytes) |
| 180 | 234 | | ib.m_imageWidth = BitConverter.ToUInt16(gifBytes, byteIndex); |
| 180 | 235 | | byteIndex += 2; |
| | 236 | |
|
| | 237 | | // Image Height(2 Bytes) |
| 180 | 238 | | ib.m_imageHeight = BitConverter.ToUInt16(gifBytes, byteIndex); |
| 180 | 239 | | byteIndex += 2; |
| | 240 | |
|
| | 241 | | // 1 Byte |
| | 242 | | { |
| | 243 | | // Local Color Table Flag(1 Bit) |
| 180 | 244 | | ib.m_localColorTableFlag = (gifBytes[byteIndex] & 128) == 128; // 0b10000000 |
| | 245 | |
|
| | 246 | | // Interlace Flag(1 Bit) |
| 180 | 247 | | ib.m_interlaceFlag = (gifBytes[byteIndex] & 64) == 64; // 0b01000000 |
| | 248 | |
|
| | 249 | | // Sort Flag(1 Bit) |
| 180 | 250 | | ib.m_sortFlag = (gifBytes[byteIndex] & 32) == 32; // 0b00100000 |
| | 251 | |
|
| | 252 | | // Reserved(2 Bits) |
| | 253 | | // Unused |
| | 254 | |
|
| | 255 | | // Size of Local Color Table(3 Bits) |
| 180 | 256 | | int val = (gifBytes[byteIndex] & 7) + 1; |
| 180 | 257 | | ib.m_sizeOfLocalColorTable = (int)Math.Pow(2, val); |
| | 258 | |
|
| 180 | 259 | | byteIndex++; |
| | 260 | | } |
| | 261 | |
|
| 180 | 262 | | if (ib.m_localColorTableFlag) |
| | 263 | | { |
| | 264 | | // Local Color Table(0~255×3 Bytes) |
| 0 | 265 | | ib.m_localColorTable = new List<byte[]>(); |
| 0 | 266 | | for (int i = byteIndex; i < byteIndex + (ib.m_sizeOfLocalColorTable * 3); i += 3) |
| | 267 | | { |
| 0 | 268 | | ib.m_localColorTable.Add(new byte[] { gifBytes[i], gifBytes[i + 1], gifBytes[i + 2] }); |
| | 269 | | } |
| 0 | 270 | | byteIndex = byteIndex + (ib.m_sizeOfLocalColorTable * 3); |
| | 271 | | } |
| | 272 | |
|
| | 273 | | // LZW Minimum Code Size(1 Byte) |
| 180 | 274 | | ib.m_lzwMinimumCodeSize = gifBytes[byteIndex]; |
| 180 | 275 | | byteIndex++; |
| | 276 | |
|
| | 277 | | // Block Size & Image Data List |
| 10440 | 278 | | while (true) |
| | 279 | | { |
| | 280 | | // Block Size(1 Byte) |
| 10620 | 281 | | byte blockSize = gifBytes[byteIndex]; |
| 10620 | 282 | | byteIndex++; |
| | 283 | |
|
| 10620 | 284 | | if (blockSize == 0x00) |
| | 285 | | { |
| | 286 | | // Block Terminator(1 Byte) |
| | 287 | | break; |
| | 288 | | } |
| | 289 | |
|
| 10440 | 290 | | var imageDataBlock = new ImageBlock.ImageDataBlock(); |
| 10440 | 291 | | imageDataBlock.m_blockSize = blockSize; |
| | 292 | |
|
| | 293 | | // Image Data(? Bytes) |
| 10440 | 294 | | imageDataBlock.m_imageData = new byte[imageDataBlock.m_blockSize]; |
| 5299608 | 295 | | for (int i = 0; i < imageDataBlock.m_imageData.Length; i++) |
| | 296 | | { |
| 2639364 | 297 | | imageDataBlock.m_imageData[i] = gifBytes[byteIndex]; |
| 2639364 | 298 | | byteIndex++; |
| | 299 | | } |
| | 300 | |
|
| 10440 | 301 | | if (ib.m_imageDataList == null) |
| | 302 | | { |
| 180 | 303 | | ib.m_imageDataList = new List<ImageBlock.ImageDataBlock>(); |
| | 304 | | } |
| 10440 | 305 | | ib.m_imageDataList.Add(imageDataBlock); |
| | 306 | | } |
| | 307 | |
|
| 180 | 308 | | if (gifData.m_imageBlockList == null) |
| | 309 | | { |
| 4 | 310 | | gifData.m_imageBlockList = new List<ImageBlock>(); |
| | 311 | | } |
| 180 | 312 | | gifData.m_imageBlockList.Add(ib); |
| 180 | 313 | | } |
| | 314 | |
|
| | 315 | | private static void SetGraphicControlExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData) |
| | 316 | | { |
| 180 | 317 | | GraphicControlExtension gcEx = new GraphicControlExtension(); |
| | 318 | |
|
| | 319 | | // Extension Introducer(1 Byte) |
| | 320 | | // 0x21 |
| 180 | 321 | | gcEx.m_extensionIntroducer = gifBytes[byteIndex]; |
| 180 | 322 | | byteIndex++; |
| | 323 | |
|
| | 324 | | // Graphic Control Label(1 Byte) |
| | 325 | | // 0xf9 |
| 180 | 326 | | gcEx.m_graphicControlLabel = gifBytes[byteIndex]; |
| 180 | 327 | | byteIndex++; |
| | 328 | |
|
| | 329 | | // Block Size(1 Byte) |
| | 330 | | // 0x04 |
| 180 | 331 | | gcEx.m_blockSize = gifBytes[byteIndex]; |
| 180 | 332 | | 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) |
| 180 | 344 | | switch (gifBytes[byteIndex] & 28) |
| | 345 | | { // 0b00011100 |
| | 346 | | case 4: // 0b00000100 |
| 180 | 347 | | gcEx.m_disposalMethod = 1; |
| 180 | 348 | | break; |
| | 349 | | case 8: // 0b00001000 |
| 0 | 350 | | gcEx.m_disposalMethod = 2; |
| 0 | 351 | | break; |
| | 352 | | case 12: // 0b00001100 |
| 0 | 353 | | gcEx.m_disposalMethod = 3; |
| 0 | 354 | | break; |
| | 355 | | default: |
| 0 | 356 | | gcEx.m_disposalMethod = 0; |
| | 357 | | break; |
| | 358 | | } |
| | 359 | |
|
| | 360 | | // User Input Flag(1 Bit) |
| | 361 | | // Unknown |
| | 362 | |
|
| | 363 | | // Transparent Color Flag(1 Bit) |
| 180 | 364 | | gcEx.m_transparentColorFlag = (gifBytes[byteIndex] & 1) == 1; // 0b00000001 |
| | 365 | |
|
| 180 | 366 | | byteIndex++; |
| | 367 | | } |
| | 368 | |
|
| | 369 | | // Delay Time(2 Bytes) |
| 180 | 370 | | gcEx.m_delayTime = BitConverter.ToUInt16(gifBytes, byteIndex); |
| 180 | 371 | | byteIndex += 2; |
| | 372 | |
|
| | 373 | | // Transparent Color Index(1 Byte) |
| 180 | 374 | | gcEx.m_transparentColorIndex = gifBytes[byteIndex]; |
| 180 | 375 | | byteIndex++; |
| | 376 | |
|
| | 377 | | // Block Terminator(1 Byte) |
| 180 | 378 | | gcEx.m_blockTerminator = gifBytes[byteIndex]; |
| 180 | 379 | | byteIndex++; |
| | 380 | |
|
| 180 | 381 | | if (gifData.m_graphicCtrlExList == null) |
| | 382 | | { |
| 4 | 383 | | gifData.m_graphicCtrlExList = new List<GraphicControlExtension>(); |
| | 384 | | } |
| 180 | 385 | | gifData.m_graphicCtrlExList.Add(gcEx); |
| 180 | 386 | | } |
| | 387 | |
|
| | 388 | | private static void SetCommentExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData) |
| | 389 | | { |
| 0 | 390 | | CommentExtension commentEx = new CommentExtension(); |
| | 391 | |
|
| | 392 | | // Extension Introducer(1 Byte) |
| | 393 | | // 0x21 |
| 0 | 394 | | commentEx.m_extensionIntroducer = gifBytes[byteIndex]; |
| 0 | 395 | | byteIndex++; |
| | 396 | |
|
| | 397 | | // Comment Label(1 Byte) |
| | 398 | | // 0xfe |
| 0 | 399 | | commentEx.m_commentLabel = gifBytes[byteIndex]; |
| 0 | 400 | | byteIndex++; |
| | 401 | |
|
| | 402 | | // Block Size & Comment Data List |
| 0 | 403 | | while (true) |
| | 404 | | { |
| | 405 | | // Block Size(1 Byte) |
| 0 | 406 | | byte blockSize = gifBytes[byteIndex]; |
| 0 | 407 | | byteIndex++; |
| | 408 | |
|
| 0 | 409 | | if (blockSize == 0x00) |
| | 410 | | { |
| | 411 | | // Block Terminator(1 Byte) |
| | 412 | | break; |
| | 413 | | } |
| | 414 | |
|
| 0 | 415 | | var commentDataBlock = new CommentExtension.CommentDataBlock(); |
| 0 | 416 | | commentDataBlock.m_blockSize = blockSize; |
| | 417 | |
|
| | 418 | | // Comment Data(n Byte) |
| 0 | 419 | | commentDataBlock.m_commentData = new byte[commentDataBlock.m_blockSize]; |
| 0 | 420 | | for (int i = 0; i < commentDataBlock.m_commentData.Length; i++) |
| | 421 | | { |
| 0 | 422 | | commentDataBlock.m_commentData[i] = gifBytes[byteIndex]; |
| 0 | 423 | | byteIndex++; |
| | 424 | | } |
| | 425 | |
|
| 0 | 426 | | if (commentEx.m_commentDataList == null) |
| | 427 | | { |
| 0 | 428 | | commentEx.m_commentDataList = new List<CommentExtension.CommentDataBlock>(); |
| | 429 | | } |
| 0 | 430 | | commentEx.m_commentDataList.Add(commentDataBlock); |
| | 431 | | } |
| | 432 | |
|
| 0 | 433 | | if (gifData.m_commentExList == null) |
| | 434 | | { |
| 0 | 435 | | gifData.m_commentExList = new List<CommentExtension>(); |
| | 436 | | } |
| 0 | 437 | | gifData.m_commentExList.Add(commentEx); |
| 0 | 438 | | } |
| | 439 | |
|
| | 440 | | private static void SetPlainTextExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData) |
| | 441 | | { |
| 0 | 442 | | PlainTextExtension plainTxtEx = new PlainTextExtension(); |
| | 443 | |
|
| | 444 | | // Extension Introducer(1 Byte) |
| | 445 | | // 0x21 |
| 0 | 446 | | plainTxtEx.m_extensionIntroducer = gifBytes[byteIndex]; |
| 0 | 447 | | byteIndex++; |
| | 448 | |
|
| | 449 | | // Plain Text Label(1 Byte) |
| | 450 | | // 0x01 |
| 0 | 451 | | plainTxtEx.m_plainTextLabel = gifBytes[byteIndex]; |
| 0 | 452 | | byteIndex++; |
| | 453 | |
|
| | 454 | | // Block Size(1 Byte) |
| | 455 | | // 0x0c |
| 0 | 456 | | plainTxtEx.m_blockSize = gifBytes[byteIndex]; |
| 0 | 457 | | byteIndex++; |
| | 458 | |
|
| | 459 | | // Text Grid Left Position(2 Bytes) |
| | 460 | | // Not supported |
| 0 | 461 | | byteIndex += 2; |
| | 462 | |
|
| | 463 | | // Text Grid Top Position(2 Bytes) |
| | 464 | | // Not supported |
| 0 | 465 | | byteIndex += 2; |
| | 466 | |
|
| | 467 | | // Text Grid Width(2 Bytes) |
| | 468 | | // Not supported |
| 0 | 469 | | byteIndex += 2; |
| | 470 | |
|
| | 471 | | // Text Grid Height(2 Bytes) |
| | 472 | | // Not supported |
| 0 | 473 | | byteIndex += 2; |
| | 474 | |
|
| | 475 | | // Character Cell Width(1 Bytes) |
| | 476 | | // Not supported |
| 0 | 477 | | byteIndex++; |
| | 478 | |
|
| | 479 | | // Character Cell Height(1 Bytes) |
| | 480 | | // Not supported |
| 0 | 481 | | byteIndex++; |
| | 482 | |
|
| | 483 | | // Text Foreground Color Index(1 Bytes) |
| | 484 | | // Not supported |
| 0 | 485 | | byteIndex++; |
| | 486 | |
|
| | 487 | | // Text Background Color Index(1 Bytes) |
| | 488 | | // Not supported |
| 0 | 489 | | byteIndex++; |
| | 490 | |
|
| | 491 | | // Block Size & Plain Text Data List |
| 0 | 492 | | while (true) |
| | 493 | | { |
| | 494 | | // Block Size(1 Byte) |
| 0 | 495 | | byte blockSize = gifBytes[byteIndex]; |
| 0 | 496 | | byteIndex++; |
| | 497 | |
|
| 0 | 498 | | if (blockSize == 0x00) |
| | 499 | | { |
| | 500 | | // Block Terminator(1 Byte) |
| | 501 | | break; |
| | 502 | | } |
| | 503 | |
|
| 0 | 504 | | var plainTextDataBlock = new PlainTextExtension.PlainTextDataBlock(); |
| 0 | 505 | | plainTextDataBlock.m_blockSize = blockSize; |
| | 506 | |
|
| | 507 | | // Plain Text Data(n Byte) |
| 0 | 508 | | plainTextDataBlock.m_plainTextData = new byte[plainTextDataBlock.m_blockSize]; |
| 0 | 509 | | for (int i = 0; i < plainTextDataBlock.m_plainTextData.Length; i++) |
| | 510 | | { |
| 0 | 511 | | plainTextDataBlock.m_plainTextData[i] = gifBytes[byteIndex]; |
| 0 | 512 | | byteIndex++; |
| | 513 | | } |
| | 514 | |
|
| 0 | 515 | | if (plainTxtEx.m_plainTextDataList == null) |
| | 516 | | { |
| 0 | 517 | | plainTxtEx.m_plainTextDataList = new List<PlainTextExtension.PlainTextDataBlock>(); |
| | 518 | | } |
| 0 | 519 | | plainTxtEx.m_plainTextDataList.Add(plainTextDataBlock); |
| | 520 | | } |
| | 521 | |
|
| 0 | 522 | | if (gifData.m_plainTextExList == null) |
| | 523 | | { |
| 0 | 524 | | gifData.m_plainTextExList = new List<PlainTextExtension>(); |
| | 525 | | } |
| 0 | 526 | | gifData.m_plainTextExList.Add(plainTxtEx); |
| 0 | 527 | | } |
| | 528 | |
|
| | 529 | | private static void SetApplicationExtension(byte[] gifBytes, ref int byteIndex, ref GifData gifData) |
| | 530 | | { |
| | 531 | | // Extension Introducer(1 Byte) |
| | 532 | | // 0x21 |
| 4 | 533 | | gifData.m_appEx.m_extensionIntroducer = gifBytes[byteIndex]; |
| 4 | 534 | | byteIndex++; |
| | 535 | |
|
| | 536 | | // Extension Label(1 Byte) |
| | 537 | | // 0xff |
| 4 | 538 | | gifData.m_appEx.m_extensionLabel = gifBytes[byteIndex]; |
| 4 | 539 | | byteIndex++; |
| | 540 | |
|
| | 541 | | // Block Size(1 Byte) |
| | 542 | | // 0x0b |
| 4 | 543 | | gifData.m_appEx.m_blockSize = gifBytes[byteIndex]; |
| 4 | 544 | | byteIndex++; |
| | 545 | |
|
| | 546 | | // Application Identifier(8 Bytes) |
| 4 | 547 | | gifData.m_appEx.m_appId1 = gifBytes[byteIndex]; |
| 4 | 548 | | byteIndex++; |
| 4 | 549 | | gifData.m_appEx.m_appId2 = gifBytes[byteIndex]; |
| 4 | 550 | | byteIndex++; |
| 4 | 551 | | gifData.m_appEx.m_appId3 = gifBytes[byteIndex]; |
| 4 | 552 | | byteIndex++; |
| 4 | 553 | | gifData.m_appEx.m_appId4 = gifBytes[byteIndex]; |
| 4 | 554 | | byteIndex++; |
| 4 | 555 | | gifData.m_appEx.m_appId5 = gifBytes[byteIndex]; |
| 4 | 556 | | byteIndex++; |
| 4 | 557 | | gifData.m_appEx.m_appId6 = gifBytes[byteIndex]; |
| 4 | 558 | | byteIndex++; |
| 4 | 559 | | gifData.m_appEx.m_appId7 = gifBytes[byteIndex]; |
| 4 | 560 | | byteIndex++; |
| 4 | 561 | | gifData.m_appEx.m_appId8 = gifBytes[byteIndex]; |
| 4 | 562 | | byteIndex++; |
| | 563 | |
|
| | 564 | | // Application Authentication Code(3 Bytes) |
| 4 | 565 | | gifData.m_appEx.m_appAuthCode1 = gifBytes[byteIndex]; |
| 4 | 566 | | byteIndex++; |
| 4 | 567 | | gifData.m_appEx.m_appAuthCode2 = gifBytes[byteIndex]; |
| 4 | 568 | | byteIndex++; |
| 4 | 569 | | gifData.m_appEx.m_appAuthCode3 = gifBytes[byteIndex]; |
| 4 | 570 | | byteIndex++; |
| | 571 | |
|
| | 572 | | // Block Size & Application Data List |
| 4 | 573 | | while (true) |
| | 574 | | { |
| | 575 | | // Block Size (1 Byte) |
| 8 | 576 | | byte blockSize = gifBytes[byteIndex]; |
| 8 | 577 | | byteIndex++; |
| | 578 | |
|
| 8 | 579 | | if (blockSize == 0x00) |
| | 580 | | { |
| | 581 | | // Block Terminator(1 Byte) |
| | 582 | | break; |
| | 583 | | } |
| | 584 | |
|
| 4 | 585 | | var appDataBlock = new ApplicationExtension.ApplicationDataBlock(); |
| 4 | 586 | | appDataBlock.m_blockSize = blockSize; |
| | 587 | |
|
| | 588 | | // Application Data(n Byte) |
| 4 | 589 | | appDataBlock.m_applicationData = new byte[appDataBlock.m_blockSize]; |
| 32 | 590 | | for (int i = 0; i < appDataBlock.m_applicationData.Length; i++) |
| | 591 | | { |
| 12 | 592 | | appDataBlock.m_applicationData[i] = gifBytes[byteIndex]; |
| 12 | 593 | | byteIndex++; |
| | 594 | | } |
| | 595 | |
|
| 4 | 596 | | if (gifData.m_appEx.m_appDataList == null) |
| | 597 | | { |
| 4 | 598 | | gifData.m_appEx.m_appDataList = new List<ApplicationExtension.ApplicationDataBlock>(); |
| | 599 | | } |
| 4 | 600 | | gifData.m_appEx.m_appDataList.Add(appDataBlock); |
| | 601 | | } |
| 4 | 602 | | } |
| | 603 | | } |