mirror of
https://github.com/love2d/love.git
synced 2026-08-17 02:58:31 +02:00
Move decoder-agnostic love.image code out of the magpie backend folder.
--HG-- branch : minor
This commit is contained in:
@@ -447,7 +447,7 @@ static int screenshotSaveToFile(lua_State *L)
|
||||
const char *filename = luaL_checkstring(L, lua_upvalueindex(1));
|
||||
const char *ext = luaL_checkstring(L, lua_upvalueindex(2));
|
||||
|
||||
image::ImageData::EncodedFormat format;
|
||||
image::FormatHandler::EncodedFormat format;
|
||||
if (!image::ImageData::getConstant(ext, format))
|
||||
return 0;
|
||||
|
||||
@@ -478,7 +478,7 @@ int w_captureScreenshot(lua_State *L)
|
||||
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||
|
||||
image::ImageData::EncodedFormat format;
|
||||
image::FormatHandler::EncodedFormat format;
|
||||
if (!image::ImageData::getConstant(ext.c_str(), format))
|
||||
return luaL_error(L, "Invalid encoded image format: %s", ext.c_str());
|
||||
|
||||
|
||||
+9
-15
@@ -18,20 +18,17 @@
|
||||
* 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
|
||||
#pragma once
|
||||
|
||||
// LOVE
|
||||
#include "filesystem/FileData.h"
|
||||
#include "image/CompressedImageData.h"
|
||||
#include "common/Object.h"
|
||||
#include "filesystem/FileData.h"
|
||||
#include "CompressedSlice.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace image
|
||||
{
|
||||
namespace magpie
|
||||
{
|
||||
|
||||
/**
|
||||
* Base class for all CompressedImageData parser library interfaces.
|
||||
@@ -45,8 +42,8 @@ public:
|
||||
virtual ~CompressedFormatHandler() {}
|
||||
|
||||
/**
|
||||
* Determines whether a particular FileData can be parsed as CompressedImageData
|
||||
* by this handler.
|
||||
* 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;
|
||||
@@ -56,21 +53,18 @@ public:
|
||||
* 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] 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,
|
||||
virtual StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
|
||||
std::vector<StrongRef<CompressedSlice>> &images,
|
||||
PixelFormat &format, bool &sRGB) = 0;
|
||||
|
||||
}; // CompressedFormatHandler
|
||||
|
||||
} // magpie
|
||||
} // image
|
||||
} // love
|
||||
|
||||
#endif // LOVE_IMAGE_MAGPIE_COMPRESSED_HANDLER_H
|
||||
@@ -27,58 +27,54 @@ namespace image
|
||||
|
||||
love::Type CompressedImageData::type("CompressedImageData", &Data::type);
|
||||
|
||||
CompressedImageData::Memory::Memory(size_t size)
|
||||
: data(nullptr)
|
||||
, size(size)
|
||||
{
|
||||
try
|
||||
{
|
||||
data = new uint8[size];
|
||||
}
|
||||
catch (std::exception &)
|
||||
{
|
||||
throw love::Exception("Out of memory.");
|
||||
}
|
||||
}
|
||||
|
||||
CompressedImageData::Memory::~Memory()
|
||||
{
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
CompressedImageData::Slice::Slice(PixelFormat format, int width, int height, Memory *memory, size_t offset, size_t size)
|
||||
: memory(memory)
|
||||
, offset(offset)
|
||||
, dataSize(size)
|
||||
{
|
||||
this->format = format;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
}
|
||||
|
||||
CompressedImageData::Slice::Slice(const Slice &s)
|
||||
: memory(s.memory)
|
||||
, offset(s.offset)
|
||||
, dataSize(s.dataSize)
|
||||
{
|
||||
this->format = s.getFormat();
|
||||
this->width = s.getWidth();
|
||||
this->height = s.getHeight();
|
||||
}
|
||||
|
||||
CompressedImageData::Slice::~Slice()
|
||||
{
|
||||
}
|
||||
|
||||
CompressedImageData::Slice *CompressedImageData::Slice::clone() const
|
||||
{
|
||||
return new Slice(*this);
|
||||
}
|
||||
|
||||
CompressedImageData::CompressedImageData()
|
||||
CompressedImageData::CompressedImageData(const std::list<CompressedFormatHandler *> &formats, love::filesystem::FileData *filedata)
|
||||
: format(PIXELFORMAT_UNKNOWN)
|
||||
, sRGB(false)
|
||||
{
|
||||
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 CompressedMemory(c.memory->size), Acquire::NORETAIN);
|
||||
memcpy(memory->data, c.memory->data, memory->size);
|
||||
|
||||
for (const auto &i : c.dataImages)
|
||||
{
|
||||
auto slice = new CompressedSlice(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()
|
||||
@@ -143,7 +139,7 @@ bool CompressedImageData::isSRGB() const
|
||||
return sRGB;
|
||||
}
|
||||
|
||||
CompressedImageData::Slice *CompressedImageData::getSlice(int slice, int miplevel) const
|
||||
CompressedSlice *CompressedImageData::getSlice(int slice, int miplevel) const
|
||||
{
|
||||
checkSliceExists(slice, miplevel);
|
||||
|
||||
|
||||
@@ -25,10 +25,13 @@
|
||||
#include "common/StringMap.h"
|
||||
#include "common/int.h"
|
||||
#include "common/pixelformat.h"
|
||||
#include "ImageDataBase.h"
|
||||
#include "filesystem/FileData.h"
|
||||
#include "CompressedSlice.h"
|
||||
#include "CompressedFormatHandler.h"
|
||||
|
||||
// STL
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -44,53 +47,16 @@ class CompressedImageData : public Data
|
||||
{
|
||||
public:
|
||||
|
||||
class Memory : public Object
|
||||
{
|
||||
public:
|
||||
|
||||
Memory(size_t size);
|
||||
virtual ~Memory();
|
||||
|
||||
uint8 *data;
|
||||
size_t size;
|
||||
|
||||
}; // Memory
|
||||
|
||||
// Compressed image data can have multiple mipmap levels, each represented
|
||||
// by a sub-image.
|
||||
class Slice : public ImageDataBase
|
||||
{
|
||||
public:
|
||||
|
||||
Slice(PixelFormat format, int width, int height, Memory *memory, size_t offset, size_t size);
|
||||
Slice(const Slice &slice);
|
||||
virtual ~Slice();
|
||||
|
||||
Slice *clone() const override;
|
||||
void *getData() const override { return memory->data + offset; }
|
||||
size_t getSize() const override { return dataSize; }
|
||||
bool isSRGB() const override { return sRGB; }
|
||||
size_t getOffset() const { return offset; }
|
||||
|
||||
private:
|
||||
|
||||
StrongRef<Memory> memory;
|
||||
|
||||
size_t offset;
|
||||
size_t dataSize;
|
||||
bool sRGB;
|
||||
|
||||
}; // Slice
|
||||
|
||||
static love::Type type;
|
||||
|
||||
CompressedImageData();
|
||||
CompressedImageData(const std::list<CompressedFormatHandler *> &formats, love::filesystem::FileData *filedata);
|
||||
CompressedImageData(const CompressedImageData &c);
|
||||
virtual ~CompressedImageData();
|
||||
|
||||
// Implements Data.
|
||||
virtual CompressedImageData *clone() const = 0;
|
||||
virtual void *getData() const;
|
||||
virtual size_t getSize() const;
|
||||
CompressedImageData *clone() const override;
|
||||
void *getData() const override;
|
||||
size_t getSize() const override;
|
||||
|
||||
/**
|
||||
* Gets the number of mipmaps in this Compressed Image Data.
|
||||
@@ -130,19 +96,18 @@ public:
|
||||
|
||||
bool isSRGB() const;
|
||||
|
||||
Slice *getSlice(int slice, int miplevel) const;
|
||||
CompressedSlice *getSlice(int slice, int miplevel) const;
|
||||
|
||||
protected:
|
||||
|
||||
PixelFormat format;
|
||||
|
||||
bool sRGB;
|
||||
|
||||
// Single block of memory containing all of the sub-images.
|
||||
StrongRef<Memory> memory;
|
||||
StrongRef<CompressedMemory> memory;
|
||||
|
||||
// Texture info for each mipmap level.
|
||||
std::vector<StrongRef<Slice>> dataImages;
|
||||
std::vector<StrongRef<CompressedSlice>> dataImages;
|
||||
|
||||
void checkSliceExists(int slice, int miplevel) const;
|
||||
|
||||
|
||||
+45
-21
@@ -18,37 +18,61 @@
|
||||
* 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>
|
||||
#include "CompressedSlice.h"
|
||||
#include "common/Exception.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace image
|
||||
{
|
||||
namespace magpie
|
||||
|
||||
CompressedMemory::CompressedMemory(size_t size)
|
||||
: data(nullptr)
|
||||
, size(size)
|
||||
{
|
||||
try
|
||||
{
|
||||
data = new uint8[size];
|
||||
}
|
||||
catch (std::exception &)
|
||||
{
|
||||
throw love::Exception("Out of memory.");
|
||||
}
|
||||
}
|
||||
|
||||
class CompressedImageData : public love::image::CompressedImageData
|
||||
CompressedMemory::~CompressedMemory()
|
||||
{
|
||||
public:
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
CompressedImageData(std::list<CompressedFormatHandler *> formats, love::filesystem::FileData *filedata);
|
||||
CompressedImageData(const CompressedImageData &c);
|
||||
virtual ~CompressedImageData();
|
||||
CompressedSlice::CompressedSlice(PixelFormat format, int width, int height, CompressedMemory *memory, size_t offset, size_t size)
|
||||
: memory(memory)
|
||||
, offset(offset)
|
||||
, dataSize(size)
|
||||
{
|
||||
this->format = format;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
}
|
||||
|
||||
virtual CompressedImageData *clone() const;
|
||||
}; // CompressedImageData
|
||||
CompressedSlice::CompressedSlice(const CompressedSlice &s)
|
||||
: memory(s.memory)
|
||||
, offset(s.offset)
|
||||
, dataSize(s.dataSize)
|
||||
{
|
||||
this->format = s.getFormat();
|
||||
this->width = s.getWidth();
|
||||
this->height = s.getHeight();
|
||||
}
|
||||
|
||||
CompressedSlice::~CompressedSlice()
|
||||
{
|
||||
}
|
||||
|
||||
CompressedSlice *CompressedSlice::clone() const
|
||||
{
|
||||
return new CompressedSlice(*this);
|
||||
}
|
||||
|
||||
} // magpie
|
||||
} // image
|
||||
} // love
|
||||
|
||||
#endif // LOVE_IMAGE_MAGPIE_COMPRESSED_IMAGE_DATA_H
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
// LOVE
|
||||
#include "common/int.h"
|
||||
#include "common/pixelformat.h"
|
||||
#include "common/Object.h"
|
||||
#include "ImageDataBase.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace image
|
||||
{
|
||||
|
||||
class CompressedMemory : public Object
|
||||
{
|
||||
public:
|
||||
|
||||
CompressedMemory(size_t size);
|
||||
virtual ~CompressedMemory();
|
||||
|
||||
uint8 *data;
|
||||
size_t size;
|
||||
|
||||
}; // CompressedMemory
|
||||
|
||||
// Compressed image data can have multiple mipmap levels, each represented by a
|
||||
// sub-image.
|
||||
class CompressedSlice : public ImageDataBase
|
||||
{
|
||||
public:
|
||||
|
||||
CompressedSlice(PixelFormat format, int width, int height, CompressedMemory *memory, size_t offset, size_t size);
|
||||
CompressedSlice(const CompressedSlice &slice);
|
||||
virtual ~CompressedSlice();
|
||||
|
||||
CompressedSlice *clone() const override;
|
||||
void *getData() const override { return memory->data + offset; }
|
||||
size_t getSize() const override { return dataSize; }
|
||||
bool isSRGB() const override { return sRGB; }
|
||||
size_t getOffset() const { return offset; }
|
||||
|
||||
private:
|
||||
|
||||
StrongRef<CompressedMemory> memory;
|
||||
size_t offset;
|
||||
size_t dataSize;
|
||||
bool sRGB;
|
||||
|
||||
}; // CompressedSlice
|
||||
|
||||
} // image
|
||||
} // love
|
||||
@@ -26,8 +26,6 @@ namespace love
|
||||
{
|
||||
namespace image
|
||||
{
|
||||
namespace magpie
|
||||
{
|
||||
|
||||
FormatHandler::FormatHandler()
|
||||
{
|
||||
@@ -42,7 +40,7 @@ bool FormatHandler::canDecode(love::filesystem::FileData* /*data*/)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FormatHandler::canEncode(PixelFormat /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/)
|
||||
bool FormatHandler::canEncode(PixelFormat /*rawFormat*/, EncodedFormat /*encodedFormat*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -52,7 +50,7 @@ FormatHandler::DecodedImage FormatHandler::decode(love::filesystem::FileData* /*
|
||||
throw love::Exception("Image decoding is not implemented for this format backend.");
|
||||
}
|
||||
|
||||
FormatHandler::EncodedImage FormatHandler::encode(const DecodedImage& /*img*/, ImageData::EncodedFormat /*format*/)
|
||||
FormatHandler::EncodedImage FormatHandler::encode(const DecodedImage& /*img*/, EncodedFormat /*format*/)
|
||||
{
|
||||
throw love::Exception("Image encoding is not implemented for this format backend.");
|
||||
}
|
||||
@@ -62,6 +60,5 @@ void FormatHandler::free(unsigned char *mem)
|
||||
delete[] mem;
|
||||
}
|
||||
|
||||
} // magpie
|
||||
} // image
|
||||
} // love
|
||||
@@ -18,20 +18,17 @@
|
||||
* 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
|
||||
#pragma once
|
||||
|
||||
// LOVE
|
||||
#include "image/ImageData.h"
|
||||
#include "filesystem/FileData.h"
|
||||
#include "common/Object.h"
|
||||
#include "common/pixelformat.h"
|
||||
#include "filesystem/FileData.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace image
|
||||
{
|
||||
namespace magpie
|
||||
{
|
||||
|
||||
/**
|
||||
* Base class for all ImageData encoder/decoder library interfaces.
|
||||
@@ -41,6 +38,13 @@ class FormatHandler : public love::Object
|
||||
{
|
||||
public:
|
||||
|
||||
enum EncodedFormat
|
||||
{
|
||||
ENCODED_TGA,
|
||||
ENCODED_PNG,
|
||||
ENCODED_MAX_ENUM
|
||||
};
|
||||
|
||||
// Raw RGBA pixel data.
|
||||
struct DecodedImage
|
||||
{
|
||||
@@ -76,7 +80,7 @@ public:
|
||||
/**
|
||||
* Whether this format handler can encode to a particular format.
|
||||
**/
|
||||
virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat);
|
||||
virtual bool canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat);
|
||||
|
||||
/**
|
||||
* Decodes an image from its encoded form into raw pixel data.
|
||||
@@ -91,7 +95,7 @@ public:
|
||||
* @param format The format to encode to.
|
||||
* @return The encoded image data.
|
||||
**/
|
||||
virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format);
|
||||
virtual EncodedImage encode(const DecodedImage &img, EncodedFormat format);
|
||||
|
||||
/**
|
||||
* Frees memory allocated by the format handler.
|
||||
@@ -100,8 +104,5 @@ public:
|
||||
|
||||
}; // FormatHandler
|
||||
|
||||
} // magpie
|
||||
} // image
|
||||
} // love
|
||||
|
||||
#endif // LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H
|
||||
@@ -20,6 +20,17 @@
|
||||
|
||||
// LOVE
|
||||
#include "Image.h"
|
||||
#include "common/config.h"
|
||||
|
||||
#include "magpie/PNGHandler.h"
|
||||
#include "magpie/STBHandler.h"
|
||||
#include "magpie/EXRHandler.h"
|
||||
|
||||
#include "magpie/ddsHandler.h"
|
||||
#include "magpie/PVRHandler.h"
|
||||
#include "magpie/KTXHandler.h"
|
||||
#include "magpie/PKMHandler.h"
|
||||
#include "magpie/ASTCHandler.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -28,6 +39,79 @@ namespace image
|
||||
|
||||
love::Type Image::type("image", &Module::type);
|
||||
|
||||
Image::Image()
|
||||
{
|
||||
using namespace magpie;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ImageData *Image::newPastedImageData(ImageData *src, int sx, int sy, int w, int h)
|
||||
{
|
||||
ImageData *res = newImageData(w, h, src->getFormat());
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include "ImageData.h"
|
||||
#include "CompressedImageData.h"
|
||||
|
||||
// C++
|
||||
#include <list>
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace image
|
||||
@@ -46,17 +49,19 @@ public:
|
||||
|
||||
static love::Type type;
|
||||
|
||||
virtual ~Image() {}
|
||||
Image();
|
||||
virtual ~Image();
|
||||
|
||||
// Implements Module.
|
||||
virtual ModuleType getModuleType() const { return M_IMAGE; }
|
||||
ModuleType getModuleType() const override { return M_IMAGE; }
|
||||
const char *getName() const override;
|
||||
|
||||
/**
|
||||
* Creates new ImageData from FileData.
|
||||
* @param data The FileData containing the encoded image data.
|
||||
* @return The new ImageData.
|
||||
**/
|
||||
virtual ImageData *newImageData(love::filesystem::FileData *data) = 0;
|
||||
ImageData *newImageData(love::filesystem::FileData *data);
|
||||
|
||||
/**
|
||||
* Creates empty ImageData with the given size.
|
||||
@@ -64,7 +69,7 @@ public:
|
||||
* @param height The height of the ImageData.
|
||||
* @return The new ImageData.
|
||||
**/
|
||||
virtual ImageData *newImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8) = 0;
|
||||
ImageData *newImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8);
|
||||
|
||||
/**
|
||||
* Creates empty ImageData with the given size.
|
||||
@@ -75,28 +80,36 @@ public:
|
||||
* copy it.
|
||||
* @return The new ImageData.
|
||||
**/
|
||||
virtual ImageData *newImageData(int width, int height, PixelFormat format, void *data, bool own = false) = 0;
|
||||
ImageData *newImageData(int width, int height, PixelFormat format, void *data, bool own = false);
|
||||
|
||||
/**
|
||||
* Creates new CompressedImageData from FileData.
|
||||
* @param data The FileData containing the compressed image data.
|
||||
* @return The new CompressedImageData.
|
||||
**/
|
||||
virtual CompressedImageData *newCompressedData(love::filesystem::FileData *data) = 0;
|
||||
CompressedImageData *newCompressedData(love::filesystem::FileData *data);
|
||||
|
||||
/**
|
||||
* Determines whether a FileData is Compressed image data or not.
|
||||
* @param data The FileData to test.
|
||||
**/
|
||||
virtual bool isCompressed(love::filesystem::FileData *data) = 0;
|
||||
bool isCompressed(love::filesystem::FileData *data);
|
||||
|
||||
std::vector<StrongRef<ImageData>> newCubeFaces(ImageData *src);
|
||||
std::vector<StrongRef<ImageData>> newVolumeLayers(ImageData *src);
|
||||
|
||||
const std::list<FormatHandler *> &getFormatHandlers() const;
|
||||
|
||||
private:
|
||||
|
||||
ImageData *newPastedImageData(ImageData *src, int sx, int sy, int w, int h);
|
||||
|
||||
// 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
|
||||
|
||||
} // image
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
**/
|
||||
|
||||
#include "ImageData.h"
|
||||
#include "Image.h"
|
||||
#include "filesystem/Filesystem.h"
|
||||
|
||||
using love::thread::Lock;
|
||||
|
||||
@@ -29,13 +31,207 @@ namespace image
|
||||
|
||||
love::Type ImageData::type("ImageData", &Data::type);
|
||||
|
||||
ImageData::ImageData()
|
||||
: data(nullptr)
|
||||
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 = Module::getInstance<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(FormatHandler::EncodedFormat encodedFormat, const char *filename, bool writefile) const
|
||||
{
|
||||
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 = Module::getInstance<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;
|
||||
}
|
||||
|
||||
size_t ImageData::getSize() const
|
||||
@@ -289,23 +485,23 @@ bool ImageData::validPixelFormat(PixelFormat format)
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageData::getConstant(const char *in, EncodedFormat &out)
|
||||
bool ImageData::getConstant(const char *in, FormatHandler::EncodedFormat &out)
|
||||
{
|
||||
return encodedFormats.find(in, out);
|
||||
}
|
||||
|
||||
bool ImageData::getConstant(EncodedFormat in, const char *&out)
|
||||
bool ImageData::getConstant(FormatHandler::EncodedFormat in, const char *&out)
|
||||
{
|
||||
return encodedFormats.find(in, out);
|
||||
}
|
||||
|
||||
StringMap<ImageData::EncodedFormat, ImageData::ENCODED_MAX_ENUM>::Entry ImageData::encodedFormatEntries[] =
|
||||
StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM>::Entry ImageData::encodedFormatEntries[] =
|
||||
{
|
||||
{"tga", ENCODED_TGA},
|
||||
{"png", ENCODED_PNG},
|
||||
{"tga", FormatHandler::ENCODED_TGA},
|
||||
{"png", FormatHandler::ENCODED_PNG},
|
||||
};
|
||||
|
||||
StringMap<ImageData::EncodedFormat, ImageData::ENCODED_MAX_ENUM> ImageData::encodedFormats(ImageData::encodedFormatEntries, sizeof(ImageData::encodedFormatEntries));
|
||||
StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM> ImageData::encodedFormats(ImageData::encodedFormatEntries, sizeof(ImageData::encodedFormatEntries));
|
||||
|
||||
} // image
|
||||
} // love
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "filesystem/FileData.h"
|
||||
#include "thread/threads.h"
|
||||
#include "ImageDataBase.h"
|
||||
#include "FormatHandler.h"
|
||||
|
||||
using love::thread::Mutex;
|
||||
|
||||
@@ -61,14 +62,10 @@ public:
|
||||
|
||||
static love::Type type;
|
||||
|
||||
enum EncodedFormat
|
||||
{
|
||||
ENCODED_TGA,
|
||||
ENCODED_PNG,
|
||||
ENCODED_MAX_ENUM
|
||||
};
|
||||
|
||||
ImageData();
|
||||
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();
|
||||
|
||||
/**
|
||||
@@ -111,12 +108,12 @@ public:
|
||||
* @param f The file to save the encoded image data to.
|
||||
* @param format The format of the encoded data.
|
||||
**/
|
||||
virtual love::filesystem::FileData *encode(EncodedFormat format, const char *filename, bool writefile) = 0;
|
||||
love::filesystem::FileData *encode(FormatHandler::EncodedFormat format, const char *filename, bool writefile) const;
|
||||
|
||||
love::thread::Mutex *getMutex() const;
|
||||
|
||||
// Implements ImageDataBase.
|
||||
virtual ImageData *clone() const override = 0;
|
||||
ImageData *clone() const override;
|
||||
void *getData() const override;
|
||||
size_t getSize() const override;
|
||||
bool isSRGB() const override;
|
||||
@@ -125,18 +122,8 @@ public:
|
||||
|
||||
static bool validPixelFormat(PixelFormat format);
|
||||
|
||||
static bool getConstant(const char *in, EncodedFormat &out);
|
||||
static bool getConstant(EncodedFormat in, const char *&out);
|
||||
|
||||
protected:
|
||||
|
||||
// The actual data.
|
||||
unsigned char *data;
|
||||
|
||||
// We need to be thread-safe
|
||||
// so we lock when we're accessing our
|
||||
// data
|
||||
love::thread::MutexRef mutex;
|
||||
static bool getConstant(const char *in, FormatHandler::EncodedFormat &out);
|
||||
static bool getConstant(FormatHandler::EncodedFormat in, const char *&out);
|
||||
|
||||
private:
|
||||
|
||||
@@ -148,6 +135,21 @@ private:
|
||||
float *f32;
|
||||
};
|
||||
|
||||
// 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 actual data.
|
||||
unsigned char *data = nullptr;
|
||||
|
||||
love::thread::MutexRef mutex;
|
||||
|
||||
// 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;
|
||||
|
||||
static void pasteRGBA8toRGBA16(Row src, Row dst, int w);
|
||||
static void pasteRGBA8toRGBA16F(Row src, Row dst, int w);
|
||||
static void pasteRGBA8toRGBA32F(Row src, Row dst, int w);
|
||||
@@ -164,8 +166,8 @@ private:
|
||||
static void pasteRGBA32FtoRGBA16(Row src, Row dst, int w);
|
||||
static void pasteRGBA32FtoRGBA16F(Row src, Row dst, int w);
|
||||
|
||||
static StringMap<EncodedFormat, ENCODED_MAX_ENUM>::Entry encodedFormatEntries[];
|
||||
static StringMap<EncodedFormat, ENCODED_MAX_ENUM> encodedFormats;
|
||||
static StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM>::Entry encodedFormatEntries[];
|
||||
static StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM> encodedFormats;
|
||||
|
||||
}; // ImageData
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -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,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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "common/Data.h"
|
||||
#include "common/StringMap.h"
|
||||
|
||||
#include "magpie/Image.h"
|
||||
#include "Image.h"
|
||||
|
||||
#include "filesystem/wrap_Filesystem.h"
|
||||
|
||||
@@ -154,7 +154,7 @@ extern "C" int luaopen_love_image(lua_State *L)
|
||||
Image *instance = instance();
|
||||
if (instance == nullptr)
|
||||
{
|
||||
luax_catchexcept(L, [&](){ instance = new love::image::magpie::Image(); });
|
||||
luax_catchexcept(L, [&](){ instance = new love::image::Image(); });
|
||||
}
|
||||
else
|
||||
instance->retain();
|
||||
|
||||
@@ -262,7 +262,7 @@ int w_ImageData_encode(lua_State *L)
|
||||
{
|
||||
ImageData *t = luax_checkimagedata(L, 1);
|
||||
|
||||
ImageData::EncodedFormat format;
|
||||
FormatHandler::EncodedFormat format;
|
||||
const char *fmt = luaL_checkstring(L, 2);
|
||||
if (!ImageData::getConstant(fmt, format))
|
||||
return luaL_error(L, "Invalid encoded image format '%s'.", fmt);
|
||||
|
||||
Reference in New Issue
Block a user