1 /*
   2  * Copyright (c) 2005, 2015, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.imageio.plugins.tiff;
  27 
  28 import java.nio.charset.StandardCharsets;
  29 import java.util.ArrayList;
  30 import java.util.List;
  31 
  32 /**
  33  * A class representing the tags found in an Exif GPS Info IFD.
  34  *
  35  * <p> The definitions of the data types referenced by the field
  36  * definitions may be found in the {@link TIFFTag TIFFTag} class.
  37  *
  38  * @since 1.9
  39  * @see   ExifTIFFTagSet
  40  */
  41 public class ExifGPSTagSet extends TIFFTagSet {
  42     private static ExifGPSTagSet theInstance = null;
  43 
  44     /**
  45      * A tag indicating the GPS tag version (type BYTE, count = 4).
  46      *
  47      * @see #GPS_VERSION_2_2
  48      */
  49     public static final int TAG_GPS_VERSION_ID = 0;
  50 
  51     /**
  52      * A value to be used with the "GPSVersionID" tag to indicate GPS version
  53      * 2.2.  The value equals the US-ASCII encoding of the byte array
  54      * <code>{'2', '2', '0', '0'}</code>.
  55      *
  56      * @see #TAG_GPS_VERSION_ID
  57      */
  58     public static final String GPS_VERSION_2_2 =
  59         new String(new byte[] { '2', '2', '0', '0' },
  60         StandardCharsets.US_ASCII);
  61 
  62     /**
  63      * A tag indicating the North or South latitude (type ASCII, count = 2).
  64      *
  65      * @see #LATITUDE_REF_NORTH
  66      * @see #LATITUDE_REF_SOUTH
  67      */
  68     public static final int TAG_GPS_LATITUDE_REF = 1;
  69 
  70     /**
  71      * A tag indicating the Latitude (type RATIONAL, count = 3).
  72      */
  73     public static final int TAG_GPS_LATITUDE = 2;
  74 
  75     /**
  76      * A tag indicating the East or West Longitude (type ASCII, count = 2).
  77      *
  78      * @see #LONGITUDE_REF_EAST
  79      * @see #LONGITUDE_REF_WEST
  80      */
  81     public static final int TAG_GPS_LONGITUDE_REF = 3;
  82 
  83     /**
  84      * A tag indicating the Longitude (type RATIONAL, count = 3).
  85      */
  86     public static final int TAG_GPS_LONGITUDE = 4;
  87 
  88     /**
  89      * A tag indicating the Altitude reference (type BYTE, count = 1);
  90      *
  91      * @see #ALTITUDE_REF_SEA_LEVEL
  92      * @see #ALTITUDE_REF_SEA_LEVEL_REFERENCE
  93      */
  94     public static final int TAG_GPS_ALTITUDE_REF = 5;
  95 
  96     /**
  97      * A tag indicating the Altitude (type RATIONAL, count = 1).
  98      */
  99     public static final int TAG_GPS_ALTITUDE = 6;
 100 
 101     /**
 102      * A tag indicating the GPS time (atomic clock) (type RATIONAL, count = 3).
 103      */
 104     public static final int TAG_GPS_TIME_STAMP = 7;
 105 
 106     /**
 107      * A tag indicating the GPS satellites used for measurement (type ASCII).
 108      */
 109     public static final int TAG_GPS_SATELLITES = 8;
 110 
 111     /**
 112      * A tag indicating the GPS receiver status (type ASCII, count = 2).
 113      *
 114      * @see #STATUS_MEASUREMENT_IN_PROGRESS
 115      * @see #STATUS_MEASUREMENT_INTEROPERABILITY
 116      */
 117     public static final int TAG_GPS_STATUS = 9;
 118 
 119     /**
 120      * A tag indicating the GPS measurement mode (type ASCII, count = 2).
 121      *
 122      * @see #MEASURE_MODE_2D
 123      * @see #MEASURE_MODE_3D
 124      */
 125     public static final int TAG_GPS_MEASURE_MODE = 10;
 126 
 127     /**
 128      * A tag indicating the Measurement precision (type RATIONAL, count = 1).
 129      */
 130     public static final int TAG_GPS_DOP = 11;
 131 
 132     /**
 133      * A tag indicating the Speed unit (type ASCII, count = 2).
 134      *
 135      * @see #SPEED_REF_KILOMETERS_PER_HOUR
 136      * @see #SPEED_REF_MILES_PER_HOUR
 137      * @see #SPEED_REF_KNOTS
 138      */
 139     public static final int TAG_GPS_SPEED_REF = 12;
 140 
 141     /**
 142      * A tag indicating the Speed of GPS receiver (type RATIONAL, count = 1).
 143      */
 144     public static final int TAG_GPS_SPEED = 13;
 145 
 146     /**
 147      * A tag indicating the Reference for direction of movement (type ASCII,
 148      * count = 2).
 149      *
 150      * @see #DIRECTION_REF_TRUE
 151      * @see #DIRECTION_REF_MAGNETIC
 152      */
 153     public static final int TAG_GPS_TRACK_REF = 14;
 154 
 155     /**
 156      * A tag indicating the Direction of movement (type RATIONAL, count = 1).
 157      */
 158     public static final int TAG_GPS_TRACK = 15;
 159 
 160     /**
 161      * A tag indicating the Reference for direction of image (type ASCII,
 162      * count = 2).
 163      *
 164      * @see #DIRECTION_REF_TRUE
 165      * @see #DIRECTION_REF_MAGNETIC
 166      */
 167     public static final int TAG_GPS_IMG_DIRECTION_REF = 16;
 168 
 169     /**
 170      * A tag indicating the Direction of image (type RATIONAL, count = 1).
 171      */
 172     public static final int TAG_GPS_IMG_DIRECTION = 17;
 173 
 174     /**
 175      * A tag indicating the Geodetic survey data used (type ASCII).
 176      */
 177     public static final int TAG_GPS_MAP_DATUM = 18;
 178 
 179     /**
 180      * A tag indicating the Reference for latitude of destination (type
 181      * ASCII, count = 2).
 182      *
 183      * @see #LATITUDE_REF_NORTH
 184      * @see #LATITUDE_REF_SOUTH
 185      */
 186     public static final int TAG_GPS_DEST_LATITUDE_REF = 19;
 187 
 188     /**
 189      * A tag indicating the Latitude of destination (type RATIONAL, count = 3).
 190      */
 191     public static final int TAG_GPS_DEST_LATITUDE = 20;
 192 
 193     /**
 194      * A tag indicating the Reference for longitude of destination (type
 195      * ASCII, count = 2).
 196      *
 197      * @see #LONGITUDE_REF_EAST
 198      * @see #LONGITUDE_REF_WEST
 199      */
 200     public static final int TAG_GPS_DEST_LONGITUDE_REF = 21;
 201 
 202     /**
 203      * A tag indicating the Longitude of destination (type RATIONAL,
 204      * count = 3).
 205      */
 206     public static final int TAG_GPS_DEST_LONGITUDE = 22;
 207 
 208     /**
 209      * A tag indicating the Reference for bearing of destination (type ASCII,
 210      * count = 2).
 211      *
 212      * @see #DIRECTION_REF_TRUE
 213      * @see #DIRECTION_REF_MAGNETIC
 214      */
 215     public static final int TAG_GPS_DEST_BEARING_REF = 23;
 216 
 217     /**
 218      * A tag indicating the Bearing of destination (type RATIONAL, count = 1).
 219      */
 220     public static final int TAG_GPS_DEST_BEARING = 24;
 221 
 222     /**
 223      * A tag indicating the Reference for distance to destination (type ASCII,
 224      * count = 2).
 225      *
 226      * @see #DEST_DISTANCE_REF_KILOMETERS
 227      * @see #DEST_DISTANCE_REF_MILES
 228      * @see #DEST_DISTANCE_REF_KNOTS
 229      */
 230     public static final int TAG_GPS_DEST_DISTANCE_REF = 25;
 231 
 232     /**
 233      * A tag indicating the Distance to destination (type RATIONAL, count = 1).
 234      */
 235     public static final int TAG_GPS_DEST_DISTANCE = 26;
 236 
 237     /**
 238      * A tag indicating the Name of GPS processing method (type UNDEFINED).
 239      */
 240     public static final int TAG_GPS_PROCESSING_METHOD = 27;
 241 
 242     /**
 243      * A tag indicating the Name of GPS area (type UNDEFINED).
 244      */
 245     public static final int TAG_GPS_AREA_INFORMATION = 28;
 246 
 247     /**
 248      * A tag indicating the GPS date (type ASCII, count 11).
 249      */
 250     public static final int TAG_GPS_DATE_STAMP = 29;
 251 
 252     /**
 253      * A tag indicating the GPS differential correction (type SHORT,
 254      * count = 1).
 255      *
 256      * @see #DIFFERENTIAL_CORRECTION_NONE
 257      * @see #DIFFERENTIAL_CORRECTION_APPLIED
 258      */
 259     public static final int TAG_GPS_DIFFERENTIAL = 30;
 260 
 261     /**
 262      * A value to be used with the "GPSLatitudeRef" and
 263      * "GPSDestLatitudeRef" tags.
 264      *
 265      * @see #TAG_GPS_LATITUDE_REF
 266      * @see #TAG_GPS_DEST_LATITUDE_REF
 267      */
 268     public static final String LATITUDE_REF_NORTH = "N";
 269 
 270     /**
 271      * A value to be used with the "GPSLatitudeRef" and
 272      * "GPSDestLatitudeRef" tags.
 273      *
 274      * @see #TAG_GPS_LATITUDE_REF
 275      * @see #TAG_GPS_DEST_LATITUDE_REF
 276      */
 277     public static final String LATITUDE_REF_SOUTH = "S";
 278 
 279     /**
 280      * A value to be used with the "GPSLongitudeRef" and
 281      * "GPSDestLongitudeRef" tags.
 282      *
 283      * @see #TAG_GPS_LONGITUDE_REF
 284      * @see #TAG_GPS_DEST_LONGITUDE_REF
 285      */
 286     public static final String LONGITUDE_REF_EAST = "E";
 287 
 288     /**
 289      * A value to be used with the "GPSLongitudeRef" and
 290      * "GPSDestLongitudeRef" tags.
 291      *
 292      * @see #TAG_GPS_LONGITUDE_REF
 293      * @see #TAG_GPS_DEST_LONGITUDE_REF
 294      */
 295     public static final String LONGITUDE_REF_WEST = "W";
 296 
 297     /**
 298      * A value to be used with the "GPSAltitudeRef" tag.
 299      *
 300      * @see #TAG_GPS_ALTITUDE_REF
 301      */
 302     public static final int ALTITUDE_REF_SEA_LEVEL = 0;
 303 
 304     /**
 305      * A value to be used with the "GPSAltitudeRef" tag.
 306      *
 307      * @see #TAG_GPS_ALTITUDE_REF
 308      */
 309     public static final int ALTITUDE_REF_SEA_LEVEL_REFERENCE = 1;
 310 
 311     /**
 312      * A value to be used with the "GPSStatus" tag.
 313      *
 314      * @see #TAG_GPS_STATUS
 315      */
 316     public static final String STATUS_MEASUREMENT_IN_PROGRESS = "A";
 317 
 318     /**
 319      * A value to be used with the "GPSStatus" tag.
 320      *
 321      * @see #TAG_GPS_STATUS
 322      */
 323     public static final String STATUS_MEASUREMENT_INTEROPERABILITY = "V";
 324 
 325     /**
 326      * A value to be used with the "GPSMeasureMode" tag.
 327      *
 328      * @see #TAG_GPS_MEASURE_MODE
 329      */
 330     public static final String MEASURE_MODE_2D = "2";
 331 
 332     /**
 333      * A value to be used with the "GPSMeasureMode" tag.
 334      *
 335      * @see #TAG_GPS_MEASURE_MODE
 336      */
 337     public static final String MEASURE_MODE_3D = "3";
 338 
 339     /**
 340      * A value to be used with the "GPSSpeedRef" tag.
 341      *
 342      * @see #TAG_GPS_SPEED_REF
 343      */
 344     public static final String SPEED_REF_KILOMETERS_PER_HOUR = "K";
 345 
 346     /**
 347      * A value to be used with the "GPSSpeedRef" tag.
 348      *
 349      * @see #TAG_GPS_SPEED_REF
 350      */
 351     public static final String SPEED_REF_MILES_PER_HOUR = "M";
 352 
 353     /**
 354      * A value to be used with the "GPSSpeedRef" tag.
 355      *
 356      * @see #TAG_GPS_SPEED_REF
 357      */
 358     public static final String SPEED_REF_KNOTS = "N";
 359 
 360     /**
 361      * A value to be used with the "GPSTrackRef", "GPSImgDirectionRef",
 362      * and "GPSDestBearingRef" tags.
 363      *
 364      * @see #TAG_GPS_TRACK_REF
 365      * @see #TAG_GPS_IMG_DIRECTION_REF
 366      * @see #TAG_GPS_DEST_BEARING_REF
 367      */
 368     public static final String DIRECTION_REF_TRUE = "T";
 369 
 370     /**
 371      * A value to be used with the "GPSTrackRef", "GPSImgDirectionRef",
 372      * and "GPSDestBearingRef" tags.
 373      *
 374      * @see #TAG_GPS_TRACK_REF
 375      * @see #TAG_GPS_IMG_DIRECTION_REF
 376      * @see #TAG_GPS_DEST_BEARING_REF
 377      */
 378     public static final String DIRECTION_REF_MAGNETIC = "M";
 379 
 380     /**
 381      * A value to be used with the "GPSDestDistanceRef" tag.
 382      *
 383      * @see #TAG_GPS_DEST_DISTANCE_REF
 384      */
 385     public static final String DEST_DISTANCE_REF_KILOMETERS = "K";
 386 
 387     /**
 388      * A value to be used with the "GPSDestDistanceRef" tag.
 389      *
 390      * @see #TAG_GPS_DEST_DISTANCE_REF
 391      */
 392     public static final String DEST_DISTANCE_REF_MILES = "M";
 393 
 394     /**
 395      * A value to be used with the "GPSDestDistanceRef" tag.
 396      *
 397      * @see #TAG_GPS_DEST_DISTANCE_REF
 398      */
 399     public static final String DEST_DISTANCE_REF_KNOTS = "N";
 400 
 401     /**
 402      * A value to be used with the "GPSDifferential" tag.
 403      *
 404      * @see #TAG_GPS_DIFFERENTIAL
 405      */
 406     public static final int DIFFERENTIAL_CORRECTION_NONE = 0;
 407 
 408     /**
 409      * A value to be used with the "GPSDifferential" tag.
 410      *
 411      * @see #TAG_GPS_DIFFERENTIAL
 412      */
 413     public static final int DIFFERENTIAL_CORRECTION_APPLIED = 1;
 414 
 415     static class GPSVersionID extends TIFFTag {
 416         public GPSVersionID() {
 417             super("GPSVersionID",
 418                   TAG_GPS_VERSION_ID,
 419                   1 << TIFFTag.TIFF_BYTE);
 420         }
 421     }
 422 
 423     static class GPSLatitudeRef extends TIFFTag {
 424         public GPSLatitudeRef() {
 425             super("GPSLatitudeRef",
 426                   TAG_GPS_LATITUDE_REF,
 427                   1 << TIFFTag.TIFF_ASCII);
 428         }
 429     }
 430 
 431     static class GPSLatitude extends TIFFTag {
 432         public GPSLatitude() {
 433             super("GPSLatitude",
 434                   TAG_GPS_LATITUDE,
 435                   1 << TIFFTag.TIFF_RATIONAL);
 436         }
 437     }
 438 
 439     static class GPSLongitudeRef extends TIFFTag {
 440         public GPSLongitudeRef() {
 441             super("GPSLongitudeRef",
 442                   TAG_GPS_LONGITUDE_REF,
 443                   1 << TIFFTag.TIFF_ASCII);
 444         }
 445     }
 446 
 447     static class GPSLongitude extends TIFFTag {
 448         public GPSLongitude() {
 449             super("GPSLongitude",
 450                   TAG_GPS_LONGITUDE,
 451                   1 << TIFFTag.TIFF_RATIONAL);
 452         }
 453     }
 454 
 455     static class GPSAltitudeRef extends TIFFTag {
 456         public GPSAltitudeRef() {
 457             super("GPSAltitudeRef",
 458                   TAG_GPS_ALTITUDE_REF,
 459                   1 << TIFFTag.TIFF_BYTE);
 460 
 461             addValueName(ALTITUDE_REF_SEA_LEVEL, "Sea level");
 462             addValueName(ALTITUDE_REF_SEA_LEVEL_REFERENCE,
 463                          "Sea level reference (negative value)");
 464         }
 465     }
 466 
 467     static class GPSAltitude extends TIFFTag {
 468         public GPSAltitude() {
 469             super("GPSAltitude",
 470                   TAG_GPS_ALTITUDE,
 471                   1 << TIFFTag.TIFF_RATIONAL);
 472         }
 473     }
 474 
 475     static class GPSTimeStamp extends TIFFTag {
 476         public GPSTimeStamp() {
 477             super("GPSTimeStamp",
 478                   TAG_GPS_TIME_STAMP,
 479                   1 << TIFFTag.TIFF_RATIONAL);
 480         }
 481     }
 482 
 483     static class GPSSatellites extends TIFFTag {
 484         public GPSSatellites() {
 485             super("GPSSatellites",
 486                   TAG_GPS_SATELLITES,
 487                   1 << TIFFTag.TIFF_ASCII);
 488         }
 489     }
 490 
 491     static class GPSStatus extends TIFFTag {
 492         public GPSStatus() {
 493             super("GPSStatus",
 494                   TAG_GPS_STATUS,
 495                   1 << TIFFTag.TIFF_ASCII);
 496         }
 497     }
 498 
 499     static class GPSMeasureMode extends TIFFTag {
 500         public GPSMeasureMode() {
 501             super("GPSMeasureMode",
 502                   TAG_GPS_MEASURE_MODE,
 503                   1 << TIFFTag.TIFF_ASCII);
 504         }
 505     }
 506 
 507     static class GPSDOP extends TIFFTag {
 508         public GPSDOP() {
 509             super("GPSDOP",
 510                   TAG_GPS_DOP,
 511                   1 << TIFFTag.TIFF_RATIONAL);
 512         }
 513     }
 514 
 515     static class GPSSpeedRef extends TIFFTag {
 516         public GPSSpeedRef() {
 517             super("GPSSpeedRef",
 518                   TAG_GPS_SPEED_REF,
 519                   1 << TIFFTag.TIFF_ASCII);
 520         }
 521     }
 522 
 523     static class GPSSpeed extends TIFFTag {
 524         public GPSSpeed() {
 525             super("GPSSpeed",
 526                   TAG_GPS_SPEED,
 527                   1 << TIFFTag.TIFF_RATIONAL);
 528         }
 529     }
 530 
 531     static class GPSTrackRef extends TIFFTag {
 532         public GPSTrackRef() {
 533             super("GPSTrackRef",
 534                   TAG_GPS_TRACK_REF,
 535                   1 << TIFFTag.TIFF_ASCII);
 536         }
 537     }
 538 
 539     static class GPSTrack extends TIFFTag {
 540         public GPSTrack() {
 541             super("GPSTrack",
 542                   TAG_GPS_TRACK,
 543                   1 << TIFFTag.TIFF_RATIONAL);
 544         }
 545     }
 546 
 547     static class GPSImgDirectionRef extends TIFFTag {
 548         public GPSImgDirectionRef() {
 549             super("GPSImgDirectionRef",
 550                   TAG_GPS_IMG_DIRECTION_REF,
 551                   1 << TIFFTag.TIFF_ASCII);
 552         }
 553     }
 554 
 555     static class GPSImgDirection extends TIFFTag {
 556         public GPSImgDirection() {
 557             super("GPSImgDirection",
 558                   TAG_GPS_IMG_DIRECTION,
 559                   1 << TIFFTag.TIFF_RATIONAL);
 560         }
 561     }
 562 
 563     static class GPSMapDatum extends TIFFTag {
 564         public GPSMapDatum() {
 565             super("GPSMapDatum",
 566                   TAG_GPS_MAP_DATUM,
 567                   1 << TIFFTag.TIFF_ASCII);
 568         }
 569     }
 570 
 571     static class GPSDestLatitudeRef extends TIFFTag {
 572         public GPSDestLatitudeRef() {
 573             super("GPSDestLatitudeRef",
 574                   TAG_GPS_DEST_LATITUDE_REF,
 575                   1 << TIFFTag.TIFF_ASCII);
 576         }
 577     }
 578 
 579     static class GPSDestLatitude extends TIFFTag {
 580         public GPSDestLatitude() {
 581             super("GPSDestLatitude",
 582                   TAG_GPS_DEST_LATITUDE,
 583                   1 << TIFFTag.TIFF_RATIONAL);
 584         }
 585     }
 586 
 587     static class GPSDestLongitudeRef extends TIFFTag {
 588         public GPSDestLongitudeRef() {
 589             super("GPSDestLongitudeRef",
 590                   TAG_GPS_DEST_LONGITUDE_REF,
 591                   1 << TIFFTag.TIFF_ASCII);
 592         }
 593     }
 594 
 595     static class GPSDestLongitude extends TIFFTag {
 596         public GPSDestLongitude() {
 597             super("GPSDestLongitude",
 598                   TAG_GPS_DEST_LONGITUDE,
 599                   1 << TIFFTag.TIFF_RATIONAL);
 600         }
 601     }
 602 
 603     static class GPSDestBearingRef extends TIFFTag {
 604         public GPSDestBearingRef() {
 605             super("GPSDestBearingRef",
 606                   TAG_GPS_DEST_BEARING_REF,
 607                   1 << TIFFTag.TIFF_ASCII);
 608         }
 609     }
 610 
 611     static class GPSDestBearing extends TIFFTag {
 612         public GPSDestBearing() {
 613             super("GPSDestBearing",
 614                   TAG_GPS_DEST_BEARING,
 615                   1 << TIFFTag.TIFF_RATIONAL);
 616         }
 617     }
 618 
 619     static class GPSDestDistanceRef extends TIFFTag {
 620         public GPSDestDistanceRef() {
 621             super("GPSDestDistanceRef",
 622                   TAG_GPS_DEST_DISTANCE_REF,
 623                   1 << TIFFTag.TIFF_ASCII);
 624         }
 625     }
 626 
 627     static class GPSDestDistance extends TIFFTag {
 628         public GPSDestDistance() {
 629             super("GPSDestDistance",
 630                   TAG_GPS_DEST_DISTANCE,
 631                   1 << TIFFTag.TIFF_RATIONAL);
 632         }
 633     }
 634 
 635     static class GPSProcessingMethod extends TIFFTag {
 636         public GPSProcessingMethod() {
 637             super("GPSProcessingMethod",
 638                   TAG_GPS_PROCESSING_METHOD,
 639                   1 << TIFFTag.TIFF_UNDEFINED);
 640         }
 641     }
 642 
 643     static class GPSAreaInformation extends TIFFTag {
 644         public GPSAreaInformation() {
 645             super("GPSAreaInformation",
 646                   TAG_GPS_AREA_INFORMATION,
 647                   1 << TIFFTag.TIFF_UNDEFINED);
 648         }
 649     }
 650 
 651     static class GPSDateStamp extends TIFFTag {
 652         public GPSDateStamp() {
 653             super("GPSDateStamp",
 654                   TAG_GPS_DATE_STAMP,
 655                   1 << TIFFTag.TIFF_ASCII);
 656         }
 657     }
 658 
 659     static class GPSDifferential extends TIFFTag {
 660         public GPSDifferential() {
 661             super("GPSDifferential",
 662                   TAG_GPS_DIFFERENTIAL,
 663                   1 << TIFFTag.TIFF_SHORT);
 664             addValueName(DIFFERENTIAL_CORRECTION_NONE,
 665                          "Measurement without differential correction");
 666             addValueName(DIFFERENTIAL_CORRECTION_APPLIED,
 667                          "Differential correction applied");
 668 
 669         }
 670     }
 671 
 672     private static List<TIFFTag> initTags() {
 673         ArrayList<TIFFTag> tags = new ArrayList<TIFFTag>(31);
 674 
 675         tags.add(new GPSVersionID());
 676         tags.add(new GPSLatitudeRef());
 677         tags.add(new GPSLatitude());
 678         tags.add(new GPSLongitudeRef());
 679         tags.add(new GPSLongitude());
 680         tags.add(new GPSAltitudeRef());
 681         tags.add(new GPSAltitude());
 682         tags.add(new GPSTimeStamp());
 683         tags.add(new GPSSatellites());
 684         tags.add(new GPSStatus());
 685         tags.add(new GPSMeasureMode());
 686         tags.add(new GPSDOP());
 687         tags.add(new GPSSpeedRef());
 688         tags.add(new GPSSpeed());
 689         tags.add(new GPSTrackRef());
 690         tags.add(new GPSTrack());
 691         tags.add(new GPSImgDirectionRef());
 692         tags.add(new GPSImgDirection());
 693         tags.add(new GPSMapDatum());
 694         tags.add(new GPSDestLatitudeRef());
 695         tags.add(new GPSDestLatitude());
 696         tags.add(new GPSDestLongitudeRef());
 697         tags.add(new GPSDestLongitude());
 698         tags.add(new GPSDestBearingRef());
 699         tags.add(new GPSDestBearing());
 700         tags.add(new GPSDestDistanceRef());
 701         tags.add(new GPSDestDistance());
 702         tags.add(new GPSProcessingMethod());
 703         tags.add(new GPSAreaInformation());
 704         tags.add(new GPSDateStamp());
 705         tags.add(new GPSDifferential());
 706         return tags;
 707     }
 708 
 709     private ExifGPSTagSet() {
 710         super(initTags());
 711     }
 712 
 713     /**
 714      * Returns a shared instance of an <code>ExifGPSTagSet</code>.
 715      *
 716      * @return an <code>ExifGPSTagSet</code> instance.
 717      */
 718     public synchronized static ExifGPSTagSet getInstance() {
 719         if (theInstance == null) {
 720             theInstance = new ExifGPSTagSet();
 721         }
 722         return theInstance;
 723     }
 724 }