public override void Completed(RandomAccessReader reader, int tiffHeaderOffset) { if (_storeThumbnailBytes) { // after the extraction process, if we have the correct tags, we may be able to store thumbnail information ExifThumbnailDirectory thumbnailDirectory = _metadata.GetDirectory <ExifThumbnailDirectory>(); if (thumbnailDirectory != null && thumbnailDirectory.ContainsTag(ExifThumbnailDirectory.TagThumbnailCompression)) { int?offset = thumbnailDirectory.GetInteger(ExifThumbnailDirectory.TagThumbnailOffset); int?length = thumbnailDirectory.GetInteger(ExifThumbnailDirectory.TagThumbnailLength); if (offset != null && length != null) { try { sbyte[] thumbnailData = reader.GetBytes(tiffHeaderOffset + offset.Value, length.Value); thumbnailDirectory.SetThumbnailData(thumbnailData); } catch (IOException ex) { thumbnailDirectory.AddError("Invalid thumbnail data specification: " + ex.Message); } } } } }
private static void ExtractTiff(RandomAccessReader reader, Com.Drew.Metadata.Metadata metadata, Com.Drew.Metadata.Directory firstDirectory, int tiffHeaderOffset) { // this should be either "MM" or "II" string byteOrderIdentifier = reader.GetString(tiffHeaderOffset, 2); if ("MM".Equals(byteOrderIdentifier)) { reader.SetMotorolaByteOrder(true); } else { if ("II".Equals(byteOrderIdentifier)) { reader.SetMotorolaByteOrder(false); } else { firstDirectory.AddError("Unclear distinction between Motorola/Intel byte ordering: " + byteOrderIdentifier); return; } } // Check the next two values for correctness. int tiffMarker = reader.GetUInt16(2 + tiffHeaderOffset); int standardTiffMarker = unchecked ((int)(0x002A)); int olympusRawTiffMarker = unchecked ((int)(0x4F52)); // for ORF files int panasonicRawTiffMarker = unchecked ((int)(0x0055)); // for RW2 files if (tiffMarker != standardTiffMarker && tiffMarker != olympusRawTiffMarker && tiffMarker != panasonicRawTiffMarker) { firstDirectory.AddError("Unexpected TIFF marker after byte order identifier: 0x" + Sharpen.Extensions.ToHexString(tiffMarker)); return; } int firstIfdOffset = reader.GetInt32(4 + tiffHeaderOffset) + tiffHeaderOffset; // David Ekholm sent a digital camera image that has this problem // TODO getLength should be avoided as it causes RandomAccessStreamReader to read to the end of the stream if (firstIfdOffset >= reader.GetLength() - 1) { firstDirectory.AddError("First Exif directory offset is beyond end of Exif data segment"); // First directory normally starts 14 bytes in -- try it here and catch another error in the worst case firstIfdOffset = 14; } ICollection <int> processedIfdOffsets = new HashSet <int>(); ProcessIFD(firstDirectory, processedIfdOffsets, firstIfdOffset, tiffHeaderOffset, metadata, reader); // after the extraction process, if we have the correct tags, we may be able to store thumbnail information ExifThumbnailDirectory thumbnailDirectory = metadata.GetDirectory <ExifThumbnailDirectory>(); if (thumbnailDirectory != null && thumbnailDirectory.ContainsTag(ExifThumbnailDirectory.TagThumbnailCompression)) { int?offset = thumbnailDirectory.GetInteger(ExifThumbnailDirectory.TagThumbnailOffset); int?length = thumbnailDirectory.GetInteger(ExifThumbnailDirectory.TagThumbnailLength); if (offset != null && length != null) { try { sbyte[] thumbnailData = reader.GetBytes(tiffHeaderOffset + offset.Value, length.Value); thumbnailDirectory.SetThumbnailData(thumbnailData); } catch (IOException ex) { firstDirectory.AddError("Invalid thumbnail data specification: " + ex.Message); } } } }