using System;
using System.Collections.ObjectModel;
using System.IO;
using Unity.Collections;
using UnityEngine;
namespace UnityEditor.U2D.Aseprite
{
///
/// Flags to define where data for a tileset is stored.
///
[Flags]
public enum TileSetFlags
{
/// Includes a link to an external file
IncludesLinkToExternal = 1,
/// Includes a link to files in this file
IncludesTilesInFile = 2,
/// Misc
Misc = 4,
}
///
/// Parsed representation of an Aseprite Tileset chunk.
/// Not supported yet.
///
public class TilesetChunk : BaseChunk
{
///
public override ChunkTypes chunkType => ChunkTypes.Tileset;
///
/// The ID of the tileset.
///
public uint tileSetId { get; private set; }
///
/// Flags to define where data for a tileset is stored.
///
public TileSetFlags tileSetFlags { get; private set; }
///
/// The number of tiles in the tileset.
///
public uint noOfTiles { get; private set; }
///
/// Tile width in pixels.
///
public ushort width { get; private set; }
///
/// Tile height in pixels.
///
public ushort height { get; private set; }
///
/// The name of the tileset.
///
public string tileSetName { get; private set; }
///
/// The image data of the tiles.
///
public NativeArray[] tileImages { get; private set; }
readonly ushort m_ColorDepth;
readonly ReadOnlyCollection m_PaletteEntries;
readonly byte m_AlphaPaletteEntry;
internal TilesetChunk(uint chunkSize, ushort colorDepth, ReadOnlyCollection paletteEntries, byte alphaPaletteEntry) : base(chunkSize)
{
m_ColorDepth = colorDepth;
m_PaletteEntries = paletteEntries;
m_AlphaPaletteEntry = alphaPaletteEntry;
}
///
/// Read and store the chunk data.
///
/// The active binary reader of the file.
protected override void InternalRead(BinaryReader reader)
{
tileSetId = reader.ReadUInt32();
tileSetFlags = (TileSetFlags)reader.ReadUInt32();
noOfTiles = reader.ReadUInt32();
width = reader.ReadUInt16();
height = reader.ReadUInt16();
var baseIndex = reader.ReadInt16();
var reservedBytes = reader.ReadBytes(14);
tileSetName = AsepriteUtilities.ReadString(reader);
if (string.IsNullOrEmpty(tileSetName))
tileSetName = $"Tileset_{tileSetId}";
// Not supported yet.
if ((tileSetFlags & TileSetFlags.IncludesLinkToExternal) != 0)
{
var idOfExternalFile = reader.ReadUInt32();
var tileSetIdInExternal = reader.ReadUInt32();
}
if ((tileSetFlags & TileSetFlags.IncludesTilesInFile) != 0)
{
var compressedDataLength = (int)reader.ReadUInt32();
var decompressedData = AsepriteUtilities.ReadAndDecompressedData(reader, compressedDataLength);
using var tilemapImage = AsepriteUtilities.GenerateImageData(m_ColorDepth, decompressedData, m_PaletteEntries, m_AlphaPaletteEntry);
tileImages = new NativeArray[noOfTiles];
for (var i = 0; i < noOfTiles; ++i)
{
var tileImage = new NativeArray(width * height, Allocator.Persistent);
var tileStartHeight = i * height;
for (var m = 0; m < height; ++m)
{
var sourceHeight = (tileStartHeight + m) * width;
var destHeight = m * width;
NativeArray.Copy(tilemapImage, sourceHeight, tileImage, destHeight, width);
}
tileImages[i] = tileImage;
}
}
}
///
/// Dispose of the image data.
///
public override void Dispose()
{
if (tileImages == null || tileImages.Length == 0)
return;
for (var i = 0; i < tileImages.Length; ++i)
tileImages[i].DisposeIfCreated();
}
}
}