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


001:        /*
002:         * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package sun.awt.image;
027:
028:        import java.io.*;
029:        import java.util.*;
030:        import java.util.zip.*;
031:        import java.awt.image.*;
032:        import java.awt.Color;
033:
034:        /** PNG - Portable Network Graphics - image file reader.
035:         See <a href=ftp://ds.internic.net/rfc/rfc2083.txt>RFC2083</a> for details. */
036:
037:        /* this is changed
038:         public class PNGImageDecoder extends FilterInputStream implements Runnable
039:         { */
040:
041:        public class PNGImageDecoder extends ImageDecoder {
042:            private static final int GRAY = 0;
043:            private static final int PALETTE = 1;
044:            private static final int COLOR = 2;
045:            private static final int ALPHA = 4;
046:
047:            private static final int bKGDChunk = 0x624B4744;
048:            private static final int cHRMChunk = 0x6348524D;
049:            private static final int gAMAChunk = 0x67414D41;
050:            private static final int hISTChunk = 0x68495354;
051:            private static final int IDATChunk = 0x49444154;
052:            private static final int IENDChunk = 0x49454E44;
053:            private static final int IHDRChunk = 0x49484452;
054:            private static final int PLTEChunk = 0x504C5445;
055:            private static final int pHYsChunk = 0x70485973;
056:            private static final int sBITChunk = 0x73424954;
057:            private static final int tEXtChunk = 0x74455874;
058:            private static final int tIMEChunk = 0x74494D45;
059:            private static final int tRNSChunk = 0x74524E53;
060:            private static final int zTXtChunk = 0x7A545874;
061:
062:            private int width;
063:            private int height;
064:            private int bitDepth;
065:            private int colorType;
066:            private int compressionMethod;
067:            private int filterMethod;
068:            private int interlaceMethod;
069:            private int gamma = 100000;
070:            private java.util.Hashtable properties;
071:            /* this is not needed
072:              ImageConsumer target;
073:             */
074:            private ColorModel cm;
075:            private byte[] red_map, green_map, blue_map, alpha_map;
076:            private int transparentPixel = -1;
077:            private byte[] transparentPixel_16 = null; // we need 6 bytes to store 16bpp value 
078:            private static ColorModel greyModels[] = new ColorModel[4];
079:
080:            /* this is not needed
081:               PNGImageDecoder next;
082:             */
083:
084:            private void property(String key, Object value) {
085:                if (value == null)
086:                    return;
087:                if (properties == null)
088:                    properties = new java.util.Hashtable();
089:                properties.put(key, value);
090:            }
091:
092:            private void property(String key, float value) {
093:                property(key, new Float(value));
094:            }
095:
096:            private final void pngassert(boolean b) throws IOException {
097:                if (!b) {
098:                    PNGException e = new PNGException("Broken file");
099:                    e.printStackTrace();
100:                    throw e;
101:                }
102:            }
103:
104:            protected boolean handleChunk(int key, byte[] buf, int st, int len)
105:                    throws IOException {
106:                switch (key) {
107:                case bKGDChunk:
108:                    Color c = null;
109:                    switch (colorType) {
110:                    case COLOR:
111:                    case COLOR | ALPHA:
112:                        pngassert(len == 6);
113:                        c = new Color(buf[st] & 0xff, buf[st + 2] & 0xff,
114:                                buf[st + 4] & 0xff);
115:                        break;
116:                    case COLOR | PALETTE:
117:                    case COLOR | PALETTE | ALPHA:
118:                        pngassert(len == 1);
119:                        int ix = buf[st] & 0xFF;
120:                        pngassert(red_map != null && ix < red_map.length);
121:                        c = new Color(red_map[ix] & 0xff, green_map[ix] & 0xff,
122:                                blue_map[ix] & 0xff);
123:                        break;
124:                    case GRAY:
125:                    case GRAY | ALPHA:
126:                        pngassert(len == 2);
127:                        int t = buf[st] & 0xFF;
128:                        c = new Color(t, t, t);
129:                        break;
130:                    }
131:                    if (c != null)
132:                        property("background", c);
133:                    break;
134:                case cHRMChunk:
135:                    property("chromaticities", new Chromaticities(getInt(st),
136:                            getInt(st + 4), getInt(st + 8), getInt(st + 12),
137:                            getInt(st + 16), getInt(st + 20), getInt(st + 24),
138:                            getInt(st + 28)));
139:                    break;
140:                case gAMAChunk:
141:                    if (len != 4)
142:                        throw new PNGException("bogus gAMA");
143:                    gamma = getInt(st);
144:                    if (gamma != 100000)
145:                        property("gamma", gamma / 100000.0f);
146:                    break;
147:                case hISTChunk:
148:                    break;
149:                case IDATChunk:
150:                    return false;
151:                case IENDChunk:
152:                    break;
153:                case IHDRChunk:
154:                    if (len != 13 || (width = getInt(st)) == 0
155:                            || (height = getInt(st + 4)) == 0)
156:                        throw new PNGException("bogus IHDR");
157:                    bitDepth = getByte(st + 8);
158:                    colorType = getByte(st + 9);
159:                    compressionMethod = getByte(st + 10);
160:                    filterMethod = getByte(st + 11);
161:                    interlaceMethod = getByte(st + 12);
162:                    /* this is not needed
163:                    if(target!=null) target.setDimensions(width,height);
164:                     */
165:                    break;
166:                case PLTEChunk: {
167:                    int tsize = len / 3;
168:                    red_map = new byte[tsize];
169:                    green_map = new byte[tsize];
170:                    blue_map = new byte[tsize];
171:                    for (int i = 0, j = st; i < tsize; i++, j += 3) {
172:                        red_map[i] = buf[j];
173:                        green_map[i] = buf[j + 1];
174:                        blue_map[i] = buf[j + 2];
175:                    }
176:                }
177:                    break;
178:                case pHYsChunk:
179:                    break;
180:                case sBITChunk:
181:                    break;
182:                case tEXtChunk:
183:                    int klen = 0;
184:                    while (klen < len && buf[st + klen] != 0)
185:                        klen++;
186:                    if (klen < len) {
187:                        String tkey = new String(buf, st, klen);
188:                        String tvalue = new String(buf, st + klen + 1, len
189:                                - klen - 1);
190:                        property(tkey, tvalue);
191:                    }
192:                    break;
193:                case tIMEChunk:
194:                    property("modtime", new GregorianCalendar(getShort(st + 0),
195:                            getByte(st + 2) - 1, getByte(st + 3),
196:                            getByte(st + 4), getByte(st + 5), getByte(st + 6))
197:                            .getTime());
198:                    break;
199:                case tRNSChunk:
200:                    switch (colorType) {
201:                    case PALETTE | COLOR:
202:                    case PALETTE | COLOR | ALPHA:
203:                        int alen = len;
204:                        if (red_map != null)
205:                            alen = red_map.length;
206:                        alpha_map = new byte[alen];
207:                        System.arraycopy(buf, st, alpha_map, 0,
208:                                len < alen ? len : alen);
209:                        while (--alen >= len)
210:                            alpha_map[alen] = (byte) 0xFF;
211:                        break;
212:                    case COLOR: // doesn't deal with 16 bit colors properly
213:                    case COLOR | ALPHA: // doesn't deal with 16 bit colors properly
214:                        pngassert(len == 6);
215:                        if (bitDepth == 16) {
216:                            transparentPixel_16 = new byte[6];
217:                            for (int i = 0; i < 6; i++) {
218:                                transparentPixel_16[i] = (byte) getByte(st + i);
219:                            }
220:                        } else {
221:                            transparentPixel = ((getShort(st + 0) & 0xFF) << 16)
222:                                    | ((getShort(st + 2) & 0xFF) << 8)
223:                                    | ((getShort(st + 4) & 0xFF));
224:                        }
225:                        break;
226:                    case GRAY: // doesn't deal with 16 bit colors properly
227:                    case GRAY | ALPHA: // doesn't deal with 16 bit colors properly
228:                        pngassert(len == 2);
229:                        /* REMIND: Discarding the LSB for 16 bit depth here
230:                         * means that the all pixels which match the MSB
231:                         * will be treated as transparent.
232:                         */
233:                        int t = getShort(st);
234:                        t = 0xFF & ((bitDepth == 16) ? (t >> 8) : t);
235:                        transparentPixel = (t << 16) | (t << 8) | t;
236:                        break;
237:                    }
238:                    break;
239:                case zTXtChunk:
240:                    break;
241:                }
242:                return true;
243:            }
244:
245:            public class PNGException extends IOException {
246:                PNGException(String s) {
247:                    super (s);
248:                }
249:            }
250:
251:            /* this is changed
252:               public void run() {
253:             */
254:            public void produceImage() throws IOException, ImageFormatException {
255:                /* this is not needed
256:                   ImageConsumer t = target;
257:                   if(t!=null) try {
258:                 */
259:                try {
260:                    for (int i = 0; i < signature.length; i++)
261:                        if ((signature[i] & 0xFF) != underlyingInputStream
262:                                .read())
263:                            throw new PNGException("Chunk signature mismatch");
264:
265:                    InputStream is = new BufferedInputStream(
266:                            new InflaterInputStream(inputStream, new Inflater()));
267:
268:                    getData();
269:
270:                    byte[] bPixels = null;
271:                    int[] wPixels = null;
272:                    int pixSize = width;
273:                    int rowStride;
274:                    int logDepth = 0;
275:                    switch (bitDepth) {
276:                    case 1:
277:                        logDepth = 0;
278:                        break;
279:                    case 2:
280:                        logDepth = 1;
281:                        break;
282:                    case 4:
283:                        logDepth = 2;
284:                        break;
285:                    case 8:
286:                        logDepth = 3;
287:                        break;
288:                    case 16:
289:                        logDepth = 4;
290:                        break;
291:                    default:
292:                        throw new PNGException("invalid depth");
293:                    }
294:                    if (interlaceMethod != 0) {
295:                        pixSize *= height;
296:                        rowStride = width;
297:                    } else
298:                        rowStride = 0;
299:                    int combinedType = colorType | (bitDepth << 3);
300:                    int bitMask = (1 << (bitDepth >= 8 ? 8 : bitDepth)) - 1;
301:                    //Figure out the color model
302:                    switch (colorType) {
303:                    case COLOR | PALETTE:
304:                    case COLOR | PALETTE | ALPHA:
305:                        if (red_map == null)
306:                            throw new PNGException("palette expected");
307:                        if (alpha_map == null)
308:                            cm = new IndexColorModel(bitDepth, red_map.length,
309:                                    red_map, green_map, blue_map);
310:                        else
311:                            cm = new IndexColorModel(bitDepth, red_map.length,
312:                                    red_map, green_map, blue_map, alpha_map);
313:                        bPixels = new byte[pixSize];
314:                        break;
315:                    case GRAY: {
316:                        int llog = logDepth >= 4 ? 3 : logDepth;
317:                        if ((cm = greyModels[llog]) == null) {
318:                            int size = 1 << (1 << llog);
319:
320:                            byte ramp[] = new byte[size];
321:                            for (int i = 0; i < size; i++)
322:                                ramp[i] = (byte) (255 * i / (size - 1));
323:
324:                            if (transparentPixel == -1) {
325:                                cm = new IndexColorModel(bitDepth, ramp.length,
326:                                        ramp, ramp, ramp);
327:                            } else {
328:                                cm = new IndexColorModel(bitDepth, ramp.length,
329:                                        ramp, ramp, ramp,
330:                                        (transparentPixel & 0xFF));
331:                            }
332:                            greyModels[llog] = cm;
333:                        }
334:                    }
335:                        bPixels = new byte[pixSize];
336:                        break;
337:                    case COLOR:
338:                    case COLOR | ALPHA:
339:                    case GRAY | ALPHA:
340:                        cm = ColorModel.getRGBdefault();
341:                        wPixels = new int[pixSize];
342:                        break;
343:                    default:
344:                        throw new PNGException("invalid color type");
345:                    }
346:                    /* this is going to be set in the pixel store
347:                    t.setColorModel(cm);
348:                    t.setHints(interlaceMethod !=0
349:                               ? ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES
350:                               : ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
351:                                 ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME);
352:                     */
353:                    // code added to make it work with ImageDecoder architecture
354:                    setDimensions(width, height);
355:                    setColorModel(cm);
356:                    int flags = (interlaceMethod != 0 ? ImageConsumer.TOPDOWNLEFTRIGHT
357:                            | ImageConsumer.COMPLETESCANLINES
358:                            : ImageConsumer.TOPDOWNLEFTRIGHT
359:                                    | ImageConsumer.COMPLETESCANLINES
360:                                    | ImageConsumer.SINGLEPASS
361:                                    | ImageConsumer.SINGLEFRAME);
362:                    setHints(flags);
363:                    headerComplete();
364:                    // end of adding
365:
366:                    int samplesPerPixel = ((colorType & PALETTE) != 0 ? 1
367:                            : ((colorType & COLOR) != 0 ? 3 : 1)
368:                                    + ((colorType & ALPHA) != 0 ? 1 : 0));
369:                    int bitsPerPixel = samplesPerPixel * bitDepth;
370:                    int bytesPerPixel = (bitsPerPixel + 7) >> 3;
371:                    int pass, passLimit;
372:                    if (interlaceMethod == 0) {
373:                        pass = -1;
374:                        passLimit = 0;
375:                    } else {
376:                        pass = 0;
377:                        passLimit = 7;
378:                    }
379:                    // These loops are far from being tuned.  They're this way to make them easy to
380:                    // debug.  Tuning comes later.
381:                    /* code changed. target not needed here
382:                    while(++pass<=passLimit && (t=target)!=null) {
383:                     */
384:                    while (++pass <= passLimit) {
385:                        int row = startingRow[pass];
386:                        int rowInc = rowIncrement[pass];
387:                        int colInc = colIncrement[pass];
388:                        int bWidth = blockWidth[pass];
389:                        int bHeight = blockHeight[pass];
390:                        int sCol = startingCol[pass];
391:                        int rowPixelWidth = (width - sCol + (colInc - 1))
392:                                / colInc;
393:                        int rowByteWidth = ((rowPixelWidth * bitsPerPixel) + 7) >> 3;
394:                        if (rowByteWidth == 0)
395:                            continue;
396:                        int pixelBufferInc = interlaceMethod == 0 ? rowInc
397:                                * width : 0;
398:                        int rowOffset = rowStride * row;
399:                        boolean firstRow = true;
400:
401:                        byte[] rowByteBuffer = new byte[rowByteWidth];
402:                        byte[] prevRowByteBuffer = new byte[rowByteWidth];
403:                        /* code changed. target not needed here 
404:                           while (row < height && (t=target)!=null) {
405:                         */
406:                        while (row < height) {
407:                            int rowFilter = is.read();
408:                            for (int rowFillPos = 0; rowFillPos < rowByteWidth;) {
409:                                int n = is.read(rowByteBuffer, rowFillPos,
410:                                        rowByteWidth - rowFillPos);
411:                                if (n <= 0)
412:                                    throw new PNGException("missing data");
413:                                rowFillPos += n;
414:                            }
415:                            filterRow(rowByteBuffer, firstRow ? null
416:                                    : prevRowByteBuffer, rowFilter,
417:                                    rowByteWidth, bytesPerPixel);
418:                            int col = sCol;
419:                            int spos = 0;
420:                            int pixel = 0;
421:                            while (col < width) {
422:                                if (wPixels != null) {
423:                                    switch (combinedType) {
424:                                    case COLOR | ALPHA | (8 << 3):
425:                                        wPixels[col + rowOffset] = ((rowByteBuffer[spos] & 0xFF) << 16)
426:                                                | ((rowByteBuffer[spos + 1] & 0xFF) << 8)
427:                                                | ((rowByteBuffer[spos + 2] & 0xFF))
428:                                                | ((rowByteBuffer[spos + 3] & 0xFF) << 24);
429:                                        spos += 4;
430:                                        break;
431:                                    case COLOR | ALPHA | (16 << 3):
432:                                        wPixels[col + rowOffset] = ((rowByteBuffer[spos] & 0xFF) << 16)
433:                                                | ((rowByteBuffer[spos + 2] & 0xFF) << 8)
434:                                                | ((rowByteBuffer[spos + 4] & 0xFF))
435:                                                | ((rowByteBuffer[spos + 6] & 0xFF) << 24);
436:                                        spos += 8;
437:                                        break;
438:                                    case COLOR | (8 << 3):
439:                                        pixel = ((rowByteBuffer[spos] & 0xFF) << 16)
440:                                                | ((rowByteBuffer[spos + 1] & 0xFF) << 8)
441:                                                | ((rowByteBuffer[spos + 2] & 0xFF));
442:                                        if (pixel != transparentPixel) {
443:                                            pixel |= 0xff000000;
444:                                        }
445:                                        wPixels[col + rowOffset] = pixel;
446:                                        spos += 3;
447:                                        break;
448:                                    case COLOR | (16 << 3):
449:                                        pixel = ((rowByteBuffer[spos] & 0xFF) << 16)
450:                                                | ((rowByteBuffer[spos + 2] & 0xFF) << 8)
451:                                                | ((rowByteBuffer[spos + 4] & 0xFF));
452:
453:                                        boolean isTransparent = (transparentPixel_16 != null);
454:                                        for (int i = 0; isTransparent
455:                                                && (i < 6); i++) {
456:                                            isTransparent &= (rowByteBuffer[spos
457:                                                    + i] & 0xFF) == (transparentPixel_16[i] & 0xFF);
458:                                        }
459:                                        if (!isTransparent) {
460:                                            pixel |= 0xff000000;
461:                                        }
462:                                        wPixels[col + rowOffset] = pixel;
463:                                        spos += 6;
464:                                        break;
465:                                    case GRAY | ALPHA | (8 << 3): {
466:                                        int tx = rowByteBuffer[spos] & 0xFF;
467:                                        wPixels[col + rowOffset] = (tx << 16)
468:                                                | (tx << 8)
469:                                                | tx
470:                                                | ((rowByteBuffer[spos + 1] & 0xFF) << 24);
471:                                    }
472:                                        spos += 2;
473:                                        break;
474:                                    case GRAY | ALPHA | (16 << 3): {
475:                                        int tx = rowByteBuffer[spos] & 0xFF;
476:                                        wPixels[col + rowOffset] = (tx << 16)
477:                                                | (tx << 8)
478:                                                | tx
479:                                                | ((rowByteBuffer[spos + 2] & 0xFF) << 24);
480:                                    }
481:                                        spos += 4;
482:                                        break;
483:                                    default:
484:                                        throw new PNGException(
485:                                                "illegal type/depth");
486:                                    }
487:                                } else
488:                                    switch (bitDepth) {
489:                                    case 1:
490:                                        bPixels[col + rowOffset] = (byte) ((rowByteBuffer[spos >> 3] >> (7 - (spos & 7))) & 1);
491:                                        spos++;
492:                                        break;
493:                                    case 2:
494:                                        bPixels[col + rowOffset] = (byte) ((rowByteBuffer[spos >> 2] >> ((3 - (spos & 3)) * 2)) & 3);
495:                                        spos++;
496:                                        break;
497:                                    case 4:
498:                                        bPixels[col + rowOffset] = (byte) ((rowByteBuffer[spos >> 1] >> ((1 - (spos & 1)) * 4)) & 15);
499:                                        spos++;
500:                                        break;
501:                                    case 8:
502:                                        bPixels[col + rowOffset] = rowByteBuffer[spos++];
503:                                        break;
504:                                    case 16:
505:                                        bPixels[col + rowOffset] = rowByteBuffer[spos];
506:                                        spos += 2;
507:                                        break;
508:                                    default:
509:                                        throw new PNGException(
510:                                                "illegal type/depth");
511:                                    }
512:                                /*visit (row, col,
513:                                    min (bHeight, height - row),
514:                                    min (bWidth, width - col)); */
515:                                col += colInc;
516:                            }
517:                            if (interlaceMethod == 0)
518:                                if (wPixels != null) {
519:                                    /* code changed. target not needed here
520:                                      t.setPixels(0,row,width,1,cm,wPixels,0,width); 
521:                                     */
522:                                    // code added to make it work with ImageDecoder arch
523:                                    sendPixels(0, row, width, 1, wPixels, 0,
524:                                            width);
525:                                    // end of adding
526:                                } else {
527:                                    /* code changed. target not needed here
528:                                       t.setPixels(0,row,width,1,cm,bPixels,0,width);
529:                                     */
530:                                    // code added to make it work with ImageDecoder arch
531:                                    sendPixels(0, row, width, 1, bPixels, 0,
532:                                            width);
533:                                    //end of adding
534:                                }
535:                            row += rowInc;
536:                            rowOffset += rowInc * rowStride;
537:                            byte[] T = rowByteBuffer;
538:                            rowByteBuffer = prevRowByteBuffer;
539:                            prevRowByteBuffer = T;
540:                            firstRow = false;
541:                        }
542:                        if (interlaceMethod != 0)
543:                            if (wPixels != null) {
544:                                /* code changed. target not needed here
545:                                   t.setPixels(0,0,width,height,cm,wPixels,0,width); 
546:                                 */
547:                                // code added to make it work with ImageDecoder arch
548:                                sendPixels(0, 0, width, height, wPixels, 0,
549:                                        width);
550:                                //end of adding
551:                            } else {
552:                                /* code changed. target not needed here
553:                                t.setPixels(0,0,width,height,cm,bPixels,0,width);
554:                                 */
555:                                // code added to make it work with ImageDecoder arch
556:                                sendPixels(0, 0, width, height, bPixels, 0,
557:                                        width);
558:                                //end of adding
559:                            }
560:                    }
561:
562:                    /* Here, the function "visit(row,column,height,width)" obtains the
563:                       next transmitted pixel and paints a rectangle of the specified
564:                       height and width, whose upper-left corner is at the specified row
565:                       and column, using the color indicated by the pixel.  Note that row
566:                       and column are measured from 0,0 at the upper left corner. */
567:
568:                    /* code not needed, don't deal with target
569:                         if((t=target)!=null) {
570:                       if(properties!=null) t.setProperties(properties);
571:                             t.imageComplete(ImageConsumer.STATICIMAGEDONE);
572:                     */
573:
574:                    imageComplete(ImageConsumer.STATICIMAGEDONE, true);
575:
576:                    /* code not needed }
577:                     is.close();
578:                     */
579:                } catch (IOException e) {
580:                    if (!aborted) {
581:                        /* code not needed
582:                           if((t=target)!=null) {
583:                           PNGEncoder.prChunk(e.toString(),inbuf,pos,limit-pos,true);
584:                         */
585:                        property("error", e);
586:                        /* code not needed
587:                           t.setProperties(properties);
588:                           t.imageComplete(ImageConsumer.IMAGEERROR|ImageConsumer.STATICIMAGEDONE);
589:                         */
590:                        imageComplete(ImageConsumer.IMAGEERROR
591:                                | ImageConsumer.STATICIMAGEDONE, true);
592:                        throw e;
593:                    }
594:                } finally {
595:                    try {
596:                        close();
597:                    } catch (Throwable e) {
598:                    }
599:                    /* code not needed
600:                       target = null;
601:                       endTurn();
602:                     */
603:                }
604:            }
605:
606:            private boolean sendPixels(int x, int y, int w, int h,
607:                    int[] pixels, int offset, int pixlength) {
608:                int count = setPixels(x, y, w, h, cm, pixels, offset, pixlength);
609:                if (count <= 0) {
610:                    aborted = true;
611:                }
612:                return !aborted;
613:            }
614:
615:            private boolean sendPixels(int x, int y, int w, int h,
616:                    byte[] pixels, int offset, int pixlength) {
617:                int count = setPixels(x, y, w, h, cm, pixels, offset, pixlength);
618:                if (count <= 0) {
619:                    aborted = true;
620:                }
621:                return !aborted;
622:            }
623:
624:            private void filterRow(byte rowByteBuffer[], byte[] prevRow,
625:                    int rowFilter, int rowByteWidth, int bytesPerSample)
626:                    throws IOException {
627:                int x = 0;
628:                switch (rowFilter) {
629:                case 0:
630:                    break;
631:                case 1:
632:                    for (x = bytesPerSample; x < rowByteWidth; x++)
633:                        rowByteBuffer[x] += rowByteBuffer[x - bytesPerSample];
634:                    break;
635:                case 2:
636:                    if (prevRow != null)
637:                        for (; x < rowByteWidth; x++)
638:                            rowByteBuffer[x] += prevRow[x];
639:                    break;
640:                case 3:
641:                    if (prevRow != null) {
642:                        for (; x < bytesPerSample; x++)
643:                            rowByteBuffer[x] += (0xff & prevRow[x]) >> 1;
644:                        for (; x < rowByteWidth; x++)
645:                            rowByteBuffer[x] += ((prevRow[x] & 0xFF) + (rowByteBuffer[x
646:                                    - bytesPerSample] & 0xFF)) >> 1;
647:                    } else
648:                        for (x = bytesPerSample; x < rowByteWidth; x++)
649:                            rowByteBuffer[x] += (rowByteBuffer[x
650:                                    - bytesPerSample] & 0xFF) >> 1;
651:                    break;
652:                case 4:
653:                    if (prevRow != null) {
654:                        for (; x < bytesPerSample; x++)
655:                            rowByteBuffer[x] += prevRow[x];
656:                        for (; x < rowByteWidth; x++) {
657:                            int a, b, c, p, pa, pb, pc, rval;
658:                            a = rowByteBuffer[x - bytesPerSample] & 0xFF;
659:                            b = prevRow[x] & 0xFF;
660:                            c = prevRow[x - bytesPerSample] & 0xFF;
661:                            p = a + b - c;
662:                            pa = p > a ? p - a : a - p;
663:                            pb = p > b ? p - b : b - p;
664:                            pc = p > c ? p - c : c - p;
665:                            rowByteBuffer[x] += (pa <= pb) && (pa <= pc) ? a
666:                                    : pb <= pc ? b : c;
667:                        }
668:                    } else
669:                        for (x = bytesPerSample; x < rowByteWidth; x++)
670:                            rowByteBuffer[x] += rowByteBuffer[x
671:                                    - bytesPerSample];
672:                    break;
673:                default:
674:                    throw new PNGException("Illegal filter");
675:                }
676:            }
677:
678:            private static final byte[] startingRow = { 0, 0, 0, 4, 0, 2, 0, 1 };
679:            private static final byte[] startingCol = { 0, 0, 4, 0, 2, 0, 1, 0 };
680:            private static final byte[] rowIncrement = { 1, 8, 8, 8, 4, 4, 2, 2 };
681:            private static final byte[] colIncrement = { 1, 8, 8, 4, 4, 2, 2, 1 };
682:            private static final byte[] blockHeight = { 1, 8, 8, 4, 4, 2, 2, 1 };
683:            private static final byte[] blockWidth = { 1, 8, 4, 4, 2, 2, 1, 1 };
684:
685:            //abstract public class ChunkReader extends FilterInputStream {
686:            int pos, limit;
687:            int chunkStart;
688:            int chunkKey, chunkLength, chunkCRC;
689:            boolean seenEOF;
690:
691:            private static final byte[] signature = { (byte) 137, (byte) 80,
692:                    (byte) 78, (byte) 71, (byte) 13, (byte) 10, (byte) 26,
693:                    (byte) 10 };
694:
695:            PNGFilterInputStream inputStream;
696:            InputStream underlyingInputStream;
697:
698:            /* code changed
699:              public PNGImageDecoder(InputStream in, ImageConsumer t) throws IOException {
700:             */
701:            public PNGImageDecoder(InputStreamImageSource src, InputStream input)
702:                    throws IOException {
703:                // code added
704:                super (src, input);
705:                inputStream = new PNGFilterInputStream(this , input);
706:                underlyingInputStream = inputStream.underlyingInputStream;
707:                // end of adding
708:                /* code changed
709:                   super(in);
710:                   target = t;
711:                   waitTurn();
712:                   new Thread(this).start();
713:                 */
714:            }
715:
716:            /* code changed to make it work with ImageDecoder architecture
717:              static int ThreadLimit = 10;
718:              private synchronized static void waitTurn() {
719:            try {
720:                while(ThreadLimit<=0) PNGImageDecoder.class.wait(1000);
721:            } catch(InterruptedException e){}
722:            ThreadLimit--;
723:              }
724:              private synchronized static void endTurn() {
725:            if(ThreadLimit<=0) PNGImageDecoder.class.notify();
726:            ThreadLimit++;
727:              }
728:             */
729:            byte[] inbuf = new byte[4096];
730:
731:            private void fill() throws IOException {
732:                if (!seenEOF) {
733:                    if (pos > 0 && pos < limit) {
734:                        System.arraycopy(inbuf, pos, inbuf, 0, limit - pos);
735:                        limit = limit - pos;
736:                        pos = 0;
737:                    } else if (pos >= limit) {
738:                        pos = 0;
739:                        limit = 0;
740:                    }
741:                    int bsize = inbuf.length;
742:                    while (limit < bsize) {
743:                        int n = underlyingInputStream.read(inbuf, limit, bsize
744:                                - limit);
745:                        if (n <= 0) {
746:                            seenEOF = true;
747:                            break;
748:                        }
749:                        limit += n;
750:                    }
751:                }
752:            }
753:
754:            private boolean need(int n) throws IOException {
755:                if (limit - pos >= n)
756:                    return true;
757:                fill();
758:                if (limit - pos >= n)
759:                    return true;
760:                if (seenEOF)
761:                    return false;
762:                byte nin[] = new byte[n + 100];
763:                System.arraycopy(inbuf, pos, nin, 0, limit - pos);
764:                limit = limit - pos;
765:                pos = 0;
766:                inbuf = nin;
767:                fill();
768:                return limit - pos >= n;
769:            }
770:
771:            private final int getInt(int pos) {
772:                return ((inbuf[pos] & 0xFF) << 24)
773:                        | ((inbuf[pos + 1] & 0xFF) << 16)
774:                        | ((inbuf[pos + 2] & 0xFF) << 8)
775:                        | ((inbuf[pos + 3] & 0xFF));
776:            }
777:
778:            private final int getShort(int pos) {
779:                return (short) (((inbuf[pos] & 0xFF) << 8) | ((inbuf[pos + 1] & 0xFF)));
780:            }
781:
782:            private final int getByte(int pos) {
783:                return inbuf[pos] & 0xFF;
784:            }
785:
786:            private final boolean getChunk() throws IOException {
787:                chunkLength = 0;
788:                if (!need(8))
789:                    return false;
790:                chunkLength = getInt(pos);
791:                chunkKey = getInt(pos + 4);
792:                if (chunkLength < 0)
793:                    throw new PNGException("bogus length: " + chunkLength);
794:                if (!need(chunkLength + 12))
795:                    return false;
796:                chunkCRC = getInt(pos + 8 + chunkLength);
797:                chunkStart = pos + 8;
798:                int calcCRC = crc(inbuf, pos + 4, chunkLength + 4);
799:                if (chunkCRC != calcCRC && checkCRC)
800:                    throw new PNGException("crc corruption");
801:                pos += chunkLength + 12;
802:                return true;
803:            }
804:
805:            private void readAll() throws IOException {
806:                while (getChunk())
807:                    handleChunk(chunkKey, inbuf, chunkStart, chunkLength);
808:            }
809:
810:            boolean getData() throws IOException {
811:                while (chunkLength == 0 && getChunk())
812:                    if (handleChunk(chunkKey, inbuf, chunkStart, chunkLength))
813:                        chunkLength = 0;
814:                return chunkLength > 0;
815:            }
816:
817:            //abstract protected boolean handleChunk(int key, byte[] buf, int st, int len)
818:            //    throws IOException;
819:            private static boolean checkCRC = true;
820:
821:            public static boolean getCheckCRC() {
822:                return checkCRC;
823:            }
824:
825:            public static void setCheckCRC(boolean c) {
826:                checkCRC = c;
827:            }
828:
829:            protected void wrc(int c) {
830:                c = c & 0xFF;
831:                if (c <= ' ' || c > 'z')
832:                    c = '?';
833:                System.out.write(c);
834:            }
835:
836:            protected void wrk(int n) {
837:                wrc(n >> 24);
838:                wrc(n >> 16);
839:                wrc(n >> 8);
840:                wrc(n);
841:            }
842:
843:            public void print() {
844:                wrk(chunkKey);
845:                System.out.print(" " + chunkLength + "\n");
846:            }
847:
848:            /* Table of CRCs of all 8-bit messages. */
849:            private static final int[] crc_table = new int[256];
850:
851:            /* Make the table for a fast CRC. */
852:            static {
853:                for (int n = 0; n < 256; n++) {
854:                    int c = n;
855:                    for (int k = 0; k < 8; k++)
856:                        if ((c & 1) != 0)
857:                            c = 0xedb88320 ^ (c >>> 1);
858:                        else
859:                            c = c >>> 1;
860:                    crc_table[n] = c;
861:                }
862:            }
863:
864:            /* Update a running CRC with the bytes buf[0..len-1]--the CRC
865:            should be initialized to all 1's, and the transmitted value
866:            is the 1's complement of the final running CRC (see the
867:            crc() routine below)). */
868:
869:            static private int update_crc(int crc, byte[] buf, int offset,
870:                    int len) {
871:                int c = crc;
872:                while (--len >= 0)
873:                    c = crc_table[(c ^ buf[offset++]) & 0xff] ^ (c >>> 8);
874:                return c;
875:            }
876:
877:            /* Return the CRC of the bytes buf[0..len-1]. */
878:            static private int crc(byte[] buf, int offset, int len) {
879:                return update_crc(0xffffffff, buf, offset, len) ^ 0xffffffff;
880:            }
881:
882:            public static class Chromaticities {
883:                public float whiteX, whiteY, redX, redY, greenX, greenY, blueX,
884:                        blueY;
885:
886:                Chromaticities(int wx, int wy, int rx, int ry, int gx, int gy,
887:                        int bx, int by) {
888:                    whiteX = wx / 100000.0f;
889:                    whiteY = wy / 100000.0f;
890:                    redX = rx / 100000.0f;
891:                    redY = ry / 100000.0f;
892:                    greenX = gx / 100000.0f;
893:                    greenY = gy / 100000.0f;
894:                    blueX = bx / 100000.0f;
895:                    blueY = by / 100000.0f;
896:                }
897:
898:                public String toString() {
899:                    return "Chromaticities(white=" + whiteX + "," + whiteY
900:                            + ";red=" + redX + "," + redY + ";green=" + greenX
901:                            + "," + greenY + ";blue=" + blueX + "," + blueY
902:                            + ")";
903:                }
904:            }
905:        }
906:
907:        // the following class are added to make it work with ImageDecoder architecture
908:
909:        class PNGFilterInputStream extends FilterInputStream {
910:            PNGImageDecoder owner;
911:            public InputStream underlyingInputStream;
912:
913:            public PNGFilterInputStream(PNGImageDecoder owner, InputStream is) {
914:                super (is);
915:                underlyingInputStream = in;
916:                this .owner = owner;
917:            }
918:
919:            public int available() throws IOException {
920:                return owner.limit - owner.pos + in.available();
921:            }
922:
923:            public boolean markSupported() {
924:                return false;
925:            }
926:
927:            public int read() throws IOException {
928:                if (owner.chunkLength <= 0)
929:                    if (!owner.getData())
930:                        return -1;
931:                owner.chunkLength--;
932:                return owner.inbuf[owner.chunkStart++] & 0xFF;
933:            }
934:
935:            public int read(byte[] b) throws IOException {
936:                return read(b, 0, b.length);
937:            }
938:
939:            public int read(byte[] b, int st, int len) throws IOException {
940:                if (owner.chunkLength <= 0)
941:                    if (!owner.getData())
942:                        return -1;
943:                if (owner.chunkLength < len)
944:                    len = owner.chunkLength;
945:                System.arraycopy(owner.inbuf, owner.chunkStart, b, st, len);
946:                owner.chunkLength -= len;
947:                owner.chunkStart += len;
948:                return len;
949:            }
950:
951:            public long skip(long n) throws IOException {
952:                int i;
953:                for (i = 0; i < n && read() >= 0; i++)
954:                    ;
955:                return i;
956:            }
957:
958:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.