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: Parse(const uint8_t * aData,const uint32_t aLength,const gfx::IntSize & aRealImageSize)35 static EXIFData Parse(const uint8_t* aData, const uint32_t aLength, 36 const gfx::IntSize& aRealImageSize) { 37 EXIFParser parser; 38 return parser.ParseEXIF(aData, aLength, aRealImageSize); 39 } 40 41 private: EXIFParser()42 EXIFParser() 43 : mStart(nullptr), 44 mCurrent(nullptr), 45 mLength(0), 46 mRemainingLength(0), 47 mByteOrder(ByteOrder::Unknown) {} 48 49 EXIFData ParseEXIF(const uint8_t* aData, const uint32_t aLength, 50 const gfx::IntSize& aRealImageSize); 51 bool ParseEXIFHeader(); 52 bool ParseTIFFHeader(uint32_t& aIFD0OffsetOut); 53 54 void ParseIFD(ParsedEXIFData&, uint32_t aDepth = 0); 55 bool ParseOrientation(uint16_t aType, uint32_t aCount, Orientation&); 56 bool ParseResolution(uint16_t aType, uint32_t aCount, Maybe<float>&); 57 bool ParseResolutionUnit(uint16_t aType, uint32_t aCount, 58 Maybe<ResolutionUnit>&); 59 bool ParseDimension(uint16_t aType, uint32_t aCount, Maybe<uint32_t>&); 60 61 bool Initialize(const uint8_t* aData, const uint32_t aLength); 62 void Advance(const uint32_t aDistance); 63 void JumpTo(const uint32_t aOffset); 64 CurrentOffset()65 uint32_t CurrentOffset() const { return mCurrent - mStart; } 66 67 class ScopedJump { 68 EXIFParser& mParser; 69 uint32_t mOldOffset; 70 71 public: ScopedJump(EXIFParser & aParser,uint32_t aOffset)72 ScopedJump(EXIFParser& aParser, uint32_t aOffset) 73 : mParser(aParser), mOldOffset(aParser.CurrentOffset()) { 74 mParser.JumpTo(aOffset); 75 } 76 ~ScopedJump()77 ~ScopedJump() { mParser.JumpTo(mOldOffset); } 78 }; 79 80 bool MatchString(const char* aString, const uint32_t aLength); 81 bool MatchUInt16(const uint16_t aValue); 82 bool ReadUInt16(uint16_t& aOut); 83 bool ReadUInt32(uint32_t& aOut); 84 bool ReadRational(float& aOut); 85 86 const uint8_t* mStart; 87 const uint8_t* mCurrent; 88 uint32_t mLength; 89 uint32_t mRemainingLength; 90 ByteOrder mByteOrder; 91 }; 92 93 } // namespace mozilla::image 94 95 #endif // mozilla_image_decoders_EXIF_h 96