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 some simple checks for TIFFDirectory
  29  * @run     main TIFFDirectoryTest
  30  */
  31 
  32 import java.util.List;
  33 import java.util.ArrayList;
  34 import javax.imageio.metadata.*;
  35 import javax.imageio.plugins.tiff.*;
  36 
  37 
  38 public class TIFFDirectoryTest {
  39 
  40     private static void check(boolean ok, String msg) {
  41         if (!ok) { throw new RuntimeException(msg); }
  42     }
  43 
  44     private void run() {
  45 
  46         int type = TIFFTag.TIFF_LONG, dt = 1 << type;
  47         int n0 = 1000, n1 = 1001, n2 = 1002, n3 = 1003;
  48 
  49         TIFFTag tag1 = new TIFFTag(Integer.toString(n1), n1, dt);
  50         TIFFTag tag2 = new TIFFTag(Integer.toString(n2), n2, dt);
  51         TIFFTag tag3 = new TIFFTag(Integer.toString(n3), n3, dt);
  52         TIFFTag parent = new TIFFTag(Integer.toString(n0), n0, dt);
  53 
  54         // tag sets array must not be null
  55         boolean ok = false;
  56         try { new TIFFDirectory(null, parent); }
  57         catch (NullPointerException e) { ok = true; }
  58         check(ok, "can construct TIFFDirectory with null tagsets array");
  59 
  60         // but can be empty
  61         TIFFTagSet emptySets[] = {};
  62         TIFFDirectory d = new TIFFDirectory(emptySets, parent);
  63         check(d.getTagSets().length == 0, "invalid number of tag sets");
  64         check(d.getParentTag().getName().equals(Integer.toString(n0)) &&
  65              (d.getParentTag().getNumber() == n0), "invalid parent tag");
  66 
  67 
  68         // add tags
  69         List<TIFFTag> tags = new ArrayList<>();
  70         tags.add(tag1);
  71         tags.add(tag2);
  72         TIFFTagSet ts1 = new TIFFTagSet(tags);
  73 
  74         tags.clear();
  75         tags.add(tag3);
  76         TIFFTagSet ts2 = new TIFFTagSet(tags);
  77 
  78         TIFFTagSet sets[] = {ts1, ts2};
  79         d = new TIFFDirectory(sets, parent);
  80 
  81         check(d.getTagSets().length == sets.length, "invalid number of tag sets");
  82 
  83         // check getTag()
  84         for (int i = n1; i <= n3; i++) {
  85             TIFFTag t = d.getTag(i);
  86             check(t.getNumber() == i, "invalid tag number");
  87             check(t.getName().equals(Integer.toString(i)), "invalid tag name");
  88             check(t.getDataTypes() == dt, "invalid tag data types");
  89         }
  90 
  91         TIFFDirectory d2;
  92         try { d2 = d.clone(); }
  93         catch (CloneNotSupportedException e) { throw new RuntimeException(e); }
  94 
  95         // check removeTagSet()
  96         d.removeTagSet(ts2);
  97         check(d.getTagSets().length == 1, "invalid number of tag sets");
  98         check(d.getTagSets()[0].getTag(n1).getName().equals(Integer.toString(n1)),
  99             "invalid tag name");
 100         check(d.getTagSets()[0].getTag(n2).getName().equals(Integer.toString(n2)),
 101             "invalid tag name");
 102 
 103         d.removeTagSet(ts1);
 104         check(d.getTagSets().length == 0, "invalid number of tag sets");
 105 
 106         // check cloned data
 107         check(d2.getTagSets().length == sets.length,
 108             "invalid number of tag sets");
 109         TIFFTagSet sets2[] = d2.getTagSets();
 110         check(sets2.length == sets.length, "invalid number of tag sets");
 111         check(
 112             (sets2[0].getTag(Integer.toString(n1)).getNumber() == n1) &&
 113             (sets2[0].getTag(Integer.toString(n2)).getNumber() == n2) &&
 114             (sets2[0].getTag(Integer.toString(n0)) == null) &&
 115             (sets2[1].getTag(Integer.toString(n3)).getNumber() == n3) &&
 116             (sets2[1].getTag(Integer.toString(n0)) == null), "invalid data");
 117 
 118         check(
 119             (sets2[0].getTag(Integer.toString(n1)).getDataTypes() == dt) &&
 120             (sets2[0].getTag(Integer.toString(n2)).getDataTypes() == dt) &&
 121             (sets2[1].getTag(Integer.toString(n3)).getDataTypes() == dt),
 122             "invalid data type");
 123 
 124         // must not be able to call removeTagSet with null argument
 125         ok = false;
 126         try { d.removeTagSet(null); }
 127         catch (NullPointerException e) { ok = true; }
 128         check(ok, "must not be able to use null as an argument for remove");
 129 
 130         // check parent tag
 131         check( d.getParentTag().getName().equals(Integer.toString(n0)) &&
 132               d2.getParentTag().getName().equals(Integer.toString(n0)),
 133             "invalid parent tag name");
 134 
 135         check(( d.getParentTag().getNumber() == n0) &&
 136               (d2.getParentTag().getNumber() == n0),
 137             "invalid parent tag number");
 138 
 139         check(( d.getParentTag().getDataTypes() == dt) &&
 140               (d2.getParentTag().getDataTypes() == dt),
 141             "invalid parent data type");
 142 
 143         d.addTagSet(ts1);
 144         d.addTagSet(ts2);
 145 
 146         // add the same tag set twice and check that nothing changed
 147         d.addTagSet(ts2);
 148 
 149         check(d.getTagSets().length == 2, "invalid number of tag sets");
 150 
 151         // check field operations
 152         check(d.getNumTIFFFields() == 0, "invalid TIFFFields number");
 153         check(d.getTIFFField(Integer.MAX_VALUE) == null,
 154             "must return null TIFFField");
 155 
 156         long offset = 4L;
 157         long a[] = {0, Integer.MAX_VALUE, (1 << 32) - 1};
 158         int v = 100500;
 159         TIFFField
 160                 f1 = new TIFFField(tag1, type, offset, d),
 161                 f2 = new TIFFField(tag2, v),
 162                 f3 = new TIFFField(tag3, type, a.length, a);
 163 
 164         d.addTIFFField(f1);
 165         d.addTIFFField(f2);
 166         d.addTIFFField(f3);
 167 
 168         check(d.containsTIFFField(n1) &&
 169               d.containsTIFFField(n2) &&
 170               d.containsTIFFField(n3) &&
 171              !d.containsTIFFField(n0), "invalid containsTIFFField() results");
 172 
 173         check(d.getTIFFField(n0) == null, "can get unadded field");
 174 
 175         check(d.getNumTIFFFields() == 3, "invalid TIFFFields number");
 176 
 177         check(d.getTIFFField(n1).getCount() == 1, "invalid TIFFField count");
 178         check(d.getTIFFField(n1).getAsLong(0) == offset, "invalid offset");
 179 
 180         check(d.getTIFFField(n2).getCount() == 1, "invalid TIFFField count");
 181         check(d.getTIFFField(n2).getAsInt(0) == v, "invalid TIFFField value");
 182 
 183         check(d.getTIFFField(n3).getCount() == a.length,
 184             "invalid TIFFField count");
 185         for (int i = 0; i < a.length; ++i) {
 186             check(d.getTIFFField(n3).getAsLong(i) == a[i],
 187                 "invalid TIFFField value");
 188         }
 189 
 190         TIFFField nested = d.getTIFFField(n1).getDirectory().getTIFFField(n1);
 191         check(nested.getTag().getNumber() == n1, "invalid tag number");
 192         check(nested.getCount() == 1, "invalid field count");
 193         check(nested.getAsLong(0) == offset, "invalid offset");
 194 
 195         // check that the field is overwritten correctly
 196         int v2 = 1 << 16;
 197         d.addTIFFField(new TIFFField(tag3, v2));
 198         check(d.getTIFFField(n3).getCount() == 1, "invalid TIFFField count");
 199         check(d.getTIFFField(n3).getAsInt(0)== v2, "invalid TIFFField value");
 200         check(d.getNumTIFFFields() == 3, "invalid TIFFFields number");
 201 
 202         // check removeTIFFField()
 203         d.removeTIFFField(n3);
 204         check(d.getNumTIFFFields() == 2, "invalid TIFFFields number");
 205         check(d.getTIFFField(n3) == null, "can get removed field");
 206 
 207         d.removeTIFFFields();
 208         check((d.getTIFFField(n1) == null) && (d.getTIFFField(n2) == null),
 209             "can get removed field");
 210         check((d.getNumTIFFFields() == 0) && (d.getTIFFFields().length == 0),
 211             "invalid TIFFFields number");
 212 
 213         // check that array returned by getTIFFFields() is sorted
 214         // by tag number (as it stated in the docs)
 215         d.addTIFFField(f3);
 216         d.addTIFFField(f1);
 217         d.addTIFFField(f2);
 218 
 219         TIFFField fa[] = d.getTIFFFields();
 220         check(fa.length == 3, "invalid number of fields");
 221         check((fa[0].getTagNumber() == n1) &&
 222               (fa[1].getTagNumber() == n2) &&
 223               (fa[2].getTagNumber() == n3),
 224             "array of the fields must be sorted by tag number");
 225 
 226         d.removeTIFFFields();
 227         d.addTIFFField(f2);
 228 
 229         // test getAsMetaData / createFromMetadata
 230         try {
 231             d2 = TIFFDirectory.createFromMetadata(d.getAsMetadata());
 232         } catch (IIOInvalidTreeException e) {
 233             throw new RuntimeException(e);
 234         }
 235 
 236         // check new data
 237         check(d2.getTagSets().length == sets.length,
 238             "invalid number of tag sets");
 239         sets2 = d2.getTagSets();
 240         check(sets2.length == sets.length, "invalid number of tag sets");
 241         check(
 242             (sets2[0].getTag(Integer.toString(n1)).getNumber() == n1) &&
 243             (sets2[0].getTag(Integer.toString(n2)).getNumber() == n2) &&
 244             (sets2[0].getTag(Integer.toString(n0)) == null) &&
 245             (sets2[1].getTag(Integer.toString(n3)).getNumber() == n3) &&
 246             (sets2[1].getTag(Integer.toString(n0)) == null), "invalid data");
 247 
 248         check(
 249             (sets2[0].getTag(Integer.toString(n1)).getDataTypes() == dt) &&
 250             (sets2[0].getTag(Integer.toString(n2)).getDataTypes() == dt) &&
 251             (sets2[1].getTag(Integer.toString(n3)).getDataTypes() == dt),
 252             "invalid data type");
 253 
 254         check(!d2.containsTIFFField(n1) &&
 255                d2.containsTIFFField(n2) &&
 256               !d2.containsTIFFField(n3), "invalid containsTIFFField() results");
 257         check(d2.getTIFFField(n2).getCount()  == 1, "invalid TIFFField count");
 258         check(d2.getTIFFField(n2).getAsInt(0) == v, "invalid TIFFField value");
 259 
 260         check((d2.getParentTag().getNumber() == n0) &&
 261                d2.getParentTag().getName().equals(Integer.toString(n0)),
 262                "invalid parent tag");
 263     }
 264 
 265     public static void main(String[] args) { (new TIFFDirectoryTest()).run(); }
 266 }