An intial commit of a large set of changes attempting to clean up the way that saving images is processed in image_util.hpp and image_util.cpp.
* Changed the passing of rgba_palette to a shared_ptr in order to better facilitate the use of a visitor pattern. * Moved PNG util processing into its own set of files so that image_util_impl.hpp would not have to depend on HAVE_PNG.
This commit is contained in:
parent
8db7f58e8f
commit
454326df17
10 changed files with 372 additions and 220 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@
|
|||
*.os
|
||||
*.so
|
||||
*.a
|
||||
*.swp
|
||||
*.dylib
|
||||
plugins/input/*.input
|
||||
plugins/input/templates/*.input
|
||||
|
|
|
@ -83,7 +83,7 @@ PyObject* tostring2(image_32 const & im, std::string const& format)
|
|||
(s.data(),s.size());
|
||||
}
|
||||
|
||||
PyObject* tostring3(image_32 const & im, std::string const& format, mapnik::rgba_palette const& pal)
|
||||
PyObject* tostring3(image_32 const & im, std::string const& format, mapnik::rgba_palette_ptr const& pal)
|
||||
{
|
||||
std::string s = save_to_string(im, format, pal);
|
||||
return
|
||||
|
@ -106,7 +106,7 @@ void save_to_file2(mapnik::image_32 const& im, std::string const& filename, std:
|
|||
save_to_file(im,filename,type);
|
||||
}
|
||||
|
||||
void save_to_file3(mapnik::image_32 const& im, std::string const& filename, std::string const& type, mapnik::rgba_palette const& pal)
|
||||
void save_to_file3(mapnik::image_32 const& im, std::string const& filename, std::string const& type, mapnik::rgba_palette_ptr const& pal)
|
||||
{
|
||||
save_to_file(im,filename,type,pal);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ PyObject* view_tostring2(image_view<image_data_rgba8> const & view, std::string
|
|||
(s.data(),s.size());
|
||||
}
|
||||
|
||||
PyObject* view_tostring3(image_view<image_data_rgba8> const & view, std::string const& format, mapnik::rgba_palette const& pal)
|
||||
PyObject* view_tostring3(image_view<image_data_rgba8> const & view, std::string const& format, mapnik::rgba_palette_ptr const& pal)
|
||||
{
|
||||
std::string s = save_to_string(view, format, pal);
|
||||
return
|
||||
|
@ -126,7 +126,7 @@ void save_view2(image_view<image_data_rgba8> const& view,
|
|||
void save_view3(image_view<image_data_rgba8> const& view,
|
||||
std::string const& filename,
|
||||
std::string const& type,
|
||||
mapnik::rgba_palette const& pal)
|
||||
mapnik::rgba_palette_ptr const& pal)
|
||||
{
|
||||
save_to_file(view,filename,type,pal);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ void export_palette ()
|
|||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<mapnik::rgba_palette,
|
||||
class_<std::shared_ptr<mapnik::rgba_palette>,
|
||||
std::shared_ptr<mapnik::rgba_palette>,
|
||||
boost::noncopyable >("Palette",no_init)
|
||||
//, init<std::string,std::string>(
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace mapnik {
|
|||
class Map;
|
||||
class rgba_palette;
|
||||
class image_32;
|
||||
typedef std::shared_ptr<rgba_palette> rgba_palette_ptr;
|
||||
|
||||
class ImageWriterException : public std::exception
|
||||
{
|
||||
|
@ -84,7 +85,7 @@ template <typename T>
|
|||
MAPNIK_DECL void save_to_file(T const& image,
|
||||
std::string const& filename,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
// guess type from file extension
|
||||
template <typename T>
|
||||
|
@ -94,7 +95,7 @@ MAPNIK_DECL void save_to_file(T const& image,
|
|||
template <typename T>
|
||||
MAPNIK_DECL void save_to_file(T const& image,
|
||||
std::string const& filename,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL std::string save_to_string(T const& image,
|
||||
|
@ -103,7 +104,7 @@ MAPNIK_DECL std::string save_to_string(T const& image,
|
|||
template <typename T>
|
||||
MAPNIK_DECL std::string save_to_string(T const& image,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void save_to_stream
|
||||
|
@ -111,7 +112,7 @@ MAPNIK_DECL void save_to_stream
|
|||
T const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette
|
||||
rgba_palette_ptr const& palette
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
|
@ -125,7 +126,7 @@ MAPNIK_DECL void save_to_stream
|
|||
template <typename T>
|
||||
void save_as_png(T const& image,
|
||||
std::string const& filename,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
#if defined(HAVE_JPEG)
|
||||
template <typename T>
|
||||
|
@ -224,7 +225,7 @@ MAPNIK_DECL void save_to_file (image_32 const& image,
|
|||
MAPNIK_DECL void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -234,14 +235,14 @@ MAPNIK_DECL std::string save_to_string(image_32 const& image,
|
|||
|
||||
MAPNIK_DECL std::string save_to_string(image_32 const& image,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MAPNIK_DECL void save_to_stream(image_32 const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
MAPNIK_DECL void save_to_stream(image_32 const& image,
|
||||
std::ostream & stream,
|
||||
|
@ -252,7 +253,7 @@ MAPNIK_DECL void save_to_stream(image_32 const& image,
|
|||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
rgba_palette_ptr const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
|
@ -260,7 +261,7 @@ extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8
|
|||
|
||||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
rgba_palette_ptr const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&);
|
||||
|
@ -269,7 +270,7 @@ extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8
|
|||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
rgba_palette_ptr const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
|
@ -277,7 +278,7 @@ extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (im
|
|||
|
||||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
rgba_palette_ptr const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&);
|
||||
|
@ -287,21 +288,21 @@ extern template MAPNIK_DECL std::string save_to_string<image_data_rgba8>(image_d
|
|||
|
||||
extern template MAPNIK_DECL std::string save_to_string<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
rgba_palette_ptr const&);
|
||||
|
||||
extern template MAPNIK_DECL std::string save_to_string<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&);
|
||||
|
||||
extern template MAPNIK_DECL std::string save_to_string<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
rgba_palette_ptr const&);
|
||||
#ifdef _MSC_VER
|
||||
|
||||
template MAPNIK_DECL void save_to_stream<image_data_rgba8>(
|
||||
image_data_rgba8 const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette
|
||||
rgba_palette_ptr const& palette
|
||||
);
|
||||
|
||||
template MAPNIK_DECL void save_to_stream<image_data_rgba8>(
|
||||
|
@ -314,7 +315,7 @@ template MAPNIK_DECL void save_to_stream<image_view<image_data_rgba8> > (
|
|||
image_view<image_data_rgba8> const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette
|
||||
rgba_palette_ptr const& palette
|
||||
);
|
||||
|
||||
template MAPNIK_DECL void save_to_stream<image_view<image_data_rgba8> > (
|
||||
|
|
48
include/mapnik/image_util_png.hpp
Normal file
48
include/mapnik/image_util_png.hpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_IMAGE_UTIL_PNG_HPP
|
||||
#define MAPNIK_IMAGE_UTIL_PNG_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct png_saver : public mapnik::util::static_visitor<>
|
||||
{
|
||||
png_saver(std::ostream &, std::string &, rgba_palette_ptr const& = nullptr);
|
||||
template <typename T>
|
||||
void operator() (T const&) const;
|
||||
private:
|
||||
std::ostream _stream;
|
||||
std::string _t;
|
||||
rgba_palette_ptr _pal;
|
||||
};
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_UTIL_PNG_HPP
|
|
@ -130,6 +130,8 @@ private:
|
|||
std::vector<unsigned> alpha_pal_;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<rgba_palette> rgba_palette_ptr;
|
||||
|
||||
} // namespace mapnik
|
||||
|
||||
#endif // MAPNIK_PALETTE_HPP
|
||||
|
|
|
@ -607,7 +607,7 @@ void save_as_png8(T1 & file,
|
|||
mapnik::image_data_gray8::pixel_type * row_out = reduced_image.getRow(y);
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
row_out[x] = tree.quantize(row[x]);
|
||||
row_out[x] = tree->quantize(row[x]);
|
||||
}
|
||||
}
|
||||
save_as_png(file, palette, reduced_image, width, height, 8, alphaTable, opts);
|
||||
|
@ -635,7 +635,7 @@ void save_as_png8(T1 & file,
|
|||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
|
||||
index = tree.quantize(row[x]);
|
||||
index = tree->quantize(row[x]);
|
||||
if (x%2 == 0)
|
||||
{
|
||||
index = index<<4;
|
||||
|
@ -657,14 +657,14 @@ void save_as_png8_hex(T1 & file,
|
|||
if (width + height > 3) // at least 3 pixels (hextree implementation requirement)
|
||||
{
|
||||
// structure for color quantization
|
||||
hextree<mapnik::rgba> tree(opts.colors);
|
||||
std::shared_ptr<hextree<mapnik::rgba>> tree = std::make_shared<hextree<mapnik::rgba>>(opts.colors);
|
||||
if (opts.trans_mode >= 0)
|
||||
{
|
||||
tree.setTransMode(opts.trans_mode);
|
||||
tree->setTransMode(opts.trans_mode);
|
||||
}
|
||||
if (opts.gamma > 0)
|
||||
{
|
||||
tree.setGamma(opts.gamma);
|
||||
tree->setGamma(opts.gamma);
|
||||
}
|
||||
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
|
@ -673,13 +673,13 @@ void save_as_png8_hex(T1 & file,
|
|||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
unsigned val = row[x];
|
||||
tree.insert(mapnik::rgba(U2RED(val), U2GREEN(val), U2BLUE(val), U2ALPHA(val)));
|
||||
tree->insert(mapnik::rgba(U2RED(val), U2GREEN(val), U2BLUE(val), U2ALPHA(val)));
|
||||
}
|
||||
}
|
||||
|
||||
//transparency values per palette index
|
||||
std::vector<mapnik::rgba> pal;
|
||||
tree.create_palette(pal);
|
||||
tree->create_palette(pal);
|
||||
std::vector<mapnik::rgb> palette;
|
||||
std::vector<unsigned> alphaTable;
|
||||
for (unsigned i=0; i<pal.size(); ++i)
|
||||
|
@ -687,7 +687,7 @@ void save_as_png8_hex(T1 & file,
|
|||
palette.push_back(rgb(pal[i].r, pal[i].g, pal[i].b));
|
||||
alphaTable.push_back(pal[i].a);
|
||||
}
|
||||
save_as_png8<T1, T2, hextree<mapnik::rgba> >(file, image, tree, palette, alphaTable, opts);
|
||||
save_as_png8<T1, T2, std::shared_ptr<hextree<mapnik::rgba>> >(file, image, tree, palette, alphaTable, opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -698,10 +698,10 @@ void save_as_png8_hex(T1 & file,
|
|||
template <typename T1, typename T2>
|
||||
void save_as_png8_pal(T1 & file,
|
||||
T2 const& image,
|
||||
rgba_palette const& pal,
|
||||
rgba_palette_ptr const& pal,
|
||||
png_options const& opts)
|
||||
{
|
||||
save_as_png8<T1, T2, rgba_palette>(file, image, pal, pal.palette(), pal.alphaTable(), opts);
|
||||
save_as_png8<T1, T2, rgba_palette_ptr>(file, image, pal, pal->palette(), pal->alphaTable(), opts);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,18 +20,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#if defined(HAVE_PNG)
|
||||
extern "C"
|
||||
{
|
||||
#include <png.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
// mapnik
|
||||
#if defined(HAVE_PNG)
|
||||
#include <mapnik/png_io.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_TIFF)
|
||||
#include <mapnik/tiff_io.hpp>
|
||||
#endif
|
||||
|
@ -45,6 +34,7 @@ extern "C"
|
|||
#endif
|
||||
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image_util_png.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/memory.hpp>
|
||||
|
@ -52,6 +42,7 @@ extern "C"
|
|||
#include <mapnik/palette.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
#ifdef HAVE_CAIRO
|
||||
#include <mapnik/cairo/cairo_renderer.hpp>
|
||||
|
@ -84,7 +75,7 @@ namespace mapnik
|
|||
template <typename T>
|
||||
std::string save_to_string(T const& image,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
rgba_palette_ptr const& palette)
|
||||
{
|
||||
std::ostringstream ss(std::ios::out|std::ios::binary);
|
||||
save_to_stream(image, ss, type, palette);
|
||||
|
@ -104,7 +95,7 @@ template <typename T>
|
|||
void save_to_file(T const& image,
|
||||
std::string const& filename,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
rgba_palette_ptr const& palette)
|
||||
{
|
||||
std::ofstream file (filename.c_str(), std::ios::out| std::ios::trunc|std::ios::binary);
|
||||
if (file)
|
||||
|
@ -127,134 +118,6 @@ void save_to_file(T const& image,
|
|||
else throw ImageWriterException("Could not write file to " + filename );
|
||||
}
|
||||
|
||||
#if defined(HAVE_PNG)
|
||||
|
||||
void handle_png_options(std::string const& type,
|
||||
png_options & opts)
|
||||
{
|
||||
if (type == "png" || type == "png24" || type == "png32")
|
||||
{
|
||||
opts.paletted = false;
|
||||
return;
|
||||
}
|
||||
else if (type == "png8" || type == "png256")
|
||||
{
|
||||
opts.paletted = true;
|
||||
return;
|
||||
}
|
||||
boost::char_separator<char> sep(":");
|
||||
boost::tokenizer< boost::char_separator<char> > tokens(type, sep);
|
||||
bool set_colors = false;
|
||||
bool set_gamma = false;
|
||||
for (std::string const& t : tokens)
|
||||
{
|
||||
if (t == "png8" || t == "png256")
|
||||
{
|
||||
opts.paletted = true;
|
||||
}
|
||||
else if (t == "png" || t == "png24" || t == "png32")
|
||||
{
|
||||
opts.paletted = false;
|
||||
}
|
||||
else if (t == "m=o")
|
||||
{
|
||||
opts.use_hextree = false;
|
||||
}
|
||||
else if (t == "m=h")
|
||||
{
|
||||
opts.use_hextree = true;
|
||||
}
|
||||
else if (t == "e=miniz")
|
||||
{
|
||||
opts.use_miniz = true;
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "c="))
|
||||
{
|
||||
set_colors = true;
|
||||
if (!mapnik::util::string2int(t.substr(2),opts.colors) || opts.colors < 1 || opts.colors > 256)
|
||||
{
|
||||
throw ImageWriterException("invalid color parameter: " + t.substr(2));
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "t="))
|
||||
{
|
||||
if (!mapnik::util::string2int(t.substr(2),opts.trans_mode) || opts.trans_mode < 0 || opts.trans_mode > 2)
|
||||
{
|
||||
throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2));
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "g="))
|
||||
{
|
||||
set_gamma = true;
|
||||
if (!mapnik::util::string2double(t.substr(2),opts.gamma) || opts.gamma < 0)
|
||||
{
|
||||
throw ImageWriterException("invalid gamma parameter: " + t.substr(2));
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "z="))
|
||||
{
|
||||
/*
|
||||
#define Z_NO_COMPRESSION 0
|
||||
#define Z_BEST_SPEED 1
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define Z_DEFAULT_COMPRESSION (-1)
|
||||
*/
|
||||
if (!mapnik::util::string2int(t.substr(2),opts.compression)
|
||||
|| opts.compression < Z_DEFAULT_COMPRESSION
|
||||
|| opts.compression > 10) // use 10 here rather than Z_BEST_COMPRESSION (9) to allow for MZ_UBER_COMPRESSION
|
||||
{
|
||||
throw ImageWriterException("invalid compression parameter: " + t.substr(2) + " (only -1 through 10 are valid)");
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "s="))
|
||||
{
|
||||
std::string s = t.substr(2);
|
||||
if (s == "default")
|
||||
{
|
||||
opts.strategy = Z_DEFAULT_STRATEGY;
|
||||
}
|
||||
else if (s == "filtered")
|
||||
{
|
||||
opts.strategy = Z_FILTERED;
|
||||
}
|
||||
else if (s == "huff")
|
||||
{
|
||||
opts.strategy = Z_HUFFMAN_ONLY;
|
||||
}
|
||||
else if (s == "rle")
|
||||
{
|
||||
opts.strategy = Z_RLE;
|
||||
}
|
||||
else if (s == "fixed")
|
||||
{
|
||||
opts.strategy = Z_FIXED;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ImageWriterException("invalid compression strategy parameter: " + s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ImageWriterException("unhandled png option: " + t);
|
||||
}
|
||||
}
|
||||
// validation
|
||||
if (!opts.paletted && set_colors)
|
||||
{
|
||||
throw ImageWriterException("invalid color parameter: unavailable for true color (non-paletted) images");
|
||||
}
|
||||
if (!opts.paletted && set_gamma)
|
||||
{
|
||||
throw ImageWriterException("invalid gamma parameter: unavailable for true color (non-paletted) images");
|
||||
}
|
||||
if ((opts.use_miniz == false) && opts.compression > Z_BEST_COMPRESSION)
|
||||
{
|
||||
throw ImageWriterException("invalid compression value: (only -1 through 9 are valid)");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_TIFF)
|
||||
void handle_tiff_options(std::string const& type,
|
||||
tiff_config & config)
|
||||
|
@ -666,10 +529,26 @@ void handle_webp_options(std::string const& type,
|
|||
#endif
|
||||
|
||||
template <typename T>
|
||||
void save_to_stream(T const& image,
|
||||
void save_to_stream(image_view<T> const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
rgba_palette_ptr const& palette)
|
||||
{
|
||||
save_to_stream(image.data(), stream, type, palette);
|
||||
}
|
||||
|
||||
void save_to_stream(image_32 const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette_ptr const& palette)
|
||||
{
|
||||
save_to_stream(image.data(), stream, type, palette);
|
||||
}
|
||||
|
||||
void save_to_stream(image_data_any const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette_ptr const& palette)
|
||||
{
|
||||
if (stream && image.width() > 0 && image.height() > 0)
|
||||
{
|
||||
|
@ -677,20 +556,7 @@ void save_to_stream(T const& image,
|
|||
std::transform(t.begin(), t.end(), t.begin(), ::tolower);
|
||||
if (t == "png" || boost::algorithm::starts_with(t, "png"))
|
||||
{
|
||||
#if defined(HAVE_PNG)
|
||||
if (palette.valid())
|
||||
{
|
||||
png_options opts;
|
||||
handle_png_options(t,opts);
|
||||
save_as_png8_pal(stream, image, palette, opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
save_to_stream(image,stream,type);
|
||||
}
|
||||
#else
|
||||
throw ImageWriterException("png output is not enabled in your build of Mapnik");
|
||||
#endif
|
||||
mapnik::util::apply_visitor(png_saver(stream, t, palette), image);
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "tif"))
|
||||
{
|
||||
|
@ -705,9 +571,22 @@ void save_to_stream(T const& image,
|
|||
else throw ImageWriterException("Could not write to empty stream" );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void save_to_stream(T const& image,
|
||||
void save_to_stream(image_view<T> const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type)
|
||||
{
|
||||
save_to_stream(image.data(), stream, type);
|
||||
}
|
||||
|
||||
void save_to_stream(image_32 const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type)
|
||||
{
|
||||
save_to_stream(image.data(), stream, type);
|
||||
}
|
||||
|
||||
void save_to_stream(image_data_any const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type)
|
||||
{
|
||||
|
@ -717,27 +596,7 @@ void save_to_stream(T const& image,
|
|||
std::transform(t.begin(), t.end(), t.begin(), ::tolower);
|
||||
if (t == "png" || boost::algorithm::starts_with(t, "png"))
|
||||
{
|
||||
#if defined(HAVE_PNG)
|
||||
png_options opts;
|
||||
handle_png_options(t,opts);
|
||||
if (opts.paletted)
|
||||
{
|
||||
if (opts.use_hextree)
|
||||
{
|
||||
save_as_png8_hex(stream, image, opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
save_as_png8_oct(stream, image, opts);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
save_as_png(stream, image, opts);
|
||||
}
|
||||
#else
|
||||
throw ImageWriterException("png output is not enabled in your build of Mapnik");
|
||||
#endif
|
||||
mapnik::util::apply_visitor(png_saver(stream, t), image);
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "tif"))
|
||||
{
|
||||
|
@ -800,7 +659,7 @@ void save_to_file(T const& image, std::string const& filename)
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
void save_to_file(T const& image, std::string const& filename, rgba_palette const& palette)
|
||||
void save_to_file(T const& image, std::string const& filename, rgba_palette_ptr const& palette)
|
||||
{
|
||||
boost::optional<std::string> type = type_from_filename(filename);
|
||||
if (type)
|
||||
|
@ -899,21 +758,21 @@ template void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
|||
template void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
std::string const&,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
template void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&);
|
||||
|
||||
template void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
template std::string save_to_string<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&);
|
||||
|
||||
template std::string save_to_string<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
template void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
|
@ -922,21 +781,21 @@ template void save_to_file<image_view<image_data_rgba8> > (image_view<image_data
|
|||
template void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
std::string const&,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
template void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&);
|
||||
|
||||
template void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
template std::string save_to_string<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&);
|
||||
|
||||
template std::string save_to_string<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
rgba_palette const& palette);
|
||||
rgba_palette_ptr const& palette);
|
||||
|
||||
void save_to_file(image_32 const& image,std::string const& file)
|
||||
{
|
||||
|
@ -953,7 +812,7 @@ void save_to_file (image_32 const& image,
|
|||
void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
rgba_palette_ptr const& palette)
|
||||
{
|
||||
save_to_file<image_data_rgba8>(image.data(), file, type, palette);
|
||||
}
|
||||
|
@ -966,7 +825,7 @@ std::string save_to_string(image_32 const& image,
|
|||
|
||||
std::string save_to_string(image_32 const& image,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
rgba_palette_ptr const& palette)
|
||||
{
|
||||
return save_to_string<image_data_rgba8>(image.data(), type, palette);
|
||||
}
|
||||
|
|
241
src/image_util_png.cpp
Normal file
241
src/image_util_png.cpp
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#if defined(HAVE_PNG)
|
||||
extern "C"
|
||||
{
|
||||
#include <png.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
// mapnik
|
||||
#if defined(HAVE_PNG)
|
||||
#include <mapnik/png_io.hpp>
|
||||
#endif
|
||||
|
||||
#include <mapnik/image_util_png.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
#if defined(HAVE_PNG)
|
||||
|
||||
void handle_png_options(std::string const& type,
|
||||
png_options & opts)
|
||||
{
|
||||
if (type == "png" || type == "png24" || type == "png32")
|
||||
{
|
||||
opts.paletted = false;
|
||||
return;
|
||||
}
|
||||
else if (type == "png8" || type == "png256")
|
||||
{
|
||||
opts.paletted = true;
|
||||
return;
|
||||
}
|
||||
boost::char_separator<char> sep(":");
|
||||
boost::tokenizer< boost::char_separator<char> > tokens(type, sep);
|
||||
bool set_colors = false;
|
||||
bool set_gamma = false;
|
||||
for (std::string const& t : tokens)
|
||||
{
|
||||
if (t == "png8" || t == "png256")
|
||||
{
|
||||
opts.paletted = true;
|
||||
}
|
||||
else if (t == "png" || t == "png24" || t == "png32")
|
||||
{
|
||||
opts.paletted = false;
|
||||
}
|
||||
else if (t == "m=o")
|
||||
{
|
||||
opts.use_hextree = false;
|
||||
}
|
||||
else if (t == "m=h")
|
||||
{
|
||||
opts.use_hextree = true;
|
||||
}
|
||||
else if (t == "e=miniz")
|
||||
{
|
||||
opts.use_miniz = true;
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "c="))
|
||||
{
|
||||
set_colors = true;
|
||||
if (!mapnik::util::string2int(t.substr(2),opts.colors) || opts.colors < 1 || opts.colors > 256)
|
||||
{
|
||||
throw ImageWriterException("invalid color parameter: " + t.substr(2));
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "t="))
|
||||
{
|
||||
if (!mapnik::util::string2int(t.substr(2),opts.trans_mode) || opts.trans_mode < 0 || opts.trans_mode > 2)
|
||||
{
|
||||
throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2));
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "g="))
|
||||
{
|
||||
set_gamma = true;
|
||||
if (!mapnik::util::string2double(t.substr(2),opts.gamma) || opts.gamma < 0)
|
||||
{
|
||||
throw ImageWriterException("invalid gamma parameter: " + t.substr(2));
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "z="))
|
||||
{
|
||||
/*
|
||||
#define Z_NO_COMPRESSION 0
|
||||
#define Z_BEST_SPEED 1
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define Z_DEFAULT_COMPRESSION (-1)
|
||||
*/
|
||||
if (!mapnik::util::string2int(t.substr(2),opts.compression)
|
||||
|| opts.compression < Z_DEFAULT_COMPRESSION
|
||||
|| opts.compression > 10) // use 10 here rather than Z_BEST_COMPRESSION (9) to allow for MZ_UBER_COMPRESSION
|
||||
{
|
||||
throw ImageWriterException("invalid compression parameter: " + t.substr(2) + " (only -1 through 10 are valid)");
|
||||
}
|
||||
}
|
||||
else if (boost::algorithm::starts_with(t, "s="))
|
||||
{
|
||||
std::string s = t.substr(2);
|
||||
if (s == "default")
|
||||
{
|
||||
opts.strategy = Z_DEFAULT_STRATEGY;
|
||||
}
|
||||
else if (s == "filtered")
|
||||
{
|
||||
opts.strategy = Z_FILTERED;
|
||||
}
|
||||
else if (s == "huff")
|
||||
{
|
||||
opts.strategy = Z_HUFFMAN_ONLY;
|
||||
}
|
||||
else if (s == "rle")
|
||||
{
|
||||
opts.strategy = Z_RLE;
|
||||
}
|
||||
else if (s == "fixed")
|
||||
{
|
||||
opts.strategy = Z_FIXED;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ImageWriterException("invalid compression strategy parameter: " + s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ImageWriterException("unhandled png option: " + t);
|
||||
}
|
||||
}
|
||||
// validation
|
||||
if (!opts.paletted && set_colors)
|
||||
{
|
||||
throw ImageWriterException("invalid color parameter: unavailable for true color (non-paletted) images");
|
||||
}
|
||||
if (!opts.paletted && set_gamma)
|
||||
{
|
||||
throw ImageWriterException("invalid gamma parameter: unavailable for true color (non-paletted) images");
|
||||
}
|
||||
if ((opts.use_miniz == false) && opts.compression > Z_BEST_COMPRESSION)
|
||||
{
|
||||
throw ImageWriterException("invalid compression value: (only -1 through 9 are valid)");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
png_saver::png_saver(std::ostream & stream, std::string const& t, rgba_palette_ptr const& pal):
|
||||
_stream(stream), _t(t), _pal(pal) {}
|
||||
|
||||
void png_saver::operator() (mapnik::image_data_rgba8 const& image) const
|
||||
{
|
||||
#if defined(HAVE_PNG)
|
||||
png_options opts;
|
||||
handle_png_options(_t, opts);
|
||||
if (_pal && _pal->valid())
|
||||
{
|
||||
png_options opts;
|
||||
handle_png_options(t,opts);
|
||||
save_as_png8_pal(stream, image, _pal, opts);
|
||||
}
|
||||
else if (opts.paletted)
|
||||
{
|
||||
if (opts.use_hextree)
|
||||
{
|
||||
save_as_png8_hex(_stream, image, opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
save_as_png8_oct(_stream, image, opts);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
save_as_png(_stream, image, opts);
|
||||
}
|
||||
#else
|
||||
throw ImageWriterException("png output is not enabled in your build of Mapnik");
|
||||
#endif
|
||||
}
|
||||
|
||||
void png_saver::operator() (mapnik::image_data_gray8 const& image) const
|
||||
{
|
||||
#if defined(HAVE_PNG)
|
||||
png_options opts;
|
||||
handle_png_options(_t, opts);
|
||||
save_as_png(_stream, image, opts);
|
||||
#else
|
||||
throw ImageWriterException("png output is not enabled in your build of Mapnik");
|
||||
#endif
|
||||
}
|
||||
|
||||
void png_saver::operator() (mapnik::image_data_gray16 const& image) const
|
||||
{
|
||||
#if defined(HAVE_PNG)
|
||||
png_options opts;
|
||||
handle_png_options(_t, opts);
|
||||
save_as_png(_stream, image, opts);
|
||||
#else
|
||||
throw ImageWriterException("png output is not enabled in your build of Mapnik");
|
||||
#endif
|
||||
}
|
||||
|
||||
void png_saver::operator() (mapnik::image_data_gray32f const& image) const
|
||||
{
|
||||
#if defined(HAVE_PNG)
|
||||
png_options opts;
|
||||
handle_png_options(_t, opts);
|
||||
save_as_png(_stream, image, opts);
|
||||
#else
|
||||
throw ImageWriterException("png output is not enabled in your build of Mapnik");
|
||||
#endif
|
||||
}
|
Loading…
Reference in a new issue