<commit_before>#include "aseprite_reader.h"
#include "halley/tools/file/filesystem.h"
#include "halley/core/graphics/sprite/sprite_sheet.h"
#include "halley/file/path.h"
#include "halley/file_formats/image.h"
#include "../assets/importers/sprite_importer.h"
#include "aseprite_file.h"
using namespace Halley;


std::map<String, std::vector<ImageData>> AsepriteReader::importAseprite(String spriteName, gsl::span<const gsl::byte> fileData, bool trim, bool groupSeparated)
{
	const String baseName = Path(spriteName).getFilename().string();

	AsepriteFile aseFile;
	aseFile.load(fileData);

	const size_t nFrames = aseFile.getNumberOfFrames();
	std::vector<char> frameTagged(nFrames, 0);

	// Load all tags
	std::vector<std::pair<String, std::vector<int>>> tags;
	for (auto& tag: aseFile.getTags()) {
		std::vector<int> frames;
		for (int i = tag.fromFrame; i <= tag.toFrame; ++i) {
			frameTagged[i] = 1;
			frames.push_back(i);
		}
		tags.emplace_back(tag.name, std::move(frames));
	}

	// Create empty tag
	{
		std::vector<int> untagged;
		for (int i = 0; i < int(frameTagged.size()); ++i) {
			if (frameTagged[i] == 0) {
				untagged.push_back(i);
			}
		}
		if (!untagged.empty()) {
			tags.emplace_back("", std::move(untagged));
		}
	}

	// Create frames
	std::map<String, std::vector<ImageData>> frameData;
	bool firstImage = true;
	for (auto& t: tags) {
		int i = 0;
		String sequence = t.first;
		String direction = "";
		if (sequence.find(':') != std::string::npos) {
			auto split = sequence.split(':');
			sequence = split.at(0);
			direction = split.at(1);
		}

		for (const int frameN: t.second) {

			std::map<String, std::unique_ptr<Image>> groupFrameImages = aseFile.makeGroupFrameImages(frameN, groupSeparated);

			const auto duration = aseFile.getFrame(frameN).duration;
			const auto hasFrameNumber = t.second.size() > 1;

			for (auto& groupFrameImage : groupFrameImages)
			{
				std::vector<ImageData> groupFrameData;
				addImageData(i, groupFrameData, std::move(groupFrameImage.second), aseFile, baseName, sequence, direction, duration, trim, hasFrameNumber, groupFrameImage.first, firstImage, spriteName);
				firstImage = false;
				
				if(frameData.find(groupFrameImage.first) == frameData.end())
				{
					frameData[groupFrameImage.first] = std::vector<ImageData>();
				}
				std::move(groupFrameData.begin(), groupFrameData.end(), std::back_inserter(frameData[groupFrameImage.first]));
			}
		}
	}

	return frameData;
}

void AsepriteReader::addImageData(int frameNumber, std::vector<ImageData>& frameData, std::unique_ptr<Image> frameImage, const AsepriteFile& aseFile,
	const String& baseName, const String& sequence, const String& direction, int duration, bool trim, bool hasFrameNumber, std::optional<String> group,
	bool firstImage, const String& spriteName)
{<commit_msg>first image is per group<commit_after>#include "aseprite_reader.h"
#include "halley/tools/file/filesystem.h"
#include "halley/core/graphics/sprite/sprite_sheet.h"
#include "halley/file/path.h"
#include "halley/file_formats/image.h"
#include "../assets/importers/sprite_importer.h"
#include "aseprite_file.h"
using namespace Halley;


std::map<String, std::vector<ImageData>> AsepriteReader::importAseprite(String spriteName, gsl::span<const gsl::byte> fileData, bool trim, bool groupSeparated)
{
	const String baseName = Path(spriteName).getFilename().string();

	AsepriteFile aseFile;
	aseFile.load(fileData);

	const size_t nFrames = aseFile.getNumberOfFrames();
	std::vector<char> frameTagged(nFrames, 0);

	// Load all tags
	std::vector<std::pair<String, std::vector<int>>> tags;
	for (auto& tag: aseFile.getTags()) {
		std::vector<int> frames;
		for (int i = tag.fromFrame; i <= tag.toFrame; ++i) {
			frameTagged[i] = 1;
			frames.push_back(i);
		}
		tags.emplace_back(tag.name, std::move(frames));
	}

	// Create empty tag
	{
		std::vector<int> untagged;
		for (int i = 0; i < int(frameTagged.size()); ++i) {
			if (frameTagged[i] == 0) {
				untagged.push_back(i);
			}
		}
		if (!untagged.empty()) {
			tags.emplace_back("", std::move(untagged));
		}
	}

	// Create frames
	std::map<String, std::vector<ImageData>> frameData;	
	for (auto& t: tags) {
		int i = 0;
		String sequence = t.first;
		String direction = "";
		if (sequence.find(':') != std::string::npos) {
			auto split = sequence.split(':');
			sequence = split.at(0);
			direction = split.at(1);
		}

		for (const int frameN: t.second) {

			std::map<String, std::unique_ptr<Image>> groupFrameImages = aseFile.makeGroupFrameImages(frameN, groupSeparated);

			const auto duration = aseFile.getFrame(frameN).duration;
			const auto hasFrameNumber = t.second.size() > 1;

			for (auto& groupFrameImage : groupFrameImages)
			{
				std::vector<ImageData> groupFrameData;
				auto firstImage = frameData.find(groupFrameImage.first) == frameData.end();
				addImageData(i, groupFrameData, std::move(groupFrameImage.second), aseFile, baseName, sequence, direction, duration, trim, hasFrameNumber, groupFrameImage.first, firstImage, spriteName);
				
				if(frameData.find(groupFrameImage.first) == frameData.end())
				{
					frameData[groupFrameImage.first] = std::vector<ImageData>();
				}
				std::move(groupFrameData.begin(), groupFrameData.end(), std::back_inserter(frameData[groupFrameImage.first]));
			}
		}
	}

	return frameData;
}

void AsepriteReader::addImageData(int frameNumber, std::vector<ImageData>& frameData, std::unique_ptr<Image> frameImage, const AsepriteFile& aseFile,
	const String& baseName, const String& sequence, const String& direction, int duration, bool trim, bool hasFrameNumber, std::optional<String> group,
	bool firstImage, const String& spriteName)
{
{'fraction_non_alphanumeric': 0.15209326974032855, 'fraction_numerical': 0.0028263557675322383, 'mean_word_length': 5.094725511302475, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '818086', 'n_tokens_mistral': 2148, 'n_tokens_neox': 1949, 'n_words': 397}