36 const bool kLittleEndian =
false;
37 const uint8_t kSig[] = {
38 'A',
'p',
'p',
'l',
'e',
' ',
'i',
'O',
'S', 0, 0, 1,
'M',
'M',
40 if (!data || data->size() <
sizeof(kSig)) {
43 if (memcmp(data->data(), kSig,
sizeof(kSig)) != 0) {
54 bool hasMaker33 =
false;
55 bool hasMaker48 =
false;
58 for (uint32_t i = 0; i < ifd->getNumEntries(); ++i) {
59 switch (ifd->getEntryTag(i)) {
62 hasMaker33 = ifd->getEntrySignedRational(i, 1, &maker33);
67 hasMaker48 = ifd->getEntrySignedRational(i, 1, &maker48);
74 if (!hasMaker33 || !hasMaker48) {
79 if (maker48 <= 0.01f) {
80 stops = -20.0f * maker48 + 1.8f;
82 stops = -0.101f * maker48 + 1.601f;
85 if (maker48 <= 0.01f) {
86 stops = -70.0f * maker48 + 3.0f;
88 stops = -0.303f * maker48 + 2.303f;
91 *hdrHeadroom = std::pow(2.f, std::max(stops, 0.f));
96 bool littleEndian =
false;
97 uint32_t ifdOffset = 0;
102 parseIfd(ifdOffset, littleEndian,
true);
105void SkExifMetadata::parseIfd(uint32_t ifdOffset,
bool littleEndian,
bool isRoot) {
111 for (uint32_t i = 0; i < ifd->getNumEntries(); ++i) {
112 switch (ifd->getEntryTag(i)) {
115 if (!fOriginPresent && ifd->getEntryUnsignedShort(i, 1, &value)) {
118 fOriginPresent =
true;
124 if (!fHdrHeadroomPresent) {
125 if (
auto makerNoteData = ifd->getEntryUndefinedData(i)) {
132 uint32_t subIfdOffset = 0;
133 if (isRoot && ifd->getEntryUnsignedLong(i, 1, &subIfdOffset)) {
134 parseIfd(subIfdOffset, littleEndian,
false);
139 if (!fXResolutionPresent) {
140 fXResolutionPresent = ifd->getEntryUnsignedRational(i, 1, &fXResolutionValue);
144 if (!fYResolutionPresent) {
145 fYResolutionPresent = ifd->getEntryUnsignedRational(i, 1, &fYResolutionValue);
149 if (!fResolutionUnitPresent) {
150 fResolutionUnitPresent =
151 ifd->getEntryUnsignedShort(i, 1, &fResolutionUnitValue);
158 if (!fPixelXDimensionPresent) {
159 uint16_t value16 = 0;
160 if (ifd->getEntryUnsignedShort(i, 1, &value16)) {
161 fPixelXDimensionValue = value16;
162 fPixelXDimensionPresent =
true;
165 if (!fPixelXDimensionPresent) {
166 fPixelXDimensionPresent =
167 ifd->getEntryUnsignedLong(i, 1, &fPixelXDimensionValue);
171 if (!fPixelYDimensionPresent) {
172 uint16_t value16 = 0;
173 if (ifd->getEntryUnsignedShort(i, 1, &value16)) {
174 fPixelYDimensionValue = value16;
175 fPixelYDimensionPresent =
true;
178 if (!fPixelYDimensionPresent) {
179 fPixelYDimensionPresent =
180 ifd->getEntryUnsignedLong(i, 1, &fPixelYDimensionValue);
#define SkCodecPrintf(...)
static bool get_maker_note_hdr_headroom(sk_sp< SkData > data, float *hdrHeadroom)
constexpr uint16_t kOriginTag
constexpr uint16_t kResolutionUnitTag
constexpr uint16_t kYResolutionTag
constexpr uint16_t kSubIFDOffsetTag
constexpr uint16_t kMarkerNoteTag
constexpr uint16_t kPixelXDimensionTag
constexpr uint16_t kPixelYDimensionTag
constexpr uint16_t kXResolutionTag
static std::unique_ptr< SkTiffImageFileDirectory > MakeFromOffset(sk_sp< SkData > data, bool littleEndian, uint32_t ifdOffset)
static bool ParseHeader(const SkData *data, bool *outLittleEndian, uint32_t *outIfdOffset)