No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AsepriteFile.cs 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /// .ase & .aseprite file format specs:
  2. /// https://github.com/aseprite/aseprite/blob/main/docs/ase-file-specs.md
  3. using System;
  4. using System.Collections.ObjectModel;
  5. using System.IO;
  6. using UnityEngine.Assertions;
  7. namespace UnityEditor.U2D.Aseprite
  8. {
  9. /// <summary>
  10. /// Parsed representation of an Aseprite file.
  11. /// Should be disposed after use.
  12. /// </summary>
  13. public class AsepriteFile : IDisposable
  14. {
  15. /// <summary>
  16. /// File size in bytes.
  17. /// </summary>
  18. public uint fileSize { get; private set; }
  19. /// <summary>
  20. /// Number of frames in the file.
  21. /// </summary>
  22. public ushort noOfFrames { get; private set; }
  23. /// <summary>
  24. /// Canvas width in pixels.
  25. /// </summary>
  26. public ushort width { get; private set; }
  27. /// <summary>
  28. /// Canvas height in pixels.
  29. /// </summary>
  30. public ushort height { get; private set; }
  31. /// <summary>
  32. /// Color depth (bits per pixel).
  33. /// </summary>
  34. public ushort colorDepth { get; private set; }
  35. internal uint flags { get; private set; }
  36. /// <summary>
  37. /// Time per frame in milliseconds.
  38. /// </summary>
  39. public ushort animSpeed { get; private set; }
  40. /// <summary>
  41. /// Palette entry (index) which represent transparent color
  42. /// in all non-background layers (only for Indexed sprites).
  43. /// </summary>
  44. public byte alphaPaletteEntry { get; private set; }
  45. /// <summary>
  46. /// Number of colors (0 means 256 for old sprites).
  47. /// </summary>
  48. public ushort noOfColors { get; private set; }
  49. /// <summary>
  50. /// Pixel width (pixel ratio is "pixel width/pixel height").
  51. /// If this or pixel height field is zero, pixel ratio is 1:1.
  52. /// </summary>
  53. public byte pixelWidth { get; private set; }
  54. /// <summary>
  55. /// Pixel height (pixel ratio is "pixel width/pixel height").
  56. /// If this or pixel width field is zero, pixel ratio is 1:1.
  57. /// </summary>
  58. public byte pixelHeight { get; private set; }
  59. /// <summary>
  60. /// X position of the grid.
  61. /// </summary>
  62. public short gridPosX { get; private set; }
  63. /// <summary>
  64. /// Y position of the grid.
  65. /// </summary>
  66. public short gridPosY { get; private set; }
  67. /// <summary>
  68. /// Grid width (zero if there is no grid, grid size is 16x16 on Aseprite by default).
  69. /// </summary>
  70. public ushort gridWidth { get; private set; }
  71. /// <summary>
  72. /// Grid height (zero if there is no grid).
  73. /// </summary>
  74. public ushort gridHeight { get; private set; }
  75. /// <summary>
  76. /// Parsed data of each frame.
  77. /// </summary>
  78. public ReadOnlyCollection<FrameData> frameData => Array.AsReadOnly(m_FrameData);
  79. FrameData[] m_FrameData;
  80. internal void Read(BinaryReader reader)
  81. {
  82. var streamLength = reader.BaseStream.Length;
  83. Assert.IsTrue(streamLength >= 128, "File is too small to be a valid Aseprite file.");
  84. fileSize = reader.ReadUInt32();
  85. var misc0 = reader.ReadUInt16();
  86. noOfFrames = reader.ReadUInt16();
  87. width = reader.ReadUInt16();
  88. height = reader.ReadUInt16();
  89. colorDepth = reader.ReadUInt16();
  90. flags = reader.ReadUInt32();
  91. animSpeed = reader.ReadUInt16();
  92. var misc1 = reader.ReadUInt32();
  93. var misc2 = reader.ReadUInt32();
  94. alphaPaletteEntry = reader.ReadByte();
  95. var miscByte0 = reader.ReadByte();
  96. var miscByte1 = reader.ReadByte();
  97. var miscByte2 = reader.ReadByte();
  98. noOfColors = reader.ReadUInt16();
  99. pixelWidth = reader.ReadByte();
  100. pixelHeight = reader.ReadByte();
  101. gridPosX = reader.ReadInt16();
  102. gridPosY = reader.ReadInt16();
  103. gridWidth = reader.ReadUInt16();
  104. gridHeight = reader.ReadUInt16();
  105. Assert.IsTrue(misc0 == 0xA5E0, "Unexpected file content. The file is most likely corrupt.");
  106. // Unused 84 bytes
  107. for (var i = 0; i < 84; ++i)
  108. reader.ReadByte();
  109. m_FrameData = new FrameData[noOfFrames];
  110. }
  111. internal void SetFrameData(int index, FrameData data)
  112. {
  113. if (index < 0 || index >= m_FrameData.Length)
  114. return;
  115. m_FrameData[index] = data;
  116. }
  117. public void Dispose()
  118. {
  119. for (var i = 0; i < m_FrameData.Length; ++i)
  120. m_FrameData[i].Dispose();
  121. }
  122. }
  123. }