Added love.math.compress(data, format [, level]) and love.math.decompress(compresseddata) / love.math.decompress(compressedstring, format).

Renamed the love.image CompressedData type to CompressedImageData.

love.math.compress returns a love.math CompressedData object which holds the newly compressed data. Currently supported formats are "lz4" and "zlib". Note that the formats are not file formats and don't compress filesystem hierarchies.
This commit is contained in:
Alex Szpakowski
2015-03-23 11:28:14 -03:00
parent 4d92d00aff
commit a29b349014
45 changed files with 3895 additions and 395 deletions
+1 -1
View File
@@ -656,7 +656,7 @@ Image *Graphics::newImage(love::image::ImageData *data, const Image::Flags &flag
return new Image(data, flags);
}
Image *Graphics::newImage(love::image::CompressedData *cdata, const Image::Flags &flags)
Image *Graphics::newImage(love::image::CompressedImageData *cdata, const Image::Flags &flags)
{
return new Image(cdata, flags);
}
+1 -1
View File
@@ -158,7 +158,7 @@ public:
* Creates an Image object with padding and/or optimization.
**/
Image *newImage(love::image::ImageData *data, const Image::Flags &flags);
Image *newImage(love::image::CompressedData *cdata, const Image::Flags &flags);
Image *newImage(love::image::CompressedImageData *cdata, const Image::Flags &flags);
Quad *newQuad(Quad::Viewport v, float sw, float sh);
+50 -50
View File
@@ -59,7 +59,7 @@ Image::Image(love::image::ImageData *data, const Flags &flags)
++imageCount;
}
Image::Image(love::image::CompressedData *cdata, const Flags &flags)
Image::Image(love::image::CompressedImageData *cdata, const Flags &flags)
: data(nullptr)
, cdata(cdata)
, texture(0)
@@ -76,7 +76,7 @@ Image::Image(love::image::CompressedData *cdata, const Flags &flags)
if (flags.mipmaps)
{
// The mipmap texture data comes from the CompressedData in this case,
// The mipmap texture data comes from the CompressedImageData in this case,
// so we should make sure it has all necessary mipmap levels.
if (cdata->getMipmapCount() < (int) log2(std::max(width, height)) + 1)
throw love::Exception("Image cannot have mipmaps: compressed image data does not have all required mipmap levels.");
@@ -198,7 +198,7 @@ bool Image::loadVolatile()
if (isCompressed() && !hasCompressedTextureSupport(cdata->getFormat(), flags.sRGB))
{
const char *str;
if (image::CompressedData::getConstant(cdata->getFormat(), str))
if (image::CompressedImageData::getConstant(cdata->getFormat(), str))
{
throw love::Exception("Cannot create image: "
"%s%s compressed images are not supported on this system.", flags.sRGB ? "sRGB " : "", str);
@@ -392,7 +392,7 @@ love::image::ImageData *Image::getImageData() const
return data.get();
}
love::image::CompressedData *Image::getCompressedData() const
love::image::CompressedImageData *Image::getCompressedData() const
{
return cdata.get();
}
@@ -491,87 +491,87 @@ bool Image::isCompressed() const
return compressed;
}
GLenum Image::getCompressedFormat(image::CompressedData::Format cformat) const
GLenum Image::getCompressedFormat(image::CompressedImageData::Format cformat) const
{
switch (cformat)
{
case image::CompressedData::FORMAT_DXT1:
case image::CompressedImageData::FORMAT_DXT1:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
else
return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
case image::CompressedData::FORMAT_DXT3:
case image::CompressedImageData::FORMAT_DXT3:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
else
return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case image::CompressedData::FORMAT_DXT5:
case image::CompressedImageData::FORMAT_DXT5:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
else
return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
case image::CompressedData::FORMAT_BC4:
case image::CompressedImageData::FORMAT_BC4:
return GL_COMPRESSED_RED_RGTC1;
case image::CompressedData::FORMAT_BC4s:
case image::CompressedImageData::FORMAT_BC4s:
return GL_COMPRESSED_SIGNED_RED_RGTC1;
case image::CompressedData::FORMAT_BC5:
case image::CompressedImageData::FORMAT_BC5:
return GL_COMPRESSED_RG_RGTC2;
case image::CompressedData::FORMAT_BC5s:
case image::CompressedImageData::FORMAT_BC5s:
return GL_COMPRESSED_SIGNED_RG_RGTC2;
case image::CompressedData::FORMAT_BC6H:
case image::CompressedImageData::FORMAT_BC6H:
return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
case image::CompressedData::FORMAT_BC6Hs:
case image::CompressedImageData::FORMAT_BC6Hs:
return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
case image::CompressedData::FORMAT_BC7:
case image::CompressedImageData::FORMAT_BC7:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM;
else
return GL_COMPRESSED_RGBA_BPTC_UNORM;
case image::CompressedData::FORMAT_ETC1:
case image::CompressedImageData::FORMAT_ETC1:
// The ETC2 format can load ETC1 textures.
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility)
return GL_COMPRESSED_RGB8_ETC2;
else
return GL_ETC1_RGB8_OES;
case image::CompressedData::FORMAT_ETC2_RGB:
case image::CompressedImageData::FORMAT_ETC2_RGB:
if (flags.sRGB)
return GL_COMPRESSED_SRGB8_ETC2;
else
return GL_COMPRESSED_RGB8_ETC2;
case image::CompressedData::FORMAT_ETC2_RGBA:
case image::CompressedImageData::FORMAT_ETC2_RGBA:
if (flags.sRGB)
return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
else
return GL_COMPRESSED_RGBA8_ETC2_EAC;
case image::CompressedData::FORMAT_ETC2_RGBA1:
case image::CompressedImageData::FORMAT_ETC2_RGBA1:
if (flags.sRGB)
return GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
else
return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
case image::CompressedData::FORMAT_EAC_R:
case image::CompressedImageData::FORMAT_EAC_R:
return GL_COMPRESSED_R11_EAC;
case image::CompressedData::FORMAT_EAC_Rs:
case image::CompressedImageData::FORMAT_EAC_Rs:
return GL_COMPRESSED_SIGNED_R11_EAC;
case image::CompressedData::FORMAT_EAC_RG:
case image::CompressedImageData::FORMAT_EAC_RG:
return GL_COMPRESSED_RG11_EAC;
case image::CompressedData::FORMAT_EAC_RGs:
case image::CompressedImageData::FORMAT_EAC_RGs:
return GL_COMPRESSED_SIGNED_RG11_EAC;
case image::CompressedData::FORMAT_PVR1_RGB2:
case image::CompressedImageData::FORMAT_PVR1_RGB2:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
else
return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
case image::CompressedData::FORMAT_PVR1_RGB4:
case image::CompressedImageData::FORMAT_PVR1_RGB4:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
else
return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
case image::CompressedData::FORMAT_PVR1_RGBA2:
case image::CompressedImageData::FORMAT_PVR1_RGBA2:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
else
return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
case image::CompressedData::FORMAT_PVR1_RGBA4:
case image::CompressedImageData::FORMAT_PVR1_RGBA4:
if (flags.sRGB)
return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
else
@@ -589,40 +589,40 @@ bool Image::hasAnisotropicFilteringSupport()
return GLAD_EXT_texture_filter_anisotropic;
}
bool Image::hasCompressedTextureSupport(image::CompressedData::Format format, bool sRGB)
bool Image::hasCompressedTextureSupport(image::CompressedImageData::Format format, bool sRGB)
{
switch (format)
{
case image::CompressedData::FORMAT_DXT1:
case image::CompressedImageData::FORMAT_DXT1:
return GLAD_EXT_texture_compression_s3tc || GLAD_EXT_texture_compression_dxt1;
case image::CompressedData::FORMAT_DXT3:
case image::CompressedImageData::FORMAT_DXT3:
return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt3;
case image::CompressedData::FORMAT_DXT5:
case image::CompressedImageData::FORMAT_DXT5:
return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt5;
case image::CompressedData::FORMAT_BC4:
case image::CompressedData::FORMAT_BC4s:
case image::CompressedData::FORMAT_BC5:
case image::CompressedData::FORMAT_BC5s:
case image::CompressedImageData::FORMAT_BC4:
case image::CompressedImageData::FORMAT_BC4s:
case image::CompressedImageData::FORMAT_BC5:
case image::CompressedImageData::FORMAT_BC5s:
return (GLAD_VERSION_3_0 || GLAD_ARB_texture_compression_rgtc || GLAD_EXT_texture_compression_rgtc);
case image::CompressedData::FORMAT_BC6H:
case image::CompressedData::FORMAT_BC6Hs:
case image::CompressedData::FORMAT_BC7:
case image::CompressedImageData::FORMAT_BC6H:
case image::CompressedImageData::FORMAT_BC6Hs:
case image::CompressedImageData::FORMAT_BC7:
return GLAD_VERSION_4_2 || GLAD_ARB_texture_compression_bptc;
case image::CompressedData::FORMAT_ETC1:
case image::CompressedImageData::FORMAT_ETC1:
// ETC2 support guarantees ETC1 support as well.
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_OES_compressed_ETC1_RGB8_texture;
case image::CompressedData::FORMAT_ETC2_RGB:
case image::CompressedData::FORMAT_ETC2_RGBA:
case image::CompressedData::FORMAT_ETC2_RGBA1:
case image::CompressedData::FORMAT_EAC_R:
case image::CompressedData::FORMAT_EAC_Rs:
case image::CompressedData::FORMAT_EAC_RG:
case image::CompressedData::FORMAT_EAC_RGs:
case image::CompressedImageData::FORMAT_ETC2_RGB:
case image::CompressedImageData::FORMAT_ETC2_RGBA:
case image::CompressedImageData::FORMAT_ETC2_RGBA1:
case image::CompressedImageData::FORMAT_EAC_R:
case image::CompressedImageData::FORMAT_EAC_Rs:
case image::CompressedImageData::FORMAT_EAC_RG:
case image::CompressedImageData::FORMAT_EAC_RGs:
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility;
case image::CompressedData::FORMAT_PVR1_RGB2:
case image::CompressedData::FORMAT_PVR1_RGB4:
case image::CompressedData::FORMAT_PVR1_RGBA2:
case image::CompressedData::FORMAT_PVR1_RGBA4:
case image::CompressedImageData::FORMAT_PVR1_RGB2:
case image::CompressedImageData::FORMAT_PVR1_RGB4:
case image::CompressedImageData::FORMAT_PVR1_RGBA2:
case image::CompressedImageData::FORMAT_PVR1_RGBA4:
if (sRGB)
return GLAD_EXT_pvrtc_sRGB;
else
+8 -8
View File
@@ -28,7 +28,7 @@
#include "common/StringMap.h"
#include "common/math.h"
#include "image/ImageData.h"
#include "image/CompressedData.h"
#include "image/CompressedImageData.h"
#include "graphics/Texture.h"
#include "graphics/Volatile.h"
@@ -78,7 +78,7 @@ public:
*
* @param cdata The compressed data from which to load the image.
**/
Image(love::image::CompressedData *cdata, const Flags &flags);
Image(love::image::CompressedImageData *cdata, const Flags &flags);
virtual ~Image();
@@ -99,7 +99,7 @@ public:
virtual const void *getHandle() const;
love::image::ImageData *getImageData() const;
love::image::CompressedData *getCompressedData() const;
love::image::CompressedImageData *getCompressedData() const;
virtual void setFilter(const Texture::Filter &f);
virtual bool setWrap(const Texture::Wrap &w);
@@ -108,12 +108,12 @@ public:
float getMipmapSharpness() const;
/**
* Whether this Image is using a compressed texture (via CompressedData).
* Whether this Image is using a compressed texture (via CompressedImageData).
**/
bool isCompressed() const;
/**
* Re-uploads the ImageData or CompressedData associated with this Image to
* Re-uploads the ImageData or CompressedImageData associated with this Image to
* the GPU.
**/
bool refresh(int xoffset, int yoffset, int w, int h);
@@ -126,7 +126,7 @@ public:
static FilterMode getDefaultMipmapFilter();
static bool hasAnisotropicFilteringSupport();
static bool hasCompressedTextureSupport(image::CompressedData::Format format, bool sRGB);
static bool hasCompressedTextureSupport(image::CompressedImageData::Format format, bool sRGB);
static bool hasSRGBSupport();
static bool getConstant(const char *in, FlagType &out);
@@ -145,7 +145,7 @@ private:
void loadFromCompressedData();
void loadFromImageData();
GLenum getCompressedFormat(image::CompressedData::Format cformat) const;
GLenum getCompressedFormat(image::CompressedImageData::Format cformat) const;
// The ImageData from which the texture is created. May be null if
// Compressed image data was used to create the texture.
@@ -153,7 +153,7 @@ private:
// Or the Compressed Image Data from which the texture is created. May be
// null if raw ImageData was used to create the texture.
StrongRef<love::image::CompressedData> cdata;
StrongRef<love::image::CompressedImageData> cdata;
// OpenGL texture identifier.
GLuint texture;
@@ -231,7 +231,7 @@ static const char *imageFlagName(Image::FlagType flagtype)
int w_newImage(lua_State *L)
{
love::image::ImageData *data = nullptr;
love::image::CompressedData *cdata = nullptr;
love::image::CompressedImageData *cdata = nullptr;
Image::Flags flags;
if (!lua_isnoneornil(L, 2))
@@ -243,7 +243,7 @@ int w_newImage(lua_State *L)
bool releasedata = false;
// Convert to ImageData / CompressedData, if necessary.
// Convert to ImageData / CompressedImageData, if necessary.
if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_ID) || luax_istype(L, 1, FILESYSTEM_FILE_DATA_ID))
{
love::image::Image *image = Module::getInstance<love::image::Image>(Module::M_IMAGE);
@@ -270,8 +270,8 @@ int w_newImage(lua_State *L)
// Lua's GC won't release the image data, so we should do it ourselves.
releasedata = true;
}
else if (luax_istype(L, 1, IMAGE_COMPRESSED_DATA_ID))
cdata = luax_checktype<love::image::CompressedData>(L, 1, IMAGE_COMPRESSED_DATA_ID);
else if (luax_istype(L, 1, IMAGE_COMPRESSED_IMAGE_DATA_ID))
cdata = luax_checktype<love::image::CompressedImageData>(L, 1, IMAGE_COMPRESSED_IMAGE_DATA_ID);
else
data = luax_checktype<love::image::ImageData>(L, 1, IMAGE_IMAGE_DATA_ID);
@@ -1125,17 +1125,17 @@ int w_getCanvasFormats(lua_State *L)
int w_getCompressedImageFormats(lua_State *L)
{
lua_createtable(L, 0, (int) image::CompressedData::FORMAT_MAX_ENUM);
lua_createtable(L, 0, (int) image::CompressedImageData::FORMAT_MAX_ENUM);
for (int i = 0; i < (int) image::CompressedData::FORMAT_MAX_ENUM; i++)
for (int i = 0; i < (int) image::CompressedImageData::FORMAT_MAX_ENUM; i++)
{
image::CompressedData::Format format = (image::CompressedData::Format) i;
image::CompressedImageData::Format format = (image::CompressedImageData::Format) i;
const char *name = nullptr;
if (format == image::CompressedData::FORMAT_UNKNOWN)
if (format == image::CompressedImageData::FORMAT_UNKNOWN)
continue;
if (!image::CompressedData::getConstant(format, name))
if (!image::CompressedImageData::getConstant(format, name))
continue;
luax_pushboolean(L, Image::hasCompressedTextureSupport(format, false));
+1 -1
View File
@@ -94,7 +94,7 @@ int w_Image_getData(lua_State *L)
Image *i = luax_checkimage(L, 1);
if (i->isCompressed())
luax_pushtype(L, IMAGE_COMPRESSED_DATA_ID, i->getCompressedData());
luax_pushtype(L, IMAGE_COMPRESSED_IMAGE_DATA_ID, i->getCompressedData());
else
luax_pushtype(L, IMAGE_IMAGE_DATA_ID, i->getImageData());