示例#1
0
image_reader* get_image_reader(std::string const& filename)
{
    boost::optional<std::string> type = type_from_filename(filename);
    if (type)
    {
        return factory<image_reader,std::string,std::string const&>::instance().create_object(*type,filename);
    }
    else
    {
        throw image_reader_exception("image_reader: can't determine type from input data");
    }
}
示例#2
0
void jpeg_reader<T>::read(unsigned x0, unsigned y0, image_data_32& 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.setRow(row - y0, out_row.get(), w);
        }
        ++row;
    }
    jpeg_finish_decompress(&cinfo);
}
示例#3
0
png_reader<T>::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();
}
示例#4
0
png_reader<T>::png_reader(std::string const& filename)
    : source_(),
      stream_(&source_),
      width_(0),
      height_(0),
      bit_depth_(0),
      color_type_(0),
      has_alpha_(false)
{
    source_.open(filename, std::ios_base::in | std::ios_base::binary);
    if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ filename + "'");
    init();
}
示例#5
0
tiff_reader<T>::tiff_reader(std::string const& file_name)
    : source_(file_name, std::ios_base::in | std::ios_base::binary),
      stream_(source_),
      read_method_(generic),
      width_(0),
      height_(0),
      rows_per_strip_(0),
      tile_width_(0),
      tile_height_(0),
      premultiplied_alpha_(false)
{
    if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ file_name);
    init();
}
示例#6
0
tiff_reader<T>::tiff_reader(char const* data, std::size_t size)
    : source_(data, size),
      stream_(source_),
      read_method_(generic),
      width_(0),
      height_(0),
      rows_per_strip_(0),
      tile_width_(0),
      tile_height_(0),
      premultiplied_alpha_(false)
{
    if (!stream_) throw image_reader_exception("TIFF reader: cannot open image stream ");
    stream_.seekg(0, std::ios::beg);
    init();
}
示例#7
0
webp_reader<T>::webp_reader(std::string const& filename)
    : buffer_(),
      size_(0),
      width_(0),
      height_(0)
{
    std::ifstream file(filename.c_str(), std::ios::binary);
    if (!file)
    {
        throw image_reader_exception("WEBP: Can't read file:" + filename);
    }
    std::streampos beg = file.tellg();
    file.seekg (0, std::ios::end);
    std::streampos end = file.tellg();
    std::size_t file_size = end - beg;
    file.seekg (0, std::ios::beg);
    buffer_ = std::auto_ptr<buffer_policy_type>(new buffer_policy_type(file_size));
    file.read(reinterpret_cast<char*>(buffer_->data()), buffer_->size());
    if (!file)
    {
        throw image_reader_exception("WEBP: Failed to read:" + filename);
    }
    init();
}
示例#8
0
    void JpegReader::init()
    {
        FILE *fp = fopen(fileName_.c_str(),"rb");
        if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + fileName_);

        struct jpeg_decompress_struct cinfo;
        struct jpeg_error_mgr jerr;
                
        cinfo.err = jpeg_std_error(&jerr);

        jpeg_create_decompress(&cinfo);
        jpeg_stdio_src(&cinfo, fp);
        jpeg_read_header(&cinfo, TRUE);

        jpeg_start_decompress(&cinfo);        
        width_ = cinfo.output_width;
        height_ = cinfo.output_height;
        //jpeg_finish_decompress(&cinfo);
        jpeg_destroy_decompress(&cinfo);
        fclose(fp);
    }
示例#9
0
void user_error_fn(png_structp png_ptr, png_const_charp error_msg)
{
    throw image_reader_exception("failed to read invalid png");
}
示例#10
0
void png_reader<T>::read(unsigned x0, unsigned y0,image_data_32& 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.getRow(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.setRow(i-y0,reinterpret_cast<unsigned*>(&row[x0 * 4]),w);
            }
        }
        //END
    }
    png_read_end(png_ptr,0);
}
示例#11
0
    void JpegReader::read(unsigned x0, unsigned y0, image_data_32& image) 
    {
        struct jpeg_decompress_struct cinfo;

        FILE *fp = fopen(fileName_.c_str(),"rb");
        if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + fileName_);

        struct jpeg_error_mgr jerr;
        cinfo.err = jpeg_std_error(&jerr);

        jpeg_create_decompress(&cinfo);
        jpeg_stdio_src(&cinfo, fp);

        jpeg_read_header(&cinfo, TRUE);
        if (cinfo.out_color_space == JCS_UNKNOWN)
            throw image_reader_exception("JPEG Reader: failed to read unknown color space in " + fileName_);
        
        jpeg_start_decompress(&cinfo);

        if (cinfo.output_width == 0) {
          jpeg_destroy_decompress (&cinfo);
          fclose(fp);
          throw image_reader_exception("JPEG Reader: failed to read image size of " + fileName_);
        }

        JSAMPARRAY buffer;
        int row_stride;
        unsigned char a,r,g,b;
        row_stride = cinfo.output_width * cinfo.output_components;
        buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

        unsigned w = std::min(unsigned(image.width()),width_);
        unsigned h = std::min(unsigned(image.height()),height_);
        
        boost::scoped_array<unsigned int> out_row(new unsigned int[w]);
        // TODO - handle x0
        for (unsigned i=0;i<h;++i)
        {
            jpeg_read_scanlines(&cinfo, buffer, 1);
            if (i>=y0 && i<h) 
            {
                for (unsigned int x=0; x<w; x++)
                {
                    a = 255; // alpha not supported in jpg
                    r = buffer[0][cinfo.output_components * x];
                    if (cinfo.output_components > 2)
                    {
                        g = buffer[0][cinfo.output_components*x+1];
                        b = buffer[0][cinfo.output_components*x+2];
                    } else {
                        g = r;
                        b = r;
                    }
                    out_row[x] = color(r, g, b, a).rgba();
                }
                image.setRow(i-y0, out_row.get(), w);
            } 
        }
        jpeg_finish_decompress(&cinfo);
        jpeg_destroy_decompress(&cinfo);
        fclose(fp);
    }
示例#12
0
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 + "'");
}
示例#13
0
void jpeg_reader<T>::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);
}
示例#14
0
void tiff_reader<T>::on_error(const char* , const char* fmt, va_list argptr)
{
  char msg[10240];
  vsprintf(msg, fmt, argptr);
  throw image_reader_exception(msg);
}
示例#15
0
    void png_reader::read(unsigned x0, unsigned y0,image_data_32& image) 
    {
        FILE *fp=fopen(fileName_.c_str(),"rb");
        if (!fp) throw image_reader_exception("cannot open image file "+fileName_);

        png_structp png_ptr = png_create_read_struct
            (PNG_LIBPNG_VER_STRING,0,0,0);

        if (!png_ptr) 
        {
            fclose(fp);
            throw image_reader_exception("failed to allocate png_ptr");
        }

        png_infop info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_read_struct(&png_ptr,0,0);
            fclose(fp);
            throw image_reader_exception("failed to create info_ptr");
        }

        png_set_read_fn(png_ptr, (png_voidp)fp, 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);

        png_read_update_info(png_ptr, info_ptr);

        //START read image rows
        unsigned w=std::min(unsigned(image.width()),width_);
        unsigned h=std::min(unsigned(image.height()),height_);
        unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr);
        boost::scoped_array<png_byte> row(new png_byte[rowbytes]);
	for (unsigned i=0;i<height_;++i)
        {
            png_read_row(png_ptr,row.get(),0);
            if (i>=y0 && i<h) 
            {
                image.setRow(i-y0,reinterpret_cast<unsigned*>(&row[x0]),w);
            } 
        }
        //END
        png_read_end(png_ptr,0);
        png_destroy_read_struct(&png_ptr, &info_ptr,0);
        fclose(fp);
    }
示例#16
0
void png_reader::init()
{
    FILE *fp=fopen(fileName_.c_str(),"rb");
    if (!fp) throw image_reader_exception("cannot open image file "+fileName_);
    png_byte header[8];
    memset(header,0,8);
    if ( fread(header,1,8,fp) != 8)
    {
        fclose(fp);
        throw image_reader_exception("Could not read " + fileName_);
    }
    int is_png=!png_sig_cmp(header,0,8);
    if (!is_png)
    {
        fclose(fp);
        throw image_reader_exception(fileName_ + " is not a png file");
    }
    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        fclose(fp);
        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;
    try
    {
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_read_struct(&png_ptr,0,0);
            fclose(fp);
            throw image_reader_exception("failed to create info_ptr");
        }
    }
    catch (std::exception const& ex)
    {
        png_destroy_read_struct(&png_ptr,0,0);
        fclose(fp);
        throw;
    }

    png_set_read_fn(png_ptr, (png_voidp)fp, 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);

    width_=width;
    height_=height;

    MAPNIK_LOG_DEBUG(png_reader) << "png_reader: bit_depth=" << bit_depth_ << ",color_type=" << color_type_;

    png_destroy_read_struct(&png_ptr,&info_ptr,0);
    fclose(fp);
}
示例#17
0
void png_reader::read(unsigned x0, unsigned y0,image_data_32& image)
{
    FILE *fp=fopen(fileName_.c_str(),"rb");
    if (!fp) throw image_reader_exception("cannot open image file "+fileName_);

    png_structp png_ptr = png_create_read_struct
        (PNG_LIBPNG_VER_STRING,0,0,0);

    if (!png_ptr)
    {
        fclose(fp);
        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;
    try
    {
        info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_read_struct(&png_ptr,0,0);
            fclose(fp);
            throw image_reader_exception("failed to create info_ptr");
        }
    }
    catch (std::exception const& ex)
    {
        png_destroy_read_struct(&png_ptr,0,0);
        fclose(fp);
        throw;
    }

    png_set_read_fn(png_ptr, (png_voidp)fp, 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
        boost::scoped_array<png_byte*> rows(new png_bytep[height_]);
        for (unsigned i=0; i<height_; ++i)
            rows[i] = (png_bytep)image.getRow(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_);
        unsigned h=std::min(unsigned(image.height()),height_);
        unsigned rowbytes=png_get_rowbytes(png_ptr, info_ptr);
        boost::scoped_array<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<h)
            {
                image.setRow(i-y0,reinterpret_cast<unsigned*>(&row[x0]),w);
            }
        }
        //END
    }

    png_read_end(png_ptr,0);
    png_destroy_read_struct(&png_ptr, &info_ptr,0);
    fclose(fp);
}