diff options
Diffstat (limited to 'linden/indra/llwindow/llwindowmacosx-objc.mm')
-rw-r--r-- | linden/indra/llwindow/llwindowmacosx-objc.mm | 75 |
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 | ||
47 | BOOL 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 | |||
110 | BOOL 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 | |||
45 | void setupCocoa() | 120 | void setupCocoa() |
46 | { | 121 | { |
47 | static bool inited = false; | 122 | static bool inited = false; |