open bmp image with memory buffer
This commit is contained in:
		
							parent
							
								
									3c8ee33ae8
								
							
						
					
					
						commit
						1c938a06fd
					
				@ -1,7 +1,7 @@
 | 
			
		||||
/*
 | 
			
		||||
 *	Bitmap Format Graphics Implementation
 | 
			
		||||
 *	Nana C++ Library(http://www.nanapro.org)
 | 
			
		||||
 *	Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *	Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
 | 
			
		||||
 *
 | 
			
		||||
 *	Distributed under the Boost Software License, Version 1.0.
 | 
			
		||||
 *	(See accompanying file LICENSE_1_0.txt or copy at
 | 
			
		||||
@ -14,14 +14,12 @@
 | 
			
		||||
#define NANA_PAINT_DETAIL_IMAGE_BMP_HPP
 | 
			
		||||
 | 
			
		||||
#include "image_pixbuf.hpp"
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
namespace nana{	namespace paint
 | 
			
		||||
{
 | 
			
		||||
	namespace detail
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
#ifndef NANA_WINDOWS
 | 
			
		||||
		struct bitmap_file_header
 | 
			
		||||
		{
 | 
			
		||||
@ -78,32 +76,14 @@ namespace nana{	namespace paint
 | 
			
		||||
 | 
			
		||||
			bool open(const void* data, std::size_t bytes) override
 | 
			
		||||
			{
 | 
			
		||||
				// TODO: read a BMP file from memory
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
				auto bmp_data = reinterpret_cast<const char*>(data);
 | 
			
		||||
 | 
			
		||||
			bool open(const nana::experimental::filesystem::path& filename) override
 | 
			
		||||
			{
 | 
			
		||||
				std::ifstream ifs(filename.string(), std::ios::binary);
 | 
			
		||||
				if(ifs)
 | 
			
		||||
				{
 | 
			
		||||
					ifs.seekg(0, std::ios::end);
 | 
			
		||||
					auto size = ifs.tellg();
 | 
			
		||||
					ifs.seekg(0, std::ios::beg);
 | 
			
		||||
 | 
			
		||||
					if(size <= static_cast<int>(sizeof(bitmap_file_header)))
 | 
			
		||||
				auto header = reinterpret_cast<const bitmap_file_header*>(bmp_data);
 | 
			
		||||
				if ((header->bfType != 0x4D42) || (header->bfSize != bytes))
 | 
			
		||||
					return false;
 | 
			
		||||
 | 
			
		||||
					std::unique_ptr<char[]> buffer(new char[static_cast<int>(size)]);
 | 
			
		||||
 | 
			
		||||
					ifs.read(buffer.get(), size);
 | 
			
		||||
					if(size == ifs.gcount())
 | 
			
		||||
					{
 | 
			
		||||
						bitmap_file_header * header = reinterpret_cast<bitmap_file_header*>(buffer.get());
 | 
			
		||||
						if((header->bfType == 0x4D42) && (static_cast<std::streamsize>(header->bfSize) == size))
 | 
			
		||||
						{
 | 
			
		||||
							unsigned char* bits = reinterpret_cast<unsigned char*>(buffer.get() + header->bfOffBits);
 | 
			
		||||
							bitmap_info * info = reinterpret_cast<bitmap_info *>(header + 1);
 | 
			
		||||
				auto bits = reinterpret_cast<const unsigned char*>(bmp_data + header->bfOffBits);
 | 
			
		||||
				auto info = reinterpret_cast<const bitmap_info *>(header + 1);
 | 
			
		||||
 | 
			
		||||
				//Bitmap file is 4byte-aligned for each line.
 | 
			
		||||
				std::size_t bytes_per_line;
 | 
			
		||||
@ -135,7 +115,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							auto s_p = s;
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
											rgb_quad & rgb = info->bmiColors[*s_p++];
 | 
			
		||||
								auto & rgb = info->bmiColors[*s_p++];
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
								d_p->element.blue = rgb.rgbBlue;
 | 
			
		||||
@ -156,7 +136,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							const auto * s_p = s;
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
											rgb_quad & rgb = info->bmiColors[*s_p++];
 | 
			
		||||
								auto & rgb = info->bmiColors[*s_p++];
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
								d_p->element.blue = rgb.rgbBlue;
 | 
			
		||||
@ -181,7 +161,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							unsigned index = 0;
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
											rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
 | 
			
		||||
								auto & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
 | 
			
		||||
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
@ -205,7 +185,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							unsigned index = 0;
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
											rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
 | 
			
		||||
								auto & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
 | 
			
		||||
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
@ -233,7 +213,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
								unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2
 | 
			
		||||
											rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift];
 | 
			
		||||
								auto& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift)) >> shift];
 | 
			
		||||
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
@ -258,7 +238,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
								unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2
 | 
			
		||||
											rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift];
 | 
			
		||||
								auto& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift)) >> shift];
 | 
			
		||||
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
@ -286,7 +266,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
								unsigned bi = (7 - (index & 7));	//(index % 8)
 | 
			
		||||
											rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
 | 
			
		||||
								auto & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
 | 
			
		||||
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
@ -311,7 +291,7 @@ namespace nana{	namespace paint
 | 
			
		||||
							while (d_p != dpend)
 | 
			
		||||
							{
 | 
			
		||||
								unsigned bi = (7 - (index & 7));
 | 
			
		||||
											rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
 | 
			
		||||
								auto & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
 | 
			
		||||
 | 
			
		||||
								d_p->element.red = rgb.rgbRed;
 | 
			
		||||
								d_p->element.green = rgb.rgbGreen;
 | 
			
		||||
@ -325,10 +305,29 @@ namespace nana{	namespace paint
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool open(const nana::experimental::filesystem::path& filename) override
 | 
			
		||||
			{
 | 
			
		||||
				std::ifstream ifs(filename.string(), std::ios::binary);
 | 
			
		||||
				if(ifs)
 | 
			
		||||
				{
 | 
			
		||||
					ifs.seekg(0, std::ios::end);
 | 
			
		||||
					auto size = ifs.tellg();
 | 
			
		||||
					ifs.seekg(0, std::ios::beg);
 | 
			
		||||
 | 
			
		||||
					if(size <= static_cast<int>(sizeof(bitmap_file_header)))
 | 
			
		||||
						return false;
 | 
			
		||||
 | 
			
		||||
					std::unique_ptr<char[]> buffer(new char[static_cast<int>(size)]);
 | 
			
		||||
 | 
			
		||||
					ifs.read(buffer.get(), size);
 | 
			
		||||
					if (size == ifs.gcount())
 | 
			
		||||
						return open(buffer.get(), size);
 | 
			
		||||
				}
 | 
			
		||||
				}
 | 
			
		||||
				return (false == pixbuf_.empty());
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool alpha_channel() const override
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user