EXIF.h (3086B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef mozilla_image_decoders_EXIF_h 7 #define mozilla_image_decoders_EXIF_h 8 9 #include <stdint.h> 10 #include "nsDebug.h" 11 12 #include "Orientation.h" 13 #include "mozilla/Maybe.h" 14 #include "mozilla/image/Resolution.h" 15 #include "mozilla/gfx/Point.h" 16 17 namespace mozilla::image { 18 19 enum class ByteOrder : uint8_t { Unknown, LittleEndian, BigEndian }; 20 21 struct EXIFData { 22 const Orientation orientation = Orientation(); 23 const Resolution resolution = Resolution(); 24 }; 25 26 struct ParsedEXIFData; 27 28 enum class ResolutionUnit : uint8_t { 29 Dpi, 30 Dpcm, 31 }; 32 33 class EXIFParser { 34 public: 35 // aExpectExifIdCode Determines whether to expect the leading "Exif\0\0". True 36 // for exif in jpeg, false for exif in png. 37 static EXIFData Parse(bool aExpectExifIdCode, const uint8_t* aData, 38 const uint32_t aLength, 39 const gfx::IntSize& aRealImageSize) { 40 EXIFParser parser(aExpectExifIdCode); 41 return parser.ParseEXIF(aData, aLength, aRealImageSize); 42 } 43 44 private: 45 explicit EXIFParser(bool aExpectExifIdCode) 46 : mStart(nullptr), 47 mCurrent(nullptr), 48 mLength(0), 49 mRemainingLength(0), 50 mByteOrder(ByteOrder::Unknown), 51 mExpectExifIdCode(aExpectExifIdCode) {} 52 53 EXIFData ParseEXIF(const uint8_t* aData, const uint32_t aLength, 54 const gfx::IntSize& aRealImageSize); 55 bool ParseEXIFHeader(); 56 bool ParseTIFFHeader(uint32_t& aIFD0OffsetOut); 57 58 void ParseIFD(ParsedEXIFData&, uint32_t aDepth = 0); 59 bool ParseOrientation(uint16_t aType, uint32_t aCount, Orientation&); 60 bool ParseResolution(uint16_t aType, uint32_t aCount, Maybe<float>&); 61 bool ParseResolutionUnit(uint16_t aType, uint32_t aCount, 62 Maybe<ResolutionUnit>&); 63 bool ParseDimension(uint16_t aType, uint32_t aCount, Maybe<uint32_t>&); 64 65 bool Initialize(const uint8_t* aData, const uint32_t aLength); 66 void Advance(const uint32_t aDistance); 67 void JumpTo(const uint32_t aOffset); 68 69 uint32_t CurrentOffset() const { return mCurrent - mStart; } 70 71 uint32_t TIFFHeaderStart() const; 72 73 class ScopedJump { 74 EXIFParser& mParser; 75 uint32_t mOldOffset; 76 77 public: 78 ScopedJump(EXIFParser& aParser, uint32_t aOffset) 79 : mParser(aParser), mOldOffset(aParser.CurrentOffset()) { 80 mParser.JumpTo(aOffset); 81 } 82 83 ~ScopedJump() { mParser.JumpTo(mOldOffset); } 84 }; 85 86 bool MatchString(const char* aString, const uint32_t aLength); 87 bool MatchUInt16(const uint16_t aValue); 88 bool ReadUInt16(uint16_t& aOut); 89 bool ReadUInt32(uint32_t& aOut); 90 bool ReadRational(float& aOut); 91 92 const uint8_t* mStart; 93 const uint8_t* mCurrent; 94 uint32_t mLength; 95 uint32_t mRemainingLength; 96 ByteOrder mByteOrder; 97 bool mExpectExifIdCode; 98 }; 99 100 } // namespace mozilla::image 101 102 #endif // mozilla_image_decoders_EXIF_h