From 565d2e1389b0a72e6eca7068988a9312991abfb1 Mon Sep 17 00:00:00 2001 From: elektrahesse Date: Sat, 9 Oct 2010 19:05:40 +0200 Subject: Mac Only: Implemented initial CoreGraphics image decoding to support uploads, both single and bulk, bypassing viewer's internal decoding classes and using osx native frameworks. Also pushing non-fully-working-yet (and thus disabled) code for native j2c decoding. --- linden/indra/llwindow/llwindowmacosx-objc.h | 10 +++++ linden/indra/llwindow/llwindowmacosx-objc.mm | 60 ++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) (limited to 'linden/indra/llwindow') diff --git a/linden/indra/llwindow/llwindowmacosx-objc.h b/linden/indra/llwindow/llwindowmacosx-objc.h index 14cddaa..14c9c92 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.h +++ b/linden/indra/llwindow/llwindowmacosx-objc.h @@ -31,6 +31,14 @@ * $/LicenseInfo$ */ +#include "llimagej2c.h" +#include + +#ifdef __OBJC__ +#ifdef BOOL +#undef BOOL +#endif +#endif // __OBJC__ // This will actually hold an NSCursor*, but that type is only available in objective C. typedef void *CursorRef; @@ -40,3 +48,5 @@ void setupCocoa(); CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); OSErr releaseImageCursor(CursorRef ref); OSErr setImageCursor(CursorRef ref); +BOOL decodeImageQuartz(std::string filename, LLImageRaw *raw_image); +BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image); diff --git a/linden/indra/llwindow/llwindowmacosx-objc.mm b/linden/indra/llwindow/llwindowmacosx-objc.mm index bc47164..5f33764 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.mm +++ b/linden/indra/llwindow/llwindowmacosx-objc.mm @@ -32,6 +32,8 @@ */ #include +#include +#include /* * These functions are broken out into a separate file because the @@ -42,6 +44,64 @@ #include "llwindowmacosx-objc.h" +BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) +{ + CFDataRef theData = CFDataCreate(kCFAllocatorDefault, data, len); + CGImageSourceRef srcRef = CGImageSourceCreateWithData(theData, NULL); + CGImageRef image_ref = CGImageSourceCreateImageAtIndex(srcRef, 0, NULL); + + size_t width = CGImageGetWidth(image_ref); + size_t height = CGImageGetHeight(image_ref); + size_t comps = CGImageGetBitsPerPixel(image_ref) / 8; + size_t bytes_per_row = CGImageGetBytesPerRow(image_ref); + CFDataRef result = CGDataProviderCopyData(CGImageGetDataProvider(image_ref)); + UInt8* bitmap = (UInt8*)CFDataGetBytePtr(result); + + CGImageAlphaInfo format = CGImageGetAlphaInfo(image_ref); + if (format & kCGImageAlphaPremultipliedFirst) + { + vImage_Buffer vb; + vb.data = bitmap; + vb.height = height; + vb.width = width; + vb.rowBytes = bytes_per_row; + llinfos << "Unpremultiplying ARGB888" << llendl; + vImageUnpremultiplyData_ARGB8888(&vb, &vb, 0); + } + else if (format & kCGImageAlphaPremultipliedLast) + { + vImage_Buffer vb; + vb.data = bitmap; + vb.height = height; + vb.width = width; + vb.rowBytes = bytes_per_row; + llinfos << "Unpremultiplying RGBA888" << llendl; + vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0); + } + + raw_image->resize(width, height, comps); + llinfos << "Decoding an image of width: " << width << " and height: " << height << " and components: " << comps << llendl; + memcpy(raw_image->getData(), bitmap, height * bytes_per_row); + raw_image->verticalFlip(); + + CFRelease(theData); + CFRelease(srcRef); + CGImageRelease(image_ref); + CFRelease(result); + + return TRUE; +} + +BOOL decodeImageQuartz(std::string filename, LLImageRaw *raw_image) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSURL *url = [[NSURL alloc] initFileURLWithPath:[NSString stringWithCString:filename.c_str()]]; + NSData *data = [NSData dataWithContentsOfURL:url]; + BOOL result = decodeImageQuartz((UInt8*)[data bytes], [data length], raw_image); + [pool release]; + return result; +} + void setupCocoa() { static bool inited = false; -- cgit v1.1 From d39b5c51f3a7cd36a4dc86423ce099e421263bcc Mon Sep 17 00:00:00 2001 From: elektrahesse Date: Wed, 13 Oct 2010 04:09:26 +0200 Subject: Added support for upload and local usage of PSD (Photoshop, including layers and native transparency) and TIFF images (including alpha channel) on any Intel Mac using native Quartz/vImage routines --- linden/indra/llwindow/llwindowmacosx-objc.mm | 45 ++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) (limited to 'linden/indra/llwindow') diff --git a/linden/indra/llwindow/llwindowmacosx-objc.mm b/linden/indra/llwindow/llwindowmacosx-objc.mm index 5f33764..e961070 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.mm +++ b/linden/indra/llwindow/llwindowmacosx-objc.mm @@ -49,7 +49,7 @@ BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) CFDataRef theData = CFDataCreate(kCFAllocatorDefault, data, len); CGImageSourceRef srcRef = CGImageSourceCreateWithData(theData, NULL); CGImageRef image_ref = CGImageSourceCreateImageAtIndex(srcRef, 0, NULL); - + CFShow(CGImageGetColorSpace(image_ref)); size_t width = CGImageGetWidth(image_ref); size_t height = CGImageGetHeight(image_ref); size_t comps = CGImageGetBitsPerPixel(image_ref) / 8; @@ -58,29 +58,44 @@ BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) UInt8* bitmap = (UInt8*)CFDataGetBytePtr(result); CGImageAlphaInfo format = CGImageGetAlphaInfo(image_ref); - if (format & kCGImageAlphaPremultipliedFirst) + if (format != kCGImageAlphaNone) { vImage_Buffer vb; vb.data = bitmap; vb.height = height; vb.width = width; vb.rowBytes = bytes_per_row; - llinfos << "Unpremultiplying ARGB888" << llendl; - vImageUnpremultiplyData_ARGB8888(&vb, &vb, 0); - } - else if (format & kCGImageAlphaPremultipliedLast) - { - vImage_Buffer vb; - vb.data = bitmap; - vb.height = height; - vb.width = width; - vb.rowBytes = bytes_per_row; - llinfos << "Unpremultiplying RGBA888" << llendl; - vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0); + + if (format & kCGImageAlphaPremultipliedFirst) + { + // Ele: ARGB -> BGRA on Intel, need to first reorder the bytes, then unpremultiply as RGBA :) + llinfos << "Unpremultiplying BGRA8888" << llendl; + + for (int i=0; iresize(width, height, comps); - llinfos << "Decoding an image of width: " << width << " and height: " << height << " and components: " << comps << llendl; memcpy(raw_image->getData(), bitmap, height * bytes_per_row); raw_image->verticalFlip(); -- cgit v1.1 From 0b502cfb4c9d44401389a5a904e296c5703a399d Mon Sep 17 00:00:00 2001 From: elektrahesse Date: Wed, 13 Oct 2010 04:15:15 +0200 Subject: Removed a debug message left over --- linden/indra/llwindow/llwindowmacosx-objc.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linden/indra/llwindow') diff --git a/linden/indra/llwindow/llwindowmacosx-objc.mm b/linden/indra/llwindow/llwindowmacosx-objc.mm index e961070..abe8c5d 100644 --- a/linden/indra/llwindow/llwindowmacosx-objc.mm +++ b/linden/indra/llwindow/llwindowmacosx-objc.mm @@ -49,7 +49,7 @@ BOOL decodeImageQuartz(const UInt8* data, int len, LLImageRaw *raw_image) CFDataRef theData = CFDataCreate(kCFAllocatorDefault, data, len); CGImageSourceRef srcRef = CGImageSourceCreateWithData(theData, NULL); CGImageRef image_ref = CGImageSourceCreateImageAtIndex(srcRef, 0, NULL); - CFShow(CGImageGetColorSpace(image_ref)); + size_t width = CGImageGetWidth(image_ref); size_t height = CGImageGetHeight(image_ref); size_t comps = CGImageGetBitsPerPixel(image_ref) / 8; -- cgit v1.1