30 #include YFM_YSLib_Adaptor_Image
31 #include <FreeImage.h>
32 #include YFM_YSLib_Service_YBlit
33 #include YFM_YSLib_Service_YGDI
34 #include YFM_CHRLib_CharacterProcessing // for CHRLib::ToASCII;
43 static_assert(
int(SamplingFilter::Box) == FILTER_BOX &&
int(
44 SamplingFilter::Bicubic) == FILTER_BICUBIC &&
int(SamplingFilter::Bilinear)
45 == FILTER_BILINEAR &&
int(SamplingFilter::BSpline) == FILTER_BSPLINE &&
int(
46 SamplingFilter::CatmullRom) == FILTER_CATMULLROM &&
int(
47 SamplingFilter::Lanczos3) == FILTER_LANCZOS3,
"Incompatible filter found.");
55 FI_OutputMessage(::FREE_IMAGE_FORMAT fif,
const char* msg)
64 [](
void *buffer,
unsigned size,
unsigned nmemb, fi_handle h){
65 return unsigned(std::fread(buffer,
std::size_t(size),
68 [](
void *buffer,
unsigned size,
unsigned nmemb, fi_handle h){
69 return unsigned(std::fwrite(buffer,
std::size_t(size),
72 [](::fi_handle h,
long offset,
int whence){
73 return std::fseek(static_cast<std::FILE*>(h), offset, whence);
76 return std::ftell(static_cast<std::FILE*>(h));
87 const auto bitmap(::FreeImage_LoadFromHandle(::FREE_IMAGE_FORMAT(fmt),
88 &u8_io, ::fi_handle(
fp),
int(flags)));
99 return LoadImage(fmt,
ufopen(filename,
"rb"), flags);
105 return LoadImage(fmt,
ufopen(filename, u
"rb"), flags);
114 const bool res(::FreeImage_SaveToHandle(::FREE_IMAGE_FORMAT(fmt),
115 dib, &u8_io, ::fi_handle(
fp),
int(flags)));
123 SaveImage(
ImageFormat fmt, ::FIBITMAP* dib,
const char* filename,
126 return SaveImage(fmt, dib,
ufopen(filename,
"wb"), flags);
129 SaveImage(
ImageFormat fmt, ::FIBITMAP* dib,
const char16_t* filename,
132 return SaveImage(fmt, dib,
ufopen(filename, u
"wb"), flags);
139 GetFileType(std::FILE*
fp)
144 fif(::FreeImage_GetFileTypeFromHandle(&u8_io, ::fi_handle(fp)));
152 GetFileType(
const char* filename)
154 return GetFileType(
ufopen(filename,
"rb"));
157 GetFileType(
const char16_t* filename)
159 return GetFileType(
ufopen(filename, u
"rb"));
164 GetFormatFromFilename(
const char16_t* filename)
166 const auto len(std::char_traits<char16_t>::length(filename));
168 const auto str(p.get());
170 for(
size_t i{}; i < len; ++i)
173 return ImageFormat(::FreeImage_GetFIFFromFilename(str));
177 LookupPlugin(::FREE_IMAGE_FORMAT fif)
179 if(
auto p_node = ::FreeImageEx_GetPluginNodeFromFIF(fif))
181 if(
const auto p_plugin = p_node->m_plugin)
184 throw LoggedEvent(
"Invalid plugin node found.");
187 throw LoggedEvent(
"No proper plugin found.");
191 #if (YCL_PIXEL_FORMAT_XYZ555 & 0x00FFFFFF) == 0x00BBCCDD
192 # define YF_PixConvSpec \
193 16, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK
194 #elif (YCL_PIXEL_FORMAT_XYZ555 & 0x00FFFFFF) == 0x00DDCCBB
195 # define YF_PixConvSpec \
196 16, FI16_555_BLUE_MASK, FI16_555_GREEN_MASK, FI16_555_RED_MASK
199 #elif (YCL_PIXEL_FORMAT_XYZ888 & 0x00FFFFFF) == 0x00DDCCBB
200 # define YF_PixConvSpec \
201 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK
202 # if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
206 # error "No supported FreeImage pixel format found."
209 # error "Unsupported pixel format found."
222 const auto p_data(pixmap.GetDataPtr());
226 handle = ::FreeImage_OpenMemory();
227 if(!::FreeImage_SaveToMemory(::FREE_IMAGE_FORMAT(
format), p_data,
229 throw LoggedEvent(
"Saving image to memory failed.");
234 format = ImageCodec::DetectFormat(
handle, buffer.size());
240 return std::move(buf);
241 }()),
handle(::FreeImage_OpenMemory(static_cast<byte*>(buffer.data()),
242 static_cast< ::DWORD>(buffer.size()))),
format(fmt)
247 ImageMemory::~ImageMemory()
250 ::FreeImage_CloseMemory(
handle);
255 :
bitmap(::FreeImage_Allocate(s.
Width, s.Height, bpp, 0, 0, 0))
263 return ::FreeImage_ConvertFromRawBits(reinterpret_cast<byte*>(src),
265 YF_PixConvSpec,
true);
269 throw LoggedEvent(
"Converting compact pixmap failed.");
272 :
HBitmap(buf.GetBufferPtr(), buf.GetSize())
275 :
HBitmap(filename, ImageCodec::DetectFormat(filename), flags)
278 :
bitmap(LoadImage(fmt, filename, flags))
284 :
HBitmap(filename, ImageCodec::DetectFormat(filename), flags)
288 :
bitmap(LoadImage(fmt, filename, flags))
294 :
bitmap(::FreeImage_LoadFromMemory(::FREE_IMAGE_FORMAT(mem.GetFormat()),
295 mem.GetNativeHandle(), int(flags)))
305 return FreeImage_ConvertTo32Bits(p_bmp);
307 return FreeImage_ConvertTo24Bits(p_bmp);
309 return FreeImage_ConvertTo16Bits555(p_bmp);
311 return FreeImage_ConvertTo8Bits(p_bmp);
313 return FreeImage_ConvertTo4Bits(p_bmp);
324 ::FREE_IMAGE_FILTER(sf)))
342 ::FreeImage_Unload(
bitmap);
346 HBitmap::operator[](
size_t idx)
const ynothrow
349 YAssert(idx < GetHeight(),
"Index out of range.");
350 return ::FreeImage_GetScanLine(
bitmap, idx);
355 const Size&
s(GetSize());
358 ::FreeImage_ConvertToRawBits(reinterpret_cast<byte*>(&pixels[0]),
359 GetDataPtr(),
s.Width *
sizeof(PixelType), YF_PixConvSpec,
true);
366 return ::FreeImage_GetBPP(
bitmap);
371 return ::FreeImage_GetHeight(
bitmap);
376 return ::FreeImage_GetPitch(
bitmap);
381 return ::FreeImage_GetBits(
bitmap);
386 return ::FreeImage_GetWidth(
bitmap);
399 return SaveImage(fmt, GetDataPtr(), filename, flags);
405 return SaveImage(fmt, GetDataPtr(), filename, flags);
415 std::reference_wrapper<::FreeImageIO>
io_ref;
421 MultiBitmapData(::fi_handle,
int, ::FI_PluginRec&, ::FreeImageIO& = u8_io,
433 LockPage(
size_t = 0) const ynothrow;
437 ::FI_PluginRec& plugin, ::FreeImageIO& io,
bool open_for_reading) ynothrow
441 io.seek_proc(
handle, 0, SEEK_SET);
442 if(
const auto open = plugin.open_proc)
445 if(
const auto proc =
plugin_ref.get().pagecount_proc)
452 ::FreeImageIO& io,
bool open_for_reading)
ynothrow
454 LookupPlugin(::FREE_IMAGE_FORMAT(fmt)), io, open_for_reading)
458 if(
const auto close =
plugin_ref.get().close_proc)
466 if(
const auto load =
plugin_ref.get().load_proc)
486 catch(std::exception&)
494 return LoadImagePages(fmt,
ufopen(filename,
"rb"), flags);
497 LoadImagePages(
ImageFormat fmt,
const char16_t* filename,
500 return LoadImagePages(fmt,
ufopen(filename, u
"rb"), flags);
511 return x.p_bitmaps == y.p_bitmaps && (!x.p_bitmaps || x.index == y.index);
515 :
HMultiBitmap(filename, ImageCodec::DetectFormat(filename), flags)
519 : pages(LoadImagePages(fmt, filename, flags))
525 :
HMultiBitmap(filename, ImageCodec::DetectFormat(filename), flags)
529 : pages(LoadImagePages(fmt, filename, flags))
536 HMultiBitmap::GetPageCount() const
ynothrow
548 ImageCodec::ImageCodec()
551 const auto old_errno(errno);
553 ::FreeImage_Initialise(
false);
554 ::FreeImage_SetOutputMessageStdCall(FI_OutputMessage);
557 ImageCodec::~ImageCodec()
559 ::FreeImage_DeInitialise();
565 return ImageFormat(::FreeImage_GetFileTypeFromMemory(handle, size));
568 ImageCodec::DetectFormat(
const char* filename)
570 const auto fmt(GetFileType(filename));
573 ?
ImageFormat(::FreeImage_GetFIFFromFilename(filename)) : fmt;
576 ImageCodec::DetectFormat(
const char16_t* filename)
578 const auto fmt(GetFileType(filename));
586 ImageMemory mem(std::move(buf));
589 throw UnknownImageFormat(
"Unknown image format found when loading.");
595 ImageCodec::LoadForPlaying(
const char* path)
597 const auto fmt(DetectFormat(path));
603 ImageCodec::LoadForPlaying(
const char16_t* path)
605 const auto fmt(DetectFormat(path));
611 #undef YF_PixConvSpec
std::FILE ConversionState fp
handle(::FreeImage_OpenMemory(static_cast< byte * >(buffer.data()), static_cast< ::DWORD >(buffer.size())))
HBitmap Lock(size_t=0) const
ImageMemory(const HBitmap &, ImageFormat=ImageFormat::BMP, ImageDecoderFlags=ImageDecoderFlags::Default)
构造:从现有图像打开。
#define yunused(...)
标记未使用的表达式。
yconstfn char ToASCII(_tChar c)
任意整数类型字符转换为 ASCII 取值范围兼容的字符。
std::reference_wrapper<::FI_PluginRec > plugin_ref
DefPred(const ynothrow, OpenForRead, read) DefGetter(const ynothrow
yconstfn auto GetAreaOf(const Size &s) ynothrow-> decltype(s.Width *s.Height)
取面积。
std::reference_wrapper<::FreeImageIO > io_ref
std::uint16_t SDst
屏幕坐标距离。
图像资源分配失败异常:表示存储等资源不足导致无法创建图像。
page_count::FIBITMAP * LockPage(size_t=0) const ynothrow
yconstfn bool operator==(const GBinaryGroup< _type > &a, const GBinaryGroup< _type > &b) ynothrow
比较:屏幕二元组相等关系。
不可复制对象:禁止派生类调用默认原型的复制构造函数和复制赋值操作符。
::FIMEMORY * NativeHandle
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
未知图像格式异常:表示请求的操作涉及的图像格式因为不明确而不受库的支持。
byte * GetPixels() const ynothrow
取像素数据。
YF_API std::FILE * ufopen(const char *filename, const char *mode) ynothrow
以 UTF-8 文件名打开文件。
MultiBitmapData(::fi_handle, int,::FI_PluginRec &,::FreeImageIO &=u8_io, bool=true) ynothrow
#define YAssertNonnull(_expr)
PDefH(byte *, GetScanLine, size_t idx) const ynothrow ImplRet(bitmap?(*this) Rescale[idx] void(const Size &, SamplingFilter=SamplingFilter::Box)
取扫描线数据。
HBitmap(DataPtr ptr={}) ynothrow
BitPerPixel GetBPP() const ynothrow
ImageDecoderFlags
图像解码器标识。
#define YTraceDe(...)
YCLib 默认调试跟踪。
bool SaveTo(const char *, ImageFormat=ImageFormat::BMP, ImageDecoderFlags=ImageDecoderFlags::Default) const ynothrow
\ brief 保存:使用指定 UTF-8 文件名、格式和解码器标识。
if(YB_UNLIKELY(r >=sGraphics.Height)) throw std return pBuffer r *sGraphics Width
DefGetter(const ynothrow, AlphaType *, BufferAlphaPtr, pBufferAlpha) DefGetter(const ynothrow
取 Alpha 缓冲区的指针。
enable_if_t<!is_array< _type >::value, std::unique_ptr< _type > > make_unique(_tParams &&...args)
使用 new 和指定参数构造指定类型的 std::unique_ptr 实例。
HMultiBitmap(const char *, ImageDecoderFlags=ImageDecoderFlags::Default)
构造:使用指定 UTF-8 文件名和解码器标识。
未被支持的图像格式异常:表示请求的操作涉及的图像格式不受库的支持。
SDst GetPitch() const ynothrow
#define YAssert(_expr, _msg)