Move decoder-agnostic love.image code out of the magpie backend folder.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2017-08-01 23:22:24 -03:00
parent 217552b5ff
commit 84d5d8b636
37 changed files with 631 additions and 921 deletions
+3 -3
View File
@@ -104,7 +104,7 @@ bool ASTCHandler::canParse(const filesystem::FileData *data)
return true;
}
StrongRef<CompressedImageData::Memory> ASTCHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedImageData::Slice>> &images, PixelFormat &format, bool &sRGB)
StrongRef<CompressedMemory> ASTCHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedSlice>> &images, PixelFormat &format, bool &sRGB)
{
if (!canParse(filedata))
throw love::Exception("Could not decode compressed data (not an .astc file?)");
@@ -129,12 +129,12 @@ StrongRef<CompressedImageData::Memory> ASTCHandler::parse(filesystem::FileData *
if (totalsize + sizeof(header) > filedata->getSize())
throw love::Exception("Could not parse .astc file: file is too small.");
StrongRef<CompressedImageData::Memory> memory(new CompressedImageData::Memory(totalsize), Acquire::NORETAIN);
StrongRef<CompressedMemory> memory(new CompressedMemory(totalsize), Acquire::NORETAIN);
// .astc files only store a single mipmap level.
memcpy(memory->data, (uint8 *) filedata->getData() + sizeof(ASTCHeader), totalsize);
images.emplace_back(new CompressedImageData::Slice(cformat, sizeX, sizeY, memory, 0, totalsize), Acquire::NORETAIN);
images.emplace_back(new CompressedSlice(cformat, sizeX, sizeY, memory, 0, totalsize), Acquire::NORETAIN);
format = cformat;
sRGB = false;
+4 -7
View File
@@ -18,11 +18,10 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H
#define LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H
#pragma once
#include "common/config.h"
#include "CompressedFormatHandler.h"
#include "image/CompressedFormatHandler.h"
namespace love
{
@@ -44,8 +43,8 @@ public:
// Implements CompressedFormatHandler.
bool canParse(const filesystem::FileData *data) override;
StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedImageData::Slice>> &images,
StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedSlice>> &images,
PixelFormat &format, bool &sRGB) override;
}; // ASTCHandler
@@ -53,5 +52,3 @@ public:
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H
@@ -1,76 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_COMPRESSED_HANDLER_H
#define LOVE_IMAGE_MAGPIE_COMPRESSED_HANDLER_H
// LOVE
#include "filesystem/FileData.h"
#include "image/CompressedImageData.h"
#include "common/Object.h"
namespace love
{
namespace image
{
namespace magpie
{
/**
* Base class for all CompressedImageData parser library interfaces.
* We inherit from love::Object to take advantage of reference counting...
**/
class CompressedFormatHandler : public love::Object
{
public:
CompressedFormatHandler() {}
virtual ~CompressedFormatHandler() {}
/**
* Determines whether a particular FileData can be parsed as CompressedImageData
* by this handler.
* @param data The data to parse.
**/
virtual bool canParse(const filesystem::FileData *data) = 0;
/**
* Parses compressed image filedata into a list of sub-images and returns
* a single block of memory containing all the images.
*
* @param[in] filedata The data to parse.
* @param[out] images The list of sub-images generated. Byte data is a pointer
* to the returned data.
* @param[out] format The format of the Compressed Data.
* @param[out] sRGB Whether the texture is sRGB-encoded.
*
* @return The single block of memory containing the parsed images.
**/
virtual StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedImageData::Slice>> &images,
PixelFormat &format, bool &sRGB) = 0;
}; // CompressedFormatHandler
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_COMPRESSED_HANDLER_H
@@ -1,85 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "CompressedImageData.h"
namespace love
{
namespace image
{
namespace magpie
{
CompressedImageData::CompressedImageData(std::list<CompressedFormatHandler *> formats, love::filesystem::FileData *filedata)
{
CompressedFormatHandler *parser = nullptr;
for (CompressedFormatHandler *handler : formats)
{
if (handler->canParse(filedata))
{
parser = handler;
break;
}
}
if (parser == nullptr)
throw love::Exception("Could not parse compressed data: Unknown format.");
memory = parser->parse(filedata, dataImages, format, sRGB);
if (memory == nullptr)
throw love::Exception("Could not parse compressed data.");
if (format == PIXELFORMAT_UNKNOWN)
throw love::Exception("Could not parse compressed data: Unknown format.");
if (dataImages.size() == 0 || memory->size == 0)
throw love::Exception("Could not parse compressed data: No valid data?");
}
CompressedImageData::CompressedImageData(const CompressedImageData &c)
{
format = c.format;
sRGB = c.sRGB;
memory.set(new Memory(c.memory->size), Acquire::NORETAIN);
memcpy(memory->data, c.memory->data, memory->size);
for (const auto &i : c.dataImages)
{
Slice *slice = new Slice(i->getFormat(), i->getWidth(), i->getHeight(), memory, i->getOffset(), i->getSize());
dataImages.push_back(slice);
slice->release();
}
}
CompressedImageData *CompressedImageData::clone() const
{
return new CompressedImageData(*this);
}
CompressedImageData::~CompressedImageData()
{
}
} // magpie
} // image
} // love
@@ -1,54 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_COMPRESSED_IMAGE_DATA_H
#define LOVE_IMAGE_MAGPIE_COMPRESSED_IMAGE_DATA_H
// LOVE
#include "CompressedFormatHandler.h"
#include "filesystem/FileData.h"
#include "image/CompressedImageData.h"
// C++
#include <list>
namespace love
{
namespace image
{
namespace magpie
{
class CompressedImageData : public love::image::CompressedImageData
{
public:
CompressedImageData(std::list<CompressedFormatHandler *> formats, love::filesystem::FileData *filedata);
CompressedImageData(const CompressedImageData &c);
virtual ~CompressedImageData();
virtual CompressedImageData *clone() const;
}; // CompressedImageData
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_COMPRESSED_IMAGE_DATA_H
+3 -2
View File
@@ -20,6 +20,7 @@
// LOVE
#include "EXRHandler.h"
#include "common/halffloat.h"
// tinyexr
#define TINYEXR_IMPLEMENTATION
@@ -41,7 +42,7 @@ bool EXRHandler::canDecode(love::filesystem::FileData *data)
return ParseEXRVersionFromMemory(&version, (const unsigned char *) data->getData(), data->getSize()) == TINYEXR_SUCCESS;
}
bool EXRHandler::canEncode(PixelFormat /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/)
bool EXRHandler::canEncode(PixelFormat /*rawFormat*/, EncodedFormat /*encodedFormat*/)
{
return false;
}
@@ -186,7 +187,7 @@ FormatHandler::DecodedImage EXRHandler::decode(love::filesystem::FileData *data)
return img;
}
FormatHandler::EncodedImage EXRHandler::encode(const DecodedImage & /*img*/, ImageData::EncodedFormat /*encodedFormat*/)
FormatHandler::EncodedImage EXRHandler::encode(const DecodedImage & /*img*/, EncodedFormat /*encodedFormat*/)
{
throw love::Exception("Invalid format.");
}
+4 -7
View File
@@ -18,10 +18,9 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_EXR_HANDLER_H
#define LOVE_IMAGE_MAGPIE_EXR_HANDLER_H
#pragma once
#include "FormatHandler.h"
#include "image/FormatHandler.h"
namespace love
{
@@ -40,10 +39,10 @@ public:
// Implements FormatHandler.
virtual bool canDecode(love::filesystem::FileData *data);
virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat);
virtual bool canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat);
virtual DecodedImage decode(love::filesystem::FileData *data);
virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format);
virtual EncodedImage encode(const DecodedImage &img, EncodedFormat format);
virtual void free(unsigned char *mem);
@@ -52,5 +51,3 @@ public:
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_EXR_HANDLER_H
@@ -1,67 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "FormatHandler.h"
#include "common/Exception.h"
namespace love
{
namespace image
{
namespace magpie
{
FormatHandler::FormatHandler()
{
}
FormatHandler::~FormatHandler()
{
}
bool FormatHandler::canDecode(love::filesystem::FileData* /*data*/)
{
return false;
}
bool FormatHandler::canEncode(PixelFormat /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/)
{
return false;
}
FormatHandler::DecodedImage FormatHandler::decode(love::filesystem::FileData* /*data*/)
{
throw love::Exception("Image decoding is not implemented for this format backend.");
}
FormatHandler::EncodedImage FormatHandler::encode(const DecodedImage& /*img*/, ImageData::EncodedFormat /*format*/)
{
throw love::Exception("Image encoding is not implemented for this format backend.");
}
void FormatHandler::free(unsigned char *mem)
{
delete[] mem;
}
} // magpie
} // image
} // love
-107
View File
@@ -1,107 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H
#define LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H
// LOVE
#include "image/ImageData.h"
#include "filesystem/FileData.h"
#include "common/Object.h"
namespace love
{
namespace image
{
namespace magpie
{
/**
* Base class for all ImageData encoder/decoder library interfaces.
* We inherit from love::Object to take advantage of reference counting...
**/
class FormatHandler : public love::Object
{
public:
// Raw RGBA pixel data.
struct DecodedImage
{
PixelFormat format = PIXELFORMAT_RGBA8;
int width = 0;
int height = 0;
size_t size = 0;
unsigned char *data = nullptr;
};
// Pixel data encoded in a particular format.
struct EncodedImage
{
size_t size = 0;
unsigned char *data = nullptr;
};
/**
* The default constructor is called when the Image module is initialized.
**/
FormatHandler();
/**
* The destructor is called when the Image module is uninitialized.
**/
virtual ~FormatHandler();
/**
* Whether this format handler can decode a particular FileData.
**/
virtual bool canDecode(love::filesystem::FileData *data);
/**
* Whether this format handler can encode to a particular format.
**/
virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat);
/**
* Decodes an image from its encoded form into raw pixel data.
* @param data The encoded data to decode.
* @return The decoded pixel data.
**/
virtual DecodedImage decode(love::filesystem::FileData *data);
/**
* Encodes an image from raw pixel data into a particular format.
* @param img The raw image data to encode.
* @param format The format to encode to.
* @return The encoded image data.
**/
virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format);
/**
* Frees memory allocated by the format handler.
**/
virtual void free(unsigned char *mem);
}; // FormatHandler
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H
-118
View File
@@ -1,118 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "common/config.h"
#include "Image.h"
#include "ImageData.h"
#include "CompressedImageData.h"
#include "PNGHandler.h"
#include "STBHandler.h"
#include "EXRHandler.h"
#include "ddsHandler.h"
#include "PVRHandler.h"
#include "KTXHandler.h"
#include "PKMHandler.h"
#include "ASTCHandler.h"
namespace love
{
namespace image
{
namespace magpie
{
Image::Image()
{
halfInit(); // Makes sure half-float conversions can be used.
formatHandlers = {
new PNGHandler,
new STBHandler,
new EXRHandler,
};
compressedFormatHandlers = {
new DDSHandler,
new PVRHandler,
new KTXHandler,
new PKMHandler,
new ASTCHandler,
};
}
Image::~Image()
{
// ImageData objects reference the FormatHandlers in our list, so we should
// release them instead of deleting them completely here.
for (FormatHandler *handler : formatHandlers)
handler->release();
for (CompressedFormatHandler *handler : compressedFormatHandlers)
handler->release();
}
const char *Image::getName() const
{
return "love.image.magpie";
}
love::image::ImageData *Image::newImageData(love::filesystem::FileData *data)
{
return new ImageData(data);
}
love::image::ImageData *Image::newImageData(int width, int height, PixelFormat format)
{
return new ImageData(width, height, format);
}
love::image::ImageData *Image::newImageData(int width, int height, PixelFormat format, void *data, bool own)
{
return new ImageData(width, height, format, data, own);
}
love::image::CompressedImageData *Image::newCompressedData(love::filesystem::FileData *data)
{
return new CompressedImageData(compressedFormatHandlers, data);
}
bool Image::isCompressed(love::filesystem::FileData *data)
{
for (CompressedFormatHandler *handler : compressedFormatHandlers)
{
if (handler->canParse(data))
return true;
}
return false;
}
const std::list<FormatHandler *> &Image::getFormatHandlers() const
{
return formatHandlers;
}
} // magpie
} // image
} // love
-78
View File
@@ -1,78 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_IMAGE_H
#define LOVE_IMAGE_MAGPIE_IMAGE_H
// LOVE
#include "image/Image.h"
#include "FormatHandler.h"
#include "CompressedFormatHandler.h"
// C++
#include <list>
namespace love
{
namespace image
{
namespace magpie
{
/**
* Similar to love.sound's Lullaby module, love.image.magpie interfaces with
* multiple image libraries and determines the correct one to use on a
* per-image basis at runtime.
**/
class Image final : public love::image::Image
{
public:
Image();
~Image();
// Implements Module.
const char *getName() const override;
love::image::ImageData *newImageData(love::filesystem::FileData *data) override;
love::image::ImageData *newImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8) override;
love::image::ImageData *newImageData(int width, int height, PixelFormat format, void *data, bool own = false) override;
love::image::CompressedImageData *newCompressedData(love::filesystem::FileData *data) override;
bool isCompressed(love::filesystem::FileData *data) override;
const std::list<FormatHandler *> &getFormatHandlers() const;
private:
// Image format handlers we can use for decoding and encoding ImageData.
std::list<FormatHandler *> formatHandlers;
// Compressed image format handers we can use for parsing CompressedImageData.
std::list<CompressedFormatHandler *> compressedFormatHandlers;
}; // Image
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_IMAGE_H
-239
View File
@@ -1,239 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "ImageData.h"
#include "Image.h"
#include "filesystem/Filesystem.h"
namespace love
{
namespace image
{
namespace magpie
{
ImageData::ImageData(love::filesystem::FileData *data)
{
decode(data);
}
ImageData::ImageData(int width, int height, PixelFormat format)
{
if (!validPixelFormat(format))
throw love::Exception("Unsupported pixel format for ImageData");
this->width = width;
this->height = height;
this->format = format;
create(width, height, format);
// Set to black/transparency.
memset(data, 0, getSize());
}
ImageData::ImageData(int width, int height, PixelFormat format, void *data, bool own)
{
if (!validPixelFormat(format))
throw love::Exception("Unsupported pixel format for ImageData");
this->width = width;
this->height = height;
this->format = format;
if (own)
this->data = (unsigned char *) data;
else
create(width, height, format, data);
}
ImageData::ImageData(const ImageData &c)
{
width = c.width;
height = c.height;
format = c.format;
create(width, height, format, c.getData());
}
ImageData::~ImageData()
{
if (decodeHandler.get())
decodeHandler->free(data);
else
delete[] data;
}
love::image::ImageData *ImageData::clone() const
{
return new ImageData(*this);
}
void ImageData::create(int width, int height, PixelFormat format, void *data)
{
size_t datasize = width * height * getPixelFormatSize(format);
try
{
this->data = new unsigned char[datasize];
}
catch(std::bad_alloc &)
{
throw love::Exception("Out of memory");
}
if (data)
memcpy(this->data, data, datasize);
decodeHandler = nullptr;
this->format = format;
}
void ImageData::decode(love::filesystem::FileData *data)
{
FormatHandler *decoder = nullptr;
FormatHandler::DecodedImage decodedimage;
auto module = dynamic_cast<Image *>(Module::getInstance<love::image::Image>(Module::M_IMAGE));
if (module == nullptr)
throw love::Exception("love.image must be loaded in order to decode an ImageData.");
for (FormatHandler *handler : module->getFormatHandlers())
{
if (handler->canDecode(data))
{
decoder = handler;
break;
}
}
if (decoder)
decodedimage = decoder->decode(data);
if (decodedimage.data == nullptr)
{
const std::string &name = data->getFilename();
throw love::Exception("Could not decode file '%s' to ImageData: unsupported file format", name.c_str());
}
if (decodedimage.size != decodedimage.width * decodedimage.height * getPixelFormatSize(decodedimage.format))
{
decoder->free(decodedimage.data);
throw love::Exception("Could not convert image!");
}
// Clean up any old data.
if (decodeHandler)
decodeHandler->free(this->data);
else
delete[] this->data;
this->width = decodedimage.width;
this->height = decodedimage.height;
this->data = decodedimage.data;
this->format = decodedimage.format;
decodeHandler = decoder;
}
love::filesystem::FileData *ImageData::encode(EncodedFormat encodedFormat, const char *filename, bool writefile)
{
FormatHandler *encoder = nullptr;
FormatHandler::EncodedImage encodedimage;
FormatHandler::DecodedImage rawimage;
rawimage.width = width;
rawimage.height = height;
rawimage.size = getSize();
rawimage.data = data;
rawimage.format = format;
auto module = dynamic_cast<Image *>(Module::getInstance<love::image::Image>(Module::M_IMAGE));
if (module == nullptr)
throw love::Exception("love.image must be loaded in order to encode an ImageData.");
for (FormatHandler *handler : module->getFormatHandlers())
{
if (handler->canEncode(format, encodedFormat))
{
encoder = handler;
break;
}
}
if (encoder != nullptr)
{
thread::Lock lock(mutex);
encodedimage = encoder->encode(rawimage, encodedFormat);
}
if (encoder == nullptr || encodedimage.data == nullptr)
{
const char *fname = "unknown";
love::getConstant(format, fname);
throw love::Exception("No suitable image encoder for %s format.", fname);
}
love::filesystem::FileData *filedata = nullptr;
try
{
filedata = new love::filesystem::FileData(encodedimage.size, filename);
}
catch (love::Exception &)
{
encoder->free(encodedimage.data);
throw;
}
memcpy(filedata->getData(), encodedimage.data, encodedimage.size);
encoder->free(encodedimage.data);
if (writefile)
{
auto fs = Module::getInstance<filesystem::Filesystem>(Module::M_FILESYSTEM);
if (fs == nullptr)
{
filedata->release();
throw love::Exception("love.filesystem must be loaded in order to write an encoded ImageData to a file.");
}
try
{
fs->write(filename, filedata->getData(), filedata->getSize());
}
catch (love::Exception &)
{
filedata->release();
throw;
}
}
return filedata;
}
} // magpie
} // image
} // love
-70
View File
@@ -1,70 +0,0 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_IMAGE_DATA_H
#define LOVE_IMAGE_MAGPIE_IMAGE_DATA_H
// LOVE
#include "FormatHandler.h"
#include "image/ImageData.h"
// C++
#include <list>
namespace love
{
namespace image
{
namespace magpie
{
class ImageData : public love::image::ImageData
{
public:
ImageData(love::filesystem::FileData *data);
ImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8);
ImageData(int width, int height, PixelFormat format, void *data, bool own);
ImageData(const ImageData &c);
virtual ~ImageData();
// Implements image::ImageData.
virtual love::image::ImageData *clone() const;
virtual love::filesystem::FileData *encode(EncodedFormat encodedFormat, const char *filename, bool writefile);
private:
// Create imagedata. Initialize with data if not null.
void create(int width, int height, PixelFormat format, void *data = nullptr);
// Decode and load an encoded format.
void decode(love::filesystem::FileData *data);
// The format handler that was used to decode the ImageData. We need to know
// this so we can properly delete memory allocated by the decoder.
StrongRef<FormatHandler> decodeHandler;
}; // ImageData
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_IMAGE_DATA_H
+4 -4
View File
@@ -297,7 +297,7 @@ bool KTXHandler::canParse(const filesystem::FileData *data)
return true;
}
StrongRef<CompressedImageData::Memory> KTXHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedImageData::Slice>> &images, PixelFormat &format, bool &sRGB)
StrongRef<CompressedMemory> KTXHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedSlice>> &images, PixelFormat &format, bool &sRGB)
{
if (!canParse(filedata))
throw love::Exception("Could not decode compressed data (not a KTX file?)");
@@ -353,8 +353,8 @@ StrongRef<CompressedImageData::Memory> KTXHandler::parse(filesystem::FileData *f
fileoffset += mipsizepadded;
}
StrongRef<CompressedImageData::Memory> memory;
memory.set(new CompressedImageData::Memory(totalsize), Acquire::NORETAIN);
StrongRef<CompressedMemory> memory;
memory.set(new CompressedMemory(totalsize), Acquire::NORETAIN);
// Reset the file offset to the start of the file's image data.
fileoffset = sizeof(KTXHeader) + header.bytesOfKeyValueData;
@@ -377,7 +377,7 @@ StrongRef<CompressedImageData::Memory> KTXHandler::parse(filesystem::FileData *f
memcpy(memory->data + dataoffset, filebytes + fileoffset, mipsize);
auto slice = new CompressedImageData::Slice(cformat, width, height, memory, dataoffset, mipsize);
auto slice = new CompressedSlice(cformat, width, height, memory, dataoffset, mipsize);
images.push_back(slice);
slice->release();
+4 -7
View File
@@ -18,11 +18,10 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_KTX_HANDLER_H
#define LOVE_IMAGE_MAGPIE_KTX_HANDLER_H
#pragma once
#include "common/config.h"
#include "CompressedFormatHandler.h"
#include "image/CompressedFormatHandler.h"
namespace love
{
@@ -43,8 +42,8 @@ public:
// Implements CompressedFormatHandler.
bool canParse(const filesystem::FileData *data) override;
StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedImageData::Slice>> &images,
StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedSlice>> &images,
PixelFormat &format, bool &sRGB) override;
}; // KTXHandler
@@ -52,5 +51,3 @@ public:
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_KTX_HANDLER_H
+4 -4
View File
@@ -113,7 +113,7 @@ bool PKMHandler::canParse(const filesystem::FileData *data)
return true;
}
StrongRef<CompressedImageData::Memory> PKMHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedImageData::Slice>> &images, PixelFormat &format, bool &sRGB)
StrongRef<CompressedMemory> PKMHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedSlice>> &images, PixelFormat &format, bool &sRGB)
{
if (!canParse(filedata))
throw love::Exception("Could not decode compressed data (not a PKM file?)");
@@ -134,8 +134,8 @@ StrongRef<CompressedImageData::Memory> PKMHandler::parse(filesystem::FileData *f
// The rest of the file after the header is all texture data.
size_t totalsize = filedata->getSize() - sizeof(PKMHeader);
StrongRef<CompressedImageData::Memory> memory;
memory.set(new CompressedImageData::Memory(totalsize), Acquire::NORETAIN);
StrongRef<CompressedMemory> memory;
memory.set(new CompressedMemory(totalsize), Acquire::NORETAIN);
// PKM files only store a single mipmap level.
memcpy(memory->data, (uint8 *) filedata->getData() + sizeof(PKMHeader), totalsize);
@@ -145,7 +145,7 @@ StrongRef<CompressedImageData::Memory> PKMHandler::parse(filesystem::FileData *f
int width = header.widthBig;
int height = header.heightBig;
images.emplace_back(new CompressedImageData::Slice(cformat, width, height, memory, 0, totalsize), Acquire::NORETAIN);
images.emplace_back(new CompressedSlice(cformat, width, height, memory, 0, totalsize), Acquire::NORETAIN);
format = cformat;
sRGB = false;
+4 -7
View File
@@ -18,11 +18,10 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_PKM_HANDLER_H
#define LOVE_IMAGE_MAGPIE_PKM_HANDLER_H
#pragma once
#include "common/config.h"
#include "CompressedFormatHandler.h"
#include "image/CompressedFormatHandler.h"
namespace love
{
@@ -43,8 +42,8 @@ public:
// Implements CompressedFormatHandler.
bool canParse(const filesystem::FileData *data) override;
StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedImageData::Slice>> &images,
StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedSlice>> &images,
PixelFormat &format, bool &sRGB) override;
}; // PKMHandler
@@ -52,5 +51,3 @@ public:
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_PKM_HANDLER_H
+3 -3
View File
@@ -140,9 +140,9 @@ bool PNGHandler::canDecode(love::filesystem::FileData *data)
return status == 0 && width > 0 && height > 0;
}
bool PNGHandler::canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat)
bool PNGHandler::canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat)
{
return encodedFormat == ImageData::ENCODED_PNG
return encodedFormat == ENCODED_PNG
&& (rawFormat == PIXELFORMAT_RGBA8 || rawFormat == PIXELFORMAT_RGBA16);
}
@@ -199,7 +199,7 @@ PNGHandler::DecodedImage PNGHandler::decode(love::filesystem::FileData *fdata)
return img;
}
PNGHandler::EncodedImage PNGHandler::encode(const DecodedImage &img, ImageData::EncodedFormat encodedFormat)
FormatHandler::EncodedImage PNGHandler::encode(const DecodedImage &img, EncodedFormat encodedFormat)
{
if (!canEncode(img.format, encodedFormat))
throw love::Exception("PNG encoder cannot encode to non-PNG format.");
+4 -7
View File
@@ -18,11 +18,10 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_PNG_HANDLER_H
#define LOVE_IMAGE_MAGPIE_PNG_HANDLER_H
#pragma once
// LOVE
#include "FormatHandler.h"
#include "image/FormatHandler.h"
namespace love
{
@@ -41,10 +40,10 @@ public:
// Implements FormatHandler.
virtual bool canDecode(love::filesystem::FileData *data);
virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat);
virtual bool canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat);
virtual DecodedImage decode(love::filesystem::FileData *data);
virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format);
virtual EncodedImage encode(const DecodedImage &img, EncodedFormat format);
virtual void free(unsigned char *mem);
@@ -53,5 +52,3 @@ public:
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_PNG_HANDLER_H
+4 -4
View File
@@ -474,7 +474,7 @@ bool PVRHandler::canParse(const filesystem::FileData *data)
return false;
}
StrongRef<CompressedImageData::Memory> PVRHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedImageData::Slice>> &images, PixelFormat &format, bool &sRGB)
StrongRef<CompressedMemory> PVRHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedSlice>> &images, PixelFormat &format, bool &sRGB)
{
if (!canParse(filedata))
throw love::Exception("Could not decode compressed data (not a PVR file?)");
@@ -524,8 +524,8 @@ StrongRef<CompressedImageData::Memory> PVRHandler::parse(filesystem::FileData *f
if (filedata->getSize() < fileoffset + totalsize)
throw love::Exception("Could not parse PVR file: invalid size calculation.");
StrongRef<CompressedImageData::Memory> memory;
memory.set(new CompressedImageData::Memory(totalsize), Acquire::NORETAIN);
StrongRef<CompressedMemory> memory;
memory.set(new CompressedMemory(totalsize), Acquire::NORETAIN);
size_t curoffset = 0;
const uint8 *filebytes = (uint8 *) filedata->getData() + fileoffset;
@@ -542,7 +542,7 @@ StrongRef<CompressedImageData::Memory> PVRHandler::parse(filesystem::FileData *f
memcpy(memory->data + curoffset, filebytes + curoffset, mipsize);
auto slice = new CompressedImageData::Slice(cformat, width, height, memory, curoffset, mipsize);
auto slice = new CompressedSlice(cformat, width, height, memory, curoffset, mipsize);
images.push_back(slice);
slice->release();
+4 -7
View File
@@ -18,12 +18,11 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_PVR_HANDLER_H
#define LOVE_IMAGE_MAGPIE_PVR_HANDLER_H
#pragma once
// LOVE
#include "common/config.h"
#include "CompressedFormatHandler.h"
#include "image/CompressedFormatHandler.h"
namespace love
{
@@ -41,8 +40,8 @@ public:
// Implements CompressedFormatHandler.
bool canParse(const filesystem::FileData *data) override;
StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedImageData::Slice>> &images,
StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedSlice>> &images,
PixelFormat &format, bool &sRGB) override;
}; // PVRHandler
@@ -50,5 +49,3 @@ public:
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_PVR_HANDLER_H
+4 -3
View File
@@ -20,6 +20,7 @@
// LOVE
#include "STBHandler.h"
#include "image/ImageData.h"
static void loveSTBIAssert(bool test, const char *teststr)
{
@@ -60,9 +61,9 @@ bool STBHandler::canDecode(love::filesystem::FileData *data)
return status == 1 && w > 0 && h > 0;
}
bool STBHandler::canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat)
bool STBHandler::canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat)
{
return encodedFormat == ImageData::ENCODED_TGA && rawFormat == PIXELFORMAT_RGBA8;
return encodedFormat == ENCODED_TGA && rawFormat == PIXELFORMAT_RGBA8;
}
FormatHandler::DecodedImage STBHandler::decode(love::filesystem::FileData *data)
@@ -97,7 +98,7 @@ FormatHandler::DecodedImage STBHandler::decode(love::filesystem::FileData *data)
return img;
}
FormatHandler::EncodedImage STBHandler::encode(const DecodedImage &img, ImageData::EncodedFormat encodedFormat)
FormatHandler::EncodedImage STBHandler::encode(const DecodedImage &img, EncodedFormat encodedFormat)
{
if (!canEncode(img.format, encodedFormat))
throw love::Exception("Invalid format.");
+8 -11
View File
@@ -18,10 +18,9 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_STB_HANDLER_H
#define LOVE_IMAGE_MAGPIE_STB_HANDLER_H
#pragma once
#include "FormatHandler.h"
#include "image/FormatHandler.h"
namespace love
{
@@ -37,24 +36,22 @@ namespace magpie
* We could use stb_image to decode PNG as well, but performance and
* comprehensive format support is lacking compared to some alternatives.
**/
class STBHandler : public FormatHandler
class STBHandler final : public FormatHandler
{
public:
// Implements FormatHandler.
virtual bool canDecode(love::filesystem::FileData *data);
virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat);
bool canDecode(love::filesystem::FileData *data) override;
bool canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat) override;
virtual DecodedImage decode(love::filesystem::FileData *data);
virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format);
DecodedImage decode(love::filesystem::FileData *data) override;
EncodedImage encode(const DecodedImage &img, EncodedFormat format) override;
virtual void free(unsigned char *mem);
void free(unsigned char *mem) override;
}; // STBHandler
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_STB_HANDLER_H
+4 -4
View File
@@ -32,7 +32,7 @@ bool DDSHandler::canParse(const filesystem::FileData *data)
return dds::isCompressedDDS(data->getData(), data->getSize());
}
StrongRef<CompressedImageData::Memory> DDSHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedImageData::Slice>> &images, PixelFormat &format, bool &sRGB)
StrongRef<CompressedMemory> DDSHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedSlice>> &images, PixelFormat &format, bool &sRGB)
{
if (!dds::isDDS(filedata->getData(), filedata->getSize()))
throw love::Exception("Could not decode compressed data (not a DDS file?)");
@@ -40,7 +40,7 @@ StrongRef<CompressedImageData::Memory> DDSHandler::parse(filesystem::FileData *f
PixelFormat texformat = PIXELFORMAT_UNKNOWN;
bool isSRGB = false;
StrongRef<CompressedImageData::Memory> memory;
StrongRef<CompressedMemory> memory;
size_t dataSize = 0;
images.clear();
@@ -63,7 +63,7 @@ StrongRef<CompressedImageData::Memory> DDSHandler::parse(filesystem::FileData *f
dataSize += img->dataSize;
}
memory.set(new CompressedImageData::Memory(dataSize), Acquire::NORETAIN);
memory.set(new CompressedMemory(dataSize), Acquire::NORETAIN);
size_t dataOffset = 0;
@@ -76,7 +76,7 @@ StrongRef<CompressedImageData::Memory> DDSHandler::parse(filesystem::FileData *f
// Copy the mipmap image from the FileData to our block of memory.
memcpy(memory->data + dataOffset, img->data, img->dataSize);
auto slice = new CompressedImageData::Slice(texformat, img->width, img->height, memory, dataOffset, img->dataSize);
auto slice = new CompressedSlice(texformat, img->width, img->height, memory, dataOffset, img->dataSize);
images.emplace_back(slice, Acquire::NORETAIN);
dataOffset += img->dataSize;
+4 -7
View File
@@ -18,11 +18,10 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_IMAGE_MAGPIE_DDS_HANDLER_H
#define LOVE_IMAGE_MAGPIE_DDS_HANDLER_H
#pragma once
// LOVE
#include "CompressedFormatHandler.h"
#include "image/CompressedFormatHandler.h"
// dds parser
#include "ddsparse/ddsparse.h"
@@ -49,8 +48,8 @@ public:
// Implements CompressedFormatHandler.
bool canParse(const filesystem::FileData *data) override;
StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedImageData::Slice>> &images,
StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
std::vector<StrongRef<CompressedSlice>> &images,
PixelFormat &format, bool &sRGB) override;
private:
@@ -62,5 +61,3 @@ private:
} // magpie
} // image
} // love
#endif // LOVE_IMAGE_MAGPIE_DDS_HANDLER_H