diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-10-29 19:58:34 -0400 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-10-30 12:02:28 -0400 |
commit | e3bc69b7e77aa6771c8db3695f12548447e1de51 (patch) | |
tree | 0c1a0bde928fea3e09b1d72222b400176c0936c7 /platform/darwin/image.mm | |
parent | 7a13db9a863c9be58709e941f44eb2c370276e2a (diff) | |
download | qtlocation-mapboxgl-e3bc69b7e77aa6771c8db3695f12548447e1de51.tar.gz |
use CoreImage for decoding/encoding images on osx/ios
Diffstat (limited to 'platform/darwin/image.mm')
-rw-r--r-- | platform/darwin/image.mm | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/platform/darwin/image.mm b/platform/darwin/image.mm new file mode 100644 index 0000000000..50c871533d --- /dev/null +++ b/platform/darwin/image.mm @@ -0,0 +1,125 @@ +#include <mbgl/util/image.hpp> + +#import <ImageIO/ImageIO.h> + +#if TARGET_OS_IPHONE +#import <MobileCoreServices/MobileCoreServices.h> +#else +#import <CoreServices/CoreServices.h> +#endif + +namespace mbgl { +namespace util { + +std::string compress_png(int width, int height, void *rgba) { + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, rgba, width * height * 4, NULL); + if (!provider) { + return ""; + } + + CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); + if (!color_space) { + CGDataProviderRelease(provider); + return ""; + } + + CGImageRef image = CGImageCreate(width, height, 8, 32, 4 * width, color_space, + kCGBitmapByteOrderDefault | kCGImageAlphaLast, provider, NULL, false, + kCGRenderingIntentDefault); + if (!image) { + CGColorSpaceRelease(color_space); + CGDataProviderRelease(provider); + return ""; + } + + CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); + if (!data) { + CGImageRelease(image); + CGColorSpaceRelease(color_space); + CGDataProviderRelease(provider); + return ""; + } + + CGImageDestinationRef image_destination = CGImageDestinationCreateWithData(data, kUTTypePNG, 1, NULL); + if (!image_destination) { + CFRelease(data); + CGImageRelease(image); + CGColorSpaceRelease(color_space); + CGDataProviderRelease(provider); + return ""; + } + + CGImageDestinationAddImage(image_destination, image, NULL); + CGImageDestinationFinalize(image_destination); + + const std::string result { + reinterpret_cast<const char *>(CFDataGetBytePtr(data)), + static_cast<size_t>(CFDataGetLength(data)) + }; + + CFRelease(image_destination); + CFRelease(data); + CGImageRelease(image); + CGColorSpaceRelease(color_space); + CGDataProviderRelease(provider); + + return result; +} + +Image::Image(const std::string &source_data) { + CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const unsigned char *>(source_data.data()), source_data.size(), kCFAllocatorNull); + if (!data) { + return; + } + + CGImageSourceRef image_source = CGImageSourceCreateWithData(data, NULL); + if (!image_source) { + CFRelease(data); + return; + } + + CGImageRef image = CGImageSourceCreateImageAtIndex(image_source, 0, NULL); + if (!image) { + CFRelease(image_source); + CFRelease(data); + return; + } + + CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); + if (!color_space) { + CGImageRelease(image); + CFRelease(image_source); + CFRelease(data); + return; + } + + width = CGImageGetWidth(image); + height = CGImageGetHeight(image); + CGRect rect = {{ 0, 0 }, { static_cast<CGFloat>(width), static_cast<CGFloat>(height) }}; + + img = ::std::unique_ptr<char[]>(new char[width * height * 4]()); + CGContextRef context = CGBitmapContextCreate(img.get(), width, height, 8, width * 4, + color_space, kCGImageAlphaPremultipliedLast); + if (!context) { + CGColorSpaceRelease(color_space); + CGImageRelease(image); + CFRelease(image_source); + CFRelease(data); + width = 0; + height = 0; + img.release(); + return; + } + + CGContextSetBlendMode(context, kCGBlendModeCopy); + CGContextDrawImage(context, rect, image); + + CGContextRelease(context); + CGColorSpaceRelease(color_space); + CGImageRelease(image); + CFRelease(image_source); + CFRelease(data); +} + +} +}
\ No newline at end of file |