123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using UnityEngine;
-
- namespace UnityEditor.U2D.Aseprite
- {
- /// <summary>
- /// File parsing utility for Aseprite files.
- /// </summary>
- public static class AsepriteReader
- {
- /// <summary>
- /// Reads an Aseprite file from the given path.
- /// </summary>
- /// <param name="assetPath">Path to the file.</param>
- /// <returns>Returns a parsed representation of the file.</returns>
- public static AsepriteFile ReadFile(string assetPath)
- {
- var doesFileExist = File.Exists(assetPath);
- if (!doesFileExist)
- {
- Debug.LogError($"File does not exist at path: {assetPath}");
- return null;
- }
-
- var fileStream = new FileStream(assetPath, FileMode.Open, FileAccess.Read);
- var binaryReader = new BinaryReader(fileStream);
-
- var file = new AsepriteFile();
- try
- {
- file.Read(binaryReader);
- ReadFrames(in binaryReader, ref file);
- }
- catch (Exception e)
- {
- Debug.LogError($"Failed to import file: {assetPath}. Error: {e.Message} \n{e.StackTrace}");
- file = null;
- }
- finally
- {
- binaryReader.Close();
- fileStream.Close();
- }
-
- return file;
- }
-
- static void ReadFrames(in BinaryReader reader, ref AsepriteFile file)
- {
- var paletteProvider = default(IPaletteProvider);
-
- for (var i = 0; i < file.noOfFrames; ++i)
- {
- var frame = new FrameData();
- frame.Read(reader);
- file.SetFrameData(i, frame);
-
- var noOfChunks = frame.chunkCount;
- for (var m = 0; m < noOfChunks; ++m)
- {
- var chunkHeader = new ChunkHeader();
- chunkHeader.Read(reader);
-
- BaseChunk chunk = null;
- switch (chunkHeader.chunkType)
- {
- case ChunkTypes.Cell:
- chunk = new CellChunk(chunkHeader.chunkSize, file.colorDepth, paletteProvider?.entries, file.alphaPaletteEntry);
- break;
- case ChunkTypes.CellExtra:
- chunk = new CellExtra(chunkHeader.chunkSize);
- break;
- case ChunkTypes.ColorProfile:
- chunk = new ColorProfileChunk(chunkHeader.chunkSize);
- break;
- case ChunkTypes.ExternalFiles:
- chunk = new ExternalFilesChunk(chunkHeader.chunkSize);
- break;
- case ChunkTypes.Layer:
- chunk = new LayerChunk(chunkHeader.chunkSize);
- break;
- case ChunkTypes.Mask:
- chunk = new MaskChunk(chunkHeader.chunkSize);
- break;
- case ChunkTypes.OldPalette:
- chunk = new OldPaletteChunk(chunkHeader.chunkSize);
- paletteProvider = ((IPaletteProvider)chunk);
- break;
- case ChunkTypes.OldPalette2:
- chunk = new OldPaletteChunk2(chunkHeader.chunkSize);
- break;
- case ChunkTypes.Palette:
- chunk = new PaletteChunk(chunkHeader.chunkSize);
- paletteProvider = ((IPaletteProvider)chunk);
- break;
- case ChunkTypes.Path:
- chunk = new PathChunk(chunkHeader.chunkSize);
- break;
- case ChunkTypes.Slice:
- chunk = new SliceChunk(chunkHeader.chunkSize);
- break;
- case ChunkTypes.Tags:
- chunk = new TagsChunk(chunkHeader.chunkSize);
- break;
- case ChunkTypes.Tileset:
- chunk = new TilesetChunk(chunkHeader.chunkSize, file.colorDepth, paletteProvider?.entries, file.alphaPaletteEntry);
- break;
- case ChunkTypes.UserData:
- chunk = new UserDataChunk(chunkHeader.chunkSize);
- break;
- default:
- Debug.LogWarning($"Could not read chunk data with ID: {chunkHeader.chunkType}. Aborting.");
- return;
- }
-
- var successful = chunk.Read(reader);
- if (!successful)
- {
- frame.SetChunkData(m, new NoneChunk(0));
- continue;
- }
-
- frame.SetChunkData(m, chunk);
-
- if (chunk.chunkType == ChunkTypes.UserData)
- AssociateUserDataWithChunk(frame.chunks, m, (UserDataChunk)chunk);
- }
- }
- }
-
- static void AssociateUserDataWithChunk(IReadOnlyList<BaseChunk> chunks, int index, UserDataChunk userData)
- {
- BaseChunk firstNonDataChunk = null;
- for (var i = index; i >= 0; --i)
- {
- if (chunks[i] != null && chunks[i] is not UserDataChunk)
- {
- firstNonDataChunk = chunks[i];
- break;
- }
- }
-
- if (firstNonDataChunk == null)
- return;
-
- switch (firstNonDataChunk.chunkType)
- {
- case ChunkTypes.Cell:
- ((CellChunk)firstNonDataChunk).dataChunk = userData;
- break;
- }
- }
- }
- }
|