12 #include "gfxlog.h" |
12 #include "gfxlog.h" |
13 #include <memory> |
13 #include <memory> |
14 |
14 |
15 namespace Java { namespace GFX { |
15 namespace Java { namespace GFX { |
16 |
16 |
17 Pixmap::Pixmap() : mAlpha(-1), mHasMask(false) |
17 Pixmap::Pixmap() : ImageBase() |
18 { |
18 { |
19 GFX_LOG_FUNC_CALL(); |
19 GFX_LOG_FUNC_CALL(); |
20 } |
20 } |
21 |
21 |
22 Pixmap::~Pixmap() |
22 Pixmap::~Pixmap() |
23 { |
23 { |
24 GFX_LOG_FUNC_CALL(); |
24 GFX_LOG_FUNC_CALL(); |
25 } |
25 } |
26 |
26 |
27 void Pixmap::createBySize(int aWidth, int aHeight, int aFillColor, TImageFormat /*aFormat*/) |
27 void Pixmap::createBySize(int aWidth, int aHeight, int aFillColor, TImageFormat /*aFormat*/) |
28 { |
28 { |
29 GFX_LOG_FUNC_CALL(); |
29 GFX_LOG_FUNC_CALL(); |
30 Q_ASSERT(mPixmap.isNull()); |
30 Q_ASSERT(mPixmap.isNull()); |
31 |
31 |
32 // Pixmap's format is selected by the framework, thus it cannot be used here |
32 // Pixmap's format is selected by the framework, thus it cannot be used here |
33 mPixmap = QPixmap(aWidth, aHeight); |
33 mPixmap = QPixmap(aWidth, aHeight); |
34 |
34 |
35 // Check if creation was successful |
35 // Check if creation was successful |
36 if(mPixmap.isNull()) |
36 if(mPixmap.isNull()) |
37 { |
37 { |
38 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
38 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
39 } |
39 } |
40 |
40 |
41 // Finally fill with given fillColor, also clears the image mem area |
41 // Finally fill with given fillColor, also clears the image mem area |
42 // otherwise there might be some random coloured pixels in image |
42 // otherwise there might be some random coloured pixels in image |
43 QColor color; |
43 QColor color; |
44 color.setRgb(aFillColor); |
44 color.setRgb(aFillColor); |
45 mPixmap.fill(color); |
45 mPixmap.fill(color); |
46 } |
46 } |
47 |
47 |
48 void Pixmap::createFromQImage(const QImage& aImage) |
48 void Pixmap::createFromQImage(const QImage& aImage) |
49 { |
49 { |
50 GFX_LOG_FUNC_CALL(); |
50 GFX_LOG_FUNC_CALL(); |
51 Q_ASSERT(mPixmap.isNull()); |
51 Q_ASSERT(mPixmap.isNull()); |
52 |
52 |
53 // Convert to Pixmap |
53 // Convert to Pixmap |
54 mPixmap = QPixmap::fromImage(aImage); |
54 mPixmap = QPixmap::fromImage(aImage); |
55 |
55 |
56 // Validate allocation |
56 // Validate allocation |
57 if(mPixmap.isNull()) |
57 if(mPixmap.isNull()) |
58 { |
58 { |
59 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
59 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
60 } |
60 } |
61 } |
61 } |
62 |
62 |
63 void Pixmap::createFromQPixmap(const QPixmap& aPixmap) |
63 void Pixmap::createFromQPixmap(const QPixmap& aPixmap) |
64 { |
64 { |
65 GFX_LOG_FUNC_CALL(); |
65 GFX_LOG_FUNC_CALL(); |
66 Q_ASSERT(mPixmap.isNull()); |
66 Q_ASSERT(mPixmap.isNull()); |
67 |
67 |
68 mPixmap = QPixmap(aPixmap); |
68 mPixmap = QPixmap(aPixmap); |
69 |
69 |
70 // Validate allocation |
70 // Validate allocation |
71 if(mPixmap.isNull()) |
71 if(mPixmap.isNull()) |
72 { |
72 { |
73 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
73 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
74 } |
74 } |
75 } |
75 } |
76 |
76 |
77 void Pixmap::createFromImage(Image* aImage, int aX, int aY, int aWidth, int aHeight) |
77 void Pixmap::createFromImage(Image* aImage, int aX, int aY, int aWidth, int aHeight) |
78 { |
78 { |
79 GFX_LOG_FUNC_CALL(); |
79 GFX_LOG_FUNC_CALL(); |
80 Q_ASSERT(mPixmap.isNull()); |
80 Q_ASSERT(mPixmap.isNull()); |
81 |
81 |
82 // Get QPixmap from original |
82 // Check if the copy should be exactly same as the original |
83 QPixmap* src = aImage->getPixmap(); |
83 if((aImage->getWidth() == aWidth) && (aImage->getHeight() == aHeight) || |
84 if(!src) |
84 QRect(aX, aY, aWidth, aHeight).isEmpty()) |
85 { |
85 { |
|
86 mPixmap = aImage->toPixmap(); |
|
87 } |
|
88 // it's needed to make partial copy of the original |
|
89 else |
|
90 { |
|
91 switch(aImage->type()) |
|
92 { |
|
93 case EImage: |
|
94 { |
|
95 mPixmap = QPixmap::fromImage(aImage->getConstImage()->copy(aX, aY, aWidth, aHeight)); |
|
96 break; |
|
97 } |
|
98 case EPixmap: |
|
99 { |
|
100 mPixmap = aImage->getConstPixmap()->copy(aX, aY, aWidth, aHeight); |
|
101 break; |
|
102 } |
|
103 default: |
|
104 throw GfxException(EGfxErrorIllegalArgument, "Unsupported source image type"); |
|
105 } |
|
106 |
|
107 } |
|
108 if(mPixmap.isNull()) |
|
109 { |
86 throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed"); |
110 throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed"); |
87 } |
111 } |
88 |
112 } |
89 // If specific values were given and they represent the whole pixmap exactly |
|
90 bool isWholePixmap = (src->size() == QSize(aWidth, aHeight)) && (aX == aY == 0); |
|
91 |
|
92 // Also an empty area means that the whole pixmap needs to be copied |
|
93 bool isEmptyArea = QRect(aX, aY, aWidth, aHeight).isEmpty(); |
|
94 |
|
95 if( isWholePixmap || isEmptyArea ) |
|
96 { |
|
97 // Assign to our copy using implicit sharing |
|
98 mPixmap = *src; |
|
99 } |
|
100 else |
|
101 { |
|
102 // Convert to QImage, copy the pixel data area, convert back to QPixmap |
|
103 mPixmap = src->copy(aX, aY, aWidth, aHeight); |
|
104 } |
|
105 |
|
106 if(mPixmap.isNull()) |
|
107 { |
|
108 throw GfxException(EGfxErrorNoMemory, "Image (pixmap) creation failed"); |
|
109 } |
|
110 } |
|
111 |
113 |
112 void Pixmap::createFromImageData(ImageDataWrapper* aData) |
114 void Pixmap::createFromImageData(ImageDataWrapper* aData) |
113 { |
115 { |
114 GFX_LOG_FUNC_CALL(); |
116 GFX_LOG_FUNC_CALL(); |
115 Q_ASSERT(mPixmap.isNull()); |
117 Q_ASSERT(mPixmap.isNull()); |
116 |
118 |
117 if(aData->getDepth() != 32) |
119 mPixmap = QPixmap::fromImage(imageDataToQImage(aData)); |
118 { |
120 |
119 // Java side always converts the ImageData to 32 bit before passing it |
121 if(mPixmap.isNull()) |
120 // to native side, bail out if we get something else |
122 { |
121 throw GfxException(EGfxErrorNoMemory, "Only 32 bit ImageData is supported in Image creation"); |
123 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
122 } |
124 } |
123 |
125 } |
124 int bpp = 4; // bit depth = 32, 4 bytes per pixel |
|
125 int size = aData->getWidth()*aData->getHeight()*bpp; |
|
126 char* pixelData = aData->getData(ImageDataWrapper::EPixelData); |
|
127 |
|
128 for(int index = 0; index < size; index += bpp) |
|
129 { |
|
130 int pixel = *(reinterpret_cast<int*>(pixelData+index)); |
|
131 |
|
132 pixelData[index] = (uchar)(pixel >> 24) & 0xFF; |
|
133 pixelData[index+1] = (uchar)(pixel >> 16) & 0xFF; |
|
134 pixelData[index+2] = (uchar)(pixel >> 8) & 0xFF; |
|
135 pixelData[index+3] = 0xFF; // Set alpha to opaque here, alpha channel data will be handled later |
|
136 } |
|
137 |
|
138 QImage image(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EPixelData)), |
|
139 aData->getWidth(), |
|
140 aData->getHeight(), |
|
141 aData->getBytesPerLine(), |
|
142 QImage::Format_ARGB32); |
|
143 if(image.isNull()) |
|
144 { |
|
145 throw GfxException(EGfxErrorNoMemory, "QImage (Pixmap) creation failed"); |
|
146 } |
|
147 |
|
148 // Set indexed palette (if one is set) |
|
149 if(!aData->isDirect()) |
|
150 { |
|
151 image.setColorTable(*aData->getPaletteData()->getIndexedPalette()); |
|
152 } |
|
153 |
|
154 mHasMask = false; |
|
155 mAlpha = aData->getAlpha(); |
|
156 |
|
157 if(aData->getData(ImageDataWrapper::EMaskData)) |
|
158 { |
|
159 QImage mask(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EMaskData)), |
|
160 aData->getWidth(), |
|
161 aData->getHeight(), |
|
162 QImage::Format_Mono); |
|
163 if(mask.isNull()) |
|
164 { |
|
165 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed"); |
|
166 } |
|
167 image.setAlphaChannel(mask); |
|
168 mHasMask = true; |
|
169 } |
|
170 else if(mAlpha != -1) |
|
171 { |
|
172 // Global alpha is set, overrides alpha channel data |
|
173 QImage alpha(aData->getWidth(), aData->getHeight(), QImage::Format_Indexed8); |
|
174 if(alpha.isNull()) |
|
175 { |
|
176 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed"); |
|
177 } |
|
178 |
|
179 alpha.fill(aData->getAlpha()); |
|
180 image.setAlphaChannel(alpha); |
|
181 } |
|
182 else if(aData->getData(ImageDataWrapper::EAlphaData)) |
|
183 { |
|
184 // Alpha channel data is set |
|
185 const int w = aData->getWidth(); |
|
186 QImage alpha(reinterpret_cast<uchar*>(aData->getData(ImageDataWrapper::EAlphaData)), |
|
187 w, |
|
188 aData->getHeight(), |
|
189 w, |
|
190 QImage::Format_Indexed8); |
|
191 QVector<QRgb> colors(255); |
|
192 for(int i=0; i<255; i++) |
|
193 { |
|
194 colors[i] = qRgb(i, i, i); |
|
195 } |
|
196 alpha.setColorTable(colors); |
|
197 colors.clear(); |
|
198 |
|
199 if(alpha.isNull()) |
|
200 { |
|
201 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) alpha channel creation failed"); |
|
202 } |
|
203 image.setAlphaChannel(alpha); |
|
204 } |
|
205 |
|
206 mPixmap = QPixmap::fromImage(image); |
|
207 |
|
208 if(mPixmap.isNull()) |
|
209 { |
|
210 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
|
211 } |
|
212 } |
|
213 |
126 |
214 void Pixmap::createFromRGB(int* aRgbdata, int aWidth, int aHeight, bool aHasAlpha) |
127 void Pixmap::createFromRGB(int* aRgbdata, int aWidth, int aHeight, bool aHasAlpha) |
215 { |
128 { |
216 GFX_LOG_FUNC_CALL(); |
129 GFX_LOG_FUNC_CALL(); |
217 Q_ASSERT(mPixmap.isNull()); |
130 Q_ASSERT(mPixmap.isNull()); |
218 |
131 |
219 // Create QImage from rgbdata as QPixmap does not directly support that |
132 // Create QImage from rgbdata as QPixmap does not directly support that |
220 QImage tmpImage(reinterpret_cast<unsigned char*>(aRgbdata), aWidth, aHeight, |
133 QImage tmpImage(reinterpret_cast<unsigned char*>(aRgbdata), aWidth, aHeight, |
221 (aHasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32)); |
134 (aHasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32)); |
222 |
135 |
223 // Validate creation |
136 // Validate creation |
224 if(tmpImage.isNull()) |
137 if(tmpImage.isNull()) |
225 { |
138 { |
226 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
139 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
227 } |
140 } |
228 |
141 |
229 // Store as QPixmap |
142 // Store as QPixmap |
230 mPixmap = QPixmap::fromImage(tmpImage); |
143 mPixmap = QPixmap::fromImage(tmpImage); |
231 |
144 |
232 // Validate conversion |
145 // Validate conversion |
233 if(mPixmap.isNull()) |
146 if(mPixmap.isNull()) |
234 { |
147 { |
235 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
148 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
236 } |
149 } |
237 } |
150 } |
238 |
151 |
239 void Pixmap::dispose() |
152 void Pixmap::dispose() |
240 { |
153 { |
241 GFX_LOG_FUNC_CALL(); |
154 GFX_LOG_FUNC_CALL(); |
242 delete this; |
155 delete this; |
243 } |
156 } |
244 |
157 |
245 QPaintDevice* Pixmap::getBindable() |
158 QPaintDevice* Pixmap::getBindable() |
246 { |
159 { |
247 GFX_LOG_FUNC_CALL(); |
160 GFX_LOG_FUNC_CALL(); |
248 return static_cast<QPaintDevice*>(&mPixmap); |
161 return static_cast<QPaintDevice*>(&mPixmap); |
249 } |
162 } |
250 |
163 |
251 int Pixmap::getFormat() |
164 TImageFormat Pixmap::getFormat() |
252 { |
165 { |
253 GFX_LOG_FUNC_CALL(); |
166 GFX_LOG_FUNC_CALL(); |
254 QImage img = mPixmap.toImage(); |
167 QImage img = mPixmap.toImage(); |
255 // Validate conversion |
168 // Validate conversion |
256 if(img.isNull()) { |
169 if(img.isNull()) |
|
170 { |
257 throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed"); |
171 throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed"); |
258 } |
172 } |
259 int imgFormat = img.format(); |
173 return mapQtFormatToInternal(img.format()); |
260 |
174 } |
261 switch (imgFormat) { |
|
262 case QImage::Format_ARGB32: |
|
263 return EFormatARGB32; |
|
264 case QImage::Format_RGB32: |
|
265 return EFormatRGB32; |
|
266 case QImage::Format_ARGB32_Premultiplied: |
|
267 return EFormatARGB32Premultiplied; |
|
268 case QImage::Format_RGB16: |
|
269 return EFormatRGB16; |
|
270 case QImage::Format_RGB555: |
|
271 return EFormatRGB555; |
|
272 case QImage::Format_RGB444: |
|
273 return EFormatRGB444; |
|
274 case QImage::Format_ARGB4444_Premultiplied: |
|
275 return EFormatARGB4444Premultiplied; |
|
276 case QImage::Format_Mono: |
|
277 return EFormatMONO; |
|
278 default: |
|
279 return EFormatNone; |
|
280 } |
|
281 } |
|
282 |
175 |
283 int Pixmap::getHeight() |
176 int Pixmap::getHeight() |
284 { |
177 { |
285 GFX_LOG_FUNC_CALL(); |
178 GFX_LOG_FUNC_CALL(); |
286 return mPixmap.height(); |
179 return mPixmap.height(); |
287 } |
180 } |
|
181 |
|
182 const QImage* Pixmap::getConstImage() |
|
183 { |
|
184 GFX_LOG_FUNC_CALL(); |
|
185 return NULL; |
|
186 } |
|
187 |
|
188 QImage* Pixmap::getImage() |
|
189 { |
|
190 GFX_LOG_FUNC_CALL(); |
|
191 return NULL; |
|
192 } |
|
193 |
|
194 const QPixmap* Pixmap::getConstPixmap() |
|
195 { |
|
196 GFX_LOG_FUNC_CALL(); |
|
197 return &mPixmap; |
|
198 } |
288 |
199 |
289 QPixmap* Pixmap::getPixmap() |
200 QPixmap* Pixmap::getPixmap() |
290 { |
201 { |
291 GFX_LOG_FUNC_CALL(); |
202 GFX_LOG_FUNC_CALL(); |
292 return &mPixmap; |
203 return &mPixmap; |
293 } |
204 } |
294 |
205 |
295 int Pixmap::getWidth() |
206 int Pixmap::getWidth() |
296 { |
207 { |
297 GFX_LOG_FUNC_CALL(); |
208 GFX_LOG_FUNC_CALL(); |
298 return mPixmap.width(); |
209 return mPixmap.width(); |
299 } |
210 } |
300 |
|
301 int Pixmap::getAlpha() |
|
302 { |
|
303 GFX_LOG_FUNC_CALL(); |
|
304 return mAlpha; |
|
305 } |
|
306 |
|
307 bool Pixmap::hasMask() |
|
308 { |
|
309 GFX_LOG_FUNC_CALL(); |
|
310 return mHasMask; |
|
311 } |
|
312 |
211 |
313 void Pixmap::getRgb(int* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight) |
212 void Pixmap::getRgb(int* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight) |
314 { |
213 { |
315 GFX_LOG_FUNC_CALL(); |
214 GFX_LOG_FUNC_CALL(); |
316 |
215 |
317 // Convert to QImage in order to access pixels |
216 // Convert to QImage in order to access pixels |
318 QImage image = mPixmap.toImage(); |
217 QImage image = mPixmap.toImage(); |
319 |
218 |
320 // Validate conversion |
219 // Validate conversion |
321 if(image.isNull()) |
220 if(image.isNull()) |
322 { |
221 { |
323 throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed"); |
222 throw GfxException(EGfxErrorNoMemory, "Convertion from QPixmap to QImage failed"); |
324 } |
223 } |
325 |
224 doGetRgb(image, aRgbdata, aOffset, aScanlength, aX, aY, aWidth, aHeight); |
326 if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height()) |
225 } |
327 { |
226 |
328 image = image.copy(aX, aY, aWidth, aHeight); |
227 |
329 if(image.isNull()) |
228 void Pixmap::getRgb(char* aRgbdata, char* aTransparencyMask,int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) { |
330 { |
|
331 throw GfxException(EGfxErrorNoMemory, "copying from original image failed"); |
|
332 } |
|
333 } |
|
334 |
|
335 |
|
336 // If image is not 32bpp we need to convert it |
|
337 if(image.format() != QImage::Format_RGB32 && |
|
338 image.format() != QImage::Format_ARGB32) |
|
339 { |
|
340 image = image.convertToFormat(QImage::Format_ARGB32); |
|
341 if(image.isNull()) |
|
342 { |
|
343 throw GfxException(EGfxErrorNoMemory, "format convertion to 32bpp failed"); |
|
344 } |
|
345 } |
|
346 |
|
347 // Temporary storage for pixels |
|
348 QRgb* pixel = NULL; |
|
349 |
|
350 // dataArray index, start from offset |
|
351 int targetIndex = aOffset; |
|
352 |
|
353 // Iterate through lines |
|
354 for(int b = 0; b < aHeight; ++b) |
|
355 { |
|
356 // Obtain pointer to start of current line (y) |
|
357 const unsigned char* lineStart = image.scanLine(b); |
|
358 |
|
359 // Iterate through pixels on each line |
|
360 for (int a = 0; a < aWidth; ++a) |
|
361 { |
|
362 // Set the current pixel, relative to line start |
|
363 pixel = ((QRgb*)lineStart) + a; |
|
364 |
|
365 // Move target pointer to the next slot |
|
366 targetIndex = aOffset + a + (b * aScanlength); |
|
367 // Shift pixels to correct places, needed for 32-bit format |
|
368 // as the bits order in memory may vary between systems |
|
369 aRgbdata[targetIndex] = ((qAlpha(*pixel) & 0xff) << 24) | |
|
370 ((qRed(*pixel) & 0xff) << 16) | |
|
371 ((qGreen(*pixel) & 0xff) << 8 ) | |
|
372 ((qBlue(*pixel) & 0xff)); |
|
373 } |
|
374 } |
|
375 |
|
376 } |
|
377 |
|
378 |
|
379 void Pixmap::getRgb(char* aRgbdata, char* aTransparencyMask,int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int /*aFormat*/) { |
|
380 |
229 |
381 GFX_LOG_FUNC_CALL(); |
230 GFX_LOG_FUNC_CALL(); |
382 |
231 |
383 // Convert to QImage in order to access pixels |
232 // Convert to QImage in order to access pixels |
384 QImage image = mPixmap.toImage(); |
233 QImage image = mPixmap.toImage(); |
385 |
234 |
386 // Validate conversion |
235 // Validate conversion |
387 if(image.isNull()) { |
236 if(image.isNull()) |
|
237 { |
388 throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed"); |
238 throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed"); |
389 } |
239 } |
390 |
240 doGetRgb(image, aRgbdata, aTransparencyMask, aOffset, aScanlength, aX, aY, aWidth, aHeight, aFormat); |
391 if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height()) |
241 } |
392 { |
242 |
393 image = image.copy(aX, aY, aWidth, aHeight); |
243 void Pixmap::getRgb(short* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) |
394 if(image.isNull()) |
244 { |
395 { |
245 GFX_LOG_FUNC_CALL(); |
396 throw GfxException(EGfxErrorNoMemory, "copying from original image failed"); |
246 |
397 } |
|
398 } |
|
399 |
|
400 if(aScanlength < 0) |
|
401 { |
|
402 image = image.mirrored(false, true); |
|
403 if(image.isNull()) |
|
404 { |
|
405 throw GfxException(EGfxErrorNoMemory, "Mirroring failed"); |
|
406 } |
|
407 } |
|
408 |
|
409 // If image is not monochrome we need to convert it |
|
410 if(image.format() != QImage::Format_Mono) |
|
411 { |
|
412 image = image.convertToFormat(QImage::Format_Mono); |
|
413 if(image.isNull()) |
|
414 { |
|
415 throw GfxException(EGfxErrorNoMemory, "Format conversion to 8bpp failed"); |
|
416 } |
|
417 } |
|
418 |
|
419 // dataArray index, start from offset |
|
420 int targetIndex = aOffset; |
|
421 |
|
422 const unsigned char* imageStart = image.bits(); |
|
423 QImage mask = image.alphaChannel(); |
|
424 const unsigned char* maskStart = mask.bits(); |
|
425 |
|
426 // Find the number of full bytes |
|
427 int fullBytes = aWidth/8; |
|
428 int bpl = image.bytesPerLine(); |
|
429 |
|
430 if(bpl == fullBytes) |
|
431 { |
|
432 memcpy(aRgbdata+targetIndex, imageStart, bpl*aHeight); |
|
433 memcpy(aTransparencyMask+targetIndex, maskStart, bpl*aHeight); |
|
434 } |
|
435 else |
|
436 { |
|
437 memcpy(aRgbdata+targetIndex, imageStart, fullBytes*aHeight + aHeight); |
|
438 memcpy(aTransparencyMask+targetIndex, maskStart, fullBytes*aHeight + aHeight); |
|
439 } |
|
440 |
|
441 } |
|
442 |
|
443 void Pixmap::getRgb(short* aRgbdata, int aOffset, int aScanlength, int aX, int aY, int aWidth, int aHeight, int aFormat) { |
|
444 GFX_LOG_FUNC_CALL(); |
|
445 |
|
446 // Match format to QT |
|
447 int format; |
|
448 switch (aFormat) { |
|
449 case EFormatRGB555: |
|
450 format = QImage::Format_RGB555; |
|
451 break; |
|
452 case EFormatRGB16: |
|
453 format = QImage::Format_RGB16; |
|
454 break; |
|
455 case EFormatRGB444: |
|
456 format = QImage::Format_RGB444; |
|
457 break; |
|
458 case EFormatARGB4444Premultiplied: |
|
459 format = QImage::Format_ARGB4444_Premultiplied; |
|
460 break; |
|
461 default: |
|
462 format = QImage::Format_RGB16; |
|
463 } |
|
464 // Convert to QImage in order to access pixels |
247 // Convert to QImage in order to access pixels |
465 QImage image = mPixmap.toImage(); |
248 QImage image = mPixmap.toImage(); |
466 |
249 |
467 // Validate conversion |
250 // Validate conversion |
468 if(image.isNull()) |
251 if(image.isNull()) |
469 { |
252 { |
470 throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed"); |
253 throw GfxException(EGfxErrorNoMemory, "Conversion from QPixmap to QImage failed"); |
471 } |
254 } |
472 |
255 doGetRgb(image, aRgbdata, aOffset, aScanlength, aX, aY, aWidth, aHeight, aFormat); |
473 if(aX != 0 || aY != 0 || aWidth < image.width() || aHeight < image.height()) |
256 } |
474 { |
257 |
475 image = image.copy(aX, aY, aWidth, aHeight); |
258 const QImage Pixmap::toConstImage() |
476 if(image.isNull()) |
259 { |
477 { |
260 GFX_LOG_FUNC_CALL(); |
478 throw GfxException(EGfxErrorNoMemory, "copying from original image failed"); |
261 return mPixmap.toImage(); |
479 } |
262 } |
480 } |
|
481 |
|
482 |
|
483 // If image is not format we need, convert it |
|
484 if(image.format() != format) |
|
485 { |
|
486 image = image.convertToFormat((QImage::Format)format); |
|
487 if(image.isNull()) |
|
488 { |
|
489 throw GfxException(EGfxErrorNoMemory, "format convertion to 16bpp failed"); |
|
490 } |
|
491 } |
|
492 |
|
493 // Temporary storage for pixels |
|
494 short* pixel = NULL; |
|
495 // dataArray index, start from offset |
|
496 int targetIndex = aOffset; |
|
497 |
|
498 // Iterate through lines |
|
499 for(int b=0; b < aHeight; b++) |
|
500 { |
|
501 // Obtain pointer to start of current line (y) |
|
502 const unsigned char* lineStart = image.scanLine(b); |
|
503 // Iterate through pixels on each line |
|
504 for(int a=0; a < aWidth; a++) |
|
505 { |
|
506 // Set the current pixel, relative to line start |
|
507 pixel = ((short*)lineStart) + a; |
|
508 // Move target pointer to the next slot |
|
509 targetIndex = aOffset + a + (b * aScanlength); |
|
510 aRgbdata[targetIndex] = *pixel; |
|
511 } |
|
512 } |
|
513 } |
|
514 |
263 |
515 QImage Pixmap::toImage() |
264 QImage Pixmap::toImage() |
516 { |
265 { |
|
266 GFX_LOG_FUNC_CALL(); |
517 return mPixmap.toImage(); |
267 return mPixmap.toImage(); |
518 } |
268 } |
|
269 |
|
270 QPixmap Pixmap::toPixmap() |
|
271 { |
|
272 GFX_LOG_FUNC_CALL(); |
|
273 return QPixmap(mPixmap); |
|
274 } |
519 |
275 |
520 void Pixmap::transform(TTransform aTransform) |
276 void Pixmap::transform(TTransform aTransform) |
521 { |
277 { |
522 GFX_LOG_FUNC_CALL(); |
278 GFX_LOG_FUNC_CALL(); |
523 |
279 mPixmap = mPixmap.transformed(generateTransformMatrix(aTransform), Qt::FastTransformation); |
524 // For rotation along z-axis |
280 if(mPixmap.isNull()) |
525 QTransform imageTransform; |
281 { |
526 bool flip = false; |
282 throw GfxException(EGfxErrorNoMemory, "Image (Pixmap) creation failed"); |
527 bool rotate = true; |
283 } |
528 |
284 } |
529 switch(aTransform) { |
|
530 case ETransNone: |
|
531 // No transform or mirror |
|
532 return; |
|
533 case ETransRot90: |
|
534 imageTransform.rotate(90, Qt::ZAxis); |
|
535 break; |
|
536 case ETransRot180: |
|
537 imageTransform.rotate(180, Qt::ZAxis); |
|
538 break; |
|
539 case ETransRot270: |
|
540 imageTransform.rotate(270, Qt::ZAxis); |
|
541 break; |
|
542 case ETransMirror: |
|
543 flip = true; |
|
544 rotate = false; |
|
545 break; |
|
546 case ETransMirrorRot90: |
|
547 imageTransform.rotate(90, Qt::ZAxis); |
|
548 flip = true; |
|
549 break; |
|
550 case ETransMirrorRot180: |
|
551 imageTransform.rotate(180, Qt::ZAxis); |
|
552 flip = true; |
|
553 break; |
|
554 case ETransMirrorRot270: |
|
555 imageTransform.rotate(270, Qt::ZAxis); |
|
556 flip = true; |
|
557 break; |
|
558 default: |
|
559 Q_ASSERT_X(false, "Graphics", "Transform type not recognized"); |
|
560 return; |
|
561 } |
|
562 |
|
563 // Mirror image first if requested |
|
564 if(flip) |
|
565 { |
|
566 QTransform flipTransform; |
|
567 flipTransform.rotate(180,Qt::YAxis); |
|
568 |
|
569 // Create temp pixmap for flipped |
|
570 QPixmap temp = mPixmap.transformed(flipTransform, Qt::FastTransformation); |
|
571 |
|
572 // Validate transformation |
|
573 if(temp.isNull()) |
|
574 { |
|
575 throw GfxException(EGfxErrorNoMemory, "temp buffer alloc failed"); |
|
576 } |
|
577 |
|
578 // Free original pixmap and store new |
|
579 mPixmap = temp; |
|
580 } |
|
581 |
|
582 // Then rotate |
|
583 if(rotate) |
|
584 { |
|
585 // Create temp pixmap for rotate |
|
586 QPixmap temp = mPixmap.transformed(imageTransform, Qt::FastTransformation); |
|
587 |
|
588 // Validate alloc |
|
589 if(temp.isNull()) |
|
590 { |
|
591 throw GfxException(EGfxErrorNoMemory, "temp buffer alloc failed"); |
|
592 } |
|
593 |
|
594 // Free original image and store new |
|
595 mPixmap = temp; |
|
596 } |
|
597 } |
|
598 |
285 |
599 TImageType Pixmap::type() |
286 TImageType Pixmap::type() |
600 { |
287 { |
601 GFX_LOG_FUNC_CALL(); |
288 GFX_LOG_FUNC_CALL(); |
602 return EPixmap; |
289 return EPixmap; |
603 } |
290 } |
604 |
291 |
605 bool Pixmap::hasAlphaChannel() |
292 bool Pixmap::hasAlphaChannel() |
606 { |
293 { |
607 GFX_LOG_FUNC_CALL(); |
294 GFX_LOG_FUNC_CALL(); |
608 return mPixmap.hasAlphaChannel(); |
295 return mPixmap.hasAlphaChannel(); |
609 } |
296 } |
610 |
297 |
611 } // namespace GFX |
298 } // namespace GFX |
612 } // namespace Java |
299 } // namespace Java |