WEBP image reader

+ add initial support
This commit is contained in:
artemp 2013-04-15 14:00:41 +01:00
parent 9584b3634f
commit e59bf22fbd
4 changed files with 165 additions and 0 deletions

View file

@ -67,6 +67,7 @@ pretty_dep_names = {
'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES',
'tiff':'TIFF C library | configure with TIFF_LIBS & TIFF_INCLUDES',
'png':'PNG C library | configure with PNG_LIBS & PNG_INCLUDES',
'webp':'WEBP C library | configure with WEBP_LIBS & WEBP_INCLUDES',
'icuuc':'ICU C++ library | configure with ICU_LIBS & ICU_INCLUDES or use ICU_LIB_NAME to specify custom lib name | more info: http://site.icu-project.org/',
'z':'Z compression library | more info: http://www.zlib.net/',
'm':'Basic math library, part of C++ stlib',
@ -317,6 +318,9 @@ PathVariable.PathAccept),
BoolVariable('TIFF', 'Build Mapnik with TIFF read and write support', 'True'),
PathVariable('TIFF_INCLUDES', 'Search path for libtiff include files', '/usr/include', PathVariable.PathAccept),
PathVariable('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
BoolVariable('WEBP', 'Build Mapnik with WEBP read', 'False'),
PathVariable('WEBP_INCLUDES', 'Search path for libwebp include files', '/usr/include', PathVariable.PathAccept),
PathVariable('WEBP_LIBS','Search path for libwebp library files','/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
BoolVariable('PROJ', 'Build Mapnik with proj4 support to enable transformations between many different projections', 'True'),
PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/include', PathVariable.PathAccept),
PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/' + LIBDIR_SCHEMA_DEFAULT, PathVariable.PathAccept),
@ -1170,6 +1174,18 @@ if not preconfigured:
else:
env['SKIPPED_DEPS'].extend(['png'])
if env['WEBP']:
env.Append(CPPDEFINES = '-DHAVE_WEBP')
LIBSHEADERS.append(['webp', 'webp/decode.h', True,'C'])
LIBSHEADERS.append(['webp', 'webp/encode.h', True,'C'])
inc_path = env['%s_INCLUDES' % 'WEBP']
lib_path = env['%s_LIBS' % 'WEBP']
env.AppendUnique(CPPPATH = os.path.realpath(inc_path))
env.AppendUnique(LIBPATH = os.path.realpath(lib_path))
else:
env['SKIPPED_DEPS'].extend(['png'])
if env['TIFF']:
env.Append(CPPDEFINES = '-DHAVE_TIFF')
LIBSHEADERS.append(['tiff', 'tiff.h', True,'C'])

View file

@ -71,6 +71,9 @@ if env['JPEG']:
if env['TIFF']:
lib_env['LIBS'].append('tiff')
if env['WEBP']:
lib_env['LIBS'].append('webp')
if len(env['EXTRA_FREETYPE_LIBS']):
lib_env['LIBS'].extend(copy(env['EXTRA_FREETYPE_LIBS']))
@ -234,6 +237,13 @@ if env['PNG']:
png_reader.cpp
""")
if env['WEBP']:
source += Split(
"""
webp_reader.cpp
""")
# agg backend
source += Split(
"""

View file

@ -52,6 +52,14 @@ inline boost::optional<std::string> type_from_bytes(char const* data, size_t siz
}
}
if (size>=12)
{
if (data[0] == 'R' && data[1] == 'I' && data[2] == 'F' && data[3] == 'F' &&
data[8] == 'W' && data[9] == 'E' && data[10] == 'B' && data[11] == 'P')
{
return result_type("webp");
}
}
return result_type();
}

131
src/webp_reader.cpp Normal file
View file

@ -0,0 +1,131 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/image_reader.hpp>
extern "C"
{
#include <webp/types.h>
#include <webp/decode.h>
}
// boost
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
namespace mapnik
{
class webp_reader : public image_reader
{
private:
uint8_t const* data_;
size_t size_;
unsigned width_;
unsigned height_;
public:
explicit webp_reader(char const* data, std::size_t size);
~webp_reader();
unsigned width() const;
unsigned height() const;
bool premultiplied_alpha() const { return false; }
void read(unsigned x,unsigned y,image_data_32& image);
private:
void init();
};
namespace
{
image_reader* create_webp_reader(char const * data, std::size_t size)
{
return new webp_reader(data, size);
}
const bool registered = register_image_reader("webp", create_webp_reader);
}
// ctor
webp_reader::webp_reader(char const* data, std::size_t size)
: data_(reinterpret_cast<uint8_t const*>(data)),
size_(size),
width_(0),
height_(0)
{
init();
}
// dtor
webp_reader::~webp_reader()
{
//
}
void webp_reader::init()
{
WebPDecoderConfig config;
if (!WebPGetFeatures(data_, size_, &config.input) == VP8_STATUS_OK)
{
throw image_reader_exception("WEBP: can't open image");
}
width_ = config.input.width;
height_ = config.input.height;
}
unsigned webp_reader::width() const
{
return width_;
}
unsigned webp_reader::height() const
{
return height_;
}
void webp_reader::read(unsigned x0, unsigned y0,image_data_32& image)
{
WebPDecoderConfig config;
config.options.use_cropping = 1;
config.options.crop_left = x0;
config.options.crop_top = y0;
config.options.crop_width = image.width();
config.options.crop_height = image.height();
if (WebPGetFeatures(data_, size_, &config.input) != VP8_STATUS_OK)
{
throw image_reader_exception("WEBP reader: WebPGetFeatures failed");
}
config.output.colorspace = MODE_RGBA;
config.output.u.RGBA.rgba = (uint8_t*)image.getBytes();
config.output.u.RGBA.stride = 4 * image.width();
config.output.u.RGBA.size = image.width()*image.height()*4;
if (WebPDecode(data_, size_, &config) != VP8_STATUS_OK)
{
throw image_reader_exception("WEBP reader: WebPDecode failed");
}
}
}