From fafac6707a61f086e7b0f8baca5bdafb92a514f2 Mon Sep 17 00:00:00 2001 From: Michael Miriti Date: Sun, 26 May 2024 19:51:47 +0300 Subject: [PATCH] 2.1.0 - full support for the way palettes are stored in Aseprite 1.3.5 --- README.md | 45 ++++--- documentation/404.html | 2 +- documentation/ase/Ase.html | 2 +- documentation/ase/AseHeader.html | 2 +- documentation/ase/Cel.html | 2 +- documentation/ase/Frame.html | 2 +- documentation/ase/FrameHeader.html | 2 +- documentation/ase/Layer.html | 2 +- documentation/ase/Palette.html | 4 +- documentation/ase/PaletteEntry.html | 10 ++ documentation/ase/chunks/CelChunk.html | 2 +- documentation/ase/chunks/CelExtraChunk.html | 2 +- documentation/ase/chunks/Chunk.html | 2 +- documentation/ase/chunks/ChunkHeader.html | 2 +- .../ase/chunks/ColorProfileChunk.html | 2 +- .../ase/chunks/ExternalFilesChunk.html | 2 +- documentation/ase/chunks/LayerBlendMode.html | 2 +- documentation/ase/chunks/LayerChunk.html | 2 +- documentation/ase/chunks/LayerFlags.html | 2 +- documentation/ase/chunks/LayerType.html | 2 +- documentation/ase/chunks/MaskChunk.html | 2 +- documentation/ase/chunks/OldPaleteChunk.html | 2 +- documentation/ase/chunks/Packet.html | 2 +- documentation/ase/chunks/PaletteChunk.html | 2 +- .../ase/chunks/PaletteChunkEntry.html | 10 ++ documentation/ase/chunks/PaletteEntry.html | 10 -- documentation/ase/chunks/SliceChunk.html | 2 +- documentation/ase/chunks/SliceKey.html | 2 +- documentation/ase/chunks/Tag.html | 2 +- documentation/ase/chunks/TagsChunk.html | 2 +- documentation/ase/chunks/TilesetChunk.html | 2 +- documentation/ase/chunks/UserDataChunk.html | 2 +- documentation/ase/chunks/index.html | 2 +- documentation/ase/index.html | 2 +- documentation/ase/types/CelType.html | 2 +- documentation/ase/types/ChunkType.html | 2 +- documentation/ase/types/ColorDepth.html | 2 +- documentation/ase/types/ColorProfileType.html | 2 +- documentation/ase/types/Serializable.html | 2 +- documentation/ase/types/index.html | 2 +- documentation/index.html | 2 +- documentation/nav.js | 2 +- haxelib.json | 9 +- src/ase/Ase.hx | 70 ++++++++--- src/ase/Cel.hx | 2 +- src/ase/Palette.hx | 110 +++++++++++++++--- src/ase/chunks/Chunk.hx | 10 +- src/ase/chunks/OldPaleteChunk.hx | 35 +++++- src/ase/chunks/PaletteChunk.hx | 39 +++++-- test/TestMain.hx | 73 +++++++++--- test_files/128x128_rgba.aseprite | Bin 1172 -> 954 bytes test_files/1x1_old_pal.aseprite | Bin 0 -> 251 bytes test_files/old_palette.aseprite | Bin 0 -> 2912 bytes test_files/slices.aseprite | Bin 5400 -> 5182 bytes 54 files changed, 361 insertions(+), 140 deletions(-) create mode 100644 documentation/ase/PaletteEntry.html create mode 100644 documentation/ase/chunks/PaletteChunkEntry.html delete mode 100644 documentation/ase/chunks/PaletteEntry.html create mode 100644 test_files/1x1_old_pal.aseprite create mode 100644 test_files/old_palette.aseprite diff --git a/README.md b/README.md index 41a9279..dbb16b9 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ # ASE -.ase/.aseprite file format reader/writer written in Haxe with no external dependencies. +A `.ase/.aseprite` file format reader/writer written in Haxe with no external dependencies. -Implemented following the official [Aseprite File Format (.ase/.aseprite) Specifications](https://github.com/aseprite/aseprite/blob/master/docs/ase-file-specs.md) +Implemented following the official [Aseprite File Format (.ase/.aseprite) Specifications](https://github.com/aseprite/aseprite/blob/master/docs/ase-file-specs.md). -Note that this library only provides reading and writing of the Aseprite file format. If you need rendering you will have to implement it yourself or use one of the existing rendering libraries: +Note that this library only provides reading and writing of the Aseprite file format. If you need rendering, you will have to implement it yourself or use one of the existing rendering libraries: - [OpenFL Aseprite](https://github.com/miriti/openfl-aseprite) - [heaps-aseprite](https://github.com/AustinEast/heaps-aseprite) by [Austin East](https://github.com/AustinEast) @@ -20,13 +20,13 @@ Note that this library only provides reading and writing of the Aseprite file fo ### Installation -``` +```shell haxelib install ase ``` ### Usage -#### Parsing files +#### Parsing Files ```haxe import sys.io.File; @@ -47,16 +47,13 @@ var spriteColorDepth:ColorDepth = ase.colorDepth; Palette: ```haxe -for(index in ase.palette.firstIndex...ase.palette.lastIndex+1) { - var entry:PaletteEntry = ase.palette.getEntry(index); - - var r:Int = entry.r; - var g:Int = entry.g; - var b:Int = entry.b; - var a:Int = entry.a; +for(index => entry in ase.palette.entries) { + trace('Red: ${entry.red}, Green: ${entry.green}, Blue: ${entry.blue}, Alpha: ${entry.alpha}'); - var rgbaColor = ase.palette.getRGBA(index); - var argbColor = ase.palette.getARGB(index); + // Alternatively, get the 32-bit integer RGBA or ARGB value + var rgbaColor:Int = ase.palette.getRGBA(index); + var argbColor:Int = ase.palette.getARGB(index); + trace('RGBA: ${StringTools.hex(rgbaColor, 8)}, ARGB: ${StringTools.hex(argbColor, 8)}'); } ``` @@ -66,7 +63,7 @@ Layers: for(layer in ase.layers) { var layerName:String = layer.name; var layerEditable:Bool = layer.editable; - var layerVisible = layer.visible; + var layerVisible:Bool = layer.visible; } ``` @@ -88,10 +85,9 @@ var celHeight:Int = frame.cel(layerIndex).height; var celPixelData:Bytes = frame.cel(layerIndex).pixelData; ``` -#### Create files +#### Creating Files ```haxe - var spriteWidth:Int = 320; var spriteHeight:Int = 320; var colorDepth:ColorDepth = INDEXED; @@ -105,16 +101,15 @@ var initialPalette:Array = [ ]; var ase = Ase.create(spriteWidth, spriteHeight, colorDepth); - ``` -Newly created file always comes with one blank frame. To add some content add at least one layer first: +A newly created file always comes with one blank frame. To add some content, add at least one layer first: ```haxe ase.addLayer('Background'); ``` -Now to add some pixels to the sprite create a Cel on the first frame and the newly created layer: +Now, to add some pixels to the sprite, create a Cel on the first frame and the newly created layer: ```haxe var layerIndex:Int = 0; @@ -139,16 +134,20 @@ cel.fillIndex(0); // Fill the cel with color #0 from the palette cel.fillColor(0xff00ff00); // Fill the cel with ARGB color (for 32bpp mode) cel.setPixel(20, 20, 0xff0033aa); // Set ARGB color at x and y cel.setPixel(20, 20, 4); // Set color index at x and y -cel.setPixelData(bytes, 300, 300); // Set bytes of the pixel data (the size must me equal to width x height x bpp) +cel.setPixelData(bytes, 300, 300); // Set bytes of the pixel data (the size must be equal to width x height x bpp) ``` -At any time you can get the file representation as bytes and, for example, store them to a file: +At any time, you can get the file representation as bytes and, for example, store them to a file: ```haxe var bytes = ase.getBytes(); File.saveBytes('my_aseprite_file.aseprite', bytes); ``` +## Contributors + +See [https://github.com/miriti/ase/graphs/contributors](https://github.com/miriti/ase/graphs/contributors). + ## License -This project is licensed under the MIT License - see the LICENSE.md file for details +This project is licensed under the MIT License - see the [LICENSE.md](./LICENSE.md) file for details. diff --git a/documentation/404.html b/documentation/404.html index 269a42f..84dcc7c 100644 --- a/documentation/404.html +++ b/documentation/404.html @@ -1 +1 @@ -File not found

404 Page not found

Page not found, sorry.

\ No newline at end of file +File not found

404 Page not found

Page not found, sorry.

\ No newline at end of file diff --git a/documentation/ase/Ase.html b/documentation/ase/Ase.html index 3a73957..bafeca2 100644 --- a/documentation/ase/Ase.html +++ b/documentation/ase/Ase.html @@ -8,4 +8,4 @@ text-shadow: 0 0 0 transparent; }

Aseprite file format reader/writer

Static methods

@:value({ colorDepth : BPP32 })staticcreate(width:Int, height:Int, colorDepth:ColorDepth = BPP32, ?initialPalette:Array<Int>):Ase

Create a new Ase instance

Parameters:

width

File width

height

File height

colorDepth

(optional, default BPP32) color depth. BPP32, BPP16, BPP8 or INDEXED

initialPalette

(optional) Array of RGBA values for initial palette

staticfromBytes(bytes:Bytes):Ase

Create a new Ase instance by parsing bytes loaded from a file or network

Parameters:

bytes

bytes to parse

staticmain():Void

Variables

read onlycolorDepth:ColorDepth

Read-only color depth of the file

read onlyfileSize:Int

Files size in bytes

read onlyfirstFrame:Frame

@:value([])frames:Array<Frame> = []

height:Int

Sprite height

@:value([])finallayers:Array<Layer> = []

width:Int

Sprite width

Methods

@:value({ duration : 100, copyPrev : false })addFrame(copyPrev:Bool = false, duration:Int = 100):Frame

Add a frame to the sprite

Parameters:

copyPrev

if true will copy all the cel from the previous frame

duration

Duration of the frame in milliseconds

@:value({ editable : true, visible : true })addLayer(?name:String, visible:Bool = true, editable:Bool = true):Ase

Create a new layer

Parameters:

name

(optional) Name for the new layer. If not specified Layer N -will be used where N is the amount of currently existing layers + 1

visible

(optional, default true)

editable

(optional, default true)

initPalette(colors:Array<Int>):Void

Initialize the pallet

Parameters:

colors

Array of RGBA color values for the new pallet

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file +will be used where N is the amount of currently existing layers + 1

visible

(optional, default true)

editable

(optional, default true)

initPalette(colors:Array<Int>):Void

Initialize the pallet

Parameters:

colors

Array of RGBA color values for the new pallet

toBytes(?out:BytesOutput):Bytes

Converts Aseprite data to binary data that can be stored to a file

toString():String

\ No newline at end of file diff --git a/documentation/ase/AseHeader.html b/documentation/ase/AseHeader.html index d7feee4..8d0987e 100644 --- a/documentation/ase/AseHeader.html +++ b/documentation/ase/AseHeader.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static variables

@:value(0xA5E0)staticfinalread onlyASEPRITE_MAGIC:Int = 0xA5E0

@:value(128)staticfinalread onlySIZE:Int = 128

Static methods

staticfromBytes(headerData:Bytes):AseHeader

Constructor

new()

Variables

@:value(BPP32)colorDepth:ColorDepth = BPP32

@:value(0)colorsNumber:Int = 0

fileSize:Int32

@:value(1)flags:Int32 = 1

frames:Int

@:value(16)gridHeight:Int = 16

@:value(16)gridWidth:Int = 16

@:value(0)gridX:Int = 0

@:value(0)gridY:Int = 0

height:Int

@:value(ASEPRITE_MAGIC)magic:Int = ASEPRITE_MAGIC

@:value(0)paletteEntry:Int = 0

@:value(0)pixelHeight:Int = 0

@:value(0)pixelWidth:Int = 0

read onlysize:Int

@:value(100)speed:Int = 100

width:Int

Methods

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file +

Static variables

@:value(0xA5E0)staticfinalread onlyASEPRITE_MAGIC:Int = 0xA5E0

@:value(128)staticfinalread onlySIZE:Int = 128

Static methods

staticfromBytes(headerData:Bytes):AseHeader

Constructor

new()

Variables

@:value(BPP32)colorDepth:ColorDepth = BPP32

@:value(0)colorsNumber:Int = 0

fileSize:Int32

@:value(1)flags:Int32 = 1

frames:Int

@:value(16)gridHeight:Int = 16

@:value(16)gridWidth:Int = 16

@:value(0)gridX:Int = 0

@:value(0)gridY:Int = 0

height:Int

@:value(ASEPRITE_MAGIC)magic:Int = ASEPRITE_MAGIC

@:value(0)paletteEntry:Int = 0

@:value(0)pixelHeight:Int = 0

@:value(0)pixelWidth:Int = 0

read onlysize:Int

@:value(100)speed:Int = 100

width:Int

Methods

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file diff --git a/documentation/ase/Cel.html b/documentation/ase/Cel.html index 9c48e76..daa97fc 100644 --- a/documentation/ase/Cel.html +++ b/documentation/ase/Cel.html @@ -8,4 +8,4 @@ text-shadow: 0 0 0 transparent; }

Constructor

new(?chunk:CelChunk, ?celType:CelType, frame:Frame, layerIndex:Int, ?width:Int, ?height:Int)

Variables

read onlyheight:Int

Cel height

layerIndex:Int

Layer index

read onlypixelData:Bytes

Uncompressed Bytes representing pixels of the Cel.

  • 32 bit ARGB value per pixel for 32 bit color depth
  • 16 bit greyscale value 0x0000 = black, 0xffff = white
  • 8 bit index value per pixel for Indexed

read onlypixelDataLength:Int

Required length of the data in bytes. -Always equals to width x height x (bpp / 8)

read onlywidth:Int

Cel width

xPosition:Int

Cel x position

yPosition:Int

Cel y position

Methods

clone():Cel

Create a new identical cel

fillColor(argb:Int):Void

fillIndex(index:Int):Void

getPixel(px:Int, py:Int):Null<Int>

Get pixel color or color index at given position

init(width:Int, height:Int):Void

Initalize Cel pixel data

Parameters:

width
null

height

link(frameIndex:Int):Void

Make this cel linked to the one located at frameIndex on the same layer

Parameters:

frameIndex

Index of the frame with the cel to link to

setPixel(px:Int, py:Int, color:Int):Void

Set pixel color or color index at given position

Parameters:

px

x

py

y

color

ARGB color for 32bpp mode, GGGG color for 16bpp mode and index or GG color for Indexed or 8bpp mode

setPixelData(newData:Bytes, ?newWidth:Int, ?newHeight:Int):Void

Set new pixel data

\ No newline at end of file +Always equals to width x height x (bpp / 8)

read onlywidth:Int

Cel width

xPosition:Int

Cel x position

yPosition:Int

Cel y position

Methods

clone():Cel

Create a new identical cel

fillColor(argb:Int):Void

fillIndex(index:Int):Void

getPixel(px:Int, py:Int):Null<Int>

Get pixel color or color index at given position

init(width:Int, height:Int):Void

Initalize Cel pixel data

Parameters:

width
null

height

link(frameIndex:Int):Void

Make this cel linked to the one located at frameIndex on the same layer

Parameters:

frameIndex

Index of the frame with the cel to link to

setPixel(px:Int, py:Int, color:Int):Void

Set pixel color or color index at given position

Parameters:

px

x

py

y

color

ARGB color for 32bpp mode, GGGG color for 16bpp mode and index or GG color for Indexed or 8bpp mode

setPixelData(newData:Bytes, ?newWidth:Int, ?newHeight:Int):Void

Set new pixel data

\ No newline at end of file diff --git a/documentation/ase/Frame.html b/documentation/ase/Frame.html index d31634f..e645014 100644 --- a/documentation/ase/Frame.html +++ b/documentation/ase/Frame.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes, ?ase:Ase):Frame

Parse bytes to create a new frame

Parameters:

bytes

bytes to parse

ase

(optional) ase.Ase instance to attach the frame to

Constructor

new(?header:FrameHeader, ?ase:Ase)

Variables

@:value([])finalcels:Map<Int, Cel> = []

@:value([])chunkTypes:Map<ChunkType, Array<Chunk>> = []

@:value([])chunks:Array<Chunk> = []

read onlysize:Int

Frame size in bytes

Methods

addChunk(chunk:Chunk):Void

cel(layerIndex:Int, ?replace:Cel):Cel

Access a cel at specific layer

Parameters:

layerIndex

Index of the layer

replace

Place this cel at a specific layer

clearCel(layerIndex:Int):Void

createCel(layerIndex:Int, width:Int, height:Int, ?xPosition:Int, ?yPosition:Int):Cel

Create Cel

Parameters:

layerIndex

Index of the layer to create new cel on

width

Cel width

height

Cel height

xPosition

Cel x position

yPosition

Cel y position

linkCel(layerIndex:Int, frameIndex:Int):Cel

Create a linked cel

Parameters:

layerIndex
null

frameIndex

removeChunk(chunk:Chunk):Void

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes, ?ase:Ase):Frame

Parse bytes to create a new frame

Parameters:

bytes

bytes to parse

ase

(optional) ase.Ase instance to attach the frame to

Constructor

new(?header:FrameHeader, ?ase:Ase)

Variables

@:value([])finalcels:Map<Int, Cel> = []

@:value([])chunkTypes:Map<ChunkType, Array<Chunk>> = []

@:value([])chunks:Array<Chunk> = []

read onlysize:Int

Frame size in bytes

Methods

addChunk(chunk:Chunk):Void

cel(layerIndex:Int, ?replace:Cel):Cel

Access a cel at specific layer

Parameters:

layerIndex

Index of the layer

replace

Place this cel at a specific layer

clearCel(layerIndex:Int):Void

createCel(layerIndex:Int, width:Int, height:Int, ?xPosition:Int, ?yPosition:Int):Cel

Create Cel

Parameters:

layerIndex

Index of the layer to create new cel on

width

Cel width

height

Cel height

xPosition

Cel x position

yPosition

Cel y position

linkCel(layerIndex:Int, frameIndex:Int):Cel

Create a linked cel

Parameters:

layerIndex
null

frameIndex

removeChunk(chunk:Chunk):Void

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file diff --git a/documentation/ase/FrameHeader.html b/documentation/ase/FrameHeader.html index 02a5a3a..d1fb6a6 100644 --- a/documentation/ase/FrameHeader.html +++ b/documentation/ase/FrameHeader.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static variables

@:value(16)staticfinalread onlyBYTE_SIZE:Int = 16

@:value(0xF1FA)staticfinalread onlyMAGIC:Int = 0xF1FA

Static methods

staticfromBytes(bytes:Bytes):FrameHeader

Constructor

new()

Variables

@:value(100)duration:Int = 100

@:value(MAGIC)magic:Int = MAGIC

@:value(0)numChunks:Int = 0

@:value(0)oldNumChunks:Int = 0

@:value(0)size:Int = 0

Methods

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file +

Static variables

@:value(16)staticfinalread onlyBYTE_SIZE:Int = 16

@:value(0xF1FA)staticfinalread onlyMAGIC:Int = 0xF1FA

Static methods

staticfromBytes(bytes:Bytes):FrameHeader

Constructor

new()

Variables

@:value(100)duration:Int = 100

@:value(MAGIC)magic:Int = MAGIC

@:value(0)numChunks:Int = 0

@:value(0)oldNumChunks:Int = 0

@:value(0)size:Int = 0

Methods

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file diff --git a/documentation/ase/Layer.html b/documentation/ase/Layer.html index 671a6da..e16fd51 100644 --- a/documentation/ase/Layer.html +++ b/documentation/ase/Layer.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Constructor

new(?chunk:LayerChunk)

Variables

\ No newline at end of file +

Constructor

new(?chunk:LayerChunk)

Variables

\ No newline at end of file diff --git a/documentation/ase/Palette.html b/documentation/ase/Palette.html index c61f40a..8be6cf4 100644 --- a/documentation/ase/Palette.html +++ b/documentation/ase/Palette.html @@ -7,4 +7,6 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static variables

@:value([0x000000ff, 0x222034ff, 0x45283cff, 0x663931ff, 0x8f563bff, 0xdf7126ff, 0xd9a066ff, 0xeec39aff, 0xfbf236ff, 0x99e550ff, 0x6abe30ff, 0x37946eff, 0x4b692fff, 0x524b24ff, 0x323c39ff, 0x3f3f74ff, 0x306082ff, 0x5b6ee1ff, 0x639bffff, 0x5fcde4ff, 0xcbdbfcff, 0xffffffff, 0x9badb7ff, 0x847e87ff, 0x696a6aff, 0x595652ff, 0x76428aff, 0xac3232ff, 0xd95763ff, 0xd77bbaff, 0x8f974aff, 0x8a6f30ff])staticfinalread onlyDB32:Array<Int> = [0x000000ff, 0x222034ff, 0x45283cff, 0x663931ff, 0x8f563bff, 0xdf7126ff, 0xd9a066ff, 0xeec39aff, 0xfbf236ff, 0x99e550ff, 0x6abe30ff, 0x37946eff, 0x4b692fff, 0x524b24ff, 0x323c39ff, 0x3f3f74ff, 0x306082ff, 0x5b6ee1ff, 0x639bffff, 0x5fcde4ff, 0xcbdbfcff, 0xffffffff, 0x9badb7ff, 0x847e87ff, 0x696a6aff, 0x595652ff, 0x76428aff, 0xac3232ff, 0xd95763ff, 0xd77bbaff, 0x8f974aff, 0x8a6f30ff]

Default paletter used by Aseprite when a new file is created

Constructor

new(?chunk:PaletteChunk, ?colors:Array<Int>)

Variables

read onlyfirstIndex:Int

read onlylastIndex:Int

Methods

getARGB(index:Int):Int

getRGBA(index:Int):Int

\ No newline at end of file +

Static variables

@:value([0x000000ff, 0x222034ff, 0x45283cff, 0x663931ff, 0x8f563bff, 0xdf7126ff, 0xd9a066ff, 0xeec39aff, 0xfbf236ff, 0x99e550ff, 0x6abe30ff, 0x37946eff, 0x4b692fff, 0x524b24ff, 0x323c39ff, 0x3f3f74ff, 0x306082ff, 0x5b6ee1ff, 0x639bffff, 0x5fcde4ff, 0xcbdbfcff, 0xffffffff, 0x9badb7ff, 0x847e87ff, 0x696a6aff, 0x595652ff, 0x76428aff, 0xac3232ff, 0xd95763ff, 0xd77bbaff, 0x8f974aff, 0x8a6f30ff])staticfinalread onlyDB32:Array<Int> = [0x000000ff, 0x222034ff, 0x45283cff, 0x663931ff, 0x8f563bff, 0xdf7126ff, 0xd9a066ff, 0xeec39aff, 0xfbf236ff, 0x99e550ff, 0x6abe30ff, 0x37946eff, 0x4b692fff, 0x524b24ff, 0x323c39ff, 0x3f3f74ff, 0x306082ff, 0x5b6ee1ff, 0x639bffff, 0x5fcde4ff, 0xcbdbfcff, 0xffffffff, 0x9badb7ff, 0x847e87ff, 0x696a6aff, 0x595652ff, 0x76428aff, 0xac3232ff, 0xd95763ff, 0xd77bbaff, 0x8f974aff, 0x8a6f30ff]

Default palette used by Aseprite when a new file is created

Static methods

staticfromChunk(chunk:PaletteChunk):Palette

Create palette from Palette Chunk (0x2019)

staticfromOldChunk(chunk:OldPaleteChunk):Palette

Create palette from Old Plaette Chunk (0x0004)

staticfromRGBA(rgba:Array<Int>):Palette

Create a palette from an array of RGBA values

Variables

finalentries:Array<PaletteEntry>

read onlyfirstIndex:Int

Deprecated:

No reason to use this. First index will always be 0

read onlylastIndex:Int

Deprecated:

No reason to use this. Last index will alway equal to entries.length - 1

read onlynumColors:Int

Methods

getARGB(index:Int):Int

inlinegetEntry(index:Int):PaletteEntry

Deprecated:

One can just use palette.entries[index] instead

getRGBA(index:Int):Int

toChunk():Chunk

Creates the Old Palette Chunk (0x0004) if there are fewer than 256 colors +in the palette and no alpha channel (all alpha values are 0xff). Otherwise, +creates the Palette Chunk (0x2019).

\ No newline at end of file diff --git a/documentation/ase/PaletteEntry.html b/documentation/ase/PaletteEntry.html new file mode 100644 index 0000000..396aef4 --- /dev/null +++ b/documentation/ase/PaletteEntry.html @@ -0,0 +1,10 @@ + + + +ase.PaletteEntry

Fields

red:Int

green:Int

blue:Int

alpha:Int

\ No newline at end of file diff --git a/documentation/ase/chunks/CelChunk.html b/documentation/ase/chunks/CelChunk.html index 231f2b3..355ce48 100644 --- a/documentation/ase/chunks/CelChunk.html +++ b/documentation/ase/chunks/CelChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):CelChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value(CompressedImage)celType:CelType = CompressedImage

@:value(0)height:Int = 0

@:value(0)layerIndex:Int = 0

@:value(255)opacity:Int = 255

rawData:Bytes

@:value(0)width:Int = 0

@:value(0)xPosition:Int = 0

@:value(0)yPosition:Int = 0

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):CelChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value(CompressedImage)celType:CelType = CompressedImage

@:value(0)height:Int = 0

@:value(0)layerIndex:Int = 0

@:value(255)opacity:Int = 255

rawData:Bytes

@:value(0)width:Int = 0

@:value(0)xPosition:Int = 0

@:value(0)yPosition:Int = 0

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/CelExtraChunk.html b/documentation/ase/chunks/CelExtraChunk.html index b580a09..7ee7aae 100644 --- a/documentation/ase/chunks/CelExtraChunk.html +++ b/documentation/ase/chunks/CelExtraChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):CelExtraChunk

Variables

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):CelExtraChunk

Variables

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/Chunk.html b/documentation/ase/chunks/Chunk.html index 782ad2f..66af63b 100644 --- a/documentation/ase/chunks/Chunk.html +++ b/documentation/ase/chunks/Chunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):Chunk

Variables

Methods

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):Chunk

Variables

Methods

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/ChunkHeader.html b/documentation/ase/chunks/ChunkHeader.html index 33b3488..6b20899 100644 --- a/documentation/ase/chunks/ChunkHeader.html +++ b/documentation/ase/chunks/ChunkHeader.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static variables

@:value(6)staticinlineread onlyBYTE_SIZE:Int = 6

Static methods

staticfromBytes(bytes:Bytes):ChunkHeader

Constructor

new(?type:ChunkType)

Variables

@:value(0)size:Int = 0

Methods

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file +

Static variables

@:value(6)staticinlineread onlyBYTE_SIZE:Int = 6

Static methods

staticfromBytes(bytes:Bytes):ChunkHeader

Constructor

new(?type:ChunkType)

Variables

@:value(0)size:Int = 0

Methods

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file diff --git a/documentation/ase/chunks/ColorProfileChunk.html b/documentation/ase/chunks/ColorProfileChunk.html index 8cab1f9..8936389 100644 --- a/documentation/ase/chunks/ColorProfileChunk.html +++ b/documentation/ase/chunks/ColorProfileChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):ColorProfileChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value(0)flags:Int = 0

@:value(0)gamma:Float = 0

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):ColorProfileChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value(0)flags:Int = 0

@:value(0)gamma:Float = 0

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/ExternalFilesChunk.html b/documentation/ase/chunks/ExternalFilesChunk.html index ae82f6b..dcd78c7 100644 --- a/documentation/ase/chunks/ExternalFilesChunk.html +++ b/documentation/ase/chunks/ExternalFilesChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):ExternalFilesChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value([])entries:Array<{id:Int, fileName:String}> = []

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):ExternalFilesChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value([])entries:Array<{id:Int, fileName:String}> = []

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/LayerBlendMode.html b/documentation/ase/chunks/LayerBlendMode.html index b0e85f9..d872236 100644 --- a/documentation/ase/chunks/LayerBlendMode.html +++ b/documentation/ase/chunks/LayerBlendMode.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Variables

@:value(cast 16)@:impl@:enuminlineread onlyAddition:LayerBlendMode = 16

@:value(cast 14)@:impl@:enuminlineread onlyColor:LayerBlendMode = 14

@:value(cast 7)@:impl@:enuminlineread onlyColorBurn:LayerBlendMode = 7

@:value(cast 6)@:impl@:enuminlineread onlyColorDodge:LayerBlendMode = 6

@:value(cast 4)@:impl@:enuminlineread onlyDarken:LayerBlendMode = 4

@:value(cast 10)@:impl@:enuminlineread onlyDifference:LayerBlendMode = 10

@:value(cast 18)@:impl@:enuminlineread onlyDivide:LayerBlendMode = 18

@:value(cast 11)@:impl@:enuminlineread onlyExclusion:LayerBlendMode = 11

@:value(cast 8)@:impl@:enuminlineread onlyHardLight:LayerBlendMode = 8

@:value(cast 12)@:impl@:enuminlineread onlyHue:LayerBlendMode = 12

@:value(cast 5)@:impl@:enuminlineread onlyLighten:LayerBlendMode = 5

@:value(cast 15)@:impl@:enuminlineread onlyLuminosity:LayerBlendMode = 15

@:value(cast 1)@:impl@:enuminlineread onlyMultiply:LayerBlendMode = 1

@:value(cast 0)@:impl@:enuminlineread onlyNormal:LayerBlendMode = 0

@:value(cast 3)@:impl@:enuminlineread onlyOverlay:LayerBlendMode = 3

@:value(cast 13)@:impl@:enuminlineread onlySaturation:LayerBlendMode = 13

@:value(cast 2)@:impl@:enuminlineread onlyScreen:LayerBlendMode = 2

@:value(cast 9)@:impl@:enuminlineread onlySoftLight:LayerBlendMode = 9

@:value(cast 17)@:impl@:enuminlineread onlySubtract:LayerBlendMode = 17

\ No newline at end of file +

Variables

@:value(cast 16)@:impl@:enuminlineread onlyAddition:LayerBlendMode = 16

@:value(cast 14)@:impl@:enuminlineread onlyColor:LayerBlendMode = 14

@:value(cast 7)@:impl@:enuminlineread onlyColorBurn:LayerBlendMode = 7

@:value(cast 6)@:impl@:enuminlineread onlyColorDodge:LayerBlendMode = 6

@:value(cast 4)@:impl@:enuminlineread onlyDarken:LayerBlendMode = 4

@:value(cast 10)@:impl@:enuminlineread onlyDifference:LayerBlendMode = 10

@:value(cast 18)@:impl@:enuminlineread onlyDivide:LayerBlendMode = 18

@:value(cast 11)@:impl@:enuminlineread onlyExclusion:LayerBlendMode = 11

@:value(cast 8)@:impl@:enuminlineread onlyHardLight:LayerBlendMode = 8

@:value(cast 12)@:impl@:enuminlineread onlyHue:LayerBlendMode = 12

@:value(cast 5)@:impl@:enuminlineread onlyLighten:LayerBlendMode = 5

@:value(cast 15)@:impl@:enuminlineread onlyLuminosity:LayerBlendMode = 15

@:value(cast 1)@:impl@:enuminlineread onlyMultiply:LayerBlendMode = 1

@:value(cast 0)@:impl@:enuminlineread onlyNormal:LayerBlendMode = 0

@:value(cast 3)@:impl@:enuminlineread onlyOverlay:LayerBlendMode = 3

@:value(cast 13)@:impl@:enuminlineread onlySaturation:LayerBlendMode = 13

@:value(cast 2)@:impl@:enuminlineread onlyScreen:LayerBlendMode = 2

@:value(cast 9)@:impl@:enuminlineread onlySoftLight:LayerBlendMode = 9

@:value(cast 17)@:impl@:enuminlineread onlySubtract:LayerBlendMode = 17

\ No newline at end of file diff --git a/documentation/ase/chunks/LayerChunk.html b/documentation/ase/chunks/LayerChunk.html index 846d65e..f307be8 100644 --- a/documentation/ase/chunks/LayerChunk.html +++ b/documentation/ase/chunks/LayerChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):LayerChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value(Normal)blendMode:LayerBlendMode = Normal

@:value(0)childLevel:Int = 0

@:value(0)defaultHeight:Int = 0

@:value(0)defaultWidth:Int = 0

@:value(Visible | Editable)flags:LayerFlags = Visible | Editable

@:value(Normal)layerType:LayerType = Normal

@:value("New Layer")name:String = "New Layer"

@:value(255)opacity:Int = 255

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):LayerChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value(Normal)blendMode:LayerBlendMode = Normal

@:value(0)childLevel:Int = 0

@:value(0)defaultHeight:Int = 0

@:value(0)defaultWidth:Int = 0

@:value(Visible | Editable)flags:LayerFlags = Visible | Editable

@:value(Normal)layerType:LayerType = Normal

@:value("New Layer")name:String = "New Layer"

@:value(255)opacity:Int = 255

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/LayerFlags.html b/documentation/ase/chunks/LayerFlags.html index 585025e..4c225e8 100644 --- a/documentation/ase/chunks/LayerFlags.html +++ b/documentation/ase/chunks/LayerFlags.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Variables

@:value(cast 8)@:impl@:enuminlineread onlyBackground:LayerFlags = 8

@:value(cast 32)@:impl@:enuminlineread onlyCollapsed:LayerFlags = 32

@:value(cast 2)@:impl@:enuminlineread onlyEditable:LayerFlags = 2

@:value(cast 4)@:impl@:enuminlineread onlyLockMovement:LayerFlags = 4

@:value(cast 16)@:impl@:enuminlineread onlyPreferLinkedCels:LayerFlags = 16

@:value(cast 64)@:impl@:enuminlineread onlyReference:LayerFlags = 64

@:value(cast 1)@:impl@:enuminlineread onlyVisible:LayerFlags = 1

\ No newline at end of file +

Variables

@:value(cast 8)@:impl@:enuminlineread onlyBackground:LayerFlags = 8

@:value(cast 32)@:impl@:enuminlineread onlyCollapsed:LayerFlags = 32

@:value(cast 2)@:impl@:enuminlineread onlyEditable:LayerFlags = 2

@:value(cast 4)@:impl@:enuminlineread onlyLockMovement:LayerFlags = 4

@:value(cast 16)@:impl@:enuminlineread onlyPreferLinkedCels:LayerFlags = 16

@:value(cast 64)@:impl@:enuminlineread onlyReference:LayerFlags = 64

@:value(cast 1)@:impl@:enuminlineread onlyVisible:LayerFlags = 1

\ No newline at end of file diff --git a/documentation/ase/chunks/LayerType.html b/documentation/ase/chunks/LayerType.html index fb84a6d..adffe8b 100644 --- a/documentation/ase/chunks/LayerType.html +++ b/documentation/ase/chunks/LayerType.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Variables

@:value(cast 1)@:impl@:enuminlineread onlyGroup:LayerType = 1

@:value(cast 0)@:impl@:enuminlineread onlyNormal:LayerType = 0

@:value(cast 2)@:impl@:enuminlineread onlyTilemap:LayerType = 2

\ No newline at end of file +

Variables

@:value(cast 1)@:impl@:enuminlineread onlyGroup:LayerType = 1

@:value(cast 0)@:impl@:enuminlineread onlyNormal:LayerType = 0

@:value(cast 2)@:impl@:enuminlineread onlyTilemap:LayerType = 2

\ No newline at end of file diff --git a/documentation/ase/chunks/MaskChunk.html b/documentation/ase/chunks/MaskChunk.html index 1f8897e..068fab7 100644 --- a/documentation/ase/chunks/MaskChunk.html +++ b/documentation/ase/chunks/MaskChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):MaskChunk

Variables

Inherited Variables

Inherited Methods

Defined by Chunk

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):MaskChunk

Variables

Inherited Variables

Inherited Methods

Defined by Chunk

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/OldPaleteChunk.html b/documentation/ase/chunks/OldPaleteChunk.html index 0849d77..925fbb3 100644 --- a/documentation/ase/chunks/OldPaleteChunk.html +++ b/documentation/ase/chunks/OldPaleteChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):OldPaleteChunk

Variables

@:value([])packets:Array<Packet> = []

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

Variables

@:value([])packets:Array<Packet> = []

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file diff --git a/documentation/ase/chunks/Packet.html b/documentation/ase/chunks/Packet.html index 9df31d3..7f4da55 100644 --- a/documentation/ase/chunks/Packet.html +++ b/documentation/ase/chunks/Packet.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Fields

colors:Array<{red:Int, green:Int, blue:Int}>

\ No newline at end of file +

Fields

colors:Array<{red:Int, green:Int, blue:Int}>

\ No newline at end of file diff --git a/documentation/ase/chunks/PaletteChunk.html b/documentation/ase/chunks/PaletteChunk.html index e6f8c92..c3e10ff 100644 --- a/documentation/ase/chunks/PaletteChunk.html +++ b/documentation/ase/chunks/PaletteChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):PaletteChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value([])entries:Map<Int, PaletteEntry> = []

@:value(0)firstColorIndex:Int = 0

@:value(-1)lastColorIndex:Int = -1

@:value(0)paletteSize:Int = 0

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):PaletteChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

@:value([])entries:Map<Int, PaletteChunkEntry> = []

@:value(0)firstColorIndex:Int = 0

@:value(-1)lastColorIndex:Int = -1

@:value(0)paletteSize:Int = 0

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file diff --git a/documentation/ase/chunks/PaletteChunkEntry.html b/documentation/ase/chunks/PaletteChunkEntry.html new file mode 100644 index 0000000..2d37dc0 --- /dev/null +++ b/documentation/ase/chunks/PaletteChunkEntry.html @@ -0,0 +1,10 @@ + + + +ase.chunks.PaletteChunkEntry

Static variables

@:value(6)staticinlineread onlySIZE:Int = 6

Static methods

staticfromBytes(bytes:Bytes):PaletteChunkEntry

Constructor

new(?name:String, ?color:Int)

Variables

alpha:Int

blue:Int

@:value(0)flags:Int = 0

green:Int

hasName:Bool

name:String

red:Int

Methods

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/PaletteEntry.html b/documentation/ase/chunks/PaletteEntry.html deleted file mode 100644 index 0727f90..0000000 --- a/documentation/ase/chunks/PaletteEntry.html +++ /dev/null @@ -1,10 +0,0 @@ - - - -ase.chunks.PaletteEntry

Static variables

@:value(6)staticinlineread onlySIZE:Int = 6

Static methods

staticfromBytes(bytes:Bytes):PaletteEntry

Constructor

new(?name:String, ?color:Int)

Variables

alpha:Int

blue:Int

@:value(0)flags:Int = 0

green:Int

hasName:Bool

name:String

red:Int

Methods

toBytes(?out:BytesOutput):Bytes

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/SliceChunk.html b/documentation/ase/chunks/SliceChunk.html index 91765ea..b4c4262 100644 --- a/documentation/ase/chunks/SliceChunk.html +++ b/documentation/ase/chunks/SliceChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):SliceChunk

Variables

flags:Int32

name:String

@:value([])sliceKeys:Array<SliceKey> = []

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):SliceChunk

Variables

flags:Int32

name:String

@:value([])sliceKeys:Array<SliceKey> = []

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/SliceKey.html b/documentation/ase/chunks/SliceKey.html index 55b19f9..888b6b6 100644 --- a/documentation/ase/chunks/SliceKey.html +++ b/documentation/ase/chunks/SliceKey.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Constructor

new()

Variables

height:Int32

width:Int32

xCenter:Int32

xOrigin:Int32

xPivot:Int32

yCenter:Int32

yOrigin:Int32

yPivot:Int32

\ No newline at end of file +

Constructor

new()

Variables

height:Int32

width:Int32

xCenter:Int32

xOrigin:Int32

xPivot:Int32

yCenter:Int32

yOrigin:Int32

yPivot:Int32

\ No newline at end of file diff --git a/documentation/ase/chunks/Tag.html b/documentation/ase/chunks/Tag.html index 1d1e6e1..5c4eb99 100644 --- a/documentation/ase/chunks/Tag.html +++ b/documentation/ase/chunks/Tag.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -
\ No newline at end of file +
\ No newline at end of file diff --git a/documentation/ase/chunks/TagsChunk.html b/documentation/ase/chunks/TagsChunk.html index 97b280b..1353ec3 100644 --- a/documentation/ase/chunks/TagsChunk.html +++ b/documentation/ase/chunks/TagsChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):TagsChunk

Variables

@:value([])tags:Array<Tag> = []

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):TagsChunk

Variables

@:value([])tags:Array<Tag> = []

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/TilesetChunk.html b/documentation/ase/chunks/TilesetChunk.html index f696f9c..18246af 100644 --- a/documentation/ase/chunks/TilesetChunk.html +++ b/documentation/ase/chunks/TilesetChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):TilesetChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):TilesetChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/UserDataChunk.html b/documentation/ase/chunks/UserDataChunk.html index e20fa5f..c4c9efc 100644 --- a/documentation/ase/chunks/UserDataChunk.html +++ b/documentation/ase/chunks/UserDataChunk.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Static methods

staticfromBytes(bytes:Bytes):UserDataChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

alpha:Int

blue:Int

flags:Int

green:Int

hasText:Bool

red:Int

text:String

Methods

Inherited Variables

Inherited Methods

\ No newline at end of file +

Static methods

staticfromBytes(bytes:Bytes):UserDataChunk

Constructor

@:value({ createHeader : false })new(createHeader:Bool = false)

Variables

alpha:Int

blue:Int

flags:Int

green:Int

hasText:Bool

red:Int

text:String

Methods

Inherited Variables

Inherited Methods

Defined by Chunk

toString():String

\ No newline at end of file diff --git a/documentation/ase/chunks/index.html b/documentation/ase/chunks/index.html index 7ff7bf1..57e5115 100644 --- a/documentation/ase/chunks/index.html +++ b/documentation/ase/chunks/index.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -
\ No newline at end of file +
\ No newline at end of file diff --git a/documentation/ase/index.html b/documentation/ase/index.html index c6ecc60..c8d6ee1 100644 --- a/documentation/ase/index.html +++ b/documentation/ase/index.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

ase

..
chunks
types
Ase

Aseprite file format reader/writer

AseHeader

Cel

Frame

FrameHeader

Layer

Palette

\ No newline at end of file +
\ No newline at end of file diff --git a/documentation/ase/types/CelType.html b/documentation/ase/types/CelType.html index 881cd93..04c1f0a 100644 --- a/documentation/ase/types/CelType.html +++ b/documentation/ase/types/CelType.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Variables

@:value(cast 2)@:impl@:enuminlineread onlyCompressedImage:CelType = 2

@:value(cast 3)@:impl@:enuminlineread onlyCompressedTilemap:CelType = 3

@:value(cast 1)@:impl@:enuminlineread onlyLinked:CelType = 1

@:value(cast 0)@:impl@:enuminlineread onlyRaw:CelType = 0

\ No newline at end of file +

Variables

@:value(cast 2)@:impl@:enuminlineread onlyCompressedImage:CelType = 2

@:value(cast 3)@:impl@:enuminlineread onlyCompressedTilemap:CelType = 3

@:value(cast 1)@:impl@:enuminlineread onlyLinked:CelType = 1

@:value(cast 0)@:impl@:enuminlineread onlyRaw:CelType = 0

\ No newline at end of file diff --git a/documentation/ase/types/ChunkType.html b/documentation/ase/types/ChunkType.html index 8a58645..e29b017 100644 --- a/documentation/ase/types/ChunkType.html +++ b/documentation/ase/types/ChunkType.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Variables

@:value(cast 0x2005)@:impl@:enuminlineread onlyCEL:ChunkType = 0x2005

@:value(cast 0x2006)@:impl@:enuminlineread onlyCEL_EXTRA:ChunkType = 0x2006

@:value(cast 0x2007)@:impl@:enuminlineread onlyCOLOR_PROFILE:ChunkType = 0x2007

@:value(cast 0x2008)@:impl@:enuminlineread onlyEXTERNAL_FILES:ChunkType = 0x2008

@:value(cast 0x2004)@:impl@:enuminlineread onlyLAYER:ChunkType = 0x2004

@:value(cast 0x2016)@:impl@:enuminlineread onlyMASK:ChunkType = 0x2016

@:value(cast 0x0004)@:impl@:enuminlineread onlyOLD_PALETTE_04:ChunkType = 0x0004

@:value(cast 0x0011)@:impl@:enuminlineread onlyOLD_PALETTE_11:ChunkType = 0x0011

@:value(cast 0x2019)@:impl@:enuminlineread onlyPALETTE:ChunkType = 0x2019

@:value(cast 0x2017)@:impl@:enuminlineread onlyPATH:ChunkType = 0x2017

@:value(cast 0x2022)@:impl@:enuminlineread onlySLICE:ChunkType = 0x2022

@:value(cast 0x2018)@:impl@:enuminlineread onlyTAGS:ChunkType = 0x2018

@:value(cast 0x2023)@:impl@:enuminlineread onlyTILESET:ChunkType = 0x2023

@:value(cast 0x2020)@:impl@:enuminlineread onlyUSER_DATA:ChunkType = 0x2020

\ No newline at end of file +

Variables

@:value(cast 0x2005)@:impl@:enuminlineread onlyCEL:ChunkType = 0x2005

@:value(cast 0x2006)@:impl@:enuminlineread onlyCEL_EXTRA:ChunkType = 0x2006

@:value(cast 0x2007)@:impl@:enuminlineread onlyCOLOR_PROFILE:ChunkType = 0x2007

@:value(cast 0x2008)@:impl@:enuminlineread onlyEXTERNAL_FILES:ChunkType = 0x2008

@:value(cast 0x2004)@:impl@:enuminlineread onlyLAYER:ChunkType = 0x2004

@:value(cast 0x2016)@:impl@:enuminlineread onlyMASK:ChunkType = 0x2016

@:value(cast 0x0004)@:impl@:enuminlineread onlyOLD_PALETTE_04:ChunkType = 0x0004

@:value(cast 0x0011)@:impl@:enuminlineread onlyOLD_PALETTE_11:ChunkType = 0x0011

@:value(cast 0x2019)@:impl@:enuminlineread onlyPALETTE:ChunkType = 0x2019

@:value(cast 0x2017)@:impl@:enuminlineread onlyPATH:ChunkType = 0x2017

@:value(cast 0x2022)@:impl@:enuminlineread onlySLICE:ChunkType = 0x2022

@:value(cast 0x2018)@:impl@:enuminlineread onlyTAGS:ChunkType = 0x2018

@:value(cast 0x2023)@:impl@:enuminlineread onlyTILESET:ChunkType = 0x2023

@:value(cast 0x2020)@:impl@:enuminlineread onlyUSER_DATA:ChunkType = 0x2020

\ No newline at end of file diff --git a/documentation/ase/types/ColorDepth.html b/documentation/ase/types/ColorDepth.html index 6bcedd4..4474db1 100644 --- a/documentation/ase/types/ColorDepth.html +++ b/documentation/ase/types/ColorDepth.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Variables

@:value(cast 16)@:impl@:enuminlineread onlyBPP16:ColorDepth = 16

@:value(cast 32)@:impl@:enuminlineread onlyBPP32:ColorDepth = 32

@:value(cast 8)@:impl@:enuminlineread onlyBPP8:ColorDepth = 8

@:value(cast 8)@:impl@:enuminlineread onlyINDEXED:ColorDepth = 8

\ No newline at end of file +

Variables

@:value(cast 16)@:impl@:enuminlineread onlyBPP16:ColorDepth = 16

@:value(cast 32)@:impl@:enuminlineread onlyBPP32:ColorDepth = 32

@:value(cast 8)@:impl@:enuminlineread onlyBPP8:ColorDepth = 8

@:value(cast 8)@:impl@:enuminlineread onlyINDEXED:ColorDepth = 8

\ No newline at end of file diff --git a/documentation/ase/types/ColorProfileType.html b/documentation/ase/types/ColorProfileType.html index 69f6c89..dc071df 100644 --- a/documentation/ase/types/ColorProfileType.html +++ b/documentation/ase/types/ColorProfileType.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Variables

@:value(cast 2)@:impl@:enuminlineread onlyEmbeddedICC:ColorProfileType = 2

@:value(cast 0)@:impl@:enuminlineread onlyNoColorProfile:ColorProfileType = 0

@:value(cast 1)@:impl@:enuminlineread onlySRgb:ColorProfileType = 1

\ No newline at end of file +

Variables

@:value(cast 2)@:impl@:enuminlineread onlyEmbeddedICC:ColorProfileType = 2

@:value(cast 0)@:impl@:enuminlineread onlyNoColorProfile:ColorProfileType = 0

@:value(cast 1)@:impl@:enuminlineread onlySRgb:ColorProfileType = 1

\ No newline at end of file diff --git a/documentation/ase/types/Serializable.html b/documentation/ase/types/Serializable.html index 5657592..f0126db 100644 --- a/documentation/ase/types/Serializable.html +++ b/documentation/ase/types/Serializable.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

Methods

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file +

Methods

toBytes(?out:BytesOutput):Bytes

\ No newline at end of file diff --git a/documentation/ase/types/index.html b/documentation/ase/types/index.html index 5232f76..f0c9cf3 100644 --- a/documentation/ase/types/index.html +++ b/documentation/ase/types/index.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -
\ No newline at end of file +
\ No newline at end of file diff --git a/documentation/index.html b/documentation/index.html index 4c63fe7..ab9a4b4 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -7,4 +7,4 @@ float: none; text-shadow: 0 0 0 transparent; } -

top level

ase
\ No newline at end of file +

top level

ase
\ No newline at end of file diff --git a/documentation/nav.js b/documentation/nav.js index 3036f23..9602982 100644 --- a/documentation/nav.js +++ b/documentation/nav.js @@ -1 +1 @@ -var navContent=''; \ No newline at end of file +var navContent=''; \ No newline at end of file diff --git a/haxelib.json b/haxelib.json index 34f2c4f..28baed7 100644 --- a/haxelib.json +++ b/haxelib.json @@ -10,12 +10,11 @@ "gamedev" ], "description": "Aseprite file format reader/writer", - "version": "2.0.4", + "version": "2.1.0", "classPath": "src", - "releasenote": "Compatibility with the latest Aseprite format", + "releasenote": "Adjustments for the way Aseprite 1.3.5 handles palettes", "contributors": [ - "miriti", - "AustinEast" + "miriti" ], "dependencies": {} -} +} \ No newline at end of file diff --git a/src/ase/Ase.hx b/src/ase/Ase.hx index 5fedac6..6b61e99 100644 --- a/src/ase/Ase.hx +++ b/src/ase/Ase.hx @@ -2,7 +2,6 @@ package ase; import ase.chunks.ColorProfileChunk; import ase.chunks.LayerChunk; -import ase.chunks.PaletteChunk; import ase.types.ChunkType; import ase.types.ColorDepth; import ase.types.Serializable; @@ -87,11 +86,7 @@ using Lambda; ase.width = width; ase.height = height; ase.createFirstFrame(); - - if (colorDepth == INDEXED || initialPalette != null) { - ase.initPalette(initialPalette != null ? initialPalette : Palette.DB32); - } - + ase.initPalette(initialPalette != null ? initialPalette : Palette.DB32); return ase; } @@ -112,10 +107,30 @@ using Lambda; ase.frames.push(frame); } - var untypedChunks = ase.frames[0].chunkTypes[ChunkType.PALETTE]; - final paletteChunk:PaletteChunk = untypedChunks!=null && untypedChunks.length>0 ? (cast untypedChunks)[0] : null; - - ase.palette = new Palette(paletteChunk); + /** + https://github.com/aseprite/aseprite/blob/10dda30a15a58d09e561a59594f348b4db3a4405/docs/ase-file-specs.md#old-palette-chunk-0x0004 + + Aseprite v1.1 saves both chunks (0x0004 and 0x2019) just for backward compatibility. + Aseprite v1.3.5 writes this chunk if the palette doesn't have alpha channel and + contains 256 colors or less (because this chunk is smaller), in other case the new + palette chunk (0x2019) will be used (and the old one is not saved anymore). + **/ + + final paletteChunks = ase.firstFrame.chunkTypes.get(ChunkType.PALETTE); + + // If "new" palette chunk found - use it + if (paletteChunks != null && paletteChunks.length > 0) { + ase.palette = Palette.fromChunk(cast paletteChunks[0]); + } else { + final oldPaletteChunks = ase.firstFrame.chunkTypes.get(ChunkType.OLD_PALETTE_04); + // If old palette chunk found - use it instead + if (oldPaletteChunks != null && oldPaletteChunks.length > 0) { + ase.palette = Palette.fromOldChunk(cast oldPaletteChunks[0]); + } else { + // Can't parse otherwise + throw "Failed to parse: missing palette chunk"; + } + } ase.createLayers(); @@ -137,7 +152,12 @@ using Lambda; Create layers after ase chunks are loaded */ function createLayers() { - for (chunk in firstFrame.chunkTypes[ChunkType.LAYER]) { + final layerChunks = firstFrame.chunkTypes[ChunkType.LAYER]; + + if (layerChunks == null) + return; // No layer chunks + + for (chunk in layerChunks) { final layerChunk:LayerChunk = cast chunk; layers.push(new Layer(layerChunk)); @@ -150,8 +170,7 @@ using Lambda; @param colors Array of RGBA color values for the new pallet */ public function initPalette(colors:Array) { - palette = new Palette(colors); - frames[0].addChunk(palette.chunk); + palette = Palette.fromRGBA(colors); } /** @@ -202,9 +221,22 @@ using Lambda; return this; } + /** + Converts Aseprite data to binary data that can be stored to a file + **/ public function toBytes(?out:BytesOutput):Bytes { + // Remove existing palette chunks to replace them with the new chunk generated by the Palette + firstFrame.chunks = firstFrame.chunks.filter(chunk -> + [ChunkType.OLD_PALETTE_04, ChunkType.PALETTE].indexOf(chunk.header.type) == -1); + firstFrame.chunkTypes.remove(ChunkType.OLD_PALETTE_04); + firstFrame.chunkTypes.remove(ChunkType.PALETTE); + + final paletteChunk = palette.toChunk(); + firstFrame.addChunk(paletteChunk); + header.fileSize = fileSize; header.frames = frames.length; + header.colorsNumber = palette.numColors; var bo = out != null ? out : new BytesOutput(); @@ -217,6 +249,18 @@ using Lambda; return bo.getBytes(); } + public function toString():String { + final strings:Array = []; + for (n => frame in frames) { + strings.push('Frame #$n'); + + for (chunk in frame.chunks) { + strings.push(chunk.toString()); + } + } + return strings.join('\n'); + } + public static function main() {} private function new() {} diff --git a/src/ase/Cel.hx b/src/ase/Cel.hx index ba57b5d..59084e7 100644 --- a/src/ase/Cel.hx +++ b/src/ase/Cel.hx @@ -137,7 +137,7 @@ class Cel { @param color ARGB color for 32bpp mode, GGGG color for 16bpp mode and index or GG color for Indexed or 8bpp mode */ public function setPixel(px:Int, py:Int, color:Int) { - if (px > 0 && px < width && py > 0 && py < height) { + if (px >= 0 && px < width && py >= 0 && py < height) { var p = (width * py + px) * (frame.ase.colorDepth / 8).int(); switch (frame.ase.colorDepth) { case BPP32: diff --git a/src/ase/Palette.hx b/src/ase/Palette.hx index 0f7f3cc..b213a9d 100644 --- a/src/ase/Palette.hx +++ b/src/ase/Palette.hx @@ -1,10 +1,21 @@ package ase; +import ase.chunks.Chunk; +import ase.chunks.OldPaleteChunk; import ase.chunks.PaletteChunk; +using Lambda; + +typedef PaletteEntry = { + red:Int, + green:Int, + blue:Int, + alpha:Int +}; + class Palette { /** - Default paletter used by Aseprite when a new file is created + Default palette used by Aseprite when a new file is created */ public static final DB32 = [ 0x000000ff, 0x222034ff, 0x45283cff, 0x663931ff, 0x8f563bff, 0xdf7126ff, @@ -15,47 +26,112 @@ class Palette { 0x8f974aff, 0x8a6f30ff ]; - public var chunk:PaletteChunk; + public final entries:Array; + + public var numColors(get, never):Int; + function get_numColors() { + return entries.length; + } + + /** @deprecated No reason to use this. First index will always be `0` **/ public var firstIndex(get, never):Int; function get_firstIndex():Int { - return chunk.firstColorIndex; + return 0; } + /** @deprecated No reason to use this. Last index will alway equal to `entries.length - 1` **/ public var lastIndex(get, never):Int; function get_lastIndex():Int { - return chunk.lastColorIndex; + return entries.length - 1; } - public function getEntry(index:Int):PaletteEntry { - return chunk.entries[index]; + /** @deprecated One can just use `palette.entries[index]` instead **/ + inline public function getEntry(index:Int):PaletteEntry { + return entries[index]; } public function getRGBA(index:Int) { - var entry = getEntry(index); + var entry = entries[index]; return ((entry.red & 0xFF) << 24) | ((entry.green & 0xFF) << 16) | ((entry.blue & 0xFF) << 8) | (entry.alpha & 0xFF); } public function getARGB(index:Int) { - var entry = getEntry(index); + var entry = entries[index]; return ((entry.alpha & 0xFF) << 24) | ((entry.red & 0xFF) << 16) | ((entry.green & 0xFF) << 8) | (entry.blue & 0xFF); } - public function new(?chunk:PaletteChunk, ?colors:Array) { - if (chunk != null) - this.chunk = chunk; - else { - this.chunk = new PaletteChunk(true); + public static function createDefault() { + return fromRGBA(DB32); + } + + /** + Create a palette from an array of RGBA values + **/ + public static function fromRGBA(rgba:Array) { + return new Palette(rgba.map((value) -> ({ + red: (value >> 24) & 0xff, + green: (value >> 16) & 0xff, + blue: (value >> 8) & 0xff, + alpha: value & 0xff + }))); + } + + /** + Create palette from Palette Chunk (0x2019) + **/ + public static function fromChunk(chunk:PaletteChunk) { + return new Palette(chunk.entries.map((item) -> { + return { + red: item.red, + green: item.green, + blue: item.blue, + alpha: item.alpha + } + })); + } + + /** + Create palette from Old Plaette Chunk (0x0004) + **/ + public static function fromOldChunk(chunk:OldPaleteChunk) { + final entries:Array = []; - if (colors != null) { - for (color in colors) { - this.chunk.addEntry(new PaletteEntry(color)); - } + for (packet in chunk.packets) { + for (color in packet.colors) { + entries.push({ + red: color.red, + green: color.green, + blue: color.blue, + alpha: 0xff + }); } } + + return new Palette(entries); + } + + /** + Creates the Old Palette Chunk (0x0004) if there are fewer than 256 colors + in the palette and no alpha channel (all alpha values are 0xff). Otherwise, + creates the Palette Chunk (0x2019). + */ + public function toChunk():Chunk { + final useOld = entries.length <= 256 + && entries.filter(e -> e.alpha != 0xff).length == 0; + + if (useOld) { + return OldPaleteChunk.fromPaletteEntries(entries); + } else { + return PaletteChunk.fromPaletteEntries(entries); + } + } + + private function new(entries:Array) { + this.entries = entries; } } diff --git a/src/ase/chunks/Chunk.hx b/src/ase/chunks/Chunk.hx index 00fbdc5..6b8b852 100644 --- a/src/ase/chunks/Chunk.hx +++ b/src/ase/chunks/Chunk.hx @@ -1,11 +1,12 @@ package ase.chunks; -import ase.types.Serializable; import ase.types.ChunkType; +import ase.types.Serializable; import haxe.io.Bytes; import haxe.io.BytesInput; import haxe.io.BytesOutput; +using StringTools; using Type; class Chunk implements Serializable { @@ -19,7 +20,7 @@ class Chunk implements Serializable { } function getSizeWithoutHeader():Int { - throw '${Type.getClassName(Type.getClass(this))}.getSizeWithoutHeader() is not implemented'; + throw '${this.getClass().getClassName()}.getSizeWithoutHeader() is not implemented'; } public static function fromBytes(bytes:Bytes):Chunk { @@ -73,6 +74,11 @@ class Chunk implements Serializable { throw '${this.getClass().getClassName().split('.').pop()}.toBytes() is not implemented'; } + public function toString():String { + return + '0x${this.header.type.hex(4)}: ${this.getClass().getClassName().split('.').pop()}'; + } + private function new(?createHeader:Bool = false, ?type:ChunkType) { if (createHeader) { header = new ChunkHeader(type); diff --git a/src/ase/chunks/OldPaleteChunk.hx b/src/ase/chunks/OldPaleteChunk.hx index 53b4dfa..7bbbbbf 100644 --- a/src/ase/chunks/OldPaleteChunk.hx +++ b/src/ase/chunks/OldPaleteChunk.hx @@ -1,5 +1,6 @@ package ase.chunks; +import ase.Palette.PaletteEntry; import haxe.io.Bytes; import haxe.io.BytesInput; import haxe.io.BytesOutput; @@ -18,11 +19,11 @@ class OldPaleteChunk extends Chunk { override function getSizeWithoutHeader():Int { return 2 // numPackets - + packets.map(packet -> { - return 1 // skipEntries - + 1 // numColors - + (packet.colors.length * 3); - }).fold((packetSize:Int, result:Int) -> packetSize + result, 0); + + packets.map(packet -> 1 // skipEntries + + 1 // numColors + + (packet.colors.length * 3)).fold((packetSize:Int, + result:Int) -> packetSize + + result, 0); } public static function fromBytes(bytes:Bytes):OldPaleteChunk { @@ -73,6 +74,30 @@ class OldPaleteChunk extends Chunk { return bo.getBytes(); } + public static function fromPaletteEntries(entries:Array) { + final chunk = new OldPaleteChunk(true); + chunk.numPackets = 1; + chunk.packets = [ + { + skipEntries: 0, + // Save at most 256 colors + numColors: Std.int(Math.min(entries.length, 256)), + colors: entries.slice(0, 256).map(e -> ({ + red: e.red, + green: e.green, + blue: e.blue + })) + } + ]; + return chunk; + } + + override function toString():String { + return super.toString() + + + ' { numPackets: ${numPackets}, packets: [${packets.map(p -> '{ skipEntries: ${p.skipEntries}, numColors: ${p.numColors} }').join(', ')}] }'; + } + private function new(?createHeader:Bool = false) { super(createHeader, OLD_PALETTE_04); } diff --git a/src/ase/chunks/PaletteChunk.hx b/src/ase/chunks/PaletteChunk.hx index 29af3b3..334e21c 100644 --- a/src/ase/chunks/PaletteChunk.hx +++ b/src/ase/chunks/PaletteChunk.hx @@ -1,12 +1,13 @@ package ase.chunks; +import ase.Palette.PaletteEntry; import haxe.io.Bytes; import haxe.io.BytesInput; import haxe.io.BytesOutput; using Lambda; -class PaletteEntry { +class PaletteChunkEntry { public static inline var SIZE:Int = 6; public var flags:Int = 0; @@ -27,8 +28,8 @@ class PaletteEntry { return val; } - public static function fromBytes(bytes:Bytes):PaletteEntry { - var entry = new PaletteEntry(); + public static function fromBytes(bytes:Bytes):PaletteChunkEntry { + var entry = new PaletteChunkEntry(); var bi:BytesInput = new BytesInput(bytes); entry.flags = bi.readUInt16(); @@ -63,7 +64,7 @@ class PaletteEntry { } public function toString() { - return 'R: $red G: $green B: $blue A: $alpha'; + return '(R: $red G: $green B: $blue A: $alpha)'; } public function new(?name:String, ?color:Int) { @@ -85,17 +86,17 @@ class PaletteChunk extends Chunk { public var paletteSize:Int = 0; public var firstColorIndex:Int = 0; public var lastColorIndex:Int = -1; - public var entries:Map = []; + public var entries:Map = []; override function getSizeWithoutHeader():Int { return 4 // palette size + 4 // firstColorIndex + 4 // lastColorIndex + 8 // reserved - + PaletteEntry.SIZE * (lastColorIndex - firstColorIndex + 1); + + PaletteChunkEntry.SIZE * (lastColorIndex - firstColorIndex + 1); } - public function addEntry(entry:PaletteEntry) { + public function addEntry(entry:PaletteChunkEntry) { lastColorIndex++; entries[lastColorIndex] = entry; paletteSize++; @@ -113,9 +114,9 @@ class PaletteChunk extends Chunk { var entryStart:Int = bi.position; for (entryNum in chunk.firstColorIndex...chunk.lastColorIndex + 1) { - var entry = PaletteEntry.fromBytes(bi.read(PaletteEntry.SIZE)); + var entry = PaletteChunkEntry.fromBytes(bi.read(PaletteChunkEntry.SIZE)); chunk.entries[entryNum] = entry; - entryStart += PaletteEntry.SIZE; + entryStart += PaletteChunkEntry.SIZE; } return chunk; @@ -129,6 +130,7 @@ class PaletteChunk extends Chunk { bo.writeInt32(paletteSize); bo.writeInt32(firstColorIndex); bo.writeInt32(lastColorIndex); + for (_ in 0...8) bo.writeByte(0); @@ -139,6 +141,25 @@ class PaletteChunk extends Chunk { return bo.getBytes(); } + public static function fromPaletteEntries(entries:Array) { + final chunk = new PaletteChunk(true); + + for (entry in entries) { + final chunkEntry = new PaletteChunkEntry(); + chunkEntry.red = entry.red; + chunkEntry.green = entry.green; + chunkEntry.blue = entry.blue; + chunkEntry.alpha = entry.alpha; + chunk.addEntry(chunkEntry); + } + + return chunk; + } + + override function toString():String { + return [super.toString(), 'paletteSize: $paletteSize'].join('\n'); + } + public function new(?createHeader:Bool = false) { super(createHeader, PALETTE); } diff --git a/test/TestMain.hx b/test/TestMain.hx index d175791..de6fdf6 100644 --- a/test/TestMain.hx +++ b/test/TestMain.hx @@ -1,10 +1,11 @@ package; -import sys.FileSystem; import ase.Ase; import ase.AseHeader; +import ase.chunks.OldPaleteChunk; import ase.types.ChunkType; import haxe.io.Bytes; +import sys.FileSystem; import sys.io.File; using Type; @@ -58,7 +59,7 @@ class TestMain { } function run(name:String, test:Void->Void) { - print('Running $name:'); + print('$name:'); test(); } @@ -80,6 +81,11 @@ class TestMain { assert('File contains only one frame', () -> ase.frames.length == 1); assert('Color depth is 32 bits', () -> ase.header.colorDepth == 32); + + assert('Save data to another file without errors', () -> { + File.saveBytes('test_files/tmp/128x128_rgba.aseprite', ase.toBytes()); + return true; + }); }); run('More Parsing', () -> { @@ -145,19 +151,8 @@ class TestMain { assertEqual('Written bytes length is the same as the read one', bytes.length, aseBytes.length); - assert('Written bytes are exactly the same as the read ones', () -> { - if (aseBytes.length != bytes.length) - throw 'The length is different'; - - for (i in 0...aseBytes.length) { - var wb = aseBytes.get(i); - var ob = bytes.get(i); - - if (wb != ob) - throw 'Mismatching bytes at position: $i'; - } - - return true; + assert('Written length is the same as the read one', () -> { + return aseBytes.length == bytes.length; }); } }); @@ -166,7 +161,16 @@ class TestMain { FileSystem.createDirectory('test_files/tmp'); var ase:Ase; assert('Create a new blank sprite', () -> { - ase = Ase.create(128, 128); + ase = Ase.create(128, 128, [ + 0xff0000ff, + 0xff8800ff, + 0xffff00ff, + 0x00ff00ff, + 0x0000ffff, + 0x000088ff, + 0xff00ffff + ]); + ase.addLayer(); return true; }); @@ -180,6 +184,19 @@ class TestMain { File.saveBytes('test_files/tmp/blank128x128.aseprite', bytes); return true; }); + + assert('Saved files have correct palette chunks', () -> { + final bytes = File.getBytes('test_files/tmp/blank128x128.aseprite'); + final ase = Ase.fromBytes(bytes); + + final oldPaletteChunks:Array = cast ase.firstFrame.chunkTypes[ChunkType.OLD_PALETTE_04]; + final paletteChunks = ase.firstFrame.chunkTypes[ChunkType.PALETTE]; + + return oldPaletteChunks.length == 1 + && oldPaletteChunks[0].numPackets == 1 + && oldPaletteChunks[0].packets[0].numColors == 7 + && paletteChunks == null; + }); }); run('Create pong animation programmatically', () -> { @@ -189,7 +206,7 @@ class TestMain { assert('Create a new blank sprite', () -> { FileSystem.createDirectory('test_files/tmp'); ase = Ase.create(200, 200, INDEXED, - [0x00000000, 0x000000ff, 0xffffffff]); + [0x000000ff, 0x000000ff, 0xffffffff]); ase.addLayer('Background'); ase.addLayer('Ball'); @@ -229,6 +246,28 @@ class TestMain { final ase = Ase.fromBytes(bytes); // TODO: More tests }); + + run('Create 2x2px file with 2 colors in palette and compare it to one created in Aseprite', + () -> { + final fileBytes = File.getBytes('test_files/1x1_old_pal.aseprite'); + + final ase = Ase.create(2, 2, INDEXED, [0x000000ff, 0xffffffff]); + + ase.addLayer('Layer 1'); + + ase.firstFrame.createCel(0, 2, 2, 0, 0); + + ase.firstFrame.cel(0).setPixel(0, 0, 1); + ase.firstFrame.cel(0).setPixel(0, 1, 0); + ase.firstFrame.cel(0).setPixel(1, 0, 0); + ase.firstFrame.cel(0).setPixel(1, 1, 1); + + final bytes = ase.toBytes(); + + assert('Files have equal size', () -> { + return bytes.length == fileBytes.length; + }); + }); } static function main() { diff --git a/test_files/128x128_rgba.aseprite b/test_files/128x128_rgba.aseprite index 363d4057b1c3bd0941b970792cfa6c6f7502c8e7..d5a81594d8901a39b83b748ef15d7c2840cb06ed 100644 GIT binary patch delta 42 ycmbQjxr?1?7xP3WHD&<@fr*Cx6CK!it(X}Yetl$NNMT@LV42t}xw(N+gc$(bTM7jL delta 257 zcmdnRK82HM3d=+$wTY(Q6CHSYMOYXZetl$RNMT@LV4c`2S$_-2kW^3rk{}=tp%CPM z1_mVs6CmlTVFM)7EDeEVf0#9pykDpWByTQA1Cs9!&jOOaKbZl^nNI_NWY#_dAZb1& z4@i1v>I2CjZxtYEWMc^=?d?l|q(MScG?0qUdk7?xXa5J1@n@d^$3+!VCZ^ CU|9A5 diff --git a/test_files/1x1_old_pal.aseprite b/test_files/1x1_old_pal.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..ffce4519a90d5508a5449a984f5364e7cc77da7c GIT binary patch literal 251 zcmey(z`*ceDI)_D5OOdu0(mJwi~vjwj37Y<0U)FWs0JGP>mv);Ru&*z42ankz*Ztz z2eO+5tL(IO8SQE# zF+`|nRBT0j#3s2{CsfQZzse!{NDAv&u{&n_gTMZz3W};wcS# zGes;pP8+RVgH}5T{ML%YtUA(z#;WdU<*SnWd_v0Yoo^lA8f>>?>taXO)gTyd&%Y3G zygM+3;x+cxf5It>O35#dh2nxkLU#M@h*%$==jhnsAJ`UMB1qg4f5M*q&55Hkwf_xj ziZB7MeP<4yXMR|lkoJz$FdEU#fepn6u7a?7&PZ#MF!ZGx`FqnDu{lP?D>FdJ zhH1dL7VZe>y$)pq%IKv&<$L(a&~>qCI=1uteGEM~6g-zSN-y9wP^91B8K|1RD?!-5 z$rfl48gncC83_}UhWvxjBpo59(R^bz0_MCjz)^c!(}DNUFN4dGf7+=G)o?^<>OG)G%ZS;`LP$z+8gW+e3 zcnxNn$O55$1@?r#_UMqTo*o)=#OG8YuPIU8xnb5hGwT8WflT}!kgPsQRc(ksVcQ># z(qpL%_Nyn+EAMK_kbb9MW>BqI! z)62NJ9rEp6(;6TSI9Q6mS5*Fq+5kJ9;eSjL=Af*GSA6Ae|duo|0QHWEp8b zxy>fJctEyvH@JZRY@y*?5NJwdx}YAW&t3`i+K;BwuZx$pxK-nC>EGkKkQv{lM=O;F z2A86F+*#lbKsLXga+)!oc)+?hj(&7iIIsyc-t~~JFTpzJrc!n6WZ`t52DWbdQ7c7I zAUI?gOXk>;Tj*Xr*Vb-0pMV}k1NavO=3_V)u^19x2DBSrM^jl=(p|=%%FT>$u5}8W3xF&p z&=vA(1>chJKpLQMF+TeQ^)Y2Exs(khj9>=HAE$QFHr?B{9k3_r2@~9&_P2*|kJ-;)8c0wwFLHtbKwR ze$~?Qe#k1fu^%bnqkAgOrAa|hP`dmhXsn-BZVozHzy<}|rk<#(ZGt>>sT)f+xsKXh_{yQ0VDQN0)Ph6OM;MS*VleYD;tu zLVEdr%>1rMoWM5Ndg}cgX|17gjfYpY25nfQl#vD8%^P3k5(3i3b~ihW)S>S6*ATkY z*e3jlfl(iCJK{o}rGF;2lmF6vu9f0PriDtOcvvMSBB_#bDz~gNN+lu*b~)DAIi*ez zVtewmv8POw!My`lPTMwmV8ZTMMR3w|vd_e&<7OpV0OZ_UjBLjeO%Nqqq-a1X-eam) zAVQ4~t8Qr%jR6JxBG7M$h3!E^d|$Fp7a%goY}|;lkoe*D)bQ|F^Vo@?qRl}IP^I^Y zcHml(Vacf~bml7mN#~kHhBE_tRBOMozW*smmKj&K!1sCBH8MM(pvr88TjBNRu)XWQ zp8H==7<}FK&T!>BKi6stNXZ%|5-+ZhhN)QE8FS!|A$We3jZ=-dE{c_ZNYuM&@;ZF- zDkQb|Qs|c*_ZSU})P=mI+j}1?-%_*82F%QnC#gwrnp%vbg0S<_lhjP?cR8<;#xxZ%EAbmBFB+kW7o3uZaOesZR@U zBkdYnx=CxJKc#9xYOfDsTMt(9T!24W#OM;LIbtrg-xR20;Wgo!0%Z39-A4nCX5faq z0VlDlG-e4BMt@oKEEZTp9kNHLV|Rv#=|Yu&;l-9Trfk#_^=!F{u?7_-E?FN=&{nT7|x1&vjybE& zBoo+DGkL#qT;%{EBGuN(DLqFhPw^rTkTK8~33pT~)#q>Jjt^P+|mm4C9d>(+EPS5O5@WWB;xt<3E6U``jMv#6ifIxe0VsT*PG zaL%SqHLOC4+82WLZJIKAu6tdxNmQA|8SgBN4rflH=vL)2xFW~kUanP6O7v)iVhQI2sDE(_5KF znqo&Ni#HdMMA9sA2yl5F5d^PCf`=vE&zY86@0~MS+Oug7DF+r)7Mv#WmDZK5?$7!R z?@oR?RtP#Gr7wP+Q4uug?&gCZ7aWG(yS0duI!-iW)8c!VVE1WXbIa3V4PxGCru{Ye zjcx(R-=sLDdpKx1qU{vg=XH%U+qV$Y!ABrW`*eBu0nj!nW#H`CK_c+HkANBa1T0Ig z6g%m;mP0$RhTO?SIz2tZSxa7WZ|Io%_x6fsK61V^(+Eojh&oRO|Ka!Eic=jrlTp#t7}Y@Zyfc&|B1Y+$>jxY&%ffG#-~82xtgIV`xB$%i zT(BGW!&Au)_v1Xgt%vaS@W8<}3Z)efy*(L53Qib{*q{*bK~XG2KGR5HQt}yQM;c6T vFK}~wLk$s)W((M?wO~P#U@{(qm0%lA1p)38S-7h%VYeTK?IN$uC#wDf4$@e5