diff options
Diffstat (limited to 'linden/indra/llimagej2coj/llimagej2cquartz.mm')
-rw-r--r-- | linden/indra/llimagej2coj/llimagej2cquartz.mm | 147 |
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 | |||
13 | BOOL 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 | } | ||