Source Code Cross Referenced for ImageDataFactory.java in  » 6.0-JDK-Modules » j2me » javax » microedition » lcdui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » javax.microedition.lcdui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *
003:         *
004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation.
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt).
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions.
025:         */
026:
027:        package javax.microedition.lcdui;
028:
029:        import java.io.InputStream;
030:        import java.io.IOException;
031:
032:        import com.sun.midp.midlet.MIDletSuite;
033:        import com.sun.midp.midlet.MIDletStateHandler;
034:
035:        /**
036:         * ImageFactory implementation based on putpixel graphics library and stores
037:         * data on Java heap.
038:         */
039:        class ImageDataFactory implements  AbstractImageDataFactory {
040:
041:            /**
042:             * PNG Header Data
043:             */
044:            private static final byte[] pngHeader = new byte[] { (byte) 0x89,
045:                    (byte) 0x50, (byte) 0x4e, (byte) 0x47, (byte) 0x0d,
046:                    (byte) 0x0a, (byte) 0x1a, (byte) 0x0a, (byte) 0x00,
047:                    (byte) 0x00, (byte) 0x00, (byte) 0x0d, (byte) 0x49,
048:                    (byte) 0x48, (byte) 0x44, (byte) 0x52 };
049:
050:            /**
051:             * JPEG Header Data
052:             */
053:            private static final byte[] jpegHeader = new byte[] { (byte) 0xff,
054:                    (byte) 0xd8, (byte) 0xff, (byte) 0xe0 };
055:
056:            /**
057:             * RAW Header Data
058:             */
059:            private static final byte[] rawHeader = new byte[] { (byte) 0x89,
060:                    (byte) 0x53, (byte) 0x55, (byte) 0x4E };
061:
062:            /**
063:             * ImageDataFactory singleton used for <code>ImageData</code>
064:             * creation.
065:             */
066:            private static ImageDataFactory imageDataFactory = new ImageDataFactory();
067:
068:            /**
069:             * Returns the singleton <code>ImageDataFactory</code> instance.
070:             *
071:             * @return the singleton <code>ImageDataFactory</code> instance.
072:             */
073:            public static AbstractImageDataFactory getImageDataFactory() {
074:                return imageDataFactory;
075:            }
076:
077:            /**
078:             * Creates a new, mutable image for off-screen drawing. Every pixel
079:             * within the newly created image is white.  The width and height of the
080:             * image must both be greater than zero.
081:             *
082:             * @param width the width of the new image, in pixels
083:             * @param height the height of the new image, in pixels
084:             * @return the created image
085:             */
086:            public ImageData createOffScreenImageData(int width, int height) {
087:                return new ImageData(width, height, true, true, false);
088:            }
089:
090:            /**
091:             * Creates an immutable <code>ImageData</code> from
092:             * a <code>mutableSource ImageData</code>.
093:             * If the source image data is mutable, an immutable copy is created and
094:             * returned.  If the source image data is immutable, the implementation may
095:             * simply return it without creating a new image.  If an immutable source
096:             * image data contains transparency information,
097:             * this information is copied to the new image data unchanged.
098:             *
099:             * <p> This method is useful for placing the contents of mutable images
100:             * into <code>Choice</code> objects.  The application can create
101:             * an off-screen image
102:             * using the
103:             * {@link #createImage(int, int) createImage(w, h)}
104:             * method, draw into it using a <code>Graphics</code> object
105:             * obtained with the
106:             * {@link #getGraphics() getGraphics()}
107:             * method, and then create an immutable copy of it with this method.
108:             * The immutable copy may then be placed into <code>Choice</code>
109:             * objects. </p>
110:             *
111:             * @param mutableSource the source mutable image to be copied
112:             * @return the new immutable image data
113:             *
114:             * @throws NullPointerException if <code>source</code> is <code>null</code>
115:             */
116:            public ImageData createImmutableCopy(ImageData mutableSource) {
117:                int width = mutableSource.getWidth();
118:                int height = mutableSource.getHeight();
119:                int length = width * height * 2;
120:
121:                return new ImageData(width, height, false, mutableSource
122:                        .getPixelData());
123:            }
124:
125:            /**
126:             * Creates an immutable <code>ImageData</code>
127:             * from decoded image data obtained from the
128:             * named resource.  The name parameter is a resource name as defined by
129:             * {@link Class#getResourceAsStream(String)
130:             * Class.getResourceAsStream(name)}.  The rules for resolving resource
131:             * names are defined in the
132:             * <a href="../../../java/lang/package-summary.html">
133:             * Application Resource Files</a> section of the
134:             * <code>java.lang</code> package documentation.
135:             *
136:             * @param name the name of the resource containing the image data in one of
137:             * the supported image formats
138:             * @return the created image data
139:             * @throws NullPointerException if <code>name</code> is <code>null</code>
140:             * @throws java.io.IOException if the resource does not exist,
141:             * the data cannot
142:             * be loaded, or the image data cannot be decoded
143:             */
144:            public ImageData createResourceImageData(String name)
145:                    throws IOException {
146:                ImageData data = new ImageData();
147:
148:                /*
149:                 * Load native image data from cache and create
150:                 * image, if available. If image is not cached,
151:                 * proceed to load and create image normally.
152:                 */
153:                if (!loadCachedImage(data, name)) {
154:                    createImageFromStream(data, ImageData.class
155:                            .getResourceAsStream(name));
156:                }
157:
158:                return data;
159:            }
160:
161:            /**
162:             * Creates an immutable <code>ImageData</code>
163:             * which is decoded from the data stored in
164:             * the specified byte array at the specified offset and length. The data
165:             * must be in a self-identifying image file format supported by the
166:             * implementation, such as <a href="#PNG">PNG</A>.
167:             *
168:             * <p>The <code>imageoffset</code> and <code>imagelength</code>
169:             * parameters specify a range of
170:             * data within the <code>imageData</code> byte array. The
171:             * <code>imageOffset</code> parameter
172:             * specifies the
173:             * offset into the array of the first data byte to be used. It must
174:             * therefore lie within the range
175:             * <code>[0..(imageData.length-1)]</code>. The
176:             * <code>imageLength</code>
177:             * parameter specifies the number of data bytes to be used. It must be a
178:             * positive integer and it must not cause the range to extend beyond
179:             * the end
180:             * of the array. That is, it must be true that
181:             * <code>imageOffset + imageLength &lt; imageData.length</code>. </p>
182:             *
183:             * <p> This method is intended for use when loading an
184:             * image from a variety of sources, such as from
185:             * persistent storage or from the network.</p>
186:             *
187:             * @param imageBytes the array of image data in a supported image format
188:             * @param imageOffset the offset of the start of the data in the array
189:             * @param imageLength the length of the data in the array
190:             *
191:             * @return the created image
192:             * @throws ArrayIndexOutOfBoundsException if <code>imageOffset</code>
193:             * and <code>imageLength</code>
194:             * specify an invalid range
195:             * @throws NullPointerException if <code>imageData</code> is
196:             * <code>null</code>
197:             * @throws IllegalArgumentException if <code>imageData</code> is incorrectly
198:             * formatted or otherwise cannot be decoded
199:             */
200:            public ImageData createImmutableImageData(byte[] imageBytes,
201:                    int imageOffset, int imageLength) {
202:                ImageData data = new ImageData();
203:                // parse the pixel data
204:                decode(data, imageBytes, imageOffset, imageLength);
205:                return data;
206:            }
207:
208:            /**
209:             * Creates an immutable <code>ImageData</code>
210:             * using pixel data from the specified
211:             * region of a source <code>ImageData</code>, transformed as specified.
212:             *
213:             * <p>The source image dara may be mutable or immutable.
214:             * For immutable source image data,
215:             * transparency information, if any, is copied to the new
216:             * image data unchanged.</p>
217:             *
218:             * <p>On some devices, pre-transformed images may render more quickly
219:             * than images that are transformed on the fly using
220:             * <code>drawRegion</code>.
221:             * However, creating such images does consume additional heap space,
222:             * so this technique should be applied only to images whose rendering
223:             * speed is critical.</p>
224:             *
225:             * <p>The transform function used must be one of the following, as defined
226:             * in the {@link javax.microedition.lcdui.game.Sprite Sprite} class:<br>
227:             *
228:             * <code>Sprite.TRANS_NONE</code> - causes the specified image
229:             * region to be copied unchanged<br>
230:             * <code>Sprite.TRANS_ROT90</code> - causes the specified image
231:             * region to be rotated clockwise by 90 degrees.<br>
232:             * <code>Sprite.TRANS_ROT180</code> - causes the specified image
233:             * region to be rotated clockwise by 180 degrees.<br>
234:             * <code>Sprite.TRANS_ROT270</code> - causes the specified image
235:             * region to be rotated clockwise by 270 degrees.<br>
236:             * <code>Sprite.TRANS_MIRROR</code> - causes the specified image
237:             * region to be reflected about its vertical center.<br>
238:             * <code>Sprite.TRANS_MIRROR_ROT90</code> - causes the specified image
239:             * region to be reflected about its vertical center and then rotated
240:             * clockwise by 90 degrees.<br>
241:             * <code>Sprite.TRANS_MIRROR_ROT180</code> - causes the specified image
242:             * region to be reflected about its vertical center and then rotated
243:             * clockwise by 180 degrees.<br>
244:             * <code>Sprite.TRANS_MIRROR_ROT270</code> - causes the specified image
245:             * region to be reflected about its vertical center and then rotated
246:             * clockwise by 270 degrees.<br></p>
247:             *
248:             * <p>
249:             * The size of the returned image will be the size of the specified region
250:             * with the transform applied.  For example, if the region is
251:             * <code>100&nbsp;x&nbsp;50</code> pixels and the transform is
252:             * <code>TRANS_ROT90</code>, the
253:             * returned image will be <code>50&nbsp;x&nbsp;100</code> pixels.</p>
254:             *
255:             * <p><strong>Note:</strong> If all of the following conditions
256:             * are met, this method may
257:             * simply return the source <code>Image</code> without creating a
258:             * new one:</p>
259:             * <ul>
260:             * <li>the source image is immutable;</li>
261:             * <li>the region represents the entire source image; and</li>
262:             * <li>the transform is <code>TRANS_NONE</code>.</li>
263:             * </ul>
264:             *
265:             * @param dataSource the source image data to be copied from
266:             * @param x the horizontal location of the region to be copied
267:             * @param y the vertical location of the region to be copied
268:             * @param w the width of the region to be copied
269:             * @param h the height of the region to be copied
270:             * @param transform the transform to be applied to the region
271:             * @return the new, immutable image
272:             *
273:             * @throws NullPointerException if <code>image</code> is <code>null</code>
274:             * @throws IllegalArgumentException if the region to be copied exceeds
275:             * the bounds of the source image
276:             * @throws IllegalArgumentException if either <code>width</code> or
277:             * <code>height</code> is zero or less
278:             * @throws IllegalArgumentException if the <code>transform</code>
279:             * is not valid
280:             *
281:             */
282:            public ImageData createImmutableImageData(ImageData dataSource,
283:                    int x, int y, int w, int h, int transform) {
284:
285:                ImageData dataDest = null;
286:
287:                if ((transform & Image.TRANSFORM_SWAP_AXIS) == Image.TRANSFORM_SWAP_AXIS) {
288:                    dataDest = new ImageData(h, w, false, false, dataSource
289:                            .hasAlpha());
290:                } else {
291:                    dataDest = new ImageData(w, h, false, false, dataSource
292:                            .hasAlpha());
293:                }
294:
295:                // Copy either the Java or romized data to its own array
296:                loadRegion(dataDest, dataSource, x, y, w, h, transform);
297:
298:                return dataDest;
299:            }
300:
301:            /**
302:             * Creates an immutable <code>ImageData</code>
303:             * from a sequence of ARGB values, specified
304:             * as <code>0xAARRGGBB</code>.
305:             * The ARGB data within the <code>rgb</code> array is arranged
306:             * horizontally from left to right within each row,
307:             * row by row from top to bottom.
308:             * If <code>processAlpha</code> is <code>true</code>,
309:             * the high-order byte specifies opacity; that is,
310:             * <code>0x00RRGGBB</code> specifies
311:             * a fully transparent pixel and <code>0xFFRRGGBB</code> specifies
312:             * a fully opaque
313:             * pixel.  Intermediate alpha values specify semitransparency.  If the
314:             * implementation does not support alpha blending for image rendering
315:             * operations, it must replace any semitransparent pixels with fully
316:             * transparent pixels.  (See <a href="#alpha">Alpha Processing</a>
317:             * for further discussion.)  If <code>processAlpha</code> is
318:             * <code>false</code>, the alpha values
319:             * are ignored and all pixels must be treated as fully opaque.
320:             *
321:             * <p>Consider <code>P(a,b)</code> to be the value of the pixel
322:             * located at column <code>a</code> and row <code>b</code> of the
323:             * Image, where rows and columns are numbered downward from the
324:             * top starting at zero, and columns are numbered rightward from
325:             * the left starting at zero. This operation can then be defined
326:             * as:</p>
327:             *
328:             * <TABLE BORDER="2">
329:             * <TR>
330:             * <TD ROWSPAN="1" COLSPAN="1">
331:             *    <pre><code>
332:             *    P(a, b) = rgb[a + b * width];    </code></pre>
333:             * </TD>
334:             * </TR>
335:             * </TABLE>
336:             * <p>for</p>
337:             *
338:             * <TABLE BORDER="2">
339:             * <TR>
340:             * <TD ROWSPAN="1" COLSPAN="1">
341:             *    <pre><code>
342:             *     0 &lt;= a &lt; width
343:             *     0 &lt;= b &lt; height    </code></pre>
344:             * </TD>
345:             * </TR>
346:             * </TABLE>
347:             * <p> </p>
348:             *
349:             * @param rgb an array of ARGB values that composes the image
350:             * @param width the width of the image
351:             * @param height the height of the image
352:             * @param processAlpha <code>true</code> if <code>rgb</code>
353:             * has an alpha channel,
354:             * <code>false</code> if all pixels are fully opaque
355:             * @return the created <code>ImageData</code>
356:             * @throws NullPointerException if <code>rgb</code> is <code>null</code>.
357:             * @throws IllegalArgumentException if either <code>width</code> or
358:             * <code>height</code> is zero or less
359:             * @throws ArrayIndexOutOfBoundsException if the length of
360:             * <code>rgb</code> is
361:             * less than<code> width&nbsp;*&nbsp;height</code>.
362:             *
363:             */
364:            public ImageData createImmutableImageData(int rgb[], int width,
365:                    int height, boolean processAlpha) {
366:                ImageData data = new ImageData(width, height, false, false,
367:                        processAlpha);
368:                loadRGB(data, rgb);
369:
370:                return data;
371:            }
372:
373:            /**
374:             * Function to decode an <code>ImageData</code> from romized data.
375:             *
376:             * @param imageDataArrayPtr native pointer to image data as Java int
377:             * @param imageDataArrayLength length of image data array
378:             * @return <code>ImageData</code> created from romized data.
379:             * @throws IllegalArgumentException if the id is invalid
380:             */
381:            public ImageData createImmutableImageData(int imageDataArrayPtr,
382:                    int imageDataArrayLength) {
383:
384:                ImageData data = new ImageData();
385:                if (!loadRomizedImage(data, imageDataArrayPtr,
386:                        imageDataArrayLength)) {
387:                    throw new IllegalArgumentException();
388:                }
389:                return data;
390:            }
391:
392:            /**
393:             * Creates an immutable image from decoded image data obtained from an
394:             * <code>InputStream</code>.  This method blocks until all image data has
395:             * been read and decoded.  After this method completes (whether by
396:             * returning or by throwing an exception) the stream is left open and its
397:             * current position is undefined.
398:             *
399:             * @param stream the name of the resource containing the image data
400:             * in one of the supported image formats
401:             *
402:             * @return the created image
403:             * @throws NullPointerException if <code>stream</code> is <code>null</code>
404:             * @throws java.io.IOException if an I/O error occurs, if the image data
405:             * cannot be loaded, or if the image data cannot be decoded
406:             *
407:             */
408:            public ImageData createImmutableImageData(InputStream stream)
409:                    throws IOException {
410:
411:                ImageData data = new ImageData();
412:                createImageFromStream(data, stream);
413:                return data;
414:            }
415:
416:            /**
417:             * Populates an immutable <code>ImageData</code>
418:             * from decoded data obtained from an <code>InputStream</code>.
419:             * This method blocks until all image data has
420:             * been read and decoded.  After this method completes (whether by
421:             * returning or by throwing an exception) the stream is left open and its
422:             * current position is undefined.
423:             *
424:             * @param data The <code>ImageData</code> to be populated
425:             * @param stream the name of the resource containing the image data
426:             * in one of the supported image formats
427:             *
428:             * @throws NullPointerException if <code>stream</code> is <code>null</code>
429:             * @throws java.io.IOException if an I/O error occurs, if the image data
430:             * cannot be loaded, or if the image data cannot be decoded
431:             *
432:             */
433:            private void createImageFromStream(ImageData data,
434:                    InputStream stream) throws java.io.IOException {
435:
436:                if (stream == null) {
437:                    throw new java.io.IOException();
438:                } else {
439:                    /*
440:                     * Allocate an array assuming available is correct.
441:                     * Only reading an EOF is the real end of file
442:                     * so allocate an extra byte to read the EOF into.
443:                     * If available is incorrect, increase the buffer
444:                     * size and keep reading.
445:                     */
446:                    int l = stream.available();
447:                    byte[] buffer = new byte[l + 1];
448:                    int length = 0;
449:
450:                    // TBD: Guard against an implementation with incorrect available
451:                    while ((l = stream.read(buffer, length, buffer.length
452:                            - length)) != -1) {
453:                        length += l;
454:                        if (length == buffer.length) {
455:                            byte[] b = new byte[buffer.length + 4096];
456:                            System.arraycopy(buffer, 0, b, 0, length);
457:                            buffer = b;
458:                        }
459:                    }
460:
461:                    stream.close();
462:
463:                    try {
464:                        decode(data, buffer, 0, length);
465:                    } catch (IllegalArgumentException e) {
466:                        throw new java.io.IOException();
467:                    }
468:                }
469:            }
470:
471:            /**
472:             * Load an <code>ImageData</code> from cache. The real work is done in
473:             * the native function.
474:             *
475:             * @param   imageData The <code>ImageData</code> to be populated
476:             * @param   resName  Image resource name
477:             * @return  true if image was loaded and created, false otherwise
478:             */
479:            private boolean loadCachedImage(ImageData imageData, String resName) {
480:                MIDletSuite midletSuite = MIDletStateHandler
481:                        .getMidletStateHandler().getMIDletSuite();
482:                int suiteId = midletSuite.getID();
483:
484:                return loadCachedImage0(imageData, suiteId, resName);
485:            }
486:
487:            /**
488:             * Native function to load native image data from cache and populate
489:             * an immutable <code>ImageData</code>.
490:             * pixelData and alphaData, width and height, will be set
491:             * in native upon success.
492:             *
493:             * @param imageData The <code>ImageData</code> to populate
494:             * @param suiteId   The suite id
495:             * @param resName   The image resource name
496:             * @return          true if image was loaded and created, false otherwise
497:             */
498:            private native boolean loadCachedImage0(ImageData imageData,
499:                    int suiteId, String resName);
500:
501:            /**
502:             * Function to decode an <code>ImageData</code> from PNG data.
503:             *
504:             * @param imageData the <code>ImageData</code> to be populated
505:             * @param imageBytes the array of image data in a supported image format
506:             * @param imageOffset the offset of the start of the data in the array
507:             * @param imageLength the length of the data in the array
508:             */
509:            private void decodePNG(ImageData imageData, byte[] imageBytes,
510:                    int imageOffset, int imageLength) {
511:                // find the format of the image data
512:                if (imageLength < pngHeader.length + 8) {
513:                    throw new IllegalArgumentException();
514:                }
515:
516:                int width = ((imageBytes[imageOffset + 16] & 0x0ff) << 24)
517:                        + ((imageBytes[imageOffset + 17] & 0x0ff) << 16)
518:                        + ((imageBytes[imageOffset + 18] & 0x0ff) << 8)
519:                        + (imageBytes[imageOffset + 19] & 0x0ff);
520:
521:                int height = ((imageBytes[imageOffset + 20] & 0x0ff) << 24)
522:                        + ((imageBytes[imageOffset + 21] & 0x0ff) << 16)
523:                        + ((imageBytes[imageOffset + 22] & 0x0ff) << 8)
524:                        + (imageBytes[imageOffset + 23] & 0x0ff);
525:
526:                if (width <= 0 || height <= 0) {
527:                    throw new IllegalArgumentException();
528:                }
529:
530:                imageData.initImageData(width, height, false, true);
531:
532:                // load the decoded PNG data into the data byte arrays
533:                if (loadPNG(imageData, imageBytes, imageOffset, imageLength) == false) {
534:                    // if loadPNG returns false, the image contains
535:                    // only opaque pixel and the alpha data is not needed
536:                    imageData.removeAlpha();
537:                }
538:            }
539:
540:            /**
541:             * Function to decode an <code>ImageData</code> from JPEG data.
542:             *
543:             * @param imageData the <code>ImageData</code> to be populated
544:             * @param imageBytes the array of image data in a supported image format
545:             * @param imageOffset the offset of the start of the data in the array
546:             * @param imageLength the length of the data in the array
547:             */
548:            private void decodeJPEG(ImageData imageData, byte[] imageBytes,
549:                    int imageOffset, int imageLength) {
550:                // find the format of the image data
551:                if (imageLength < jpegHeader.length + 8) {
552:                    throw new IllegalArgumentException();
553:                }
554:
555:                int width = 0;
556:                int height = 0;
557:
558:                /**
559:                 * Find SOF (Start Of Frame) marker:
560:                 * format of SOF
561:                 *   2 bytes    Marker Identity  (0xff 0xc<N>)
562:                 *   2 bytes    Length of block
563:                 *   1 byte     bits/sample
564:                 *   2 bytes    Image Height
565:                 *   2 bytes    Image Width
566:                 *   1 bytes    Number of components
567:                 *   n bytes    the components
568:                 *
569:                 * Searching for the byte pair representing SOF is unsafe
570:                 * because a prior marker might contain the SOFn pattern
571:                 * so we must skip over the preceding markers.
572:                 *
573:                 * When editing this code, don't forget to make the appropriate changes
574:                 * in src/lowlevelui/graphics_util/reference/native/gxutl_image_util.c.
575:                 */
576:                int idx = imageOffset + 2;
577:
578:                while (idx + 8 < imageOffset + imageLength) {
579:                    if (imageBytes[idx] != (byte) 0xff) {
580:                        break;
581:                    }
582:
583:                    if ((byte) (imageBytes[idx + 1] & 0xf0) == (byte) 0xc0) {
584:                        byte code = imageBytes[idx + 1];
585:
586:                        if (code != (byte) 0xc4 || code != (byte) 0xcc) {
587:                            /* Big endian */
588:                            height = ((imageBytes[idx + 5] & 0xff) << 8)
589:                                    + (imageBytes[idx + 6] & 0xff);
590:                            width = ((imageBytes[idx + 7] & 0xff) << 8)
591:                                    + (imageBytes[idx + 8] & 0xff);
592:                            break;
593:                        }
594:                    }
595:
596:                    /* Go to the next marker */
597:                    int field_len = ((imageBytes[idx + 2] & 0xff) << 8)
598:                            + (imageBytes[idx + 3] & 0xff);
599:                    idx += field_len + 2;
600:                }
601:
602:                if (width <= 0 || height <= 0) {
603:                    throw new IllegalArgumentException();
604:                }
605:
606:                imageData.initImageData(width, height, false, false);
607:
608:                // load the decoded JPEG data into the pixelData array
609:                loadJPEG(imageData, imageBytes, imageOffset, imageLength);
610:            }
611:
612:            /**
613:             * Function to decode an <code>ImageData</code> from RAW data.
614:             *
615:             * @param imageData the <code>ImageData</code> to be populated
616:             * @param imageBytes the array of image data in a supported image format
617:             * @param imageOffset the offset of the start of the data in the array
618:             * @param imageLength the length of the data in the array
619:             */
620:            private void decodeRAW(ImageData imageData, byte[] imageBytes,
621:                    int imageOffset, int imageLength) {
622:                // find the format of the image data
623:                if (imageLength < rawHeader.length + 8) {
624:                    throw new IllegalArgumentException();
625:                }
626:                loadRAW(imageData, imageBytes, imageOffset, imageLength);
627:            }
628:
629:            /**
630:             * Function to compare byte data to the given header
631:             *
632:             * @param header header data to compare imageData with
633:             * @param imageData the array of image data in a supported image format
634:             * @param imageOffset the offset of the start of the data in the array
635:             * @param imageLength the length of the data in the array
636:             * @return true if the header.length bytes at imageData[imageOffset]
637:             * are equal to the bytes in header array, false otherwise
638:             */
639:            private boolean headerMatch(byte[] header, byte[] imageData,
640:                    int imageOffset, int imageLength) {
641:                if (imageLength < header.length) {
642:                    return false;
643:                }
644:
645:                for (int i = 0; i < header.length; i++) {
646:                    if (imageData[imageOffset + i] != header[i]) {
647:                        return false;
648:                    }
649:                }
650:
651:                return true;
652:            }
653:
654:            /**
655:             * Function to decode an <code>ImageData</code> from byte data.
656:             *
657:             * @param imageData the <code>ImageData<code> to populate
658:             * @param imageBytes the array of image data in a supported image format
659:             * @param imageOffset the offset of the start of the data in the array
660:             * @param imageLength the length of the data in the array
661:             * @throws IllegalArgumentException if the data is not formatted correctly
662:             */
663:            private void decode(ImageData imageData, byte[] imageBytes,
664:                    int imageOffset, int imageLength) {
665:                // check if it is a PNG image
666:                if (headerMatch(pngHeader, imageBytes, imageOffset, imageLength)) {
667:                    // image type is PNG
668:                    decodePNG(imageData, imageBytes, imageOffset, imageLength);
669:                } else if (headerMatch(jpegHeader, imageBytes, imageOffset,
670:                        imageLength)) {
671:                    // image type is JPEG
672:                    decodeJPEG(imageData, imageBytes, imageOffset, imageLength);
673:                } else if (headerMatch(rawHeader, imageBytes, imageOffset,
674:                        imageLength)) {
675:                    // image type is RAW
676:                    decodeRAW(imageData, imageBytes, imageOffset, imageLength);
677:                } else {
678:                    // does not match supported image type
679:                    throw new IllegalArgumentException();
680:                }
681:            }
682:
683:            /**
684:             * Native function to load an <code>ImageData</code> from PNG data.
685:             *
686:             * @param imageData the <code>ImageData</code> to load to
687:             * @param imageBytes the array of image data in a supported image format
688:             * @param imageOffset the offset of the start of the data in the array
689:             * @param imageLength the length of the data in the array
690:             *
691:             * @return true if there is alpha data
692:             */
693:            private native boolean loadPNG(ImageData imageData,
694:                    byte[] imageBytes, int imageOffset, int imageLength);
695:
696:            /**
697:             * Native function to load an <code>ImageData </code>from JPEG data.
698:             *
699:             * @param imageData the <code>ImageData</code> to load to
700:             * @param imageBytes the array of image data in a supported image format
701:             * @param imageOffset the offset of the start of the data in the array
702:             * @param imageLength the length of the data in the array
703:             */
704:            private native void loadJPEG(ImageData imageData,
705:                    byte[] imageBytes, int imageOffset, int imageLength);
706:
707:            /**
708:             * Native function to load an <code>ImageData</code>
709:             * directly out of the rom image.
710:             *
711:             * @param data The <code>ImageData</code> to load to
712:             * @param imageDataArrayPtr native pointer to image data as Java int
713:             * @param imageDataArrayLength length of image data array
714:             * @return true if romized image was loaded successfully,
715:             *         false - otherwise
716:             */
717:            private native boolean loadRomizedImage(ImageData data,
718:                    int imageDataArrayPtr, int imageDataArrayLength);
719:
720:            /**
721:             * Native function to load an <code>ImageData</code> from ARGB data.
722:             *
723:             * @param imgData The <code>ImageData</code> to load to
724:             * @param rgb the array of image data in a ARGB format
725:             */
726:            private native void loadRGB(ImageData imgData, int[] rgb);
727:
728:            /**
729:             * Native function to load an <code>ImageData</code> from RAW data.
730:             *
731:             * @param imgData The <code>ImageData</code> to load to
732:             * @param imageBytes the array of image data in a RAW format
733:             */
734:            private native void loadRAW(ImageData imgData, byte[] imageBytes,
735:                    int imageOffset, int imageLength);
736:
737:            /**
738:             * Copy either Java or romized data into another <code>ImageData</code>
739:             * from an <code>ImageData</code> region.
740:             *
741:             * @param dest the <code>ImageData</code> to copy to
742:             * @param source the source image to be copied from
743:             * @param x the horizontal location of the region to be copied
744:             * @param y the vertical location of the region to be copied
745:             * @param width the width of the region to be copied
746:             * @param height the height of the region to be copied
747:             * @param transform the transform to be applied to the region
748:             */
749:            private native void loadRegion(ImageData dest, ImageData source,
750:                    int x, int y, int width, int height, int transform);
751:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.