Source Code Cross Referenced for ImageInfo.java in  » J2EE » Pustefix » de » schlund » pfixxml » 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 » J2EE » Pustefix » de.schlund.pfixxml 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * This file is part of PFIXCORE.
003:         *
004:         * PFIXCORE is free software; you can redistribute it and/or modify
005:         * it under the terms of the GNU Lesser General Public License as published by
006:         * the Free Software Foundation; either version 2 of the License, or
007:         * (at your option) any later version.
008:         *
009:         * PFIXCORE is distributed in the hope that it will be useful,
010:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012:         * GNU Lesser General Public License for more details.
013:         *
014:         * You should have received a copy of the GNU Lesser General Public License
015:         * along with PFIXCORE; if not, write to the Free Software
016:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
017:         *
018:         */
019:
020:        package de.schlund.pfixxml;
021:
022:        /*
023:         * 2002/04/16: Added packaged name for our purposes (jtl)
024:         *
025:         * ImageInfo.java
026:         *
027:         * Version 1.1.1
028:         *
029:         * A Java class to determine image width, height and color depth for
030:         * a number of image file formats.
031:         *
032:         * Written by Marco Schmidt <marcoschmidt@users.sourceforge.net>
033:         *
034:         * Contributed to the Public Domain.
035:         *
036:         * Last modification 2002-04-10
037:         */
038:
039:        import java.io.DataInput;
040:        import java.io.FileInputStream;
041:        import java.io.IOException;
042:        import java.io.InputStream;
043:
044:        /**
045:         * Get file format, image resolution, number of bits per pixel and optionally 
046:         * number of images from 
047:         * JPEG, GIF, BMP, PCX, PNG, IFF, RAS, PBM, PGM, PPM and PSD files 
048:         * (or input streams).
049:         * <p>
050:         * Use the class like this:
051:         * <pre>
052:         * ImageInfo ii = new ImageInfo();
053:         * ii.setInput(in); // in can be InputStream or RandomAccessFile
054:         * ii.setDetermineImageNumber(true); // default is false
055:         * if (!ii.check()) {
056:         *   System.err.println("Not a supported image file format.");
057:         * } else {
058:         *  System.out.println(ii.getFormatName() + ", " + ii.getMimeType() + 
059:         *   ", " + ii.getWidth() + " x " + ii.getHeight() + " pixels, " + 
060:         *   ii.getBitsPerPixel() + " bits per pixel, " + ii.getNumberOfImages() +
061:         *   " image(s).");
062:         * }
063:         * </pre>
064:         * You can also use this class as a command line program.
065:         * Call it with a number of image file names as parameters:
066:         * <pre>
067:         *   java ImageInfo *.jpg *.png *.gif
068:         * </pre>
069:         * or call it without parameters and pipe data to it:
070:         * <pre>
071:         *   cat image.jpg | java ImageInfo
072:         * </pre>
073:         * <p>
074:         * Known limitations:
075:         * <ul>
076:         * <li>When the determination of the number of images is turned off, GIF bits 
077:         *  per pixel are only read from the global header.
078:         *  For some GIFs, local palettes change this to a typically larger
079:         *  value. To be certain to get the correct color depth, call
080:         *  setDetermineImageNumber(true) before calling check().
081:         *  The complete scan over the GIF file will take additional time.</li>
082:         * <li>Transparency information is not included in the bits per pixel count.
083:         *  Actually, it was my decision not to include those bits, so it's a feature! ;-)</li>
084:         * </ul>
085:         * <p>
086:         * Requirements:
087:         * <ul>
088:         * <li>Java 1.1 or higher</li>
089:         * </ul>
090:         * <p>
091:         * The latest version can be found at <a href="http://www.geocities.com/marcoschmidt.geo/image-info.html">http://www.geocities.com/marcoschmidt.geo/image-info.html</a>.
092:         * <p>
093:         * Written by <a href="mailto:marcoschmidt@users.sourceforge.net">Marco Schmidt</a>.
094:         * <p>
095:         * This class is contributed to the Public Domain.
096:         * Use it at your own risk.
097:         * <p>
098:         * Last modification 2002-04-10.
099:         * <p>
100:         * History:
101:         * <ul>
102:         * <li><strong>2001-08-24</strong> Initial version.</li>
103:         * <li><strong>2001-10-13</strong> Added support for the file formats BMP and PCX.</li>
104:         * <li><strong>2001-10-16</strong> Fixed bug in read(int[], int, int) that returned
105:         * <li><strong>2002-01-22</strong> Added support for file formats Amiga IFF and Sun Raster (RAS).</li>
106:         * <li><strong>2002-01-24</strong> Added support for file formats Portable Bitmap / Graymap / Pixmap (PBM, PGM, PPM) and Adobe Photoshop (PSD).
107:         *   Added new method getMimeType() to return the MIME type associated with a particular file format.</li>
108:         * <li><strong>2002-03-15</strong> Added support to recognize number of images in file. Only works with GIF.
109:         *   Use {@link #setDetermineImageNumber} with <code>true</code> as argument to identify animated GIFs
110:         *   ({@link #getNumberOfImages()} will return a value larger than <code>1</code>).</li>
111:         * <li><strong>2002-04-10</strong> Fixed a bug in the feature 'determine number of images in animated GIF' introduced with version 1.1.
112:         *   Thanks to Marcelo P. Lima for sending in the bug report.</li>
113:         * </ul>
114:         */
115:        public class ImageInfo {
116:            /** Return value of {@link #getFormat()} for JPEG streams. */
117:            public static final int FORMAT_JPEG = 0;
118:            /** Return value of {@link #getFormat()} for GIF streams. */
119:            public static final int FORMAT_GIF = 1;
120:            /** Return value of {@link #getFormat()} for PNG streams. */
121:            public static final int FORMAT_PNG = 2;
122:            /** Return value of {@link #getFormat()} for BMP streams. */
123:            public static final int FORMAT_BMP = 3;
124:            /** Return value of {@link #getFormat()} for PCX streams. */
125:            public static final int FORMAT_PCX = 4;
126:            /** Return value of {@link #getFormat()} for IFF streams. */
127:            public static final int FORMAT_IFF = 5;
128:            /** Return value of {@link #getFormat()} for RAS streams. */
129:            public static final int FORMAT_RAS = 6;
130:            /** Return value of {@link #getFormat()} for PBM streams. */
131:            public static final int FORMAT_PBM = 7;
132:            /** Return value of {@link #getFormat()} for PBM streams. */
133:            public static final int FORMAT_PGM = 8;
134:            /** Return value of {@link #getFormat()} for PBM streams. */
135:            public static final int FORMAT_PPM = 9;
136:            /** Return value of {@link #getFormat()} for PBM streams. */
137:            public static final int FORMAT_PSD = 10;
138:            private static final String[] FORMAT_NAMES = { "JPEG", "GIF",
139:                    "PNG", "BMP", "PCX", "IFF", "RAS", "PBM", "PGM", "PPM",
140:                    "PSD" };
141:            private static final String[] MIME_TYPE_STRINGS = { "image/jpeg",
142:                    "image/gif", "image/png", "image/bmp", "image/pcx",
143:                    "image/iff", "image/ras", "image/x-portable-bitmap",
144:                    "image/x-portable-graymap", "image/x-portable-pixmap",
145:                    "image/psd" };
146:            private int width;
147:            private int height;
148:            private int bitsPerPixel;
149:            private int format;
150:            private InputStream in;
151:            private DataInput din;
152:            // private boolean collectComments;
153:            private boolean determineNumberOfImages;
154:            private int numberOfImages;
155:
156:            /**
157:             * Call this method after you have provided an input stream or file
158:             * using {@link #setInput(InputStream)} or {@link #setInput(DataInput)}.
159:             * If true is returned, the file format was known and you information
160:             * about its content can be retrieved using the various getXyz methods.
161:             * @return if information could be retrieved from input
162:             */
163:            public boolean check() {
164:                format = -1;
165:                width = -1;
166:                height = -1;
167:                bitsPerPixel = -1;
168:                numberOfImages = 1;
169:                try {
170:                    int b1 = read() & 0xff;
171:                    int b2 = read() & 0xff;
172:                    if (b1 == 0x47 && b2 == 0x49) {
173:                        return checkGif();
174:                    } else if (b1 == 0x89 && b2 == 0x50) {
175:                        return checkPng();
176:                    } else if (b1 == 0xff && b2 == 0xd8) {
177:                        return checkJpeg();
178:                    } else if (b1 == 0x42 && b2 == 0x4d) {
179:                        return checkBmp();
180:                    } else if (b1 == 0x0a && b2 < 0x06) {
181:                        return checkPcx();
182:                    } else if (b1 == 0x46 && b2 == 0x4f) {
183:                        return checkIff();
184:                    } else if (b1 == 0x59 && b2 == 0xa6) {
185:                        return checkRas();
186:                    } else if (b1 == 0x50 && b2 >= 0x31 && b2 <= 0x36) {
187:                        return checkPnm(b2 - '0');
188:                    } else if (b1 == 0x38 && b2 == 0x42) {
189:                        return checkPsd();
190:                    } else {
191:                        return false;
192:                    }
193:                } catch (IOException ioe) {
194:                    return false;
195:                }
196:            }
197:
198:            private boolean checkBmp() throws IOException {
199:                byte[] a = new byte[28];
200:                if (read(a) != a.length) {
201:                    return false;
202:                }
203:                width = getIntLittleEndian(a, 16);
204:                height = getIntLittleEndian(a, 20);
205:                bitsPerPixel = getShortLittleEndian(a, 26);
206:                if (width < 1 || height < 1) {
207:                    return false;
208:                }
209:                if (bitsPerPixel != 1 && bitsPerPixel != 4 && bitsPerPixel != 8
210:                        && bitsPerPixel != 16 && bitsPerPixel != 24
211:                        && bitsPerPixel != 32) {
212:                    return false;
213:                }
214:                format = FORMAT_BMP;
215:                return true;
216:            }
217:
218:            private boolean checkGif() throws IOException {
219:                final byte[] GIF_MAGIC_87A = { 0x46, 0x38, 0x37, 0x61 };
220:                final byte[] GIF_MAGIC_89A = { 0x46, 0x38, 0x39, 0x61 };
221:                byte[] a = new byte[11]; // 4 from the GIF signature + 7 from the global header
222:                if (read(a) != 11) {
223:                    return false;
224:                }
225:                if ((!equals(a, 0, GIF_MAGIC_89A, 0, 4))
226:                        && (!equals(a, 0, GIF_MAGIC_87A, 0, 4))) {
227:                    return false;
228:                }
229:                format = FORMAT_GIF;
230:                width = getShortLittleEndian(a, 4);
231:                height = getShortLittleEndian(a, 6);
232:                int flags = a[8] & 0xff;
233:                bitsPerPixel = ((flags >> 4) & 0x07) + 1;
234:                if (!determineNumberOfImages) {
235:                    return true;
236:                }
237:                // skip global color palette
238:                if ((flags & 0x80) != 0) {
239:                    int tableSize = (1 << ((flags & 7) + 1)) * 3;
240:                    skip(tableSize);
241:                }
242:                numberOfImages = 0;
243:                int blockType;
244:                do {
245:                    blockType = read();
246:                    switch (blockType) {
247:                    case (0x2c): // image separator
248:                    {
249:                        if (read(a, 0, 9) != 9) {
250:                            return false;
251:                        }
252:                        flags = a[8] & 0xff;
253:                        int localBitsPerPixel = (flags & 0x07) + 1;
254:                        if (localBitsPerPixel > bitsPerPixel) {
255:                            bitsPerPixel = localBitsPerPixel;
256:                        }
257:                        if ((flags & 0x80) != 0) {
258:                            skip((1 << localBitsPerPixel) * 3);
259:                        }
260:                        skip(1); // initial code length
261:                        int n;
262:                        do {
263:                            n = read();
264:                            if (n > 0) {
265:                                skip(n);
266:                            } else if (n == -1) {
267:                                return false;
268:                            }
269:                        } while (n > 0);
270:                        numberOfImages++;
271:                        break;
272:                    }
273:                    case (0x21): // extension
274:                    {
275:                        skip(1); // extension type
276:                        int n;
277:                        do {
278:                            n = read();
279:                            if (n > 0) {
280:                                skip(n);
281:                            } else if (n == -1) {
282:                                return false;
283:                            }
284:                        } while (n > 0);
285:                        break;
286:                    }
287:                    case (0x3b): // end of file
288:                    {
289:                        break;
290:                    }
291:                    default: {
292:                        return false;
293:                    }
294:                    }
295:                } while (blockType != 0x3b);
296:                return true;
297:            }
298:
299:            private boolean checkIff() throws IOException {
300:                byte[] a = new byte[10];
301:                // read remaining 2 bytes of file id, 4 bytes file size 
302:                // and 4 bytes IFF subformat
303:                if (read(a, 0, 10) != 10) {
304:                    return false;
305:                }
306:                final byte[] IFF_RM = { 0x52, 0x4d };
307:                if (!equals(a, 0, IFF_RM, 0, 2)) {
308:                    return false;
309:                }
310:                int type = getIntBigEndian(a, 6);
311:                if (type != 0x494c424d && // type must be ILBM...
312:                        type != 0x50424d20) { // ...or PBM
313:                    return false;
314:                }
315:                // loop chunks to find BMHD chunk
316:                do {
317:                    if (read(a, 0, 8) != 8) {
318:                        return false;
319:                    }
320:                    int chunkId = getIntBigEndian(a, 0);
321:                    int size = getIntBigEndian(a, 4);
322:                    if ((size & 1) == 1) {
323:                        size++;
324:                    }
325:                    if (chunkId == 0x424d4844) { // BMHD chunk
326:                        if (read(a, 0, 9) != 9) {
327:                            return false;
328:                        }
329:                        format = FORMAT_IFF;
330:                        width = getShortBigEndian(a, 0);
331:                        height = getShortBigEndian(a, 2);
332:                        bitsPerPixel = a[8] & 0xff;
333:                        return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel < 33);
334:                    } else {
335:                        skip(size);
336:                    }
337:                } while (true);
338:            }
339:
340:            private boolean checkJpeg() throws IOException {
341:                byte[] data = new byte[6];
342:                while (true) {
343:                    if (read(data, 0, 4) != 4) {
344:                        return false;
345:                    }
346:                    int marker = getShortBigEndian(data, 0);
347:                    int size = getShortBigEndian(data, 2);
348:                    if ((marker & 0xff00) != 0xff00) {
349:                        return false; // not a valid marker
350:                    }
351:                    if (marker >= 0xffc0 && marker <= 0xffcf
352:                            && marker != 0xffc4 && marker != 0xffc8) {
353:                        if (read(data) != 6) {
354:                            return false;
355:                        }
356:                        format = FORMAT_JPEG;
357:                        bitsPerPixel = (data[0] & 0xff) * (data[5] & 0xff);
358:                        width = getShortBigEndian(data, 3);
359:                        height = getShortBigEndian(data, 1);
360:                        return true;
361:                    } else {
362:                        skip(size - 2);
363:                    }
364:                }
365:            }
366:
367:            private boolean checkPcx() throws IOException {
368:                byte[] a = new byte[64];
369:                if (read(a) != a.length) {
370:                    return false;
371:                }
372:                if (a[0] != 1) { // encoding, 1=RLE is only valid value
373:                    return false;
374:                }
375:                // width / height
376:                int x1 = getShortLittleEndian(a, 2);
377:                int y1 = getShortLittleEndian(a, 4);
378:                int x2 = getShortLittleEndian(a, 6);
379:                int y2 = getShortLittleEndian(a, 8);
380:                if (x1 < 0 || x2 < x1 || y1 < 0 || y2 < y1) {
381:                    return false;
382:                }
383:                width = x2 - x1 + 1;
384:                height = y2 - y1 + 1;
385:                // color depth
386:                int bits = a[1];
387:                int planes = a[63];
388:                if (planes == 1
389:                        && (bits == 1 || bits == 2 || bits == 4 || bits == 8)) {
390:                    // paletted
391:                    bitsPerPixel = bits;
392:                } else if (planes == 3 && bits == 8) {
393:                    // RGB truecolor
394:                    bitsPerPixel = 24;
395:                } else {
396:                    return false;
397:                }
398:                format = FORMAT_PCX;
399:                return true;
400:            }
401:
402:            private boolean checkPng() throws IOException {
403:                final byte[] PNG_MAGIC = { 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
404:                byte[] a = new byte[24];
405:                if (read(a) != 24) {
406:                    return false;
407:                }
408:                if (!equals(a, 0, PNG_MAGIC, 0, 6)) {
409:                    return false;
410:                }
411:                format = FORMAT_PNG;
412:                width = getIntBigEndian(a, 14);
413:                height = getIntBigEndian(a, 18);
414:                bitsPerPixel = a[22] & 0xff;
415:                int colorType = a[23] & 0xff;
416:                if (colorType == 2 || colorType == 6) {
417:                    bitsPerPixel *= 3;
418:                }
419:                return true;
420:            }
421:
422:            private boolean checkPnm(int id) throws IOException {
423:                if (id < 1 || id > 6) {
424:                    return false;
425:                }
426:                final int[] PNM_FORMATS = { FORMAT_PBM, FORMAT_PGM, FORMAT_PPM };
427:                format = PNM_FORMATS[(id - 1) % 3];
428:                boolean hasPixelResolution = false;
429:                String s;
430:                while (true) {
431:                    s = readLine();
432:                    if (s != null) {
433:                        s = s.trim();
434:                    }
435:                    if (s == null || s.length() < 1) {
436:                        continue;
437:                    }
438:                    if (s.charAt(0) == '#') { // comment
439:                        continue;
440:                    }
441:                    if (!hasPixelResolution) { // split "343 966" into width=343, height=966
442:                        int spaceIndex = s.indexOf(' ');
443:                        if (spaceIndex == -1) {
444:                            return false;
445:                        }
446:                        String widthString = s.substring(0, spaceIndex);
447:                        spaceIndex = s.lastIndexOf(' ');
448:                        if (spaceIndex == -1) {
449:                            return false;
450:                        }
451:                        String heightString = s.substring(spaceIndex + 1);
452:                        try {
453:                            width = Integer.parseInt(widthString);
454:                            height = Integer.parseInt(heightString);
455:                        } catch (NumberFormatException nfe) {
456:                            return false;
457:                        }
458:                        if (width < 1 || height < 1) {
459:                            return false;
460:                        }
461:                        if (format == FORMAT_PBM) {
462:                            bitsPerPixel = 1;
463:                            return true;
464:                        }
465:                        hasPixelResolution = true;
466:                    } else {
467:                        int maxSample;
468:                        try {
469:                            maxSample = Integer.parseInt(s);
470:                        } catch (NumberFormatException nfe) {
471:                            return false;
472:                        }
473:                        if (maxSample < 0) {
474:                            return false;
475:                        }
476:                        for (int i = 0; i < 25; i++) {
477:                            if (maxSample < (1 << (i + 1))) {
478:                                bitsPerPixel = i + 1;
479:                                if (format == FORMAT_PPM) {
480:                                    bitsPerPixel *= 3;
481:                                }
482:                                return true;
483:                            }
484:                        }
485:                        return false;
486:                    }
487:                }
488:            }
489:
490:            private boolean checkPsd() throws IOException {
491:                byte[] a = new byte[24];
492:                if (read(a) != a.length) {
493:                    return false;
494:                }
495:                final byte[] PSD_MAGIC = { 0x50, 0x53 };
496:                if (!equals(a, 0, PSD_MAGIC, 0, 2)) {
497:                    return false;
498:                }
499:                format = FORMAT_PSD;
500:                width = getIntBigEndian(a, 16);
501:                height = getIntBigEndian(a, 12);
502:                int channels = getShortBigEndian(a, 10);
503:                int depth = getShortBigEndian(a, 20);
504:                bitsPerPixel = channels * depth;
505:                return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 64);
506:            }
507:
508:            private boolean checkRas() throws IOException {
509:                byte[] a = new byte[14];
510:                if (read(a) != a.length) {
511:                    return false;
512:                }
513:                final byte[] RAS_MAGIC = { 0x6a, (byte) 0x95 };
514:                if (!equals(a, 0, RAS_MAGIC, 0, 2)) {
515:                    return false;
516:                }
517:                format = FORMAT_RAS;
518:                width = getIntBigEndian(a, 2);
519:                height = getIntBigEndian(a, 6);
520:                bitsPerPixel = getIntBigEndian(a, 10);
521:                return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 24);
522:            }
523:
524:            private boolean equals(byte[] a1, int offs1, byte[] a2, int offs2,
525:                    int num) {
526:                while (num-- > 0) {
527:                    if (a1[offs1++] != a2[offs2++]) {
528:                        return false;
529:                    }
530:                }
531:                return true;
532:            }
533:
534:            /** 
535:             * If {@link #check()} was successful, returns the image's number of bits per pixel.
536:             * Does not include transparency information like the alpha channel.
537:             * @return number of bits per image pixel
538:             */
539:            public int getBitsPerPixel() {
540:                return bitsPerPixel;
541:            }
542:
543:            /**
544:             * If {@link #check()} was successful, returns the image format as one
545:             * of the FORMAT_xyz constants from this class.
546:             * Use {@link #getFormatName()} to get a textual description of the file format.
547:             * @return file format as a FORMAT_xyz constant
548:             */
549:            public int getFormat() {
550:                return format;
551:            }
552:
553:            /**
554:             * If {@link #check()} was successful, returns the image format's name.
555:             * Use {@link #getFormat()} to get a unique number.
556:             * @return file format name
557:             */
558:            public String getFormatName() {
559:                if (format >= 0 && format < FORMAT_NAMES.length) {
560:                    return FORMAT_NAMES[format];
561:                } else {
562:                    return "?";
563:                }
564:            }
565:
566:            /** 
567:             * If {@link #check()} was successful, returns one the image's vertical
568:             * resolution in pixels.
569:             * @return image height in pixels
570:             */
571:            public int getHeight() {
572:                return height;
573:            }
574:
575:            private int getIntBigEndian(byte[] a, int offs) {
576:                return (a[offs] & 0xff) << 24 | (a[offs + 1] & 0xff) << 16
577:                        | (a[offs + 2] & 0xff) << 8 | a[offs + 3] & 0xff;
578:            }
579:
580:            private int getIntLittleEndian(byte[] a, int offs) {
581:                return (a[offs + 3] & 0xff) << 24 | (a[offs + 2] & 0xff) << 16
582:                        | (a[offs + 1] & 0xff) << 8 | a[offs] & 0xff;
583:            }
584:
585:            /** 
586:             * If {@link #check()} was successful, returns a String with the
587:             * MIME type of the format.
588:             * @return MIME type, e.g. <code>image/jpeg</code>
589:             */
590:            public String getMimeType() {
591:                if (format >= 0 && format < MIME_TYPE_STRINGS.length) {
592:                    return MIME_TYPE_STRINGS[format];
593:                } else {
594:                    return null;
595:                }
596:            }
597:
598:            /**
599:             * Returns the number of images in the examined file 
600:             * if <code>setDetermineImageNumber(true);</code> was called before
601:             * a successful call to {@link #check()}.
602:             * @return number of images in file
603:             */
604:            public int getNumberOfImages() {
605:                return numberOfImages;
606:            }
607:
608:            private int getShortBigEndian(byte[] a, int offs) {
609:                return (a[offs] & 0xff) << 8 | (a[offs + 1] & 0xff);
610:            }
611:
612:            private int getShortLittleEndian(byte[] a, int offs) {
613:                return (a[offs] & 0xff) | (a[offs + 1] & 0xff) << 8;
614:            }
615:
616:            /** 
617:             * If {@link #check()} was successful, returns one the image's horizontal
618:             * resolution in pixels.
619:             * @return image width in pixels
620:             */
621:            public int getWidth() {
622:                return width;
623:            }
624:
625:            /**
626:             * To use this class as a command line application, give it either 
627:             * some file names as parameters (information on them will be
628:             * printed to standard output, one line per file) or call
629:             * it with no parameters. It will then check data given to it
630:             * via standard input.
631:             * @param args the program arguments which must be file names
632:             */
633:            public static void main(String[] args) {
634:                ImageInfo imageInfo = new ImageInfo();
635:                if (args.length == 0) {
636:                    run(System.in, imageInfo);
637:                } else {
638:                    int index = 0;
639:                    while (index < args.length) {
640:                        FileInputStream tmp = null;
641:                        try {
642:                            String filename = args[index++];
643:                            System.out.print(filename + ";");
644:                            tmp = new FileInputStream(filename);
645:                            run(tmp, imageInfo);
646:                            tmp.close();
647:                        } catch (Exception e) {
648:                            System.out.println(e);
649:                            try {
650:                                tmp.close();
651:                            } catch (Exception ee) {
652:                            }
653:                        }
654:                    }
655:                }
656:            }
657:
658:            private int read() throws IOException {
659:                if (in != null) {
660:                    return in.read();
661:                } else {
662:                    return din.readByte();
663:                }
664:            }
665:
666:            private int read(byte[] a) throws IOException {
667:                if (in != null) {
668:                    return in.read(a);
669:                } else {
670:                    din.readFully(a);
671:                    return a.length;
672:                }
673:            }
674:
675:            private int read(byte[] a, int offset, int num) throws IOException {
676:                if (in != null) {
677:                    return in.read(a, offset, num);
678:                } else {
679:                    din.readFully(a, offset, num);
680:                    return num;
681:                }
682:            }
683:
684:            private String readLine() throws IOException {
685:                return readLine(new StringBuffer());
686:            }
687:
688:            private String readLine(StringBuffer sb) throws IOException {
689:                boolean finished;
690:                do {
691:                    int value = read();
692:                    finished = (value == -1 || value == 10);
693:                    if (!finished) {
694:                        sb.append((char) value);
695:                    }
696:                } while (!finished);
697:                return sb.toString();
698:            }
699:
700:            private static void run(InputStream in, ImageInfo imageInfo) {
701:                imageInfo.setInput(in);
702:                imageInfo.setDetermineImageNumber(true);
703:                if (imageInfo.check()) {
704:                    System.out.println(imageInfo.getFormatName() + ";"
705:                            + imageInfo.getMimeType() + ";"
706:                            + imageInfo.getWidth() + ";"
707:                            + imageInfo.getHeight() + ";"
708:                            + imageInfo.getBitsPerPixel() + ";"
709:                            + imageInfo.getNumberOfImages());
710:                } else {
711:                    System.out.println("?");
712:                }
713:            }
714:
715:            public void setCollectComments(boolean newValue) {
716:                // collectComments = newValue;
717:            }
718:
719:            /**
720:             * Specify whether the number of images in a file are to be
721:             * determined - default is <code>false</code>.
722:             * Will only make a difference with file formats that do support 
723:             * more than one image like GIF.
724:             * If this method is called with <code>true</code> as argument,
725:             * the actual number of images can be queried via 
726:             * {@link #getNumberOfImages()} after a successful call to
727:             * {@link #check()}.
728:             * @param newValue will the number of images be determined?
729:             */
730:            public void setDetermineImageNumber(boolean newValue) {
731:                determineNumberOfImages = newValue;
732:            }
733:
734:            /**
735:             * Set the input stream to the argument stream (or file). 
736:             * Note that {@link java.io.RandomAccessFile} implements
737:             * {@link java.io.DataInput}.
738:             * @param dataInput the input stream to read from
739:             */
740:            public void setInput(DataInput dataInput) {
741:                din = dataInput;
742:                in = null;
743:            }
744:
745:            /**
746:             * Set the input stream to the argument stream (or file).
747:             * @param inputStream the input stream to read from
748:             */
749:            public void setInput(InputStream inputStream) {
750:                in = inputStream;
751:                din = null;
752:            }
753:
754:            private void skip(int num) throws IOException {
755:                if (in != null) {
756:                    in.skip(num);
757:                } else {
758:                    din.skipBytes(num);
759:                }
760:            }
761:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.