Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/codec/SkTiffUtility.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2023 Google Inc.
3
 *
4
 * Use of this source code is governed by a BSD-style license that can be
5
 * found in the LICENSE file.
6
 */
7
8
#ifndef SkTiffUtility_codec_DEFINED
9
#define SkTiffUtility_codec_DEFINED
10
11
#include "include/core/SkData.h"
12
#include "include/core/SkRefCnt.h"
13
14
#include <cstddef>
15
#include <cstdint>
16
#include <memory>
17
18
/*
19
 * Helper function for parsing a Tiff Image File Directory (IFD) structure. This structure is used
20
 * by EXIF tags, multi-picture, and maker note metadata.
21
 */
22
class SkTiffImageFileDirectory {
23
public:
24
    /*
25
     * Parse |data| to read the endian-ness into |outLittleEndian| and the IFD offset into
26
     * |outIfdOffset|. Return true if the endian-ness was successfully parsed and there was
27
     * the IFD offset was read.
28
     */
29
    static bool ParseHeader(const SkData* data, bool* outLittleEndian, uint32_t* outIfdOffset);
30
31
    /*
32
     * Create an object for parsing an IFD at offset |ifdOffset| inside |data| which has endianness
33
     * indicated by |littleEndian|.
34
     */
35
    static std::unique_ptr<SkTiffImageFileDirectory> MakeFromOffset(sk_sp<SkData> data,
36
                                                                    bool littleEndian,
37
                                                                    uint32_t ifdOffset);
38
39
    /*
40
     * Return the number of entries.
41
     */
42
267k
    uint16_t getNumEntries() const { return fNumEntries; }
43
44
    /*
45
     * Return the offset (within the specified SkData) of the next IFD in the list of IFDs.
46
     */
47
0
    uint32_t nextIfdOffset() const { return fNextIfdOffset; }
48
49
    /*
50
     * Return the tag, of a specific entry.
51
     */
52
    uint16_t getEntryTag(uint16_t entryIndex) const;
53
54
    /*
55
     * If |entryIndex| has type unsigned short (3), unsigned long (4), or signed rational (10), and
56
     * count |count|, then populate |values| with the data for the tag and return true. Otherwise
57
     * return false.
58
     */
59
6.89k
    bool getEntryUnsignedShort(uint16_t entryIndex, uint32_t count, uint16_t* values) const {
60
6.89k
        return getEntryValuesGeneric(entryIndex, kTypeUnsignedShort, count, values);
61
6.89k
    }
62
7.44k
    bool getEntryUnsignedLong(uint16_t entryIndex, uint32_t count, uint32_t* values) const {
63
7.44k
        return getEntryValuesGeneric(entryIndex, kTypeUnsignedLong, count, values);
64
7.44k
    }
65
288
    bool getEntrySignedRational(uint16_t entryIndex, uint32_t count, float* values) const {
66
288
        return getEntryValuesGeneric(entryIndex, kTypeSignedRational, count, values);
67
288
    }
68
1.71k
    bool getEntryUnsignedRational(uint16_t entryIndex, uint32_t count, float* values) const {
69
1.71k
        return getEntryValuesGeneric(entryIndex, kTypeUnsignedRational, count, values);
70
1.71k
    }
71
72
    /*
73
     * If |entryIndex| has type undefined (7), then return the bytes specified by the count field
74
     * and the offset (read from the value field as an unsigned long).
75
     */
76
    sk_sp<SkData> getEntryUndefinedData(uint16_t entryIndex) const;
77
78
private:
79
    static constexpr uint16_t kTypeUnsignedByte = 1;
80
    static constexpr uint16_t kTypeAsciiString = 2;
81
    static constexpr uint16_t kTypeUnsignedShort = 3;
82
    static constexpr uint16_t kTypeUnsignedLong = 4;
83
    static constexpr uint16_t kTypeUnsignedRational = 5;
84
    static constexpr uint16_t kTypeSignedByte = 6;
85
    static constexpr uint16_t kTypeUndefined = 7;
86
    static constexpr uint16_t kTypeSignedShort = 8;
87
    static constexpr uint16_t kTypeSignedLong = 9;
88
    static constexpr uint16_t kTypeSignedRational = 10;
89
    static constexpr uint16_t kTypeSingleFloat = 11;
90
    static constexpr uint16_t kTypeDoubleFloat = 12;
91
92
    static bool IsValidType(uint16_t type);
93
    static size_t BytesForType(uint16_t type);
94
95
    SkTiffImageFileDirectory(sk_sp<SkData> data,
96
                             bool littleEndian,
97
                             uint32_t offset,
98
                             uint16_t ifdNumEntries,
99
                             uint32_t ifdNextOffset);
100
101
    /*
102
     * Return the tag, type, count, and data for the specified entry. Return false if the type
103
     * is invalid, or if the data in the IFD is out of bounds.
104
     */
105
    bool getEntryRawData(uint16_t entryIndex,
106
                         uint16_t* outTag,
107
                         uint16_t* outType,
108
                         uint32_t* outCount,
109
                         const uint8_t** outData,
110
                         size_t* outDataSize) const;
111
112
    /*
113
     * Helper function for assorted getTag functions.
114
     */
115
    bool getEntryValuesGeneric(uint16_t entryIndex,
116
                               uint16_t type,
117
                               uint32_t count,
118
                               void* values) const;
119
120
    // The data that the IFD indexes into.
121
    const sk_sp<SkData> fData;
122
123
    // True if the data is little endian.
124
    const bool fLittleEndian;
125
126
    // The offset where the IFD starts.
127
    const uint32_t fOffset;
128
129
    // The number of entries of the IFD (read from the first 2 bytes at the IFD offset).
130
    const uint16_t fNumEntries;
131
132
    // The offset of the next IFD (read from the next 4 bytes after the IFD entries).
133
    const uint32_t fNextIfdOffset;
134
};
135
136
#endif