summaryrefslogtreecommitdiff
path: root/src/imageutils-macosx.cc
diff options
context:
space:
mode:
authordonbright <hugh.m.bright@gmail.com>2013-03-05 23:47:14 (GMT)
committerdonbright <hugh.m.bright@gmail.com>2013-03-05 23:47:14 (GMT)
commit42f21c3a0850083d245aa3ac346a53e876f0679e (patch)
treefacf41750e0fe27cc4cdaf352c9c8e687011d103 /src/imageutils-macosx.cc
parent422c668dcb538f181683ae51305bf8d3404f48d6 (diff)
parent4734172c3a16cc06b09e4d2131aa8e380bd0f226 (diff)
Merge pull request #288 from openscad/issue11_2
Issue11 2
Diffstat (limited to 'src/imageutils-macosx.cc')
-rw-r--r--src/imageutils-macosx.cc98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/imageutils-macosx.cc b/src/imageutils-macosx.cc
new file mode 100644
index 0000000..4c7c446
--- /dev/null
+++ b/src/imageutils-macosx.cc
@@ -0,0 +1,98 @@
+#include <ApplicationServices/ApplicationServices.h>
+#include <iostream>
+#include "imageutils.h"
+#include <assert.h>
+
+CGDataConsumerCallbacks dc_callbacks;
+
+size_t write_bytes_to_ostream (void *info,const void *buffer,size_t count)
+{
+ assert( info && buffer );
+ std::ostream *output = (std::ostream *)info;
+ size_t startpos = output->tellp();
+ size_t endpos = startpos;
+ try {
+ output->write( (const char *)buffer, count );
+ endpos = output->tellp();
+ } catch (const std::ios_base::failure& e) {
+ std::cerr << "Error writing to ostream:" << e.what() << "\n";
+ }
+ return (endpos-startpos);
+}
+
+CGDataConsumerRef CGDataConsumerCreateWithOstream(std::ostream &output)
+{
+ dc_callbacks.putBytes = write_bytes_to_ostream;
+ dc_callbacks.releaseConsumer = NULL; // ostream closed by caller of write_png
+ CGDataConsumerRef dc = CGDataConsumerCreate ( (void *)(&output), &dc_callbacks );
+ return dc;
+}
+
+bool write_png(std::ostream &output, unsigned char *pixels, int width, int height)
+{
+ size_t rowBytes = width * 4;
+// CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big; // BGRA
+ int bitsPerComponent = 8;
+ CGContextRef contextRef = CGBitmapContextCreate(pixels, width, height,
+ bitsPerComponent, rowBytes,
+ colorSpace, bitmapInfo);
+ if (!contextRef) {
+ std::cerr << "Unable to create CGContextRef.";
+ return false;
+ }
+
+ CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
+ if (!imageRef) {
+ std::cerr << "Unable to create CGImageRef.";
+ return false;
+ }
+
+ CGDataConsumerRef dataconsumer = CGDataConsumerCreateWithOstream(output);
+ /*
+ CFStringRef fname = CFStringCreateWithCString(kCFAllocatorDefault, filename, kCFStringEncodingUTF8);
+ CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ fname, kCFURLPOSIXPathStyle, false);
+ if (!fileURL) {
+ std::cerr << "Unable to create file URL ref.";
+ return false;
+ }
+
+ CGDataConsumerRef dataconsumer = CGDataConsumerCreateWithURL(fileURL);
+ */
+
+ CFIndex fileImageIndex = 1;
+ CFMutableDictionaryRef fileDict = NULL;
+ CFStringRef fileUTType = kUTTypePNG;
+ // Create an image destination opaque reference for authoring an image file
+ CGImageDestinationRef imageDest = CGImageDestinationCreateWithDataConsumer(dataconsumer,
+ fileUTType,
+ fileImageIndex,
+ fileDict);
+ if (!imageDest) {
+ std::cerr << "Unable to create CGImageDestinationRef.";
+ return false;
+ }
+
+ CFIndex capacity = 1;
+ CFMutableDictionaryRef imageProps =
+ CFDictionaryCreateMutable(kCFAllocatorDefault,
+ capacity,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CGImageDestinationAddImage(imageDest, imageRef, imageProps);
+ CGImageDestinationFinalize(imageDest);
+
+ CFRelease(imageDest);
+ CFRelease(dataconsumer);
+ //CFRelease(fileURL);
+ //CFRelease(fname);
+ CFRelease(imageProps);
+ CGColorSpaceRelease(colorSpace);
+ CGImageRelease(imageRef);
+ return true;
+}
+
+
+
contact: Jan Huwald // Impressum