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


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