aboutsummaryrefslogtreecommitdiff
path: root/src/tiff_parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/tiff_parser.h')
-rw-r--r--src/tiff_parser.h172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/tiff_parser.h b/src/tiff_parser.h
new file mode 100644
index 0000000..087844d
--- /dev/null
+++ b/src/tiff_parser.h
@@ -0,0 +1,172 @@
+// Copyright 2015 Google Inc.
+//
+// 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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef PIEX_TIFF_PARSER_H_
+#define PIEX_TIFF_PARSER_H_
+
+#include <cstdint>
+#include <memory>
+#include <set>
+#include <vector>
+
+#include "src/piex_types.h"
+#include "src/tiff_directory/tiff_directory.h"
+
+namespace piex {
+
+// Specifies all tags that might be of interest to get the preview data.
+enum Tags {
+ kExifTagColorSpace = 0xA001,
+ kExifTagDateTimeOriginal = 0x9003,
+ kExifTagDefaultCropSize = 0xC620,
+ kExifTagExposureTime = 0x829a,
+ kExifTagFnumber = 0x829d,
+ kExifTagFocalLength = 0x920A,
+ kExifTagGps = 0x8825,
+ kExifTagHeight = 0xA003,
+ kExifTagIsoSpeed = 0x8827,
+ kExifTagMakernotes = 0x927C,
+ kExifTagWidth = 0xA002,
+ kGpsTagLatitudeRef = 1,
+ kGpsTagLatitude = 2,
+ kGpsTagLongitudeRef = 3,
+ kGpsTagLongitude = 4,
+ kGpsTagAltitudeRef = 5,
+ kGpsTagAltitude = 6,
+ kGpsTagTimeStamp = 7,
+ kGpsTagDateStamp = 29,
+ kOlymTagAspectFrame = 0x1113,
+ kOlymTagCameraSettings = 0x2020,
+ kOlymTagRawProcessing = 0x2040,
+ kPanaTagBottomBorder = 0x006,
+ kPanaTagIso = 0x0017,
+ kPanaTagJpegImage = 0x002E,
+ kPanaTagLeftBorder = 0x0005,
+ kPanaTagRightBorder = 0x007,
+ kPanaTagTopBorder = 0x0004,
+ kTiffTagArtist = 0x013B,
+ kTiffTagBitsPerSample = 0x0102,
+ kTiffTagCompression = 0x0103,
+ kTiffTagDateTime = 0x0132,
+ kTiffTagExifIfd = 0x8769,
+ kTiffTagImageDescription = 0x010E,
+ kTiffTagImageLength = 0x0101,
+ kTiffTagImageWidth = 0x0100,
+ kTiffTagJpegByteCount = 0x0202,
+ kTiffTagJpegOffset = 0x0201,
+ kTiffTagMake = 0x010F,
+ kTiffTagModel = 0x0110,
+ kTiffTagOrientation = 0x0112,
+ kTiffTagPhotometric = 0x0106,
+ kTiffTagPlanarConfig = 0x011C,
+ kTiffTagResolutionUnit = 0x0128,
+ kTiffTagRowsPerStrip = 0x0116,
+ kTiffTagSamplesPerPixel = 0x0115,
+ kTiffTagSoftware = 0x0131,
+ kTiffTagStripByteCounts = 0x0117,
+ kTiffTagStripOffsets = 0x0111,
+ kTiffTagSubIfd = 0x014A,
+ kTiffTagTileByteCounts = 0x0145,
+ kTiffTagTileLength = 0x0143,
+ kTiffTagTileOffsets = 0x0144,
+ kTiffTagTileWidth = 0x0142,
+ kTiffTagXresolution = 0x011A,
+ kTiffTagYresolution = 0x011B,
+};
+
+typedef std::set<Tags> TagSet;
+typedef std::vector<tiff_directory::TiffDirectory> IfdVector;
+
+struct TiffContent {
+ IfdVector tiff_directory;
+ std::unique_ptr<tiff_directory::TiffDirectory> exif_directory;
+ std::unique_ptr<tiff_directory::TiffDirectory> gps_directory;
+};
+
+// Reads 2 bytes, an unsigned 16bit from 'stream' at a certain 'offset'. The
+// bytes get swapped according to the desired endianness returning true on
+// success. Returns false when something is wrong.
+bool Get16u(StreamInterface* stream, const std::uint32_t offset,
+ const tiff_directory::Endian& endian, std::uint16_t* value);
+
+// Reads 4 bytes, an unsigned 32bit 'value' from 'stream' at a certain 'offset'.
+// The bytes get swapped according to the desired endianness returning true on
+// success. Returns false when something is wrong.
+bool Get32u(StreamInterface* stream, const std::uint32_t offset,
+ const tiff_directory::Endian& endian, std::uint32_t* value);
+
+// Retrieves a byte vector of size 'length' from 'stream' beginning at some
+// 'offset' reading the data in chunks of one MiB.
+// If 'error' is not set to kOk the returned value is invalid.
+std::vector<std::uint8_t> GetData(const size_t offset, const size_t length,
+ StreamInterface* stream, Error* error);
+
+// Retrieves the endianness of TIFF compliant data at 'tiff_offset' from
+// 'stream' returning true on success. Returns false if when something is wrong.
+bool GetEndianness(const std::uint32_t tiff_offset, StreamInterface* stream,
+ tiff_directory::Endian* endian);
+
+// Retrieves the width and height from the jpeg preview returning true on
+// success. Returns false when something is wrong.
+bool GetPreviewDimensions(const std::uint32_t jpeg_offset,
+ StreamInterface* stream, std::uint16_t* width,
+ std::uint16_t* height);
+
+// Parses through a Tiff IFD and writes all 'desired_tags' to a
+// 'tiff_directory'.
+// Sets 'error' to kFail if something with the Tiff data is wrong.
+Error ParseDirectory(const std::uint32_t tiff_offset,
+ const std::uint32_t ifd_offset,
+ const tiff_directory::Endian endian,
+ const TagSet& desired_tags, StreamInterface* stream,
+ tiff_directory::TiffDirectory* tiff_directory,
+ std::uint32_t* next_ifd_offset);
+
+// Enables us to parse through data that complies to the Tiff/EP specification.
+class TiffParser {
+ public:
+ // The caller owns 'stream' and is responsible to keep it alive while the
+ // TiffParser object is used.
+ explicit TiffParser(StreamInterface* stream);
+ TiffParser(StreamInterface* stream, const std::uint32_t offset);
+
+ // Runs over the Tiff IFD, Exif IFD and subIFDs to get the preview image data.
+ // Returns kFail if something with the Tiff tags is wrong.
+ Error GetPreviewImageData(const TiffContent& tiff_content,
+ PreviewImageData* image_metadata);
+
+ // Returns kFail if called more that once or something with the Tiff data is
+ // wrong.
+ Error Parse(const TagSet& desired_tags, const std::uint16_t max_number_ifds,
+ TiffContent* tiff_content);
+
+ private:
+ // Disallow copy and assignment.
+ TiffParser(const TiffParser&) = delete;
+ TiffParser& operator=(const TiffParser&) = delete;
+
+ Error ParseIfd(const std::uint32_t ifd_offset, const TagSet& desired_tags,
+ const std::uint16_t max_number_ifds,
+ IfdVector* tiff_directory);
+
+ StreamInterface* stream_ = nullptr;
+ std::uint32_t tiff_offset_ = 0;
+ tiff_directory::Endian endian_;
+};
+
+} // namespace piex
+
+#endif // PIEX_TIFF_PARSER_H_