mirror of
https://github.com/love2d/love.git
synced 2026-08-18 11:44:15 +02:00
ImageData (and Images loaded from them) now support different data formats. Resolves issue #1048.
Currently exposed formats are rgba8 and rgba16 (normalized), and rgba16f and rgba32f (floating-point). Some systems, especially mobile ones, won't support every format when creating a love.graphics Image. Use love.graphics.getRawImageFormats to check for support. love.image.newImageData now takes an optional format parameter as its third argument when creating an empty sized ImageData. It defaults to rgba8. 16-bit PNGs, .hdr images, and floating-point OpenEXR images can now be loaded via love.image.newImageData and love.graphics.newImage. --HG-- branch : minor
This commit is contained in:
@@ -28,8 +28,8 @@ namespace image
|
||||
namespace magpie
|
||||
{
|
||||
|
||||
ImageData::ImageData(std::list<FormatHandler *> formats, love::filesystem::FileData *data)
|
||||
: formatHandlers(formats)
|
||||
ImageData::ImageData(std::list<FormatHandler *> formatHandlers, love::filesystem::FileData *data)
|
||||
: formatHandlers(formatHandlers)
|
||||
, decodeHandler(nullptr)
|
||||
{
|
||||
for (FormatHandler *handler : formatHandlers)
|
||||
@@ -38,8 +38,8 @@ ImageData::ImageData(std::list<FormatHandler *> formats, love::filesystem::FileD
|
||||
decode(data);
|
||||
}
|
||||
|
||||
ImageData::ImageData(std::list<FormatHandler *> formats, int width, int height)
|
||||
: formatHandlers(formats)
|
||||
ImageData::ImageData(std::list<FormatHandler *> formatHandlers, int width, int height, Format format)
|
||||
: formatHandlers(formatHandlers)
|
||||
, decodeHandler(nullptr)
|
||||
{
|
||||
for (FormatHandler *handler : formatHandlers)
|
||||
@@ -47,15 +47,16 @@ ImageData::ImageData(std::list<FormatHandler *> formats, int width, int height)
|
||||
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->format = format;
|
||||
|
||||
create(width, height);
|
||||
create(width, height, format);
|
||||
|
||||
// Set to black/transparency.
|
||||
memset(data, 0, width*height*sizeof(pixel));
|
||||
memset(data, 0, getSize());
|
||||
}
|
||||
|
||||
ImageData::ImageData(std::list<FormatHandler *> formats, int width, int height, void *data, bool own)
|
||||
: formatHandlers(formats)
|
||||
ImageData::ImageData(std::list<FormatHandler *> formatHandlers, int width, int height, Format format, void *data, bool own)
|
||||
: formatHandlers(formatHandlers)
|
||||
, decodeHandler(nullptr)
|
||||
{
|
||||
for (FormatHandler *handler : formatHandlers)
|
||||
@@ -63,11 +64,12 @@ ImageData::ImageData(std::list<FormatHandler *> formats, int width, int height,
|
||||
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->format = format;
|
||||
|
||||
if (own)
|
||||
this->data = (unsigned char *) data;
|
||||
else
|
||||
create(width, height, data);
|
||||
create(width, height, format, data);
|
||||
}
|
||||
|
||||
ImageData::~ImageData()
|
||||
@@ -81,11 +83,13 @@ ImageData::~ImageData()
|
||||
handler->release();
|
||||
}
|
||||
|
||||
void ImageData::create(int width, int height, void *data)
|
||||
void ImageData::create(int width, int height, Format format, void *data)
|
||||
{
|
||||
size_t datasize = width * height * getPixelSize(format);
|
||||
|
||||
try
|
||||
{
|
||||
this->data = new unsigned char[width*height*sizeof(pixel)];
|
||||
this->data = new unsigned char[datasize];
|
||||
}
|
||||
catch(std::bad_alloc &)
|
||||
{
|
||||
@@ -93,9 +97,10 @@ void ImageData::create(int width, int height, void *data)
|
||||
}
|
||||
|
||||
if (data)
|
||||
memcpy(this->data, data, width*height*sizeof(pixel));
|
||||
memcpy(this->data, data, datasize);
|
||||
|
||||
decodeHandler = nullptr;
|
||||
this->format = format;
|
||||
}
|
||||
|
||||
void ImageData::decode(love::filesystem::FileData *data)
|
||||
@@ -121,8 +126,7 @@ void ImageData::decode(love::filesystem::FileData *data)
|
||||
throw love::Exception("Could not decode file '%s' to ImageData: unsupported file format", name.c_str());
|
||||
}
|
||||
|
||||
// The decoder *must* output a 32 bits-per-pixel image.
|
||||
if (decodedimage.size != decodedimage.width*decodedimage.height*sizeof(pixel))
|
||||
if (decodedimage.size != decodedimage.width * decodedimage.height * getPixelSize(decodedimage.format))
|
||||
{
|
||||
decoder->free(decodedimage.data);
|
||||
throw love::Exception("Could not convert image!");
|
||||
@@ -134,14 +138,15 @@ void ImageData::decode(love::filesystem::FileData *data)
|
||||
else
|
||||
delete[] this->data;
|
||||
|
||||
this->width = decodedimage.width;
|
||||
this->width = decodedimage.width;
|
||||
this->height = decodedimage.height;
|
||||
this->data = decodedimage.data;
|
||||
this->data = decodedimage.data;
|
||||
this->format = decodedimage.format;
|
||||
|
||||
decodeHandler = decoder;
|
||||
}
|
||||
|
||||
love::filesystem::FileData *ImageData::encode(EncodedFormat format, const char *filename)
|
||||
love::filesystem::FileData *ImageData::encode(EncodedFormat encodedFormat, const char *filename)
|
||||
{
|
||||
FormatHandler *encoder = nullptr;
|
||||
FormatHandler::EncodedImage encodedimage;
|
||||
@@ -149,12 +154,12 @@ love::filesystem::FileData *ImageData::encode(EncodedFormat format, const char *
|
||||
|
||||
rawimage.width = width;
|
||||
rawimage.height = height;
|
||||
rawimage.size = width*height*sizeof(pixel);
|
||||
rawimage.size = getSize();
|
||||
rawimage.data = data;
|
||||
|
||||
for (FormatHandler *handler : formatHandlers)
|
||||
{
|
||||
if (handler->canEncode(format))
|
||||
if (handler->canEncode(format, encodedFormat))
|
||||
{
|
||||
encoder = handler;
|
||||
break;
|
||||
@@ -164,7 +169,7 @@ love::filesystem::FileData *ImageData::encode(EncodedFormat format, const char *
|
||||
if (encoder != nullptr)
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
encodedimage = encoder->encode(rawimage, format);
|
||||
encodedimage = encoder->encode(rawimage, encodedFormat);
|
||||
}
|
||||
|
||||
if (encoder == nullptr || encodedimage.data == nullptr)
|
||||
|
||||
Reference in New Issue
Block a user