예제 #1
0
        public static int GTIFKeyGet(GTIF gtif, geokey_t thekey, out string val, int index, int count)
        {
            val = null;
            if (count < 0)
            {
                return(0);
            }

            if (!gtif.gt_keys.ContainsKey(thekey))
            {
                return(0);
            }
            GeoKey key = gtif.gt_keys[thekey];

            if (key.gk_type != tagtype_t.TYPE_ASCII)
            {
                return(0);
            }

            string val_ = (string)key.gk_data;

            if (count == 0 || (count + index) > val_.Length)
            {
                val = val_.Substring(index);
            }
            else
            {
                val = val_.Substring(index, count);
            }

            return(val.Length);
        }
예제 #2
0
        public static int GTIFKeyGet(GTIF gtif, geokey_t thekey, out double[] val, int index, int count)
        {
            val = null;
            if (!gtif.gt_keys.ContainsKey(thekey))
            {
                return(0);
            }
            GeoKey key = gtif.gt_keys[thekey];

            if (key.gk_type != tagtype_t.TYPE_DOUBLE)
            {
                return(0);
            }

            double[] val_ = (double[])key.gk_data;
            if (count == 0 || (count + index) > val_.Length)
            {
                count = val_.Length - index;
            }
            if (count <= 0)
            {
                return(0);
            }
            val = new double[count];
            Array.Copy(val_, index, val, 0, count);
            return(count);
        }
예제 #3
0
        public static int GTIFKeyInfo(GTIF gtif, geokey_t key, out tagtype_t type)
        {
            type = tagtype_t.TYPE_UNKNOWN;
            if (!gtif.gt_keys.ContainsKey(key))
            {
                return(0);
            }
            GeoKey keyptr = gtif.gt_keys[key];

            type = keyptr.gk_type;
            return(keyptr.gk_count);
        }
예제 #4
0
        public static int GTIFKeyGet(GTIF gtif, geokey_t thekey, out string val)
        {
            val = null;
            if (!gtif.gt_keys.ContainsKey(thekey))
            {
                return(0);
            }
            GeoKey key = gtif.gt_keys[thekey];

            if (key.gk_type != tagtype_t.TYPE_ASCII)
            {
                return(0);
            }

            val = (string)key.gk_data;

            return(val.Length);
        }
예제 #5
0
        public static bool GTIFKeySet(GTIF gtif, geokey_t keyID, double[] val)
        {
            if (val == null)          // delete the indicated tag
            {
                if (!gtif.gt_keys.ContainsKey(keyID))
                {
                    return(false);
                }
                gtif.gt_keys.Remove(keyID);
                gtif.gt_flags |= gtiff_flags.FLAG_FILE_MODIFIED;
                return(true);
            }

            if (gtif.gt_keys.ContainsKey(keyID))
            {
                gtif.gt_keys.Remove(keyID);
                gtif.gt_flags |= gtiff_flags.FLAG_FILE_MODIFIED;
            }

            // We need to create the key
            try
            {
                GeoKey key = new GeoKey();
                key.gk_key   = keyID;
                key.gk_type  = tagtype_t.TYPE_DOUBLE;
                key.gk_count = val.Length;

                double[] tmp = new double[val.Length];
                val.CopyTo(tmp, 0);
                key.gk_data = tmp;

                gtif.gt_keys.Add(keyID, key);
                gtif.gt_flags |= gtiff_flags.FLAG_FILE_MODIFIED;
                return(true);
            }
            catch
            {
                return(false);
            }
        }
예제 #6
0
        public static bool GTIFKeySet(GTIF gtif, geokey_t keyID, string val)
        {
            if (val == null)          // delete the indicated tag
            {
                if (!gtif.gt_keys.ContainsKey(keyID))
                {
                    return(false);
                }
                gtif.gt_keys.Remove(keyID);
                gtif.gt_flags |= gtiff_flags.FLAG_FILE_MODIFIED;
                return(true);
            }

            if (gtif.gt_keys.ContainsKey(keyID))
            {
                gtif.gt_keys.Remove(keyID);
                gtif.gt_flags |= gtiff_flags.FLAG_FILE_MODIFIED;
            }

            val = val.Trim('\0');

            // We need to create the key
            try
            {
                GeoKey key = new GeoKey();
                key.gk_key   = keyID;
                key.gk_type  = tagtype_t.TYPE_ASCII;
                key.gk_count = val.Length;
                key.gk_data  = val.Substring(0, val.Length);
                gtif.gt_keys.Add(keyID, key);
                gtif.gt_flags |= gtiff_flags.FLAG_FILE_MODIFIED;
                return(true);
            }
            catch
            {
                return(false);
            }
        }
예제 #7
0
		static void PrintKey(GeoKey key, GTIFPrintMethod print, object aux)
		{
			print("\t\t", aux);

			geokey_t keyid=key.gk_key;
			print(GTIFKeyName(keyid), aux);

			int count=key.gk_count;
			string message=string.Format(" ({0},{1}): ", GTIFTypeName(key.gk_type), count);
			print(message, aux);

			object data=key.gk_data;

			switch(key.gk_type)
			{
				case tagtype_t.TYPE_ASCII:
					{
						string str=data as string;
						if(str==null) throw new Exception("string expected.");
						if(str.Length<count) throw new Exception("string too short.");

						message="\"";
						
						for(int i=0; i<count; i++)
						{
							char c=str[i];

							if(c=='\n') message+="\\n";
							else if(c=='\\') message+="\\\\";
							else if(c=='\t') message+="\\t";
							else if(c=='\b') message+="\\b";
							else if(c=='\r') message+="\\r";
							else if(c=='"') message+="\\\"";
							else if(c=='\0') message+="\\0";
							else message+=c;
						}

						message+="\"\n";
						print(message, aux);
					}
					break;
				case tagtype_t.TYPE_DOUBLE:
					double[] dptr=data as double[];
					if(dptr==null) throw new Exception("double[] expected.");
					if(dptr.Length<count) throw new Exception("double[] too short.");
					for(int i=0; i<count; i+=3)
					{
						int done=Math.Min(i+3, count);
						for(int j=i; j<done; j++)
						{
							message=string.Format(FMT_DOUBLE, dptr[j]);
							print(message, aux);
						}
						print("\n", aux);
					}
					break;
				case tagtype_t.TYPE_SHORT:
					ushort[] sptr=data as ushort[];
					if(sptr==null) throw new Exception("ushort[] expected.");
					if(sptr.Length<count) throw new Exception("ushort[] too short.");
					if(count==1)
					{
						print(GTIFValueName(keyid, sptr[0]), aux);
						print("\n", aux);
					}
					else
					{
						for(int i=0; i<count; i+=3)
						{
							int done=Math.Min(i+3, count);
							for(int j=i; j<done; j++)
							{
								message=string.Format(FMT_SHORT, sptr[j]);
								print(message, aux);
							}
							print("\n", aux);
						}
					}
					break;
				default:
					message=string.Format("Unknown Type ({0})\n", key.gk_type);
					print(message, aux);
					break;
			}
		}
예제 #8
0
        static void PrintKey(GeoKey key, GTIFPrintMethod print, object aux)
        {
            print("\t\t", aux);

            geokey_t keyid = key.gk_key;

            print(GTIFKeyName(keyid), aux);

            int    count   = key.gk_count;
            string message = string.Format(" ({0},{1}): ", GTIFTypeName(key.gk_type), count);

            print(message, aux);

            object data = key.gk_data;

            switch (key.gk_type)
            {
            case tagtype_t.TYPE_ASCII:
            {
                string str = data as string;
                if (str == null)
                {
                    throw new Exception("string expected.");
                }
                if (str.Length < count)
                {
                    throw new Exception("string too short.");
                }

                message = "\"";

                for (int i = 0; i < count; i++)
                {
                    char c = str[i];

                    if (c == '\n')
                    {
                        message += "\\n";
                    }
                    else if (c == '\\')
                    {
                        message += "\\\\";
                    }
                    else if (c == '\t')
                    {
                        message += "\\t";
                    }
                    else if (c == '\b')
                    {
                        message += "\\b";
                    }
                    else if (c == '\r')
                    {
                        message += "\\r";
                    }
                    else if (c == '"')
                    {
                        message += "\\\"";
                    }
                    else if (c == '\0')
                    {
                        message += "\\0";
                    }
                    else
                    {
                        message += c;
                    }
                }

                message += "\"\n";
                print(message, aux);
            }
            break;

            case tagtype_t.TYPE_DOUBLE:
                double[] dptr = data as double[];
                if (dptr == null)
                {
                    throw new Exception("double[] expected.");
                }
                if (dptr.Length < count)
                {
                    throw new Exception("double[] too short.");
                }
                for (int i = 0; i < count; i += 3)
                {
                    int done = Math.Min(i + 3, count);
                    for (int j = i; j < done; j++)
                    {
                        message = string.Format(FMT_DOUBLE, dptr[j]);
                        print(message, aux);
                    }
                    print("\n", aux);
                }
                break;

            case tagtype_t.TYPE_SHORT:
                ushort[] sptr = data as ushort[];
                if (sptr == null)
                {
                    throw new Exception("ushort[] expected.");
                }
                if (sptr.Length < count)
                {
                    throw new Exception("ushort[] too short.");
                }
                if (count == 1)
                {
                    print(GTIFValueName(keyid, sptr[0]), aux);
                    print("\n", aux);
                }
                else
                {
                    for (int i = 0; i < count; i += 3)
                    {
                        int done = Math.Min(i + 3, count);
                        for (int j = i; j < done; j++)
                        {
                            message = string.Format(FMT_SHORT, sptr[j]);
                            print(message, aux);
                        }
                        print("\n", aux);
                    }
                }
                break;

            default:
                message = string.Format("Unknown Type ({0})\n", key.gk_type);
                print(message, aux);
                break;
            }
        }
예제 #9
0
        // **************************************************************************
        // *						GTIFNewWithMethods()							*
        // *																		*
        // *	Create a new geotiff, passing in the methods structure to			*
        // *	support not libtiff implementations without replacing the			*
        // *	default methods.													*
        // **************************************************************************
        public static GTIF GTIFNewWithMethods(TIFF tif, TIFFMethod methods)
        {
            GTIF gt = null;

            try
            {
                gt            = new GTIF();
                gt.gt_methods = new TIFFMethod();
                gt.gt_keys    = new Dictionary <geokey_t, GeoKey>();
            }
            catch
            {
                return(null);
            }

            // install TIFF file and I/O methods
            gt.gt_tif          = tif;
            gt.gt_methods.get  = methods.get;
            gt.gt_methods.set  = methods.set;
            gt.gt_methods.type = methods.type;

            gt.gt_rev_major = GvCurrentRevision;
            gt.gt_rev_minor = GvCurrentMinorRev;
            gt.gt_version   = GvCurrentVersion;

            if (tif == null)
            {
                return(gt);
            }

            object data;
            int    nshorts;

            // since this is an array, GTIF will allocate the memory
            if (!gt.gt_methods.get(tif, (ushort)GTIFF_GEOKEYDIRECTORY, out nshorts, out data))
            {
                return(gt);
            }

            if (nshorts < 4)
            {
                return(null);
            }
            ushort[] shorts = data as ushort[];
            if (shorts == null || shorts.Length < 4)
            {
                return(null);
            }

            if (shorts[0] > GvCurrentVersion)
            {
                return(null);
            }
            gt.gt_version = shorts[0];

            if (shorts[1] > GvCurrentRevision)
            {
                // issue warning
            }
            gt.gt_rev_major = shorts[1];
            gt.gt_rev_minor = shorts[2];

            int count = shorts[3];

            if (count == 0)
            {
                return(gt);
            }
            if (shorts.Length < (count * 4 + 4))
            {
                return(null);
            }

            // If we got here, then the geokey can be parsed

            // Get the PARAMS Tags, if any
            int ndoubles;

            double[] doubles;
            if (!gt.gt_methods.get(tif, (ushort)GTIFF_DOUBLEPARAMS, out ndoubles, out data))
            {
                try
                {
                    doubles = new double[MAX_VALUES];
                }
                catch
                {
                    return(null);
                }
            }
            else
            {
                doubles = data as double[];
                if (doubles == null)
                {
                    return(null);
                }
            }

            int    stringsLength = 0;
            string strings       = null;

            if (gt.gt_methods.get(tif, (ushort)GTIFF_ASCIIPARAMS, out stringsLength, out data))
            {
                strings = data as string;
                if (strings == null)
                {
                    return(null);
                }
                strings       = strings.TrimEnd('\0');         // last NULL doesn't count; "|" used for delimiter
                stringsLength = strings.Length;
            }

            for (int i = 0; i < count; i++)
            {
                ushort KeyID           = shorts[i * 4 + 4];
                ushort TIFFTagLocation = shorts[i * 4 + 5];
                ushort Count           = shorts[i * 4 + 6];
                ushort Value_Offset    = shorts[i * 4 + 7];

                GeoKey keyptr;

                try
                {
                    keyptr = new GeoKey();

                    keyptr.gk_key = (geokey_t)KeyID;

                    if (TIFFTagLocation != 0)
                    {
                        keyptr.gk_type = gt.gt_methods.type(gt.gt_tif, TIFFTagLocation);
                    }
                    else
                    {
                        keyptr.gk_type = tagtype_t.TYPE_SHORT;                    //gt.gt_methods.type(gt.gt_tif, (ushort)GTIFF_GEOKEYDIRECTORY);
                    }
                    switch (TIFFTagLocation)
                    {
                    case (ushort)GTIFF_LOCAL:
                        // store value into data value
                        keyptr.gk_data  = new ushort[] { Value_Offset };
                        keyptr.gk_count = 1;
                        break;

                    case (ushort)GTIFF_GEOKEYDIRECTORY:
                        ushort[] s = new ushort[Count];
                        keyptr.gk_data = s;
                        Array.Copy(shorts, Value_Offset, s, 0, Count);
                        keyptr.gk_count = Count;
                        break;

                    case (ushort)GTIFF_DOUBLEPARAMS:
                        double[] d = new double[Count];
                        keyptr.gk_data = d;
                        Array.Copy(doubles, Value_Offset, d, 0, Count);
                        keyptr.gk_count = Count;
                        break;

                    case (ushort)GTIFF_ASCIIPARAMS:
                        string str = strings.Substring(Value_Offset, Count);
                        str             = str.Replace('|', '\0');
                        str             = str.Trim('\0');
                        keyptr.gk_count = str.Length;
                        keyptr.gk_data  = str;
                        break;

                    default:
                        return(null);                                // failure
                    }
                }
                catch
                {
                    return(null);
                }

                gt.gt_keys.Add(keyptr.gk_key, keyptr);
            }

            return(gt);
        }
예제 #10
0
        // This function flushes all the GeoTIFF keys that have been set with the
        // GTIFKeySet() function into the associated
        // TIFF file.
        //
        // @param gt The GeoTIFF handle returned by GTIFNew.
        //
        // GTIFWriteKeys() should be called before
        // GTIFFree() is used to deallocate a GeoTIFF access handle.
        public static bool GTIFWriteKeys(GTIF gt)
        {
            if ((gt.gt_flags & gtiff_flags.FLAG_FILE_MODIFIED) == 0)
            {
                return(true);
            }
            if (gt.gt_tif == null)
            {
                return(false);
            }

            List <geokey_t> keys = new List <geokey_t>(gt.gt_keys.Keys);

            keys.Sort();

            List <ushort> shorts       = new List <ushort>();
            List <ushort> shortsValues = new List <ushort>();
            List <double> doubles      = new List <double>();
            string        strings      = "";

            // Set up header of ProjectionInfo tag
            shorts.Add((ushort)GvCurrentVersion);
            shorts.Add((ushort)GvCurrentRevision);
            shorts.Add((ushort)GvCurrentMinorRev);
            shorts.Add((ushort)keys.Count);

            int shortOffset = 4 + keys.Count * 4;

            foreach (geokey_t key in keys)
            {
                GeoKey keyptr = gt.gt_keys[key];
                if (keyptr.gk_type == tagtype_t.TYPE_ASCII)
                {
                    string str = keyptr.gk_data as string;
                    if (str == null)
                    {
                        str = "";
                    }

                    str  = str.Trim('\0');
                    str += "|";
                    str  = str.Replace('\0', '|');

                    shorts.Add((ushort)key);
                    shorts.Add((ushort)GTIFF_ASCIIPARAMS);
                    shorts.Add((ushort)str.Length);
                    shorts.Add((ushort)strings.Length);
                    strings += str;

                    continue;
                }

                if (keyptr.gk_type == tagtype_t.TYPE_DOUBLE)
                {
                    double[] dbl = keyptr.gk_data as double[];
                    if (dbl == null)
                    {
                        shorts.Add((ushort)key);
                        shorts.Add((ushort)GTIFF_DOUBLEPARAMS);
                        shorts.Add((ushort)0);
                        shorts.Add((ushort)0);
                    }
                    else
                    {
                        shorts.Add((ushort)key);
                        shorts.Add((ushort)GTIFF_DOUBLEPARAMS);
                        shorts.Add((ushort)dbl.Length);
                        shorts.Add((ushort)doubles.Count);
                        doubles.AddRange(dbl);
                    }
                    continue;
                }

                ushort[] sht = keyptr.gk_data as ushort[];
                if (sht == null)
                {
                    shorts.Add((ushort)key);
                    shorts.Add((ushort)GTIFF_LOCAL);
                    shorts.Add((ushort)0);
                    shorts.Add((ushort)0);
                }
                else
                {
                    if (sht.Length < 2)
                    {
                        shorts.Add((ushort)key);
                        shorts.Add((ushort)GTIFF_LOCAL);
                        shorts.Add((ushort)sht.Length);
                        if (sht.Length == 1)
                        {
                            shorts.Add(sht[0]);
                        }
                        else
                        {
                            shorts.Add(0);
                        }
                    }
                    else
                    {
                        shorts.Add((ushort)key);
                        shorts.Add((ushort)GTIFF_GEOKEYDIRECTORY);
                        shorts.Add((ushort)sht.Length);
                        shorts.Add((ushort)(shortOffset + shortsValues.Count));
                        shortsValues.AddRange(sht);
                    }
                }
            }

            if (shorts.Count != shortOffset)
            {
                return(false);
            }
            shorts.AddRange(shortsValues);

            // Write out the Key Directory
            gt.gt_methods.set(gt.gt_tif, (ushort)GTIFF_GEOKEYDIRECTORY, shorts.Count, shorts.ToArray());

            // Write out the params directories
            if (doubles.Count > 0)
            {
                gt.gt_methods.set(gt.gt_tif, (ushort)GTIFF_DOUBLEPARAMS, doubles.Count, doubles.ToArray());
            }
            if (strings.Length > 0)
            {
                gt.gt_methods.set(gt.gt_tif, (ushort)GTIFF_ASCIIPARAMS, strings.Length, strings);
            }

            gt.gt_flags &= ~gtiff_flags.FLAG_FILE_MODIFIED;

            return(true);
        }
예제 #11
0
		public static bool GTIFKeySet(GTIF gtif, geokey_t keyID, string val)
		{
			if(val==null) // delete the indicated tag
			{
				if(!gtif.gt_keys.ContainsKey(keyID)) return false;
				gtif.gt_keys.Remove(keyID);
				gtif.gt_flags|=gtiff_flags.FLAG_FILE_MODIFIED;
				return true;
			}

			if(gtif.gt_keys.ContainsKey(keyID))
			{
				gtif.gt_keys.Remove(keyID);
				gtif.gt_flags|=gtiff_flags.FLAG_FILE_MODIFIED;
			}

			val=val.Trim('\0');

			// We need to create the key
			try
			{
				GeoKey key=new GeoKey();
				key.gk_key=keyID;
				key.gk_type=tagtype_t.TYPE_ASCII;
				key.gk_count=val.Length;
				key.gk_data=val.Substring(0, val.Length);
				gtif.gt_keys.Add(keyID, key);
				gtif.gt_flags|=gtiff_flags.FLAG_FILE_MODIFIED;
				return true;
			}
			catch
			{
				return false;
			}
		}
예제 #12
0
		public static bool GTIFKeySet(GTIF gtif, geokey_t keyID, double[] val)
		{
			if(val==null) // delete the indicated tag
			{
				if(!gtif.gt_keys.ContainsKey(keyID)) return false;
				gtif.gt_keys.Remove(keyID);
				gtif.gt_flags|=gtiff_flags.FLAG_FILE_MODIFIED;
				return true;
			}

			if(gtif.gt_keys.ContainsKey(keyID))
			{
				gtif.gt_keys.Remove(keyID);
				gtif.gt_flags|=gtiff_flags.FLAG_FILE_MODIFIED;
			}
			
			// We need to create the key
			try
			{
				GeoKey key=new GeoKey();
				key.gk_key=keyID;
				key.gk_type=tagtype_t.TYPE_DOUBLE;
				key.gk_count=val.Length;

				double[] tmp=new double[val.Length];
				val.CopyTo(tmp, 0);
				key.gk_data=tmp;

				gtif.gt_keys.Add(keyID, key);
				gtif.gt_flags|=gtiff_flags.FLAG_FILE_MODIFIED;
				return true;
			}
			catch
			{
				return false;
			}
		}
예제 #13
0
		// **************************************************************************
		// *						GTIFNewWithMethods()							*
		// *																		*
		// *	Create a new geotiff, passing in the methods structure to			*
		// *	support not libtiff implementations without replacing the			*
		// *	default methods.													*
		// **************************************************************************
		public static GTIF GTIFNewWithMethods(TIFF tif, TIFFMethod methods)
		{
			GTIF gt=null;

			try
			{
				gt=new GTIF();
				gt.gt_methods=new TIFFMethod();
				gt.gt_keys=new Dictionary<geokey_t, GeoKey>();
			}
			catch
			{
				return null;
			}

			// install TIFF file and I/O methods
			gt.gt_tif=tif;
			gt.gt_methods.get=methods.get;
			gt.gt_methods.set=methods.set;
			gt.gt_methods.type=methods.type;

			gt.gt_rev_major=GvCurrentRevision;
			gt.gt_rev_minor=GvCurrentMinorRev;
			gt.gt_version=GvCurrentVersion;

			if(tif==null) return gt;

			object data;
			int nshorts;

			// since this is an array, GTIF will allocate the memory
			if(!gt.gt_methods.get(tif, (ushort)GTIFF_GEOKEYDIRECTORY, out nshorts, out data)) return gt;

			if(nshorts<4) return null;
			ushort[] shorts=data as ushort[];
			if(shorts==null||shorts.Length<4) return null;
			
			if(shorts[0]>GvCurrentVersion) return null;
			gt.gt_version=shorts[0];

			if(shorts[1]>GvCurrentRevision)
			{
				// issue warning
			}
			gt.gt_rev_major=shorts[1];
			gt.gt_rev_minor=shorts[2];

			int count=shorts[3];
			if(count==0) return gt;
			if(shorts.Length<(count*4+4)) return null;

			// If we got here, then the geokey can be parsed

			// Get the PARAMS Tags, if any
			int ndoubles;
			double[] doubles;
			if(!gt.gt_methods.get(tif, (ushort)GTIFF_DOUBLEPARAMS, out ndoubles, out data))
			{
				try
				{
					doubles=new double[MAX_VALUES];
				}
				catch
				{
					return null;
				}
			}
			else
			{
				doubles=data as double[];
				if(doubles==null) return null;
			}

			int stringsLength=0;
			string strings=null;
			if(gt.gt_methods.get(tif, (ushort)GTIFF_ASCIIPARAMS, out stringsLength, out data))
			{
				strings=data as string;
				if(strings==null) return null;
				strings=strings.TrimEnd('\0'); // last NULL doesn't count; "|" used for delimiter
				stringsLength=strings.Length;
			}

			for(int i=0; i<count; i++)
			{
				ushort KeyID=shorts[i*4+4];
				ushort TIFFTagLocation=shorts[i*4+5];
				ushort Count=shorts[i*4+6];
				ushort Value_Offset=shorts[i*4+7];

				GeoKey keyptr;

				try
				{
					keyptr=new GeoKey();

					keyptr.gk_key=(geokey_t)KeyID;

					if(TIFFTagLocation!=0) keyptr.gk_type=gt.gt_methods.type(gt.gt_tif, TIFFTagLocation);
					else keyptr.gk_type=tagtype_t.TYPE_SHORT; //gt.gt_methods.type(gt.gt_tif, (ushort)GTIFF_GEOKEYDIRECTORY);

					switch(TIFFTagLocation)
					{
						case (ushort)GTIFF_LOCAL:
							// store value into data value
							keyptr.gk_data=new ushort[] { Value_Offset };
							keyptr.gk_count=1;
							break;
						case (ushort)GTIFF_GEOKEYDIRECTORY:
							ushort[] s=new ushort[Count];
							keyptr.gk_data=s;
							Array.Copy(shorts, Value_Offset, s, 0, Count);
							keyptr.gk_count=Count;
							break;
						case (ushort)GTIFF_DOUBLEPARAMS:
							double[] d=new double[Count];
							keyptr.gk_data=d;
							Array.Copy(doubles, Value_Offset, d, 0, Count);
							keyptr.gk_count=Count;
							break;
						case (ushort)GTIFF_ASCIIPARAMS:
							string str=strings.Substring(Value_Offset, Count);
							str=str.Replace('|', '\0');
							str=str.Trim('\0');
							keyptr.gk_count=str.Length;
							keyptr.gk_data=str;
							break;
						default:
							return null; // failure
					}
				}
				catch
				{
					return null;
				}

				gt.gt_keys.Add(keyptr.gk_key, keyptr);
			}

			return gt;
		}