Source Code Cross Referenced for XTIFFImageEncoder.java in  » GIS » openjump » org » libtiff » jai » codecimpl » 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 » GIS » openjump » org.libtiff.jai.codecimpl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.libtiff.jai.codecimpl;
002:
003:        /*
004:         * XTIFF: eXtensible TIFF libraries for JAI.
005:         * 
006:         * The contents of this file are subject to the JAVA ADVANCED IMAGING SAMPLE
007:         * INPUT-OUTPUT CODECS AND WIDGET HANDLING SOURCE CODE License Version 1.0 (the
008:         * "License"); You may not use this file except in compliance with the License.
009:         * You may obtain a copy of the License at
010:         * http://www.sun.com/software/imaging/JAI/index.html
011:         * 
012:         * Software distributed under the License is distributed on an "AS IS" basis,
013:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
014:         * the specific language governing rights and limitations under the License.
015:         * 
016:         * The Original Code is JAVA ADVANCED IMAGING SAMPLE INPUT-OUTPUT CODECS AND
017:         * WIDGET HANDLING SOURCE CODE. The Initial Developer of the Original Code is:
018:         * Sun Microsystems, Inc.. Portions created by: Niles Ritter are Copyright (C):
019:         * Niles Ritter, GeoTIFF.org, 1999,2000. All Rights Reserved. Contributor(s):
020:         * Niles Ritter
021:         */
022:
023:        import java.awt.Rectangle;
024:        import java.awt.color.ColorSpace;
025:        import java.awt.image.ColorModel;
026:        import java.awt.image.DataBuffer;
027:        import java.awt.image.IndexColorModel;
028:        import java.awt.image.RenderedImage;
029:        import java.awt.image.SampleModel;
030:        import java.io.File;
031:        import java.io.FileInputStream;
032:        import java.io.FileOutputStream;
033:        import java.io.IOException;
034:        import java.io.OutputStream;
035:        import java.util.Vector;
036:
037:        import org.libtiff.jai.codec.XTIFF;
038:        import org.libtiff.jai.codec.XTIFFDirectory;
039:        import org.libtiff.jai.codec.XTIFFEncodeParam;
040:        import org.libtiff.jai.codec.XTIFFField;
041:        import org.libtiff.jai.codec.XTIFFTileCodec;
042:        import org.libtiff.jai.util.JaiI18N;
043:
044:        import com.sun.media.jai.codec.ImageEncodeParam;
045:        import com.sun.media.jai.codec.TIFFEncodeParam;
046:        import com.sun.media.jai.codec.TIFFField;
047:        import com.sun.media.jai.codecimpl.TIFFImageDecoder;
048:        import com.sun.media.jai.codecimpl.TIFFImageEncoder;
049:
050:        /**
051:         * A baseline TIFF writer. The writer outputs TIFF images in either Bilevel,
052:         * Greyscale, Palette color or Full Color modes.
053:         *  
054:         */
055:        public class XTIFFImageEncoder extends TIFFImageEncoder {
056:
057:            long firstIFDOffset = 0;
058:            XTIFFDirectory directory;
059:            XTIFFEncodeParam tparam;
060:            int width;
061:            int length;
062:            SampleModel sampleModel;
063:            int numBands;
064:            int sampleSize[];
065:            int dataType;
066:            boolean dataTypeIsShort;
067:            ColorModel colorModel;
068:            int numTiles;
069:            int compression;
070:            boolean isTiled;
071:            long tileLength;
072:            long tileWidth;
073:            byte[] bpixels = null;
074:            long stripTileByteCounts[];
075:            long stripTileOffsets[];
076:            long currentOffset = 0;
077:
078:            // Image Types
079:            public static final int XTIFF_BILEVEL_WHITE_IS_ZERO = 0;
080:            public static final int XTIFF_BILEVEL_BLACK_IS_ZERO = 1;
081:            public static final int XTIFF_PALETTE = 2;
082:            public static final int XTIFF_FULLCOLOR = 3;
083:            public static final int XTIFF_GREYSCALE = 4;
084:
085:            /**
086:             * Standard constructor
087:             */
088:            public XTIFFImageEncoder(OutputStream output, ImageEncodeParam param) {
089:                super (output, param);
090:                if (this .param == null || !(param instanceof  XTIFFEncodeParam)) {
091:                    this .param = new XTIFFEncodeParam((TIFFEncodeParam) param);
092:                }
093:                tparam = (XTIFFEncodeParam) this .param;
094:                directory = tparam.getDirectory();
095:            }
096:
097:            private File createTemp() throws IOException {
098:                String tmpdir = System.getProperty("tiff.io.tmpdir");
099:                File file = null;
100:                if (tmpdir != null)
101:                    file = File.createTempFile("libtiff.jai.", ".dat",
102:                            new File(tmpdir));
103:                else
104:                    file = File.createTempFile("libtiff.jai.", ".dat");
105:                file.deleteOnExit();
106:                return file;
107:            }
108:
109:            private void copyImageData(File tmp, OutputStream out, int total)
110:                    throws IOException {
111:                int bufsize = 1024;
112:                int bytes = 0;
113:                byte[] buf = new byte[bufsize];
114:                FileInputStream in = new FileInputStream(tmp);
115:                do {
116:                    bytes = in.read(buf);
117:                    out.write(buf, 0, bytes);
118:                    total -= bytes;
119:                } while (total > 0);
120:                in.close();
121:            }
122:
123:            /**
124:             * Encodes a RenderedImage and writes the output to the OutputStream
125:             * associated with this ImageEncoder.
126:             */
127:            public void encode(RenderedImage im) throws IOException {
128:
129:                // Set comp into directory
130:                compression = tparam.getCompression();
131:
132:                // see if tiled
133:                isTiled = ((TIFFEncodeParam) param).getWriteTiled();
134:
135:                // Setup Directory fields.
136:                getImageFields(im);
137:
138:                if (compression == XTIFF.COMPRESSION_NONE) {
139:                    computeIFDOffset();
140:                    writeFileHeader(firstIFDOffset);
141:                    currentOffset = 8;
142:                    writeImageData(im, output);
143:                    writeDirectory(directory.getFields(), 0);
144:                } else {
145:                    // We have to write compressed data out to
146:                    // a temp file to compute the IFD offset.
147:                    // The only alternative is to compress the
148:                    // data twice, which is just about as bad.
149:                    currentOffset = 8;
150:                    File tmp = null;
151:                    try {
152:                        tmp = createTemp();
153:                        OutputStream tmpOut = new FileOutputStream(tmp);
154:                        int total = writeImageData(im, tmpOut);
155:                        tmpOut.close();
156:                        writeFileHeader(currentOffset + currentOffset % 2);
157:                        copyImageData(tmp, output, total);
158:                        writeDirectory(directory.getFields(), 0);
159:                    } finally {
160:                        if (tmp != null)
161:                            tmp.delete();
162:                    }
163:                }
164:            }
165:
166:            /**
167:             * Precomputes the IFD Offset for uncompressed data.
168:             */
169:            private void computeIFDOffset() {
170:
171:                long bytesPerRow = (long) Math.ceil((sampleSize[0] / 8.0)
172:                        * tileWidth * numBands);
173:                long bytesPerTile = bytesPerRow * tileLength;
174:                long lastTile = bytesPerTile;
175:
176:                if (!isTiled) {
177:                    // Last strip may have lesser rows
178:                    long lastStripRows = length - (tileLength * (numTiles - 1));
179:                    lastTile = lastStripRows * bytesPerRow;
180:                }
181:
182:                long totalBytesOfData = bytesPerTile * (numTiles - 1)
183:                        + lastTile;
184:
185:                // File header always occupies 8 bytes and we write the image data
186:                // after that.
187:                firstIFDOffset = 8 + totalBytesOfData;
188:                // Must begin on a word boundary
189:                if ((firstIFDOffset % 2) != 0) {
190:                    firstIFDOffset++;
191:                }
192:            }
193:
194:            private void writeFileHeader(long firstIFDOffset)
195:                    throws IOException {
196:                // 8 byte image file header
197:
198:                // Byte order used within the file - Big Endian
199:                output.write('M');
200:                output.write('M');
201:
202:                // Magic value
203:                output.write(0);
204:                output.write(42);
205:
206:                // Offset in bytes of the first IFD, must begin on a word boundary
207:                writeLong(firstIFDOffset);
208:
209:            }
210:
211:            // method for adding tags that haven't been set by user
212:            private void addIfAbsent(int tag, int type, int count, Object obj) {
213:                if (directory.getField(tag) == null)
214:                    directory.addField(tag, type, count, obj);
215:            }
216:
217:            private void getImageFields(RenderedImage im)
218:            /* throws IOException */
219:            {
220:
221:                width = im.getWidth();
222:                length = im.getHeight(); //TIFF calls it length
223:
224:                sampleModel = im.getSampleModel();
225:                numBands = sampleModel.getNumBands();
226:                sampleSize = sampleModel.getSampleSize();
227:
228:                dataType = sampleModel.getDataType();
229:                if (dataType != DataBuffer.TYPE_BYTE
230:                        && dataType != DataBuffer.TYPE_SHORT
231:                        && dataType != DataBuffer.TYPE_USHORT) {
232:                    // Support only byte and (unsigned) short.
233:                    throw new Error(JaiI18N.getString("TIFFImageEncoder0"));
234:                }
235:
236:                dataTypeIsShort = dataType == DataBuffer.TYPE_SHORT
237:                        || dataType == DataBuffer.TYPE_USHORT;
238:
239:                colorModel = im.getColorModel();
240:                if (colorModel != null && colorModel instanceof  IndexColorModel
241:                        && dataTypeIsShort) {
242:                    // Don't support (unsigned) short palette-color images.
243:                    throw new Error(JaiI18N.getString("TIFFImageEncoder2"));
244:                }
245:                IndexColorModel icm = null;
246:                int sizeOfColormap = 0;
247:                char colormap[] = null;
248:
249:                // Basic fields - have to be in increasing numerical order BILEVEL
250:                // ImageWidth 256
251:                // ImageLength 257
252:                // BitsPerSample 258
253:                // Compression 259
254:                // PhotoMetricInterpretation 262
255:                // StripOffsets 273
256:                // RowsPerStrip 278
257:                // StripByteCounts 279
258:                // XResolution 282
259:                // YResolution 283
260:                // ResolutionUnit 296
261:
262:                int photometricInterpretation = XTIFF.PHOTOMETRIC_RGB;
263:                int imageType = XTIFF_FULLCOLOR;
264:
265:                // IMAGE TYPES POSSIBLE
266:
267:                // Bilevel
268:                // BitsPerSample = 1
269:                // Compression = 1, 2, or 32773
270:                // PhotometricInterpretation either 0 or 1
271:
272:                // Greyscale
273:                // BitsPerSample = 4 or 8
274:                // Compression = 1, 32773
275:                // PhotometricInterpretation either 0 or 1
276:
277:                // Palette
278:                // ColorMap 320
279:                // BitsPerSample = 4 or 8
280:                // PhotometrciInterpretation = 3
281:
282:                // Full color
283:                // BitsPerSample = 8, 8, 8
284:                // SamplesPerPixel = 3 or more 277
285:                // Compression = 1, 32773
286:                // PhotometricInterpretation = 2
287:
288:                if (colorModel instanceof  IndexColorModel) {
289:
290:                    icm = (IndexColorModel) colorModel;
291:                    int mapSize = icm.getMapSize();
292:
293:                    if (sampleSize[0] == 1) {
294:                        // Bilevel image
295:
296:                        if (mapSize != 2) {
297:                            throw new IllegalArgumentException(JaiI18N
298:                                    .getString("TIFFImageEncoder1"));
299:                        }
300:
301:                        byte r[] = new byte[mapSize];
302:                        icm.getReds(r);
303:                        byte g[] = new byte[mapSize];
304:                        icm.getGreens(g);
305:                        byte b[] = new byte[mapSize];
306:                        icm.getBlues(b);
307:
308:                        if ((r[0] & 0xff) == 0 && (r[1] & 0xff) == 255
309:                                && (g[0] & 0xff) == 0 && (g[1] & 0xff) == 255
310:                                && (b[0] & 0xff) == 0 && (b[1] & 0xff) == 255) {
311:
312:                            imageType = XTIFF_BILEVEL_BLACK_IS_ZERO;
313:
314:                        } else if ((r[0] & 0xff) == 255 && (r[1] & 0xff) == 0
315:                                && (g[0] & 0xff) == 255 && (g[1] & 0xff) == 0
316:                                && (b[0] & 0xff) == 255 && (b[1] & 0xff) == 0) {
317:
318:                            imageType = XTIFF_BILEVEL_WHITE_IS_ZERO;
319:
320:                        } else {
321:                            imageType = XTIFF_PALETTE;
322:                        }
323:
324:                    } else {
325:                        // Palette color image.
326:                        imageType = XTIFF_PALETTE;
327:                    }
328:                } else {
329:
330:                    // If it is not an IndexColorModel, it can either be a greyscale
331:                    // image or a full color image
332:
333:                    if ((colorModel == null || colorModel.getColorSpace()
334:                            .getType() == ColorSpace.TYPE_GRAY)
335:                            && numBands == 1) {
336:                        // Greyscale image
337:                        imageType = XTIFF_GREYSCALE;
338:                    } else {
339:                        // Full color image
340:                        imageType = XTIFF_FULLCOLOR;
341:                    }
342:                }
343:
344:                switch (imageType) {
345:
346:                case XTIFF_BILEVEL_WHITE_IS_ZERO:
347:                    photometricInterpretation = XTIFF.PHOTOMETRIC_WHITE_IS_ZERO;
348:                    break;
349:
350:                case XTIFF_BILEVEL_BLACK_IS_ZERO:
351:                    photometricInterpretation = XTIFF.PHOTOMETRIC_BLACK_IS_ZERO;
352:                    break;
353:
354:                case XTIFF_GREYSCALE:
355:                    // Since the CS_GRAY colorspace is always of type black_is_zero
356:                    photometricInterpretation = XTIFF.PHOTOMETRIC_BLACK_IS_ZERO;
357:                    break;
358:
359:                case XTIFF_PALETTE:
360:                    photometricInterpretation = XTIFF.PHOTOMETRIC_PALETTE;
361:
362:                    icm = (IndexColorModel) colorModel;
363:                    sizeOfColormap = icm.getMapSize();
364:
365:                    byte r[] = new byte[sizeOfColormap];
366:                    icm.getReds(r);
367:                    byte g[] = new byte[sizeOfColormap];
368:                    icm.getGreens(g);
369:                    byte b[] = new byte[sizeOfColormap];
370:                    icm.getBlues(b);
371:
372:                    int redIndex = 0,
373:                    greenIndex = sizeOfColormap;
374:                    int blueIndex = 2 * sizeOfColormap;
375:                    colormap = new char[sizeOfColormap * 3];
376:                    for (int i = 0; i < sizeOfColormap; i++) {
377:                        colormap[redIndex++] = (char) (r[i] << 8);
378:                        colormap[greenIndex++] = (char) (g[i] << 8);
379:                        colormap[blueIndex++] = (char) (b[i] << 8);
380:                    }
381:
382:                    sizeOfColormap *= 3;
383:
384:                    // Since we will be writing the colormap field.
385:                    break;
386:
387:                case XTIFF_FULLCOLOR:
388:                    photometricInterpretation = XTIFF.PHOTOMETRIC_RGB;
389:                    break;
390:
391:                }
392:
393:                if (isTiled) {
394:                    tileWidth = 16L;
395:                    tileLength = 16L;
396:                    XTIFFField fld = directory
397:                            .getField(XTIFF.TIFFTAG_TILE_WIDTH);
398:                    if (fld != null)
399:                        tileWidth = (int) fld.getAsLong(0);
400:                    fld = directory.getField(XTIFF.TIFFTAG_TILE_LENGTH);
401:                    if (fld != null)
402:                        tileLength = (int) fld.getAsLong(0);
403:                } else {
404:                    // Default strip is 8 rows.
405:                    tileLength = 8L;
406:                    // tileWidth of strip is width
407:
408:                    tileWidth = width;
409:                    XTIFFField fld = directory
410:                            .getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP);
411:                    if (fld != null)
412:                        tileLength = fld.getAsLong(0);
413:                }
414:
415:                numTiles = (int) Math.ceil((double) length
416:                        / (double) tileLength)
417:                        * (int) Math.ceil((double) width / (double) tileWidth);
418:
419:                stripTileByteCounts = new long[numTiles];
420:                stripTileOffsets = new long[numTiles];
421:
422:                // Image Width
423:                directory
424:                        .addField(XTIFF.TIFFTAG_IMAGE_WIDTH,
425:                                TIFFField.TIFF_LONG, 1,
426:                                (Object) (new long[] { width }));
427:
428:                // Image Length
429:                directory.addField(XTIFF.TIFFTAG_IMAGE_LENGTH,
430:                        TIFFField.TIFF_LONG, 1, new long[] { length });
431:
432:                directory.addField(XTIFF.TIFFTAG_BITS_PER_SAMPLE,
433:                        TIFFField.TIFF_SHORT, numBands,
434:                        convertToChars(sampleSize));
435:
436:                directory.addField(XTIFF.TIFFTAG_COMPRESSION,
437:                        TIFFField.TIFF_SHORT, 1,
438:                        new char[] { (char) compression });
439:
440:                directory.addField(XTIFF.TIFFTAG_PHOTOMETRIC_INTERPRETATION,
441:                        TIFFField.TIFF_SHORT, 1,
442:                        new char[] { (char) photometricInterpretation });
443:
444:                directory
445:                        .addField(XTIFF.TIFFTAG_SAMPLES_PER_PIXEL,
446:                                TIFFField.TIFF_SHORT, 1,
447:                                new char[] { (char) numBands });
448:
449:                if (isTiled) {
450:                    directory.addField(XTIFF.TIFFTAG_TILE_WIDTH,
451:                            TIFFField.TIFF_LONG, 1, new long[] { tileWidth });
452:
453:                    directory.addField(XTIFF.TIFFTAG_TILE_LENGTH,
454:                            TIFFField.TIFF_LONG, 1, new long[] { tileLength });
455:
456:                    directory.addField(XTIFF.TIFFTAG_TILE_OFFSETS,
457:                            TIFFField.TIFF_LONG, numTiles, stripTileOffsets);
458:
459:                    directory.addField(XTIFF.TIFFTAG_TILE_BYTE_COUNTS,
460:                            TIFFField.TIFF_LONG, numTiles, stripTileByteCounts);
461:                } else {
462:                    directory.addField(XTIFF.TIFFTAG_STRIP_OFFSETS,
463:                            TIFFField.TIFF_LONG, numTiles, stripTileOffsets);
464:
465:                    directory.addField(XTIFF.TIFFTAG_ROWS_PER_STRIP,
466:                            TIFFField.TIFF_LONG, 1, new long[] { tileLength });
467:
468:                    directory.addField(XTIFF.TIFFTAG_STRIP_BYTE_COUNTS,
469:                            TIFFField.TIFF_LONG, numTiles, stripTileByteCounts);
470:                }
471:
472:                addIfAbsent(XTIFF.TIFFTAG_X_RESOLUTION,
473:                        TIFFField.TIFF_RATIONAL, 1, new long[][] { { 72, 1 } });
474:
475:                addIfAbsent(XTIFF.TIFFTAG_Y_RESOLUTION,
476:                        TIFFField.TIFF_RATIONAL, 1, new long[][] { { 72, 1 } });
477:
478:                addIfAbsent(XTIFF.TIFFTAG_RESOLUTION_UNIT,
479:                        TIFFField.TIFF_SHORT, 1, new char[] { (char) 2 });
480:
481:                if (colormap != null) {
482:                    directory.addField(XTIFF.TIFFTAG_COLORMAP,
483:                            TIFFField.TIFF_SHORT, sizeOfColormap, colormap);
484:                }
485:
486:                // Data Sample Format Extension fields.
487:                if (dataTypeIsShort) {
488:                    // SampleFormat
489:                    int[] sampleFormat = new int[numBands];
490:                    sampleFormat[0] = dataType == DataBuffer.TYPE_USHORT ? 1
491:                            : 2;
492:                    for (int b = 1; b < numBands; b++) {
493:                        sampleFormat[b] = sampleFormat[0];
494:                    }
495:                    directory.addField(XTIFF.TIFFTAG_SAMPLE_FORMAT,
496:                            TIFFField.TIFF_SHORT, numBands,
497:                            convertToChars(sampleFormat));
498:
499:                    // SMinSampleValue: set to data type minimum.
500:                    int[] minValue = new int[numBands];
501:                    minValue[0] = dataType == DataBuffer.TYPE_USHORT ? 0
502:                            : Short.MIN_VALUE;
503:                    for (int b = 1; b < numBands; b++) {
504:                        minValue[b] = minValue[0];
505:                    }
506:                    directory.addField(XTIFF.TIFFTAG_S_MIN_SAMPLE_VALUE,
507:                            TIFFField.TIFF_SHORT, numBands,
508:                            convertToChars(minValue));
509:
510:                    // SMaxSampleValue: set to data type maximum.
511:                    int[] maxValue = new int[numBands];
512:                    maxValue[0] = dataType == DataBuffer.TYPE_USHORT ? 65535
513:                            : Short.MAX_VALUE;
514:                    for (int b = 1; b < numBands; b++) {
515:                        maxValue[b] = maxValue[0];
516:                    }
517:                    directory.addField(XTIFF.TIFFTAG_S_MAX_SAMPLE_VALUE,
518:                            TIFFField.TIFF_SHORT, numBands,
519:                            convertToChars(maxValue));
520:                }
521:
522:            }
523:
524:            private char[] convertToChars(int[] shorts) {
525:                char[] out = new char[shorts.length];
526:                for (int i = 0; i < shorts.length; i++)
527:                    out[i] = (char) shorts[i];
528:                return out;
529:            }
530:
531:            protected int getSampleSize() {
532:                if (dataType == DataBuffer.TYPE_BYTE)
533:                    return 1;
534:                else if (dataTypeIsShort)
535:                    return 2;
536:                return 1; // what should go here?
537:            }
538:
539:            protected int getTileSize() {
540:                return (int) (tileLength * tileWidth * numBands);
541:            }
542:
543:            private int writeImageData(RenderedImage im, OutputStream out)
544:                    throws IOException {
545:                int total = 0;
546:
547:                // Get the encoder
548:                XTIFFTileCodec codec = directory.createTileCodec(tparam);
549:
550:                // Create a buffer to hold the data
551:                // to be written to the file, so we can use array writes.
552:                int tsize = codec.getCompressedTileSize(im);
553:                bpixels = new byte[tsize];
554:
555:                // Encode one tile at a time
556:                Rectangle rect = new Rectangle();
557:                float minX = (float) im.getMinX();
558:                float minY = (float) im.getMinY();
559:                float rows = (float) tileLength;
560:                float cols = (float) tileWidth;
561:                int i = 0;
562:                for (int row = 0; row < length; row += tileLength) {
563:                    for (int col = 0; col < width; col += tileWidth) {
564:                        if (!isTiled)
565:                            rows = Math.min(tileLength, length - row);
566:                        rect.setRect(minX + col, minY + row, cols, rows);
567:                        int tileSize = codec.encode(im, rect, bpixels);
568:                        out.write(bpixels, 0, tileSize);
569:                        stripTileOffsets[i] = currentOffset;
570:                        stripTileByteCounts[i++] = tileSize;
571:                        currentOffset += tileSize;
572:                        total += tileSize;
573:                    }
574:                }
575:                return total;
576:            }
577:
578:            private void writeDirectory(XTIFFField fields[], int nextIFDOffset)
579:                    throws IOException {
580:
581:                if (currentOffset % 2 == 1) {
582:                    output.write(0);
583:                    currentOffset++;
584:                }
585:
586:                // 2 byte count of number of directory entries (fields)
587:                int numEntries = fields.length;
588:
589:                long offsetBeyondIFD = currentOffset + 12 * numEntries + 4 + 2;
590:                Vector tooBig = new Vector();
591:
592:                XTIFFField field;
593:                int tag;
594:                int type;
595:                int count;
596:
597:                // Write number of fields in the IFD
598:                writeUnsignedShort(numEntries);
599:
600:                for (int i = 0; i < numEntries; i++) {
601:
602:                    field = fields[i];
603:
604:                    // 12 byte field entry TIFFField
605:
606:                    // byte 0-1 Tag that identifies a field
607:                    tag = field.getTag();
608:                    writeUnsignedShort(tag);
609:
610:                    // byte 2-3 The field type
611:                    type = field.getType();
612:                    writeUnsignedShort(type);
613:
614:                    // bytes 4-7 the number of values of the indicated type
615:                    count = field.getCount();
616:                    writeLong(count);
617:
618:                    // bytes 8 - 11 the value offset
619:                    if (count * sizeOfType[type] > 4) {
620:
621:                        // We need an offset as data won't fit into 4 bytes
622:                        writeLong(offsetBeyondIFD);
623:                        offsetBeyondIFD += (count * sizeOfType[type]);
624:                        tooBig.add(new Integer(i));
625:
626:                    } else {
627:
628:                        writeValuesAsFourBytes(field);
629:                    }
630:
631:                }
632:
633:                // Address of next IFD
634:                writeLong(nextIFDOffset);
635:
636:                int index;
637:                // Write the tag values that did not fit into 4 bytes
638:
639:                for (int i = 0; i < tooBig.size(); i++) {
640:                    index = ((Integer) tooBig.elementAt(i)).intValue();
641:                    writeValues(fields[index]);
642:                }
643:            }
644:
645:            private static final int[] sizeOfType = { 0, //  0 = n/a
646:                    1, //  1 = byte
647:                    1, //  2 = ascii
648:                    2, //  3 = short
649:                    4, //  4 = long
650:                    8, //  5 = rational
651:                    1, //  6 = sbyte
652:                    1, //  7 = undefined
653:                    2, //  8 = sshort
654:                    4, //  9 = slong
655:                    8, // 10 = srational
656:                    4, // 11 = float
657:                    8 // 12 = double
658:            };
659:
660:            private void writeValuesAsFourBytes(XTIFFField field)
661:                    throws IOException {
662:
663:                int dataType = field.getType();
664:                int count = field.getCount();
665:
666:                switch (dataType) {
667:
668:                // unsigned 8 bits
669:                case TIFFField.TIFF_BYTE:
670:                    byte bytes[] = field.getAsBytes();
671:
672:                    for (int i = 0; i < count; i++) {
673:                        output.write(bytes[i]);
674:                    }
675:
676:                    for (int i = 0; i < (4 - count); i++) {
677:                        output.write(0);
678:                    }
679:
680:                    break;
681:
682:                // unsigned 16 bits
683:                case TIFFField.TIFF_SHORT:
684:                    char shorts[] = field.getAsChars();
685:
686:                    for (int i = 0; i < count; i++) {
687:                        writeUnsignedShort((int) shorts[i]);
688:                    }
689:
690:                    for (int i = 0; i < (2 - count); i++) {
691:                        writeUnsignedShort(0);
692:                    }
693:
694:                    break;
695:
696:                // unsigned 32 bits
697:                case TIFFField.TIFF_LONG:
698:                    long longs[] = field.getAsLongs();
699:
700:                    for (int i = 0; i < count; i++) {
701:                        writeLong(longs[i]);
702:                    }
703:                    break;
704:                }
705:
706:            }
707:
708:            private void writeValues(XTIFFField field) throws IOException {
709:
710:                int dataType = field.getType();
711:                int count = field.getCount();
712:
713:                switch (dataType) {
714:
715:                // character data with NULL termination
716:                case TIFFField.TIFF_ASCII:
717:                    String strings[] = field.getAsStrings();
718:                    for (int i = 0; i < strings.length; i++) {
719:                        byte bytes[] = strings[i].getBytes();
720:                        for (int j = 0; j < bytes.length; j++) {
721:                            output.write(bytes[j]);
722:                        }
723:                        if ((i + 1) < count)
724:                            output.write(0);
725:                    }
726:                    break;
727:
728:                // unsigned 8 bits
729:                case TIFFField.TIFF_BYTE:
730:                    byte bytes[] = field.getAsBytes();
731:                    for (int i = 0; i < count; i++) {
732:                        output.write(bytes[i]);
733:                    }
734:                    break;
735:
736:                // unsigned 16 bits
737:                case TIFFField.TIFF_SHORT:
738:                    char shorts[] = field.getAsChars();
739:                    for (int i = 0; i < count; i++) {
740:                        writeUnsignedShort((int) shorts[i]);
741:                    }
742:                    break;
743:
744:                // unsigned 32 bits
745:                case TIFFField.TIFF_LONG:
746:                    long longs[] = field.getAsLongs();
747:                    for (int i = 0; i < count; i++) {
748:                        writeLong(longs[i]);
749:                    }
750:                    break;
751:
752:                // IEEE 8-byte double
753:                case TIFFField.TIFF_DOUBLE:
754:                    double doubles[] = field.getAsDoubles();
755:                    for (int i = 0; i < count; i++) {
756:                        writeDouble(doubles[i]);
757:                    }
758:                    break;
759:
760:                case TIFFField.TIFF_RATIONAL:
761:                    long rationals[][] = field.getAsRationals();
762:                    for (int i = 0; i < count; i++) {
763:                        writeLong(rationals[i][0]);
764:                        writeLong(rationals[i][1]);
765:                    }
766:                    break;
767:
768:                }
769:
770:            }
771:
772:            // Here s is never expected to have value greater than what can be
773:            // stored in 2 bytes.
774:            private void writeUnsignedShort(int s) throws IOException {
775:                output.write((s & 0xff00) >>> 8);
776:                output.write(s & 0x00ff);
777:            }
778:
779:            private void writeLong(long l) throws IOException {
780:                output.write((int) ((l & 0xff000000) >>> 24));
781:                output.write((int) ((l & 0x00ff0000) >>> 16));
782:                output.write((int) ((l & 0x0000ff00) >>> 8));
783:                output.write(((int) l & 0x000000ff));
784:            }
785:
786:            // write 8-byte IEEE double
787:            private void writeDouble(double d) throws IOException {
788:                long lval = Double.doubleToLongBits(d);
789:                writeLong(lval >>> 32);
790:                writeLong((lval & 0xffffffff));
791:            }
792:
793:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.