image calls proper delete/stbi_image_free

This commit is contained in:
Noel Berry 2020-10-19 00:49:37 -07:00
parent bf03bc815d
commit 28c142e8de
2 changed files with 53 additions and 32 deletions

View File

@ -14,18 +14,20 @@ 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
{
int Blah_STBI_Read(void* user, char* data, int size)
{ {
int64_t read = ((Stream*)user)->read(data, size); int64_t read = ((Stream*)user)->read(data, size);
return (int)read; 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();
@ -36,21 +38,24 @@ int Engine_STBI_Eof(void *user)
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()
{ {
if (m_stbi_ownership)
stbi_image_free(pixels);
else
delete[] pixels; 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");

View File

@ -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;
}; };
} }