<commit_before>// Copyright (C) 2015 <NAME>
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Utility/Formats/STBLoader.hpp>
#include <stb/stb_image_write.h>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <map>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>

namespace Nz
{
	namespace
	{
		using FormatHandler = bool(*)(const Image& image, const ImageParams& parameters, Stream& stream);

		std::map<String, FormatHandler> s_formatHandlers;

		int ConvertToFloatFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_R32F:
					return 1;

				case PixelFormatType_RG32F:
					return 2;

				case PixelFormatType_RGB32F:
					return 3;

				case PixelFormatType_RGBA32F:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA32F))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB32F))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		int ConvertToIntegerFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_L8:
				case PixelFormatType_R8:
					return 1;

				case PixelFormatType_LA8:
				case PixelFormatType_RG8:
					return 2;

				case PixelFormatType_RGB8:
					return 3;

				case PixelFormatType_RGBA8:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA8))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB8))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		void WriteToStream(void* userdata, void* data, int size)
		{
			Stream* stream = static_cast<Stream*>(userdata);
			if (stream->Write(data, size) != size)
				throw std::runtime_error("Failed to write to stream");
		}

		bool FormatQuerier(const String& extension)
		{
			return s_formatHandlers.find(extension) != s_formatHandlers.end();
		}

		bool SaveToStream(const Image& image, const String& format, Stream& stream, const ImageParams& parameters)
		{
			NazaraUnused(parameters);

			if (!image.IsValid())
			{
				NazaraError("Invalid image");
				return false;
			}

			ImageType type = image.GetType();
			if (type != ImageType_1D && type != ImageType_2D)
			{
				NazaraError("Image type 0x" + String::Number(type, 16) + " is not ");
				return false;
			}

			auto it = s_formatHandlers.find(format);
			NazaraAssert(it != s_formatHandlers.end(), "Invalid handler");

			const FormatHandler& handler = it->second;
			try
			{
				return handler(image, parameters, stream);
			}
			catch (const std::exception& e)
			{
				NazaraError(e.what());
				return false;
			}
		}

		bool SaveBMP(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required
			<commit_msg>Utility/STBSaver: Fix error message<commit_after>// Copyright (C) 2015 <NAME>
// This file is part of the "Nazara Engine - Utility module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Utility/Formats/STBLoader.hpp>
#include <stb/stb_image_write.h>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <map>
#include <stdexcept>
#include <Nazara/Utility/Debug.hpp>

namespace Nz
{
	namespace
	{
		using FormatHandler = bool(*)(const Image& image, const ImageParams& parameters, Stream& stream);

		std::map<String, FormatHandler> s_formatHandlers;

		int ConvertToFloatFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_R32F:
					return 1;

				case PixelFormatType_RG32F:
					return 2;

				case PixelFormatType_RGB32F:
					return 3;

				case PixelFormatType_RGBA32F:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA32F))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB32F))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		int ConvertToIntegerFormat(Image& image)
		{
			switch (image.GetFormat())
			{
				case PixelFormatType_L8:
				case PixelFormatType_R8:
					return 1;

				case PixelFormatType_LA8:
				case PixelFormatType_RG8:
					return 2;

				case PixelFormatType_RGB8:
					return 3;

				case PixelFormatType_RGBA8:
					return 4;

				default:
				{
					if (PixelFormat::HasAlpha(image.GetFormat()))
					{
						if (!image.Convert(PixelFormatType_RGBA8))
							break;

						return 4;
					}
					else
					{
						if (!image.Convert(PixelFormatType_RGB8))
							break;

						return 3;
					}
				}
			}

			return 0;
		}

		void WriteToStream(void* userdata, void* data, int size)
		{
			Stream* stream = static_cast<Stream*>(userdata);
			if (stream->Write(data, size) != size)
				throw std::runtime_error("Failed to write to stream");
		}

		bool FormatQuerier(const String& extension)
		{
			return s_formatHandlers.find(extension) != s_formatHandlers.end();
		}

		bool SaveToStream(const Image& image, const String& format, Stream& stream, const ImageParams& parameters)
		{
			NazaraUnused(parameters);

			if (!image.IsValid())
			{
				NazaraError("Invalid image");
				return false;
			}

			ImageType type = image.GetType();
			if (type != ImageType_1D && type != ImageType_2D)
			{
				NazaraError("Image type 0x" + String::Number(type, 16) + " is not in a supported format");
				return false;
			}

			auto it = s_formatHandlers.find(format);
			NazaraAssert(it != s_formatHandlers.end(), "Invalid handler");

			const FormatHandler& handler = it->second;
			try
			{
				return handler(image, parameters, stream);
			}
			catch (const std::exception& e)
			{
				NazaraError(e.what());
				return false;
			}
		}

		bool SaveBMP(const Image& image, const ImageParams& parameters, Stream& stream)
		{
			Image tempImage(image); //< We're using COW here to prevent Image copy unless required
			
{'fraction_non_alphanumeric': 0.11109316970773454, 'fraction_numerical': 0.013886646213466818, 'mean_word_length': 3.011658031088083, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, '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': '6874326', 'n_tokens_mistral': 2735, 'n_tokens_neox': 2032, 'n_words': 489}