~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/PNGImageDecoder.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: PNGImageDecoder.java 1353184 2012-06-23 19:18:01Z gadams $ */
 
18
/* $Id: PNGImageDecoder.java 1681698 2015-05-26 07:49:35Z ssteiner $ */
19
19
 
20
20
package org.apache.xmlgraphics.image.codec.png;
21
21
 
44
44
import java.util.Date;
45
45
import java.util.GregorianCalendar;
46
46
import java.util.List;
 
47
import java.util.Locale;
47
48
import java.util.TimeZone;
48
49
import java.util.zip.Inflater;
49
50
import java.util.zip.InflaterInputStream;
63
64
// CSOFF: WhitespaceAround
64
65
 
65
66
/**
66
 
 * @version $Id: PNGImageDecoder.java 1353184 2012-06-23 19:18:01Z gadams $
 
67
 * @version $Id: PNGImageDecoder.java 1681698 2015-05-26 07:49:35Z ssteiner $
67
68
 */
68
69
public class PNGImageDecoder extends ImageDecoderImpl {
69
70
 
126
127
 
127
128
    private int maxOpacity;
128
129
 
129
 
    private int[] significantBits = null;
 
130
    private int[] significantBits;
130
131
 
131
132
    // Parameter information
132
133
 
133
134
    // If true, the user wants destination alpha where applicable.
134
 
    private boolean suppressAlpha = false;
 
135
    private boolean suppressAlpha;
135
136
 
136
137
    // If true, perform palette lookup internally
137
 
    private boolean expandPalette = false;
 
138
    private boolean expandPalette;
138
139
 
139
140
    // If true, output < 8 bit gray images in 8 bit components format
140
 
    private boolean output8BitGray = false;
 
141
    private boolean output8BitGray;
141
142
 
142
143
    // Create an alpha channel in the destination color model.
143
 
    private boolean outputHasAlphaPalette = false;
 
144
    private boolean outputHasAlphaPalette;
144
145
 
145
146
    // Perform gamma correction on the image
146
 
    private boolean performGammaCorrection = false;
 
147
    private boolean performGammaCorrection;
147
148
 
148
149
    // Expand GA to GGGA for compatbility with Java2D
149
 
    private boolean expandGrayAlpha = false;
 
150
    private boolean expandGrayAlpha;
150
151
 
151
152
    // Produce an instance of PNGEncodeParam
152
 
    private boolean generateEncodeParam = false;
 
153
    private boolean generateEncodeParam;
153
154
 
154
155
    // PNGDecodeParam controlling decode process
155
 
    private PNGDecodeParam decodeParam = null;
 
156
    private PNGDecodeParam decodeParam;
156
157
 
157
158
    // PNGEncodeParam to store file details in
158
 
    private PNGEncodeParam encodeParam = null;
 
159
    private PNGEncodeParam encodeParam;
159
160
 
160
161
    private boolean emitProperties = true;
161
162
 
162
 
    private float fileGamma = 45455/100000.0F;
 
163
    private float fileGamma = 45455 / 100000.0F;
163
164
 
164
165
    private float userExponent = 1.0F;
165
166
 
166
167
    private float displayExponent = 2.2F;
167
168
 
168
 
    private float[] chromaticity = null;
 
169
    private float[] chromaticity;
169
170
 
170
171
    private int sRGBRenderingIntent = -1;
171
172
 
231
232
    private int outputBands;
232
233
 
233
234
    // Number of private chunks
234
 
    private int chunkIndex = 0;
 
235
    private int chunkIndex;
235
236
 
236
237
    private List textKeys = new ArrayList();
237
238
    private List textStrings = new ArrayList();
241
242
 
242
243
    private WritableRaster theTile;
243
244
 
244
 
    private int[] gammaLut = null;
 
245
    private int[] gammaLut;
245
246
 
246
247
    private void initGammaLut(int bits) {
247
 
        double exp = (double)userExponent/(fileGamma*displayExponent);
 
248
        double exp = (double)userExponent / (fileGamma * displayExponent);
248
249
        int numSamples = 1 << bits;
249
250
        int maxOutSample = (bits == 16) ? 65535 : 255;
250
251
 
251
252
        gammaLut = new int[numSamples];
252
253
        for (int i = 0; i < numSamples; i++) {
253
 
            double gbright = (double)i/(numSamples - 1);
 
254
            double gbright = (double)i / (numSamples - 1);
254
255
            double gamma = Math.pow(gbright, exp);
255
 
            int igamma = (int)(gamma*maxOutSample + 0.5);
 
256
            int igamma = (int)(gamma * maxOutSample + 0.5);
256
257
            if (igamma > maxOutSample) {
257
258
                igamma = maxOutSample;
258
259
            }
271
272
          (byte)0xcc, (byte)0xdd, (byte)0xee, (byte)0xff }
272
273
    };
273
274
 
274
 
    private int[] grayLut = null;
 
275
    private int[] grayLut;
275
276
 
276
277
    private void initGrayLut(int bits) {
277
278
        int len = 1 << bits;
329
330
        }
330
331
 
331
332
        do {
332
 
            try {
 
333
//            try {
333
334
                PNGChunk chunk;
334
335
 
335
336
                String chunkType = PNGChunk.getChunkType(distream);
344
345
                    streamVec.add(new ByteArrayInputStream(chunk.getData()));
345
346
                } else if (chunkType.equals(PNGChunk.ChunkType.IEND.name())) {
346
347
                    chunk = PNGChunk.readChunk(distream);
347
 
                    parse_IEND_chunk(chunk);
 
348
                    try {
 
349
                        parse_IEND_chunk(chunk);
 
350
                    } catch (Exception e) {
 
351
                        e.printStackTrace();
 
352
                        String msg = PropertyUtil.getString("PNGImageDecoder2");
 
353
                        throw new RuntimeException(msg);
 
354
                    }
348
355
                    break; // fall through to the bottom
349
356
                } else if (chunkType.equals(PNGChunk.ChunkType.bKGD.name())) {
350
357
                    chunk = PNGChunk.readChunk(distream);
393
400
                    }
394
401
                    if (emitProperties) {
395
402
                        String key = "chunk_" + chunkIndex++ + ':' + type;
396
 
                        properties.put(key.toLowerCase(), data);
 
403
                        properties.put(key.toLowerCase(Locale.getDefault()), data);
397
404
                    }
398
405
                }
399
 
            } catch (Exception e) {
400
 
                e.printStackTrace();
401
 
                String msg = PropertyUtil.getString("PNGImageDecoder2");
402
 
                throw new RuntimeException(msg);
403
 
            }
 
406
//            } catch (Exception e) {
 
407
//                e.printStackTrace();
 
408
//                String msg = PropertyUtil.getString("PNGImageDecoder2");
 
409
//                throw new RuntimeException(msg);
 
410
//            }
404
411
        } while (true);
405
412
 
406
413
        // Final post-processing
423
430
 
424
431
        bitDepth = chunk.getInt1(8);
425
432
 
426
 
        if ((bitDepth != 1) && (bitDepth != 2) && (bitDepth != 4) &&
427
 
            (bitDepth != 8) && (bitDepth != 16)) {
 
433
        if ((bitDepth != 1) && (bitDepth != 2) && (bitDepth != 4)
 
434
            && (bitDepth != 8) && (bitDepth != 16)) {
428
435
            // Error -- bad bit depth
429
436
            String msg = PropertyUtil.getString("PNGImageDecoder3");
430
437
            throw new RuntimeException(msg);
432
439
        maxOpacity = (1 << bitDepth) - 1;
433
440
 
434
441
        colorType = chunk.getInt1(9);
435
 
        if ((colorType != PNG_COLOR_GRAY) &&
436
 
            (colorType != PNG_COLOR_RGB) &&
437
 
            (colorType != PNG_COLOR_PALETTE) &&
438
 
            (colorType != PNG_COLOR_GRAY_ALPHA) &&
439
 
            (colorType != PNG_COLOR_RGB_ALPHA)) {
 
442
        if ((colorType != PNG_COLOR_GRAY)
 
443
            && (colorType != PNG_COLOR_RGB)
 
444
            && (colorType != PNG_COLOR_PALETTE)
 
445
            && (colorType != PNG_COLOR_GRAY_ALPHA)
 
446
            && (colorType != PNG_COLOR_RGB_ALPHA)) {
440
447
            System.out.println(PropertyUtil.getString("PNGImageDecoder4"));
441
448
        }
442
449
 
471
478
        if (generateEncodeParam) {
472
479
            if (colorType == PNG_COLOR_PALETTE) {
473
480
                encodeParam = new PNGEncodeParam.Palette();
474
 
            } else if (colorType == PNG_COLOR_GRAY ||
475
 
                       colorType == PNG_COLOR_GRAY_ALPHA) {
 
481
            } else if (colorType == PNG_COLOR_GRAY
 
482
                       || colorType == PNG_COLOR_GRAY_ALPHA) {
476
483
                encodeParam = new PNGEncodeParam.Gray();
477
484
            } else {
478
485
                encodeParam = new PNGEncodeParam.RGB();
484
491
            encodeParam.setBitDepth(bitDepth);
485
492
        }
486
493
        if (emitProperties) {
487
 
            properties.put("bit_depth", new Integer(bitDepth));
 
494
            properties.put("bit_depth", bitDepth);
488
495
        }
489
496
 
490
497
        if (performGammaCorrection) {
491
498
            // Assume file gamma is 1/2.2 unless we get a gAMA chunk
492
 
            float gamma = (1.0F/2.2F)*(displayExponent/userExponent);
 
499
            float gamma = (1.0F / 2.2F) * (displayExponent / userExponent);
493
500
            if (encodeParam != null) {
494
501
                encodeParam.setGamma(gamma);
495
502
            }
496
503
            if (emitProperties) {
497
 
                properties.put("gamma", new Float(gamma));
 
504
                properties.put("gamma", gamma);
498
505
            }
499
506
        }
500
507
 
614
621
    private void parse_IEND_chunk(PNGChunk chunk) throws Exception {
615
622
        // Store text strings
616
623
        int textLen = textKeys.size();
617
 
        String[] textArray = new String[2*textLen];
 
624
        String[] textArray = new String[2 * textLen];
618
625
        for (int i = 0; i < textLen; i++) {
619
626
            String key = (String)textKeys.get(i);
620
627
            String val = (String)textStrings.get(i);
621
 
            textArray[2*i] = key;
622
 
            textArray[2*i + 1] = val;
 
628
            textArray[2 * i] = key;
 
629
            textArray[2 * i + 1] = val;
623
630
            if (emitProperties) {
624
631
                String uniqueKey = "text_" + i + ':' + key;
625
 
                properties.put(uniqueKey.toLowerCase(), val);
 
632
                properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val);
626
633
            }
627
634
        }
628
635
        if (encodeParam != null) {
631
638
 
632
639
        // Store compressed text strings
633
640
        int ztextLen = ztextKeys.size();
634
 
        String[] ztextArray = new String[2*ztextLen];
 
641
        String[] ztextArray = new String[2 * ztextLen];
635
642
        for (int i = 0; i < ztextLen; i++) {
636
643
            String key = (String)ztextKeys.get(i);
637
644
            String val = (String)ztextStrings.get(i);
638
 
            ztextArray[2*i] = key;
639
 
            ztextArray[2*i + 1] = val;
 
645
            ztextArray[2 * i] = key;
 
646
            ztextArray[2 * i + 1] = val;
640
647
            if (emitProperties) {
641
648
                String uniqueKey = "ztext_" + i + ':' + key;
642
 
                properties.put(uniqueKey.toLowerCase(), val);
 
649
                properties.put(uniqueKey.toLowerCase(Locale.getDefault()), val);
643
650
            }
644
651
        }
645
652
        if (encodeParam != null) {
655
662
 
656
663
        // Create an empty WritableRaster
657
664
        int depth = bitDepth;
658
 
        if ((colorType == PNG_COLOR_GRAY) &&
659
 
            (bitDepth < 8) && output8BitGray) {
 
665
        if ((colorType == PNG_COLOR_GRAY)
 
666
            && (bitDepth < 8) && output8BitGray) {
660
667
            depth = 8;
661
668
        }
662
669
        if ((colorType == PNG_COLOR_PALETTE) && expandPalette) {
663
670
            depth = 8;
664
671
        }
665
 
        int bytesPerRow = (outputBands*width*depth + 7)/8;
 
672
        int bytesPerRow = (outputBands * width * depth + 7) / 8;
666
673
        int scanlineStride =
667
 
            (depth == 16) ? (bytesPerRow/2) : bytesPerRow;
 
674
            (depth == 16) ? (bytesPerRow / 2) : bytesPerRow;
668
675
 
669
676
        theTile = createRaster(width, height, outputBands,
670
677
                               scanlineStride,
673
680
        if (performGammaCorrection && (gammaLut == null)) {
674
681
            initGammaLut(bitDepth);
675
682
        }
676
 
        if ((postProcess == POST_GRAY_LUT) ||
677
 
            (postProcess == POST_GRAY_LUT_ADD_TRANS) ||
678
 
            (postProcess == POST_GRAY_LUT_ADD_TRANS_EXP)) {
 
683
        if ((postProcess == POST_GRAY_LUT)
 
684
            || (postProcess == POST_GRAY_LUT_ADD_TRANS)
 
685
            || (postProcess == POST_GRAY_LUT_ADD_TRANS_EXP)) {
679
686
            initGrayLut(bitDepth);
680
687
        }
681
688
 
697
704
                                                 greenPalette,
698
705
                                                 bluePalette);
699
706
            }
700
 
        } else if ((colorType == PNG_COLOR_GRAY) &&
701
 
                   (bitDepth < 8) && !output8BitGray) {
 
707
        } else if ((colorType == PNG_COLOR_GRAY)
 
708
                   && (bitDepth < 8) && !output8BitGray) {
702
709
            byte[] palette = expandBits[bitDepth];
703
710
            colorModel = new IndexColorModel(bitDepth,
704
711
                                             palette.length,
860
867
    }
861
868
 
862
869
    private void parse_PLTE_chunk(PNGChunk chunk) {
863
 
        paletteEntries = chunk.getLength()/3;
 
870
        paletteEntries = chunk.getLength() / 3;
864
871
        redPalette = new byte[paletteEntries];
865
872
        greenPalette = new byte[paletteEntries];
866
873
        bluePalette = new byte[paletteEntries];
901
908
            bkgdBlue = bluePalette[bkgdIndex] & 0xff;
902
909
 
903
910
            if (encodeParam != null) {
904
 
                ((PNGEncodeParam.Palette)encodeParam).
905
 
                    setBackgroundPaletteIndex(bkgdIndex);
 
911
                ((PNGEncodeParam.Palette)encodeParam).setBackgroundPaletteIndex(bkgdIndex);
906
912
            }
907
913
            break;
908
914
        case PNG_COLOR_GRAY: case PNG_COLOR_GRAY_ALPHA:
910
916
            bkgdRed = bkgdGreen = bkgdBlue = bkgdGray;
911
917
 
912
918
            if (encodeParam != null) {
913
 
                ((PNGEncodeParam.Gray)encodeParam).
914
 
                    setBackgroundGray(bkgdGray);
 
919
                ((PNGEncodeParam.Gray)encodeParam).setBackgroundGray(bkgdGray);
915
920
            }
916
921
            break;
917
922
        case PNG_COLOR_RGB: case PNG_COLOR_RGB_ALPHA:
924
929
            bkgdRGB[1] = bkgdGreen;
925
930
            bkgdRGB[2] = bkgdBlue;
926
931
            if (encodeParam != null) {
927
 
                ((PNGEncodeParam.RGB)encodeParam).
928
 
                    setBackgroundRGB(bkgdRGB);
 
932
                ((PNGEncodeParam.RGB)encodeParam).setBackgroundRGB(bkgdRGB);
929
933
            }
930
934
            break;
931
935
        }
932
936
 
933
 
        int r = 0, g = 0, b = 0;
 
937
        int r = 0;
 
938
        int g = 0;
 
939
        int b = 0;
934
940
        if (bitDepth < 8) {
935
941
            r = expandBits[bitDepth][bkgdRed];
936
942
            g = expandBits[bitDepth][bkgdGreen];
956
962
        }
957
963
 
958
964
        chromaticity = new float[8];
959
 
        chromaticity[0] = chunk.getInt4(0)/100000.0F;
960
 
        chromaticity[1] = chunk.getInt4(4)/100000.0F;
961
 
        chromaticity[2] = chunk.getInt4(8)/100000.0F;
962
 
        chromaticity[3] = chunk.getInt4(12)/100000.0F;
963
 
        chromaticity[4] = chunk.getInt4(16)/100000.0F;
964
 
        chromaticity[5] = chunk.getInt4(20)/100000.0F;
965
 
        chromaticity[6] = chunk.getInt4(24)/100000.0F;
966
 
        chromaticity[7] = chunk.getInt4(28)/100000.0F;
 
965
        chromaticity[0] = chunk.getInt4(0) / 100000.0F;
 
966
        chromaticity[1] = chunk.getInt4(4) / 100000.0F;
 
967
        chromaticity[2] = chunk.getInt4(8) / 100000.0F;
 
968
        chromaticity[3] = chunk.getInt4(12) / 100000.0F;
 
969
        chromaticity[4] = chunk.getInt4(16) / 100000.0F;
 
970
        chromaticity[5] = chunk.getInt4(20) / 100000.0F;
 
971
        chromaticity[6] = chunk.getInt4(24) / 100000.0F;
 
972
        chromaticity[7] = chunk.getInt4(28) / 100000.0F;
967
973
 
968
974
        if (encodeParam != null) {
969
975
            encodeParam.setChromaticity(chromaticity);
970
976
        }
971
977
        if (emitProperties) {
972
 
            properties.put("white_point_x", new Float(chromaticity[0]));
973
 
            properties.put("white_point_y", new Float(chromaticity[1]));
974
 
            properties.put("red_x", new Float(chromaticity[2]));
975
 
            properties.put("red_y", new Float(chromaticity[3]));
976
 
            properties.put("green_x", new Float(chromaticity[4]));
977
 
            properties.put("green_y", new Float(chromaticity[5]));
978
 
            properties.put("blue_x", new Float(chromaticity[6]));
979
 
            properties.put("blue_y", new Float(chromaticity[7]));
 
978
            properties.put("white_point_x", chromaticity[0]);
 
979
            properties.put("white_point_y", chromaticity[1]);
 
980
            properties.put("red_x", chromaticity[2]);
 
981
            properties.put("red_y", chromaticity[3]);
 
982
            properties.put("green_x", chromaticity[4]);
 
983
            properties.put("green_y", chromaticity[5]);
 
984
            properties.put("blue_x", chromaticity[6]);
 
985
            properties.put("blue_y", chromaticity[7]);
980
986
        }
981
987
    }
982
988
 
986
992
            return;
987
993
        }
988
994
 
989
 
        fileGamma = chunk.getInt4(0)/100000.0F;
 
995
        fileGamma = chunk.getInt4(0) / 100000.0F;
990
996
 
991
997
        float exp =
992
 
            performGammaCorrection ? displayExponent/userExponent : 1.0F;
 
998
            performGammaCorrection ? displayExponent / userExponent : 1.0F;
993
999
        if (encodeParam != null) {
994
 
            encodeParam.setGamma(fileGamma*exp);
 
1000
            encodeParam.setGamma(fileGamma * exp);
995
1001
        }
996
1002
        if (emitProperties) {
997
 
            properties.put("gamma", new Float(fileGamma*exp));
 
1003
            properties.put("gamma", fileGamma * exp);
998
1004
        }
999
1005
    }
1000
1006
 
1007
1013
        int length = redPalette.length;
1008
1014
        int[] hist = new int[length];
1009
1015
        for (int i = 0; i < length; i++) {
1010
 
            hist[i] = chunk.getInt2(2*i);
 
1016
            hist[i] = chunk.getInt2(2 * i);
1011
1017
        }
1012
1018
 
1013
1019
        if (encodeParam != null) {
1016
1022
    }
1017
1023
 
1018
1024
    private void parse_iCCP_chunk(PNGChunk chunk) {
1019
 
        String name = "";  // todo simplify this
1020
 
        byte b;
 
1025
//        String name = "";  // todo simplify this
 
1026
//        byte b;
1021
1027
 
1022
 
        int textIndex = 0;
1023
 
        while ((b = chunk.getByte(textIndex++)) != 0) {
1024
 
            name += (char)b;
1025
 
        }
 
1028
//        int textIndex = 0;
 
1029
//        while ((b = chunk.getByte(textIndex++)) != 0) {
 
1030
//            name += (char)b;
 
1031
//        }
1026
1032
    }
1027
1033
 
1028
1034
    private void parse_pHYs_chunk(PNGChunk chunk) {
1036
1042
                                             unitSpecifier);
1037
1043
        }
1038
1044
        if (emitProperties) {
1039
 
            properties.put("x_pixels_per_unit", new Integer(xPixelsPerUnit));
1040
 
            properties.put("y_pixels_per_unit", new Integer(yPixelsPerUnit));
 
1045
            properties.put("x_pixels_per_unit", xPixelsPerUnit);
 
1046
            properties.put("y_pixels_per_unit", yPixelsPerUnit);
1041
1047
            properties.put("pixel_aspect_ratio",
1042
 
                           new Float((float)xPixelsPerUnit/yPixelsPerUnit));
 
1048
                    (float) xPixelsPerUnit / yPixelsPerUnit);
1043
1049
            if (unitSpecifier == 1) {
1044
1050
                properties.put("pixel_units", "Meters");
1045
1051
            } else if (unitSpecifier != 0) {
1081
1087
 
1082
1088
        // The presence of an sRGB chunk implies particular
1083
1089
        // settings for gamma and chroma.
1084
 
        fileGamma = 45455/100000.0F;
 
1090
        fileGamma = 45455 / 100000.0F;
1085
1091
 
1086
1092
        chromaticity = new float[8];
1087
 
        chromaticity[0] = 31270/10000.0F;
1088
 
        chromaticity[1] = 32900/10000.0F;
1089
 
        chromaticity[2] = 64000/10000.0F;
1090
 
        chromaticity[3] = 33000/10000.0F;
1091
 
        chromaticity[4] = 30000/10000.0F;
1092
 
        chromaticity[5] = 60000/10000.0F;
1093
 
        chromaticity[6] = 15000/10000.0F;
1094
 
        chromaticity[7] =  6000/10000.0F;
 
1093
        chromaticity[0] = 31270 / 10000.0F;
 
1094
        chromaticity[1] = 32900 / 10000.0F;
 
1095
        chromaticity[2] = 64000 / 10000.0F;
 
1096
        chromaticity[3] = 33000 / 10000.0F;
 
1097
        chromaticity[4] = 30000 / 10000.0F;
 
1098
        chromaticity[5] = 60000 / 10000.0F;
 
1099
        chromaticity[6] = 15000 / 10000.0F;
 
1100
        chromaticity[7] =  6000 / 10000.0F;
1095
1101
 
1096
1102
        if (performGammaCorrection) {
1097
1103
            // File gamma is 1/2.2
1098
 
            float gamma = fileGamma*(displayExponent/userExponent);
 
1104
            float gamma = fileGamma * (displayExponent / userExponent);
1099
1105
            if (encodeParam != null) {
1100
1106
                encodeParam.setGamma(gamma);
1101
1107
                encodeParam.setChromaticity(chromaticity);
1102
1108
            }
1103
1109
            if (emitProperties) {
1104
 
                properties.put("gamma", new Float(gamma));
1105
 
                properties.put("white_point_x", new Float(chromaticity[0]));
1106
 
                properties.put("white_point_y", new Float(chromaticity[1]));
1107
 
                properties.put("red_x", new Float(chromaticity[2]));
1108
 
                properties.put("red_y", new Float(chromaticity[3]));
1109
 
                properties.put("green_x", new Float(chromaticity[4]));
1110
 
                properties.put("green_y", new Float(chromaticity[5]));
1111
 
                properties.put("blue_x", new Float(chromaticity[6]));
1112
 
                properties.put("blue_y", new Float(chromaticity[7]));
 
1110
                properties.put("gamma", gamma);
 
1111
                properties.put("white_point_x", chromaticity[0]);
 
1112
                properties.put("white_point_y", chromaticity[1]);
 
1113
                properties.put("red_x", chromaticity[2]);
 
1114
                properties.put("red_y", chromaticity[3]);
 
1115
                properties.put("green_x", chromaticity[4]);
 
1116
                properties.put("green_y", chromaticity[5]);
 
1117
                properties.put("blue_x", chromaticity[6]);
 
1118
                properties.put("blue_y", chromaticity[7]);
1113
1119
            }
1114
1120
        }
1115
1121
    }
1120
1126
        StringBuffer key = new StringBuffer();
1121
1127
        int textIndex = 0;
1122
1128
        while ((b = chunk.getByte(textIndex++)) != 0) {
1123
 
            key.append( (char)b );
 
1129
            key.append((char)b);
1124
1130
        }
1125
1131
 
1126
1132
        StringBuilder value = new StringBuilder();
1203
1209
                }
1204
1210
 
1205
1211
                if (encodeParam != null) {
1206
 
                    ((PNGEncodeParam.Gray)encodeParam).
1207
 
                        setTransparentGray(grayTransparentAlpha);
 
1212
                    ((PNGEncodeParam.Gray)encodeParam).setTransparentGray(grayTransparentAlpha);
1208
1213
                }
1209
1214
            }
1210
1215
        } else if (colorType == PNG_COLOR_RGB) {
1221
1226
                    rgbTrans[0] = redTransparentAlpha;
1222
1227
                    rgbTrans[1] = greenTransparentAlpha;
1223
1228
                    rgbTrans[2] = blueTransparentAlpha;
1224
 
                    ((PNGEncodeParam.RGB)encodeParam).
1225
 
                        setTransparentRGB(rgbTrans);
 
1229
                    ((PNGEncodeParam.RGB)encodeParam).setTransparentRGB(rgbTrans);
1226
1230
                }
1227
1231
            }
1228
 
        } else if (colorType == PNG_COLOR_GRAY_ALPHA ||
1229
 
                   colorType == PNG_COLOR_RGB_ALPHA) {
 
1232
        } else if (colorType == PNG_COLOR_GRAY_ALPHA
 
1233
                   || colorType == PNG_COLOR_RGB_ALPHA) {
1230
1234
            // Error -- GA or RGBA image can't have a tRNS chunk.
1231
1235
            String msg = PropertyUtil.getString("PNGImageDecoder15");
1232
1236
            throw new RuntimeException(msg);
1239
1243
        StringBuffer key = new StringBuffer();
1240
1244
        byte b;
1241
1245
        while ((b = chunk.getByte(textIndex++)) != 0) {
1242
 
            key.append( (char)b );
 
1246
            key.append((char)b);
1243
1247
        }
1244
1248
        /* int method = */ chunk.getByte(textIndex++);
1245
1249
 
1271
1275
        WritableRaster ras = null;
1272
1276
        Point origin = new Point(0, 0);
1273
1277
        if ((bitDepth < 8) && (bands == 1)) {
1274
 
            dataBuffer = new DataBufferByte(height*scanlineStride);
 
1278
            dataBuffer = new DataBufferByte(height * scanlineStride);
1275
1279
            ras = Raster.createPackedRaster(dataBuffer,
1276
1280
                                            width, height,
1277
1281
                                            bitDepth,
1278
1282
                                            origin);
1279
1283
        } else if (bitDepth <= 8) {
1280
 
            dataBuffer = new DataBufferByte(height*scanlineStride);
 
1284
            dataBuffer = new DataBufferByte(height * scanlineStride);
1281
1285
           ras = Raster.createInterleavedRaster(dataBuffer,
1282
1286
                                                 width, height,
1283
1287
                                                 scanlineStride,
1285
1289
                                                 bandOffsets[bands],
1286
1290
                                                 origin);
1287
1291
        } else {
1288
 
            dataBuffer = new DataBufferUShort(height*scanlineStride);
 
1292
            dataBuffer = new DataBufferUShort(height * scanlineStride);
1289
1293
            ras = Raster.createInterleavedRaster(dataBuffer,
1290
1294
                                                 width, height,
1291
1295
                                                 scanlineStride,
1322
1326
 
1323
1327
    private static void decodeAverageFilter(byte[] curr, byte[] prev,
1324
1328
                                            int count, int bpp) {
1325
 
        int raw, priorPixel, priorRow;
 
1329
        int raw;
 
1330
        int priorPixel;
 
1331
        int priorRow;
1326
1332
 
1327
1333
        for (int i = 0; i < bpp; i++) {
1328
1334
            raw = curr[i] & 0xff;
1329
1335
            priorRow = prev[i] & 0xff;
1330
1336
 
1331
 
            curr[i] = (byte)(raw + priorRow/2);
 
1337
            curr[i] = (byte)(raw + priorRow / 2);
1332
1338
        }
1333
1339
 
1334
1340
        for (int i = bpp; i < count; i++) {
1336
1342
            priorPixel = curr[i - bpp] & 0xff;
1337
1343
            priorRow = prev[i] & 0xff;
1338
1344
 
1339
 
            curr[i] = (byte)(raw + (priorPixel + priorRow)/2);
 
1345
            curr[i] = (byte)(raw + (priorPixel + priorRow) / 2);
1340
1346
        }
1341
1347
    }
1342
1348
 
1343
1349
    private static void decodePaethFilter(byte[] curr, byte[] prev,
1344
1350
                                          int count, int bpp) {
1345
 
        int raw, priorPixel, priorRow, priorRowPixel;
 
1351
        int raw;
 
1352
        int priorPixel;
 
1353
        int priorRow;
 
1354
        int priorRowPixel;
1346
1355
 
1347
1356
        for (int i = 0; i < bpp; i++) {
1348
1357
            raw = curr[i] & 0xff;
1366
1375
    private void processPixels(int process,
1367
1376
                               Raster src, WritableRaster dst,
1368
1377
                               int xOffset, int step, int y, int width) {
1369
 
        int srcX, dstX;
 
1378
        int srcX;
 
1379
        int dstX;
1370
1380
 
1371
1381
        // Create an array suitable for holding one pixel
1372
1382
        int[] ps = src.getPixel(0, 0, (int[])null);
1489
1499
                    pd[1] = g;
1490
1500
                    pd[2] = b;
1491
1501
                }
1492
 
                if ((r == redTransparentAlpha) &&
1493
 
                    (g == greenTransparentAlpha) &&
1494
 
                    (b == blueTransparentAlpha)) {
 
1502
                if ((r == redTransparentAlpha)
 
1503
                    && (g == greenTransparentAlpha)
 
1504
                    && (b == blueTransparentAlpha)) {
1495
1505
                    pd[3] = 0;
1496
1506
                } else {
1497
1507
                    pd[3] = maxOpacity;
1629
1639
            return;
1630
1640
        }
1631
1641
 
1632
 
        int bytesPerRow = (inputBands*passWidth*bitDepth + 7)/8;
1633
 
        int eltsPerRow = (bitDepth == 16) ? bytesPerRow/2 : bytesPerRow;
 
1642
        int bytesPerRow = (inputBands * passWidth * bitDepth + 7) / 8;
 
1643
        int eltsPerRow = (bitDepth == 16) ? bytesPerRow / 2 : bytesPerRow;
1634
1644
        byte[] curr = new byte[bytesPerRow];
1635
1645
        byte[] prior = new byte[bytesPerRow];
1636
1646
 
1650
1660
        }
1651
1661
 
1652
1662
        // Decode the (sub)image row-by-row
1653
 
        int srcY, dstY;
 
1663
        int srcY;
 
1664
        int dstY;
1654
1665
        for (srcY = 0, dstY = yOffset;
1655
1666
             srcY < passHeight;
1656
1667
             srcY++, dstY += yStep) {
1710
1721
        if (!useInterlacing) {
1711
1722
            decodePass(theTile, 0, 0, 1, 1, width, height);
1712
1723
        } else {
1713
 
            decodePass(theTile, 0, 0, 8, 8, (width + 7)/8, (height + 7)/8);
1714
 
            decodePass(theTile, 4, 0, 8, 8, (width + 3)/8, (height + 7)/8);
1715
 
            decodePass(theTile, 0, 4, 4, 8, (width + 3)/4, (height + 3)/8);
1716
 
            decodePass(theTile, 2, 0, 4, 4, (width + 1)/4, (height + 3)/4);
1717
 
            decodePass(theTile, 0, 2, 2, 4, (width + 1)/2, (height + 1)/4);
1718
 
            decodePass(theTile, 1, 0, 2, 2, width/2, (height + 1)/2);
1719
 
            decodePass(theTile, 0, 1, 1, 2, width, height/2);
 
1724
            decodePass(theTile, 0, 0, 8, 8, (width + 7) / 8, (height + 7) / 8);
 
1725
            decodePass(theTile, 4, 0, 8, 8, (width + 3) / 8, (height + 7) / 8);
 
1726
            decodePass(theTile, 0, 4, 4, 8, (width + 3) / 4, (height + 3) / 8);
 
1727
            decodePass(theTile, 2, 0, 4, 4, (width + 1) / 4, (height + 3) / 4);
 
1728
            decodePass(theTile, 0, 2, 2, 4, (width + 1) / 2, (height + 1) / 4);
 
1729
            decodePass(theTile, 1, 0, 2, 2, width / 2, (height + 1) / 2);
 
1730
            decodePass(theTile, 0, 1, 1, 2, width, height / 2);
1720
1731
        }
1721
1732
    }
1722
1733