sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmarec...@apache.org
Subject svn commit: r1768741 [1/2] - in /sis/branches/JDK8/storage: sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/ sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ sis-storage/src/main/java/org/apache/sis/internal/storage/
Date Tue, 08 Nov 2016 17:19:55 GMT
Author: rmarechal
Date: Tue Nov  8 17:19:54 2016
New Revision: 1768741

URL: http://svn.apache.org/viewvc?rev=1768741&view=rev
Log:
First draft of CRS creation from Tiff tags. Work in progress.


Added:
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeysRange.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/TiffCRSBuilder.java
Modified:
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Tags.java
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java?rev=1768741&r1=1768740&r2=1768741&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] Tue Nov  8 17:19:54 2016
@@ -59,10 +59,80 @@ public final class Resources extends Ind
         }
 
         /**
+         * Apache SIS implementation stipulate that the height of the dithering or halftoning matrix
+         * used to create a dithered or halftoned bilevel file is: CellHeight =  “{0}” .
+         */
+        public static final short CellHeight_1 = 7;
+
+        /**
+         * Apache SIS implementation stipulate that the width of the dithering or halftoning matrix
+         * used to create a dithered or halftoned bilevel file is: CellWidth =  “{0}” .
+         */
+        public static final short CellWidth_1 = 8;
+
+        /**
          * Apache SIS implementation requires that all “{0}” elements have the same value, but the
          * element found in “{1}” are {2}.
          */
         public static final short ConstantValueRequired_3 = 0;
+
+        /**
+         * Apache SIS implementation stipulate that following tiff tag, named: “{0}”, has not been
+         * define corectly. The tag is initialized to the following default value “{1}”.
+         */
+        public static final short DefaultAttribut_2 = 4;
+
+        /**
+         * Apache SIS implementation stipulate that following tag “{0}” , is ignored.
+         */
+        public static final short IgnoredTag_1 = 6;
+
+        /**
+         * Apache SIS implementation stipulate that the Key named  “{0}” , has not been define
+         * corectly. Expected value:  “{1}” , found:  “{2}” .
+         */
+        public static final short KeyValue_3 = 12;
+
+        /**
+         * Apache SIS implementation stipulate that length of tiff tag attribut value “{0}” mismatch
+         * from other following  “{1}” tiff tag(s) values, expected: “{2}” , found: “{3}”.
+         */
+        public static final short MismatchLength_4 = 5;
+
+        /**
+         * Apache SIS implementation can't read image from  “{0}” because tile and strip tags are
+         * missing.
+         */
+        public static final short MissingTileStrip_1 = 2;
+
+        /**
+         * Apache SIS implementation can't read image from  “{1}” because  “{0}” tag is missing.
+         */
+        public static final short MissingValueRequired_2 = 1;
+
+        /**
+         * Apache SIS implementation try to re-build missing “{0}” tiff tag, from other “{1}” tags
+         * values.
+         */
+        public static final short ReBuildAttribut_2 = 3;
+
+        /**
+         * Apache SIS implementation stipulate that Threshholding = 1(default value). No dithering or
+         * halftoning has been applied to the image data.
+         */
+        public static final short Threshholding1_0 = 9;
+
+        /**
+         * Apache SIS implementation stipulate that Threshholding = 2. An ordered dither or halftone
+         * technique has been applied to the image data.
+         */
+        public static final short Threshholding2_0 = 10;
+
+        /**
+         * Apache SIS implementation stipulate that Threshholding = 3. A randomized process such as
+         * error diffusion has been applied to the image data.
+         */
+        public static final short Threshholding3_0 = 11;
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties?rev=1768741&r1=1768740&r2=1768741&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties [ISO-8859-1] Tue Nov  8 17:19:54 2016
@@ -20,3 +20,15 @@
 # For resources shared by all modules in the Apache SIS project, see "org.apache.sis.util.resources" package.
 #
 ConstantValueRequired_3           = Apache SIS implementation requires that all \u201c{0}\u201d elements have the same value, but the element found in \u201c{1}\u201d are {2}.
+MissingValueRequired_2            = Apache SIS implementation can't read image from  \u201c{1}\u201d because  \u201c{0}\u201d tag is missing.
+MissingTileStrip_1                = Apache SIS implementation can't read image from  \u201c{0}\u201d because tile and strip tags are missing.
+ReBuildAttribut_2                 = Apache SIS implementation try to re-build missing \u201c{0}\u201d tiff tag, from other \u201c{1}\u201d tags values.
+DefaultAttribut_2                 = Apache SIS implementation stipulate that following tiff tag, named: \u201c{0}\u201d, has not been define corectly. The tag is initialized to the following default value \u201c{1}\u201d.
+MismatchLength_4                  = Apache SIS implementation stipulate that length of tiff tag attribut value \u201c{0}\u201d mismatch from other following  \u201c{1}\u201d tiff tag(s) values, expected: \u201c{2}\u201d , found: \u201c{3}\u201d.
+IgnoredTag_1                      = Apache SIS implementation stipulate that following tag \u201c{0}\u201d , is ignored.
+CellWidth_1                       = Apache SIS implementation stipulate that the width of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file is: CellWidth =  \u201c{0}\u201d .
+CellHeight_1                      = Apache SIS implementation stipulate that the height of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file is: CellHeight =  \u201c{0}\u201d .
+Threshholding2_0                  = Apache SIS implementation stipulate that Threshholding = 2. An ordered dither or halftone technique has been applied to the image data.
+Threshholding3_0                  = Apache SIS implementation stipulate that Threshholding = 3. A randomized process such as error diffusion has been applied to the image data.
+Threshholding1_0                  = Apache SIS implementation stipulate that Threshholding = 1(default value). No dithering or halftoning has been applied to the image data.
+KeyValue_3                        = Apache SIS implementation stipulate that the Key named  \u201c{0}\u201d , has not been define corectly. Expected value:  \u201c{1}\u201d , found:  \u201c{2}\u201d .
\ No newline at end of file

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties?rev=1768741&r1=1768740&r2=1768741&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties [ISO-8859-1] Tue Nov  8 17:19:54 2016
@@ -25,3 +25,15 @@
 #   U+00A0 NO-BREAK SPACE         before  :
 #
 ConstantValueRequired_3           = L\u2019impl\u00e9mentation de Apache SIS requiert que tous les \u00e9l\u00e9ments de \u00ab\u202f{0}\u202f\u00bb aient la m\u00eame valeur, mais les \u00e9l\u00e9ments trouv\u00e9s dans \u00ab\u202f{1}\u202f\u00bb sont {2}.
+MissingValueRequired_2            = L\u2019impl\u00e9mentation de Apache SIS ne peut pas lire l'image provenant de \u00ab\u202f{1}\u202f\u00bb car le tag \u00ab\u202f{0}\u202f\u00bb est manquant.
+MissingTileStrip_1                = L\u2019impl\u00e9mentation de Apache SIS ne peut pas lire l'image provenant de \u00ab\u202f{0}\u202f\u00bb car les tags definissant les tiles et strips sont manquants.
+ReBuildAttribut_2                 = L\u2019impl\u00e9mentation de Apache SIS essaye de reconstruire le tag tiff manquant nomm\u00e9 \u00ab\u202f{0}\u202f\u00bb \u00e0 partir des tags suivant \u00ab\u202f{1}\u202f\u00bb .
+DefaultAttribut_2                 = L\u2019impl\u00e9mentation de Apache SIS stipule que le tag tiff nomm\u00e9 \u00ab\u202f{0}\u202f\u00bb , n'est pas d\u00e9finit. Il est initialis\u00e9 \u00e0 la valeur par defaut suivante \u00ab\u202f{1}\u202f\u00bb .
+MismatchLength_4                  = L\u2019impl\u00e9mentation de Apache SIS stipule que la longueur de la valeur du tag tiff nomm\u00e9 \u00ab\u202f{0}\u202f\u00bb ne correspond pas par rapport aux valeurs des autres tags tiff suivant \u00ab\u202f{1}\u202f\u00bb , attendu : \u00ab\u202f{2}\u202f\u00bb , trouv\u00e9 : \u00ab\u202f{3}\u202f\u00bb .
+IgnoredTag_1                      = L\u2019impl\u00e9mentation de Apache SIS stipule que le tag suivant \u00ab\u202f{0}\u202f\u00bb , est ignor\u00e9.
+CellWidth_1                       = L\u2019impl\u00e9mentation de Apache SIS stipule que la largeur de la matrice de tramage afin de creer une donn\u00e9e demi-teinte ou tram\u00e9e en demi teinte sur 2 niveaux. CellWidth = \u00ab\u202f{0}\u202f\u00bb .
+CellHeight_1                      = L\u2019impl\u00e9mentation de Apache SIS stipule que la hauteur de la matrice de tramage afin de creer une donn\u00e9e demi-teinte ou tram\u00e9e en demi teinte sur 2 niveaux. CellHeight = \u00ab\u202f{0}\u202f\u00bb .
+Threshholding2_0                  = L\u2019impl\u00e9mentation de Apache SIS stipule que Threshholding = 2. Un tramage ordonn\u00e9 ou une technique en demi-teinte a \u00e9t\u00e9 appliqu\u00e9.(dither or halftone technique).
+Threshholding3_0                  = L\u2019impl\u00e9mentation de Apache SIS stipule que Threshholding = 3. Un processus al\u00e9atoire comme la diffusion d'erreur a \u00e9t\u00e9 appliqu\u00e9.
+Threshholding1_0                  = L\u2019impl\u00e9mentation de Apache SIS stipule que Threshholding = 1(default value). Aucun tramage, aucune technique en demi-teinte n'a \u00e9t\u00e9 appliqu\u00e9e. (Aucune dither or halftone technique).
+KeyValue_3                        = L\u2019impl\u00e9mentation de Apache SIS stipule que la cl\u00e9e nomm\u00e9e  \u00ab\u202f{0}\u202f\u00bb , n'a pas \u00e9t\u00e9 d\u00e9finie correctement. valeur attendue :  \u00ab\u202f{1}\u202f\u00bb , trouv\u00e9e : \u00ab\u202f{2}\u202f\u00bb .
\ No newline at end of file

Added: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java?rev=1768741&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java (added)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeys.java Tue Nov  8 17:19:54 2016
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2016 rmarechal.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.geotiff;
+
+import java.lang.reflect.Field;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+
+/**
+ * Reference all Geographic Keys needed to build {@link CoordinateReferenceSystem}
+ * and {@linkplain MathTransform GridToCrs} from tiff tags contents.
+ *
+ * @author Rémi Maréchal.
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+final class GeoKeys {
+
+    private GeoKeys() {
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // KEYS, values are taken from :
+    // http://www.remotesensing.org/geotiff/spec/geotiff6.html#6
+    ////////////////////////////////////////////////////////////////////////////
+    static class Configuration {
+
+        //6.2.1 GeoTIFF Configuration Keys
+        static final int GTModelTypeGeoKey           = 1024; /* Section 6.3.1.1 Codes */
+        static final int GTRasterTypeGeoKey          = 1025; /* Section 6.3.1.2 Codes */
+        static final int GTCitationGeoKey            = 1026; /* documentation */
+
+        /*
+         * 6.3.1.1 Model Type Codes
+         *
+         * Ranges:
+         *   0              = undefined
+         *   [   1,  32766] = GeoTIFF Reserved Codes
+         *   32767          = user-defined
+         *   [32768, 65535] = Private User Implementations
+         *
+         * Notes:
+         *   1. ModelTypeGeographic and ModelTypeProjected
+         *   correspond to the FGDC metadata Geographic and
+         *   Planar-Projected coordinate system types.
+         */
+        //GeoTIFF defined CS Model Type Codes:
+        static final int ModelTypeProjected   = 1;   /* Projection Coordinate System         */
+        static final int ModelTypeGeographic  = 2;   /* Geographic latitude-longitude System */
+        static final int ModelTypeGeocentric  = 3;   /* Geocentric (X,Y,Z) Coordinate System */
+        ////////////////////////////////////////////////////////////////////////////
+        // Codes
+        ////////////////////////////////////////////////////////////////////////////
+
+        static final short GTUserDefinedGeoKey         = 32767;
+        static final String GTUserDefinedGeoKey_String = "32767";
+
+        /**
+         * Return tag Name from {@link GeoTiffConstants} class.
+         *
+         * @param tag
+         * @return tag Name from {@link GeoTiffConstants} class.
+         */
+        static String getName(final int tag) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == tag) {
+                            return field.getName();
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return Integer.toHexString(tag);
+        }
+
+        static boolean contain(int key) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == key) {
+                            return true;
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return false;
+        }
+    }
+
+    static class Operation_Method {
+        /*
+         * 6.3.3.3 Coordinate Transformation Codes
+         * Ranges:
+         * 0 = undefined
+         * [    1, 16383] = GeoTIFF Coordinate Transformation codes
+         * [16384, 32766] = Reserved by GeoTIFF
+         * 32767          = user-defined
+         * [32768, 65535] = Private User Implementations
+         */
+        static final int CT_TransverseMercator =             1;
+        static final int CT_TransvMercator_Modified_Alaska = 2;
+        static final int CT_ObliqueMercator =                3;
+        static final int CT_ObliqueMercator_Laborde =        4;
+        static final int CT_ObliqueMercator_Rosenmund =      5;
+        static final int CT_ObliqueMercator_Spherical =      6;
+        static final int CT_Mercator =                       7;
+        static final int CT_LambertConfConic_2SP =           8;
+        static final int CT_LambertConfConic_1SP =           9;
+        static final int CT_LambertAzimEqualArea =           10;
+        static final int CT_AlbersEqualArea =                11;
+        static final int CT_AzimuthalEquidistant =           12;
+        static final int CT_EquidistantConic =               13;
+        static final int CT_Stereographic =                  14;
+        static final int CT_PolarStereographic =             15;
+        static final int CT_ObliqueStereographic =           16;
+        static final int CT_Equirectangular =                17;
+        static final int CT_CassiniSoldner =                 18;
+        static final int CT_Gnomonic =                       19;
+        static final int CT_MillerCylindrical =              20;
+        static final int CT_Orthographic =                   21;
+        static final int CT_Polyconic =                      22;
+        static final int CT_Robinson =                       23;
+        static final int CT_Sinusoidal =                     24;
+        static final int CT_VanDerGrinten =                  25;
+        static final int CT_NewZealandMapGrid =              26;
+        static final int CT_TransvMercator_SouthOriented=    27;
+        //Aliases:
+        static final int CT_AlaskaConformal =                CT_TransvMercator_Modified_Alaska;
+        static final int CT_TransvEquidistCylindrical =      CT_CassiniSoldner;
+        static final int CT_ObliqueMercator_Hotine =         CT_ObliqueMercator;
+        static final int CT_SwissObliqueCylindrical =        CT_ObliqueMercator_Rosenmund;
+        static final int CT_GaussBoaga =                     CT_TransverseMercator;
+        static final int CT_GaussKruger =                    CT_TransverseMercator;
+        static final int CT_LambertConfConic =               CT_LambertConfConic_2SP ;
+        static final int CT_LambertConfConic_Helmert =       CT_LambertConfConic_1SP;
+        static final int CT_SouthOrientedGaussConformal =    CT_TransvMercator_SouthOriented;
+
+        /**
+         * Return tag Name from {@link GeoTiffConstants} class.
+         *
+         * @param tag
+         * @return tag Name from {@link GeoTiffConstants} class.
+         */
+        static String getName(final int tag) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == tag) {
+                            return field.getName();
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return Integer.toHexString(tag);
+        }
+
+        static boolean contain(int key) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == key) {
+                            return true;
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return false;
+        }
+    }
+
+    static class Units {
+        /*
+         * 6.3.1.3 Linear Units Codes
+         *
+         *  There are several different kinds of units that may be used in geographically related raster data: linear units, angular units, units of time (e.g. for radar-return), CCD-voltages, etc. For this reason there will be a single, unique range for each kind of unit, broken down into the following currently defined ranges:
+         *  Ranges:
+         *     0             = undefined
+         *     [   1,  2000] = Obsolete GeoTIFF codes
+         *     [2001,  8999] = Reserved by GeoTIFF
+         *     [9000,  9099] = EPSG Linear Units.
+         *     [9100,  9199] = EPSG Angular Units.
+         *     32767         = user-defined unit
+         *     [32768, 65535]= Private User Implementations
+         *  Linear Unit Values (See the ESPG/POSC tables for definition):
+         */
+        static final int Linear_Meter                       = 9001;
+        static final int Linear_Foot                        = 9002;
+        static final int Linear_Foot_US_Survey              = 9003;
+        static final int Linear_Foot_Modified_American      = 9004;
+        static final int Linear_Foot_Clarke                 = 9005;
+        static final int Linear_Foot_Indian                 = 9006;
+        static final int Linear_Link                        = 9007;
+        static final int Linear_Link_Benoit                 = 9008;
+        static final int Linear_Link_Sears                  = 9009;
+        static final int Linear_Chain_Benoit                = 9010;
+        static final int Linear_Chain_Sears                 = 9011;
+        static final int Linear_Yard_Sears                  = 9012;
+        static final int Linear_Yard_Indian                 = 9013;
+        static final int Linear_Fathom                      = 9014;
+        static final int Linear_Mile_International_Nautical = 9015;
+
+        /*
+         * 6.3.1.4 Angular Units Codes
+         * These codes shall be used for any key that requires specification of an angular unit of measurement.
+         */
+        static final int Angular_Radian         = 9101;
+        static final int Angular_Degree         = 9102;
+        static final int Angular_Arc_Minute     = 9103;
+        static final int Angular_Arc_Second     = 9104;
+        static final int Angular_Grad           = 9105;
+        static final int Angular_Gon            = 9106;
+        static final int Angular_DMS            = 9107;
+        static final int Angular_DMS_Hemisphere = 9108;
+
+        /**
+         * Return tag Name from {@link GeoTiffConstants} class.
+         *
+         * @param tag
+         * @return tag Name from {@link GeoTiffConstants} class.
+         */
+        static String getName(final int tag) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == tag) {
+                            return field.getName();
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return Integer.toHexString(tag);
+        }
+
+        static boolean contain(int key) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == key) {
+                            return true;
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return false;
+        }
+    }
+
+
+    static class CRS {
+
+        //6.2.2 Geographic CS Parameter Keys
+        static final int GeographicTypeGeoKey        = 2048; /* Section 6.3.2.1 Codes */
+        static final int GeogCitationGeoKey          = 2049; /* documentation */
+        static final int GeogGeodeticDatumGeoKey     = 2050; /* Section 6.3.2.2 Codes */
+        static final int GeogPrimeMeridianGeoKey     = 2051; /* Section 6.3.2.4 codes */
+        static final int GeogLinearUnitsGeoKey       = 2052; /* Section 6.3.1.3 Codes */
+        static final int GeogLinearUnitSizeGeoKey    = 2053; /* meters */
+        static final int GeogAngularUnitsGeoKey      = 2054; /* Section 6.3.1.4 Codes */
+        static final int GeogAngularUnitSizeGeoKey   = 2055; /* radians */
+        static final int GeogEllipsoidGeoKey         = 2056; /* Section 6.3.2.3 Codes */
+        static final int GeogSemiMajorAxisGeoKey     = 2057; /* GeogLinearUnits */
+        static final int GeogSemiMinorAxisGeoKey     = 2058; /* GeogLinearUnits */
+        static final int GeogInvFlatteningGeoKey     = 2059; /* ratio */
+        static final int GeogAzimuthUnitsGeoKey      = 2060; /* Section 6.3.1.4 Codes */
+        static final int GeogPrimeMeridianLongGeoKey = 2061; /* GeogAngularUnit */
+
+        //6.2.3 Projected CS Parameter Keys
+        static final int ProjectedCSTypeGeoKey          = 3072;  /* Section 6.3.3.1 codes */
+        static final int PCSCitationGeoKey              = 3073;  /* documentation */
+        static final int ProjectionGeoKey               = 3074;  /* Section 6.3.3.2 codes */
+        static final int ProjCoordTransGeoKey           = 3075;  /* Section 6.3.3.3 codes */
+        static final int ProjLinearUnitsGeoKey          = 3076;  /* Section 6.3.1.3 codes */
+        static final int ProjLinearUnitSizeGeoKey       = 3077;  /* meters */
+        static final int ProjStdParallel1GeoKey         = 3078;  /* GeogAngularUnit */
+        static final int ProjStdParallel2GeoKey         = 3079;  /* GeogAngularUnit */
+        static final int ProjNatOriginLongGeoKey        = 3080;  /* GeogAngularUnit */
+        static final int ProjNatOriginLatGeoKey         = 3081;  /* GeogAngularUnit */
+        static final int ProjFalseEastingGeoKey         = 3082;  /* ProjLinearUnits */
+        static final int ProjFalseNorthingGeoKey        = 3083;  /* ProjLinearUnits */
+        static final int ProjFalseOriginLongGeoKey      = 3084;  /* GeogAngularUnit */
+        static final int ProjFalseOriginLatGeoKey       = 3085;  /* GeogAngularUnit */
+        static final int ProjFalseOriginEastingGeoKey   = 3086;  /* ProjLinearUnits */
+        static final int ProjFalseOriginNorthingGeoKey  = 3087;  /* ProjLinearUnits */
+        static final int ProjCenterLongGeoKey           = 3088;  /* GeogAngularUnit */
+        static final int ProjCenterLatGeoKey            = 3089;  /* GeogAngularUnit */
+        static final int ProjCenterEastingGeoKey        = 3090;  /* ProjLinearUnits */
+        static final int ProjCenterNorthingGeoKey       = 3091;  /* ProjLinearUnits */
+        static final int ProjScaleAtNatOriginGeoKey     = 3092;  /* ratio */
+        static final int ProjScaleAtCenterGeoKey        = 3093;  /* ratio */
+        static final int ProjAzimuthAngleGeoKey         = 3094;  /* GeogAzimuthUnit */
+        static final int ProjStraightVertPoleLongGeoKey = 3095;  /* GeogAngularUnit */
+        //Aliases:
+        static final int ProjStdParallelGeoKey       = ProjStdParallel1GeoKey;
+        static final int ProjOriginLongGeoKey        = ProjNatOriginLongGeoKey;
+        static final int ProjOriginLatGeoKey         = ProjNatOriginLatGeoKey;
+        static final int ProjScaleAtOriginGeoKey     = ProjScaleAtNatOriginGeoKey;
+
+        //6.2.4 Vertical CS Keys
+        static final int VerticalCSTypeGeoKey    = 4096;   /* Section 6.3.4.1 codes */
+        static final int VerticalCitationGeoKey  = 4097;   /* documentation */
+        static final int VerticalDatumGeoKey     = 4098;   /* Section 6.3.4.2 codes */
+        static final int VerticalUnitsGeoKey     = 4099;   /* Section 6.3.1.3 codes */
+
+        /**
+         * Return tag Name from {@link GeoTiffConstants} class.
+         *
+         * @param tag
+         * @return tag Name from {@link GeoTiffConstants} class.
+         */
+        static String getName(final int tag) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == tag) {
+                            return field.getName();
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return Integer.toHexString(tag);
+        }
+
+        static boolean contain(int key) {
+            try {
+                for (final Field field : CRS.class.getDeclaredFields()) {
+                    if (field.getType() == Integer.TYPE) {
+                        if (field.getInt(null) == key) {
+                            return true;
+                        }
+                    }
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw new AssertionError(ex); // Should never happen.
+            }
+            return false;
+        }
+    }
+
+    static class GridToCrs {
+
+    }
+
+}

Added: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeysRange.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeysRange.java?rev=1768741&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeysRange.java (added)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoKeysRange.java Tue Nov  8 17:19:54 2016
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2016 rmarechal.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.geotiff;
+
+/**
+ * Enum which represente range value validity for EPSG codes,
+ * of Geographical key from geotiff specification.
+ *
+ * @author Remi Maréchal(Geomatys).
+ */
+enum GeoKeysRange {
+
+    /**
+     * Operation method means (Coordinate Transformation Codes in geotiff).
+     * Example: CT_TransverseMercator = 1, CT_Polyconic = 22 etc ...
+     *
+     * Ranges:
+     * 0 = undefined
+     * [    1, 16383] = GeoTIFF Coordinate Transformation codes
+     * [16384, 32766] = Reserved by GeoTIFF
+     * 32767          = user-defined
+     * [32768, 65535] = Private User Implementations
+     *
+     * note : from documentation, given range is [1; 16383]
+     * but value are within into [1, 27]
+     * OperationMethod range is initialized by [1; 27] to avoid overlaps with ProjectedCRS range [10000; 32760]
+     */
+    OPERATION_METHOD(1, 27),
+
+    /**
+     * Ranges:
+
+     * 0 = undefined
+     * [    1,  1000] = Obsolete EPSG/POSC Geographic Codes
+     * [ 1001,  3999] = Reserved by GeoTIFF
+     * [ 4000, 4199]  = EPSG GCS Based on Ellipsoid only
+     * [ 4200, 4999]  = EPSG GCS Based on EPSG Datum
+     * [ 5000, 32766] = Reserved by GeoTIFF
+     * 32767          = user-defined GCS
+     * [32768, 65535] = Private User Implementations
+     */
+    GEOGRAPHIC_CRS(4200, 4999),
+
+    /**
+     * Projected CRS means (Projected CS Type Codes in geotiff).
+     * Example: PCS_WGS84_UTM_zone_7S = 32707, PCS_NAD27_UTM_zone_21N = 26721 etc ...
+     *
+     * Ranges:
+     * [    1,   1000]  = Obsolete EPSG/POSC Projection System Codes
+     * [20000,  32760]  = EPSG Projection System codes
+     * 32767            = user-defined
+     * [32768,  65535]  = Private User Implementations
+     *
+     * and also (Projection Codes in geotiff)
+     * Note: Projections do not include GCS or PCS definitions. If possible, use the PCS code for standard projected coordinate systems, and use this code only if nonstandard datums are required.
+     * Ranges:
+     * 0 = undefined
+     * [    1,  9999] = Obsolete EPSG/POSC Projection codes
+     * [10000, 19999] = EPSG/POSC Projection codes
+     * 32767          = user-defined
+     * [32768, 65535] = Private User Implementations
+     */
+    PROJECTED_CRS(10000, 32760),
+
+    /**
+     * Prime Meridian Codes.
+     *
+     * Ranges:
+     * 0 = undefined
+     * [    1,   100] = Obsolete EPSG/POSC Prime Meridian codes
+     * [  101,  7999] = Reserved by GeoTIFF
+     * [ 8000,  8999] = EPSG Prime Meridian Codes
+     * [ 9000, 32766] = Reserved by GeoTIFF
+     * 32767          = user-defined
+     * [32768, 65535] = Private User Implementations
+     */
+    PRIME_MERIDIAN(8000, 8999),
+
+    /**
+     * Geodetic Datum Codes.
+     *
+     * Ranges:
+     * 0 = undefined
+     * [    1,  1000] = Obsolete EPSG/POSC Datum Codes
+     * [ 1001,  5999] = Reserved by GeoTIFF
+     * [ 6000, 6199]  = EPSG Datum Based on Ellipsoid only
+     * [ 6200, 6999]  = EPSG Datum Based on EPSG Datum
+     * [ 6322, 6327]  = WGS Datum
+     * [ 6900, 6999]  = Archaic Datum
+     * [ 7000, 32766] = Reserved by GeoTIFF
+     * 32767          = user-defined GCS
+     * [32768, 65535] = Private User Implementations
+     *
+     */
+    DATUM(6000, 6999),
+
+    /**
+     * Ellipsoid Codes
+     *
+     * Ranges:
+     * 0 = undefined
+     * [    1, 1000]  = Obsolete EPSG/POSC Ellipsoid codes
+     * [1001,  6999]  = Reserved by GeoTIFF
+     * [7000,  7999]  = EPSG Ellipsoid codes
+     * [8000, 32766]  = Reserved by GeoTIFF
+     * 32767          = user-defined
+     * [32768, 65535] = Private User Implementations
+     *
+     */
+    ELLIPSOID(7000, 7999),
+
+    /**
+     * Units.
+     * Linear  [9000 9099]
+     * Angular [9100, 9199]
+     *
+     * Ranges:
+     * 0             = undefined
+     * [   1,  2000] = Obsolete GeoTIFF codes
+     * [2001,  8999] = Reserved by GeoTIFF
+     * [9000,  9099] = EPSG Linear Units.
+     * [9100,  9199] = EPSG Angular Units.
+     * 32767         = user-defined unit
+     * [32768, 65535]= Private User Implementations
+     */
+    UNITS(9000, 9199);//-- maybe separate in two different enum.
+
+//------------------------------------------------------------------------------
+    /**
+     * Returns the {@link GeoKeysRange} enum which contain the given key.
+     *
+     * @param key
+     * @return
+     */
+    static GeoKeysRange getRange(final int key) {
+        for (GeoKeysRange value : values()) {
+            if (value.contain(key)) return value;
+        }
+        return null;//-- TODO exception unexpected key
+    }
+
+//------------------------------------------------------------------------------
+    /**
+     * Minimum inclusive range value and
+     * Maximum exclusive range value.
+     */
+    private final int minRange, maxRange;
+
+    /**
+     * Create a Range enum with range borders.
+     *
+     * @param minimumRange <strong>inclusive</strong> minimum range value.
+     * @param maximumRange <strong>inclusive</strong> maximum range value.
+     */
+    private GeoKeysRange(final int minimumRange, final int maximumRange) {
+        minRange = minimumRange;
+        maxRange = maximumRange;
+    }
+
+    /**
+     * Returns {@code true} if the key is within this range enum, else {@code false}.
+     *
+     * @param key
+     * @return true if key is within else false.
+     */
+    private boolean contain(final int key) {
+        return key >= minRange && key <= maxRange;
+    }
+}

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java?rev=1768741&r1=1768740&r2=1768741&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] Tue Nov  8 17:19:54 2016
@@ -19,6 +19,7 @@ package org.apache.sis.storage.geotiff;
 import java.util.Locale;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.util.logging.LogRecord;
 import org.opengis.metadata.Metadata;
 import org.apache.sis.setup.OptionKey;
 import org.apache.sis.storage.DataStore;
@@ -26,9 +27,11 @@ import org.apache.sis.storage.StorageCon
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.internal.storage.ChannelDataInput;
+import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Classes;
+import org.opengis.util.FactoryException;
 
 
 /**
@@ -69,7 +72,8 @@ public class GeoTiffStore extends DataSt
      */
     public GeoTiffStore(final StorageConnector storage) throws DataStoreException {
         ArgumentChecks.ensureNonNull("storage", storage);
-        encoding = storage.getOption(OptionKey.ENCODING);
+        final Charset option         = storage.getOption(OptionKey.ENCODING);
+        encoding                     = (option != null) ? option : Charset.defaultCharset(); //-- TODO : ce n'est pas la bonne solution (maybe)
         final ChannelDataInput input = storage.getStorageAs(ChannelDataInput.class);
         if (input == null) {
             throw new DataStoreException(Errors.format(Errors.Keys.IllegalInputTypeForReader_2,
@@ -100,11 +104,16 @@ public class GeoTiffStore extends DataSt
             while ((dir = reader.getImageFileDirectory(n++)) != null) {
                 dir.completeMetadata(reader.metadata, locale);
             }
+
+            //-- add geotiff CRS
+            reader.metadata.add(reader.crsBuilder.build());
             metadata = reader.metadata.build(true);
         } catch (IOException e) {
             throw new DataStoreException(reader.errors().getString(Errors.Keys.CanNotRead_1, reader.input.filename), e);
         } catch (ArithmeticException e) {
             throw new DataStoreContentException(reader.canNotDecode(), e);
+        } catch (FactoryException e) {
+            throw new DataStoreContentException(e);
         }
         return metadata;
     }
@@ -135,4 +144,20 @@ public class GeoTiffStore extends DataSt
     final void warning(final String message, final Exception exception) {
         listeners.warning(message, exception);
     }
+
+    /**
+     * Reports a warning represented by the given {@link LogRecord}.
+     *
+     * <p>Moreover, {@linkplain LogRecord#setSourceClassName(java.lang.String) Class name}
+     * and {@linkplain LogRecord#setSourceMethodName(java.lang.String) method name}
+     * are added into the given LogRecord.</p>
+     *
+     * @param logRecord the warning as a logrecord.
+     */
+    final void warning(final LogRecord logRecord) {
+        ArgumentChecks.ensureNonNull("logRecord", logRecord);
+        logRecord.setSourceClassName(GeoTiffStore.class.getName());
+        logRecord.setSourceMethodName("read");
+        listeners.warning(logRecord);
+    }
 }

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java?rev=1768741&r1=1768740&r2=1768741&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] Tue Nov  8 17:19:54 2016
@@ -18,13 +18,19 @@ package org.apache.sis.storage.geotiff;
 
 import java.util.Locale;
 import java.io.IOException;
+import java.nio.charset.Charset;
 import java.text.ParseException;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import javax.measure.Unit;
 import org.opengis.metadata.citation.DateType;
 import org.apache.sis.internal.geotiff.Resources;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.internal.storage.MetadataBuilder;
 import org.apache.sis.math.Vector;
+import org.apache.sis.measure.Units;
 
 
 /**
@@ -41,6 +47,11 @@ import org.apache.sis.math.Vector;
  * @see <a href="http://www.awaresystems.be/imaging/tiff/tifftags.html">TIFF Tag Reference</a>
  */
 final class ImageFileDirectory {
+
+    /**
+     * Default {@link Unit} adapted to ISO 19115 metadata.
+     */
+    private static final Unit METER = Units.METRE;
     /**
      * {@code true} if this {@code ImageFileDirectory} has not yet read all deferred entries.
      * When this flag is {@code true}, the {@code ImageFileDirectory} is not yet ready for use.
@@ -57,13 +68,114 @@ final class ImageFileDirectory {
     private long imageWidth = -1, imageHeight = -1;
 
     /**
+     * The width of each tile, or -1 if the information has not be found.
+     * This is the number of columns in each tile.
+     * Tiles should be small enough for fitting in memory.
+     *
+     * Assuming integer arithmetic, three computed values that are useful in the following field descriptions are:
+     * {@preformat math
+     * TilesAcross = (ImageWidth + TileWidth - 1) / TileWidth
+     * TilesDown = (ImageLength + TileLength - 1) / TileLength
+     * TilesPerImage = TilesAcross * TilesDown
+     * }
+     * These computed values are not TIFF fields; they are simply values determined by
+     * the ImageWidth, TileWidth, ImageLength, and TileLength fields.
+     * TileWidth must be a multiple of 16. This restriction improves performance
+     * in some graphics environments and enhances compatibility with compression schemes such as JPEG.
+     * Tiles need not be square.
+     * Note that ImageWidth can be less than TileWidth, although this means that the tiles
+     * are too large or that you are using tiling on really small images, neither of which is recommended.
+     * The same observation holds for ImageLength and TileLength.
+     */
+    private long tileWidth = -1;
+
+    /**
      * The size of each tile, or -1 if the information has not be found.
+     * This is the number of rows in each tile.
      * Tiles should be small enough for fitting in memory.
      *
+     * Assuming integer arithmetic, three computed values that are useful in the following field descriptions are:
+     * {@preformat math
+     *   TilesAcross = (ImageWidth + TileWidth - 1) / TileWidth
+     *     TilesDown = (ImageLength + TileLength - 1) / TileLength
+     * TilesPerImage = TilesAcross * TilesDown
+     * }
+     * These computed values are not TIFF fields; they are simply values determined by
+     * the ImageWidth, TileWidth, ImageLength, and TileLength fields.
+     * TileLength must be a multiple of 16. This restriction improves performance
+     * in some graphics environments and enhances compatibility with compression schemes such as JPEG.
+     * Tiles need not be square
+     *
      * <p><b>Note:</b>
      * the {@link #tileHeight} attribute is named {@code TileLength} in TIFF specification.</p>
      */
-    private int tileWidth = -1, tileHeight = -1;
+    private long tileHeight = -1;
+
+    /**
+     * For each tile, the byte offset of that tile, as compressed and stored on disk.
+     *
+     * The offset is specified with respect to the beginning of the TIFF file.
+     *
+     * <p><b>Note</b> that this implies that each tile has a location independent of the locations of other tiles.</p>
+     *
+     * Offsets are ordered left-to-right and top-to-bottom. For PlanarConfiguration = 2,
+     * the offsets for the first component plane are stored first,
+     * followed by all the offsets for the second component plane, and so on.
+     */
+    private Vector tileOffsets;
+
+    /**
+     * For each tile, the number of (compressed) bytes in that tile.
+     * See {@link #tileOffsets} for a description of how the byte counts are ordered.
+     */
+    private Vector tileByteCounts;
+
+    /**
+     * The number of rows per strip.
+     * TIFF image data can be organized into strips for faster random access and efficient I/O buffering.
+     * The {@code rowsPerStrip} and {@link #imageHeight} fields together tell us the number of strips in the entire image.
+     * The equation is:
+     *
+     * {@preformat math
+     *     StripsPerImage = floor ((ImageLength + RowsPerStrip - 1) / RowsPerStrip)
+     * }
+     *
+     * {@code StripsPerImage} is not a field. It is merely a value that a TIFF reader will want to compute
+     * because it specifies the number of {@code StripOffsets} and {@code StripByteCounts} for the image.
+     *
+     * <p>This field should be interpreted as an unsigned value.
+     * The default is 2^32 - 1, which is effectively infinity (i.e. the entire image is one strip).</p>
+     */
+    private long rowsPerStrip = 0xFFFFFFFF;
+
+    /**
+     * For each strip, the number of bytes in the strip after compression.
+     * <p>N = StripsPerImage for PlanarConfiguration equal to 1.
+     * N = SamplesPerPixel * StripsPerImage for PlanarConfiguration equal to 2.</p>
+     */
+    private Vector stripByteCounts;
+
+    /**
+     *  For each strip, the byte offset of that strip.
+     *
+     * The offset is specified with respect to the beginning of the TIFF file.
+     *
+     * Note that this implies that each strip has a location independent of the locations of other strips.
+     * This feature may be useful for editing applications.
+     * This required field is the only way for a reader to find the image data.
+     * (Unless TileOffsets is used; see {@link #tileOffsets}.
+     *
+     * Note that either SHORT or LONG values may be used to specify the strip offsets.
+     * SHORT values may be used for small TIFF files. It should be noted, however,
+     * that earlier TIFF specifications required LONG strip offsets and that some
+     * software may not accept SHORT values.
+     *
+     * For maximum compatibility with operating systems such as MS-DOS and Windows,
+     * the StripOffsets array should be less than or equal to 64K bytes in length,
+     * and the strips themselves, in both compressed and uncompressed forms,
+     * should not be larger than 64K bytes.
+     */
+    private Vector stripOffsets;
 
     /**
      * The number of components per pixel.
@@ -71,7 +183,7 @@ final class ImageFileDirectory {
      * and 3 for RGB images. If this value is higher, then the {@code ExtraSamples} TIFF tag should
      * give an indication of the meaning of the additional channels.
      */
-    private short samplesPerPixel = 1;
+    private short samplesPerPixel = 0;
 
     /**
      * Number of bits per component.
@@ -79,7 +191,7 @@ final class ImageFileDirectory {
      * For example, RGB color data could use a different number of bits per component for each of the three color planes.
      * However, current Apache SIS implementation requires that all components have the same {@code BitsPerSample} value.
      */
-    private short bitsPerSample = 1;
+    private short bitsPerSample = 0;
 
     /**
      * If {@code true}, the components are stored in separate “component planes”.
@@ -95,22 +207,107 @@ final class ImageFileDirectory {
     private Compression compression;
 
     /**
-     * The number of rows per strip.
-     * TIFF image data can be organized into strips for faster random access and efficient I/O buffering.
-     * The {@code rowsPerStrip} and {@link #imageHeight} fields together tell us the number of strips in the entire image.
-     * The equation is:
+     * The color space of the image data.
+     * 0 = WhiteIsZero. For bilevel and grayscale images: 0 is imaged as white.
+     * 1 = BlackIsZero. For bilevel and grayscale images: 0 is imaged as black.
+     * 2 = RGB. RGB value of (0,0,0) represents black, and (255,255,255) represents white.
+     * 3 = Palette color. The value of the component is used as an index into the RGB valuesthe ColorMap.
+     * 4 = Transparency Mask the defines an irregularly shaped region of another image in the same TIFF file.
+     */
+    private short photometricInterpretation;
+
+    /**
+     * The logical order of bits within a byte.
      *
-     * {@preformat math
-     *     StripsPerImage = floor ((ImageLength + RowsPerStrip - 1) / RowsPerStrip)
+     * The specification defines these values:
+     *
+     * 1 = pixels with lower column values are stored in the higher-order bits of the byte.
+     * 2 = pixels with lower column values are stored in the lower-order bits of the byte.
+     *
+     * The specification goes on to warn that FillOrder=2 should not be used in some cases to avoid ambigouty,
+     * and that support for FillOrder=2.
+     *
+     * In practice, the use of FillOrder=2 is very uncommon, and is not recommended.
+     */
+    private short fillOrder = 1;
+
+    /**
+     * Specifies that each pixel has N extra components whose interpretation is defined by one of the values listed below.
+     * When this field is used, the SamplesPerPixel field has a value greater than the PhotometricInterpretation field suggests.
+     * For example, full-color RGB data normally has SamplesPerPixel=3.
+     * If SamplesPerPixel is greater than 3, then the ExtraSamples field describes the meaning of the extra samples.
+     * If SamplesPerPixel is, say, 5 then ExtraSamples will contain 2 values, one for each extra sample.
+     * ExtraSamples is typically used to include non-color information, such as opacity, in an image.
+     *
+     * The possible values for each item in the field's value are:
+     * 0 = Unspecified data
+     * 1 = Associated alpha data (with pre-multiplied color)
+     * 2 = Unassociated alpha data
+
+     * The difference between associated alpha and unassociated alpha is not just a matter of taste or a matter of maths.
+
+     * Associated alpha is generally interpreted as true transparancy information.
+     * Indeed, the original color values are lost in the case of complete transparency,
+     * and rounded in the case of partial transparency. Also, associated alpha is only
+     * logically possible as the single extra channel.
+
+     * Unassociated alpha channels, on the other hand, can be used to encode a number of independent masks, for example.
+     * The original color data is preserved without rounding. Any number of unassociated alpha channels can accompany an image.
+
+     * If an extra sample is used to encode information that has little or nothing to do with alpha,
+     * ExtraSample=0 (EXTRASAMPLE_UNSPECIFIED) is recommended.
+
+     * <strong>Note also that extra components that are present must be stored as the last components in each pixel.
+     * For example, if SamplesPerPixel is 4 and there is 1 extra component,
+     * then it is located in the last component location (SamplesPerPixel-1) in each pixel.</strong>
+
+     * This field must be present if there are extra samples.
+     */
+    private Vector extraSamples;
+
+    /**
+     * A color map for palette color images.
+
+     * This field defines a Red-Green-Blue color map (often called a lookup table) for palette-color images.
+     * In a palette-color image, a pixel value is used to index into an RGB lookup table.
+     * For example, a palette-color pixel having a value of 0 would be displayed according to the 0th Red, Green, Blue triplet.
+
+     * In a TIFF ColorMap, all the Red values come first, followed by the Green values,
+     * then the Blue values. The number of values for each color is 2**BitsPerSample.
+     * Therefore, the ColorMap field for an 8-bit palette-color image would have 3 * 256 values.
+     * The width of each value is 16 bits, as implied by the type of SHORT. 0 represents the minimum intensity,
+     * and 65535 represents the maximum intensity. Black is represented by 0,0,0, and white by 65535, 65535, 65535.
+
+     * ColorMap must be included in all palette-color images.
+
+     * In Specification Supplement 1, support was added for ColorMaps containing other then RGB values.
+     * This scheme includes the Indexed tag, with value 1, and a PhotometricInterpretation different
+     * from PaletteColor then next denotes the colorspace of the ColorMap entries.
+     */
+    private Vector colorMap;
+
+    /**
+     * The number of pixels per ResolutionUnit in the ImageWidth and the ImageHeight direction.
+     *
+     * In SIS use case, ISO 19115 Metadatas allow only one kind of resolution exprimate in meters.
+     * This attribut is the maximum value from tiff XRESOLUTION and YRESOLUTION.
+     * {@preformat
+     * tiffResolution = Math.max(XRESOLUTION, YRESOLUTION);
      * }
+     */
+    private double tiffResolution = -1;
+
+    /**
+     * The unit of measurement for {@linkplain #tiffResolution XResolution and YResolution}.
+     * Default value assume 2 (Inch).
      *
-     * {@code StripsPerImage} is not a field. It is merely a value that a TIFF reader will want to compute
-     * because it specifies the number of {@code StripOffsets} and {@code StripByteCounts} for the image.
+     * The specification defines these values:
      *
-     * <p>This field should be interpreted as an unsigned value.
-     * The default is 2^32 - 1, which is effectively infinity (i.e. the entire image is one strip).</p>
+     * 1 = No absolute unit of measurement. Used for images that may have a non-square aspect ratio, but no meaningful absolute dimensions.
+     * 2 = Inch.
+     * 3 = Centimeter.
      */
-    private int rowsPerStrip = 0xFFFFFFFF;
+    private Unit resolutionUnit = Units.INCH;
 
     /**
      * Creates a new image file directory.
@@ -119,6 +316,38 @@ final class ImageFileDirectory {
     }
 
     /**
+     * Reports a warning represented by the given message and exception.
+     * At least one of message and exception shall be non-null.
+     *
+     * @param reader reader which manage exception and message.
+     * @param message - the message to log, or null if none.
+     * @param exception - the exception to log, or null if none.
+     */
+    private void warning(final Reader reader, final Level level, final short key, final Object ...message) {
+        final LogRecord r = reader.resources().getLogRecord(level, key, message);
+        reader.owner.warning(r);
+    }
+
+    /**
+     * Returns {@code true} if this image contain some internaly TIFF TAGS adapted for tiled reading, else return {@code false}.
+     *
+     * @return {@code true} for tiled tags attributs existance, else return {@code false}.
+     */
+    private boolean isTiled() {
+        return (tileWidth != -1        || tileHeight != -1
+             || tileByteCounts != null || tileOffsets != null);
+    }
+
+    /**
+     * Returns {@code true} if this image contain some internaly TIFF TAGS adapted for strip reading, else return {@code false}.
+     *
+     * @return {@code true} for strip tags attributs existance, else return {@code false}.
+     */
+    private boolean isStripped() {
+        return (stripByteCounts !=  null || stripOffsets != null);
+    }
+
+    /**
      * Adds the value read from the current position in the given stream
      * for the entry identified by the given GeoTIFF tag.
      *
@@ -174,28 +403,79 @@ final class ImageFileDirectory {
                 imageHeight = type.readUnsignedLong(reader.input, count);
                 break;
             }
+
+            ////////////////////////////////////////////////////////////////////
+            ////                                                            ////
+            ////            Internaly stored into strips hierarchy          ////
+            ////                                                            ////
+            ////////////////////////////////////////////////////////////////////
             /*
              * The number of rows per strip. RowsPerStrip and ImageLength together tell us the number of strips
              * in the entire image: StripsPerImage = floor((ImageLength + RowsPerStrip - 1) / RowsPerStrip).
              */
             case Tags.RowsPerStrip: {
-                // TODO
+                rowsPerStrip = type.readUnsignedLong(reader.input, count);
                 break;
             }
             /*
              * For each strip, the number of bytes in the strip after compression.
              */
             case Tags.StripByteCounts: {
-                // TODO
+                stripByteCounts = type.readVector(reader.input, count);
                 break;
             }
             /*
              * For each strip, the byte offset of that strip relative to the beginning of the TIFF file.
              */
             case Tags.StripOffsets: {
-                // TODO
+                stripOffsets = type.readVector(reader.input, count);
+                break;
+            }
+
+            ////////////////////////////////////////////////////////////////////
+            ////                                                            ////
+            ////            Internaly stored into Tiles hierarchy           ////
+            ////                                                            ////
+            ////////////////////////////////////////////////////////////////////
+
+            /*
+             * The tile width in pixels. This is the number of columns in each tile.
+             */
+            case Tags.TileWidth: {
+                tileWidth = type.readUnsignedLong(reader.input, count);
+                break;
+            }
+
+            /*
+             * The tile length (height) in pixels. This is the number of rows in each tile.
+             */
+            case Tags.TileLength: {
+                tileHeight = type.readUnsignedLong(reader.input, count);
                 break;
             }
+
+            /*
+             * The tile length (height) in pixels. This is the number of rows in each tile.
+             */
+            case Tags.TileOffsets: {
+                tileOffsets = type.readVector(reader.input, count);
+                break;
+            }
+
+            /*
+             * The tile width in pixels. This is the number of columns in each tile.
+             */
+            case Tags.TileByteCounts: {
+                tileByteCounts = type.readVector(reader.input, count);
+                break;
+            }
+
+            ////////////////////////////////////////////////////////////////////
+            ////                                                            ////
+            ////                  Samples encoding made                     ////
+            ////                                                            ////
+            ////////////////////////////////////////////////////////////////////
+
             /*
              * Compression scheme used on the image data.
              */
@@ -212,7 +492,7 @@ final class ImageFileDirectory {
              * bytes before decompression.
              */
             case Tags.FillOrder: {
-                // TODO
+                fillOrder = type.readShort(reader.input, count);
                 break;
             }
             /*
@@ -252,7 +532,7 @@ final class ImageFileDirectory {
              * describes the meaning of the extra samples. It may be an alpha channel, but not necessarily.
              */
             case Tags.ExtraSamples: {
-                // TODO
+                extraSamples = type.readVector(reader.input, count);
                 break;
             }
 
@@ -272,7 +552,7 @@ final class ImageFileDirectory {
              * 4 = Transparency Mask the defines an irregularly shaped region of another image in the same TIFF file.
              */
             case Tags.PhotometricInterpretation: {
-                // TODO
+                photometricInterpretation = type.readShort(reader.input, count);
                 break;
             }
             /*
@@ -284,7 +564,7 @@ final class ImageFileDirectory {
              * then the color space may be different than RGB.
              */
             case Tags.ColorMap: {
-                // TODO
+                colorMap = type.readVector(reader.input, count);
                 break;
             }
             /*
@@ -336,6 +616,41 @@ final class ImageFileDirectory {
 
             ////////////////////////////////////////////////////////////////////////////////////////////////
             ////                                                                                        ////
+            ////    Information related to the Coordinate Reference System referencement.        ////
+            ////                                                                                        ////
+            ////////////////////////////////////////////////////////////////////////////////////////////////
+
+           /*
+            * References the needed "GeoKeys" to build CRS.
+            * An array of unsigned SHORT values, which are primarily grouped into blocks of 4.
+            * The first 4 values are special, and contain GeoKey directory header information.
+            */
+            case Tags.GeoKeyDirectoryTag : {
+                reader.crsBuilder.setGeoKeyDirectoryTag(type.readVector(reader.input, count));
+                break;
+            }
+
+           /*
+            * This tag is used to store all of the DOUBLE valued GeoKeys, referenced by the GeoKeyDirectoryTag.
+            */
+            case Tags.GeoDoubleParamsTag : {
+                reader.crsBuilder.setGeoDoubleParamsTag(type.readVector(reader.input, count));
+                break;
+            }
+
+           /*
+            * This tag is used to store all of the ASCII valued GeoKeys, referenced by the GeoKeyDirectoryTag.
+            */
+            case Tags.GeoAsciiParamsTag : {
+                final String[] readString = type.readString(reader.input, count, reader.owner.encoding);
+                if (readString != null && readString.length > 0)
+                    reader.crsBuilder.setGeoAsciiParamsTag(readString[0]);
+                break;
+            }
+
+
+            ////////////////////////////////////////////////////////////////////////////////////////////////
+            ////                                                                                        ////
             ////    Information related to the Coordinate Reference System and the bounding box.        ////
             ////                                                                                        ////
             ////////////////////////////////////////////////////////////////////////////////////////////////
@@ -400,14 +715,18 @@ final class ImageFileDirectory {
              * The computer and/or operating system in use at the time of image creation.
              */
             case Tags.HostComputer: {
-                // TODO
+                for (final String value : type.readString(reader.input, count, reader.owner.encoding)) {
+                    reader.metadata.addProcessing(value);
+                }
                 break;
             }
             /*
              * Name and version number of the software package(s) used to create the image.
              */
             case Tags.Software: {
-                // TODO
+                for (final String value : type.readString(reader.input, count, reader.owner.encoding)) {
+                    reader.metadata.setSoftwareReferences(value);
+                }
                 break;
             }
             /*
@@ -415,7 +734,9 @@ final class ImageFileDirectory {
              * Synthetic images should not include this field.
              */
             case Tags.Make: {
-                // TODO
+                for (final String value : type.readString(reader.input, count, reader.owner.encoding)) {
+                    reader.metadata.addInstrument(value);
+                }
                 break;
             }
             /*
@@ -423,21 +744,23 @@ final class ImageFileDirectory {
              * generate the image.
              */
             case Tags.Model: {
-                // TODO
+                for (final String value : type.readString(reader.input, count, reader.owner.encoding)) {
+                    reader.metadata.addInstrument(value);
+                }
                 break;
             }
             /*
              * The number of pixels per ResolutionUnit in the ImageWidth direction.
              */
             case Tags.XResolution: {
-                // TODO
+                tiffResolution = Math.max(type.readDouble(reader.input, count), tiffResolution);
                 break;
             }
             /*
              * The number of pixels per ResolutionUnit in the ImageLength direction.
              */
             case Tags.YResolution: {
-                // TODO
+                tiffResolution = Math.max(type.readDouble(reader.input, count), tiffResolution);
                 break;
             }
             /*
@@ -445,7 +768,21 @@ final class ImageFileDirectory {
              * 1 = None, 2 = Inch, 3 = Centimeter.
              */
             case Tags.ResolutionUnit: {
-                // TODO
+                final short res = type.readShort(reader.input, count);
+                switch(res) {
+                    case 2 : {
+                        resolutionUnit = Units.INCH;
+                        break;
+                    }
+                    case 3 : {
+                        resolutionUnit = Units.CENTIMETRE;
+                        break;
+                    }
+                    default : {
+                        resolutionUnit = null;
+                        break;
+                    }
+                }
                 break;
             }
             /*
@@ -455,7 +792,23 @@ final class ImageFileDirectory {
              * 3 = A randomized process such as error diffusion has been applied to the image data.
              */
             case Tags.Threshholding: {
-                // TODO
+                final short value = type.readShort(reader.input, count);
+                final String s;
+                switch(value) {
+                    case 2 : {
+                        s = reader.resources().getString(Resources.Keys.Threshholding2_0);
+                        break;
+                    }
+                    case 3 : {
+                        s = reader.resources().getString(Resources.Keys.Threshholding3_0);
+                        break;
+                    }
+                    default : {
+                        s = reader.resources().getString(Resources.Keys.Threshholding1_0);
+                        break;
+                    }
+                }
+                reader.metadata.setProcedureDescription(s);
                 break;
             }
             /*
@@ -463,7 +816,8 @@ final class ImageFileDirectory {
              * bilevel file. Meaningful only if Threshholding = 2.
              */
             case Tags.CellWidth: {
-                // TODO
+                final String s = reader.resources().getString(Resources.Keys.CellWidth_1, type.readShort(reader.input, count));
+                reader.metadata.setProcessingDocumentation(s);
                 break;
             }
             /*
@@ -471,7 +825,8 @@ final class ImageFileDirectory {
              * bilevel file. Meaningful only if Threshholding = 2.
              */
             case Tags.CellLength: {
-                // TODO
+                final String s = reader.resources().getString(Resources.Keys.CellHeight_1, type.readShort(reader.input, count));
+                reader.metadata.setProcessingDocumentation(s);
                 break;
             }
 
@@ -493,7 +848,7 @@ final class ImageFileDirectory {
              */
             case Tags.GrayResponseCurve:
             case Tags.GrayResponseUnit: {
-                // TODO: log a warning saying that this tag is ignored.
+                warning(reader, Level.FINE, Resources.Keys.IgnoredTag_1, Tags.name(tag));
                 break;
             }
         }
@@ -501,6 +856,167 @@ final class ImageFileDirectory {
     }
 
     /**
+     * Validate method which re-build missing attributs from others as if possible or
+     * throw exception if mandatory attributs are missing or also if it is impossible
+     * to resolve ambiguity between some attributs.
+     *
+     * @throws DataStoreContentException
+     */
+    final void checkTiffTags(final Reader reader)
+            throws DataStoreContentException {
+
+        if (imageWidth == -1)
+            throw new DataStoreContentException(reader.resources().getString(
+                                Resources.Keys.MissingValueRequired_2, "ImageWidth", reader.input.filename));
+
+        if (imageHeight == -1)
+            throw new DataStoreContentException(reader.resources().getString(
+                                Resources.Keys.MissingValueRequired_2, "ImageLength", reader.input.filename));
+
+        if ((!isTiled() && !isStripped())
+          || (isTiled() &&  isStripped()))
+            throw new DataStoreContentException(reader.resources().getString(
+                                Resources.Keys.MissingTileStrip_1, reader.input.filename));
+
+        if (samplesPerPixel == 0) {
+            samplesPerPixel = 1;
+            warning(reader, Level.FINE, Resources.Keys.DefaultAttribut_2, "SamplesPerPixel", 1);
+        }
+
+        if (bitsPerSample == 0) {
+            bitsPerSample = 1;
+            warning(reader, Level.FINE, Resources.Keys.DefaultAttribut_2, "BitsPerSample", 1);
+        }
+
+        if (colorMap != null) {
+            final int expectedSize = 3 * (1 << bitsPerSample);
+            if (colorMap.size() != expectedSize)
+                warning(reader, Level.WARNING, Resources.Keys.MismatchLength_4, "ColorMap array",
+                        "BitsPerSample",
+                        "3* 2^bitsPerSample : "+expectedSize, colorMap.size());
+        }
+
+
+        final boolean canReBuilt = (!isPlanar && compression.equals(Compression.NONE));
+
+        if (isTiled()) {
+            //-- it is not efficient and dangerous to try to re-build tileOffsets.
+            if (tileOffsets == null)
+                throw new DataStoreContentException(reader.resources().getString(
+                                    Resources.Keys.MissingValueRequired_2, "TileOffsets", reader.input.filename));
+
+            if (canReBuilt) {
+                int twThTbc = 0;
+                if (tileWidth      >= 0)    twThTbc |= 4;
+                if (tileHeight     >= 0)    twThTbc |= 2;
+                if (tileByteCounts != null) twThTbc |= 1;
+
+                switch(twThTbc) {
+                    case 3 : {
+                        //-- missing tile width twThTbc = 011
+                        warning(reader, Level.WARNING, Resources.Keys.ReBuildAttribut_2, "TileWidth","TileByteCounts, TileHeight, SamplesPerPixel, BitsPerSamples");
+                        tileWidth = tileByteCounts.get(0).intValue() / (tileHeight * samplesPerPixel * (bitsPerSample / Byte.SIZE));
+                        break;
+                    }
+                    case 5 : {
+                        //-- missing tileHeight twThTbc = 101
+                        warning(reader, Level.WARNING, Resources.Keys.ReBuildAttribut_2, "TileHeight","TileByteCounts, TileWidth, SamplesPerPixel, BitsPerSamples");
+                        tileHeight = tileByteCounts.get(0).intValue() / (tileWidth * samplesPerPixel * (bitsPerSample / Byte.SIZE));
+                        break;
+                    }
+                    case 6 : {
+                        //-- missing tileByteCount twThTbc = 110
+                        warning(reader, Level.WARNING, Resources.Keys.ReBuildAttribut_2, "TileByteCounts","TileOffsets, TileHeight, TileWidth, SamplesPerPixel, BitsPerSamples");
+                        final long tileByteCount        = tileHeight * tileWidth * samplesPerPixel * bitsPerSample;
+                        final long[] tileByteCountArray = new long[tileOffsets.size()];
+                        Arrays.fill(tileByteCountArray, tileByteCount);
+                        tileByteCounts = Vector.create(tileByteCountArray, true);
+                        break;
+                    }
+                    case 7 : {
+                        //-- every thing is ok
+                        break;
+                    }
+                    default : {
+                        throw new DataStoreContentException(reader.resources().getString(
+                                            Resources.Keys.MissingValueRequired_2, "TileWidth, TileHeight, TileByteCount", reader.input.filename));
+                    }
+                }
+            }
+
+            if (tileByteCounts == null)
+                throw new DataStoreContentException(reader.resources().getString(
+                                    Resources.Keys.MissingValueRequired_2, "TileByteCount", reader.input.filename));
+
+            if (tileWidth == -1)
+                throw new DataStoreContentException(reader.resources().getString(
+                                Resources.Keys.MissingValueRequired_2, "TileWidth", reader.input.filename));
+            if (tileHeight == -1)
+                throw new DataStoreContentException(reader.resources().getString(
+                                    Resources.Keys.MissingValueRequired_2, "TileLength", reader.input.filename));
+
+            //-- Check size of ByteCounts and Offsets
+            //-- important reading attributs, Level WARNING
+            int expectedSize = (int) (Math.floorDiv(imageWidth, tileWidth) * Math.floorDiv(imageHeight, tileHeight));
+            if (isPlanar) expectedSize *= samplesPerPixel;
+            if (tileOffsets.size() != expectedSize)
+                warning(reader, Level.WARNING, Resources.Keys.MismatchLength_4, "TileOffsets",
+                        "ImageWidth, ImageHeight, TileWidth, TileHeight, SamplePerPixel and PlanarConfiguration",
+                        expectedSize, tileOffsets.size());
+            if (tileByteCounts.size() != expectedSize)
+                warning(reader, Level.WARNING, Resources.Keys.MismatchLength_4, "TileByteCounts",
+                        "ImageWidth, ImageHeight, TileWidth, TileHeight, SamplePerPixel and PlanarConfiguration",
+                        expectedSize, tileByteCounts.size());
+            if (tileByteCounts.size() != tileOffsets.size())
+                warning(reader, Level.WARNING, Resources.Keys.MismatchLength_4, "TileByteCounts",
+                        "TileOffsets", tileOffsets.size(), tileByteCounts.size());
+        }
+
+        if (isStripped()) {
+
+            if (stripOffsets == null)
+                throw new DataStoreContentException(reader.resources().getString(
+                                    Resources.Keys.MissingValueRequired_2, "StripOffsets", reader.input.filename));
+
+            if (rowsPerStrip == 0xFFFFFFFF) {
+                rowsPerStrip = imageHeight;
+                warning(reader, Level.FINE, Resources.Keys.DefaultAttribut_2, "RowsPerStrip", imageHeight+"(= imageLength)");
+            }
+
+            if (canReBuilt) {
+                if (stripByteCounts == null) {
+                    warning(reader, Level.WARNING, Resources.Keys.ReBuildAttribut_2, "StripByteCounts","StripOffset, RowsPerStrip, ImageWidth, SamplesPerPixel, BitsPerSamples");
+                    final long stripByteCount = rowsPerStrip * imageWidth * samplesPerPixel * bitsPerSample;
+                    final long[] stripByteCountsArray = new long[stripOffsets.size()];
+                    Arrays.fill(stripByteCountsArray, stripByteCount);
+                    stripByteCounts = Vector.create(stripByteCountsArray, true);
+                }
+            }
+
+            if (stripByteCounts == null)
+                throw new DataStoreContentException(reader.resources().getString(
+                                    Resources.Keys.MissingValueRequired_2, "StripByteCount", reader.input.filename));
+
+            //-- Check size of ByteCounts and Offsets
+            //-- important reading attributs, Level WARNING
+            int expectedSize = (int) Math.floorDiv(imageHeight, rowsPerStrip);
+            if (isPlanar) expectedSize *= samplesPerPixel;
+            if (stripOffsets.size() != expectedSize)
+                warning(reader, Level.WARNING, Resources.Keys.MismatchLength_4, "StripOffsets",
+                        "RowsPerStrip, ImageHeight, SamplePerPixel and PlanarConfiguration",
+                        expectedSize, stripOffsets.size());
+            if (stripByteCounts.size() != expectedSize)
+                warning(reader, Level.WARNING, Resources.Keys.MismatchLength_4, "StripByteCounts",
+                        "RowsPerStrip, ImageHeight, SamplePerPixel and PlanarConfiguration",
+                        expectedSize, stripByteCounts.size());
+            if (stripByteCounts.size() != stripOffsets.size())
+                warning(reader, Level.WARNING, Resources.Keys.MismatchLength_4, "StripByteCounts",
+                        "StripOffsets", stripOffsets.size(), stripByteCounts.size());
+        }
+    }
+
+
+    /**
      * Completes the metadata with the information stored in the field of this IFD.
      * This method is invoked only if the user requested the ISO 19115 metadata.
      */
@@ -508,5 +1024,11 @@ final class ImageFileDirectory {
         if (compression != null) {
             metadata.addCompression(compression.name().toLowerCase(locale));
         }
+        //-- add Resolution into metadata
+        //-- convert into meters
+        if (tiffResolution != -1 && resolutionUnit != null) {
+            metadata.addResolution(resolutionUnit.getConverterTo(METER).convert(tiffResolution));
+        }
     }
+
 }

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java?rev=1768741&r1=1768740&r2=1768741&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Reader.java [UTF-8] Tue Nov  8 17:19:54 2016
@@ -110,6 +110,11 @@ final class Reader extends GeoTIFF {
     final MetadataBuilder metadata;
 
     /**
+     * Builder for the Coordinate Reference System.
+     */
+    final TiffCRSBuilder crsBuilder;
+
+    /**
      * Creates a new GeoTIFF reader which will read data from the given input.
      * The input must be at the beginning of the GeoTIFF file.
      *
@@ -118,9 +123,10 @@ final class Reader extends GeoTIFF {
      */
     Reader(final GeoTiffStore owner, final ChannelDataInput input) throws IOException, DataStoreException {
         super(owner);
-        this.input    = input;
-        this.origin   = input.getStreamPosition();
-        this.metadata = new MetadataBuilder();
+        this.input      = input;
+        this.origin     = input.getStreamPosition();
+        this.metadata   = new MetadataBuilder();
+        this.crsBuilder = new TiffCRSBuilder(this);
         /*
          * A TIFF file begins with either "II" (0x4949) or "MM" (0x4D4D) characters.
          * Those characters identify the byte order. Note we we do not need to care
@@ -290,6 +296,7 @@ final class Reader extends GeoTIFF {
             resolveDeferredEntries(dir, Long.MAX_VALUE);
             dir.hasDeferredEntries = false;
         }
+        dir.checkTiffTags(this);
         return dir;
     }
 

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Tags.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Tags.java?rev=1768741&r1=1768740&r2=1768741&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Tags.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Tags.java [UTF-8] Tue Nov  8 17:19:54 2016
@@ -123,6 +123,35 @@ final class Tags {
     public static final int GDAL_METADATA = 42112;  // http://www.awaresystems.be/imaging/tiff/tifftags/gdal_metadata.html
     public static final int GDAL_NODATA   = 42113;  // http://www.awaresystems.be/imaging/tiff/tifftags/gdal_nodata.html
 
+
+    /////////////////////////////////////////////////////////
+    //                 GEOTIFF EXTENSION TAGS              //
+    /////////////////////////////////////////////////////////
+
+    //------------------------------- CRS ------------------------------------//
+    /**
+     * References the needed "GeoKeys" to build CRS.
+     */
+    public static final int GeoKeyDirectoryTag = 0x87AF; //-- 34735
+
+    /**
+     * This tag is used to store all of the DOUBLE valued GeoKeys, referenced by the GeoKeyDirectoryTag.
+     */
+    public static final int GeoDoubleParamsTag = 0x87B0; //-- 34736
+
+    /**
+     * This tag is used to store all of the ASCII valued GeoKeys, referenced by the GeoKeyDirectoryTag.
+     */
+    public static final int GeoAsciiParamsTag = 0x87B1; //-- 34737
+
+    static final class CRSKeys {
+
+    }
+
+
+
+
+
     /**
      * Do not allow instantiation of this class.
      */



Mime
View raw message