aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llimagej2coj/llimagej2cquartz.mm
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llimagej2coj/llimagej2cquartz.mm')
-rw-r--r--linden/indra/llimagej2coj/llimagej2cquartz.mm147
1 files changed, 147 insertions, 0 deletions
diff --git a/linden/indra/llimagej2coj/llimagej2cquartz.mm b/linden/indra/llimagej2coj/llimagej2cquartz.mm
new file mode 100644
index 0000000..d5eefd1
--- /dev/null
+++ b/linden/indra/llimagej2coj/llimagej2cquartz.mm
@@ -0,0 +1,147 @@
1#import <Accelerate/Accelerate.h>
2#import <QuartzCore/QuartzCore.h>
3#import <Quartz/Quartz.h>
4
5#include "llimagej2cquartz.h"
6
7#if defined(__BIG_ENDIAN__)
8 CGImageAlphaInfo const kDefaultAlphaLocation = kCGImageAlphaPremultipliedLast;
9#else
10 CGImageAlphaInfo const kDefaultAlphaLocation = kCGImageAlphaPremultipliedFirst;
11#endif
12
13BOOL decodeJ2CQuartz(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
14{
15 U8 *srcData = (U8*)base.getData();
16 int srcLen = base.getDataSize();
17
18 llinfos << "[1] compressed image size: '" << srcLen << "'" << llendl;
19
20 int width = base.getWidth();
21 int height = base.getHeight();
22 int components = base.getComponents();
23
24 S32 channels = components - first_channel;
25 if( channels > max_channel_count )
26 channels = max_channel_count;
27
28 llinfos << "[2] components: '" << components << "' - channels: '" << channels << "' - first_channel: '" << first_channel << "' - max_channel_count: '" << max_channel_count << "'" << llendl;
29
30 if(components <= first_channel || components > 4)
31 return FALSE;
32
33 llinfos << "[3] attempting to decode a texture: '" << width << "'X'" << height << "'@'" << components * 8 << "'" << llendl;
34
35 U8 *tgt = (U8*)raw_image.getData();
36 if (!tgt)
37 return FALSE;
38
39 raw_image.resize(width, height, channels);
40
41 size_t rowBytes = width * components;
42 int realLen = width * height * components;
43
44 llinfos << "[4] allocating buffer of size: '" << realLen << "' to hold temp texture data" << llendl;
45 unsigned char* dataplane;
46
47 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
48 NSBitmapImageRep *rep = [NSBitmapImageRep alloc];
49
50 switch (components)
51 {
52 case 1:
53 {
54 rep = [[rep
55 initWithBitmapDataPlanes:nil
56 pixelsWide:width
57 pixelsHigh:height
58 bitsPerSample:8
59 samplesPerPixel:1
60 hasAlpha:NO
61 isPlanar:NO
62 colorSpaceName:NSDeviceWhiteColorSpace
63 bytesPerRow:rowBytes
64 bitsPerPixel:8
65 ] autorelease];
66
67 memcpy([rep bitmapData], srcData, srcLen);
68
69 dataplane = (unsigned char*)malloc(realLen);
70 memcpy(dataplane, [rep bitmapData], realLen);
71
72 [rep release];
73 }
74 break;
75
76 case 3:
77 {
78 NSData *data = [NSData dataWithBytes:srcData length:srcLen];
79 rep = [rep initWithData:data];
80
81 dataplane = (unsigned char*)malloc(realLen);
82 memcpy(dataplane, [rep bitmapData], realLen);
83
84 [data release];
85 [rep release];
86 }
87 break;
88
89 case 4:
90 {
91 NSData *data = [NSData dataWithBytes:srcData length:srcLen];
92 rep = [rep initWithData:data];
93
94 int imgLen = [rep pixelsHigh] * [rep bytesPerRow];
95 if (imgLen != realLen)
96 {
97 llwarns << "decoded image buffer size (" << imgLen << ") != expected buffer size (" << realLen << ") !" << llendl;
98 [rep release];
99 [data release];
100 return FALSE;
101 }
102
103 dataplane = (unsigned char*)malloc(realLen);
104 memcpy(dataplane, [rep bitmapData], realLen);
105
106 vImage_Buffer vb;
107 vb.data = dataplane;
108 vb.height = [rep pixelsHigh];
109 vb.width = [rep pixelsWide];
110 vb.rowBytes = [rep bytesPerRow];
111
112 llinfos << "Attempting Alpha Unpremultiplication" << llendl;
113 vImageUnpremultiplyData_RGBA8888(&vb, &vb, 0);
114 llinfos << "Unpremultiplied Alpha" << llendl;
115
116 llwarns << "after decoding: " << [rep pixelsWide] << "'X'" << [rep pixelsHigh] << "'@'" << [rep bitsPerPixel] << "'" << llendl;
117
118 [rep release];
119 [data release];
120 }
121 break;
122 }
123
124 if (dataplane)
125 {
126 for (int h=height-1; h>=0; h--)
127 {
128 for (int w=0; w<rowBytes; w+=(first_channel + channels))
129 {
130 for (int c=first_channel; c<(first_channel + channels); c++)
131 memcpy(tgt++, &dataplane[h*rowBytes + w + c], sizeof(unsigned char));
132 }
133 }
134
135 free(dataplane);
136
137 llinfos << "[5] size of decoded image is: '" << width*height*channels << "'" << llendl;
138
139 return TRUE;
140 }
141 else
142 {
143 llwarns << "[5] cannot decode image !" << llendl;
144 }
145
146 return FALSE;
147}