jdk/test/javax/imageio/plugins/tiff/TIFFImageReadParamTest.java
changeset 37546 53ef9c809b5b
child 42749 91fb907a8732
equal deleted inserted replaced
37545:466d61de704b 37546:53ef9c809b5b
       
     1 /*
       
     2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /**
       
    25  * @test
       
    26  * @bug     8149028
       
    27  * @author  a.stepanov
       
    28  * @summary check TIFFDirectory manipulation
       
    29  *          by means of TIFFImageReadParam
       
    30  * @run     main TIFFImageReadParamTest
       
    31  */
       
    32 
       
    33 
       
    34 import java.awt.Color;
       
    35 import java.awt.Graphics;
       
    36 import java.awt.image.BufferedImage;
       
    37 import java.io.*;
       
    38 import javax.imageio.*;
       
    39 import javax.imageio.metadata.IIOMetadata;
       
    40 import javax.imageio.plugins.tiff.*;
       
    41 import javax.imageio.stream.ImageInputStream;
       
    42 import javax.imageio.stream.ImageOutputStream;
       
    43 
       
    44 public class TIFFImageReadParamTest {
       
    45 
       
    46     private final static String FILENAME = "test.tiff";
       
    47     private final static int SZ = 100;
       
    48     private final static Color C = Color.RED;
       
    49 
       
    50     private final static String GEO_DATA = "test params";
       
    51     private final static int GEO_N = GeoTIFFTagSet.TAG_GEO_ASCII_PARAMS;
       
    52 
       
    53     private final static String EXIF_DATA = "2000:01:01 00:00:01";
       
    54     private final static int EXIF_N = ExifTIFFTagSet.TAG_DATE_TIME_ORIGINAL;
       
    55 
       
    56     private final static String GPS_DATA =
       
    57         ExifGPSTagSet.STATUS_MEASUREMENT_IN_PROGRESS;
       
    58     private final static int GPS_N = ExifGPSTagSet.TAG_GPS_STATUS;
       
    59 
       
    60     private final static short FAX_DATA =
       
    61         FaxTIFFTagSet.CLEAN_FAX_DATA_ERRORS_UNCORRECTED;
       
    62     private final static int FAX_N = FaxTIFFTagSet.TAG_CLEAN_FAX_DATA;
       
    63 
       
    64     private ImageWriter getTIFFWriter() {
       
    65 
       
    66         java.util.Iterator<ImageWriter> writers =
       
    67             ImageIO.getImageWritersByFormatName("TIFF");
       
    68         if (!writers.hasNext()) {
       
    69             throw new RuntimeException("No writers available for TIFF format");
       
    70         }
       
    71         return writers.next();
       
    72     }
       
    73 
       
    74     private ImageReader getTIFFReader() {
       
    75 
       
    76         java.util.Iterator<ImageReader> readers =
       
    77             ImageIO.getImageReadersByFormatName("TIFF");
       
    78         if (!readers.hasNext()) {
       
    79             throw new RuntimeException("No readers available for TIFF format");
       
    80         }
       
    81         return readers.next();
       
    82     }
       
    83 
       
    84     private void check(boolean ok, String msg) {
       
    85         if (!ok) { throw new RuntimeException(msg); }
       
    86     }
       
    87 
       
    88     private void addASCIIField(TIFFDirectory d,
       
    89                                String        name,
       
    90                                String        data,
       
    91                                int           num) {
       
    92 
       
    93         String a[] = {data};
       
    94         d.addTIFFField(new TIFFField(
       
    95             new TIFFTag(name, num, 1 << TIFFTag.TIFF_ASCII),
       
    96                 TIFFTag.TIFF_ASCII, 1, a));
       
    97     }
       
    98 
       
    99     private void checkASCIIValue(TIFFDirectory d,
       
   100                                  String        what,
       
   101                                  String        data,
       
   102                                  int           num) {
       
   103 
       
   104         TIFFField f = d.getTIFFField(num);
       
   105         check(f.getType() == TIFFTag.TIFF_ASCII, "field type != ASCII");
       
   106         check(f.getCount() == 1, "invalid " + what + " data count");
       
   107         check(f.getValueAsString(0).equals(data),
       
   108             "invalid " + what + " data");
       
   109     }
       
   110 
       
   111 
       
   112     private void writeImage() throws Exception {
       
   113 
       
   114         OutputStream s = new BufferedOutputStream(new FileOutputStream(FILENAME));
       
   115         try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
       
   116             ImageWriter writer = getTIFFWriter();
       
   117             writer.setOutput(ios);
       
   118 
       
   119             BufferedImage img =
       
   120                 new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
       
   121             Graphics g = img.getGraphics();
       
   122             g.setColor(C);
       
   123             g.fillRect(0, 0, SZ, SZ);
       
   124             g.dispose();
       
   125 
       
   126             IIOMetadata metadata = writer.getDefaultImageMetadata(
       
   127                 new ImageTypeSpecifier(img), writer.getDefaultWriteParam());
       
   128 
       
   129             TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
       
   130 
       
   131             // add some extension tags
       
   132             addASCIIField(dir, "GeoAsciiParamsTag", GEO_DATA, GEO_N);
       
   133             addASCIIField(dir, "DateTimeOriginal", EXIF_DATA, EXIF_N);
       
   134             addASCIIField(dir, "GPSStatus", GPS_DATA, GPS_N);
       
   135 
       
   136             dir.addTIFFField(new TIFFField(new TIFFTag(
       
   137                 "CleanFaxData", FAX_N, 1 << TIFFTag.TIFF_SHORT), FAX_DATA));
       
   138 
       
   139             IIOMetadata data = dir.getAsMetadata();
       
   140 
       
   141             writer.write(new IIOImage(img, null, data));
       
   142 
       
   143             ios.flush();
       
   144             writer.dispose();
       
   145         }
       
   146     }
       
   147 
       
   148     private void checkImage(BufferedImage img) {
       
   149 
       
   150         check(img.getWidth() == SZ, "invalid image width");
       
   151         check(img.getHeight() == SZ, "invalid image height");
       
   152         Color c = new Color(img.getRGB(SZ / 2, SZ / 2));
       
   153         check(c.equals(C), "invalid image color");
       
   154     }
       
   155 
       
   156     private TIFFDirectory getDir(TIFFTagSet[] add,
       
   157                                  TIFFTagSet[] remove) throws Exception {
       
   158 
       
   159         ImageReader reader = getTIFFReader();
       
   160 
       
   161         ImageInputStream s = ImageIO.createImageInputStream(new File(FILENAME));
       
   162         reader.setInput(s, false, true);
       
   163 
       
   164         int ni = reader.getNumImages(true);
       
   165         check(ni == 1, "invalid number of images: " + ni);
       
   166 
       
   167         TIFFImageReadParam param = new TIFFImageReadParam();
       
   168         for (TIFFTagSet ts: add) { param.addAllowedTagSet(ts); }
       
   169         for (TIFFTagSet ts: remove) { param.removeAllowedTagSet(ts); }
       
   170 
       
   171         IIOImage img = reader.readAll(0, param);
       
   172 
       
   173         // just in case, check image
       
   174         checkImage((BufferedImage) img.getRenderedImage());
       
   175 
       
   176         IIOMetadata metadata = img.getMetadata();
       
   177         TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
       
   178 
       
   179         reader.dispose();
       
   180         s.close();
       
   181 
       
   182         return dir;
       
   183     }
       
   184 
       
   185     private void simpleChecks() {
       
   186 
       
   187         TIFFImageReadParam param = new TIFFImageReadParam();
       
   188 
       
   189         java.util.List<TIFFTagSet> allowed = param.getAllowedTagSets();
       
   190 
       
   191         // see docs
       
   192         check(allowed.contains(BaselineTIFFTagSet.getInstance()),
       
   193             "must contain BaselineTIFFTagSet");
       
   194         check(allowed.contains(FaxTIFFTagSet.getInstance()),
       
   195             "must contain FaxTIFFTagSet");
       
   196         check(allowed.contains(ExifParentTIFFTagSet.getInstance()),
       
   197             "must contain ExifParentTIFFTagSet");
       
   198         check(allowed.contains(GeoTIFFTagSet.getInstance()),
       
   199             "must contain GeoTIFFTagSet");
       
   200 
       
   201         TIFFTagSet gps = ExifGPSTagSet.getInstance();
       
   202         param.addAllowedTagSet(gps);
       
   203         check(param.getAllowedTagSets().contains(gps),
       
   204             "must contain ExifGPSTagSet");
       
   205 
       
   206         param.removeAllowedTagSet(gps);
       
   207         check(!param.getAllowedTagSets().contains(gps),
       
   208             "must not contain ExifGPSTagSet");
       
   209 
       
   210         // check that repeating remove goes properly
       
   211         param.removeAllowedTagSet(gps);
       
   212 
       
   213         boolean ok = false;
       
   214         try { param.addAllowedTagSet(null); }
       
   215         catch (IllegalArgumentException e) { ok = true; }
       
   216         check(ok, "must not be able to add null tag set");
       
   217 
       
   218         ok = false;
       
   219         try { param.removeAllowedTagSet(null); }
       
   220         catch (IllegalArgumentException e) { ok = true; }
       
   221         check(ok, "must not be able to remove null tag set");
       
   222     }
       
   223 
       
   224     private void run() {
       
   225 
       
   226         simpleChecks();
       
   227 
       
   228         try {
       
   229 
       
   230             writeImage();
       
   231 
       
   232             TIFFTagSet
       
   233                 empty[] = {},
       
   234                 geo[]   = {  GeoTIFFTagSet.getInstance() },
       
   235                 exif[]  = { ExifTIFFTagSet.getInstance() },
       
   236                 gps[]   = {  ExifGPSTagSet.getInstance() },
       
   237                 fax[]   = {  FaxTIFFTagSet.getInstance() };
       
   238 
       
   239             // default param state
       
   240             TIFFDirectory dir = getDir(empty, empty);
       
   241             // Geo and Fax are default allowed tag sets
       
   242             check(dir.containsTIFFField(GEO_N), "must contain Geo field");
       
   243             checkASCIIValue(dir, "Geo", GEO_DATA, GEO_N);
       
   244             check(dir.containsTIFFField(FAX_N), "must contain Fax field");
       
   245             check(
       
   246                 (dir.getTIFFField(FAX_N).getCount() == 1) &&
       
   247                 (dir.getTIFFField(FAX_N).getAsInt(0) == FAX_DATA),
       
   248                 "invalid Fax field value");
       
   249 
       
   250             // corresponding tag sets are non-default
       
   251             check(!dir.containsTIFFField(EXIF_N), "must not contain Geo field");
       
   252             check(!dir.containsTIFFField(GPS_N), "must not contain GPS field");
       
   253 
       
   254             // remove Fax
       
   255             dir = getDir(empty, fax);
       
   256             check(!dir.containsTIFFField(FAX_N), "must not contain Fax field");
       
   257 
       
   258             // add EXIF, remove Geo
       
   259             dir = getDir(exif, geo);
       
   260             check(dir.containsTIFFField(EXIF_N), "must contain EXIF field");
       
   261             checkASCIIValue(dir, "EXIF", EXIF_DATA, EXIF_N);
       
   262             check(!dir.containsTIFFField(GEO_N), "must not contain Geo field");
       
   263 
       
   264             // add GPS
       
   265             dir = getDir(gps, empty);
       
   266             check(dir.containsTIFFField(GPS_N), "must contain GPS field");
       
   267             checkASCIIValue(dir, "GPS", GPS_DATA, GPS_N);
       
   268 
       
   269         } catch (Exception e) { throw new RuntimeException(e); }
       
   270     }
       
   271 
       
   272     public static void main(String[] args) {
       
   273         (new TIFFImageReadParamTest()).run();
       
   274     }
       
   275 }