Last active
January 19, 2020 13:48
-
-
Save alf-p-steinbach/dd46eff089924deefcacfedc0f1a1c6c to your computer and use it in GitHub Desktop.
Gdi+ bitmap from base-64 encoded data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <string_view> // std::string_view | |
//---------------------------------------- Lenna image scaled down to 51x51: | |
namespace lenna { | |
using std::string_view; | |
const auto& data_literal = R"( | |
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 | |
d4I3FbxtBXdTKRR7g7nH/YXfQQHvs09CRRfQXbLoKavpZZYN9NAXXXYvpAWBBcje | |
JUfuGkXl9zAPfw+pA2Pr4fj2YGI/JnxWLhwKJ3ejiIOhpDEKa0YgmRFLpyWyAY50 | |
MTVpu7Zoq/7hVlPlTm+zZ6BtZ/ipZ6zHM9G7OzP8ZuVZlzPxGZW+b1bsmdX1AQT6 | |
33z09yI22mpfj/eUcyNpx6GiU3DeKTiQFOyTsEcUxZTJ9DzV9iLFAqr0Qz/xRwPV | |
PIgRfUjX7BoFwH8quR3cCMW2wDCdgTiAbCtR0x0S/jQkfBBPeUbnjjH4k1z+MJP/ | |
Kit5PS99ozxvs7poq+XxVnP1dmeDp6/VM9TuHunaGe/dmRpyTw+Pcfn7NsWuSVbs | |
h4qnqle7Gt/MDb5fHOktLqEeh/G8wKxj/tyT0Hhf+qzZ8jwx5kWy9XmSGVQPwzZB | |
0X1BAJn4MFMD7NU+wRWAinBsOxzTHRjaFxK2/yC6MyisM5AwiCNNkFgTNM4IS/jS | |
YV5x2jfyMjbL8zcel6xVFG5Ul2w3Vbk7G9x9rauNVduDHe6Rp1sjPdt9bQdm3qZd | |
M1eavz3UfjDVuzve/XZhtCMzm+4FAxoR56vJYGMa07LL9jLJ+jzBshJnAjXBsY1Q | |
zBAK89oh+ZSnfeuUVvsEVt4LaYJhWqDojgBsRwDuqMoySojoDAwfwPwfGVP0Qh81 | |
r9G8cNheZSSvFWav5qWvlzzYLMvdqCzcqC1ff1K61ly93l6/1lzzsqVupblu50m+ | |
p69+b6TdM9rpAQ7KcMeHpbECuZF5EsY4dl/gjXgcJluyWl+l2F8kxgBky3FmUB0U | |
Ww9B94aEvnGJj/Ki38ZKq31DqnxCmqGYZiiqHY7uRIf/WW1al7P6UWG96IgRMmdZ | |
pZ6SKp4b9MtG44s451pa4mZe2mZB+npu+mpO2lpp7vrjh6u1latVZc9LCp5XFW22 | |
P9rpa/IMtbqH2j0jnbtDbS+Lsna76xQ3cCwvMPOYv/6n8Dk9UEfHV7Ik23NAtkQL | |
qAaMrvFHDaLxb12Sj3nR71zSaj90lQ+qEYJpgqBaoKhOPOnLE73HyJsikfpx1AWp | |
YpwrXlJHzinUi3rDK5vtpTNhIT593uF8mRz3KiNp7UHa6oOM51mZy9kP1h/l73RU | |
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)"; | |
// 1 byte for zero-termination, 1 byte for initial newline => 2 byte adjustment. | |
constexpr auto data = string_view( data_literal + 1, sizeof( data_literal ) - 2 ); | |
} // namespace lenna |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// For C++17 and later. Link with "gdiplus", "shlwapi" and "crypt32". | |
#include <header-wrappers/winapi/gdiplus-h.hpp> | |
#include <header-wrappers/winapi/wincrypt-h.hpp> // CryptStringToBinaryA | |
#include <header-wrappers/winapi/shlwapi-h.hpp> | |
#include <stddef.h> // ptrdiff_t | |
#include <fstream> // std::ofstream | |
#include <iostream> // std::clog | |
#include <memory> // std::unique_ptr | |
#include <optional> // std::optional | |
#include <stdexcept> // std::(exception, runtime_error) | |
#include <string> // std::string | |
#include <string_view> // std::string_view | |
#include <type_traits> // std::(is_class_v, is_aggregate_v) | |
#include "lenna.hpp" // - 51x51 Lenna image, base-64 encoded, 7662 bytes decoded. | |
//---------------------------------------- Extending the core language & std library: | |
#define WITH( ... ) \ | |
if( const auto& _ [[maybe_unused]] = __VA_ARGS__; true ) | |
namespace cppx { | |
using std::runtime_error, std::string; | |
template< class T > constexpr bool has_constructor = | |
std::is_class_v<T> and not std::is_aggregate_v<T>; | |
template< class T > using Type_ = T; | |
using Byte = unsigned char; | |
using Size = ptrdiff_t; | |
auto hopefully( const bool expr ) -> bool { return expr; } | |
auto fail( const string& message ) -> bool { throw runtime_error( message ); } | |
} // namespace cppx | |
//---------------------------------------- Base64 decryption: | |
namespace base64 { | |
using std::optional, std::string; | |
using cppx::Size; | |
// Based on the Windows API's CryptStringToBinaryA, <url: | |
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinarya> | |
// because "polfosol"'s function, <url: | |
// https://stackoverflow.com/a/37109258>, didn't work. | |
auto decode( const void* data, const Size len ) | |
-> optional<string> | |
{ | |
using R = optional<string>; | |
const DWORD flags = CRYPT_STRING_BASE64; | |
DWORD n_bytes = 0; | |
const bool found_n_bytes = !!CryptStringToBinaryA( | |
reinterpret_cast<const char*>( data ), // LPCSTR pszString, | |
len, // DWORD cchString, | |
flags, // DWORD dwFlags, | |
nullptr, // BYTE *pbBinary, | |
&n_bytes, // DWORD *pcbBinary, | |
nullptr, // DWORD *pdwSkip, | |
nullptr // DWORD *pdwFlags | |
); | |
if( not found_n_bytes ) { | |
return R(); | |
} else if( n_bytes <= 1 ) { | |
return R( "" ); | |
} | |
auto result = string( n_bytes, '\0' ); | |
const bool success = !!CryptStringToBinaryA( | |
reinterpret_cast<const char*>( data ), // LPCSTR pszString, | |
len, // DWORD cchString, | |
flags, // DWORD dwFlags, | |
reinterpret_cast<BYTE*>( result.data() ), // BYTE *pbBinary, | |
&n_bytes, // DWORD *pcbBinary, | |
nullptr, // DWORD *pdwSkip, | |
nullptr // DWORD *pdwFlags | |
); | |
return (success? R( result ) : R()); | |
} | |
} // namespace base64 | |
//---------------------------------------- GDI+ wrapping: | |
namespace gdi_plusplus { | |
using std::to_string, std::unique_ptr; | |
using | |
cppx::Type_, cppx::has_constructor, | |
cppx::Size, cppx::Byte, | |
cppx::hopefully, cppx::fail; | |
namespace gp = Gdiplus; // Microsoft's GDI+ API. | |
// API function result type. | |
namespace status { | |
using Enum = gp::Status; | |
using gp::Ok; // Etc. | |
} | |
class Library_usage | |
{ | |
ULONG_PTR m_token; | |
public: | |
Library_usage() | |
{ | |
static_assert( has_constructor<gp::GdiplusStartupInput>, "!" ); | |
gp::GdiplusStartupInput startup_input; | |
const status::Enum rc = gp::GdiplusStartup( &m_token, &startup_input, nullptr ); | |
hopefully( rc == status::Ok ) | |
or fail( "GdiplusStartup failed, code " + to_string( rc ) ); | |
} | |
~Library_usage() { gp::GdiplusShutdown( m_token ); } | |
}; | |
auto bitmap_from_bytes( const Type_<const void*> p_bytes, const Size len ) | |
-> unique_ptr<gp::Bitmap> | |
{ | |
using R = unique_ptr<gp::Bitmap>; | |
struct Stream | |
{ | |
IStream* p; | |
Stream( const Type_<const void*> p_bytes, const Size len ): | |
p( SHCreateMemStream( reinterpret_cast<const Byte*>( p_bytes ), len ) ) | |
{ | |
hopefully( p != nullptr ) | |
or fail( "SHCreateMemStream failed" ); | |
} | |
~Stream() { p->Release(); } | |
}; | |
Stream stream( p_bytes, len ); | |
return R( gp::Bitmap::FromStream( stream.p ) ); | |
} | |
auto size_of( const gp::Image& image ) | |
-> gp::SizeF | |
{ | |
gp::SizeF result; | |
const status::Enum result_code = | |
const_cast<gp::Image&>( image ).GetPhysicalDimension( &result ); | |
hopefully( result_code == status::Ok ) | |
or fail( "GdiPlus::Image::GetPhysicalDimension failed" ); | |
return result; | |
} | |
} // namespace gdi_plusplus | |
//---------------------------------------- Demo app: | |
namespace app { | |
using std::ofstream, std::optional, std::string, std::unique_ptr, std::cout, std::endl; | |
using cppx::hopefully, cppx::fail; | |
void run() | |
{ | |
namespace gp = Gdiplus; | |
namespace gpp = gdi_plusplus; | |
WITH( gpp::Library_usage() ) { | |
const optional<string> lenna_image_bytes = base64::decode( | |
&lenna::data[0], lenna::data.size() | |
); | |
hopefully( lenna_image_bytes.has_value() ) | |
or fail( "base64::decode failed to decode lenna image data." ); | |
#ifdef SAVE_RAW_PLEASE | |
{ // Save the raw image bytes. | |
ofstream f( "image.raw-bytes.jpg", ofstream::binary ); | |
f.write( lenna_image_bytes->data(), lenna_image_bytes->size() ); | |
} | |
#endif | |
unique_ptr<gp::Bitmap> lenna = gpp::bitmap_from_bytes( | |
lenna_image_bytes->data(), lenna_image_bytes->size() | |
); | |
const gp::SizeF size = gpp::size_of( *lenna ); | |
cout << "GDI+ successfully constructed a " | |
<< size.Width << "x" << size.Height << " image." | |
<< endl; | |
} | |
} | |
} // namespace app | |
#include <stdlib.h> // EXIT_... | |
auto main() | |
-> int | |
{ | |
using std::exception, std::clog, std::endl; | |
try { | |
app::run(); | |
return EXIT_SUCCESS; | |
} catch( const exception& x ) { | |
clog << "!" << x.what() << endl; | |
} | |
return EXIT_FAILURE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment