Source Code Cross Referenced for GIFImageDecoder.java in  » 6.0-JDK-Modules » j2me » com » sun » mmedia » 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 » com.sun.mmedia 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004:         * 
005:         * This program is free software; you can redistribute it and/or
006:         * modify it under the terms of the GNU General Public License version
007:         * 2 only, as published by the Free Software Foundation.
008:         * 
009:         * This program is distributed in the hope that it will be useful, but
010:         * WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012:         * General Public License version 2 for more details (a copy is
013:         * included at /legal/license.txt).
014:         * 
015:         * You should have received a copy of the GNU General Public License
016:         * version 2 along with this work; if not, write to the Free Software
017:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018:         * 02110-1301 USA
019:         * 
020:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021:         * Clara, CA 95054 or visit www.sun.com if you need additional
022:         * information or have any questions.
023:         */
024:        package com.sun.mmedia;
025:
026:        /**
027:         * Decodes single images after parsing headers. Helper for GIFPlayer.
028:         * Performs LZW decoding, palette mapping, interlacing, tranparency follow-up
029:         */
030:        class GIFImageDecoder {
031:
032:            final static int UNDRAW_LEAVE = 1;
033:            final static int UNDRAW_RESTORE_BACKGROUND = 2;
034:            final static int UNDRAW_RESTORE_PREVIOUS = 3;
035:
036:            private int width, height, colorDepth, globalColorDepth,
037:                    curColorDepth;
038:            private byte[] globalPalette;
039:            private byte[] curPalette;
040:            private int[] argb;
041:            private int[] curArgb;
042:            private int backgroundIndex;
043:
044:            private int transparentColorIndex = -1;
045:            private int undrawFlag = UNDRAW_LEAVE;
046:
047:            private int framePosX, framePosY, frameWidth, frameHeight;
048:            private boolean interlace;
049:
050:            /// Initialize with Global Descriptor data
051:            GIFImageDecoder(int width, int height, int colorDepth) {
052:                this .width = width;
053:                this .height = height;
054:                this .colorDepth = colorDepth;
055:
056:                globalColorDepth = colorDepth;
057:                globalPalette = new byte[3 * (1 << globalColorDepth)];
058:
059:                // default global color map - increasing grays
060:                globalPalette[0] = 0;
061:                globalPalette[1] = 0;
062:                globalPalette[2] = 0;
063:                int shift = 8 - globalColorDepth;
064:                int add = (1 << shift) - 1;
065:                for (int i = 1; i < (1 << globalColorDepth); ++i) {
066:                    byte gray = (byte) ((i << shift) | add);
067:                    globalPalette[3 * i + 0] = gray;
068:                    globalPalette[3 * i + 1] = gray;
069:                    globalPalette[3 * i + 2] = gray;
070:                }
071:
072:                backgroundIndex = -1;
073:
074:                curColorDepth = globalColorDepth;
075:                curPalette = globalPalette;
076:
077:                argb = new int[width * height];
078:                for (int i = 0; i < width * height; ++i)
079:                    argb[i] = 0x00badbad; // transparent
080:            }
081:
082:            /// Set Global Descriptor's palette data (optional)
083:            void setGlobalPalette(int colorDepth, byte[] palette,
084:                    int backgroundIndex) {
085:                if (curPalette == globalPalette) {
086:                    curPalette = palette;
087:                    curColorDepth = colorDepth;
088:                }
089:                globalPalette = palette;
090:                globalColorDepth = colorDepth;
091:
092:                this .backgroundIndex = backgroundIndex;
093:            }
094:
095:            /// Clear current image to background color
096:            void clearImage() {
097:                if (globalPalette != null && backgroundIndex >= 0) {
098:                    int bkg = getColor(backgroundIndex, globalPalette);
099:                    for (int i = 0; i < width * height; ++i)
100:                        argb[i] = bkg;
101:                }
102:            }
103:
104:            /// Get current image (after undraw)
105:            //int [] getCurrentARGB() {
106:            //    return argb;
107:            //}
108:
109:            /// Get color from palette
110:            private int getColor(int index, byte[] palette) {
111:                index *= 3;
112:                return 0xff000000 | ((palette[index + 0] & 0xff) << 16)
113:                        | ((palette[index + 1] & 0xff) << 8)
114:                        | (palette[index + 2] & 0xff);
115:            }
116:
117:            /// Prepare for next frame decoding (set Local Descriptor data)
118:            void newFrame(int relx, int rely, int width, int height,
119:                    boolean interlaceFlag) {
120:                if (relx + width > this .width)
121:                    framePosX = this .width - width;
122:                else
123:                    framePosX = relx;
124:
125:                if (rely + height > this .height)
126:                    framePosY = this .height - height;
127:                else
128:                    framePosY = rely;
129:
130:                // Relying that frameWidth < this.width && frameHeight << this.height
131:                frameWidth = width;
132:                frameHeight = height;
133:                interlace = interlaceFlag;
134:            }
135:
136:            /// Set Local Descriptor's palette data (optional)
137:            void setLocalPalette(int colorDepth, byte[] palette) {
138:                curColorDepth = colorDepth;
139:                curPalette = palette;
140:            }
141:
142:            /**
143:             * Set Local Description Extension data (optional)
144:             *
145:             * udrawFlag: see UNDRAW_* constants
146:             * tranparentColor:  -1 - no transparent color, otherwise - index from color table
147:             */
148:            void setGraphicsControl(int undrawFlag, int transparentColorIndex) {
149:                this .undrawFlag = undrawFlag;
150:                this .transparentColorIndex = transparentColorIndex;
151:            }
152:
153:            /// Decode frame data from dataBlocks to out
154:            boolean decodeImage(int lzwCodeSize, int dataSize, byte data[],
155:                    int out[]) {
156:                curArgb = out;
157:
158:                // Get saved image
159:                System.arraycopy(argb, 0, curArgb, 0, width * height);
160:
161:                // LZW decode
162:                boolean result = lzwImage(lzwCodeSize, dataSize, data);
163:
164:                // Undraw
165:                switch (undrawFlag) {
166:                case UNDRAW_LEAVE: {
167:                    int pixel = framePosX + framePosY * width;
168:                    for (int i = 0; i < frameHeight; ++i, pixel += width)
169:                        System.arraycopy(curArgb, pixel, argb, pixel,
170:                                frameWidth);
171:                    break;
172:                }
173:                case UNDRAW_RESTORE_BACKGROUND:
174:                    if (globalPalette != null && backgroundIndex >= 0) {
175:                        int pixel = framePosX + framePosY * width;
176:                        int wdif = width - frameWidth;
177:                        int bkg = getColor(backgroundIndex, globalPalette);
178:
179:                        for (int i = 0; i < frameHeight; ++i, pixel += wdif)
180:                            for (int j = 0; j < frameWidth; ++j, ++pixel)
181:                                argb[pixel] = bkg;
182:                        break;
183:                    }
184:                case UNDRAW_RESTORE_PREVIOUS:
185:                    // Do nothing
186:                    break;
187:                }
188:                resetLocalData();
189:
190:                return result;
191:            }
192:
193:            // Should be called at the end of the image parsing
194:            private void resetLocalData() {
195:                undrawFlag = UNDRAW_LEAVE;
196:                transparentColorIndex = -1;
197:                curColorDepth = globalColorDepth;
198:                curPalette = globalPalette;
199:            }
200:
201:            private void drawLine(byte[] line, int y/*, int multiply*/) {
202:                if (y > frameHeight)
203:                    return;
204:                int pixel = (framePosY + y) * width + framePosX;
205:
206:                for (int i = 0; i < frameWidth; ++i, ++pixel) {
207:                    int idx = line[i] & 0xff;
208:                    if (idx != transparentColorIndex)
209:                        curArgb[pixel] = getColor(idx, curPalette);
210:                }
211:            }
212:
213:            // ------------------------- LZW decoder ------------------------
214:            // This is converted from the native version. The java version is 
215:            // much faster when we have JIT.
216:
217:            private short prefix[] = new short[4096];
218:            private byte suffix[] = new byte[4096];
219:            private byte outCode[] = new byte[4097];
220:
221:            /**
222:             * Parses image, using current palette and graphics control.
223:             * Returns true if the image has been wholly parsed,
224:             * false if it was truncated.
225:             */
226:            private boolean lzwImage(int initCodeSize, int dataSize,
227:                    byte block[]) {
228:
229:                byte[] rasline = new byte[frameWidth];
230:
231:                int OUTCODELENGTH = 4097;
232:
233:                int clearCode = (1 << initCodeSize);
234:                int eofCode = clearCode + 1;
235:                int bitMask;
236:                int curCode;
237:                int outCount = OUTCODELENGTH;
238:
239:                /* Variables used to walk read data */
240:                int remain = dataSize;
241:                int byteoff = 0;
242:                int accumbits = 0;
243:                int accumdata = 0;
244:
245:                /* Variables used to decompress the data */
246:                int codeSize = initCodeSize + 1;
247:                int maxCode = 1 << codeSize;
248:                int codeMask = maxCode - 1;
249:                int freeCode = clearCode + 2;
250:                int code = 0;
251:                int oldCode = 0;
252:                char prevChar = 0;
253:
254:                /* Variables used for writing pixels */
255:                int x = frameWidth;
256:                int y = 0;
257:                int off = 0;
258:                int passinc = interlace ? 8 : 1;
259:                int passht = passinc;
260:
261:                bitMask = (1 << curColorDepth) - 1;
262:
263:                /* Read codes until the eofCode is encountered */
264:                for (;;) {
265:                    if (accumbits < codeSize) {
266:                        while (remain < 2) {
267:                            /* Sometimes we have one last byte to process... */
268:                            if (remain == 1 && accumbits + 8 >= codeSize)
269:                                break;
270:
271:                            if (off > 0)
272:                                drawLine(rasline, y/*, passht*/);
273:
274:                            /* quietly accept truncated GIF images */
275:                            return false;
276:                        }
277:
278:                        /* 2 bytes at a time saves checking for accumbits < codeSize.
279:                         * We know we'll get enough and also that we can't overflow
280:                         * since codeSize <= 12.
281:                         */
282:                        if (remain >= 2) {
283:                            remain -= 2;
284:                            accumdata += (block[byteoff++] & 0xff) << accumbits;
285:                            accumbits += 8;
286:                            accumdata += (block[byteoff++] & 0xff) << accumbits;
287:                            accumbits += 8;
288:                        } else {
289:                            remain--;
290:                            accumdata += (block[byteoff++] & 0xff) << accumbits;
291:                            accumbits += 8;
292:                        }
293:                    }
294:
295:                    /* Compute the code */
296:                    code = accumdata & codeMask;
297:                    accumdata >>= codeSize;
298:                    accumbits -= codeSize;
299:
300:                    /*
301:                     * Interpret the code
302:                     */
303:                    if (code == clearCode) {
304:                        /* Clear code sets everything back to its initial value, then
305:                         * reads the immediately subsequent code as uncompressed data.
306:                         */
307:
308:                        /* Note that freeCode is one less than it is supposed to be,
309:                         * this is because it will be incremented next time round the 
310:                         * loop
311:                         */
312:                        freeCode = clearCode + 1;
313:                        codeSize = initCodeSize + 1;
314:                        maxCode = 1 << codeSize;
315:                        codeMask = maxCode - 1;
316:
317:                        /* Continue if we've NOT reached the end, some Gif images
318:                         * contain bogus codes after the last clear code.
319:                         */
320:                        if (y < height)
321:                            continue;
322:
323:                        return true;
324:                    }
325:
326:                    if (code == eofCode)
327:                        return true;
328:
329:                    /* It must be data: save code in CurCode */
330:                    curCode = code;
331:                    /* Whenever it gets here outCount is always equal to 
332:                       OUTCODELENGTH, so no need to reset outCount. */
333:                    //outCount = OUTCODELENGTH;
334:                    /* If greater or equal to freeCode, not in the hash table
335:                     * yet; repeat the last character decoded
336:                     */
337:                    if (curCode >= freeCode) {
338:                        if (curCode > freeCode)
339:                            /*
340:                             * if we get a code too far outside our range, it
341:                             * could case the parser to start traversing parts
342:                             * of our data structure that are out of range...
343:                             */
344:                            return true;
345:
346:                        curCode = oldCode;
347:                        outCode[--outCount] = (byte) prevChar;
348:                    }
349:
350:                    /* Unless this code is raw data, pursue the chain pointed
351:                     * to by curCode through the hash table to its end; each
352:                     * code in the chain puts its associated output code on
353:                     * the output queue.
354:                     */
355:                    while (curCode > bitMask) {
356:                        outCode[--outCount] = suffix[curCode];
357:                        if (outCount == 0)
358:                            /*
359:                             * In theory this should never happen since our
360:                             * prefix and suffix arrays are monotonically
361:                             * decreasing and so outCode will only be filled
362:                             * as much as those arrays, but I don't want to
363:                             * take that chance and the test is probably
364:                             * cheap compared to the read and write operations.
365:                             * If we ever do overflow the array, we will just
366:                             * flush the rest of the data and quietly accept
367:                             * the GIF as truncated here.
368:                             */
369:                            return true;
370:
371:                        curCode = prefix[curCode];
372:                    }
373:
374:                    /* The last code in the chain is treated as raw data. */
375:                    prevChar = (char) curCode;
376:                    outCode[--outCount] = (byte) prevChar;
377:
378:                    /* Now we put the data out to the Output routine. It's
379:                     * been stacked LIFO, so deal with it that way...
380:                     */
381:                    int len = OUTCODELENGTH - outCount; /* This is why I commented out
382:                                                                  the code that resets outCount. */
383:                    while (--len >= 0) {
384:                        rasline[off++] = outCode[outCount++];
385:
386:                        /* Update the X-coordinate, and if it overflows, update the
387:                         * Y-coordinate
388:                         */
389:                        if (--x == 0) {
390:                            /* If a non-interlaced picture, just increment y to the next
391:                             * scan line.  If it's interlaced, deal with the interlace as
392:                             * described in the GIF spec.  Put the decoded scan line out
393:                             * to the screen if we haven't gone past the bottom of it
394:                             */
395:                            drawLine(rasline, y/*, passht*/);
396:
397:                            x = frameWidth;
398:                            off = 0;
399:                            /*  pass        inc     ht      ystart */
400:                            /*   0           8      8          0   */
401:                            /*   1           8      4          4   */
402:                            /*   2           4      2          2   */
403:                            /*   3           2      1          1   */
404:                            y += passinc;
405:                            while (y >= height) {
406:                                passinc = passht;
407:                                passht >>= 1;
408:                                y = passht;
409:                                if (passht == 0)
410:                                    return true;
411:                            }
412:                        }
413:                    }
414:
415:                    /* Build the hash table on-the-fly. No table is stored in the file. */
416:                    prefix[freeCode] = (short) oldCode;
417:                    suffix[freeCode] = (byte) prevChar;
418:                    oldCode = code;
419:                    /* Point to the next slot in the table.  If we exceed the
420:                     * maxCode, increment the code size unless
421:                     * it's already 12.  If it is, do nothing: the next code
422:                     * decompressed better be CLEAR
423:                     */
424:                    if (++freeCode >= maxCode) {
425:                        if (codeSize < 12) {
426:                            codeSize++;
427:                            maxCode <<= 1;
428:                            codeMask = maxCode - 1;
429:                        } else
430:                            /* Just in case */
431:                            freeCode = maxCode - 1;
432:                    }
433:                }
434:            }
435:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.