Source Code Cross Referenced for GIFFileFormat.java in  » IDE-Eclipse » swt » org » eclipse » swt » internal » image » 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 » IDE Eclipse » swt » org.eclipse.swt.internal.image 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2005 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.swt.internal.image;
011:
012:        import org.eclipse.swt.*;
013:        import org.eclipse.swt.graphics.*;
014:        import java.io.*;
015:
016:        final class GIFFileFormat extends FileFormat {
017:            String signature;
018:            int screenWidth, screenHeight, backgroundPixel, bitsPerPixel,
019:                    defaultDepth;
020:            int disposalMethod = 0;
021:            int delayTime = 0;
022:            int transparentPixel = -1;
023:            int repeatCount = 1;
024:
025:            static final int GIF_APPLICATION_EXTENSION_BLOCK_ID = 0xFF;
026:            static final int GIF_GRAPHICS_CONTROL_BLOCK_ID = 0xF9;
027:            static final int GIF_PLAIN_TEXT_BLOCK_ID = 0x01;
028:            static final int GIF_COMMENT_BLOCK_ID = 0xFE;
029:            static final int GIF_EXTENSION_BLOCK_ID = 0x21;
030:            static final int GIF_IMAGE_BLOCK_ID = 0x2C;
031:            static final int GIF_TRAILER_ID = 0x3B;
032:            static final byte[] GIF89a = new byte[] { (byte) 'G', (byte) 'I',
033:                    (byte) 'F', (byte) '8', (byte) '9', (byte) 'a' };
034:            static final byte[] NETSCAPE2_0 = new byte[] { (byte) 'N',
035:                    (byte) 'E', (byte) 'T', (byte) 'S', (byte) 'C', (byte) 'A',
036:                    (byte) 'P', (byte) 'E', (byte) '2', (byte) '.', (byte) '0' };
037:
038:            /**
039:             * Answer a palette containing numGrays
040:             * shades of gray, ranging from black to white.
041:             */
042:            static PaletteData grayRamp(int numGrays) {
043:                int n = numGrays - 1;
044:                RGB[] colors = new RGB[numGrays];
045:                for (int i = 0; i < numGrays; i++) {
046:                    int intensity = (byte) ((i * 3) * 256 / n);
047:                    colors[i] = new RGB(intensity, intensity, intensity);
048:                }
049:                return new PaletteData(colors);
050:            }
051:
052:            boolean isFileFormat(LEDataInputStream stream) {
053:                try {
054:                    byte[] signature = new byte[3];
055:                    stream.read(signature);
056:                    stream.unread(signature);
057:                    return new String(signature).equals("GIF"); //$NON-NLS-1$
058:                } catch (Exception e) {
059:                    return false;
060:                }
061:            }
062:
063:            /**
064:             * Load the GIF image(s) stored in the input stream.
065:             * Return an array of ImageData representing the image(s).
066:             */
067:            ImageData[] loadFromByteStream() {
068:                byte[] signatureBytes = new byte[3];
069:                byte[] versionBytes = new byte[3];
070:                byte[] block = new byte[7];
071:                try {
072:                    inputStream.read(signatureBytes);
073:                    signature = new String(signatureBytes);
074:                    if (!signature.equals("GIF")) //$NON-NLS-1$
075:                        SWT.error(SWT.ERROR_INVALID_IMAGE);
076:
077:                    inputStream.read(versionBytes);
078:
079:                    inputStream.read(block);
080:                } catch (IOException e) {
081:                    SWT.error(SWT.ERROR_IO, e);
082:                }
083:                screenWidth = (block[0] & 0xFF) | ((block[1] & 0xFF) << 8);
084:                loader.logicalScreenWidth = screenWidth;
085:                screenHeight = (block[2] & 0xFF) | ((block[3] & 0xFF) << 8);
086:                loader.logicalScreenHeight = screenHeight;
087:                byte bitField = block[4];
088:                backgroundPixel = block[5] & 0xFF;
089:                //aspect = block[6] & 0xFF;
090:                bitsPerPixel = ((bitField >> 4) & 0x07) + 1;
091:                defaultDepth = (bitField & 0x7) + 1;
092:                PaletteData palette = null;
093:                if ((bitField & 0x80) != 0) {
094:                    // Global palette.
095:                    //sorted = (bitField & 0x8) != 0;
096:                    palette = readPalette(1 << defaultDepth);
097:                } else {
098:                    // No global palette.
099:                    //sorted = false;
100:                    backgroundPixel = -1;
101:                    defaultDepth = bitsPerPixel;
102:                }
103:                loader.backgroundPixel = backgroundPixel;
104:
105:                getExtensions();
106:                int id = readID();
107:                ImageData[] images = new ImageData[0];
108:                while (id == GIF_IMAGE_BLOCK_ID) {
109:                    ImageData image = readImageBlock(palette);
110:                    if (loader.hasListeners()) {
111:                        loader.notifyListeners(new ImageLoaderEvent(loader,
112:                                image, 3, true));
113:                    }
114:                    ImageData[] oldImages = images;
115:                    images = new ImageData[oldImages.length + 1];
116:                    System.arraycopy(oldImages, 0, images, 0, oldImages.length);
117:                    images[images.length - 1] = image;
118:                    try {
119:                        /* Read the 0-byte terminator at the end of the image. */
120:                        id = inputStream.read();
121:                        if (id > 0) {
122:                            /* We read the terminator earlier. */
123:                            inputStream.unread(new byte[] { (byte) id });
124:                        }
125:                    } catch (IOException e) {
126:                        SWT.error(SWT.ERROR_IO, e);
127:                    }
128:                    getExtensions();
129:                    id = readID();
130:                }
131:                return images;
132:            }
133:
134:            /**
135:             * Read and return the next block or extension identifier from the file.
136:             */
137:            int readID() {
138:                try {
139:                    return inputStream.read();
140:                } catch (IOException e) {
141:                    SWT.error(SWT.ERROR_IO, e);
142:                }
143:                return -1;
144:            }
145:
146:            /**
147:             * Read extensions until an image descriptor appears.
148:             * In the future, if we care about the extensions, they
149:             * should be properly grouped with the image data before
150:             * which they appeared. Right now, the interesting parts
151:             * of some extensions are kept, but the rest is discarded.
152:             * Throw an error if an error occurs.
153:             */
154:            void getExtensions() {
155:                int id = readID();
156:                while (id != GIF_IMAGE_BLOCK_ID && id != GIF_TRAILER_ID
157:                        && id > 0) {
158:                    if (id == GIF_EXTENSION_BLOCK_ID) {
159:                        readExtension();
160:                    } else {
161:                        SWT.error(SWT.ERROR_INVALID_IMAGE);
162:                    }
163:                    id = readID();
164:                }
165:                if (id == GIF_IMAGE_BLOCK_ID || id == GIF_TRAILER_ID) {
166:                    try {
167:                        inputStream.unread(new byte[] { (byte) id });
168:                    } catch (IOException e) {
169:                        SWT.error(SWT.ERROR_IO, e);
170:                    }
171:                }
172:            }
173:
174:            /**
175:             * Read a control extension.
176:             * Return the extension block data.
177:             */
178:            byte[] readExtension() {
179:                int extensionID = readID();
180:                if (extensionID == GIF_COMMENT_BLOCK_ID)
181:                    return readCommentExtension();
182:                if (extensionID == GIF_PLAIN_TEXT_BLOCK_ID)
183:                    return readPlainTextExtension();
184:                if (extensionID == GIF_GRAPHICS_CONTROL_BLOCK_ID)
185:                    return readGraphicsControlExtension();
186:                if (extensionID == GIF_APPLICATION_EXTENSION_BLOCK_ID)
187:                    return readApplicationExtension();
188:                // Otherwise, we don't recognize the block. If the
189:                // field size is correct, we can just skip over
190:                // the block contents.
191:                try {
192:                    int extSize = inputStream.read();
193:                    if (extSize < 0) {
194:                        SWT.error(SWT.ERROR_INVALID_IMAGE);
195:                    }
196:                    byte[] ext = new byte[extSize];
197:                    inputStream.read(ext, 0, extSize);
198:                    return ext;
199:                } catch (IOException e) {
200:                    SWT.error(SWT.ERROR_IO, e);
201:                    return null;
202:                }
203:            }
204:
205:            /**
206:             * We have just read the Comment extension identifier
207:             * from the input stream. Read in the rest of the comment
208:             * and return it. GIF comment blocks are variable size.
209:             */
210:            byte[] readCommentExtension() {
211:                try {
212:                    byte[] comment = new byte[0];
213:                    byte[] block = new byte[255];
214:                    int size = inputStream.read();
215:                    while ((size > 0)
216:                            && (inputStream.read(block, 0, size) != -1)) {
217:                        byte[] oldComment = comment;
218:                        comment = new byte[oldComment.length + size];
219:                        System.arraycopy(oldComment, 0, comment, 0,
220:                                oldComment.length);
221:                        System.arraycopy(block, 0, comment, oldComment.length,
222:                                size);
223:                        size = inputStream.read();
224:                    }
225:                    return comment;
226:                } catch (Exception e) {
227:                    SWT.error(SWT.ERROR_IO, e);
228:                    return null;
229:                }
230:            }
231:
232:            /**
233:             * We have just read the PlainText extension identifier
234:             * from the input stream. Read in the plain text info and text,
235:             * and return the text. GIF plain text blocks are variable size.
236:             */
237:            byte[] readPlainTextExtension() {
238:                try {
239:                    // Read size of block = 0x0C.
240:                    inputStream.read();
241:                    // Read the text information (x, y, width, height, colors).
242:                    byte[] info = new byte[12];
243:                    inputStream.read(info);
244:                    // Read the text.
245:                    byte[] text = new byte[0];
246:                    byte[] block = new byte[255];
247:                    int size = inputStream.read();
248:                    while ((size > 0)
249:                            && (inputStream.read(block, 0, size) != -1)) {
250:                        byte[] oldText = text;
251:                        text = new byte[oldText.length + size];
252:                        System.arraycopy(oldText, 0, text, 0, oldText.length);
253:                        System.arraycopy(block, 0, text, oldText.length, size);
254:                        size = inputStream.read();
255:                    }
256:                    return text;
257:                } catch (Exception e) {
258:                    SWT.error(SWT.ERROR_IO, e);
259:                    return null;
260:                }
261:            }
262:
263:            /**
264:             * We have just read the GraphicsControl extension identifier
265:             * from the input stream. Read in the control information, store
266:             * it, and return it.
267:             */
268:            byte[] readGraphicsControlExtension() {
269:                try {
270:                    // Read size of block = 0x04.
271:                    inputStream.read();
272:                    // Read the control block.
273:                    byte[] controlBlock = new byte[4];
274:                    inputStream.read(controlBlock);
275:                    byte bitField = controlBlock[0];
276:                    // Store the user input field.
277:                    //userInput = (bitField & 0x02) != 0;
278:                    // Store the disposal method.
279:                    disposalMethod = (bitField >> 2) & 0x07;
280:                    // Store the delay time.
281:                    delayTime = (controlBlock[1] & 0xFF)
282:                            | ((controlBlock[2] & 0xFF) << 8);
283:                    // Store the transparent color.
284:                    if ((bitField & 0x01) != 0) {
285:                        transparentPixel = controlBlock[3] & 0xFF;
286:                    } else {
287:                        transparentPixel = -1;
288:                    }
289:                    // Read block terminator.
290:                    inputStream.read();
291:                    return controlBlock;
292:                } catch (Exception e) {
293:                    SWT.error(SWT.ERROR_IO, e);
294:                    return null;
295:                }
296:            }
297:
298:            /**
299:             * We have just read the Application extension identifier
300:             * from the input stream.  Read in the rest of the extension,
301:             * look for and store 'number of repeats', and return the data.
302:             */
303:            byte[] readApplicationExtension() {
304:                try {
305:                    // Read size of block = 0x0B.
306:                    inputStream.read();
307:                    // Read application identifier.
308:                    byte[] applicationBytes = new byte[8];
309:                    inputStream.read(applicationBytes);
310:                    String application = new String(applicationBytes);
311:                    // Read authentication code.
312:                    byte[] authenticationBytes = new byte[3];
313:                    inputStream.read(authenticationBytes);
314:                    String authentication = new String(authenticationBytes);
315:                    // Read application data.
316:                    byte[] data = new byte[0];
317:                    byte[] block = new byte[255];
318:                    int size = inputStream.read();
319:                    while ((size > 0)
320:                            && (inputStream.read(block, 0, size) != -1)) {
321:                        byte[] oldData = data;
322:                        data = new byte[oldData.length + size];
323:                        System.arraycopy(oldData, 0, data, 0, oldData.length);
324:                        System.arraycopy(block, 0, data, oldData.length, size);
325:                        size = inputStream.read();
326:                    }
327:                    // Look for the NETSCAPE 'repeat count' field for an animated GIF.
328:                    if (application.equals("NETSCAPE") && authentication.equals("2.0") && data[0] == 01) { //$NON-NLS-1$ //$NON-NLS-2$
329:                        repeatCount = (data[1] & 0xFF)
330:                                | ((data[2] & 0xFF) << 8);
331:                        loader.repeatCount = repeatCount;
332:                    }
333:                    return data;
334:                } catch (Exception e) {
335:                    SWT.error(SWT.ERROR_IO, e);
336:                    return null;
337:                }
338:            }
339:
340:            /**
341:             * Return a DeviceIndependentImage representing the
342:             * image block at the current position in the input stream.
343:             * Throw an error if an error occurs.
344:             */
345:            ImageData readImageBlock(PaletteData defaultPalette) {
346:                int depth;
347:                PaletteData palette;
348:                byte[] block = new byte[9];
349:                try {
350:                    inputStream.read(block);
351:                } catch (IOException e) {
352:                    SWT.error(SWT.ERROR_IO, e);
353:                }
354:                int left = (block[0] & 0xFF) | ((block[1] & 0xFF) << 8);
355:                int top = (block[2] & 0xFF) | ((block[3] & 0xFF) << 8);
356:                int width = (block[4] & 0xFF) | ((block[5] & 0xFF) << 8);
357:                int height = (block[6] & 0xFF) | ((block[7] & 0xFF) << 8);
358:                byte bitField = block[8];
359:                boolean interlaced = (bitField & 0x40) != 0;
360:                //boolean sorted = (bitField & 0x20) != 0;
361:                if ((bitField & 0x80) != 0) {
362:                    // Local palette.
363:                    depth = (bitField & 0x7) + 1;
364:                    palette = readPalette(1 << depth);
365:                } else {
366:                    // No local palette.
367:                    depth = defaultDepth;
368:                    palette = defaultPalette;
369:                }
370:                /* Work around: Ignore the case where a GIF specifies an
371:                 * invalid index for the transparent pixel that is larger
372:                 * than the number of entries in the palette. */
373:                if (transparentPixel > 1 << depth) {
374:                    transparentPixel = -1;
375:                }
376:                // Promote depth to next highest supported value.
377:                if (!(depth == 1 || depth == 4 || depth == 8)) {
378:                    if (depth < 4)
379:                        depth = 4;
380:                    else
381:                        depth = 8;
382:                }
383:                if (palette == null) {
384:                    palette = grayRamp(1 << depth);
385:                }
386:                int initialCodeSize = -1;
387:                try {
388:                    initialCodeSize = inputStream.read();
389:                } catch (IOException e) {
390:                    SWT.error(SWT.ERROR_IO, e);
391:                }
392:                if (initialCodeSize < 0) {
393:                    SWT.error(SWT.ERROR_INVALID_IMAGE);
394:                }
395:                ImageData image = ImageData.internal_new(width, height, depth,
396:                        palette, 4, null, 0, null, null, -1, transparentPixel,
397:                        SWT.IMAGE_GIF, left, top, disposalMethod, delayTime);
398:                LZWCodec codec = new LZWCodec();
399:                codec.decode(inputStream, loader, image, interlaced,
400:                        initialCodeSize);
401:                return image;
402:            }
403:
404:            /**
405:             * Read a palette from the input stream.
406:             */
407:            PaletteData readPalette(int numColors) {
408:                byte[] bytes = new byte[numColors * 3];
409:                try {
410:                    if (inputStream.read(bytes) != bytes.length)
411:                        SWT.error(SWT.ERROR_INVALID_IMAGE);
412:                } catch (IOException e) {
413:                    SWT.error(SWT.ERROR_IO, e);
414:                }
415:                RGB[] colors = new RGB[numColors];
416:                for (int i = 0; i < numColors; i++)
417:                    colors[i] = new RGB(bytes[i * 3] & 0xFF,
418:                            bytes[i * 3 + 1] & 0xFF, bytes[i * 3 + 2] & 0xFF);
419:                return new PaletteData(colors);
420:            }
421:
422:            void unloadIntoByteStream(ImageLoader loader) {
423:
424:                /* Step 1: Acquire GIF parameters. */
425:                ImageData[] data = loader.data;
426:                int frameCount = data.length;
427:                boolean multi = frameCount > 1;
428:                ImageData firstImage = data[0];
429:                int logicalScreenWidth = multi ? loader.logicalScreenWidth
430:                        : firstImage.width;
431:                int logicalScreenHeight = multi ? loader.logicalScreenHeight
432:                        : firstImage.height;
433:                int backgroundPixel = loader.backgroundPixel;
434:                int depth = firstImage.depth;
435:                PaletteData palette = firstImage.palette;
436:                RGB[] colors = palette.getRGBs();
437:                short globalTable = 1;
438:
439:                /* Step 2: Check for validity and global/local color map. */
440:                if (!(depth == 1 || depth == 4 || depth == 8)) {
441:                    SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
442:                }
443:                for (int i = 0; i < frameCount; i++) {
444:                    if (data[i].palette.isDirect) {
445:                        SWT.error(SWT.ERROR_INVALID_IMAGE);
446:                    }
447:                    if (multi) {
448:                        if (!(data[i].height <= logicalScreenHeight
449:                                && data[i].width <= logicalScreenWidth && data[i].depth == depth)) {
450:                            SWT.error(SWT.ERROR_INVALID_IMAGE);
451:                        }
452:                        if (globalTable == 1) {
453:                            RGB rgbs[] = data[i].palette.getRGBs();
454:                            if (rgbs.length != colors.length) {
455:                                globalTable = 0;
456:                            } else {
457:                                for (int j = 0; j < colors.length; j++) {
458:                                    if (!(rgbs[j].red == colors[j].red
459:                                            && rgbs[j].green == colors[j].green && rgbs[j].blue == colors[j].blue))
460:                                        globalTable = 0;
461:                                }
462:                            }
463:                        }
464:                    }
465:                }
466:
467:                try {
468:                    /* Step 3: Write the GIF89a Header and Logical Screen Descriptor. */
469:                    outputStream.write(GIF89a);
470:                    int bitField = globalTable * 128 + (depth - 1) * 16 + depth
471:                            - 1;
472:                    outputStream.writeShort((short) logicalScreenWidth);
473:                    outputStream.writeShort((short) logicalScreenHeight);
474:                    outputStream.write(bitField);
475:                    outputStream.write(backgroundPixel);
476:                    outputStream.write(0); // Aspect ratio is 1:1
477:                } catch (IOException e) {
478:                    SWT.error(SWT.ERROR_IO, e);
479:                }
480:
481:                /* Step 4: Write Global Color Table if applicable. */
482:                if (globalTable == 1) {
483:                    writePalette(palette, depth);
484:                }
485:
486:                /* Step 5: Write Application Extension if applicable. */
487:                if (multi) {
488:                    int repeatCount = loader.repeatCount;
489:                    try {
490:                        outputStream.write(GIF_EXTENSION_BLOCK_ID);
491:                        outputStream.write(GIF_APPLICATION_EXTENSION_BLOCK_ID);
492:                        outputStream.write(NETSCAPE2_0.length);
493:                        outputStream.write(NETSCAPE2_0);
494:                        outputStream.write(3); // Three bytes follow
495:                        outputStream.write(1); // Extension type
496:                        outputStream.writeShort((short) repeatCount);
497:                        outputStream.write(0); // Block terminator
498:                    } catch (IOException e) {
499:                        SWT.error(SWT.ERROR_IO, e);
500:                    }
501:                }
502:
503:                for (int frame = 0; frame < frameCount; frame++) {
504:
505:                    /* Step 6: Write Graphics Control Block for each frame if applicable. */
506:                    if (multi || data[frame].transparentPixel != -1) {
507:                        writeGraphicsControlBlock(data[frame]);
508:                    }
509:
510:                    /* Step 7: Write Image Header for each frame. */
511:                    int x = data[frame].x;
512:                    int y = data[frame].y;
513:                    int width = data[frame].width;
514:                    int height = data[frame].height;
515:                    try {
516:                        outputStream.write(GIF_IMAGE_BLOCK_ID);
517:                        byte[] block = new byte[9];
518:                        block[0] = (byte) (x & 0xFF);
519:                        block[1] = (byte) ((x >> 8) & 0xFF);
520:                        block[2] = (byte) (y & 0xFF);
521:                        block[3] = (byte) ((y >> 8) & 0xFF);
522:                        block[4] = (byte) (width & 0xFF);
523:                        block[5] = (byte) ((width >> 8) & 0xFF);
524:                        block[6] = (byte) (height & 0xFF);
525:                        block[7] = (byte) ((height >> 8) & 0xFF);
526:                        block[8] = (byte) (globalTable == 0 ? (depth - 1) | 0x80
527:                                : 0x00);
528:                        outputStream.write(block);
529:                    } catch (IOException e) {
530:                        SWT.error(SWT.ERROR_IO, e);
531:                    }
532:
533:                    /* Step 8: Write Local Color Table for each frame if applicable. */
534:                    if (globalTable == 0) {
535:                        writePalette(data[frame].palette, depth);
536:                    }
537:
538:                    /* Step 9: Write the actual data for each frame. */
539:                    try {
540:                        outputStream.write(depth); // Minimum LZW Code size
541:                    } catch (IOException e) {
542:                        SWT.error(SWT.ERROR_IO, e);
543:                    }
544:                    new LZWCodec().encode(outputStream, data[frame]);
545:                }
546:
547:                /* Step 10: Write GIF terminator. */
548:                try {
549:                    outputStream.write(0x3B);
550:                } catch (IOException e) {
551:                    SWT.error(SWT.ERROR_IO, e);
552:                }
553:            }
554:
555:            /**
556:             * Write out a GraphicsControlBlock to describe
557:             * the specified device independent image.
558:             */
559:            void writeGraphicsControlBlock(ImageData image) {
560:                try {
561:                    outputStream.write(GIF_EXTENSION_BLOCK_ID);
562:                    outputStream.write(GIF_GRAPHICS_CONTROL_BLOCK_ID);
563:                    byte[] gcBlock = new byte[4];
564:                    gcBlock[0] = 0;
565:                    gcBlock[1] = 0;
566:                    gcBlock[2] = 0;
567:                    gcBlock[3] = 0;
568:                    if (image.transparentPixel != -1) {
569:                        gcBlock[0] = (byte) 0x01;
570:                        gcBlock[3] = (byte) image.transparentPixel;
571:                    }
572:                    if (image.disposalMethod != 0) {
573:                        gcBlock[0] |= (byte) ((image.disposalMethod & 0x07) << 2);
574:                    }
575:                    if (image.delayTime != 0) {
576:                        gcBlock[1] = (byte) (image.delayTime & 0xFF);
577:                        gcBlock[2] = (byte) ((image.delayTime >> 8) & 0xFF);
578:                    }
579:                    outputStream.write((byte) gcBlock.length);
580:                    outputStream.write(gcBlock);
581:                    outputStream.write(0); // Block terminator
582:                } catch (IOException e) {
583:                    SWT.error(SWT.ERROR_IO, e);
584:                }
585:            }
586:
587:            /**
588:             * Write the specified palette to the output stream.
589:             */
590:            void writePalette(PaletteData palette, int depth) {
591:                byte[] bytes = new byte[(1 << depth) * 3];
592:                int offset = 0;
593:                for (int i = 0; i < palette.colors.length; i++) {
594:                    RGB color = palette.colors[i];
595:                    bytes[offset] = (byte) color.red;
596:                    bytes[offset + 1] = (byte) color.green;
597:                    bytes[offset + 2] = (byte) color.blue;
598:                    offset += 3;
599:                }
600:                try {
601:                    outputStream.write(bytes);
602:                } catch (IOException e) {
603:                    SWT.error(SWT.ERROR_IO, e);
604:                }
605:            }
606:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.