~hjd/ubuntu/wily/xmlgraphics-commons/debian-merged

« back to all changes in this revision

Viewing changes to src/java/org/apache/xmlgraphics/image/codec/png/PNGRed.java

  • Committer: Hans Joachim Desserud
  • Date: 2015-11-11 18:22:53 UTC
  • mfrom: (9.1.5 sid)
  • Revision ID: hans_joachim_desserud-20151111182253-zwi0frfm97j0wddn
  * Merge from Debian unstable.  Remaining changes:
    - d/control: Drop dependencies required for unit testing as they
      include libmockito-java which would pull maven into main, disable unit
      test execution.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 * limitations under the License.
16
16
 */
17
17
 
18
 
/* $Id: PNGRed.java 1345683 2012-06-03 14:50:33Z gadams $ */
 
18
/* $Id: PNGRed.java 1681698 2015-05-26 07:49:35Z ssteiner $ */
19
19
 
20
20
package org.apache.xmlgraphics.image.codec.png;
21
21
 
45
45
import java.util.GregorianCalendar;
46
46
import java.util.HashMap;
47
47
import java.util.List;
 
48
import java.util.Locale;
48
49
import java.util.Map;
49
50
import java.util.TimeZone;
50
51
import java.util.zip.Inflater;
65
66
// CSOFF: WhitespaceAround
66
67
 
67
68
/**
68
 
 * @version $Id: PNGRed.java 1345683 2012-06-03 14:50:33Z gadams $
 
69
 * @version $Id: PNGRed.java 1681698 2015-05-26 07:49:35Z ssteiner $
69
70
 */
70
71
public class PNGRed extends AbstractRed {
71
72
 
73
74
        int length;
74
75
        int type;
75
76
        byte[] data;
76
 
        int crc;
77
77
 
78
78
        String typeString;
79
79
 
81
81
            this.length = length;
82
82
            this.type = type;
83
83
            this.data = data;
84
 
            this.crc = crc;
85
84
 
86
85
            typeString = "";
87
86
            typeString += (char)(type >> 24);
115
114
        }
116
115
 
117
116
        public int getInt2(int offset) {
118
 
            return ((data[offset] & 0xff) << 8) |
119
 
                (data[offset + 1] & 0xff);
 
117
            return ((data[offset] & 0xff) << 8)
 
118
                | (data[offset + 1] & 0xff);
120
119
        }
121
120
 
122
121
        public int getInt4(int offset) {
123
 
            return ((data[offset] & 0xff) << 24) |
124
 
                ((data[offset + 1] & 0xff) << 16) |
125
 
                ((data[offset + 2] & 0xff) << 8) |
126
 
                (data[offset + 3] & 0xff);
 
122
            return ((data[offset] & 0xff) << 24)
 
123
                | ((data[offset + 1] & 0xff) << 16)
 
124
                | ((data[offset + 2] & 0xff) << 8)
 
125
                | (data[offset + 3] & 0xff);
127
126
        }
128
127
 
129
128
        public String getString4(int offset) {
130
 
            String s = new String();
 
129
            String s = "";
131
130
            s += (char)data[offset];
132
131
            s += (char)data[offset + 1];
133
132
            s += (char)data[offset + 2];
189
188
 
190
189
    private int maxOpacity;
191
190
 
192
 
    private int[] significantBits = null;
 
191
    private int[] significantBits;
193
192
 
194
193
    // Parameter information
195
194
 
196
195
    // If true, the user wants destination alpha where applicable.
197
 
    private boolean suppressAlpha = false;
 
196
    private boolean suppressAlpha;
198
197
 
199
198
    // If true, perform palette lookup internally
200
 
    private boolean expandPalette = false;
 
199
    private boolean expandPalette;
201
200
 
202
201
    // If true, output < 8 bit gray images in 8 bit components format
203
 
    private boolean output8BitGray = false;
 
202
    private boolean output8BitGray;
204
203
 
205
204
    // Create an alpha channel in the destination color model.
206
 
    private boolean outputHasAlphaPalette = false;
 
205
    private boolean outputHasAlphaPalette;
207
206
 
208
207
    // Perform gamma correction on the image
209
 
    private boolean performGammaCorrection = false;
 
208
    private boolean performGammaCorrection;
210
209
 
211
210
    // Expand GA to GGGA for compatbility with Java2D
212
 
    private boolean expandGrayAlpha = false;
 
211
    private boolean expandGrayAlpha;
213
212
 
214
213
    // Produce an instance of PNGEncodeParam
215
 
    private boolean generateEncodeParam = false;
 
214
    private boolean generateEncodeParam;
216
215
 
217
216
    // PNGDecodeParam controlling decode process
218
 
    private PNGDecodeParam decodeParam = null;
 
217
    private PNGDecodeParam decodeParam;
219
218
 
220
219
    // PNGEncodeParam to store file details in
221
 
    private PNGEncodeParam encodeParam = null;
 
220
    private PNGEncodeParam encodeParam;
222
221
 
223
222
    private boolean emitProperties = true;
224
223
 
225
 
    private float fileGamma = 45455/100000.0F;
 
224
    private float fileGamma = 45455 / 100000.0F;
226
225
 
227
226
    private float userExponent = 1.0F;
228
227
 
229
228
    private float displayExponent = 2.2F;
230
229
 
231
 
    private float[] chromaticity = null;
 
230
    private float[] chromaticity;
232
231
 
233
232
    private int sRGBRenderingIntent = -1;
234
233
 
294
293
    private int outputBands;
295
294
 
296
295
    // Number of private chunks
297
 
    private int chunkIndex = 0;
 
296
    private int chunkIndex;
298
297
 
299
298
    private List textKeys = new ArrayList();
300
299
    private List textStrings = new ArrayList();
309
308
    private Map<String, Object> properties = new HashMap<String, Object>();
310
309
 
311
310
 
312
 
    private int[] gammaLut = null;
 
311
    private int[] gammaLut;
313
312
 
314
313
    private void initGammaLut(int bits) {
315
 
        double exp = (double)userExponent/(fileGamma*displayExponent);
 
314
        double exp = (double)userExponent / (fileGamma * displayExponent);
316
315
        int numSamples = 1 << bits;
317
316
        int maxOutSample = (bits == 16) ? 65535 : 255;
318
317
 
319
318
        gammaLut = new int[numSamples];
320
319
        for (int i = 0; i < numSamples; i++) {
321
 
            double gbright = (double)i/(numSamples - 1);
 
320
            double gbright = (double)i / (numSamples - 1);
322
321
            double gamma = Math.pow(gbright, exp);
323
 
            int igamma = (int)(gamma*maxOutSample + 0.5);
 
322
            int igamma = (int)(gamma * maxOutSample + 0.5);
324
323
            if (igamma > maxOutSample) {
325
324
                igamma = maxOutSample;
326
325
            }
339
338
          (byte)0xcc, (byte)0xdd, (byte)0xee, (byte)0xff }
340
339
    };
341
340
 
342
 
    private int[] grayLut = null;
 
341
    private int[] grayLut;
343
342
 
344
343
    private void initGrayLut(int bits) {
345
344
        int len = 1 << bits;
388
387
            properties.put("file_type", "PNG v. 1.0");
389
388
        }
390
389
 
391
 
        try {
392
 
            long magic = distream.readLong();
393
 
            if (magic != 0x89504e470d0a1a0aL) {
394
 
                String msg = PropertyUtil.getString("PNGImageDecoder0");
395
 
                throw new RuntimeException(msg);
396
 
            }
397
 
        } catch (Exception e) {
398
 
            e.printStackTrace();
399
 
            String msg = PropertyUtil.getString("PNGImageDecoder1");
 
390
        long magic = distream.readLong();
 
391
        if (magic != 0x89504e470d0a1a0aL) {
 
392
            String msg = PropertyUtil.getString("PNGImageDecoder0");
400
393
            throw new RuntimeException(msg);
401
394
        }
402
395
 
403
396
        do {
404
 
            try {
405
 
                PNGChunk chunk;
 
397
            PNGChunk chunk;
406
398
 
407
 
                String chunkType = getChunkType(distream);
408
 
                if (chunkType.equals("IHDR")) {
409
 
                    chunk = readChunk(distream);
410
 
                    parse_IHDR_chunk(chunk);
411
 
                } else if (chunkType.equals("PLTE")) {
412
 
                    chunk = readChunk(distream);
413
 
                    parse_PLTE_chunk(chunk);
414
 
                } else if (chunkType.equals("IDAT")) {
415
 
                    chunk = readChunk(distream);
416
 
                    streamVec.add(new ByteArrayInputStream(chunk.getData()));
417
 
                } else if (chunkType.equals("IEND")) {
418
 
                    chunk = readChunk(distream);
 
399
            String chunkType = getChunkType(distream);
 
400
            if (chunkType.equals("IHDR")) {
 
401
                chunk = readChunk(distream);
 
402
                parse_IHDR_chunk(chunk);
 
403
            } else if (chunkType.equals("PLTE")) {
 
404
                chunk = readChunk(distream);
 
405
                parse_PLTE_chunk(chunk);
 
406
            } else if (chunkType.equals("IDAT")) {
 
407
                chunk = readChunk(distream);
 
408
                streamVec.add(new ByteArrayInputStream(chunk.getData()));
 
409
            } else if (chunkType.equals("IEND")) {
 
410
                chunk = readChunk(distream);
 
411
                try {
419
412
                    parse_IEND_chunk(chunk);
420
 
                    break; // fall through to the bottom
421
 
                } else if (chunkType.equals("bKGD")) {
422
 
                    chunk = readChunk(distream);
423
 
                    parse_bKGD_chunk(chunk);
424
 
                } else if (chunkType.equals("cHRM")) {
425
 
                    chunk = readChunk(distream);
426
 
                    parse_cHRM_chunk(chunk);
427
 
                } else if (chunkType.equals("gAMA")) {
428
 
                    chunk = readChunk(distream);
429
 
                    parse_gAMA_chunk(chunk);
430
 
                } else if (chunkType.equals("hIST")) {
431
 
                    chunk = readChunk(distream);
432
 
                    parse_hIST_chunk(chunk);
433
 
                } else if (chunkType.equals("iCCP")) {
434
 
                    chunk = readChunk(distream);
435
 
                    parse_iCCP_chunk(chunk);
436
 
                } else if (chunkType.equals("pHYs")) {
437
 
                    chunk = readChunk(distream);
438
 
                    parse_pHYs_chunk(chunk);
439
 
                } else if (chunkType.equals("sBIT")) {
440
 
                    chunk = readChunk(distream);
441
 
                    parse_sBIT_chunk(chunk);
442
 
                } else if (chunkType.equals("sRGB")) {
443
 
                    chunk = readChunk(distream);
444
 
                    parse_sRGB_chunk(chunk);
445
 
                } else if (chunkType.equals("tEXt")) {
446
 
                    chunk = readChunk(distream);
447
 
                    parse_tEXt_chunk(chunk);
448
 
                } else if (chunkType.equals("tIME")) {
449
 
                    chunk = readChunk(distream);
450
 
                    parse_tIME_chunk(chunk);
451
 
                } else if (chunkType.equals("tRNS")) {
452
 
                    chunk = readChunk(distream);
453
 
                    parse_tRNS_chunk(chunk);
454
 
                } else if (chunkType.equals("zTXt")) {
455
 
                    chunk = readChunk(distream);
456
 
                    parse_zTXt_chunk(chunk);
457
 
                } else {
458
 
                    chunk = readChunk(distream);
459
 
                    // Output the chunk data in raw form
 
413
                } catch (Exception e) {
 
414
                    e.printStackTrace();
 
415
                    String msg = PropertyUtil.getString("PNGImageDecoder2");
 
416
                    throw new RuntimeException(msg);
 
417
                }
 
418
                break; // fall through to the bottom
 
419
            } else if (chunkType.equals("bKGD")) {
 
420
                chunk = readChunk(distream);
 
421
                parse_bKGD_chunk(chunk);
 
422
            } else if (chunkType.equals("cHRM")) {
 
423
                chunk = readChunk(distream);
 
424
                parse_cHRM_chunk(chunk);
 
425
            } else if (chunkType.equals("gAMA")) {
 
426
                chunk = readChunk(distream);
 
427
                parse_gAMA_chunk(chunk);
 
428
            } else if (chunkType.equals("hIST")) {
 
429
                chunk = readChunk(distream);
 
430
                parse_hIST_chunk(chunk);
 
431
            } else if (chunkType.equals("iCCP")) {
 
432
                chunk = readChunk(distream);
 
433
            } else if (chunkType.equals("pHYs")) {
 
434
                chunk = readChunk(distream);
 
435
                parse_pHYs_chunk(chunk);
 
436
            } else if (chunkType.equals("sBIT")) {
 
437
                chunk = readChunk(distream);
 
438
                parse_sBIT_chunk(chunk);
 
439
            } else if (chunkType.equals("sRGB")) {
 
440
                chunk = readChunk(distream);
 
441
                parse_sRGB_chunk(chunk);
 
442
            } else if (chunkType.equals("tEXt")) {
 
443
                chunk = readChunk(distream);
 
444
                parse_tEXt_chunk(chunk);
 
445
            } else if (chunkType.equals("tIME")) {
 
446
                chunk = readChunk(distream);
 
447
                parse_tIME_chunk(chunk);
 
448
            } else if (chunkType.equals("tRNS")) {
 
449
                chunk = readChunk(distream);
 
450
                parse_tRNS_chunk(chunk);
 
451
            } else if (chunkType.equals("zTXt")) {
 
452
                chunk = readChunk(distream);
 
453
                parse_zTXt_chunk(chunk);
 
454
            } else {
 
455
                chunk = readChunk(distream);
 
456
                // Output the chunk data in raw form
460
457
 
461
 
                    String type = chunk.getTypeString();
462
 
                    byte[] data = chunk.getData();
463
 
                    if (encodeParam != null) {
464
 
                        encodeParam.addPrivateChunk(type, data);
465
 
                    }
466
 
                    if (emitProperties) {
467
 
                        String key = "chunk_" + chunkIndex++ + ':' + type;
468
 
                        properties.put(key.toLowerCase(), data);
469
 
                    }
470
 
                }
471
 
            } catch (Exception e) {
472
 
                e.printStackTrace();
473
 
                String msg = PropertyUtil.getString("PNGImageDecoder2");
474
 
                throw new RuntimeException(msg);
 
458
                String type = chunk.getTypeString();
 
459
                byte[] data = chunk.getData();
 
460
                if (encodeParam != null) {
 
461
                    encodeParam.addPrivateChunk(type, data);
 
462
                }
 
463
                if (emitProperties) {
 
464
                    String key = "chunk_" + chunkIndex++ + ':' + type;
 
465
                    properties.put(key.toLowerCase(Locale.getDefault()), data);
 
466
                }
475
467
            }
476
468
        } while (true);
477
469
 
502
494
                              + (char)((type >> 24) & 0xff)
503
495
                              + (char)((type >> 16) & 0xff)
504
496
                              + (char)((type >>  8) & 0xff)
505
 
                              + (char)( type        & 0xff);
 
497
                              + (char)(type        & 0xff);
506
498
            return typeString;
507
499
        } catch (Exception e) {
508
500
            e.printStackTrace();
542
534
        maxOpacity = (1 << bitDepth) - 1;
543
535
 
544
536
        colorType = chunk.getInt1(9);
545
 
        if ((colorType != PNG_COLOR_GRAY) &&
546
 
            (colorType != PNG_COLOR_RGB) &&
547
 
            (colorType != PNG_COLOR_PALETTE) &&
548
 
            (colorType != PNG_COLOR_GRAY_ALPHA) &&
549
 
            (colorType != PNG_COLOR_RGB_ALPHA)) {
 
537
        if ((colorType != PNG_COLOR_GRAY)
 
538
            && (colorType != PNG_COLOR_RGB)
 
539
            && (colorType != PNG_COLOR_PALETTE)
 
540
            && (colorType != PNG_COLOR_GRAY_ALPHA)
 
541
            && (colorType != PNG_COLOR_RGB_ALPHA)) {
550
542
            System.out.println(PropertyUtil.getString("PNGImageDecoder4"));
551
543
        }
552
544
 
581
573
        if (generateEncodeParam) {
582
574
            if (colorType == PNG_COLOR_PALETTE) {
583
575
                encodeParam = new PNGEncodeParam.Palette();
584
 
            } else if (colorType == PNG_COLOR_GRAY ||
585
 
                       colorType == PNG_COLOR_GRAY_ALPHA) {
 
576
            } else if (colorType == PNG_COLOR_GRAY
 
577
                       || colorType == PNG_COLOR_GRAY_ALPHA) {
586
578
                encodeParam = new PNGEncodeParam.Gray();
587
579
            } else {
588
580
                encodeParam = new PNGEncodeParam.RGB();
594
586
            encodeParam.setBitDepth(bitDepth);
595
587
        }
596
588
        if (emitProperties) {
597
 
            properties.put("bit_depth", new Integer(bitDepth));
 
589
            properties.put("bit_depth", bitDepth);
598
590
        }
599
591
 
600
592
        if (performGammaCorrection) {
601
593
            // Assume file gamma is 1/2.2 unless we get a gAMA chunk
602
 
            float gamma = (1.0F/2.2F)*(displayExponent/userExponent);
 
594
            float gamma = (1.0F / 2.2F) * (displayExponent / userExponent);
603
595
            if (encodeParam != null) {
604
596
                encodeParam.setGamma(gamma);
605
597
            }
606
598
            if (emitProperties) {
607
 
                properties.put("gamma", new Float(gamma));
 
599
                properties.put("gamma", gamma);
608
600
            }
609
601
        }
610
602
 
724
716
    private void parse_IEND_chunk(PNGChunk chunk) throws Exception {
725
717
        // Store text strings
726
718
        int textLen = textKeys.size();
727
 
        String[] textArray = new String[2*textLen];
 
719
        String[] textArray = new String[2 * textLen];
728
720
        for (int i = 0; i < textLen; i++) {
729
721
            String key = (String)textKeys.get(i);
730
722
            String val = (String)textStrings.get(i);
731
 
            textArray[2*i] = key;
732
 
            textArray[2*i + 1] = val;
 
723
            textArray[2 * i] = key;
 
724
            textArray[2 * i + 1] = val;
733
725
            if (emitProperties) {
734
726
                String uniqueKey = "text_" + i + ':' + key;
735
 
                properties.put(uniqueKey.toLowerCase(), val);
 
727
                properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val);
736
728
            }
737
729
        }
738
730
        if (encodeParam != null) {
741
733
 
742
734
        // Store compressed text strings
743
735
        int ztextLen = ztextKeys.size();
744
 
        String[] ztextArray = new String[2*ztextLen];
 
736
        String[] ztextArray = new String[2 * ztextLen];
745
737
        for (int i = 0; i < ztextLen; i++) {
746
738
            String key = (String)ztextKeys.get(i);
747
739
            String val = (String)ztextStrings.get(i);
748
 
            ztextArray[2*i] = key;
749
 
            ztextArray[2*i + 1] = val;
 
740
            ztextArray[2 * i] = key;
 
741
            ztextArray[2 * i + 1] = val;
750
742
            if (emitProperties) {
751
743
                String uniqueKey = "ztext_" + i + ':' + key;
752
 
                properties.put(uniqueKey.toLowerCase(), val);
 
744
                properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val);
753
745
            }
754
746
        }
755
747
        if (encodeParam != null) {
758
750
 
759
751
        // Parse prior IDAT chunks
760
752
        InputStream seqStream =
761
 
            new SequenceInputStream( Collections.enumeration( streamVec ));
 
753
            new SequenceInputStream(Collections.enumeration(streamVec));
762
754
        InputStream infStream =
763
755
            new InflaterInputStream(seqStream, new Inflater());
764
756
        dataStream = new DataInputStream(infStream);
765
757
 
766
758
        // Create an empty WritableRaster
767
759
        int depth = bitDepth;
768
 
        if ((colorType == PNG_COLOR_GRAY) &&
769
 
            (bitDepth < 8) && output8BitGray) {
 
760
        if ((colorType == PNG_COLOR_GRAY)
 
761
            && (bitDepth < 8) && output8BitGray) {
770
762
            depth = 8;
771
763
        }
772
764
        if ((colorType == PNG_COLOR_PALETTE) && expandPalette) {
775
767
        int width  = bounds.width;
776
768
        int height = bounds.height;
777
769
 
778
 
        int bytesPerRow = (outputBands*width*depth + 7)/8;
 
770
        int bytesPerRow = (outputBands * width * depth + 7) / 8;
779
771
        int scanlineStride =
780
 
            (depth == 16) ? (bytesPerRow/2) : bytesPerRow;
 
772
            (depth == 16) ? (bytesPerRow / 2) : bytesPerRow;
781
773
 
782
774
        theTile = createRaster(width, height, outputBands,
783
775
                               scanlineStride,
786
778
        if (performGammaCorrection && (gammaLut == null)) {
787
779
            initGammaLut(bitDepth);
788
780
        }
789
 
        if ((postProcess == POST_GRAY_LUT) ||
790
 
            (postProcess == POST_GRAY_LUT_ADD_TRANS) ||
791
 
            (postProcess == POST_GRAY_LUT_ADD_TRANS_EXP)) {
 
781
        if ((postProcess == POST_GRAY_LUT)
 
782
            || (postProcess == POST_GRAY_LUT_ADD_TRANS)
 
783
            || (postProcess == POST_GRAY_LUT_ADD_TRANS_EXP)) {
792
784
            initGrayLut(bitDepth);
793
785
        }
794
786
 
818
810
                                                 greenPalette,
819
811
                                                 bluePalette);
820
812
            }
821
 
        } else if ((colorType == PNG_COLOR_GRAY) &&
822
 
                   (bitDepth < 8) && !output8BitGray) {
 
813
        } else if ((colorType == PNG_COLOR_GRAY)
 
814
                   && (bitDepth < 8) && !output8BitGray) {
823
815
            byte[] palette = expandBits[bitDepth];
824
816
            cm = new IndexColorModel(bitDepth,
825
817
                                             palette.length,
983
975
    }
984
976
 
985
977
    private void parse_PLTE_chunk(PNGChunk chunk) {
986
 
        paletteEntries = chunk.getLength()/3;
 
978
        paletteEntries = chunk.getLength() / 3;
987
979
        redPalette = new byte[paletteEntries];
988
980
        greenPalette = new byte[paletteEntries];
989
981
        bluePalette = new byte[paletteEntries];
1024
1016
            bkgdBlue  = bluePalette[bkgdIndex]  & 0xff;
1025
1017
 
1026
1018
            if (encodeParam != null) {
1027
 
                ((PNGEncodeParam.Palette)encodeParam).
1028
 
                    setBackgroundPaletteIndex(bkgdIndex);
 
1019
                ((PNGEncodeParam.Palette)encodeParam).setBackgroundPaletteIndex(bkgdIndex);
1029
1020
            }
1030
1021
            break;
1031
1022
        case PNG_COLOR_GRAY: case PNG_COLOR_GRAY_ALPHA:
1033
1024
            bkgdRed = bkgdGreen = bkgdBlue = bkgdGray;
1034
1025
 
1035
1026
            if (encodeParam != null) {
1036
 
                ((PNGEncodeParam.Gray)encodeParam).
1037
 
                    setBackgroundGray(bkgdGray);
 
1027
                ((PNGEncodeParam.Gray)encodeParam).setBackgroundGray(bkgdGray);
1038
1028
            }
1039
1029
            break;
1040
1030
        case PNG_COLOR_RGB: case PNG_COLOR_RGB_ALPHA:
1047
1037
            bkgdRGB[1] = bkgdGreen;
1048
1038
            bkgdRGB[2] = bkgdBlue;
1049
1039
            if (encodeParam != null) {
1050
 
                ((PNGEncodeParam.RGB)encodeParam).
1051
 
                    setBackgroundRGB(bkgdRGB);
 
1040
                ((PNGEncodeParam.RGB)encodeParam).setBackgroundRGB(bkgdRGB);
1052
1041
            }
1053
1042
            break;
1054
1043
        }
1055
1044
 
1056
1045
        if (emitProperties) {
1057
 
            int r = 0, g = 0, b = 0;
 
1046
            int r = 0;
 
1047
            int g = 0;
 
1048
            int b = 0;
1058
1049
            if ((colorType == PNG_COLOR_PALETTE) || (bitDepth == 8)) {
1059
1050
                r = bkgdRed;
1060
1051
                g = bkgdGreen;
1079
1070
        }
1080
1071
 
1081
1072
        chromaticity = new float[8];
1082
 
        chromaticity[0] = chunk.getInt4(0)/100000.0F;
1083
 
        chromaticity[1] = chunk.getInt4(4)/100000.0F;
1084
 
        chromaticity[2] = chunk.getInt4(8)/100000.0F;
1085
 
        chromaticity[3] = chunk.getInt4(12)/100000.0F;
1086
 
        chromaticity[4] = chunk.getInt4(16)/100000.0F;
1087
 
        chromaticity[5] = chunk.getInt4(20)/100000.0F;
1088
 
        chromaticity[6] = chunk.getInt4(24)/100000.0F;
1089
 
        chromaticity[7] = chunk.getInt4(28)/100000.0F;
 
1073
        chromaticity[0] = chunk.getInt4(0) / 100000.0F;
 
1074
        chromaticity[1] = chunk.getInt4(4) / 100000.0F;
 
1075
        chromaticity[2] = chunk.getInt4(8) / 100000.0F;
 
1076
        chromaticity[3] = chunk.getInt4(12) / 100000.0F;
 
1077
        chromaticity[4] = chunk.getInt4(16) / 100000.0F;
 
1078
        chromaticity[5] = chunk.getInt4(20) / 100000.0F;
 
1079
        chromaticity[6] = chunk.getInt4(24) / 100000.0F;
 
1080
        chromaticity[7] = chunk.getInt4(28) / 100000.0F;
1090
1081
 
1091
1082
        if (encodeParam != null) {
1092
1083
            encodeParam.setChromaticity(chromaticity);
1093
1084
        }
1094
1085
        if (emitProperties) {
1095
 
            properties.put("white_point_x", new Float(chromaticity[0]));
1096
 
            properties.put("white_point_y", new Float(chromaticity[1]));
1097
 
            properties.put("red_x", new Float(chromaticity[2]));
1098
 
            properties.put("red_y", new Float(chromaticity[3]));
1099
 
            properties.put("green_x", new Float(chromaticity[4]));
1100
 
            properties.put("green_y", new Float(chromaticity[5]));
1101
 
            properties.put("blue_x", new Float(chromaticity[6]));
1102
 
            properties.put("blue_y", new Float(chromaticity[7]));
 
1086
            properties.put("white_point_x", chromaticity[0]);
 
1087
            properties.put("white_point_y", chromaticity[1]);
 
1088
            properties.put("red_x", chromaticity[2]);
 
1089
            properties.put("red_y", chromaticity[3]);
 
1090
            properties.put("green_x", chromaticity[4]);
 
1091
            properties.put("green_y", chromaticity[5]);
 
1092
            properties.put("blue_x", chromaticity[6]);
 
1093
            properties.put("blue_y", chromaticity[7]);
1103
1094
        }
1104
1095
    }
1105
1096
 
1109
1100
            return;
1110
1101
        }
1111
1102
 
1112
 
        fileGamma = chunk.getInt4(0)/100000.0F;
 
1103
        fileGamma = chunk.getInt4(0) / 100000.0F;
1113
1104
        // System.out.println("Gamma: " + fileGamma);
1114
1105
        float exp =
1115
 
            performGammaCorrection ? displayExponent/userExponent : 1.0F;
 
1106
            performGammaCorrection ? displayExponent / userExponent : 1.0F;
1116
1107
        if (encodeParam != null) {
1117
 
            encodeParam.setGamma(fileGamma*exp);
 
1108
            encodeParam.setGamma(fileGamma * exp);
1118
1109
        }
1119
1110
        if (emitProperties) {
1120
 
            properties.put("gamma", new Float(fileGamma*exp));
 
1111
            properties.put("gamma", fileGamma * exp);
1121
1112
        }
1122
1113
    }
1123
1114
 
1130
1121
        int length = redPalette.length;
1131
1122
        int[] hist = new int[length];
1132
1123
        for (int i = 0; i < length; i++) {
1133
 
            hist[i] = chunk.getInt2(2*i);
 
1124
            hist[i] = chunk.getInt2(2 * i);
1134
1125
        }
1135
1126
 
1136
1127
        if (encodeParam != null) {
1138
1129
        }
1139
1130
    }
1140
1131
 
1141
 
    private void parse_iCCP_chunk(PNGChunk chunk) {
1142
 
        String name = "";
1143
 
        byte b;
1144
 
 
1145
 
        int textIndex = 0;
1146
 
        while ((b = chunk.getByte(textIndex++)) != 0) {
1147
 
            name += (char)b;
1148
 
        }
1149
 
    }
1150
 
 
1151
1132
    private void parse_pHYs_chunk(PNGChunk chunk) {
1152
1133
        int xPixelsPerUnit = chunk.getInt4(0);
1153
1134
        int yPixelsPerUnit = chunk.getInt4(4);
1159
1140
                                             unitSpecifier);
1160
1141
        }
1161
1142
        if (emitProperties) {
1162
 
            properties.put("x_pixels_per_unit", new Integer(xPixelsPerUnit));
1163
 
            properties.put("y_pixels_per_unit", new Integer(yPixelsPerUnit));
 
1143
            properties.put("x_pixels_per_unit", xPixelsPerUnit);
 
1144
            properties.put("y_pixels_per_unit", yPixelsPerUnit);
1164
1145
            properties.put("pixel_aspect_ratio",
1165
 
                           new Float((float)xPixelsPerUnit/yPixelsPerUnit));
 
1146
                    (float) xPixelsPerUnit / yPixelsPerUnit);
1166
1147
            if (unitSpecifier == 1) {
1167
1148
                properties.put("pixel_units", "Meters");
1168
1149
            } else if (unitSpecifier != 0) {
1204
1185
 
1205
1186
        // The presence of an sRGB chunk implies particular
1206
1187
        // settings for gamma and chroma.
1207
 
        fileGamma = 45455/100000.0F;
 
1188
        fileGamma = 45455 / 100000.0F;
1208
1189
 
1209
1190
        chromaticity = new float[8];
1210
 
        chromaticity[0] = 31270/10000.0F;
1211
 
        chromaticity[1] = 32900/10000.0F;
1212
 
        chromaticity[2] = 64000/10000.0F;
1213
 
        chromaticity[3] = 33000/10000.0F;
1214
 
        chromaticity[4] = 30000/10000.0F;
1215
 
        chromaticity[5] = 60000/10000.0F;
1216
 
        chromaticity[6] = 15000/10000.0F;
1217
 
        chromaticity[7] =  6000/10000.0F;
 
1191
        chromaticity[0] = 31270 / 10000.0F;
 
1192
        chromaticity[1] = 32900 / 10000.0F;
 
1193
        chromaticity[2] = 64000 / 10000.0F;
 
1194
        chromaticity[3] = 33000 / 10000.0F;
 
1195
        chromaticity[4] = 30000 / 10000.0F;
 
1196
        chromaticity[5] = 60000 / 10000.0F;
 
1197
        chromaticity[6] = 15000 / 10000.0F;
 
1198
        chromaticity[7] =  6000 / 10000.0F;
1218
1199
 
1219
1200
        if (performGammaCorrection) {
1220
1201
            // File gamma is 1/2.2
1221
 
            float gamma = fileGamma*(displayExponent/userExponent);
 
1202
            float gamma = fileGamma * (displayExponent / userExponent);
1222
1203
            if (encodeParam != null) {
1223
1204
                encodeParam.setGamma(gamma);
1224
1205
                encodeParam.setChromaticity(chromaticity);
1225
1206
            }
1226
1207
            if (emitProperties) {
1227
 
                properties.put("gamma", new Float(gamma));
1228
 
                properties.put("white_point_x", new Float(chromaticity[0]));
1229
 
                properties.put("white_point_y", new Float(chromaticity[1]));
1230
 
                properties.put("red_x", new Float(chromaticity[2]));
1231
 
                properties.put("red_y", new Float(chromaticity[3]));
1232
 
                properties.put("green_x", new Float(chromaticity[4]));
1233
 
                properties.put("green_y", new Float(chromaticity[5]));
1234
 
                properties.put("blue_x", new Float(chromaticity[6]));
1235
 
                properties.put("blue_y", new Float(chromaticity[7]));
 
1208
                properties.put("gamma", gamma);
 
1209
                properties.put("white_point_x", chromaticity[0]);
 
1210
                properties.put("white_point_y", chromaticity[1]);
 
1211
                properties.put("red_x", chromaticity[2]);
 
1212
                properties.put("red_y", chromaticity[3]);
 
1213
                properties.put("green_x", chromaticity[4]);
 
1214
                properties.put("green_y", chromaticity[5]);
 
1215
                properties.put("blue_x", chromaticity[6]);
 
1216
                properties.put("blue_y", chromaticity[7]);
1236
1217
            }
1237
1218
        }
1238
1219
    }
1326
1307
                }
1327
1308
 
1328
1309
                if (encodeParam != null) {
1329
 
                    ((PNGEncodeParam.Gray)encodeParam).
1330
 
                        setTransparentGray(grayTransparentAlpha);
 
1310
                    ((PNGEncodeParam.Gray)encodeParam).setTransparentGray(grayTransparentAlpha);
1331
1311
                }
1332
1312
            }
1333
1313
        } else if (colorType == PNG_COLOR_RGB) {
1344
1324
                    rgbTrans[0] = redTransparentAlpha;
1345
1325
                    rgbTrans[1] = greenTransparentAlpha;
1346
1326
                    rgbTrans[2] = blueTransparentAlpha;
1347
 
                    ((PNGEncodeParam.RGB)encodeParam).
1348
 
                        setTransparentRGB(rgbTrans);
 
1327
                    ((PNGEncodeParam.RGB)encodeParam).setTransparentRGB(rgbTrans);
1349
1328
                }
1350
1329
            }
1351
 
        } else if (colorType == PNG_COLOR_GRAY_ALPHA ||
1352
 
                   colorType == PNG_COLOR_RGB_ALPHA) {
 
1330
        } else if (colorType == PNG_COLOR_GRAY_ALPHA
 
1331
                   || colorType == PNG_COLOR_RGB_ALPHA) {
1353
1332
            // Error -- GA or RGBA image can't have a tRNS chunk.
1354
1333
            String msg = PropertyUtil.getString("PNGImageDecoder15");
1355
1334
            throw new RuntimeException(msg);
1379
1358
                value.append((char)c);
1380
1359
            }
1381
1360
 
1382
 
            ztextKeys.add(key.toString() );
1383
 
            ztextStrings.add(value.toString() );
 
1361
            ztextKeys.add(key.toString());
 
1362
            ztextStrings.add(value.toString());
1384
1363
        } catch (Exception e) {
1385
1364
            e.printStackTrace();
1386
1365
        }
1394
1373
        WritableRaster ras = null;
1395
1374
        Point origin = new Point(0, 0);
1396
1375
        if ((bitDepth < 8) && (bands == 1)) {
1397
 
            dataBuffer = new DataBufferByte(height*scanlineStride);
 
1376
            dataBuffer = new DataBufferByte(height * scanlineStride);
1398
1377
            ras = Raster.createPackedRaster(dataBuffer,
1399
1378
                                            width, height,
1400
1379
                                            bitDepth,
1401
1380
                                            origin);
1402
1381
        } else if (bitDepth <= 8) {
1403
 
            dataBuffer = new DataBufferByte(height*scanlineStride);
 
1382
            dataBuffer = new DataBufferByte(height * scanlineStride);
1404
1383
           ras = Raster.createInterleavedRaster(dataBuffer,
1405
1384
                                                 width, height,
1406
1385
                                                 scanlineStride,
1408
1387
                                                 bandOffsets[bands],
1409
1388
                                                 origin);
1410
1389
        } else {
1411
 
            dataBuffer = new DataBufferUShort(height*scanlineStride);
 
1390
            dataBuffer = new DataBufferUShort(height * scanlineStride);
1412
1391
            ras = Raster.createInterleavedRaster(dataBuffer,
1413
1392
                                                 width, height,
1414
1393
                                                 scanlineStride,
1449
1428
            int raw      = curr[i] & 0xff;
1450
1429
            int priorRow = prev[i] & 0xff;
1451
1430
 
1452
 
            curr[i] = (byte)(raw + priorRow/2);
 
1431
            curr[i] = (byte)(raw + priorRow / 2);
1453
1432
        }
1454
1433
 
1455
1434
        for (int i = bpp; i < count; i++) {
1457
1436
            int priorPixel = curr[i - bpp] & 0xff;
1458
1437
            int priorRow = prev[i] & 0xff;
1459
1438
 
1460
 
            curr[i] = (byte)(raw + (priorPixel + priorRow)/2);
 
1439
            curr[i] = (byte)(raw + (priorPixel + priorRow) / 2);
1461
1440
        }
1462
1441
    }
1463
1442
 
1478
1457
 
1479
1458
    private static void decodePaethFilter(byte[] curr, byte[] prev,
1480
1459
                                          int count, int bpp) {
1481
 
        int priorPixel, priorRowPixel;
 
1460
        int priorPixel;
 
1461
        int priorRowPixel;
1482
1462
 
1483
1463
        for (int i = 0; i < bpp; i++) {
1484
1464
            int raw = curr[i] & 0xff;
1502
1482
    private void processPixels(int process,
1503
1483
                               Raster src, WritableRaster dst,
1504
1484
                               int xOffset, int step, int y, int width) {
1505
 
        int srcX, dstX;
 
1485
        int srcX;
 
1486
        int dstX;
1506
1487
 
1507
1488
        // Create an array suitable for holding one pixel
1508
1489
        int[] ps = src.getPixel(0, 0, (int[])null);
1627
1608
                    pd[1] = g;
1628
1609
                    pd[2] = b;
1629
1610
                }
1630
 
                if ((r == redTransparentAlpha) &&
1631
 
                    (g == greenTransparentAlpha) &&
1632
 
                    (b == blueTransparentAlpha)) {
 
1611
                if ((r == redTransparentAlpha)
 
1612
                    && (g == greenTransparentAlpha)
 
1613
                    && (b == blueTransparentAlpha)) {
1633
1614
                    pd[3] = 0;
1634
1615
                } else {
1635
1616
                    pd[3] = maxOpacity;
1767
1748
            return;
1768
1749
        }
1769
1750
 
1770
 
        int bytesPerRow = (inputBands*passWidth*bitDepth + 7)/8;
1771
 
        int eltsPerRow = (bitDepth == 16) ? bytesPerRow/2 : bytesPerRow;
 
1751
        int bytesPerRow = (inputBands * passWidth * bitDepth + 7) / 8;
 
1752
        int eltsPerRow = (bitDepth == 16) ? bytesPerRow / 2 : bytesPerRow;
1772
1753
        byte[] curr = new byte[bytesPerRow];
1773
1754
        byte[] prior = new byte[bytesPerRow];
1774
1755
 
1788
1769
        }
1789
1770
 
1790
1771
        // Decode the (sub)image row-by-row
1791
 
        int srcY, dstY;
 
1772
        int srcY;
 
1773
        int dstY;
1792
1774
        for (srcY = 0, dstY = yOffset;
1793
1775
             srcY < passHeight;
1794
1776
             srcY++, dstY += yStep) {
1851
1833
        if (!useInterlacing) {
1852
1834
            decodePass(theTile, 0, 0, 1, 1, width, height);
1853
1835
        } else {
1854
 
            decodePass(theTile, 0, 0, 8, 8, (width + 7)/8, (height + 7)/8);
1855
 
            decodePass(theTile, 4, 0, 8, 8, (width + 3)/8, (height + 7)/8);
1856
 
            decodePass(theTile, 0, 4, 4, 8, (width + 3)/4, (height + 3)/8);
1857
 
            decodePass(theTile, 2, 0, 4, 4, (width + 1)/4, (height + 3)/4);
1858
 
            decodePass(theTile, 0, 2, 2, 4, (width + 1)/2, (height + 1)/4);
1859
 
            decodePass(theTile, 1, 0, 2, 2, width/2, (height + 1)/2);
1860
 
            decodePass(theTile, 0, 1, 1, 2, width, height/2);
 
1836
            decodePass(theTile, 0, 0, 8, 8, (width + 7) / 8, (height + 7) / 8);
 
1837
            decodePass(theTile, 4, 0, 8, 8, (width + 3) / 8, (height + 7) / 8);
 
1838
            decodePass(theTile, 0, 4, 4, 8, (width + 3) / 4, (height + 3) / 8);
 
1839
            decodePass(theTile, 2, 0, 4, 4, (width + 1) / 4, (height + 3) / 4);
 
1840
            decodePass(theTile, 0, 2, 2, 4, (width + 1) / 2, (height + 1) / 4);
 
1841
            decodePass(theTile, 1, 0, 2, 2, width / 2, (height + 1) / 2);
 
1842
            decodePass(theTile, 0, 1, 1, 2, width, height / 2);
1861
1843
        }
1862
1844
    }
1863
1845