Skip to content

Commit

Permalink
Add basic WebP format support.
Browse files Browse the repository at this point in the history
- decode/encode
- partial build (platform/unix)
  • Loading branch information
ImagicTheCat committed Feb 12, 2020
1 parent 813b1e0 commit 368a9b2
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -652,6 +652,8 @@ set(LOVE_SRC_MODULE_IMAGE_MAGPIE
src/modules/image/magpie/PKMHandler.h
src/modules/image/magpie/PNGHandler.cpp
src/modules/image/magpie/PNGHandler.h
src/modules/image/magpie/WEBPHandler.cpp
src/modules/image/magpie/WEBPHandler.h
src/modules/image/magpie/PVRHandler.cpp
src/modules/image/magpie/PVRHandler.h
src/modules/image/magpie/STBHandler.cpp
Expand Down
1 change: 1 addition & 0 deletions platform/unix/configure.ac
Expand Up @@ -77,6 +77,7 @@ AS_VAR_IF([enable_gme], [yes], [ACLOVE_DEP_GME], [])
AS_VAR_IF([enable_mpg123], [no],
AC_DEFINE([LOVE_NOMPG123], [], [Build without mpg123]),
[ACLOVE_DEP_MPG123])
AS_VAR_IF([enable_module_image], [yes], [ACLOVE_DEP_WEBP], [])

# Add flags for optional libraries
AC_ARG_ENABLE([library-enet], [ --disable-library-enet Turn off library enet], [], [enable_library_enet=yes])
Expand Down
3 changes: 3 additions & 0 deletions platform/unix/deps.m4
Expand Up @@ -27,6 +27,9 @@ AC_DEFUN([ACLOVE_DEP_SDL2], [
AC_DEFUN([ACLOVE_DEP_PTHREAD], [
AC_SEARCH_LIBS([pthread_create], [pthread], [], [LOVE_MSG_ERROR([the POSIX threads library])])])

AC_DEFUN([ACLOVE_DEP_WEBP], [
AC_SEARCH_LIBS([WebPDecodeRGBA], [webp], [], [LOVE_MSG_ERROR([WebP])])])

# does not use pkg-config because of the FILE_OFFSET_BITS.. bit
AC_DEFUN([ACLOVE_DEP_MPG123], [
AC_SEARCH_LIBS([mpg123_open_feed], [mpg123], [],
Expand Down
1 change: 1 addition & 0 deletions src/modules/image/FormatHandler.h
Expand Up @@ -43,6 +43,7 @@ class FormatHandler : public love::Object
{
ENCODED_TGA,
ENCODED_PNG,
ENCODED_WEBP,
ENCODED_MAX_ENUM
};

Expand Down
2 changes: 2 additions & 0 deletions src/modules/image/Image.cpp
Expand Up @@ -23,6 +23,7 @@
#include "common/config.h"

#include "magpie/PNGHandler.h"
#include "magpie/WEBPHandler.h"
#include "magpie/STBHandler.h"
#include "magpie/EXRHandler.h"

Expand All @@ -47,6 +48,7 @@ Image::Image()

formatHandlers = {
new PNGHandler,
new WEBPHandler,
new STBHandler,
new EXRHandler,
new DDSHandler,
Expand Down
1 change: 1 addition & 0 deletions src/modules/image/ImageData.cpp
Expand Up @@ -897,6 +897,7 @@ StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM>::Entry
{
{"tga", FormatHandler::ENCODED_TGA},
{"png", FormatHandler::ENCODED_PNG},
{"webp", FormatHandler::ENCODED_WEBP}
};

StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM> ImageData::encodedFormats(ImageData::encodedFormatEntries, sizeof(ImageData::encodedFormatEntries));
Expand Down
100 changes: 100 additions & 0 deletions src/modules/image/magpie/WEBPHandler.cpp
@@ -0,0 +1,100 @@
/**
* Copyright (c) 2006-2020 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 "WEBPHandler.h"

// LOVE
#include "common/Exception.h"
#include "common/math.h"

// libwebp
#include <webp/decode.h>
#include <webp/encode.h>

// C++

// C
#include <cstdlib>

namespace love
{
namespace image
{
namespace magpie
{

bool WEBPHandler::canDecode(Data *data)
{
WebPBitstreamFeatures features;
bool ok = (WebPGetFeatures((uint8_t*)data->getData(), data->getSize(), &features) == VP8_STATUS_OK);
return ok && features.width > 0 && features.height > 0;
}

bool WEBPHandler::canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat)
{
return encodedFormat == ENCODED_WEBP && rawFormat == PIXELFORMAT_RGBA8;
}

WEBPHandler::DecodedImage WEBPHandler::decode(Data *data)
{
int width, height;
uint8_t *pdata = WebPDecodeRGBA((uint8_t*)data->getData(), data->getSize(), &width, &height);

if(pdata){
DecodedImage img;
img.width = width;
img.height = height;
img.size = (size_t)width*height*4;
img.format = PIXELFORMAT_RGBA8;
img.data = pdata;
return img;
}
else
throw love::Exception("Could not decode WebP image");
}

FormatHandler::EncodedImage WEBPHandler::encode(const DecodedImage &img, EncodedFormat encodedFormat)
{
if (!canEncode(img.format, encodedFormat))
throw love::Exception("WebP encoder cannot encode to non-WebP format.");

uint8_t *data = 0;
// export using lossless encoding
size_t size = WebPEncodeLosslessRGBA((uint8_t*)img.data, img.width, img.height, img.width*4, &data);
if(size > 0){
EncodedImage out_img;
out_img.size = size;
out_img.data = data;
return out_img;
}
else{
if(data) WebPFree(data); // doc ambiguity: data may need to be freed on error
throw love::Exception("Could not encode WebP image");
}
}

void WEBPHandler::freeRawPixels(unsigned char *mem)
{
WebPFree(mem);
}

} // magpie
} // image
} // love
53 changes: 53 additions & 0 deletions src/modules/image/magpie/WEBPHandler.h
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2006-2020 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 "image/FormatHandler.h"

namespace love
{
namespace image
{
namespace magpie
{

/**
* Interface between ImageData and libwebp.
**/
class WEBPHandler : public FormatHandler
{
public:

// Implements FormatHandler.

virtual bool canDecode(Data *data);
virtual bool canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat);

virtual DecodedImage decode(Data *data);
virtual EncodedImage encode(const DecodedImage &img, EncodedFormat format);

virtual void freeRawPixels(unsigned char *mem);
}; // WEBPHandler

} // magpie
} // image
} // love

0 comments on commit 368a9b2

Please sign in to comment.