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     8154058
  27  * @author  a.stepanov
  28  * @summary Some checks for ignoring metadata
  29  * @run     main ReadParamTest
  30  */
  31 
  32 import java.awt.*;
  33 import java.awt.image.BufferedImage;
  34 import java.io.*;
  35 import javax.imageio.*;
  36 import javax.imageio.metadata.*;
  37 
  38 import javax.imageio.stream.*;
  39 import javax.imageio.plugins.tiff.*;
  40 
  41 
  42 public class ReadParamTest {
  43 
  44     private final static int SZ = 50;
  45     private final static Color C = Color.RED;
  46 
  47     private final static String EXIF_DATA[] = {"2000:00:00 00:00:00"};
  48     private final static int N_EXIF = ExifTIFFTagSet.TAG_DATE_TIME_ORIGINAL;
  49 
  50     private final static short FAX_DATA =
  51         FaxTIFFTagSet.CLEAN_FAX_DATA_ERRORS_UNCORRECTED;
  52     private final static int N_FAX = FaxTIFFTagSet.TAG_CLEAN_FAX_DATA;
  53 
  54     private final static String GPS_DATA[] =
  55         {ExifGPSTagSet.STATUS_MEASUREMENT_IN_PROGRESS};
  56     private final static int N_GPS = ExifGPSTagSet.TAG_GPS_STATUS;
  57 
  58     private final boolean ignoreMetadata;
  59 
  60     public ReadParamTest(boolean ignoreMetadata) {
  61         this.ignoreMetadata = ignoreMetadata;
  62     }
  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 
  85     private void writeImage() throws Exception {
  86 
  87         String fn = "test-" + ignoreMetadata + ".tiff";
  88         OutputStream s = new BufferedOutputStream(new FileOutputStream(fn));
  89         try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
  90 
  91             ImageWriter writer = getTIFFWriter();
  92             writer.setOutput(ios);
  93 
  94             BufferedImage img = new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
  95             Graphics g = img.getGraphics();
  96             g.setColor(C);
  97             g.fillRect(0, 0, SZ, SZ);
  98             g.dispose();
  99 
 100             ImageWriteParam param = writer.getDefaultWriteParam();
 101 
 102             IIOMetadata md = writer.getDefaultImageMetadata(
 103                     new ImageTypeSpecifier(img), param);
 104 
 105             TIFFDirectory dir = TIFFDirectory.createFromMetadata(md);
 106 
 107             int ascii = TIFFTag.TIFF_ASCII;
 108 
 109             TIFFTag exifTag = new TIFFTag("DateTimeOriginal", N_EXIF, 1 << ascii);
 110             dir.addTIFFField(new TIFFField(exifTag, ascii, 1, EXIF_DATA));
 111 
 112             TIFFTag faxTag = new TIFFTag("CleanFaxData", N_FAX, 1 << TIFFTag.TIFF_SHORT);
 113             dir.addTIFFField(new TIFFField(faxTag, FAX_DATA));
 114 
 115             TIFFTag gpsTag = new TIFFTag("GPSStatus", N_GPS, 1 << ascii);
 116             dir.addTIFFField(new TIFFField(gpsTag, ascii, 1, GPS_DATA));
 117 
 118             writer.write(new IIOImage(img, null, dir.getAsMetadata()));
 119 
 120             ios.flush();
 121             writer.dispose();
 122         }
 123         s.close();
 124     }
 125 
 126     private void readAndCheckImage() throws Exception {
 127 
 128         ImageReader reader = getTIFFReader();
 129 
 130         String fn = "test-" + ignoreMetadata + ".tiff";
 131         ImageInputStream s = ImageIO.createImageInputStream(new File(fn));
 132 
 133         reader.setInput(s, false, ignoreMetadata);
 134 
 135         int ni = reader.getNumImages(true);
 136         check(ni == 1, "invalid number of images");
 137 
 138 
 139         TIFFImageReadParam param = new TIFFImageReadParam();
 140         // fax data are allowed by default
 141         param.removeAllowedTagSet(FaxTIFFTagSet.getInstance());
 142         // add non-default data
 143         param.addAllowedTagSet(ExifGPSTagSet.getInstance());
 144 
 145         // read images and metadata
 146         IIOImage i = reader.readAll(0, param);
 147         BufferedImage bi = (BufferedImage) i.getRenderedImage();
 148 
 149         check(bi.getWidth()  == SZ, "invalid width");
 150         check(bi.getHeight() == SZ, "invalid height");
 151         Color c = new Color(bi.getRGB(SZ / 2, SZ / 2));
 152         check(c.equals(C), "invalid color");
 153 
 154         IIOMetadata metadata = i.getMetadata();
 155 
 156         if (metadata == null) {
 157             throw new RuntimeException("No image metadata retrieved");
 158         } else {
 159             int failures = 0;
 160 
 161             TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
 162 
 163             TIFFField widthField =
 164                 dir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
 165             System.out.printf("ImageWidth: %d%n", widthField.getAsLong(0));
 166 
 167             System.out.println("EXIF (" + !ignoreMetadata + "): "
 168                                + dir.containsTIFFField(N_EXIF));
 169             System.out.println("Fax (" + !ignoreMetadata + "): "
 170                                + dir.containsTIFFField(N_FAX));
 171             System.out.println("GPS (true): "
 172                                + dir.containsTIFFField(N_GPS));
 173 
 174             if (!dir.containsTIFFField(N_GPS)) {
 175                 System.err.println("Metadata is missing non-default GPS data");
 176                 failures++;
 177             }
 178             if (ignoreMetadata && dir.containsTIFFField(N_FAX)) {
 179                 System.err.println("Fax metadata present despite ignoreMetadata");
 180                 failures++;
 181             }
 182             if (ignoreMetadata && dir.containsTIFFField(N_EXIF)) {
 183                 System.err.println("Exif metadata present despite ignoreMetadata");
 184                 failures++;
 185             }
 186             if (failures > 0) {
 187                 throw new RuntimeException("Test failed for ignoreMetadata "
 188                                            + ignoreMetadata);
 189             }
 190         }
 191     }
 192 
 193     public void run() {
 194 
 195         try {
 196             writeImage();
 197             readAndCheckImage();
 198         } catch (Exception e) {
 199             throw new RuntimeException(e);
 200         }
 201     }
 202 
 203     private void check(boolean ok, String msg) {
 204         if (!ok) { throw new RuntimeException(msg); }
 205     }
 206 
 207     public static void main(String[] args) {
 208         int failures = 0;
 209         try {
 210             System.out.println("ignore = true:");
 211             (new ReadParamTest(true)).run();
 212         } catch (Exception e) {
 213             e.printStackTrace();
 214             failures++;
 215         }
 216 
 217         try {
 218             System.out.println("\nignore = false:");
 219             (new ReadParamTest(false)).run();
 220         } catch (Exception e) {
 221             e.printStackTrace();
 222             failures++;
 223         }
 224 
 225         if (failures != 0) {
 226             throw new RuntimeException("Test failed!");
 227         } else {
 228             System.out.println("Test succeeded.");
 229         }
 230     }
 231 }