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 int DESCRIPTION_TAG =
  48         BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION;
  49     private final static String DESCRIPTION = "A Test Image";
  50 
  51     private final static int FAX_TAG = FaxTIFFTagSet.TAG_CLEAN_FAX_DATA;
  52     private final static short FAX_DATA =
  53         FaxTIFFTagSet.CLEAN_FAX_DATA_ERRORS_UNCORRECTED;
  54 
  55     private final boolean ignoreMetadata;
  56     private final boolean readUnknownTags;
  57 
  58     public ReadParamTest(boolean ignoreMetadata, boolean readUnknownTags) {
  59         this.ignoreMetadata = ignoreMetadata;
  60         this.readUnknownTags = readUnknownTags;
  61     }
  62 
  63     private ImageWriter getTIFFWriter() {
  64 
  65         java.util.Iterator<ImageWriter> writers =
  66             ImageIO.getImageWritersByFormatName("TIFF");
  67         if (!writers.hasNext()) {
  68             throw new RuntimeException("No writers available for TIFF format");
  69         }
  70         return writers.next();
  71     }
  72 
  73     private ImageReader getTIFFReader() {
  74 
  75         java.util.Iterator<ImageReader> readers =
  76             ImageIO.getImageReadersByFormatName("TIFF");
  77         if (!readers.hasNext()) {
  78             throw new RuntimeException("No readers available for TIFF format");
  79         }
  80         return readers.next();
  81     }
  82 
  83 
  84     private void writeImage() throws Exception {
  85 
  86         String fn = "test-" + ignoreMetadata + ".tiff";
  87         OutputStream s = new BufferedOutputStream(new FileOutputStream(fn));
  88         try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
  89 
  90             ImageWriter writer = getTIFFWriter();
  91             writer.setOutput(ios);
  92 
  93             BufferedImage img = new BufferedImage(SZ, SZ,
  94                 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             TIFFTag descTag =
 108                 BaselineTIFFTagSet.getInstance().getTag(DESCRIPTION_TAG);
 109             dir.addTIFFField(new TIFFField(descTag, TIFFTag.TIFF_ASCII, 1,
 110                 new String[] {DESCRIPTION}));
 111 
 112             TIFFTag faxTag = FaxTIFFTagSet.getInstance().getTag(FAX_TAG);
 113             dir.addTIFFField(new TIFFField(faxTag, FAX_DATA));
 114 
 115             writer.write(new IIOImage(img, null, dir.getAsMetadata()));
 116 
 117             ios.flush();
 118             writer.dispose();
 119         }
 120         s.close();
 121     }
 122 
 123     private void readAndCheckImage() throws Exception {
 124 
 125         ImageReader reader = getTIFFReader();
 126 
 127         String fn = "test-" + ignoreMetadata + ".tiff";
 128         ImageInputStream s = ImageIO.createImageInputStream(new File(fn));
 129 
 130         reader.setInput(s, false, ignoreMetadata);
 131 
 132         int ni = reader.getNumImages(true);
 133         check(ni == 1, "invalid number of images");
 134 
 135 
 136         TIFFImageReadParam param = new TIFFImageReadParam();
 137         // fax data are allowed by default
 138         param.removeAllowedTagSet(FaxTIFFTagSet.getInstance());
 139 
 140         // readUnknownTags setting
 141         if (param.getReadUnknownTags()) {
 142             throw new RuntimeException("Default readUnknownTags is not false");
 143         }
 144         param.setReadUnknownTags(readUnknownTags);
 145         if (param.getReadUnknownTags() != readUnknownTags) {
 146             throw new RuntimeException("Incorrect readUnknownTags setting "
 147                 + "\"" + readUnknownTags + "\"");
 148         }
 149 
 150         // read images and metadata
 151         IIOImage i = reader.readAll(0, param);
 152         BufferedImage bi = (BufferedImage) i.getRenderedImage();
 153 
 154         check(bi.getWidth()  == SZ, "invalid width");
 155         check(bi.getHeight() == SZ, "invalid height");
 156         Color c = new Color(bi.getRGB(SZ / 2, SZ / 2));
 157         check(c.equals(C), "invalid color");
 158 
 159         IIOMetadata metadata = i.getMetadata();
 160 
 161         //
 162         // Verify presence of image metadata
 163         //
 164         if (metadata == null) {
 165             throw new RuntimeException("No image metadata retrieved");
 166         }
 167 
 168         TIFFDirectory dir = TIFFDirectory.createFromMetadata(metadata);
 169 
 170         //
 171         // Verify presence of essential ImageWidth field regardless of
 172         // settings of ignoreMetadata and readUnknownTags
 173         //
 174         int failures = 0;
 175         if (!dir.containsTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH)) {
 176             System.err.println("Metadata is missing essential ImageWidth tag");
 177             failures++;
 178         } else {
 179             TIFFField widthField =
 180                 dir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
 181             System.out.printf("ImageWidth: %d%n", widthField.getAsLong(0));
 182         }
 183 
 184         //
 185         // Verify presence of non-essential baseline ImageDescription field
 186         // if and only if ignoreMetadata == false
 187         //
 188         boolean hasDescription = dir.containsTIFFField(DESCRIPTION_TAG);
 189         System.out.println("ImageDescription (" + !ignoreMetadata + "): "
 190             + hasDescription);
 191         if (ignoreMetadata && hasDescription) {
 192             System.err.println
 193                 ("Description metadata present despite ignoreMetadata");
 194             failures++;
 195         } else if (!ignoreMetadata && !hasDescription) {
 196             System.err.println
 197                 ("Description metadata absent despite !ignoreMetadata");
 198             failures++;
 199         }
 200 
 201         //
 202         // Verify presence of CleanFaxData field if and only if
 203         // ignoreMetadata == false and readUnknownTags == true
 204         //
 205         boolean shouldHaveFaxField = !ignoreMetadata && readUnknownTags;
 206         boolean hasFaxField = dir.containsTIFFField(FAX_TAG);
 207         System.out.println("CleanFaxData (" + shouldHaveFaxField + "): "
 208             + hasFaxField);
 209 
 210         if (ignoreMetadata) {
 211             if (hasFaxField) {
 212                 System.err.println
 213                     ("Fax metadata present despite ignoreMetadata");
 214                 failures++;
 215             }
 216         } else { // !ignoreMetadata
 217             if (!readUnknownTags && hasFaxField) {
 218                 System.err.println
 219                     ("Fax metadata present despite !readUnknownTags");
 220                 failures++;
 221             } else if (readUnknownTags && !hasFaxField) {
 222                 System.err.println
 223                     ("Fax metadata absent despite readUnknownTags");
 224                 failures++;
 225             }
 226         }
 227 
 228         if (failures > 0) {
 229             throw new RuntimeException("Test failed for ignoreMetadata "
 230                 + ignoreMetadata + " and readUnknownTags " + readUnknownTags);
 231         }
 232     }
 233 
 234     public void run() {
 235         try {
 236             writeImage();
 237             readAndCheckImage();
 238         } catch (Exception e) {
 239             throw new RuntimeException(e);
 240         }
 241     }
 242 
 243     private void check(boolean ok, String msg) {
 244         if (!ok) { throw new RuntimeException(msg); }
 245     }
 246 
 247     public static void main(String[] args) {
 248         int failures = 0;
 249 
 250         System.out.println();
 251         for (boolean ignoreMetadata : new boolean[] {false, true}) {
 252             for (boolean readUnknownTags : new boolean[] {false, true}) {
 253                 try {
 254                     System.out.printf
 255                         ("ignoreMetadata: %s, readUnknownTags: %s%n",
 256                         ignoreMetadata, readUnknownTags);
 257                     (new ReadParamTest(ignoreMetadata,
 258                         readUnknownTags)).run();
 259                 } catch (Exception e) {
 260                     e.printStackTrace();
 261                     failures++;
 262                 } finally {
 263                     System.out.println();
 264                 }
 265             }
 266         }
 267     }
 268 }