open png/jpg image with memory buffer

This commit is contained in:
Jinhao
2016-01-27 01:14:28 +08:00
parent 5a960ed88c
commit 3c8ee33ae8
8 changed files with 278 additions and 152 deletions

View File

@@ -25,6 +25,27 @@ namespace nana
struct ::jpeg_error_mgr pub;
std::jmp_buf setjmp_buf;
};
void _m_read_jpg(jpeg_decompress_struct& jdstru)
{
::jpeg_read_header(&jdstru, true); //Reject a tables-only JPEG file as an error
::jpeg_start_decompress(&jdstru);
//JSAMPLEs per row in output buffer
auto row_stride = jdstru.output_width * jdstru.output_components;
pixbuf_.open(jdstru.output_width, jdstru.output_height);
auto row_buf = jdstru.mem->alloc_sarray(reinterpret_cast<j_common_ptr>(&jdstru), JPOOL_IMAGE, row_stride, 1);
while (jdstru.output_scanline < jdstru.output_height)
{
::jpeg_read_scanlines(&jdstru, row_buf, 1);
pixbuf_.fill_row(jdstru.output_scanline - 1, reinterpret_cast<unsigned char*>(*row_buf), row_stride, jdstru.output_components * 8);
}
}
public:
bool open(const experimental::filesystem::path& jpeg_file) override
{
@@ -45,25 +66,10 @@ namespace nana
::jpeg_stdio_src(&jdstru, fp);
::jpeg_read_header(&jdstru, true); //Reject a tables-only JPEG file as an error
::jpeg_start_decompress(&jdstru);
//JSAMPLEs per row in output buffer
auto row_stride = jdstru.output_width * jdstru.output_components;
pixbuf_.open(jdstru.output_width, jdstru.output_height);
auto row_buf = jdstru.mem->alloc_sarray(reinterpret_cast<j_common_ptr>(&jdstru), JPOOL_IMAGE, row_stride, 1);
while (jdstru.output_scanline < jdstru.output_height)
{
::jpeg_read_scanlines(&jdstru, row_buf, 1);
pixbuf_.fill_row(jdstru.output_scanline - 1, reinterpret_cast<unsigned char*>(*row_buf), row_stride, jdstru.output_components * 8);
}
_m_read_jpg(jdstru);
jpeg_finish_decompress(&jdstru);
is_opened = true;
}
::jpeg_destroy_decompress(&jdstru);
@@ -73,8 +79,27 @@ namespace nana
bool open(const void* data, std::size_t bytes) override
{
throw std::logic_error("JPEG is not supported for raw data buffer");
return false;
bool is_opened = false;
struct ::jpeg_decompress_struct jdstru;
error_mgr jerr;
jdstru.err = ::jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = _m_error_handler;
if (!setjmp(jerr.setjmp_buf))
{
::jpeg_create_decompress(&jdstru);
::jpeg_mem_src(&jdstru, const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(data)), bytes);
_m_read_jpg(jdstru);
jpeg_finish_decompress(&jdstru);
is_opened = true;
}
::jpeg_destroy_decompress(&jdstru);
return is_opened;
}
private:
static void _m_error_handler(::j_common_ptr jdstru)