public virtual void TestGetUInt8()
        {
            sbyte[]            buffer = new sbyte[] { unchecked ((int)(0x00)), unchecked ((int)(0x01)), unchecked ((sbyte)unchecked ((int)(0x7F))), unchecked ((sbyte)unchecked ((int)(0xFF))) };
            RandomAccessReader reader = CreateReader(buffer);

            Sharpen.Tests.AreEqual(0, reader.GetUInt8(0));
            Sharpen.Tests.AreEqual(1, reader.GetUInt8(1));
            Sharpen.Tests.AreEqual(127, reader.GetUInt8(2));
            Sharpen.Tests.AreEqual(255, reader.GetUInt8(3));
        }
 public virtual void TestGetUInt8_OutOfBounds()
 {
     try
     {
         RandomAccessReader reader = CreateReader(new sbyte[2]);
         reader.GetUInt8(2);
         NUnit.Framework.Assert.Fail("Exception expected");
     }
     catch (IOException ex)
     {
         Sharpen.Tests.AreEqual("Attempt to read from beyond end of underlying data source (requested index: 2, requested count: 1, max index: 1)", ex.Message);
     }
 }
Ejemplo n.º 3
0
		/// <summary>
		/// Performs the Jfif data extraction, adding found values to the specified
		/// instance of
		/// <see cref="Com.Drew.Metadata.Metadata"/>
		/// .
		/// </summary>
		public virtual void Extract(RandomAccessReader reader, Com.Drew.Metadata.Metadata metadata)
		{
			JfifDirectory directory = metadata.GetOrCreateDirectory<JfifDirectory>();
			try
			{
				// For JFIF, the tag number is also the offset into the segment
				int ver = reader.GetUInt16(JfifDirectory.TagVersion);
				directory.SetInt(JfifDirectory.TagVersion, ver);
				int units = reader.GetUInt8(JfifDirectory.TagUnits);
				directory.SetInt(JfifDirectory.TagUnits, units);
				int height = reader.GetUInt16(JfifDirectory.TagResx);
				directory.SetInt(JfifDirectory.TagResx, height);
				int width = reader.GetUInt16(JfifDirectory.TagResy);
				directory.SetInt(JfifDirectory.TagResy, width);
			}
			catch (IOException me)
			{
				directory.AddError(me.Message);
			}
		}
Ejemplo n.º 4
0
		private static void ProcessTag(Com.Drew.Metadata.Directory directory, int tagType, int tagValueOffset, int componentCount, int formatCode, RandomAccessReader reader)
		{
			switch (formatCode)
			{
				case FmtUndefined:
				{
					// Directory simply stores raw values
					// The display side uses a Descriptor class per directory to turn the raw values into 'pretty' descriptions
					// this includes exif user comments
					directory.SetByteArray(tagType, reader.GetBytes(tagValueOffset, componentCount));
					break;
				}

				case FmtString:
				{
					string @string = reader.GetNullTerminatedString(tagValueOffset, componentCount);
					directory.SetString(tagType, @string);
					break;
				}

				case FmtSrational:
				{
					if (componentCount == 1)
					{
						directory.SetRational(tagType, new Rational(reader.GetInt32(tagValueOffset), reader.GetInt32(tagValueOffset + 4)));
					}
					else
					{
						if (componentCount > 1)
						{
							Rational[] rationals = new Rational[componentCount];
							for (int i = 0; i < componentCount; i++)
							{
								rationals[i] = new Rational(reader.GetInt32(tagValueOffset + (8 * i)), reader.GetInt32(tagValueOffset + 4 + (8 * i)));
							}
							directory.SetRationalArray(tagType, rationals);
						}
					}
					break;
				}

				case FmtUrational:
				{
					if (componentCount == 1)
					{
						directory.SetRational(tagType, new Rational(reader.GetUInt32(tagValueOffset), reader.GetUInt32(tagValueOffset + 4)));
					}
					else
					{
						if (componentCount > 1)
						{
							Rational[] rationals = new Rational[componentCount];
							for (int i = 0; i < componentCount; i++)
							{
								rationals[i] = new Rational(reader.GetUInt32(tagValueOffset + (8 * i)), reader.GetUInt32(tagValueOffset + 4 + (8 * i)));
							}
							directory.SetRationalArray(tagType, rationals);
						}
					}
					break;
				}

				case FmtSingle:
				{
					if (componentCount == 1)
					{
						directory.SetFloat(tagType, reader.GetFloat32(tagValueOffset));
					}
					else
					{
						float[] floats = new float[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							floats[i] = reader.GetFloat32(tagValueOffset + (i * 4));
						}
						directory.SetFloatArray(tagType, floats);
					}
					break;
				}

				case FmtDouble:
				{
					if (componentCount == 1)
					{
						directory.SetDouble(tagType, reader.GetDouble64(tagValueOffset));
					}
					else
					{
						double[] doubles = new double[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							doubles[i] = reader.GetDouble64(tagValueOffset + (i * 4));
						}
						directory.SetDoubleArray(tagType, doubles);
					}
					break;
				}

				case FmtSbyte:
				{
					//
					// Note that all integral types are stored as int32 internally (the largest supported by TIFF)
					//
					if (componentCount == 1)
					{
						directory.SetInt(tagType, reader.GetInt8(tagValueOffset));
					}
					else
					{
						int[] bytes = new int[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							bytes[i] = reader.GetInt8(tagValueOffset + i);
						}
						directory.SetIntArray(tagType, bytes);
					}
					break;
				}

				case FmtByte:
				{
					if (componentCount == 1)
					{
						directory.SetInt(tagType, reader.GetUInt8(tagValueOffset));
					}
					else
					{
						int[] bytes = new int[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							bytes[i] = reader.GetUInt8(tagValueOffset + i);
						}
						directory.SetIntArray(tagType, bytes);
					}
					break;
				}

				case FmtUshort:
				{
					if (componentCount == 1)
					{
						int i = reader.GetUInt16(tagValueOffset);
						directory.SetInt(tagType, i);
					}
					else
					{
						int[] ints = new int[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							ints[i] = reader.GetUInt16(tagValueOffset + (i * 2));
						}
						directory.SetIntArray(tagType, ints);
					}
					break;
				}

				case FmtSshort:
				{
					if (componentCount == 1)
					{
						int i = reader.GetInt16(tagValueOffset);
						directory.SetInt(tagType, i);
					}
					else
					{
						int[] ints = new int[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							ints[i] = reader.GetInt16(tagValueOffset + (i * 2));
						}
						directory.SetIntArray(tagType, ints);
					}
					break;
				}

				case FmtSlong:
				case FmtUlong:
				{
					// NOTE 'long' in this case means 32 bit, not 64
					if (componentCount == 1)
					{
						int i = reader.GetInt32(tagValueOffset);
						directory.SetInt(tagType, i);
					}
					else
					{
						int[] ints = new int[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							ints[i] = reader.GetInt32(tagValueOffset + (i * 4));
						}
						directory.SetIntArray(tagType, ints);
					}
					break;
				}

				default:
				{
					directory.AddError("Unknown format code " + formatCode + " for tag " + tagType);
					break;
				}
			}
		}
Ejemplo n.º 5
0
		private static void ProcessKodakMakernote(KodakMakernoteDirectory directory, int tagValueOffset, RandomAccessReader reader)
		{
			// Kodak's makernote is not in IFD format. It has values at fixed offsets.
			int dataOffset = tagValueOffset + 8;
			try
			{
				directory.SetString(KodakMakernoteDirectory.TagKodakModel, reader.GetString(dataOffset, 8));
				directory.SetInt(KodakMakernoteDirectory.TagQuality, reader.GetUInt8(dataOffset + 9));
				directory.SetInt(KodakMakernoteDirectory.TagBurstMode, reader.GetUInt8(dataOffset + 10));
				directory.SetInt(KodakMakernoteDirectory.TagImageWidth, reader.GetUInt16(dataOffset + 12));
				directory.SetInt(KodakMakernoteDirectory.TagImageHeight, reader.GetUInt16(dataOffset + 14));
				directory.SetInt(KodakMakernoteDirectory.TagYearCreated, reader.GetUInt16(dataOffset + 16));
				directory.SetByteArray(KodakMakernoteDirectory.TagMonthDayCreated, reader.GetBytes(dataOffset + 18, 2));
				directory.SetByteArray(KodakMakernoteDirectory.TagTimeCreated, reader.GetBytes(dataOffset + 20, 4));
				directory.SetInt(KodakMakernoteDirectory.TagBurstMode2, reader.GetUInt16(dataOffset + 24));
				directory.SetInt(KodakMakernoteDirectory.TagShutterMode, reader.GetUInt8(dataOffset + 27));
				directory.SetInt(KodakMakernoteDirectory.TagMeteringMode, reader.GetUInt8(dataOffset + 28));
				directory.SetInt(KodakMakernoteDirectory.TagSequenceNumber, reader.GetUInt8(dataOffset + 29));
				directory.SetInt(KodakMakernoteDirectory.TagFNumber, reader.GetUInt16(dataOffset + 30));
				directory.SetLong(KodakMakernoteDirectory.TagExposureTime, reader.GetUInt32(dataOffset + 32));
				directory.SetInt(KodakMakernoteDirectory.TagExposureCompensation, reader.GetInt16(dataOffset + 36));
				directory.SetInt(KodakMakernoteDirectory.TagFocusMode, reader.GetUInt8(dataOffset + 56));
				directory.SetInt(KodakMakernoteDirectory.TagWhiteBalance, reader.GetUInt8(dataOffset + 64));
				directory.SetInt(KodakMakernoteDirectory.TagFlashMode, reader.GetUInt8(dataOffset + 92));
				directory.SetInt(KodakMakernoteDirectory.TagFlashFired, reader.GetUInt8(dataOffset + 93));
				directory.SetInt(KodakMakernoteDirectory.TagIsoSetting, reader.GetUInt16(dataOffset + 94));
				directory.SetInt(KodakMakernoteDirectory.TagIso, reader.GetUInt16(dataOffset + 96));
				directory.SetInt(KodakMakernoteDirectory.TagTotalZoom, reader.GetUInt16(dataOffset + 98));
				directory.SetInt(KodakMakernoteDirectory.TagDateTimeStamp, reader.GetUInt16(dataOffset + 100));
				directory.SetInt(KodakMakernoteDirectory.TagColorMode, reader.GetUInt16(dataOffset + 102));
				directory.SetInt(KodakMakernoteDirectory.TagDigitalZoom, reader.GetUInt16(dataOffset + 104));
				directory.SetInt(KodakMakernoteDirectory.TagSharpness, reader.GetInt8(dataOffset + 107));
			}
			catch (IOException ex)
			{
				directory.AddError("Error processing Kodak makernote data: " + ex.Message);
			}
		}
Ejemplo n.º 6
0
		private static void ProcessMakernote(int makernoteOffset, ICollection<int> processedIfdOffsets, int tiffHeaderOffset, Com.Drew.Metadata.Metadata metadata, RandomAccessReader reader)
		{
			// Determine the camera model and makernote format
			Com.Drew.Metadata.Directory ifd0Directory = metadata.GetDirectory<ExifIFD0Directory>();
			if (ifd0Directory == null)
			{
				return;
			}
			string cameraMake = ifd0Directory.GetString(ExifIFD0Directory.TagMake);
			string firstThreeChars = reader.GetString(makernoteOffset, 3);
			string firstFourChars = reader.GetString(makernoteOffset, 4);
			string firstFiveChars = reader.GetString(makernoteOffset, 5);
			string firstSixChars = reader.GetString(makernoteOffset, 6);
			string firstSevenChars = reader.GetString(makernoteOffset, 7);
			string firstEightChars = reader.GetString(makernoteOffset, 8);
			string firstTwelveChars = reader.GetString(makernoteOffset, 12);
			bool byteOrderBefore = reader.IsMotorolaByteOrder();
			if ("OLYMP".Equals(firstFiveChars) || "EPSON".Equals(firstFiveChars) || "AGFA".Equals(firstFourChars))
			{
				// Olympus Makernote
				// Epson and Agfa use Olympus makernote standard: http://www.ozhiker.com/electronics/pjmt/jpeg_info/
				ProcessIFD(metadata.GetOrCreateDirectory<OlympusMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader);
			}
			else
			{
				if (cameraMake != null && Sharpen.Extensions.Trim(cameraMake).ToUpper().StartsWith("NIKON"))
				{
					if ("Nikon".Equals(firstFiveChars))
					{
						switch (reader.GetUInt8(makernoteOffset + 6))
						{
							case 1:
							{
								/* There are two scenarios here:
                 * Type 1:                  **
                 * :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon...........
                 * :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................
                 * Type 3:                  **
                 * :0000: 4E 69 6B 6F 6E 00 02 00-00 00 4D 4D 00 2A 00 00 Nikon....MM.*...
                 * :0010: 00 08 00 1E 00 01 00 07-00 00 00 04 30 32 30 30 ............0200
                 */
								ProcessIFD(metadata.GetOrCreateDirectory<NikonType1MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader);
								break;
							}

							case 2:
							{
								ProcessIFD(metadata.GetOrCreateDirectory<NikonType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 18, makernoteOffset + 10, metadata, reader);
								break;
							}

							default:
							{
								ifd0Directory.AddError("Unsupported Nikon makernote data ignored.");
								break;
							}
						}
					}
					else
					{
						// The IFD begins with the first Makernote byte (no ASCII name).  This occurs with CoolPix 775, E990 and D1 models.
						ProcessIFD(metadata.GetOrCreateDirectory<NikonType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader);
					}
				}
				else
				{
					if ("SONY CAM".Equals(firstEightChars) || "SONY DSC".Equals(firstEightChars))
					{
						ProcessIFD(metadata.GetOrCreateDirectory<SonyType1MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 12, tiffHeaderOffset, metadata, reader);
					}
					else
					{
						if ("SEMC MS\u0000\u0000\u0000\u0000\u0000".Equals(firstTwelveChars))
						{
							// force MM for this directory
							reader.SetMotorolaByteOrder(true);
							// skip 12 byte header + 2 for "MM" + 6
							ProcessIFD(metadata.GetOrCreateDirectory<SonyType6MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 20, tiffHeaderOffset, metadata, reader);
						}
						else
						{
							if ("SIGMA\u0000\u0000\u0000".Equals(firstEightChars) || "FOVEON\u0000\u0000".Equals(firstEightChars))
							{
								ProcessIFD(metadata.GetOrCreateDirectory<SigmaMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 10, tiffHeaderOffset, metadata, reader);
							}
							else
							{
								if ("KDK".Equals(firstThreeChars))
								{
									reader.SetMotorolaByteOrder(firstSevenChars.Equals("KDK INFO"));
									ProcessKodakMakernote(metadata.GetOrCreateDirectory<KodakMakernoteDirectory>(), makernoteOffset, reader);
								}
								else
								{
									if (Sharpen.Runtime.EqualsIgnoreCase("Canon", cameraMake))
									{
										ProcessIFD(metadata.GetOrCreateDirectory<CanonMakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader);
									}
									else
									{
										if (cameraMake != null && cameraMake.ToUpper().StartsWith("CASIO"))
										{
											if ("QVC\u0000\u0000\u0000".Equals(firstSixChars))
											{
												ProcessIFD(metadata.GetOrCreateDirectory<CasioType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 6, tiffHeaderOffset, metadata, reader);
											}
											else
											{
												ProcessIFD(metadata.GetOrCreateDirectory<CasioType1MakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader);
											}
										}
										else
										{
											if ("FUJIFILM".Equals(firstEightChars) || Sharpen.Runtime.EqualsIgnoreCase("Fujifilm", cameraMake))
											{
												// Note that this also applies to certain Leica cameras, such as the Digilux-4.3
												reader.SetMotorolaByteOrder(false);
												// the 4 bytes after "FUJIFILM" in the makernote point to the start of the makernote
												// IFD, though the offset is relative to the start of the makernote, not the TIFF
												// header (like everywhere else)
												int ifdStart = makernoteOffset + reader.GetInt32(makernoteOffset + 8);
												ProcessIFD(metadata.GetOrCreateDirectory<FujifilmMakernoteDirectory>(), processedIfdOffsets, ifdStart, makernoteOffset, metadata, reader);
											}
											else
											{
												if (cameraMake != null && cameraMake.ToUpper().StartsWith("MINOLTA"))
												{
													// Cases seen with the model starting with MINOLTA in capitals seem to have a valid Olympus makernote
													// area that commences immediately.
													ProcessIFD(metadata.GetOrCreateDirectory<OlympusMakernoteDirectory>(), processedIfdOffsets, makernoteOffset, tiffHeaderOffset, metadata, reader);
												}
												else
												{
													if ("KYOCERA".Equals(firstSevenChars))
													{
														// http://www.ozhiker.com/electronics/pjmt/jpeg_info/kyocera_mn.html
														ProcessIFD(metadata.GetOrCreateDirectory<KyoceraMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 22, tiffHeaderOffset, metadata, reader);
													}
													else
													{
														if ("LEICA".Equals(firstFiveChars))
														{
															reader.SetMotorolaByteOrder(false);
															if ("Leica Camera AG".Equals(cameraMake))
															{
																ProcessIFD(metadata.GetOrCreateDirectory<LeicaMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader);
															}
															else
															{
																if ("LEICA".Equals(cameraMake))
																{
																	// Some Leica cameras use Panasonic makernote tags
																	ProcessIFD(metadata.GetOrCreateDirectory<PanasonicMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset, metadata, reader);
																}
															}
														}
														else
														{
															if ("Panasonic\u0000\u0000\u0000".Equals(reader.GetString(makernoteOffset, 12)))
															{
																// NON-Standard TIFF IFD Data using Panasonic Tags. There is no Next-IFD pointer after the IFD
																// Offsets are relative to the start of the TIFF header at the beginning of the EXIF segment
																// more information here: http://www.ozhiker.com/electronics/pjmt/jpeg_info/panasonic_mn.html
																ProcessIFD(metadata.GetOrCreateDirectory<PanasonicMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 12, tiffHeaderOffset, metadata, reader);
															}
															else
															{
																if ("AOC\u0000".Equals(firstFourChars))
																{
																	// NON-Standard TIFF IFD Data using Casio Type 2 Tags
																	// IFD has no Next-IFD pointer at end of IFD, and
																	// Offsets are relative to the start of the current IFD tag, not the TIFF header
																	// Observed for:
																	// - Pentax ist D
																	ProcessIFD(metadata.GetOrCreateDirectory<CasioType2MakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 6, makernoteOffset, metadata, reader);
																}
																else
																{
																	if (cameraMake != null && (cameraMake.ToUpper().StartsWith("PENTAX") || cameraMake.ToUpper().StartsWith("ASAHI")))
																	{
																		// NON-Standard TIFF IFD Data using Pentax Tags
																		// IFD has no Next-IFD pointer at end of IFD, and
																		// Offsets are relative to the start of the current IFD tag, not the TIFF header
																		// Observed for:
																		// - PENTAX Optio 330
																		// - PENTAX Optio 430
																		ProcessIFD(metadata.GetOrCreateDirectory<PentaxMakernoteDirectory>(), processedIfdOffsets, makernoteOffset, makernoteOffset, metadata, reader);
																	}
																	else
																	{
																		//        } else if ("KC".equals(firstTwoChars) || "MINOL".equals(firstFiveChars) || "MLY".equals(firstThreeChars) || "+M+M+M+M".equals(firstEightChars)) {
																		//            // This Konica data is not understood.  Header identified in accordance with information at this site:
																		//            // http://www.ozhiker.com/electronics/pjmt/jpeg_info/minolta_mn.html
																		//            // TODO add support for minolta/konica cameras
																		//            exifDirectory.addError("Unsupported Konica/Minolta data ignored.");
																		if ("SANYO\x0\x1\x0".Equals(firstEightChars))
																		{
																			ProcessIFD(metadata.GetOrCreateDirectory<SanyoMakernoteDirectory>(), processedIfdOffsets, makernoteOffset + 8, makernoteOffset, metadata, reader);
																		}
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			// The makernote is not comprehended by this library.
			// If you are reading this and believe a particular camera's image should be processed, get in touch.
			reader.SetMotorolaByteOrder(byteOrderBefore);
		}
Ejemplo n.º 7
0
		/// <exception cref="System.IO.IOException"/>
		private static void ProcessTag(TiffHandler handler, int tagId, int tagValueOffset, int componentCount, int formatCode, RandomAccessReader reader)
		{
			switch (formatCode)
			{
				case TiffDataFormat.CodeUndefined:
				{
					// this includes exif user comments
					handler.SetByteArray(tagId, reader.GetBytes(tagValueOffset, componentCount));
					break;
				}

				case TiffDataFormat.CodeString:
				{
					handler.SetString(tagId, reader.GetNullTerminatedString(tagValueOffset, componentCount));
					break;
				}

				case TiffDataFormat.CodeRationalS:
				{
					if (componentCount == 1)
					{
						handler.SetRational(tagId, new Rational(reader.GetInt32(tagValueOffset), reader.GetInt32(tagValueOffset + 4)));
					}
					else
					{
						if (componentCount > 1)
						{
							Rational[] array = new Rational[componentCount];
							for (int i = 0; i < componentCount; i++)
							{
								array[i] = new Rational(reader.GetInt32(tagValueOffset + (8 * i)), reader.GetInt32(tagValueOffset + 4 + (8 * i)));
							}
							handler.SetRationalArray(tagId, array);
						}
					}
					break;
				}

				case TiffDataFormat.CodeRationalU:
				{
					if (componentCount == 1)
					{
						handler.SetRational(tagId, new Rational(reader.GetUInt32(tagValueOffset), reader.GetUInt32(tagValueOffset + 4)));
					}
					else
					{
						if (componentCount > 1)
						{
							Rational[] array = new Rational[componentCount];
							for (int i = 0; i < componentCount; i++)
							{
								array[i] = new Rational(reader.GetUInt32(tagValueOffset + (8 * i)), reader.GetUInt32(tagValueOffset + 4 + (8 * i)));
							}
							handler.SetRationalArray(tagId, array);
						}
					}
					break;
				}

				case TiffDataFormat.CodeSingle:
				{
					if (componentCount == 1)
					{
						handler.SetFloat(tagId, reader.GetFloat32(tagValueOffset));
					}
					else
					{
						float[] array = new float[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetFloat32(tagValueOffset + (i * 4));
						}
						handler.SetFloatArray(tagId, array);
					}
					break;
				}

				case TiffDataFormat.CodeDouble:
				{
					if (componentCount == 1)
					{
						handler.SetDouble(tagId, reader.GetDouble64(tagValueOffset));
					}
					else
					{
						double[] array = new double[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetDouble64(tagValueOffset + (i * 4));
						}
						handler.SetDoubleArray(tagId, array);
					}
					break;
				}

				case TiffDataFormat.CodeInt8S:
				{
					if (componentCount == 1)
					{
						handler.SetInt8s(tagId, reader.GetInt8(tagValueOffset));
					}
					else
					{
						sbyte[] array = new sbyte[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetInt8(tagValueOffset + i);
						}
						handler.SetInt8sArray(tagId, array);
					}
					break;
				}

				case TiffDataFormat.CodeInt8U:
				{
					if (componentCount == 1)
					{
						handler.SetInt8u(tagId, reader.GetUInt8(tagValueOffset));
					}
					else
					{
						short[] array = new short[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetUInt8(tagValueOffset + i);
						}
						handler.SetInt8uArray(tagId, array);
					}
					break;
				}

				case TiffDataFormat.CodeInt16S:
				{
					if (componentCount == 1)
					{
						handler.SetInt16s(tagId, (int)reader.GetInt16(tagValueOffset));
					}
					else
					{
						short[] array = new short[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetInt16(tagValueOffset + (i * 2));
						}
						handler.SetInt16sArray(tagId, array);
					}
					break;
				}

				case TiffDataFormat.CodeInt16U:
				{
					if (componentCount == 1)
					{
						handler.SetInt16u(tagId, reader.GetUInt16(tagValueOffset));
					}
					else
					{
						int[] array = new int[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetUInt16(tagValueOffset + (i * 2));
						}
						handler.SetInt16uArray(tagId, array);
					}
					break;
				}

				case TiffDataFormat.CodeInt32S:
				{
					// NOTE 'long' in this case means 32 bit, not 64
					if (componentCount == 1)
					{
						handler.SetInt32s(tagId, reader.GetInt32(tagValueOffset));
					}
					else
					{
						int[] array = new int[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetInt32(tagValueOffset + (i * 4));
						}
						handler.SetInt32sArray(tagId, array);
					}
					break;
				}

				case TiffDataFormat.CodeInt32U:
				{
					// NOTE 'long' in this case means 32 bit, not 64
					if (componentCount == 1)
					{
						handler.SetInt32u(tagId, reader.GetUInt32(tagValueOffset));
					}
					else
					{
						long[] array = new long[componentCount];
						for (int i = 0; i < componentCount; i++)
						{
							array[i] = reader.GetUInt32(tagValueOffset + (i * 4));
						}
						handler.SetInt32uArray(tagId, array);
					}
					break;
				}

				default:
				{
					handler.Error(Sharpen.Extensions.StringFormat("Unknown format code %d for tag %d", formatCode, tagId));
					break;
				}
			}
		}