1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 #include "javax_microedition_m3g_Image2D.h" |
|
18 |
|
19 JNIEXPORT void JNICALL Java_javax_microedition_m3g_Image2D__1set |
|
20 (JNIEnv* aEnv, jclass, jint aHImage2D, jint aX, jint aY, jint aWidth, jint aHeight, jbyteArray aImageArray) |
|
21 { |
|
22 jbyte* imageArray = NULL; |
|
23 if (aImageArray) |
|
24 { |
|
25 imageArray = aEnv->GetByteArrayElements(aImageArray, NULL); |
|
26 if (imageArray == NULL) |
|
27 { |
|
28 M3G_RAISE_EXCEPTION(aEnv, "java/lang/OutOfMemoryError"); |
|
29 return; |
|
30 } |
|
31 } |
|
32 M3G_DO_LOCK |
|
33 m3gSetSubImage((M3GImage)aHImage2D, aX, aY, aWidth, aHeight, aImageArray ? aEnv->GetArrayLength(aImageArray) : NULL, imageArray); |
|
34 M3G_DO_UNLOCK(aEnv) |
|
35 |
|
36 if (imageArray) |
|
37 { |
|
38 aEnv->ReleaseByteArrayElements(aImageArray, imageArray, JNI_ABORT); |
|
39 } |
|
40 } |
|
41 |
|
42 static void getImageScanline(const QImage* qtImage, |
|
43 M3Gint line, |
|
44 M3Gint bpl, |
|
45 M3Guint *pixels, |
|
46 M3Gbool *trueAlpha) |
|
47 { |
|
48 |
|
49 // Get pointer to start of requested line |
|
50 const unsigned char* srcAddr = qtImage->bits() + line * bpl; |
|
51 |
|
52 // As input and output are in the same, i.e. #AARRGGBB format, |
|
53 // just run mem copy from source to destination to copy one line |
|
54 memcpy(pixels, srcAddr, bpl); |
|
55 *trueAlpha = false; |
|
56 } |
|
57 |
|
58 /* |
|
59 * Must be excuted in UI thread |
|
60 */ |
|
61 JNIEXPORT jint JNICALL Java_javax_microedition_m3g_Image2D__1ctorImage |
|
62 (JNIEnv* aEnv, jclass, jint aHM3g, jint aFormat, jint aImageHandle) |
|
63 { |
|
64 |
|
65 if (aImageHandle != 0) |
|
66 { |
|
67 Java::GFX::Image* cgfxImage = reinterpret_cast<Java::GFX::Image*>(aImageHandle); |
|
68 QImage qtImage; |
|
69 |
|
70 if (!cgfxImage) |
|
71 { |
|
72 return 0; |
|
73 } |
|
74 else |
|
75 { |
|
76 qtImage = cgfxImage->toImage(); |
|
77 if (qtImage.isNull()) |
|
78 { |
|
79 return 0; |
|
80 } |
|
81 } |
|
82 |
|
83 // m3g needs format in 32bpp, i.e. in RGB32 or ARGB32 so |
|
84 // if format is not one of those convert it here |
|
85 if ((qtImage.format() != QImage::Format_ARGB32) || (qtImage.format() != QImage::Format_RGB32)) |
|
86 { |
|
87 qtImage = qtImage.convertToFormat(QImage::Format_ARGB32); |
|
88 if (qtImage.isNull()) |
|
89 { |
|
90 return 0; |
|
91 } |
|
92 } |
|
93 |
|
94 // Create Image2D |
|
95 M3GImage image; |
|
96 M3Gint width = qtImage.width(); |
|
97 M3Gint height = qtImage.height(); |
|
98 M3Gint bpl = qtImage.bytesPerLine(); |
|
99 |
|
100 M3G_DO_LOCK |
|
101 |
|
102 image = m3gCreateImage((M3GInterface)aHM3g, (M3GImageFormat)aFormat, width, height, 0); |
|
103 if (image == NULL) |
|
104 { |
|
105 return 0; // exception automatically raised |
|
106 } |
|
107 |
|
108 M3Guint *tempPixels = (M3Guint *) malloc(width * 4); |
|
109 if (tempPixels == NULL) |
|
110 { |
|
111 m3gDeleteObject((M3GObject) image); |
|
112 return 0; |
|
113 } |
|
114 |
|
115 // read and write scanline by scanline |
|
116 for (M3Gint y = 0; y < height; ++y) |
|
117 { |
|
118 M3Gbool trueAlpha; |
|
119 getImageScanline(&qtImage, y, bpl, tempPixels, &trueAlpha); |
|
120 m3gSetImageScanline(image, y, trueAlpha, tempPixels); |
|
121 } |
|
122 |
|
123 // finally commit image |
|
124 m3gCommitImage(image); |
|
125 |
|
126 M3G_DO_UNLOCK(aEnv) |
|
127 |
|
128 // free memory |
|
129 free(tempPixels); |
|
130 |
|
131 cgfxImage = NULL; |
|
132 return reinterpret_cast<jint>(image); |
|
133 } |
|
134 return 0; |
|
135 } |
|
136 |
|
137 JNIEXPORT jint JNICALL Java_javax_microedition_m3g_Image2D__1getFormat |
|
138 (JNIEnv* aEnv, jclass, jint aHImage2D) |
|
139 { |
|
140 M3G_DO_LOCK |
|
141 jint format = (jint)m3gGetFormat((M3GImage)aHImage2D); |
|
142 M3G_DO_UNLOCK(aEnv) |
|
143 return format; |
|
144 } |
|
145 |
|
146 JNIEXPORT jint JNICALL Java_javax_microedition_m3g_Image2D__1ctorSizePixelsPalette |
|
147 (JNIEnv* aEnv, jclass, jint aM3g, jint aFormat, jint aWidth, jint aHeight, jbyteArray aImage, jbyteArray aPalette) |
|
148 { |
|
149 M3GImageFormat format = (M3GImageFormat)aFormat; |
|
150 |
|
151 int bpp = jsr184BytesPerPixel(format); |
|
152 |
|
153 if (validateArray(aEnv, aImage, aWidth * aHeight)) |
|
154 { |
|
155 if (aPalette == NULL) |
|
156 { |
|
157 M3G_RAISE_EXCEPTION(aEnv, "java/lang/NullPointerException"); |
|
158 return 0; |
|
159 } |
|
160 int paletteLen = aEnv->GetArrayLength(aPalette); |
|
161 if ((paletteLen < 256 *(unsigned)bpp) && |
|
162 (paletteLen % (unsigned)bpp != 0)) |
|
163 { |
|
164 M3G_RAISE_EXCEPTION(aEnv, "java/lang/IllegalArgumentException"); |
|
165 return 0; |
|
166 } |
|
167 else |
|
168 { |
|
169 M3G_DO_LOCK |
|
170 |
|
171 M3GImage hImg = m3gCreateImage((M3GInterface)aM3g, |
|
172 format, |
|
173 aWidth, aHeight, |
|
174 M3G_PALETTED); |
|
175 if (hImg != NULL) |
|
176 { |
|
177 jbyte* palette = NULL; |
|
178 |
|
179 int numEntries = paletteLen / bpp; |
|
180 if (numEntries > 256) |
|
181 { |
|
182 numEntries = 256; |
|
183 } |
|
184 |
|
185 jbyte* image = aEnv->GetByteArrayElements(aImage, NULL); |
|
186 if (image == NULL) |
|
187 { |
|
188 M3G_RAISE_EXCEPTION(aEnv, "java/lang/OutOfMemoryError"); |
|
189 return 0; |
|
190 } |
|
191 |
|
192 m3gSetImage(hImg, image); |
|
193 |
|
194 palette = aEnv->GetByteArrayElements(aPalette, NULL); |
|
195 if (palette == NULL) |
|
196 { |
|
197 if (image) |
|
198 { |
|
199 aEnv->ReleaseByteArrayElements(aImage, image, JNI_ABORT); |
|
200 } |
|
201 M3G_RAISE_EXCEPTION(aEnv, "java/lang/OutOfMemoryError"); |
|
202 return 0; |
|
203 } |
|
204 |
|
205 m3gSetImagePalette(hImg, numEntries, palette); |
|
206 m3gCommitImage(hImg); |
|
207 |
|
208 if (image) |
|
209 { |
|
210 aEnv->ReleaseByteArrayElements(aImage, image, JNI_ABORT); |
|
211 } |
|
212 if (palette) |
|
213 { |
|
214 aEnv->ReleaseByteArrayElements(aPalette, palette, JNI_ABORT); |
|
215 } |
|
216 } |
|
217 M3G_DO_UNLOCK(aEnv) |
|
218 return ((unsigned) hImg); |
|
219 } |
|
220 } |
|
221 return 0; |
|
222 } |
|
223 |
|
224 JNIEXPORT jboolean JNICALL Java_javax_microedition_m3g_Image2D__1isMutable |
|
225 (JNIEnv* aEnv, jclass, jint aHImage2D) |
|
226 { |
|
227 M3G_DO_LOCK |
|
228 jboolean isMutable = (jboolean)m3gIsMutable((M3GImage)aHImage2D); |
|
229 M3G_DO_UNLOCK(aEnv) |
|
230 return isMutable; |
|
231 } |
|
232 |
|
233 JNIEXPORT jint JNICALL Java_javax_microedition_m3g_Image2D__1getHeight |
|
234 (JNIEnv* aEnv, jclass, jint aHImage2D) |
|
235 { |
|
236 M3G_DO_LOCK |
|
237 jint height = (jint)m3gGetHeight((M3GImage)aHImage2D); |
|
238 M3G_DO_UNLOCK(aEnv) |
|
239 return height; |
|
240 } |
|
241 |
|
242 JNIEXPORT jint JNICALL Java_javax_microedition_m3g_Image2D__1ctorSize |
|
243 (JNIEnv* aEnv, jclass, jint aM3g, jint aFormat, jint aWidth, jint aHeight) |
|
244 { |
|
245 M3G_DO_LOCK |
|
246 jint handle = (M3Guint) m3gCreateImage((M3GInterface)aM3g, |
|
247 (M3GImageFormat)aFormat, |
|
248 aWidth, aHeight, |
|
249 M3G_DYNAMIC|M3G_RENDERING_TARGET); |
|
250 M3G_DO_UNLOCK(aEnv) |
|
251 return handle; |
|
252 } |
|
253 |
|
254 JNIEXPORT jint JNICALL Java_javax_microedition_m3g_Image2D__1getWidth |
|
255 (JNIEnv* aEnv, jclass, jint aHImage2D) |
|
256 { |
|
257 M3G_DO_LOCK |
|
258 jint width = (jint)m3gGetWidth((M3GImage)aHImage2D); |
|
259 M3G_DO_UNLOCK(aEnv) |
|
260 return width; |
|
261 } |
|
262 |
|
263 |
|
264 JNIEXPORT jint JNICALL Java_javax_microedition_m3g_Image2D__1ctorSizePixels |
|
265 (JNIEnv* aEnv, jclass, jint aM3g, jint aFormat, jint aWidth, jint aHeight, jbyteArray aImage) |
|
266 { |
|
267 M3GImageFormat format = (M3GImageFormat)aFormat; |
|
268 |
|
269 if (validateArray(aEnv, aImage, jsr184BytesPerPixel(format) * aWidth * aHeight)) |
|
270 { |
|
271 M3G_DO_LOCK |
|
272 |
|
273 M3GImage hImg = m3gCreateImage((M3GInterface)aM3g, format, aWidth, aHeight, 0); |
|
274 if (hImg != NULL) |
|
275 { |
|
276 M3GImageFormat format = (M3GImageFormat)aFormat; |
|
277 |
|
278 int bpp = jsr184BytesPerPixel(format); |
|
279 jbyte* imageScanline = (jbyte*)malloc(aWidth * bpp); |
|
280 for (int i=0; i < aHeight; i++) |
|
281 { |
|
282 aEnv->GetByteArrayRegion(aImage, aWidth * i * bpp, aWidth * bpp, imageScanline); |
|
283 m3gSetSubImage(hImg, 0, i, aWidth, 1, aWidth * bpp, imageScanline); |
|
284 } |
|
285 m3gCommitImage(hImg); |
|
286 |
|
287 free(imageScanline); |
|
288 } |
|
289 M3G_DO_UNLOCK(aEnv) |
|
290 return (unsigned) hImg; |
|
291 } |
|
292 return 0; |
|
293 } |
|