diff options
author | crupest <crupest@outlook.com> | 2022-05-08 18:46:32 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-05-08 18:46:32 +0800 |
commit | a7ca9057de3a01d5071406828f134e2e3bcfb49c (patch) | |
tree | d5fb0ce03ba86b1cb6db36ad6922a5ed0f0d9810 /src/osx/graphics/quartz/ImageFactory.cpp | |
parent | 75c8a508acc3388b2c2f624bdf00fb155cd914f9 (diff) | |
download | cru-a7ca9057de3a01d5071406828f134e2e3bcfb49c.tar.gz cru-a7ca9057de3a01d5071406828f134e2e3bcfb49c.tar.bz2 cru-a7ca9057de3a01d5071406828f134e2e3bcfb49c.zip |
...
Diffstat (limited to 'src/osx/graphics/quartz/ImageFactory.cpp')
-rw-r--r-- | src/osx/graphics/quartz/ImageFactory.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/osx/graphics/quartz/ImageFactory.cpp b/src/osx/graphics/quartz/ImageFactory.cpp index a8c17719..2c6d4705 100644 --- a/src/osx/graphics/quartz/ImageFactory.cpp +++ b/src/osx/graphics/quartz/ImageFactory.cpp @@ -1,12 +1,16 @@ #include "cru/osx/graphics/quartz/ImageFactory.h" #include "cru/common/Exception.h" +#include "cru/common/platform/osx/Convert.h" #include "cru/osx/graphics/quartz/Convert.h" #include "cru/osx/graphics/quartz/Image.h" +#include "cru/platform/Check.h" #include "cru/platform/graphics/Image.h" #include <ImageIO/ImageIO.h> namespace cru::platform::graphics::osx::quartz { +using cru::platform::osx::Convert; + QuartzImageFactory::QuartzImageFactory(IGraphicsFactory* graphics_factory) : OsxQuartzResource(graphics_factory) {} @@ -28,6 +32,53 @@ std::unique_ptr<IImage> QuartzImageFactory::DecodeFromStream( new QuartzImage(GetGraphicsFactory(), this, cg_image, true)); } +static String GetImageFormatUniformTypeIdentifier(ImageFormat format) { + switch (format) { + case ImageFormat::Png: + return u"public.png"; + case ImageFormat::Jpeg: + return u"public.jpeg"; + case ImageFormat::Gif: + return u"com.compuserve.gif"; + default: + throw Exception(u"Unknown image format."); + } +} + +void QuartzImageFactory::EncodeToStream(IImage* image, io::Stream* stream, + ImageFormat format, float quality) { + if (quality <= 0 || quality > 1) { + throw Exception(u"Invalid quality value."); + } + + auto quartz_image = CheckPlatform<QuartzImage>(image, GetPlatformId()); + auto cg_image = quartz_image->GetCGImage(); + + CFStringRef uti = Convert(GetImageFormatUniformTypeIdentifier(format)); + CGDataConsumerRef data_consumer = ConvertStreamToCGDataConsumer(stream); + CGImageDestinationRef destination = + CGImageDestinationCreateWithDataConsumer(data_consumer, uti, 1, nullptr); + + CFMutableDictionaryRef properties = + CFDictionaryCreateMutable(nullptr, 0, nullptr, nullptr); + CFNumberRef quality_wrap = + CFNumberCreate(nullptr, kCFNumberFloatType, &quality); + CFDictionaryAddValue(properties, kCGImageDestinationLossyCompressionQuality, + quality_wrap); + + CGImageDestinationAddImage(destination, cg_image, properties); + + if (!CGImageDestinationFinalize(destination)) { + throw Exception(u"Failed to finalize image destination."); + } + + CFRelease(quality_wrap); + CFRelease(properties); + CFRelease(destination); + CFRelease(data_consumer); + CFRelease(uti); +} + std::unique_ptr<IImage> QuartzImageFactory::CreateBitmap(int width, int height) { if (width <= 0) throw Exception(u"Image width should be greater than 0."); |