예제 #1
0
MAPNIK_DECL void composite(image_rgba8 & dst, image_rgba8 const& src, composite_mode_e mode,
               float opacity,
               int dx,
               int dy
#ifdef MAPNIK_STATS_RENDER
               , std::ostream * log_stream
#endif
                     )
{
#ifdef MAPNIK_STATS_RENDER
    boost::optional<std::string> mode_name = comp_op_to_string(mode);
    std::stringstream ss;
    ss << "comp-op" << ' '
        << (mode_name ? *mode_name : "unknown") << ' '
        << std::to_string(src.width()) << "x"
        << std::to_string(src.height()) << " -> "
        << std::to_string(dst.width()) << "x"
        << std::to_string(dst.height());
    log_render lr(ss.str(), log_stream ? *log_stream : std::clog);
    timer_with_action<log_render> __stats__(lr);
#endif
#ifdef MAPNIK_DEBUG
    if (!src.get_premultiplied())
    {
        throw std::runtime_error("SOURCE MUST BE PREMULTIPLIED FOR COMPOSITING!");
    }
    if (!dst.get_premultiplied())
    {
        throw std::runtime_error("DESTINATION MUST BE PREMULTIPLIED FOR COMPOSITING!");
    }
#endif
    unsigned jobs = util::jobs_by_image_size(src.width(), src.height());
    composite_functor comp_func{ dst, src, mode, opacity, dx, dy };
    util::parallelize(comp_func, jobs, src.height());
}
예제 #2
0
void render_pattern<image_rgba8>(rasterizer & ras,
                                 marker_svg const& marker,
                                 agg::trans_affine const& tr,
                                 double opacity,
                                 image_rgba8 & image)
{
    using pixfmt = agg::pixfmt_rgba32_pre;
    using renderer_base = agg::renderer_base<pixfmt>;
    using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>;
    agg::scanline_u8 sl;

    mapnik::box2d<double> const& bbox = marker.bounding_box() * tr;
    mapnik::coord<double,2> c = bbox.center();
    agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
    mtx.translate(0.5 * bbox.width(), 0.5 * bbox.height());
    mtx = tr * mtx;

    agg::rendering_buffer buf(image.bytes(), image.width(), image.height(), image.row_size());
    pixfmt pixf(buf);
    renderer_base renb(pixf);

    mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source());
    mapnik::svg::svg_path_adapter svg_path(stl_storage);
    mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,
                                  agg::pod_bvector<mapnik::svg::path_attributes>,
                                  renderer_solid,
                                  pixfmt > svg_renderer(svg_path,
                                                        marker.get_data()->attributes());

    svg_renderer.render(ras, sl, renb, mtx, opacity, bbox);
}
예제 #3
0
void render_raster_marker(RendererType ren,
                          RasterizerType & ras,
                          image_rgba8 const& src,
                          mapnik::feature_impl const& feature,
                          agg::trans_affine const& marker_tr,
                          double opacity)
{
    using color_type = typename RendererType::color_type;
    agg::scanline_bin sl;
    double width  = src.width();
    double height = src.height();
    double p[8];
    p[0] = 0;     p[1] = 0;
    p[2] = width; p[3] = 0;
    p[4] = width; p[5] = height;
    p[6] = 0;     p[7] = height;
    marker_tr.transform(&p[0], &p[1]);
    marker_tr.transform(&p[2], &p[3]);
    marker_tr.transform(&p[4], &p[5]);
    marker_tr.transform(&p[6], &p[7]);
    ras.move_to_d(p[0],p[1]);
    ras.line_to_d(p[2],p[3]);
    ras.line_to_d(p[4],p[5]);
    ras.line_to_d(p[6],p[7]);
    ren.color(color_type(feature.id()));
    agg::render_scanlines(ras, sl, ren);
}
예제 #4
0
void jpeg_reader<T>::read(unsigned x0, unsigned y0, image_rgba8& 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 a,r,g,b;
    row_stride = cinfo.output_width * cinfo.output_components;
    buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

    unsigned w = std::min(unsigned(image.width()),width_ - x0);
    unsigned h = std::min(unsigned(image.height()),height_ - y0);

    const std::unique_ptr<unsigned int[]> 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;
                a = 255; // alpha not supported in jpg
                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] = color(r, g, b, a).rgba();
            }
            image.set_row(row - y0, out_row.get(), w);
        }
        ++row;
    }
    jpeg_finish_decompress(&cinfo);
}
예제 #5
0
 raster_markers_dispatch(image_rgba8 const& src,
                         agg::trans_affine const& marker_trans,
                         symbolizer_base const& sym,
                         Detector & detector,
                         double scale_factor,
                         feature_impl const& feature,
                         attributes const& vars,
                         markers_renderer_context & renderer_context)
     : params_(box2d<double>(0, 0, src.width(), src.height()),
               marker_trans, sym, feature, vars, scale_factor)
     , renderer_context_(renderer_context)
     , src_(src)
     , detector_(detector)
 {}
예제 #6
0
void raster_colorizer::colorize(image_rgba8 & out, T const& in,
                                boost::optional<double> const& nodata,
                                feature_impl const& f) const
{
    using image_type = T;
    using pixel_type = typename image_type::pixel_type;
    // TODO: assuming in/out have the same width/height for now
    std::uint32_t * out_data = out.data();
    pixel_type const* in_data = in.data();
    int len = out.width() * out.height();
    for (int i=0; i<len; ++i)
    {
        pixel_type value = in_data[i];
        if (nodata && (std::fabs(value - *nodata) < epsilon_))
        {
            out_data[i] = 0; // rgba(0,0,0,0)
        }
        else
        {
            out_data[i] = get_color(value);
        }
    }
}
예제 #7
0
void png_reader<T>::read(unsigned x0, unsigned y0,image_rgba8& 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 && image.width() >= width_ && image.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<png_bytep[]> rows(new png_bytep[height_]);
        for (unsigned i=0; i<height_; ++i)
            rows[i] = (png_bytep)image.get_row(i);
        png_read_image(png_ptr, rows.get());
    }
    else
    {
        png_read_update_info(png_ptr, info_ptr);
        unsigned w=std::min(unsigned(image.width()),width_ - x0);
        unsigned h=std::min(unsigned(image.height()),height_ - y0);
        unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr);
        const std::unique_ptr<png_byte[]> 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.set_row(i-y0,reinterpret_cast<unsigned*>(&row[x0 * 4]),w);
            }
        }
        //END
    }
    png_read_end(png_ptr,0);
}
예제 #8
0
void render_raster_marker(RendererType renb, RasterizerType & ras, image_rgba8 const& src,
                          agg::trans_affine const& tr, double opacity,
                          float scale_factor, bool snap_to_pixels)
{
    using color_type = agg::rgba8;
    using const_rendering_buffer = util::rendering_buffer<image_rgba8>;
    using pixfmt_pre = agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_pre, const_rendering_buffer, agg::pixel32_type>;

    agg::scanline_u8 sl;
    double width  = src.width();
    double height = src.height();
    if (std::fabs(1.0 - scale_factor) < 0.001
        && (std::fabs(1.0 - tr.sx) < agg::affine_epsilon)
        && (std::fabs(0.0 - tr.shy) < agg::affine_epsilon)
        && (std::fabs(0.0 - tr.shx) < agg::affine_epsilon)
        && (std::fabs(1.0 - tr.sy) < agg::affine_epsilon))
    {
        const_rendering_buffer src_buffer(src);
        pixfmt_pre pixf_mask(src_buffer);
        if (snap_to_pixels)
        {
            renb.blend_from(pixf_mask,
                            0,
                            static_cast<int>(std::floor(tr.tx + .5)),
                            static_cast<int>(std::floor(tr.ty + .5)),
                            unsigned(255*opacity));
        }
        else
        {
            renb.blend_from(pixf_mask,
                            0,
                            static_cast<int>(tr.tx),
                            static_cast<int>(tr.ty),
                            unsigned(255*opacity));
        }
    }
    else
    {
        using img_accessor_type = agg::image_accessor_clone<pixfmt_pre>;
        using interpolator_type = agg::span_interpolator_linear<>;
        //using span_gen_type = agg::span_image_filter_rgba_2x2<img_accessor_type,interpolator_type>;
        using span_gen_type = agg::span_image_resample_rgba_affine<img_accessor_type>;
        using renderer_type = agg::renderer_scanline_aa_alpha<RendererType,
                                                              agg::span_allocator<color_type>,
                                                              span_gen_type>;

        double p[8];
        p[0] = 0;     p[1] = 0;
        p[2] = width; p[3] = 0;
        p[4] = width; p[5] = height;
        p[6] = 0;     p[7] = height;
        tr.transform(&p[0], &p[1]);
        tr.transform(&p[2], &p[3]);
        tr.transform(&p[4], &p[5]);
        tr.transform(&p[6], &p[7]);
        agg::span_allocator<color_type> sa;
        agg::image_filter_lut filter;
        filter.calculate(agg::image_filter_bilinear(), true);
        const_rendering_buffer src_buffer(src);
        pixfmt_pre pixf(src_buffer);
        img_accessor_type ia(pixf);
        agg::trans_affine final_tr(p, 0, 0, width, height);
        if (snap_to_pixels)
        {
            final_tr.tx = std::floor(final_tr.tx+.5);
            final_tr.ty = std::floor(final_tr.ty+.5);
        }
        interpolator_type interpolator(final_tr);
        span_gen_type sg(ia, interpolator, filter);
        renderer_type rp(renb, sa, sg, unsigned(opacity*255));
        ras.move_to_d(p[0],p[1]);
        ras.line_to_d(p[2],p[3]);
        ras.line_to_d(p[4],p[5]);
        ras.line_to_d(p[6],p[7]);
        agg::render_scanlines(ras, sl, rp);
    }
}