diff --git a/CHANGELOG b/CHANGELOG index 6b4a3fa33..130b452fe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,11 +14,13 @@ For a complete change history, see the SVN log. Mapnik Trunk ------------ +- Added support for reading jpeg images (in addition to png/tiff) for image symbolizers (#518) + - Made libjpeg dependency optional at compile time and added mapnik2.has_jpeg() method to check for support in python (#545). - Fixed reading of PostGIS data on Big Endian systems (#515) -- PostGIS: Added better support for alterative schemas (#500) +- PostGIS: Added better support for alternative schemas (#500) - AGG Renderer - Enforced default gamma function on all symbolizers to ensure proper antialiasing even when gamma is modified on the PolygonSymbolizer. (#512) diff --git a/src/SConscript b/src/SConscript index 19ca0426b..66a3282a4 100644 --- a/src/SConscript +++ b/src/SConscript @@ -113,7 +113,12 @@ source = Split( """ ) - +if env['JPEG']: + source += Split( + """ + jpeg_reader.cpp + """) + if True : # agg backend source += Split( """ diff --git a/src/jpeg_reader.cpp b/src/jpeg_reader.cpp new file mode 100644 index 000000000..bbe843277 --- /dev/null +++ b/src/jpeg_reader.cpp @@ -0,0 +1,174 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2010 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 + * + *****************************************************************************/ + +//$Id: jpeg_reader.cpp 33 2005-04-04 13:01:03Z dane $ + +// mapnik +#include +#include + +// jpeg +extern "C" +{ +#include +} + +// mapnik + +#include +#include + +#ifdef MAPNIK_DEBUG +#include +#endif + +namespace mapnik +{ + class JpegReader : public image_reader, boost::noncopyable + { + private: + std::string fileName_; + unsigned width_; + unsigned height_; + public: + explicit JpegReader(const std::string& fileName); + ~JpegReader(); + unsigned width() const; + unsigned height() const; + void read(unsigned x,unsigned y,image_data_32& image); + private: + void init(); + }; + + namespace + { + image_reader* createJpegReader(const std::string& file) + { + return new JpegReader(file); + } + const bool registered = register_image_reader("jpeg",createJpegReader); + } + + JpegReader::JpegReader(const std::string& fileName) + : fileName_(fileName), + width_(0), + height_(0) + { + init(); + } + + JpegReader::~JpegReader() {} + + void JpegReader::init() + { + FILE *fp = fopen(fileName_.c_str(),"rb"); + if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + fileName_); + + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error(&jerr); + + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, fp); + jpeg_read_header(&cinfo, TRUE); + + jpeg_start_decompress(&cinfo); + width_ = cinfo.output_width; + height_ = cinfo.output_height; + //jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(fp); + } + + unsigned JpegReader::width() const + { + return width_; + } + + unsigned JpegReader::height() const + { + return height_; + } + + void JpegReader::read(unsigned x0, unsigned y0,image_data_32& image) + { + struct jpeg_decompress_struct cinfo; + + FILE *fp = fopen(fileName_.c_str(),"rb"); + if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + fileName_); + + struct jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, fp); + + jpeg_read_header(&cinfo, TRUE); + if (cinfo.out_color_space == JCS_UNKNOWN) + throw image_reader_exception("JPEG Reader: failed to read unknown color space in " + fileName_); + + jpeg_start_decompress(&cinfo); + + if (cinfo.output_width == 0) { + jpeg_destroy_decompress (&cinfo); + fclose(fp); + throw image_reader_exception("JPEG Reader: failed to read image size of " + fileName_); + } + + JSAMPARRAY buffer; + int row_stride; + unsigned char a,r,g,b; + row_stride = cinfo.output_width * cinfo.output_components; + buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + unsigned w = std::min(unsigned(image.width()),width_); + unsigned h = std::min(unsigned(image.height()),height_); + + unsigned int out_row[w]; + for (unsigned i=0;i=y0 && i 2) + { + g = buffer[0][cinfo.output_components*x+1]; + b = buffer[0][cinfo.output_components*x+2]; + } else { + g = r; + b = r; + } + out_row[x] = color(r, g, b, a).rgba(); + } + image.setRow(i-y0, out_row, w); + } + } + //jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(fp); + } +}