From 13686cc18252f20aec3409d9982235f78a170feb Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 7 Nov 2014 11:26:55 +0000 Subject: [PATCH 01/24] add jpeg lib --- configure | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/configure b/configure index 8c8a07c1d8b..b0a5e5332c4 100755 --- a/configure +++ b/configure @@ -19,21 +19,22 @@ trap finish EXIT case ${MASON_PLATFORM} in 'ios') - SQLITE_VERSION=system - LIBUV_VERSION=0.10.28 - ZLIB_VERSION=system - BOOST_VERSION=system - ;; + SQLITE_VERSION=system + LIBUV_VERSION=0.10.28 + ZLIB_VERSION=system + BOOST_VERSION=system + ;; *) - GLFW_VERSION=a21f2377 - SQLITE_VERSION=system - LIBPNG_VERSION=1.6.13 - LIBCURL_VERSION=system - LIBUV_VERSION=0.10.28 - ZLIB_VERSION=system - BOOST_VERSION=system - NUNICODE_VERSION=1.4 - ;; + GLFW_VERSION=a21f2377 + SQLITE_VERSION=system + LIBPNG_VERSION=1.6.13 + LIBJPEG_VERSION=v8d + LIBCURL_VERSION=system + LIBUV_VERSION=0.10.28 + ZLIB_VERSION=system + BOOST_VERSION=system + NUNICODE_VERSION=1.4 + ;; esac function abort { >&2 echo -e "\033[1m\033[31m$1\033[0m"; exit 1; } @@ -91,6 +92,13 @@ if [ ! -z ${LIBPNG_VERSION} ]; then CONFIG+=" 'png_ldflags': $(quote_flags $(mason ldflags libpng ${LIBPNG_VERSION})),"$LN fi +if [ ! -z ${LIBJPEG_VERSION} ]; then + mason install jpeg ${LIBJPEG_VERSION} + CONFIG+=" 'jpeg_static_libs': $(quote_flags $(mason static_libs jpeg ${LIBJPEG_VERSION})),"$LN + CONFIG+=" 'jpeg_cflags': $(quote_flags $(mason cflags jpeg ${LIBJPEG_VERSION})),"$LN + CONFIG+=" 'jpeg_ldflags': $(quote_flags $(mason ldflags jpeg ${LIBJPEG_VERSION})),"$LN +fi + if [ ! -z ${SQLITE_VERSION} ]; then mason install sqlite ${SQLITE_VERSION} CONFIG+=" 'sqlite3_static_libs': $(quote_flags $(mason static_libs sqlite ${SQLITE_VERSION})),"$LN From f42d39dc6eca3154cf0de9252ac70b465022410e Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 7 Nov 2014 11:49:31 +0000 Subject: [PATCH 02/24] add image_reader abstraction layer to hanfle multiple image formats (work-in-progress) --- gyp/mbgl-linux.gypi | 1 + include/mbgl/util/factory.hpp | 50 +++++ include/mbgl/util/image_reader.hpp | 50 +++++ include/mbgl/util/singleton.hpp | 126 +++++++++++++ linux/mapboxgl-app.gyp | 5 + platform/default/image.cpp | 126 ++----------- platform/default/image_reader.cpp | 67 +++++++ platform/default/jpeg_reader.cpp | 291 +++++++++++++++++++++++++++++ platform/default/png_reader.cpp | 279 +++++++++++++++++++++++++++ 9 files changed, 884 insertions(+), 111 deletions(-) create mode 100644 include/mbgl/util/factory.hpp create mode 100644 include/mbgl/util/image_reader.hpp create mode 100644 include/mbgl/util/singleton.hpp create mode 100644 platform/default/image_reader.cpp create mode 100644 platform/default/jpeg_reader.cpp create mode 100644 platform/default/png_reader.cpp diff --git a/gyp/mbgl-linux.gypi b/gyp/mbgl-linux.gypi index 823ba91c35b..a2bc51fc8e0 100644 --- a/gyp/mbgl-linux.gypi +++ b/gyp/mbgl-linux.gypi @@ -19,6 +19,7 @@ ], 'ldflags': [ '<@(png_ldflags)', + '<@(jpeg_ldflags)', '<@(uv_ldflags)', '<@(curl_ldflags)', '<@(nu_ldflags)', diff --git a/include/mbgl/util/factory.hpp b/include/mbgl/util/factory.hpp new file mode 100644 index 00000000000..eb1c22933a0 --- /dev/null +++ b/include/mbgl/util/factory.hpp @@ -0,0 +1,50 @@ +#ifndef MBGL_UTIL_FACTORY_HPP +#define MBGL_UTIL_FACTORY_HPP + +#include "singleton.hpp" + +// stl +#include +#include + +namespace mbgl { namespace util { + +template +< +typename product_type, +typename key_type, +typename ...Args > +class factory : public singleton > +{ +private: + using product_creator = product_type* (*) (Args...); + using product_map = std::map; + product_map map_; +public: + + bool register_product(key_type const& key, product_creator creator) + { + return map_.insert(typename product_map::value_type(key,creator)).second; + } + + bool unregister_product(const key_type& key) + { + return map_.erase(key)==1; + } + + product_type* create_object(key_type const& key, Args...args) + { + typename product_map::const_iterator pos=map_.find(key); + if (pos!=map_.end()) + { + return (pos->second)(args...); + } + return 0; + } +}; + +}} + +#endif diff --git a/include/mbgl/util/image_reader.hpp b/include/mbgl/util/image_reader.hpp new file mode 100644 index 00000000000..4e804394667 --- /dev/null +++ b/include/mbgl/util/image_reader.hpp @@ -0,0 +1,50 @@ +#ifndef MBGL_UTIL_IMAGE_READER_HPP +#define MBGL_UTIL_IMAGE_READER_HPP + +#include "factory.hpp" +#include "noncopyable.hpp" +// stl +#include +#include + +namespace mbgl { namespace util { + +class image_reader_exception : public std::exception +{ +private: + std::string message_; +public: + image_reader_exception(std::string const& message) + : message_(message) {} + + ~image_reader_exception() throw() {} + + virtual const char* what() const throw() + { + return message_.c_str(); + } +}; + +struct image_reader : private noncopyable +{ + virtual unsigned width() const=0; + virtual unsigned height() const=0; + virtual bool has_alpha() const=0; + virtual bool premultiplied_alpha() const=0; + virtual void read(unsigned x,unsigned y, unsigned width, unsigned height, char* image)=0; + virtual ~image_reader() {} +}; + +template +bool register_image_reader(std::string const& type, image_reader* (* fun)(Args...)) +{ + return factory::instance().register_product(type, fun); +} + +//image_reader* get_image_reader(std::string const& file,std::string const& type); +//image_reader* get_image_reader(std::string const& file); +image_reader* get_image_reader(char const* data, size_t size); + +}} + +#endif diff --git a/include/mbgl/util/singleton.hpp b/include/mbgl/util/singleton.hpp new file mode 100644 index 00000000000..a1c1e3ebffe --- /dev/null +++ b/include/mbgl/util/singleton.hpp @@ -0,0 +1,126 @@ +#ifndef MBGL_UTIL_SINGLETON_HPP +#define MBGL_UTIL_SINGLETON_HPP + +// stl +#include // std::runtime_error +#include // std::atexit +#include // operator new +#define SINGLETON_THREADSAFE +#ifdef SINGLETON_THREADSAFE +#include +#endif + +namespace mbgl { namespace util { + +template +class CreateUsingNew +{ +public: + static T* create() + { + return new T; + } + static void destroy(T* obj) + { + delete obj; + } +}; + +template +class CreateStatic +{ +private: + union MaxAlign + { + char t_[sizeof(T)]; + short int shortInt_; + int int_; + long int longInt_; + float float_; + double double_; + long double longDouble_; + struct Test; + int Test::* pMember_; + int (Test::*pMemberFn_)(int); + }; + +public: + + static T* create() + { + static MaxAlign staticMemory; + return new(&staticMemory) T; + } + static void destroy(volatile T* obj) + { + obj->~T(); + } +}; + +template class CreatePolicy=CreateStatic> class singleton +{ + friend class CreatePolicy; + static T* pInstance_; + static bool destroyed_; + singleton(const singleton &rhs); + singleton& operator=(const singleton&); + + static void onDeadReference() + { + throw std::runtime_error("dead reference!"); + } + + static void DestroySingleton() + { + CreatePolicy::destroy(pInstance_); + pInstance_ = 0; + destroyed_ = true; + } + +protected: + +#ifdef SINGLETON_THREADSAFE + static std::mutex mutex_; +#endif + singleton() {} + public: + static T& instance() + { + if (! pInstance_) + { +#ifdef SINGLETON_THREADSAFE + std::unique_lock lock(mutex_); +#endif + if (! pInstance_) + { + if (destroyed_) + { + destroyed_ = false; + onDeadReference(); + } + else + { + pInstance_ = CreatePolicy::create(); + // register destruction + std::atexit(&DestroySingleton); + } + } + } + return *pInstance_; + } +}; + +#ifdef SINGLETON_THREADSAFE + template class CreatePolicy> std::mutex singleton::mutex_; +#endif + + template class CreatePolicy> T* singleton::pInstance_=0; + template class CreatePolicy> bool singleton::destroyed_=false; + +}} + +#endif // diff --git a/linux/mapboxgl-app.gyp b/linux/mapboxgl-app.gyp index c4be409be3f..c5aad61647d 100644 --- a/linux/mapboxgl-app.gyp +++ b/linux/mapboxgl-app.gyp @@ -12,10 +12,15 @@ '../platform/default/settings_json.cpp', '../platform/default/glfw_view.cpp', '../platform/default/log_stderr.cpp', + '../platform/default/image_reader.cpp', + '../platform/default/png_reader.cpp', + '../platform/default/jpeg_reader.cpp', ], 'xcode_settings': { 'OTHER_CPLUSPLUSFLAGS':[ '<@(glfw3_cflags)', + '<@(png_cflags)', + '<@(jpeg_cflags)', ], }, 'cflags_cc': [ diff --git a/platform/default/image.cpp b/platform/default/image.cpp index 68d17869137..397a6b19289 100644 --- a/platform/default/image.cpp +++ b/platform/default/image.cpp @@ -6,7 +6,7 @@ #include #include #include - +#include namespace mbgl { namespace util { @@ -58,119 +58,23 @@ std::string compress_png(int width, int height, void *rgba) { return result; } - -struct Buffer { - Buffer(const std::string& data_) - : data(data_.data()), length(data_.size()) {} - const char *const data = 0; - const size_t length = 0; - size_t pos = 0; -}; - -void readCallback(png_structp png, png_bytep data, png_size_t length) { - Buffer *reader = static_cast(png_get_io_ptr(png)); - - // Read `length` bytes into `data`. - if (reader->pos + length > reader->length) { - png_error(png, "Read Error"); - } else { - std::memcpy(data, reader->data + reader->pos, length); - reader->pos += length; - } -} - -void errorHandler(png_structp, png_const_charp error_msg) { - throw std::runtime_error(error_msg); -} - -void warningHandler(png_structp, png_const_charp error_msg) { - fprintf(stderr, "PNG: %s\n", error_msg); -} - -Image::Image(const std::string &data) { - Buffer buffer(data); - - if (buffer.length < 8 || !png_check_sig((const png_bytep)buffer.data, 8)) { - fprintf(stderr, "image is not a valid PNG image\n"); - return; - } - - png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, errorHandler, warningHandler); - assert(png); - - png_infop info = png_create_info_struct(png); - assert(info); - - int depth, color, interlace; - - try { - png_set_read_fn(png, (png_voidp)&buffer, readCallback); - png_read_info(png, info); - png_get_IHDR(png, info, (png_uint_32*)&width, (png_uint_32*)&height, &depth, &color, &interlace, nullptr, nullptr); - bool alpha = (color & PNG_COLOR_MASK_ALPHA) || png_get_valid(png, info, PNG_INFO_tRNS); - - // From http://trac.mapnik.org/browser/trunk/src/png_reader.cpp - if (color == PNG_COLOR_TYPE_PALETTE) - png_set_expand(png); - if (color == PNG_COLOR_TYPE_GRAY) - png_set_expand(png); - if (png_get_valid(png, info, PNG_INFO_tRNS)) - png_set_expand(png); - if (depth == 16) - png_set_strip_16(png); - if (depth < 8) - png_set_packing(png); - if (color == PNG_COLOR_TYPE_GRAY || - color == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png); - - if (interlace == PNG_INTERLACE_ADAM7) - png_set_interlace_handling(png); - - // Always add an alpha channel. - if (!alpha) { - png_set_add_alpha(png, 0xFF, PNG_FILLER_AFTER); - } - - double gamma; - if (png_get_gAMA(png, info, &gamma)) - png_set_gamma(png, 2.2, gamma); - - png_set_alpha_mode(png, PNG_ALPHA_PREMULTIPLIED, 2.2); - - png_read_update_info(png, info); - - png_size_t rowbytes = png_get_rowbytes(png, info); - assert(width * 4 == rowbytes); - +Image::Image(std::string const& data) +{ + try + { + std::unique_ptr reader(get_image_reader(data.c_str(), data.size())); + width = reader->width(); + height = reader->height(); img = ::std::unique_ptr(new char[width * height * 4]()); - - char *surface = img.get(); - assert(surface); - - struct ptrs { - ptrs(size_t count) : rows(new png_bytep[count]) {} - ~ptrs() { delete[] rows; } - png_bytep *rows = nullptr; - } pointers(height); - for (unsigned i = 0; i < height; ++i) { - pointers.rows[i] = (png_bytep)(surface + (i * rowbytes)); - } - - // Read image data - png_read_image(png, pointers.rows); - - png_read_end(png, nullptr); - - png_destroy_read_struct(&png, &info, nullptr); - } catch (std::exception& e) { - fprintf(stderr, "loading PNG failed: %s\n", e.what()); - png_destroy_read_struct(&png, &info, nullptr); - if (img) { - img.reset(); - } + reader->read(0, 0, width, height, img.get()); + } + catch (image_reader_exception const& ex) + { + fprintf(stderr, "ImageReader: %s\n", ex.what()); + img.reset(); width = 0; height = 0; + } } diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp new file mode 100644 index 00000000000..75d7b0c139c --- /dev/null +++ b/platform/default/image_reader.cpp @@ -0,0 +1,67 @@ +#include "mbgl/util/image_reader.hpp" +#include + +namespace mbgl { namespace util { + +inline boost::optional type_from_bytes(char const* data, size_t size) +{ + using result_type = boost::optional; + if (size >= 4) + { + unsigned int magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + if (magic == 0x89504E47U) + { + return result_type("png"); + } + else if (magic == 0x49492A00 || magic == 0x4D4D002A) + { + return result_type("tiff"); + } + } + if (size>=2) + { + unsigned int magic = ((data[0] << 8) | data[1]) & 0xffff; + if (magic == 0xffd8) + { + return result_type("jpeg"); + } + } + + 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(); +} + +image_reader* get_image_reader(char const* data, size_t size) +{ + boost::optional type = type_from_bytes(data,size); + if (type) + { + return factory::instance().create_object(*type, data,size); + } + else + throw image_reader_exception("image_reader: can't determine type from input data"); +} + +//image_reader* get_image_reader(std::string const& filename,std::string const& type) +//{ +// return factory::instance().create_object(type,filename); +//} + +//image_reader* get_image_reader(std::string const& filename) +//{ + //boost::optional type = type_from_filename(filename); + //if (type) + //{ + // return factory::instance().create_object(*type,filename); + //} +// return 0; +//} + +}} diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp new file mode 100644 index 00000000000..de93cfad250 --- /dev/null +++ b/platform/default/jpeg_reader.cpp @@ -0,0 +1,291 @@ +#include "mbgl/util/image_reader.hpp" +//#include + +// jpeg +extern "C" +{ +#include +} + +// boost +#pragma GCC diagnostic push +//#pragma GCC diagnostic ignored "-Wunused-local-typedef" +#include +#include +#include +#pragma GCC diagnostic pop + +// std +#include +#include + +namespace mbgl { namespace util { + +template +class jpeg_reader : public image_reader +{ +public: + using source_type = T; + using input_stream = boost::iostreams::stream; + const static unsigned BUF_SIZE = 4096; +private: + struct jpeg_stream_wrapper + { + jpeg_source_mgr manager; + input_stream * stream; + JOCTET buffer[BUF_SIZE]; + }; + + struct jpeg_info_guard + { + jpeg_info_guard(jpeg_decompress_struct * cinfo) + : i_(cinfo) {} + + ~jpeg_info_guard() + { + jpeg_destroy_decompress(i_); + } + jpeg_decompress_struct * i_; + }; + +private: + source_type source_; + input_stream stream_; + unsigned width_; + unsigned height_; +public: + explicit jpeg_reader(std::string const& file_name); + explicit jpeg_reader(char const* data, size_t size); + ~jpeg_reader(); + unsigned width() const; + unsigned height() const; + inline bool has_alpha() const { return false; } + inline bool premultiplied_alpha() const { return true; } + void read(unsigned x,unsigned y, unsigned width, unsigned height, char *image); +private: + void init(); + static void on_error(j_common_ptr cinfo); + static void on_error_message(j_common_ptr cinfo); + static void init_source(j_decompress_ptr cinfo); + static boolean fill_input_buffer(j_decompress_ptr cinfo); + static void skip(j_decompress_ptr cinfo, long count); + static void term(j_decompress_ptr cinfo); + static void attach_stream(j_decompress_ptr cinfo, input_stream* in); +}; + +namespace +{ +image_reader* create_jpeg_reader(std::string const& file) +{ + return new jpeg_reader(file); +} + +image_reader* create_jpeg_reader2(char const* data, size_t size) +{ + return new jpeg_reader(data, size); +} + +const bool registered = register_image_reader("jpeg",create_jpeg_reader); +const bool registered2 = register_image_reader("jpeg",create_jpeg_reader2); +} + +// ctors +template +jpeg_reader::jpeg_reader(std::string const& file_name) + : source_(file_name,std::ios_base::in | std::ios_base::binary), + stream_(source_), + width_(0), + height_(0) +{ + if (!stream_) throw image_reader_exception("cannot open image file "+ file_name); + init(); +} + +template +jpeg_reader::jpeg_reader(char const* data, size_t size) + : source_(data, size), + stream_(source_), + width_(0), + height_(0) +{ + if (!stream_) throw image_reader_exception("cannot open image stream"); + init(); +} + +// dtor +template +jpeg_reader::~jpeg_reader() {} + +// jpeg stream wrapper +template +void jpeg_reader::init_source (j_decompress_ptr cinfo) +{ + jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); + wrap->stream->seekg(0,std::ios_base::beg); +} + +template +boolean jpeg_reader::fill_input_buffer (j_decompress_ptr cinfo) +{ + jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); + wrap->stream->read(reinterpret_cast(&wrap->buffer[0]),BUF_SIZE); + std::streamsize size = wrap->stream->gcount(); + wrap->manager.next_input_byte = wrap->buffer; + wrap->manager.bytes_in_buffer = BUF_SIZE; + return (size > 0) ? TRUE : FALSE; +} + +template +void jpeg_reader::skip(j_decompress_ptr cinfo, long count) +{ + if (count <= 0) return; //A zero or negative skip count should be treated as a no-op. + jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); + + if (wrap->manager.bytes_in_buffer > 0 && count < static_cast(wrap->manager.bytes_in_buffer)) + { + wrap->manager.bytes_in_buffer -= count; + wrap->manager.next_input_byte = &wrap->buffer[BUF_SIZE - wrap->manager.bytes_in_buffer]; + } + else + { + wrap->stream->seekg(count - wrap->manager.bytes_in_buffer, std::ios_base::cur); + // trigger buffer fill + wrap->manager.next_input_byte = 0; + wrap->manager.bytes_in_buffer = 0; //bytes_in_buffer may be zero on return. + } +} + +template +void jpeg_reader::term (j_decompress_ptr /*cinfo*/) +{ +// no-op +} + +template +void jpeg_reader::attach_stream (j_decompress_ptr cinfo, input_stream* in) +{ + if (cinfo->src == 0) + { + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(jpeg_stream_wrapper)); + } + jpeg_reader::jpeg_stream_wrapper * src = reinterpret_cast (cinfo->src); + src->manager.init_source = init_source; + src->manager.fill_input_buffer = fill_input_buffer; + src->manager.skip_input_data = skip; + src->manager.resync_to_restart = jpeg_resync_to_restart; + src->manager.term_source = term; + src->manager.bytes_in_buffer = 0; + src->manager.next_input_byte = 0; + src->stream = in; +} + +template +void jpeg_reader::on_error(j_common_ptr /*cinfo*/) +{ +} + +template +void jpeg_reader::on_error_message(j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, buffer); + throw image_reader_exception(std::string("JPEG Reader: libjpeg could not read image: ") + buffer); +} + +template +void jpeg_reader::init() +{ + jpeg_decompress_struct cinfo; + jpeg_info_guard iguard(&cinfo); + jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + jerr.error_exit = on_error; + jerr.output_message = on_error_message; + jpeg_create_decompress(&cinfo); + attach_stream(&cinfo, &stream_); + int ret = jpeg_read_header(&cinfo, TRUE); + if (ret != JPEG_HEADER_OK) + throw image_reader_exception("JPEG Reader: failed to read header"); + jpeg_start_decompress(&cinfo); + width_ = cinfo.output_width; + height_ = cinfo.output_height; + + if (cinfo.out_color_space == JCS_UNKNOWN) + { + throw image_reader_exception("JPEG Reader: failed to read unknown color space"); + } + if (cinfo.output_width == 0 || cinfo.output_height == 0) + { + throw image_reader_exception("JPEG Reader: failed to read image size of"); + } +} + +template +unsigned jpeg_reader::width() const +{ + return width_; +} + +template +unsigned jpeg_reader::height() const +{ + return height_; +} + +template +void jpeg_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned height, char* image) +{ + stream_.clear(); + stream_.seekg(0, std::ios_base::beg); + + jpeg_decompress_struct cinfo; + jpeg_info_guard iguard(&cinfo); + jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + jerr.error_exit = on_error; + jerr.output_message = on_error_message; + jpeg_create_decompress(&cinfo); + attach_stream(&cinfo, &stream_); + int ret = jpeg_read_header(&cinfo, TRUE); + if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader read(): failed to read header"); + jpeg_start_decompress(&cinfo); + JSAMPARRAY buffer; + int row_stride; + unsigned char 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(width,width_ - x0); + unsigned h = std::min(height,height_ - y0); + + const std::unique_ptr out_row(new unsigned int[w]); + unsigned row = 0; + while (cinfo.output_scanline < cinfo.output_height) + { + jpeg_read_scanlines(&cinfo, buffer, 1); + if (row >= y0 && row < y0 + h) + { + for (unsigned int x = 0; x < w; ++x) + { + unsigned col = x + x0; + r = buffer[0][cinfo.output_components * col]; + if (cinfo.output_components > 2) + { + g = buffer[0][cinfo.output_components * col + 1]; + b = buffer[0][cinfo.output_components * col + 2]; + } else { + g = r; + b = r; + } + out_row[x] = (0xff << 24) | (b << 16) | (g << 8) | r;//color(r, g, b, a).rgba(); + } + //image.setRow(row - y0, out_row.get(), w); + std::copy((char*)out_row.get(), (char*)out_row.get() + w*4, image + (row - y0)*width_*4); + } + ++row; + } + jpeg_finish_decompress(&cinfo); +} + +}} diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp new file mode 100644 index 00000000000..1780ecf23ce --- /dev/null +++ b/platform/default/png_reader.cpp @@ -0,0 +1,279 @@ +#include "mbgl/util/image_reader.hpp" +#include +extern "C" +{ +#include +} +// boost +#pragma GCC diagnostic push +//#pragma GCC diagnostic ignored "-Wunused-local-typedef" +#include +#include +#include +#pragma GCC diagnostic pop + +// stl +#include +#include + +namespace mbgl { namespace util { + +template +class png_reader : public image_reader +{ + using source_type = T; + using input_stream = boost::iostreams::stream; + + struct png_struct_guard + { + png_struct_guard(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) + : p_(png_ptr_ptr), + i_(info_ptr_ptr) {} + + ~png_struct_guard() + { + png_destroy_read_struct(p_,i_,0); + } + png_structpp p_; + png_infopp i_; + }; + +private: + + source_type source_; + input_stream stream_; + unsigned width_; + unsigned height_; + int bit_depth_; + int color_type_; + bool has_alpha_; +public: + explicit png_reader(std::string const& file_name); + png_reader(char const* data, std::size_t size); + ~png_reader(); + unsigned width() const; + unsigned height() const; + inline bool has_alpha() const { return has_alpha_; } + bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html + void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image); +private: + void init(); + static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); +}; + +namespace +{ + +image_reader* create_png_reader(std::string const& file) +{ + return new png_reader(file); +} + +image_reader* create_png_reader2(char const * data, std::size_t size) +{ + return new png_reader(data, size); +} + +const bool registered = register_image_reader("png",create_png_reader); +const bool registered2 = register_image_reader("png", create_png_reader2); +} + + +void user_error_fn(png_structp /*png_ptr*/, png_const_charp error_msg) +{ + throw image_reader_exception(std::string("failed to read invalid png: '") + error_msg + "'"); +} + +void user_warning_fn(png_structp /*png_ptr*/, png_const_charp warning_msg) +{ + fprintf(stderr, "ImageReader (PNG): %s\n", warning_msg); + +} + +template +void png_reader::png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + input_stream * fin = reinterpret_cast(png_get_io_ptr(png_ptr)); + fin->read(reinterpret_cast(data), length); + std::streamsize read_count = fin->gcount(); + if (read_count < 0 || static_cast(read_count) != length) + { + png_error(png_ptr, "Read Error"); + } +} + +template +png_reader::png_reader(std::string const& file_name) + : source_(file_name,std::ios_base::in | std::ios_base::binary), + stream_(source_), + width_(0), + height_(0), + bit_depth_(0), + color_type_(0), + has_alpha_(false) +{ + if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'"); + if (!stream_) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'"); + init(); +} + +template +png_reader::png_reader(char const* data, std::size_t size) + : source_(data,size), + stream_(source_), + width_(0), + height_(0), + bit_depth_(0), + color_type_(0), + has_alpha_(false) +{ + + if (!stream_) throw image_reader_exception("PNG reader: cannot open image stream"); + init(); +} + + +template +png_reader::~png_reader() {} + + +template +void png_reader::init() +{ + png_byte header[8]; + std::memset(header,0,8); + stream_.read(reinterpret_cast(header),8); + if ( stream_.gcount() != 8) + { + throw image_reader_exception("PNG reader: Could not read image"); + } + int is_png=!png_sig_cmp(header,0,8); + if (!is_png) + { + throw image_reader_exception("File or stream is not a png"); + } + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING,0,0,0); + + if (!png_ptr) + { + throw image_reader_exception("failed to allocate png_ptr"); + } + + // catch errors in a custom way to avoid the need for setjmp + png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn); + + png_infop info_ptr; + png_struct_guard sguard(&png_ptr,&info_ptr); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) throw image_reader_exception("failed to create info_ptr"); + + png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data); + + png_set_sig_bytes(png_ptr,8); + png_read_info(png_ptr, info_ptr); + + png_uint_32 width, height; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth_, &color_type_,0,0,0); + has_alpha_ = (color_type_ & PNG_COLOR_MASK_ALPHA) || png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); + width_=width; + height_=height; + + //MAPNIK_LOG_DEBUG(png_reader) << "png_reader: bit_depth=" << bit_depth_ << ",color_type=" << color_type_; +} + +template +unsigned png_reader::width() const +{ + return width_; +} + +template +unsigned png_reader::height() const +{ + return height_; +} + +template +void png_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned height, char * image) +{ + stream_.clear(); + stream_.seekg(0, std::ios_base::beg); + + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING,0,0,0); + + if (!png_ptr) + { + throw image_reader_exception("failed to allocate png_ptr"); + } + + // catch errors in a custom way to avoid the need for setjmp + png_set_error_fn(png_ptr, png_get_error_ptr(png_ptr), user_error_fn, user_warning_fn); + + png_infop info_ptr; + png_struct_guard sguard(&png_ptr,&info_ptr); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) throw image_reader_exception("failed to create info_ptr"); + + png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data); + png_read_info(png_ptr, info_ptr); + + if (color_type_ == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png_ptr); + if (color_type_ == PNG_COLOR_TYPE_GRAY && bit_depth_ < 8) + png_set_expand(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_expand(png_ptr); + if (bit_depth_ == 16) + png_set_strip_16(png_ptr); + if (color_type_ == PNG_COLOR_TYPE_GRAY || + color_type_ == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + // quick hack -- only work in >=libpng 1.2.7 + png_set_add_alpha(png_ptr,0xff,PNG_FILLER_AFTER); //rgba + + double gamma; + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, 2.2, gamma); + + if (x0 == 0 && y0 == 0 && width >= width_ && height >= height_) + { + if (png_get_interlace_type(png_ptr,info_ptr) == PNG_INTERLACE_ADAM7) + { + png_set_interlace_handling(png_ptr); // FIXME: libpng bug? + // according to docs png_read_image + // "..automatically handles interlacing, + // so you don't need to call png_set_interlace_handling()" + } + png_read_update_info(png_ptr, info_ptr); + // we can read whole image at once + // alloc row pointers + const std::unique_ptr rows(new png_bytep[height_]); + for (unsigned row = 0; row < height_; ++row) + rows[row] = (png_bytep)image + row * width_ ; + png_read_image(png_ptr, rows.get()); + } + else + { + png_read_update_info(png_ptr, info_ptr); + //unsigned w=std::min(width, width_ - x0); + unsigned h=std::min(height, height_ - y0); + unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr); + const std::unique_ptr row(new png_byte[rowbytes]); + //START read image rows + for (unsigned i = 0; i < height_; ++i) + { + png_read_row(png_ptr,row.get(),0); + if (i >= y0 && i < (y0 + h)) + { +////image.setRow(i-y0,reinterpret_cast(&row[x0 * 4]),w); + //std::copy(image, buf + size, pData_ + i * width); + } + } + //END + } + png_read_end(png_ptr,0); +} +}} From aafb1280b25a24df94d885f8503bbd5d600cfaa6 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 7 Nov 2014 15:20:34 +0000 Subject: [PATCH 03/24] add cflags for linux builds --- linux/mapboxgl-app.gyp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux/mapboxgl-app.gyp b/linux/mapboxgl-app.gyp index c5aad61647d..45137dd3861 100644 --- a/linux/mapboxgl-app.gyp +++ b/linux/mapboxgl-app.gyp @@ -25,6 +25,8 @@ }, 'cflags_cc': [ '<@(glfw3_cflags)', + '<@(png_cflags)', + '<@(jpeg_cflags)', '-I<(boost_root)/include', ], 'variables': { From dfeab9f921af92d9112ecb43f9889b91bd59ce66 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 7 Nov 2014 15:31:18 +0000 Subject: [PATCH 04/24] move image_reader to mbgl-linux --- gyp/mbgl-linux.gypi | 1 + linux/mapboxgl-app.gyp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gyp/mbgl-linux.gypi b/gyp/mbgl-linux.gypi index a2bc51fc8e0..a66a80ebfa2 100644 --- a/gyp/mbgl-linux.gypi +++ b/gyp/mbgl-linux.gypi @@ -31,6 +31,7 @@ '../platform/default/string_stdlib.cpp', '../platform/default/http_request_baton_curl.cpp', '../platform/default/image.cpp', + '../platform/default/image_reader.cpp', ], 'include_dirs': [ '../include', diff --git a/linux/mapboxgl-app.gyp b/linux/mapboxgl-app.gyp index 45137dd3861..dbcc4b44791 100644 --- a/linux/mapboxgl-app.gyp +++ b/linux/mapboxgl-app.gyp @@ -12,7 +12,6 @@ '../platform/default/settings_json.cpp', '../platform/default/glfw_view.cpp', '../platform/default/log_stderr.cpp', - '../platform/default/image_reader.cpp', '../platform/default/png_reader.cpp', '../platform/default/jpeg_reader.cpp', ], From 5d29742e1c9b944599c100a76a2aecbf87cefa50 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 7 Nov 2014 15:52:30 +0000 Subject: [PATCH 05/24] fix tests for linux (todo - find a better way to run 'linux' tests on 'osx') --- test/test.gyp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test.gyp b/test/test.gyp index 2c6f411cf93..b245a057b81 100644 --- a/test/test.gyp +++ b/test/test.gyp @@ -163,6 +163,7 @@ 'type': 'executable', 'sources': [ './headless.cpp', + '../platform/default/png_reader.cpp', './fixtures/fixture_log.cpp', ], 'conditions': [ @@ -170,12 +171,12 @@ ['OS == "mac"', { 'xcode_settings': { - 'OTHER_CPLUSPLUSFLAGS': ['<@(uv_cflags)'], + 'OTHER_CPLUSPLUSFLAGS': ['<@(uv_cflags)','<@(png_cflags)'], 'OTHER_LDFLAGS': ['<@(glfw3_ldflags)', '<@(ldflags)'], }, }, { - 'cflags': ['<@(uv_cflags)'], + 'cflags': ['<@(uv_cflags)','<@(png_cflags)'], 'libraries': ['<@(glfw3_ldflags)', '<@(ldflags)'], }], ], From 9fd9ced95647a721e9c2f7f539ce9dfac3356f43 Mon Sep 17 00:00:00 2001 From: artemp Date: Thu, 13 Nov 2014 15:43:35 +0000 Subject: [PATCH 06/24] cleanups --- platform/default/jpeg_reader.cpp | 3 +-- platform/default/png_reader.cpp | 23 +++++++++-------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index de93cfad250..3f693379278 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -278,9 +278,8 @@ void jpeg_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned hei g = r; b = r; } - out_row[x] = (0xff << 24) | (b << 16) | (g << 8) | r;//color(r, g, b, a).rgba(); + out_row[x] = (0xff << 24) | (b << 16) | (g << 8) | r; } - //image.setRow(row - y0, out_row.get(), w); std::copy((char*)out_row.get(), (char*)out_row.get() + w*4, image + (row - y0)*width_*4); } ++row; diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 1780ecf23ce..580c1743033 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -173,13 +173,11 @@ void png_reader::init() png_set_sig_bytes(png_ptr,8); png_read_info(png_ptr, info_ptr); - png_uint_32 width, height; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth_, &color_type_,0,0,0); + png_uint_32 w, h; + png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth_, &color_type_,0,0,0); has_alpha_ = (color_type_ & PNG_COLOR_MASK_ALPHA) || png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); - width_=width; - height_=height; - - //MAPNIK_LOG_DEBUG(png_reader) << "png_reader: bit_depth=" << bit_depth_ << ",color_type=" << color_type_; + width_=w; + height_=h; } template @@ -195,7 +193,7 @@ unsigned png_reader::height() const } template -void png_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned height, char * image) +void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * image) { stream_.clear(); stream_.seekg(0, std::ios_base::beg); @@ -238,7 +236,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned heig if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, 2.2, gamma); - if (x0 == 0 && y0 == 0 && width >= width_ && height >= height_) + if (x0 == 0 && y0 == 0 && w >= width_ && h >= height_) { if (png_get_interlace_type(png_ptr,info_ptr) == PNG_INTERLACE_ADAM7) { @@ -258,21 +256,18 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned heig else { png_read_update_info(png_ptr, info_ptr); - //unsigned w=std::min(width, width_ - x0); - unsigned h=std::min(height, height_ - y0); + w=std::min(w, width_ - x0); + h=std::min(h, height_ - y0); unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr); const std::unique_ptr row(new png_byte[rowbytes]); - //START read image rows for (unsigned i = 0; i < height_; ++i) { png_read_row(png_ptr,row.get(),0); if (i >= y0 && i < (y0 + h)) { -////image.setRow(i-y0,reinterpret_cast(&row[x0 * 4]),w); - //std::copy(image, buf + size, pData_ + i * width); + std::copy(&row[x0 * 4], &row[x0 * 4] + w, image + i * width_* 4); } } - //END } png_read_end(png_ptr,0); } From b62da09cbfd118b432b179f0a56304c31bf69b7f Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 14 Nov 2014 11:26:59 +0100 Subject: [PATCH 07/24] fix linux build --- platform/default/jpeg_reader.cpp | 12 ++++++------ platform/default/png_reader.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index 3f693379278..c838b2821cb 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -61,7 +61,7 @@ class jpeg_reader : public image_reader unsigned height() const; inline bool has_alpha() const { return false; } inline bool premultiplied_alpha() const { return true; } - void read(unsigned x,unsigned y, unsigned width, unsigned height, char *image); + void read(unsigned x,unsigned y, unsigned w, unsigned h, char *image); private: void init(); static void on_error(j_common_ptr cinfo); @@ -85,8 +85,8 @@ image_reader* create_jpeg_reader2(char const* data, size_t size) return new jpeg_reader(data, size); } -const bool registered = register_image_reader("jpeg",create_jpeg_reader); -const bool registered2 = register_image_reader("jpeg",create_jpeg_reader2); +const static bool registered = register_image_reader("jpeg",create_jpeg_reader); +const static bool registered2 = register_image_reader("jpeg",create_jpeg_reader2); } // ctors @@ -234,7 +234,7 @@ unsigned jpeg_reader::height() const } template -void jpeg_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned height, char* image) +void jpeg_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char* image) { stream_.clear(); stream_.seekg(0, std::ios_base::beg); @@ -256,8 +256,8 @@ void jpeg_reader::read(unsigned x0, unsigned y0, unsigned width, unsigned hei 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(width,width_ - x0); - unsigned h = std::min(height,height_ - y0); + w = std::min(w,width_ - x0); + h = std::min(h,height_ - y0); const std::unique_ptr out_row(new unsigned int[w]); unsigned row = 0; diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 580c1743033..b11de9a92ca 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -74,8 +74,8 @@ image_reader* create_png_reader2(char const * data, std::size_t size) return new png_reader(data, size); } -const bool registered = register_image_reader("png",create_png_reader); -const bool registered2 = register_image_reader("png", create_png_reader2); +const static bool registered = register_image_reader("png",create_png_reader); +const static bool registered2 = register_image_reader("png", create_png_reader2); } From e3adc4664babecadbbc70b73241b28681c273c74 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 14 Nov 2014 11:40:35 +0100 Subject: [PATCH 08/24] remove unused pragmas --- platform/default/jpeg_reader.cpp | 4 ---- platform/default/png_reader.cpp | 4 +--- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index c838b2821cb..d56c10af2a0 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -1,5 +1,4 @@ #include "mbgl/util/image_reader.hpp" -//#include // jpeg extern "C" @@ -8,12 +7,9 @@ extern "C" } // boost -#pragma GCC diagnostic push -//#pragma GCC diagnostic ignored "-Wunused-local-typedef" #include #include #include -#pragma GCC diagnostic pop // std #include diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index b11de9a92ca..33d17a1b82d 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -4,13 +4,11 @@ extern "C" { #include } + // boost -#pragma GCC diagnostic push -//#pragma GCC diagnostic ignored "-Wunused-local-typedef" #include #include #include -#pragma GCC diagnostic pop // stl #include From 761b2ba5836e4c7349f3dd3ae034ded07e9dbbb3 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 14 Nov 2014 12:23:27 +0100 Subject: [PATCH 09/24] simplify factory class to not rely on singleton + cleanups --- include/mbgl/util/factory.hpp | 25 +++++++++++++++---------- include/mbgl/util/image_reader.hpp | 4 +--- platform/default/image_reader.cpp | 17 +---------------- 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/include/mbgl/util/factory.hpp b/include/mbgl/util/factory.hpp index eb1c22933a0..1ffcac6f929 100644 --- a/include/mbgl/util/factory.hpp +++ b/include/mbgl/util/factory.hpp @@ -1,10 +1,9 @@ #ifndef MBGL_UTIL_FACTORY_HPP #define MBGL_UTIL_FACTORY_HPP -#include "singleton.hpp" - // stl #include +#include #include namespace mbgl { namespace util { @@ -14,27 +13,28 @@ template typename product_type, typename key_type, typename ...Args > -class factory : public singleton > +class factory { -private: +public: using product_creator = product_type* (*) (Args...); using product_map = std::map; - product_map map_; + static product_map map_; + static std::mutex mutex_; public: - bool register_product(key_type const& key, product_creator creator) + static bool register_product(key_type const& key, product_creator creator) { + std::unique_lock lock(mutex_); return map_.insert(typename product_map::value_type(key,creator)).second; } - bool unregister_product(const key_type& key) + static bool unregister_product(const key_type& key) { + std::unique_lock lock(mutex_); return map_.erase(key)==1; } - product_type* create_object(key_type const& key, Args...args) + static product_type* create_object(key_type const& key, Args...args) { typename product_map::const_iterator pos=map_.find(key); if (pos!=map_.end()) @@ -45,6 +45,11 @@ class factory : public singleton +typename factory::product_map factory::map_; +template +typename std::mutex factory::mutex_; + }} #endif diff --git a/include/mbgl/util/image_reader.hpp b/include/mbgl/util/image_reader.hpp index 4e804394667..144127b76e8 100644 --- a/include/mbgl/util/image_reader.hpp +++ b/include/mbgl/util/image_reader.hpp @@ -38,11 +38,9 @@ struct image_reader : private noncopyable template bool register_image_reader(std::string const& type, image_reader* (* fun)(Args...)) { - return factory::instance().register_product(type, fun); + return factory::register_product(type, fun); } -//image_reader* get_image_reader(std::string const& file,std::string const& type); -//image_reader* get_image_reader(std::string const& file); image_reader* get_image_reader(char const* data, size_t size); }} diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index 75d7b0c139c..53ab5758aa8 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -43,25 +43,10 @@ image_reader* get_image_reader(char const* data, size_t size) boost::optional type = type_from_bytes(data,size); if (type) { - return factory::instance().create_object(*type, data,size); + return factory::create_object(*type, data,size); } else throw image_reader_exception("image_reader: can't determine type from input data"); } -//image_reader* get_image_reader(std::string const& filename,std::string const& type) -//{ -// return factory::instance().create_object(type,filename); -//} - -//image_reader* get_image_reader(std::string const& filename) -//{ - //boost::optional type = type_from_filename(filename); - //if (type) - //{ - // return factory::instance().create_object(*type,filename); - //} -// return 0; -//} - }} From 23d3588f500f79cc5f532ae7aaf687aaacd6568d Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 14 Nov 2014 19:00:15 +0100 Subject: [PATCH 10/24] remove travis default installed libs which might conflict --- scripts/travis_script.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/travis_script.sh b/scripts/travis_script.sh index ea6097dc55b..4bd3333b591 100755 --- a/scripts/travis_script.sh +++ b/scripts/travis_script.sh @@ -10,6 +10,10 @@ if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then # # build & test Linux # + echo "removing potentially conflicting libraries" + # remove travis default installed libs which will conflict + sudo apt-get purge -qq -y libtiff* libjpeg* libpng3 + sudo apt-get autoremove -y -qq mapbox_time "compile_program" \ make linux -j$JOBS BUILDTYPE=${BUILDTYPE} @@ -26,9 +30,9 @@ if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then ./scripts/compare_images.sh if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then - mapbox_time_start "deploy_results" - (cd ./test/suite/ && ./bin/deploy_results.sh) - mapbox_time_finish + mapbox_time_start "deploy_results" + (cd ./test/suite/ && ./bin/deploy_results.sh) + mapbox_time_finish fi elif [[ ${TRAVIS_OS_NAME} == "osx" ]]; then From c8dea1024d6aa43749d5f8c0f2141a7010b5c3fb Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 14 Nov 2014 19:06:03 +0100 Subject: [PATCH 11/24] Revert "remove travis default installed libs which might conflict" This reverts commit 23d3588f500f79cc5f532ae7aaf687aaacd6568d. --- scripts/travis_script.sh | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/scripts/travis_script.sh b/scripts/travis_script.sh index 4bd3333b591..ea6097dc55b 100755 --- a/scripts/travis_script.sh +++ b/scripts/travis_script.sh @@ -10,10 +10,6 @@ if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then # # build & test Linux # - echo "removing potentially conflicting libraries" - # remove travis default installed libs which will conflict - sudo apt-get purge -qq -y libtiff* libjpeg* libpng3 - sudo apt-get autoremove -y -qq mapbox_time "compile_program" \ make linux -j$JOBS BUILDTYPE=${BUILDTYPE} @@ -30,9 +26,9 @@ if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then ./scripts/compare_images.sh if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then - mapbox_time_start "deploy_results" - (cd ./test/suite/ && ./bin/deploy_results.sh) - mapbox_time_finish + mapbox_time_start "deploy_results" + (cd ./test/suite/ && ./bin/deploy_results.sh) + mapbox_time_finish fi elif [[ ${TRAVIS_OS_NAME} == "osx" ]]; then From 9051ae17cf65339546b6328896f3d2854b16c861 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 17 Nov 2014 11:40:27 +0100 Subject: [PATCH 12/24] fix png_reader --- platform/default/png_reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 33d17a1b82d..76437dec38b 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -248,7 +248,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char // alloc row pointers const std::unique_ptr rows(new png_bytep[height_]); for (unsigned row = 0; row < height_; ++row) - rows[row] = (png_bytep)image + row * width_ ; + rows[row] = (png_bytep)image + row * width_ * 4 ; png_read_image(png_ptr, rows.get()); } else @@ -263,7 +263,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char png_read_row(png_ptr,row.get(),0); if (i >= y0 && i < (y0 + h)) { - std::copy(&row[x0 * 4], &row[x0 * 4] + w, image + i * width_* 4); + std::copy(&row[x0 * 4], &row[x0 * 4] + w * 4, image + i * width_* 4); } } } From 08357cfcf86ad0b6c8e8563767110ed50cbb2f56 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 17 Nov 2014 12:21:58 +0100 Subject: [PATCH 13/24] image-readers: only register readers that are used create_png_reader(char const* data, size_t size) create_jpeg_reader(char const* data, size_t size) --- platform/default/jpeg_reader.cpp | 10 ++-------- platform/default/png_reader.cpp | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index d56c10af2a0..f1e9d0fdfe3 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -71,18 +71,12 @@ class jpeg_reader : public image_reader namespace { -image_reader* create_jpeg_reader(std::string const& file) -{ - return new jpeg_reader(file); -} - -image_reader* create_jpeg_reader2(char const* data, size_t size) +image_reader* create_jpeg_reader(char const* data, size_t size) { return new jpeg_reader(data, size); } -const static bool registered = register_image_reader("jpeg",create_jpeg_reader); -const static bool registered2 = register_image_reader("jpeg",create_jpeg_reader2); +const static bool registered = register_image_reader("jpeg",create_jpeg_reader); } // ctors diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 76437dec38b..838344286ed 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -61,19 +61,13 @@ class png_reader : public image_reader namespace { - -image_reader* create_png_reader(std::string const& file) -{ - return new png_reader(file); -} - -image_reader* create_png_reader2(char const * data, std::size_t size) +image_reader* create_png_reader(char const * data, std::size_t size) { return new png_reader(data, size); } const static bool registered = register_image_reader("png",create_png_reader); -const static bool registered2 = register_image_reader("png", create_png_reader2); + } From 759a5e65cf853d679650339e26fef25141ab1901 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 19 Nov 2014 13:06:47 +0100 Subject: [PATCH 14/24] simplify image_readers creation implementation * remove static callbacks registration * link png_reader/jpeg_reader into mbgl-linux lib --- gyp/mbgl-linux.gypi | 3 + include/mbgl/util/factory.hpp | 55 ------------- include/mbgl/util/image_reader.hpp | 7 -- include/mbgl/util/jpeg_reader.hpp | 69 ++++++++++++++++ include/mbgl/util/png_reader.hpp | 62 ++++++++++++++ include/mbgl/util/singleton.hpp | 126 ----------------------------- linux/mapboxgl-app.gyp | 2 - platform/default/image_reader.cpp | 16 +++- platform/default/jpeg_reader.cpp | 87 ++------------------ platform/default/png_reader.cpp | 75 +---------------- test/test.gyp | 1 - 11 files changed, 156 insertions(+), 347 deletions(-) delete mode 100644 include/mbgl/util/factory.hpp create mode 100644 include/mbgl/util/jpeg_reader.hpp create mode 100644 include/mbgl/util/png_reader.hpp delete mode 100644 include/mbgl/util/singleton.hpp diff --git a/gyp/mbgl-linux.gypi b/gyp/mbgl-linux.gypi index a66a80ebfa2..aee928685af 100644 --- a/gyp/mbgl-linux.gypi +++ b/gyp/mbgl-linux.gypi @@ -8,6 +8,7 @@ 'variables': { 'cflags_cc': [ '<@(png_cflags)', + '<@(jpeg_cflags)', '<@(uv_cflags)', '<@(curl_cflags)', '<@(nu_cflags)', @@ -32,6 +33,8 @@ '../platform/default/http_request_baton_curl.cpp', '../platform/default/image.cpp', '../platform/default/image_reader.cpp', + '../platform/default/png_reader.cpp', + '../platform/default/jpeg_reader.cpp', ], 'include_dirs': [ '../include', diff --git a/include/mbgl/util/factory.hpp b/include/mbgl/util/factory.hpp deleted file mode 100644 index 1ffcac6f929..00000000000 --- a/include/mbgl/util/factory.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef MBGL_UTIL_FACTORY_HPP -#define MBGL_UTIL_FACTORY_HPP - -// stl -#include -#include -#include - -namespace mbgl { namespace util { - -template -< -typename product_type, -typename key_type, -typename ...Args > -class factory -{ -public: - using product_creator = product_type* (*) (Args...); - using product_map = std::map; - static product_map map_; - static std::mutex mutex_; -public: - - static bool register_product(key_type const& key, product_creator creator) - { - std::unique_lock lock(mutex_); - return map_.insert(typename product_map::value_type(key,creator)).second; - } - - static bool unregister_product(const key_type& key) - { - std::unique_lock lock(mutex_); - return map_.erase(key)==1; - } - - static product_type* create_object(key_type const& key, Args...args) - { - typename product_map::const_iterator pos=map_.find(key); - if (pos!=map_.end()) - { - return (pos->second)(args...); - } - return 0; - } -}; - -template -typename factory::product_map factory::map_; -template -typename std::mutex factory::mutex_; - -}} - -#endif diff --git a/include/mbgl/util/image_reader.hpp b/include/mbgl/util/image_reader.hpp index 144127b76e8..589653ec5c6 100644 --- a/include/mbgl/util/image_reader.hpp +++ b/include/mbgl/util/image_reader.hpp @@ -1,7 +1,6 @@ #ifndef MBGL_UTIL_IMAGE_READER_HPP #define MBGL_UTIL_IMAGE_READER_HPP -#include "factory.hpp" #include "noncopyable.hpp" // stl #include @@ -35,12 +34,6 @@ struct image_reader : private noncopyable virtual ~image_reader() {} }; -template -bool register_image_reader(std::string const& type, image_reader* (* fun)(Args...)) -{ - return factory::register_product(type, fun); -} - image_reader* get_image_reader(char const* data, size_t size); }} diff --git a/include/mbgl/util/jpeg_reader.hpp b/include/mbgl/util/jpeg_reader.hpp new file mode 100644 index 00000000000..77356007d89 --- /dev/null +++ b/include/mbgl/util/jpeg_reader.hpp @@ -0,0 +1,69 @@ +#ifndef MBGL_UTIL_JPEG_READER_HPP +#define MBGL_UTIL_JPEG_READER_HPP + +#include "image_reader.hpp" + +// jpeg +extern "C" +{ +#include +} + +#include + +namespace mbgl { namespace util { + +template +class jpeg_reader : public image_reader +{ +public: + using source_type = T; + using input_stream = boost::iostreams::stream; + const static unsigned BUF_SIZE = 4096; +private: + struct jpeg_stream_wrapper + { + jpeg_source_mgr manager; + input_stream * stream; + JOCTET buffer[BUF_SIZE]; + }; + + struct jpeg_info_guard + { + jpeg_info_guard(jpeg_decompress_struct * cinfo) + : i_(cinfo) {} + + ~jpeg_info_guard() + { + jpeg_destroy_decompress(i_); + } + jpeg_decompress_struct * i_; + }; + +private: + source_type source_; + input_stream stream_; + unsigned width_; + unsigned height_; +public: + jpeg_reader(char const* data, size_t size); + ~jpeg_reader(); + unsigned width() const; + unsigned height() const; + inline bool has_alpha() const { return false; } + inline bool premultiplied_alpha() const { return true; } + void read(unsigned x,unsigned y, unsigned w, unsigned h, char *image); +private: + void init(); + static void on_error(j_common_ptr cinfo); + static void on_error_message(j_common_ptr cinfo); + static void init_source(j_decompress_ptr cinfo); + static boolean fill_input_buffer(j_decompress_ptr cinfo); + static void skip(j_decompress_ptr cinfo, long count); + static void term(j_decompress_ptr cinfo); + static void attach_stream(j_decompress_ptr cinfo, input_stream* in); +}; + +}} + +#endif // MBGL_UTIL_JPEG_READER_HPP diff --git a/include/mbgl/util/png_reader.hpp b/include/mbgl/util/png_reader.hpp new file mode 100644 index 00000000000..3d6e1db51e6 --- /dev/null +++ b/include/mbgl/util/png_reader.hpp @@ -0,0 +1,62 @@ +#ifndef MBGL_UTIL_PNG_READER_HPP +#define MBGL_UTIL_PNG_READER_HPP + +#include "mbgl/util/image_reader.hpp" + +extern "C" +{ +#include +} + +#include +#include + +#include + +namespace mbgl { namespace util { + +template +class png_reader : public image_reader +{ + using source_type = T; + using input_stream = boost::iostreams::stream; + + struct png_struct_guard + { + png_struct_guard(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) + : p_(png_ptr_ptr), + i_(info_ptr_ptr) {} + + ~png_struct_guard() + { + png_destroy_read_struct(p_,i_,0); + } + png_structpp p_; + png_infopp i_; + }; + +private: + source_type source_; + input_stream stream_; + unsigned width_; + unsigned height_; + int bit_depth_; + int color_type_; + bool has_alpha_; +public: + png_reader(char const* data, std::size_t size); + ~png_reader(); + unsigned width() const; + unsigned height() const; + inline bool has_alpha() const { return has_alpha_; } + bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html + void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image); +private: + void init(); + static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); +}; + + +}} + +#endif // MBGL_UTIL_PNG_READER_HPP diff --git a/include/mbgl/util/singleton.hpp b/include/mbgl/util/singleton.hpp deleted file mode 100644 index a1c1e3ebffe..00000000000 --- a/include/mbgl/util/singleton.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef MBGL_UTIL_SINGLETON_HPP -#define MBGL_UTIL_SINGLETON_HPP - -// stl -#include // std::runtime_error -#include // std::atexit -#include // operator new -#define SINGLETON_THREADSAFE -#ifdef SINGLETON_THREADSAFE -#include -#endif - -namespace mbgl { namespace util { - -template -class CreateUsingNew -{ -public: - static T* create() - { - return new T; - } - static void destroy(T* obj) - { - delete obj; - } -}; - -template -class CreateStatic -{ -private: - union MaxAlign - { - char t_[sizeof(T)]; - short int shortInt_; - int int_; - long int longInt_; - float float_; - double double_; - long double longDouble_; - struct Test; - int Test::* pMember_; - int (Test::*pMemberFn_)(int); - }; - -public: - - static T* create() - { - static MaxAlign staticMemory; - return new(&staticMemory) T; - } - static void destroy(volatile T* obj) - { - obj->~T(); - } -}; - -template class CreatePolicy=CreateStatic> class singleton -{ - friend class CreatePolicy; - static T* pInstance_; - static bool destroyed_; - singleton(const singleton &rhs); - singleton& operator=(const singleton&); - - static void onDeadReference() - { - throw std::runtime_error("dead reference!"); - } - - static void DestroySingleton() - { - CreatePolicy::destroy(pInstance_); - pInstance_ = 0; - destroyed_ = true; - } - -protected: - -#ifdef SINGLETON_THREADSAFE - static std::mutex mutex_; -#endif - singleton() {} - public: - static T& instance() - { - if (! pInstance_) - { -#ifdef SINGLETON_THREADSAFE - std::unique_lock lock(mutex_); -#endif - if (! pInstance_) - { - if (destroyed_) - { - destroyed_ = false; - onDeadReference(); - } - else - { - pInstance_ = CreatePolicy::create(); - // register destruction - std::atexit(&DestroySingleton); - } - } - } - return *pInstance_; - } -}; - -#ifdef SINGLETON_THREADSAFE - template class CreatePolicy> std::mutex singleton::mutex_; -#endif - - template class CreatePolicy> T* singleton::pInstance_=0; - template class CreatePolicy> bool singleton::destroyed_=false; - -}} - -#endif // diff --git a/linux/mapboxgl-app.gyp b/linux/mapboxgl-app.gyp index dbcc4b44791..fbeabd74ea0 100644 --- a/linux/mapboxgl-app.gyp +++ b/linux/mapboxgl-app.gyp @@ -12,8 +12,6 @@ '../platform/default/settings_json.cpp', '../platform/default/glfw_view.cpp', '../platform/default/log_stderr.cpp', - '../platform/default/png_reader.cpp', - '../platform/default/jpeg_reader.cpp', ], 'xcode_settings': { 'OTHER_CPLUSPLUSFLAGS':[ diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index 53ab5758aa8..599ccb13a48 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -1,5 +1,9 @@ #include "mbgl/util/image_reader.hpp" +#include "mbgl/util/png_reader.hpp" +#include "mbgl/util/jpeg_reader.hpp" + #include +#include namespace mbgl { namespace util { @@ -43,10 +47,16 @@ image_reader* get_image_reader(char const* data, size_t size) boost::optional type = type_from_bytes(data,size); if (type) { - return factory::create_object(*type, data,size); + if (*type == "png") + { + return new png_reader(data, size); + } + else if (*type == "jpeg") + { + return new jpeg_reader(data, size); + } } - else - throw image_reader_exception("image_reader: can't determine type from input data"); + throw image_reader_exception("image_reader: can't determine type from input data"); } }} diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index f1e9d0fdfe3..b722c08fa18 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -1,15 +1,9 @@ -#include "mbgl/util/image_reader.hpp" - -// jpeg -extern "C" -{ -#include -} +#include "mbgl/util/jpeg_reader.hpp" // boost #include #include -#include + // std #include @@ -17,80 +11,7 @@ extern "C" namespace mbgl { namespace util { -template -class jpeg_reader : public image_reader -{ -public: - using source_type = T; - using input_stream = boost::iostreams::stream; - const static unsigned BUF_SIZE = 4096; -private: - struct jpeg_stream_wrapper - { - jpeg_source_mgr manager; - input_stream * stream; - JOCTET buffer[BUF_SIZE]; - }; - - struct jpeg_info_guard - { - jpeg_info_guard(jpeg_decompress_struct * cinfo) - : i_(cinfo) {} - - ~jpeg_info_guard() - { - jpeg_destroy_decompress(i_); - } - jpeg_decompress_struct * i_; - }; - -private: - source_type source_; - input_stream stream_; - unsigned width_; - unsigned height_; -public: - explicit jpeg_reader(std::string const& file_name); - explicit jpeg_reader(char const* data, size_t size); - ~jpeg_reader(); - unsigned width() const; - unsigned height() const; - inline bool has_alpha() const { return false; } - inline bool premultiplied_alpha() const { return true; } - void read(unsigned x,unsigned y, unsigned w, unsigned h, char *image); -private: - void init(); - static void on_error(j_common_ptr cinfo); - static void on_error_message(j_common_ptr cinfo); - static void init_source(j_decompress_ptr cinfo); - static boolean fill_input_buffer(j_decompress_ptr cinfo); - static void skip(j_decompress_ptr cinfo, long count); - static void term(j_decompress_ptr cinfo); - static void attach_stream(j_decompress_ptr cinfo, input_stream* in); -}; - -namespace -{ -image_reader* create_jpeg_reader(char const* data, size_t size) -{ - return new jpeg_reader(data, size); -} - -const static bool registered = register_image_reader("jpeg",create_jpeg_reader); -} - -// ctors -template -jpeg_reader::jpeg_reader(std::string const& file_name) - : source_(file_name,std::ios_base::in | std::ios_base::binary), - stream_(source_), - width_(0), - height_(0) -{ - if (!stream_) throw image_reader_exception("cannot open image file "+ file_name); - init(); -} - +// ctor template jpeg_reader::jpeg_reader(char const* data, size_t size) : source_(data, size), @@ -277,4 +198,6 @@ void jpeg_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char jpeg_finish_decompress(&cinfo); } +template class jpeg_reader; + }} diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 838344286ed..4d0abce04c7 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -1,4 +1,4 @@ -#include "mbgl/util/image_reader.hpp" +#include "mbgl/util/png_reader.hpp" #include extern "C" { @@ -16,61 +16,6 @@ extern "C" namespace mbgl { namespace util { -template -class png_reader : public image_reader -{ - using source_type = T; - using input_stream = boost::iostreams::stream; - - struct png_struct_guard - { - png_struct_guard(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) - : p_(png_ptr_ptr), - i_(info_ptr_ptr) {} - - ~png_struct_guard() - { - png_destroy_read_struct(p_,i_,0); - } - png_structpp p_; - png_infopp i_; - }; - -private: - - source_type source_; - input_stream stream_; - unsigned width_; - unsigned height_; - int bit_depth_; - int color_type_; - bool has_alpha_; -public: - explicit png_reader(std::string const& file_name); - png_reader(char const* data, std::size_t size); - ~png_reader(); - unsigned width() const; - unsigned height() const; - inline bool has_alpha() const { return has_alpha_; } - bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html - void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image); -private: - void init(); - static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); -}; - -namespace -{ -image_reader* create_png_reader(char const * data, std::size_t size) -{ - return new png_reader(data, size); -} - -const static bool registered = register_image_reader("png",create_png_reader); - -} - - void user_error_fn(png_structp /*png_ptr*/, png_const_charp error_msg) { throw image_reader_exception(std::string("failed to read invalid png: '") + error_msg + "'"); @@ -94,21 +39,6 @@ void png_reader::png_read_data(png_structp png_ptr, png_bytep data, png_size_ } } -template -png_reader::png_reader(std::string const& file_name) - : source_(file_name,std::ios_base::in | std::ios_base::binary), - stream_(source_), - width_(0), - height_(0), - bit_depth_(0), - color_type_(0), - has_alpha_(false) -{ - if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'"); - if (!stream_) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'"); - init(); -} - template png_reader::png_reader(char const* data, std::size_t size) : source_(data,size), @@ -263,4 +193,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char } png_read_end(png_ptr,0); } + +template class png_reader; + }} diff --git a/test/test.gyp b/test/test.gyp index fecb6ed9398..86dbcc08a56 100644 --- a/test/test.gyp +++ b/test/test.gyp @@ -163,7 +163,6 @@ 'type': 'executable', 'sources': [ './headless.cpp', - '../platform/default/png_reader.cpp', './fixtures/fixture_log.cpp', ], 'conditions': [ From f7e813238da85270a974e4a045242af2dda0fda0 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 19 Nov 2014 16:17:52 +0100 Subject: [PATCH 15/24] ensure all exceptions are caught in Image ctor --- platform/default/image.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/default/image.cpp b/platform/default/image.cpp index 96d01ab7180..9a76ef33f63 100644 --- a/platform/default/image.cpp +++ b/platform/default/image.cpp @@ -84,12 +84,19 @@ Image::Image(std::string const& data) } catch (image_reader_exception const& ex) { - fprintf(stderr, "ImageReader: %s\n", ex.what()); + fprintf(stderr, "Image: %s\n", ex.what()); img.reset(); width = 0; height = 0; } + catch (...) // catch the rest + { + fprintf(stderr, "Image: exception in constructor"); + img.reset(); + width = 0; + height = 0; + } } } From 04cea00d5dba694387e308215227f20eac0668c7 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 19 Nov 2014 16:31:16 +0100 Subject: [PATCH 16/24] return unique_ptr from get_image_reader --- include/mbgl/util/image_reader.hpp | 2 +- platform/default/image.cpp | 2 +- platform/default/image_reader.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/mbgl/util/image_reader.hpp b/include/mbgl/util/image_reader.hpp index 589653ec5c6..4bdaf420f8d 100644 --- a/include/mbgl/util/image_reader.hpp +++ b/include/mbgl/util/image_reader.hpp @@ -34,7 +34,7 @@ struct image_reader : private noncopyable virtual ~image_reader() {} }; -image_reader* get_image_reader(char const* data, size_t size); +std::unique_ptr get_image_reader(char const* data, size_t size); }} diff --git a/platform/default/image.cpp b/platform/default/image.cpp index 9a76ef33f63..8d0374c64c8 100644 --- a/platform/default/image.cpp +++ b/platform/default/image.cpp @@ -76,7 +76,7 @@ Image::Image(std::string const& data) { try { - std::unique_ptr reader(get_image_reader(data.c_str(), data.size())); + auto reader = get_image_reader(data.c_str(), data.size()); width = reader->width(); height = reader->height(); img = ::std::unique_ptr(new char[width * height * 4]()); diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index 599ccb13a48..71b8e099181 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -1,3 +1,4 @@ +#include "mbgl/util/std.hpp" #include "mbgl/util/image_reader.hpp" #include "mbgl/util/png_reader.hpp" #include "mbgl/util/jpeg_reader.hpp" @@ -42,18 +43,18 @@ inline boost::optional type_from_bytes(char const* data, size_t siz return result_type(); } -image_reader* get_image_reader(char const* data, size_t size) +std::unique_ptr get_image_reader(char const* data, size_t size) { boost::optional type = type_from_bytes(data,size); if (type) { if (*type == "png") { - return new png_reader(data, size); + return std::make_unique>(data, size); } else if (*type == "jpeg") { - return new jpeg_reader(data, size); + return std::make_unique>(data, size); } } throw image_reader_exception("image_reader: can't determine type from input data"); From 813586d1d413e58110c4311190a8677aec3ca2bb Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 19 Nov 2014 16:49:26 +0100 Subject: [PATCH 17/24] move std.hpp include into image_reader.hpp (g++) --- include/mbgl/util/image_reader.hpp | 3 ++- platform/default/image_reader.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbgl/util/image_reader.hpp b/include/mbgl/util/image_reader.hpp index 4bdaf420f8d..a35830cf5e5 100644 --- a/include/mbgl/util/image_reader.hpp +++ b/include/mbgl/util/image_reader.hpp @@ -1,7 +1,8 @@ #ifndef MBGL_UTIL_IMAGE_READER_HPP #define MBGL_UTIL_IMAGE_READER_HPP -#include "noncopyable.hpp" +#include +#include // stl #include #include diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index 71b8e099181..86dae78fba5 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -1,4 +1,3 @@ -#include "mbgl/util/std.hpp" #include "mbgl/util/image_reader.hpp" #include "mbgl/util/png_reader.hpp" #include "mbgl/util/jpeg_reader.hpp" From f89c9753ddf9cf31b84e6fd8677291908e146083 Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 19 Nov 2014 16:56:53 +0100 Subject: [PATCH 18/24] image-readers: move concrete implementations headers into platform/default --- include/mbgl/{util => platform/default}/image_reader.hpp | 0 include/mbgl/{util => platform/default}/jpeg_reader.hpp | 2 +- include/mbgl/{util => platform/default}/png_reader.hpp | 2 +- platform/default/image.cpp | 3 ++- platform/default/image_reader.cpp | 6 +++--- platform/default/jpeg_reader.cpp | 2 +- platform/default/png_reader.cpp | 2 +- 7 files changed, 9 insertions(+), 8 deletions(-) rename include/mbgl/{util => platform/default}/image_reader.hpp (100%) rename include/mbgl/{util => platform/default}/jpeg_reader.hpp (97%) rename include/mbgl/{util => platform/default}/png_reader.hpp (96%) diff --git a/include/mbgl/util/image_reader.hpp b/include/mbgl/platform/default/image_reader.hpp similarity index 100% rename from include/mbgl/util/image_reader.hpp rename to include/mbgl/platform/default/image_reader.hpp diff --git a/include/mbgl/util/jpeg_reader.hpp b/include/mbgl/platform/default/jpeg_reader.hpp similarity index 97% rename from include/mbgl/util/jpeg_reader.hpp rename to include/mbgl/platform/default/jpeg_reader.hpp index 77356007d89..964e4731ee7 100644 --- a/include/mbgl/util/jpeg_reader.hpp +++ b/include/mbgl/platform/default/jpeg_reader.hpp @@ -1,7 +1,7 @@ #ifndef MBGL_UTIL_JPEG_READER_HPP #define MBGL_UTIL_JPEG_READER_HPP -#include "image_reader.hpp" +#include // jpeg extern "C" diff --git a/include/mbgl/util/png_reader.hpp b/include/mbgl/platform/default/png_reader.hpp similarity index 96% rename from include/mbgl/util/png_reader.hpp rename to include/mbgl/platform/default/png_reader.hpp index 3d6e1db51e6..f6b5aaf9cf5 100644 --- a/include/mbgl/util/png_reader.hpp +++ b/include/mbgl/platform/default/png_reader.hpp @@ -1,7 +1,7 @@ #ifndef MBGL_UTIL_PNG_READER_HPP #define MBGL_UTIL_PNG_READER_HPP -#include "mbgl/util/image_reader.hpp" +#include extern "C" { diff --git a/platform/default/image.cpp b/platform/default/image.cpp index 8d0374c64c8..558f33cb81f 100644 --- a/platform/default/image.cpp +++ b/platform/default/image.cpp @@ -7,7 +7,8 @@ #include #include #include -#include + +#include // Check png library version. const static bool png_version_check = []() { diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index 86dae78fba5..2e2842d19d9 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -1,6 +1,6 @@ -#include "mbgl/util/image_reader.hpp" -#include "mbgl/util/png_reader.hpp" -#include "mbgl/util/jpeg_reader.hpp" +#include +#include +#include #include #include diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index b722c08fa18..18350c3e703 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -1,4 +1,4 @@ -#include "mbgl/util/jpeg_reader.hpp" +#include // boost #include diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 4d0abce04c7..e9f38a9d3da 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -1,4 +1,4 @@ -#include "mbgl/util/png_reader.hpp" +#include #include extern "C" { From 4af232dcf347723969aad01d7347ff2cdd8cf575 Mon Sep 17 00:00:00 2001 From: artemp Date: Fri, 21 Nov 2014 11:28:56 +0100 Subject: [PATCH 19/24] image_readers: premultiply alpha --- include/mbgl/platform/default/png_reader.hpp | 2 +- platform/default/png_reader.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mbgl/platform/default/png_reader.hpp b/include/mbgl/platform/default/png_reader.hpp index f6b5aaf9cf5..db20d85e251 100644 --- a/include/mbgl/platform/default/png_reader.hpp +++ b/include/mbgl/platform/default/png_reader.hpp @@ -49,7 +49,7 @@ class png_reader : public image_reader unsigned width() const; unsigned height() const; inline bool has_alpha() const { return has_alpha_; } - bool premultiplied_alpha() const { return false; } //http://www.libpng.org/pub/png/spec/1.1/PNG-Rationale.html + bool premultiplied_alpha() const { return true; } // png_set_alpha_mode(png, PNG_ALPHA_PREMULTIPLIED, 2.2) void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image); private: void init(); diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index e9f38a9d3da..507db715a41 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -157,6 +157,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char double gamma; if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, 2.2, gamma); + png_set_alpha_mode(png_ptr, PNG_ALPHA_PREMULTIPLIED, 2.2); if (x0 == 0 && y0 == 0 && w >= width_ && h >= height_) { From 2b0cb4a518aca590d91f2cff3cab1fe26d7f6be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Sch=C3=BC=C3=9Fler?= Date: Sat, 22 Nov 2014 19:55:07 +0100 Subject: [PATCH 20/24] Fix member shadowing warnings --- include/mbgl/util/uv_detail.hpp | 4 ++-- src/storage/http_request.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mbgl/util/uv_detail.hpp b/include/mbgl/util/uv_detail.hpp index 3bbfa4ac5a9..5da222b0455 100644 --- a/include/mbgl/util/uv_detail.hpp +++ b/include/mbgl/util/uv_detail.hpp @@ -129,8 +129,8 @@ class worker { uv_worker_init(w, loop, count, name); } inline ~worker() { - uv_worker_close(w, [](uv_worker_t *worker) { - delete worker; + uv_worker_close(w, [](uv_worker_t *worker_) { + delete worker_; }); } inline void add(void *data, uv_worker_cb work_cb, uv_worker_after_cb after_work_cb) { diff --git a/src/storage/http_request.cpp b/src/storage/http_request.cpp index 46b1d5e194f..c87a92e1234 100644 --- a/src/storage/http_request.cpp +++ b/src/storage/http_request.cpp @@ -36,12 +36,12 @@ void HTTPRequest::startCacheRequest() { cache_baton->request = this; cache_baton->path = path; cache_baton->store = store; - store->get(path, [](std::unique_ptr &&response, void *ptr) { + store->get(path, [](std::unique_ptr &&response_, void *ptr) { // Wrap in a unique_ptr, so it'll always get auto-destructed. std::unique_ptr baton((CacheRequestBaton *)ptr); if (baton->request) { baton->request->cache_baton = nullptr; - baton->request->handleCacheResponse(std::move(response)); + baton->request->handleCacheResponse(std::move(response_)); } }, cache_baton); } From d978feed92b99f6f14fc925f865710fc98cf5d03 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 25 Nov 2014 14:31:08 -0800 Subject: [PATCH 21/24] Update linux instructions --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 998618f7bf9..3c8fb2fd38e 100644 --- a/README.md +++ b/README.md @@ -93,17 +93,14 @@ Once you're done installing the build dependencies, you can get started by runni ./configure -which downloads all other dependencies that we need to build manually with [Mason](https://github.com/mapbox/mason). There's a good chance that there already are binary files and that you don't need to compile anything. - -Then, you can then proceed to build the library like: - - make mbgl - -Or proceed to building the debug application with: +Then, you can then proceed to build the library: + git submodule update --init make linux -Be sure to setup an access token per below before running `build/Release/mapbox-gl`. +Set an access token as described below, and then run: + + make run-linux # Troubleshooting From 84551d93490071a970ef4aace7935097a8effc2e Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 26 Nov 2014 17:50:12 +0100 Subject: [PATCH 22/24] convert image_reader public interface to use CamelCase to match the rest of codebase --- .../mbgl/platform/default/image_reader.hpp | 16 +++---- include/mbgl/platform/default/jpeg_reader.hpp | 10 ++--- include/mbgl/platform/default/png_reader.hpp | 10 ++--- platform/default/image.cpp | 4 +- platform/default/image_reader.cpp | 8 ++-- platform/default/jpeg_reader.cpp | 42 +++++++++---------- platform/default/png_reader.cpp | 32 +++++++------- 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/include/mbgl/platform/default/image_reader.hpp b/include/mbgl/platform/default/image_reader.hpp index a35830cf5e5..985e4874cd2 100644 --- a/include/mbgl/platform/default/image_reader.hpp +++ b/include/mbgl/platform/default/image_reader.hpp @@ -9,15 +9,15 @@ namespace mbgl { namespace util { -class image_reader_exception : public std::exception +class ImageReaderException : public std::exception { private: std::string message_; public: - image_reader_exception(std::string const& message) + ImageReaderException(std::string const& message) : message_(message) {} - ~image_reader_exception() throw() {} + ~ImageReaderException() throw() {} virtual const char* what() const throw() { @@ -25,17 +25,17 @@ class image_reader_exception : public std::exception } }; -struct image_reader : private noncopyable +struct ImageReader : private noncopyable { virtual unsigned width() const=0; virtual unsigned height() const=0; - virtual bool has_alpha() const=0; - virtual bool premultiplied_alpha() const=0; + virtual bool hasAlpha() const=0; + virtual bool premultipliedAlpha() const=0; virtual void read(unsigned x,unsigned y, unsigned width, unsigned height, char* image)=0; - virtual ~image_reader() {} + virtual ~ImageReader() {} }; -std::unique_ptr get_image_reader(char const* data, size_t size); +std::unique_ptr getImageReader(char const* data, size_t size); }} diff --git a/include/mbgl/platform/default/jpeg_reader.hpp b/include/mbgl/platform/default/jpeg_reader.hpp index 964e4731ee7..7122f24cd23 100644 --- a/include/mbgl/platform/default/jpeg_reader.hpp +++ b/include/mbgl/platform/default/jpeg_reader.hpp @@ -14,7 +14,7 @@ extern "C" namespace mbgl { namespace util { template -class jpeg_reader : public image_reader +class JpegReader : public ImageReader { public: using source_type = T; @@ -46,12 +46,12 @@ class jpeg_reader : public image_reader unsigned width_; unsigned height_; public: - jpeg_reader(char const* data, size_t size); - ~jpeg_reader(); + JpegReader(char const* data, size_t size); + ~JpegReader(); unsigned width() const; unsigned height() const; - inline bool has_alpha() const { return false; } - inline bool premultiplied_alpha() const { return true; } + inline bool hasAlpha() const { return false; } + inline bool premultipliedAlpha() const { return true; } void read(unsigned x,unsigned y, unsigned w, unsigned h, char *image); private: void init(); diff --git a/include/mbgl/platform/default/png_reader.hpp b/include/mbgl/platform/default/png_reader.hpp index db20d85e251..66debd4fbaf 100644 --- a/include/mbgl/platform/default/png_reader.hpp +++ b/include/mbgl/platform/default/png_reader.hpp @@ -16,7 +16,7 @@ extern "C" namespace mbgl { namespace util { template -class png_reader : public image_reader +class PngReader : public ImageReader { using source_type = T; using input_stream = boost::iostreams::stream; @@ -44,12 +44,12 @@ class png_reader : public image_reader int color_type_; bool has_alpha_; public: - png_reader(char const* data, std::size_t size); - ~png_reader(); + PngReader(char const* data, std::size_t size); + ~PngReader(); unsigned width() const; unsigned height() const; - inline bool has_alpha() const { return has_alpha_; } - bool premultiplied_alpha() const { return true; } // png_set_alpha_mode(png, PNG_ALPHA_PREMULTIPLIED, 2.2) + inline bool hasAlpha() const { return has_alpha_; } + bool premultipliedAlpha() const { return true; } // png_set_alpha_mode(png, PNG_ALPHA_PREMULTIPLIED, 2.2) void read(unsigned x,unsigned y, unsigned width, unsigned height, char * image); private: void init(); diff --git a/platform/default/image.cpp b/platform/default/image.cpp index 558f33cb81f..242367e8892 100644 --- a/platform/default/image.cpp +++ b/platform/default/image.cpp @@ -77,13 +77,13 @@ Image::Image(std::string const& data) { try { - auto reader = get_image_reader(data.c_str(), data.size()); + auto reader = getImageReader(data.c_str(), data.size()); width = reader->width(); height = reader->height(); img = ::std::unique_ptr(new char[width * height * 4]()); reader->read(0, 0, width, height, img.get()); } - catch (image_reader_exception const& ex) + catch (ImageReaderException const& ex) { fprintf(stderr, "Image: %s\n", ex.what()); img.reset(); diff --git a/platform/default/image_reader.cpp b/platform/default/image_reader.cpp index 2e2842d19d9..e80ccb68193 100644 --- a/platform/default/image_reader.cpp +++ b/platform/default/image_reader.cpp @@ -42,21 +42,21 @@ inline boost::optional type_from_bytes(char const* data, size_t siz return result_type(); } -std::unique_ptr get_image_reader(char const* data, size_t size) +std::unique_ptr getImageReader(char const* data, size_t size) { boost::optional type = type_from_bytes(data,size); if (type) { if (*type == "png") { - return std::make_unique>(data, size); + return std::make_unique>(data, size); } else if (*type == "jpeg") { - return std::make_unique>(data, size); + return std::make_unique>(data, size); } } - throw image_reader_exception("image_reader: can't determine type from input data"); + throw ImageReaderException("ImageReader: can't determine type from input data"); } }} diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp index 18350c3e703..f89e7668740 100644 --- a/platform/default/jpeg_reader.cpp +++ b/platform/default/jpeg_reader.cpp @@ -13,30 +13,30 @@ namespace mbgl { namespace util { // ctor template -jpeg_reader::jpeg_reader(char const* data, size_t size) +JpegReader::JpegReader(char const* data, size_t size) : source_(data, size), stream_(source_), width_(0), height_(0) { - if (!stream_) throw image_reader_exception("cannot open image stream"); + if (!stream_) throw ImageReaderException("cannot open image stream"); init(); } // dtor template -jpeg_reader::~jpeg_reader() {} +JpegReader::~JpegReader() {} // jpeg stream wrapper template -void jpeg_reader::init_source (j_decompress_ptr cinfo) +void JpegReader::init_source (j_decompress_ptr cinfo) { jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); wrap->stream->seekg(0,std::ios_base::beg); } template -boolean jpeg_reader::fill_input_buffer (j_decompress_ptr cinfo) +boolean JpegReader::fill_input_buffer (j_decompress_ptr cinfo) { jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); wrap->stream->read(reinterpret_cast(&wrap->buffer[0]),BUF_SIZE); @@ -47,7 +47,7 @@ boolean jpeg_reader::fill_input_buffer (j_decompress_ptr cinfo) } template -void jpeg_reader::skip(j_decompress_ptr cinfo, long count) +void JpegReader::skip(j_decompress_ptr cinfo, long count) { if (count <= 0) return; //A zero or negative skip count should be treated as a no-op. jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); @@ -67,20 +67,20 @@ void jpeg_reader::skip(j_decompress_ptr cinfo, long count) } template -void jpeg_reader::term (j_decompress_ptr /*cinfo*/) +void JpegReader::term (j_decompress_ptr /*cinfo*/) { // no-op } template -void jpeg_reader::attach_stream (j_decompress_ptr cinfo, input_stream* in) +void JpegReader::attach_stream (j_decompress_ptr cinfo, input_stream* in) { if (cinfo->src == 0) { cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(jpeg_stream_wrapper)); } - jpeg_reader::jpeg_stream_wrapper * src = reinterpret_cast (cinfo->src); + JpegReader::jpeg_stream_wrapper * src = reinterpret_cast (cinfo->src); src->manager.init_source = init_source; src->manager.fill_input_buffer = fill_input_buffer; src->manager.skip_input_data = skip; @@ -92,20 +92,20 @@ void jpeg_reader::attach_stream (j_decompress_ptr cinfo, input_stream* in) } template -void jpeg_reader::on_error(j_common_ptr /*cinfo*/) +void JpegReader::on_error(j_common_ptr /*cinfo*/) { } template -void jpeg_reader::on_error_message(j_common_ptr cinfo) +void JpegReader::on_error_message(j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message)(cinfo, buffer); - throw image_reader_exception(std::string("JPEG Reader: libjpeg could not read image: ") + buffer); + throw ImageReaderException(std::string("JPEG Reader: libjpeg could not read image: ") + buffer); } template -void jpeg_reader::init() +void JpegReader::init() { jpeg_decompress_struct cinfo; jpeg_info_guard iguard(&cinfo); @@ -117,35 +117,35 @@ void jpeg_reader::init() attach_stream(&cinfo, &stream_); int ret = jpeg_read_header(&cinfo, TRUE); if (ret != JPEG_HEADER_OK) - throw image_reader_exception("JPEG Reader: failed to read header"); + throw ImageReaderException("JPEG Reader: failed to read header"); jpeg_start_decompress(&cinfo); width_ = cinfo.output_width; height_ = cinfo.output_height; if (cinfo.out_color_space == JCS_UNKNOWN) { - throw image_reader_exception("JPEG Reader: failed to read unknown color space"); + throw ImageReaderException("JPEG Reader: failed to read unknown color space"); } if (cinfo.output_width == 0 || cinfo.output_height == 0) { - throw image_reader_exception("JPEG Reader: failed to read image size of"); + throw ImageReaderException("JPEG Reader: failed to read image size of"); } } template -unsigned jpeg_reader::width() const +unsigned JpegReader::width() const { return width_; } template -unsigned jpeg_reader::height() const +unsigned JpegReader::height() const { return height_; } template -void jpeg_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char* image) +void JpegReader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char* image) { stream_.clear(); stream_.seekg(0, std::ios_base::beg); @@ -159,7 +159,7 @@ void jpeg_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char jpeg_create_decompress(&cinfo); attach_stream(&cinfo, &stream_); int ret = jpeg_read_header(&cinfo, TRUE); - if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader read(): failed to read header"); + if (ret != JPEG_HEADER_OK) throw ImageReaderException("JPEG Reader read(): failed to read header"); jpeg_start_decompress(&cinfo); JSAMPARRAY buffer; int row_stride; @@ -198,6 +198,6 @@ void jpeg_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char jpeg_finish_decompress(&cinfo); } -template class jpeg_reader; +template class JpegReader; }} diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 507db715a41..cf96ca2363e 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -18,7 +18,7 @@ namespace mbgl { namespace util { void user_error_fn(png_structp /*png_ptr*/, png_const_charp error_msg) { - throw image_reader_exception(std::string("failed to read invalid png: '") + error_msg + "'"); + throw ImageReaderException(std::string("failed to read invalid png: '") + error_msg + "'"); } void user_warning_fn(png_structp /*png_ptr*/, png_const_charp warning_msg) @@ -28,7 +28,7 @@ void user_warning_fn(png_structp /*png_ptr*/, png_const_charp warning_msg) } template -void png_reader::png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +void PngReader::png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { input_stream * fin = reinterpret_cast(png_get_io_ptr(png_ptr)); fin->read(reinterpret_cast(data), length); @@ -40,7 +40,7 @@ void png_reader::png_read_data(png_structp png_ptr, png_bytep data, png_size_ } template -png_reader::png_reader(char const* data, std::size_t size) +PngReader::PngReader(char const* data, std::size_t size) : source_(data,size), stream_(source_), width_(0), @@ -50,36 +50,36 @@ png_reader::png_reader(char const* data, std::size_t size) has_alpha_(false) { - if (!stream_) throw image_reader_exception("PNG reader: cannot open image stream"); + if (!stream_) throw ImageReaderException("PNG reader: cannot open image stream"); init(); } template -png_reader::~png_reader() {} +PngReader::~PngReader() {} template -void png_reader::init() +void PngReader::init() { png_byte header[8]; std::memset(header,0,8); stream_.read(reinterpret_cast(header),8); if ( stream_.gcount() != 8) { - throw image_reader_exception("PNG reader: Could not read image"); + throw ImageReaderException("PNG reader: Could not read image"); } int is_png=!png_sig_cmp(header,0,8); if (!is_png) { - throw image_reader_exception("File or stream is not a png"); + throw ImageReaderException("File or stream is not a png"); } png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { - throw image_reader_exception("failed to allocate png_ptr"); + throw ImageReaderException("failed to allocate png_ptr"); } // catch errors in a custom way to avoid the need for setjmp @@ -88,7 +88,7 @@ void png_reader::init() png_infop info_ptr; png_struct_guard sguard(&png_ptr,&info_ptr); info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) throw image_reader_exception("failed to create info_ptr"); + if (!info_ptr) throw ImageReaderException("failed to create info_ptr"); png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data); @@ -103,19 +103,19 @@ void png_reader::init() } template -unsigned png_reader::width() const +unsigned PngReader::width() const { return width_; } template -unsigned png_reader::height() const +unsigned PngReader::height() const { return height_; } template -void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * image) +void PngReader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char * image) { stream_.clear(); stream_.seekg(0, std::ios_base::beg); @@ -125,7 +125,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char if (!png_ptr) { - throw image_reader_exception("failed to allocate png_ptr"); + throw ImageReaderException("failed to allocate png_ptr"); } // catch errors in a custom way to avoid the need for setjmp @@ -134,7 +134,7 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char png_infop info_ptr; png_struct_guard sguard(&png_ptr,&info_ptr); info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) throw image_reader_exception("failed to create info_ptr"); + if (!info_ptr) throw ImageReaderException("failed to create info_ptr"); png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data); png_read_info(png_ptr, info_ptr); @@ -195,6 +195,6 @@ void png_reader::read(unsigned x0, unsigned y0, unsigned w, unsigned h, char png_read_end(png_ptr,0); } -template class png_reader; +template class PngReader; }} From 1f067f1e9dfca44722b79815997bc6886b65b18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 26 Nov 2014 17:58:23 +0100 Subject: [PATCH 23/24] add {prefix} to tile URL replacement token scheme prefix is a 2 character hex code derived from the tile x/y --- src/map/tile_data.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 9ff694bf3a6..0a59bdc62b4 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -37,6 +37,12 @@ void TileData::request(FileSource& fileSource) { if (token == "z") return std::to_string(id.z); if (token == "x") return std::to_string(id.x); if (token == "y") return std::to_string(id.y); + if (token == "prefix") { + std::string prefix { 2 }; + prefix[0] = "0123456789abcdef"[id.x % 16]; + prefix[1] = "0123456789abcdef"[id.y % 16]; + return prefix; + } if (token == "ratio") return (map.getState().getPixelRatio() > 1.0 ? "@2x" : ""); return ""; }); From 370297763c41c642783aae4731612429390e99ec Mon Sep 17 00:00:00 2001 From: Mike Morris Date: Wed, 26 Nov 2014 10:00:48 -0800 Subject: [PATCH 24/24] add jpeg_static_libs to linux install ldflags --- gyp/install.gypi | 1 + 1 file changed, 1 insertion(+) diff --git a/gyp/install.gypi b/gyp/install.gypi index 7b8cf6220e7..d46900dfffb 100644 --- a/gyp/install.gypi +++ b/gyp/install.gypi @@ -23,6 +23,7 @@ ['OS == "linux"', { 'other_ldflags': [ '<@(png_static_libs)', + '<@(jpeg_static_libs)', '<@(glfw3_static_libs)', '<@(glfw3_ldflags)', ]