mirror of
				https://github.com/NoelFB/blah.git
				synced 2025-11-04 01:41:34 +08:00 
			
		
		
		
	image calls proper delete/stbi_image_free
This commit is contained in:
		@ -14,43 +14,48 @@ using namespace Blah;
 | 
				
			|||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
 | 
					#define STB_IMAGE_WRITE_IMPLEMENTATION
 | 
				
			||||||
#include <blah/third_party/stb_image_write.h>
 | 
					#include <blah/third_party/stb_image_write.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Engine_STBI_Read(void *user, char *data, int size)
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int64_t read = ((Stream*)user)->read(data, size);
 | 
						int Blah_STBI_Read(void* user, char* data, int size)
 | 
				
			||||||
	return (int)read;
 | 
						{
 | 
				
			||||||
}
 | 
							int64_t read = ((Stream*)user)->read(data, size);
 | 
				
			||||||
 | 
							return (int)read;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Engine_STBI_Skip(void *user, int n)
 | 
						void Blah_STBI_Skip(void* user, int n)
 | 
				
			||||||
{
 | 
						{
 | 
				
			||||||
	((Stream*)user)->seek(((Stream*)user)->position() + n);
 | 
							((Stream*)user)->seek(((Stream*)user)->position() + n);
 | 
				
			||||||
}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int Engine_STBI_Eof(void *user)
 | 
						int Blah_STBI_Eof(void* user)
 | 
				
			||||||
{
 | 
						{
 | 
				
			||||||
	int64_t position = ((Stream*)user)->position();
 | 
							int64_t position = ((Stream*)user)->position();
 | 
				
			||||||
	int64_t length = ((Stream*)user)->length();
 | 
							int64_t length = ((Stream*)user)->length();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (position >= length)
 | 
							if (position >= length)
 | 
				
			||||||
		return 1;
 | 
								return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
							return 0;
 | 
				
			||||||
}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Engine_STBI_Write(void *context, void *data, int size)
 | 
						void Blah_STBI_Write(void* context, void* data, int size)
 | 
				
			||||||
{
 | 
						{
 | 
				
			||||||
	((Stream*)context)->write((char*)data, size);
 | 
							((Stream*)context)->write((char*)data, size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Image::Image()
 | 
					Image::Image()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	width = height = 0;
 | 
						width = height = 0;
 | 
				
			||||||
	pixels = nullptr;
 | 
						pixels = nullptr;
 | 
				
			||||||
 | 
						m_stbi_ownership = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Image::Image(Stream& stream)
 | 
					Image::Image(Stream& stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	width = height = 0;
 | 
						width = height = 0;
 | 
				
			||||||
	pixels = nullptr;
 | 
						pixels = nullptr;
 | 
				
			||||||
 | 
						m_stbi_ownership = false;
 | 
				
			||||||
	from_stream(stream);
 | 
						from_stream(stream);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -58,19 +63,21 @@ Image::Image(const char* file)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	width = height = 0;
 | 
						width = height = 0;
 | 
				
			||||||
	pixels = nullptr;
 | 
						pixels = nullptr;
 | 
				
			||||||
 | 
						m_stbi_ownership = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FileStream fs(file, FileMode::Read);
 | 
						FileStream fs(file, FileMode::Read);
 | 
				
			||||||
	if (fs.is_readable())
 | 
						if (fs.is_readable())
 | 
				
			||||||
		from_stream(fs);
 | 
							from_stream(fs);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Image::Image(int width, int height)
 | 
					Image::Image(int w, int h)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	BLAH_ASSERT(width >= 0 && height >= 0, "Image width and height must be larger than 0");
 | 
						BLAH_ASSERT(w >= 0 && h >= 0, "Image width and height must be larger than 0");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->width = width;
 | 
						width = w;
 | 
				
			||||||
	this->height = height;
 | 
						height = h;
 | 
				
			||||||
	pixels = new Color[width * height];
 | 
						pixels = new Color[width * height];
 | 
				
			||||||
 | 
						m_stbi_ownership = false;
 | 
				
			||||||
	memset(pixels, 0, (size_t)width * (size_t)height * sizeof(Color));
 | 
						memset(pixels, 0, (size_t)width * (size_t)height * sizeof(Color));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,6 +85,7 @@ Image::Image(const Image& src)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	width = src.width;
 | 
						width = src.width;
 | 
				
			||||||
	height = src.height;
 | 
						height = src.height;
 | 
				
			||||||
 | 
						m_stbi_ownership = src.m_stbi_ownership;
 | 
				
			||||||
	pixels = nullptr;
 | 
						pixels = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (src.pixels != nullptr && width > 0 && height > 0)
 | 
						if (src.pixels != nullptr && width > 0 && height > 0)
 | 
				
			||||||
@ -91,6 +99,7 @@ Image& Image::operator=(const Image& src)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	width = src.width;
 | 
						width = src.width;
 | 
				
			||||||
	height = src.height;
 | 
						height = src.height;
 | 
				
			||||||
 | 
						m_stbi_ownership = src.m_stbi_ownership;
 | 
				
			||||||
	pixels = nullptr;
 | 
						pixels = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (src.pixels != nullptr && width > 0 && height > 0)
 | 
						if (src.pixels != nullptr && width > 0 && height > 0)
 | 
				
			||||||
@ -107,8 +116,10 @@ Image::Image(Image&& src) noexcept
 | 
				
			|||||||
	width = src.width;
 | 
						width = src.width;
 | 
				
			||||||
	height = src.height;
 | 
						height = src.height;
 | 
				
			||||||
	pixels = src.pixels;
 | 
						pixels = src.pixels;
 | 
				
			||||||
 | 
						m_stbi_ownership = src.m_stbi_ownership;
 | 
				
			||||||
	src.width = src.height = 0;
 | 
						src.width = src.height = 0;
 | 
				
			||||||
	src.pixels = nullptr;
 | 
						src.pixels = nullptr;
 | 
				
			||||||
 | 
						src.m_stbi_ownership = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Image& Image::operator=(Image&& src) noexcept
 | 
					Image& Image::operator=(Image&& src) noexcept
 | 
				
			||||||
@ -116,8 +127,10 @@ Image& Image::operator=(Image&& src) noexcept
 | 
				
			|||||||
	width = src.width;
 | 
						width = src.width;
 | 
				
			||||||
	height = src.height;
 | 
						height = src.height;
 | 
				
			||||||
	pixels = src.pixels;
 | 
						pixels = src.pixels;
 | 
				
			||||||
 | 
						m_stbi_ownership = src.m_stbi_ownership;
 | 
				
			||||||
	src.width = src.height = 0;
 | 
						src.width = src.height = 0;
 | 
				
			||||||
	src.pixels = nullptr;
 | 
						src.pixels = nullptr;
 | 
				
			||||||
 | 
						src.m_stbi_ownership = false;
 | 
				
			||||||
	return *this;
 | 
						return *this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -137,9 +150,9 @@ void Image::from_stream(Stream& stream)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stbi_io_callbacks callbacks;
 | 
						stbi_io_callbacks callbacks;
 | 
				
			||||||
	callbacks.eof = Engine_STBI_Eof;
 | 
						callbacks.eof = Blah_STBI_Eof;
 | 
				
			||||||
	callbacks.read = Engine_STBI_Read;
 | 
						callbacks.read = Blah_STBI_Read;
 | 
				
			||||||
	callbacks.skip = Engine_STBI_Skip;
 | 
						callbacks.skip = Blah_STBI_Skip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int x, y, comps;
 | 
						int x, y, comps;
 | 
				
			||||||
	uint8_t* data = stbi_load_from_callbacks(&callbacks, &stream, &x, &y, &comps, 4);
 | 
						uint8_t* data = stbi_load_from_callbacks(&callbacks, &stream, &x, &y, &comps, 4);
 | 
				
			||||||
@ -150,17 +163,21 @@ void Image::from_stream(Stream& stream)
 | 
				
			|||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m_stbi_ownership = true;
 | 
				
			||||||
 | 
						pixels = (Color*)data;
 | 
				
			||||||
	width = x;
 | 
						width = x;
 | 
				
			||||||
	height = y;
 | 
						height = y;
 | 
				
			||||||
	pixels = (Color*)data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Image::dispose()
 | 
					void Image::dispose()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	delete[] pixels;
 | 
						if (m_stbi_ownership)
 | 
				
			||||||
 | 
							stbi_image_free(pixels);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							delete[] pixels;
 | 
				
			||||||
	pixels = nullptr;
 | 
						pixels = nullptr;
 | 
				
			||||||
	width = height = 0;
 | 
						width = height = 0;
 | 
				
			||||||
 | 
						m_stbi_ownership = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Image::premultiply()
 | 
					void Image::premultiply()
 | 
				
			||||||
@ -202,7 +219,7 @@ bool Image::save_png(Stream& stream) const
 | 
				
			|||||||
		stbi_write_force_png_filter = 0;
 | 
							stbi_write_force_png_filter = 0;
 | 
				
			||||||
		stbi_write_png_compression_level = 0;
 | 
							stbi_write_png_compression_level = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (stbi_write_png_to_func(Engine_STBI_Write, &stream, width, height, 4, pixels, width * 4) != 0)
 | 
							if (stbi_write_png_to_func(Blah_STBI_Write, &stream, width, height, 4, pixels, width * 4) != 0)
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			Log::error("stbi_write_png_to_func failed");
 | 
								Log::error("stbi_write_png_to_func failed");
 | 
				
			||||||
@ -239,7 +256,7 @@ bool Image::save_jpg(Stream& stream, int quality) const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (stream.is_writable())
 | 
						if (stream.is_writable())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (stbi_write_jpg_to_func(Engine_STBI_Write, &stream, width, height, 4, pixels, quality) != 0)
 | 
							if (stbi_write_jpg_to_func(Blah_STBI_Write, &stream, width, height, 4, pixels, quality) != 0)
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			Log::error("stbi_write_jpg_to_func failed");
 | 
								Log::error("stbi_write_jpg_to_func failed");
 | 
				
			||||||
 | 
				
			|||||||
@ -7,8 +7,9 @@ namespace Blah
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	class Stream;
 | 
						class Stream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct Image
 | 
						class Image
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
		int width = 0;
 | 
							int width = 0;
 | 
				
			||||||
		int height = 0;
 | 
							int height = 0;
 | 
				
			||||||
		Color* pixels = nullptr;
 | 
							Color* pixels = nullptr;
 | 
				
			||||||
@ -34,5 +35,8 @@ namespace Blah
 | 
				
			|||||||
		bool save_jpg(Stream& stream, int quality) const;
 | 
							bool save_jpg(Stream& stream, int quality) const;
 | 
				
			||||||
		void get_pixels(Color* dest, const Point& destPos, const Point& destSize, RectI sourceRect);
 | 
							void get_pixels(Color* dest, const Point& destPos, const Point& destSize, RectI sourceRect);
 | 
				
			||||||
		Image get_sub_image(const RectI& sourceRect);
 | 
							Image get_sub_image(const RectI& sourceRect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
							bool m_stbi_ownership;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user