From 8ed97d133e5b24515e79c2af84730d94b9f667a5 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Wed, 16 Sep 2020 21:33:41 -0700 Subject: [PATCH] fixed incorrect aseprite linked-cel parsing --- public/blah/images/aseprite.cpp | 80 +++++++++++++++++---------------- public/blah/images/aseprite.h | 3 +- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/public/blah/images/aseprite.cpp b/public/blah/images/aseprite.cpp index 4e278e0..80c5b8b 100644 --- a/public/blah/images/aseprite.cpp +++ b/public/blah/images/aseprite.cpp @@ -48,6 +48,18 @@ Aseprite::Aseprite(const Aseprite& src) palette = src.palette; } +Aseprite::Aseprite(Aseprite&& src) noexcept +{ + mode = src.mode; + width = src.width; + height = src.height; + layers = std::move(src.layers); + frames = std::move(src.frames); + tags = std::move(src.tags); + slices = std::move(src.slices); + palette = std::move(src.palette); +} + Aseprite& Aseprite::operator=(const Aseprite& src) { mode = src.mode; @@ -61,18 +73,6 @@ Aseprite& Aseprite::operator=(const Aseprite& src) return *this; } -Aseprite::Aseprite(Aseprite&& src) noexcept -{ - mode = src.mode; - width = src.width; - height = src.height; - layers = std::move(src.layers); - frames = std::move(src.frames); - tags = std::move(src.tags); - slices = std::move(src.slices); - palette = std::move(src.palette); -} - Aseprite& Aseprite::operator=(Aseprite&& src) noexcept { mode = src.mode; @@ -126,17 +126,17 @@ void Aseprite::Parse(Stream& stream) stream.read(Endian::Little); // Should be 0 stream.read(Endian::Little); // Should be 0 stream.read(Endian::Little); // Palette entry - stream.seek(stream.position() + 3); // Ignore these bytes + stream.seek(stream.position() + 3); // Ignore these bytes stream.read(Endian::Little); // Number of colors (0 means 256 for old sprites) - stream.read(Endian::Little); // Pixel width - stream.read(Endian::Little); // Pixel height - stream.seek(stream.position() + 92); // For Future + stream.read(Endian::Little); // Pixel width + stream.read(Endian::Little); // Pixel height + stream.seek(stream.position() + 92); // For Future } frames.expand(frameCount); // frames - for (int i = 0; i < frameCount; i ++) + for (int i = 0; i < frameCount; i++) { auto frameStart = stream.position(); auto frameEnd = frameStart + stream.read(Endian::Little); @@ -166,7 +166,7 @@ void Aseprite::Parse(Stream& stream) frames[i].image = Image(width, height); // frame chunks - for (unsigned int j = 0; j < chunks; j ++) + for (unsigned int j = 0; j < chunks; j++) { auto chunkStart = stream.position(); auto chunkEnd = chunkStart + stream.read(Endian::Little); @@ -174,13 +174,13 @@ void Aseprite::Parse(Stream& stream) switch (chunkType) { - case Chunks::Layer: ParseLayer(stream, i); break; - case Chunks::Cel: ParseCel(stream, i, (size_t)chunkEnd); break; - case Chunks::Palette: ParsePalette(stream, i); break; - case Chunks::UserData: ParseUserData(stream, i); break; - case Chunks::FrameTags: ParseTag(stream, i); break; - case Chunks::Slice: ParseSlice(stream, i); break; - default: break; + case Chunks::Layer: ParseLayer(stream, i); break; + case Chunks::Cel: ParseCel(stream, i, chunkEnd); break; + case Chunks::Palette: ParsePalette(stream, i); break; + case Chunks::UserData: ParseUserData(stream, i); break; + case Chunks::FrameTags: ParseTag(stream, i); break; + case Chunks::Slice: ParseSlice(stream, i); break; + default: break; } stream.seek(chunkEnd); @@ -221,7 +221,6 @@ void Aseprite::ParseCel(Stream& stream, int frameIndex, size_t maxPosition) cel->y = stream.read(Endian::Little); cel->alpha = stream.read(Endian::Little); cel->linked_frame_index = -1; - cel->linked_cel_index = -1; auto celType = stream.read(Endian::Little); stream.seek(stream.position() + 7); @@ -248,8 +247,6 @@ void Aseprite::ParseCel(Stream& stream, int frameIndex, size_t maxPosition) auto size = maxPosition - stream.position(); if (size > INT32_MAX) size = INT32_MAX; - if (size < 0) - size = 0; char* buffer = new char[size]; stream.read(buffer, size); @@ -272,14 +269,14 @@ void Aseprite::ParseCel(Stream& stream, int frameIndex, size_t maxPosition) { auto src = (unsigned char*)cel->image.pixels; auto dst = cel->image.pixels; - for (int d = width * height - 1, s = (width * height - 1) * 2; d >= 0; d --, s -= 2) + for (int d = width * height - 1, s = (width * height - 1) * 2; d >= 0; d--, s -= 2) dst[d] = Color(src[s], src[s], src[s], src[s + 1]); } else if (mode == Modes::Indexed) { auto src = (unsigned char*)cel->image.pixels; auto dst = cel->image.pixels; - for (int i = width * height - 1; i >= 0; i --) + for (int i = width * height - 1; i >= 0; i--) dst[i] = palette[src[i]]; } @@ -289,7 +286,6 @@ void Aseprite::ParseCel(Stream& stream, int frameIndex, size_t maxPosition) else if (celType == 1) { cel->linked_frame_index = stream.read(Endian::Little); - cel->linked_cel_index = static_cast(frame.cels.count() - 1); } // draw to frame if visible @@ -323,7 +319,7 @@ void Aseprite::ParsePalette(Stream& stream, int frame) int len = stream.read(Endian::Little); stream.seek(stream.position() + len); } - } + } } void Aseprite::ParseUserData(Stream& stream, int frame) @@ -362,7 +358,7 @@ void Aseprite::ParseTag(Stream& stream, int frame) stream.seek(stream.position() + 1); tag->name.set_length(stream.read(Endian::Little)); - stream.read(tag->name .cstr(), tag->name.length()); + stream.read(tag->name.cstr(), tag->name.length()); } } @@ -385,7 +381,7 @@ void Aseprite::ParseSlice(Stream& stream, int frame) slice->origin.y = stream.read(Endian::Little); slice->width = stream.read(Endian::Little); slice->height = stream.read(Endian::Little); - + // 9 slice (ignored atm) if (flags & (1 << 0)) { @@ -413,10 +409,18 @@ void Aseprite::ParseSlice(Stream& stream, int frame) void Aseprite::RenderCel(Cel* cel, Frame* frame) { Layer& layer = layers[cel->layer_index]; - + while (cel->linked_frame_index >= 0) - cel = &(frames[cel->linked_frame_index].cels[cel->linked_cel_index]); - + { + auto& frame = frames[cel->linked_frame_index]; + for (auto& it : frame.cels) + if (it.layer_index == cel->layer_index) + { + cel = ⁢ + break; + } + } + int t; unsigned char opacity = MUL_UN8(cel->alpha, layer.alpha, t); if (opacity <= 0) @@ -456,7 +460,7 @@ void Aseprite::RenderCel(Cel* cel, Frame* frame) dstColor->b = (unsigned char)(dstColor->b + (srcColor->b - dstColor->b) * sa / ra); dstColor->a = (unsigned char)ra; } - } + } } } else diff --git a/public/blah/images/aseprite.h b/public/blah/images/aseprite.h index 5b76f5a..a574232 100644 --- a/public/blah/images/aseprite.h +++ b/public/blah/images/aseprite.h @@ -69,7 +69,6 @@ namespace Blah { int layer_index = 0; int linked_frame_index = 0; - int linked_cel_index = 0; int x = 0; int y = 0; unsigned char alpha = 0; @@ -132,8 +131,8 @@ namespace Blah Aseprite(const char* path); Aseprite(Stream& stream); Aseprite(const Aseprite& src); - Aseprite& operator=(const Aseprite& src); Aseprite(Aseprite&& src) noexcept; + Aseprite& operator=(const Aseprite& src); Aseprite& operator=(Aseprite&& src) noexcept; ~Aseprite();