aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llwindow/llwindowmacosx-objc.mm
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llwindow/llwindowmacosx-objc.mm')
-rw-r--r--linden/indra/llwindow/llwindowmacosx-objc.mm75
1 files changed, 75 insertions, 0 deletions
diff --git a/linden/indra/llwindow/llwindowmacosx-objc.mm b/linden/indra/llwindow/llwindowmacosx-objc.mm
index bc47164..abe8c5d 100644
--- a/linden/indra/llwindow/llwindowmacosx-objc.mm
+++ b/linden/indra/llwindow/llwindowmacosx-objc.mm
@@ -32,6 +32,8 @@
32 */ 32 */
33 33
34#include <AppKit/AppKit.h> 34#include <AppKit/AppKit.h>
35#include <Accelerate/Accelerate.h>
36#include <Quartz/Quartz.h>
35 37
36/* 38/*
37 * These functions are broken out into a separate file because the 39 * These functions are broken out into a separate file because the
@@ -42,6 +44,79 @@
42 44
43#include "llwindowmacosx-objc.h" 45#include "llwindowmacosx-objc.h"
44 46
47BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image)
48{
49 CFDataRef theData = CFDataCreate(kCFAllocatorDefault, data, len);
50 CGImageSourceRef srcRef = CGImageSourceCreateWithData(theData, NULL);
51 CGImageRef image_ref = CGImageSourceCreateImageAtIndex(srcRef, 0, NULL);
52
53 size_t width = CGImageGetWidth(image_ref);
54 size_t height = CGImageGetHeight(image_ref);
55 size_t comps = CGImageGetBitsPerPixel(image_ref) / 8;
56 size_t bytes_per_row = CGImageGetBytesPerRow(image_ref);
57 CFDataRef result = CGDataProviderCopyData(CGImageGetDataProvider(image_ref));
58 UInt8* bitmap = (UInt8*)CFDataGetBytePtr(result);
59
60 CGImageAlphaInfo format = CGImageGetAlphaInfo(image_ref);
61 if (format != kCGImageAlphaNone)
62 {
63 vImage_Buffer vb;
64 vb.data = bitmap;
65 vb.height = height;
66 vb.width = width;
67 vb.rowBytes = bytes_per_row;
68
69 if (format & kCGImageAlphaPremultipliedFirst)
70 {
71 // Ele: ARGB -> BGRA on Intel, need to first reorder the bytes, then unpremultiply as RGBA :)
72 llinfos << "Unpremultiplying BGRA8888" << llendl;
73
74 for (int i=0; i<height; i++)
75 {
76 for (int j=0; j<bytes_per_row; j+=4)
77 {
78 unsigned char tmp[4];
79
80 tmp[0] = bitmap[j*height+3];
81 tmp[1] = bitmap[j*height+2];
82 tmp[2] = bitmap[j*height+1];
83 tmp[3] = bitmap[j*height];
84
85 memcpy(&bitmap[j*height], &tmp, 4);
86 }
87 }
88
89 vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0);
90 }
91 else if (format & kCGImageAlphaPremultipliedLast)
92 {
93 llinfos << "Unpremultiplying RGBA8888" << llendl;
94 vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0);
95 }
96 }
97
98 raw_image->resize(width, height, comps);
99 memcpy(raw_image->getData(), bitmap, height * bytes_per_row);
100 raw_image->verticalFlip();
101
102 CFRelease(theData);
103 CFRelease(srcRef);
104 CGImageRelease(image_ref);
105 CFRelease(result);
106
107 return TRUE;
108}
109
110BOOL decodeImageQuartz(std::string filename, LLImageRaw *raw_image)
111{
112 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
113 NSURL *url = [[NSURL alloc] initFileURLWithPath:[NSString stringWithCString:filename.c_str()]];
114 NSData *data = [NSData dataWithContentsOfURL:url];
115 BOOL result = decodeImageQuartz((UInt8*)[data bytes], [data length], raw_image);
116 [pool release];
117 return result;
118}
119
45void setupCocoa() 120void setupCocoa()
46{ 121{
47 static bool inited = false; 122 static bool inited = false;