Skip to content

Commit

Permalink
v4.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
RobLoach committed Mar 5, 2022
1 parent 8bded7c commit 7aaced0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.11)
project (raylib_aseprite
VERSION 4.0.2
VERSION 4.0.3
DESCRIPTION "raylib_aseprite: Use Aseprite files in raylib"
HOMEPAGE_URL "https://github.com/robloach/raylib-aseprite"
LANGUAGES C)
Expand Down
59 changes: 51 additions & 8 deletions include/cute_aseprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Licensing information can be found at the end of the file.
------------------------------------------------------------------------------
cute_aseprite.h - v1.01
cute_aseprite.h - v1.02
To create implementation (the function definitions)
#define CUTE_ASEPRITE_IMPLEMENTATION
Expand Down Expand Up @@ -43,6 +43,8 @@
Revision history:
1.00 (08/25/2020) initial release
1.01 (08/31/2020) fixed memleaks, tag parsing bug (crash), blend bugs
1.02 (02/05/2022) fixed icc profile parse bug, support transparent pal-
ette index, can parse 1.3 files (no tileset support)
*/

/*
Expand Down Expand Up @@ -102,7 +104,7 @@ void cute_aseprite_free(ase_t* aseprite);

#define CUTE_ASEPRITE_MAX_LAYERS (64)
#define CUTE_ASEPRITE_MAX_SLICES (128)
#define CUTE_ASEPRITE_MAX_PALETTE_ENTRIES (256)
#define CUTE_ASEPRITE_MAX_PALETTE_ENTRIES (1024)
#define CUTE_ASEPRITE_MAX_TAGS (256)

#include <stdint.h>
Expand Down Expand Up @@ -162,7 +164,7 @@ struct ase_layer_t
ase_layer_flags_t flags;
ase_layer_type_t type;
const char* name;
int child_level;
ase_layer_t* parent;
float opacity;
ase_udata_t udata;
};
Expand Down Expand Up @@ -212,6 +214,7 @@ struct ase_tag_t
ase_animation_direction_t loop_animation_direction;
uint8_t r, g, b;
const char* name;
ase_udata_t udata;
};

struct ase_slice_t
Expand Down Expand Up @@ -852,7 +855,8 @@ static ase_color_t s_blend(ase_color_t src, ase_color_t dst, uint8_t opacity)
g = dst.g + (src.g - dst.g) * src.a / a;
b = dst.b + (src.b - dst.b) * src.a / a;
}
return (ase_color_t) { (uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a };
ase_color_t ret = { (uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a };
return ret;
}

static int s_min(int a, int b)
Expand All @@ -878,7 +882,14 @@ static ase_color_t s_color(ase_t* ase, void* src, int index)
} else {
CUTE_ASEPRITE_ASSERT(ase->mode == ASE_MODE_INDEXED);
uint8_t palette_index = ((uint8_t*)src)[index];
result = ase->palette.entries[palette_index].color;
if (palette_index == ase->transparent_palette_entry_index) {
result.r = 0;
result.g = 0;
result.b = 0;
result.a = 0;
} else {
result = ase->palette.entries[palette_index].color;
}
}
return result;
}
Expand Down Expand Up @@ -926,6 +937,10 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
CUTE_ASEPRITE_MEMSET(ase->frames, 0, sizeof(ase_frame_t) * (size_t)ase->frame_count);

ase_udata_t* last_udata = NULL;
int was_on_tags = 0;
int tag_index = 0;

ase_layer_t* layer_stack[CUTE_ASEPRITE_MAX_LAYERS];

// Parse all chunks in the .aseprite file.
for (int i = 0; i < ase->frame_count; ++i) {
Expand Down Expand Up @@ -954,7 +969,12 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
ase_layer_t* layer = ase->layers + ase->layer_count++;
layer->flags = (ase_layer_flags_t)s_read_uint16(s);
layer->type = (ase_layer_type_t)s_read_uint16(s);
layer->child_level = (int)s_read_uint16(s);
layer->parent = NULL;
int child_level = (int)s_read_uint16(s);
layer_stack[child_level] = layer;
if (child_level) {
layer->parent = layer_stack[child_level - 1];
}
s_skip(s, sizeof(uint16_t)); // Default layer width in pixels (ignored).
s_skip(s, sizeof(uint16_t)); // Default layer height in pixels (ignored).
int blend_mode = (int)s_read_uint16(s);
Expand Down Expand Up @@ -1037,6 +1057,7 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
ase->color_profile.icc_profile_data_length = s_read_uint32(s);
ase->color_profile.icc_profile_data = CUTE_ASEPRITE_ALLOC(ase->color_profile.icc_profile_data_length, mem_ctx);
CUTE_ASEPRITE_MEMCPY(ase->color_profile.icc_profile_data, s->in, ase->color_profile.icc_profile_data_length);
s->in += ase->color_profile.icc_profile_data_length;
}
} break;

Expand All @@ -1058,11 +1079,13 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
tag.name = s_read_string(s);
ase->tags[k] = tag;
}
was_on_tags = 1;
} break;

case 0x2019: // Palette chunk.
{
ase->palette.entry_count = (int)s_read_uint32(s);
CUTE_ASEPRITE_ASSERT(ase->palette.entry_count <= CUTE_ASEPRITE_MAX_PALETTE_ENTRIES);
int first_index = (int)s_read_uint32(s);
int last_index = (int)s_read_uint32(s);
s_skip(s, 8); // For future (set to zero).
Expand All @@ -1078,13 +1101,18 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
} else {
entry.color_name = NULL;
}
CUTE_ASEPRITE_ASSERT(k < CUTE_ASEPRITE_MAX_PALETTE_ENTRIES);
ase->palette.entries[k] = entry;
}
} break;

case 0x2020: // Udata chunk.
{
CUTE_ASEPRITE_ASSERT(last_udata);
CUTE_ASEPRITE_ASSERT(last_udata || was_on_tags);
if (was_on_tags && !last_udata) {
CUTE_ASEPRITE_ASSERT(tag_index < ase->tag_count);
last_udata = &ase->tags[tag_index++].udata;
}
int flags = (int)s_read_uint32(s);
if (flags & 1) {
last_udata->has_text = 1;
Expand Down Expand Up @@ -1136,6 +1164,9 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
s_skip(s, (int)chunk_size);
break;
}

uint32_t size_read = (uint32_t)(s->in - chunk_start);
CUTE_ASEPRITE_ASSERT(size_read == chunk_size);
}
}

Expand All @@ -1150,8 +1181,20 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct
if (!(cel->layer->flags & ASE_LAYER_FLAGS_VISIBLE)) {
continue;
}
if (cel->layer->parent && !(cel->layer->parent->flags & ASE_LAYER_FLAGS_VISIBLE)) {
continue;
}
while (cel->is_linked) {
cel = ase->frames[cel->linked_frame_index].cels + j;
ase_frame_t* frame = ase->frames + cel->linked_frame_index;
int found = 0;
for (int k = 0; k < frame->cel_count; ++k) {
if (frame->cels[k].layer == cel->layer) {
cel = frame->cels + k;
found = 1;
break;
}
}
CUTE_ASEPRITE_ASSERT(found);
}
void* src = cel->pixels;
uint8_t opacity = (uint8_t)(cel->opacity * cel->layer->opacity * 255.0f);
Expand Down

0 comments on commit 7aaced0

Please sign in to comment.