/src/libultrahdr/lib/src/multipictureformat.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2023 The Android Open Source Project |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
5 | | * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
6 | | * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
7 | | * option. This file may not be copied, modified, or distributed |
8 | | * except according to those terms. |
9 | | */ |
10 | | |
11 | | #include "ultrahdr/multipictureformat.h" |
12 | | |
13 | | namespace ultrahdr { |
14 | 4.11k | size_t calculateMpfSize() { |
15 | 4.11k | return sizeof(kMpfSig) + // Signature |
16 | 4.11k | kMpEndianSize + // Endianness |
17 | 4.11k | sizeof(uint32_t) + // Index IFD Offset |
18 | 4.11k | sizeof(uint16_t) + // Tag count |
19 | 4.11k | kTagSerializedCount * kTagSize + // 3 tags at 12 bytes each |
20 | 4.11k | sizeof(uint32_t) + // Attribute IFD offset |
21 | 4.11k | kNumPictures * kMPEntrySize; // MP Entries for each image |
22 | 4.11k | } |
23 | | |
24 | | std::shared_ptr<DataStruct> generateMpf(size_t primary_image_size, size_t primary_image_offset, |
25 | | size_t secondary_image_size, |
26 | 2.05k | size_t secondary_image_offset) { |
27 | 2.05k | size_t mpf_size = calculateMpfSize(); |
28 | 2.05k | std::shared_ptr<DataStruct> dataStruct = std::make_shared<DataStruct>(mpf_size); |
29 | | |
30 | 2.05k | dataStruct->write(static_cast<const void*>(kMpfSig), sizeof(kMpfSig)); |
31 | 2.05k | #if USE_BIG_ENDIAN_IN_MPF |
32 | 2.05k | dataStruct->write(static_cast<const void*>(kMpBigEndian), kMpEndianSize); |
33 | | #else |
34 | | dataStruct->write(static_cast<const void*>(kMpLittleEndian), kMpEndianSize); |
35 | | #endif |
36 | | |
37 | | // Set the Index IFD offset be the position after the endianness value and this offset. |
38 | 2.05k | constexpr uint32_t indexIfdOffset = static_cast<uint16_t>(kMpEndianSize + sizeof(kMpfSig)); |
39 | 2.05k | dataStruct->write32(Endian_SwapBE32(indexIfdOffset)); |
40 | | |
41 | | // We will write 3 tags (version, number of images, MP entries). |
42 | 2.05k | dataStruct->write16(Endian_SwapBE16(kTagSerializedCount)); |
43 | | |
44 | | // Write the version tag. |
45 | 2.05k | dataStruct->write16(Endian_SwapBE16(kVersionTag)); |
46 | 2.05k | dataStruct->write16(Endian_SwapBE16(kVersionType)); |
47 | 2.05k | dataStruct->write32(Endian_SwapBE32(kVersionCount)); |
48 | 2.05k | dataStruct->write(kVersionExpected, kVersionSize); |
49 | | |
50 | | // Write the number of images. |
51 | 2.05k | dataStruct->write16(Endian_SwapBE16(kNumberOfImagesTag)); |
52 | 2.05k | dataStruct->write16(Endian_SwapBE16(kNumberOfImagesType)); |
53 | 2.05k | dataStruct->write32(Endian_SwapBE32(kNumberOfImagesCount)); |
54 | 2.05k | dataStruct->write32(Endian_SwapBE32(kNumPictures)); |
55 | | |
56 | | // Write the MP entries. |
57 | 2.05k | dataStruct->write16(Endian_SwapBE16(kMPEntryTag)); |
58 | 2.05k | dataStruct->write16(Endian_SwapBE16(kMPEntryType)); |
59 | 2.05k | dataStruct->write32(Endian_SwapBE32(kMPEntrySize * kNumPictures)); |
60 | 2.05k | const uint32_t mpEntryOffset = |
61 | 2.05k | static_cast<uint32_t>(dataStruct->getBytesWritten() - // The bytes written so far |
62 | 2.05k | sizeof(kMpfSig) + // Excluding the MPF signature |
63 | 2.05k | sizeof(uint32_t) + // The 4 bytes for this offset |
64 | 2.05k | sizeof(uint32_t)); // The 4 bytes for the attribute IFD offset. |
65 | 2.05k | dataStruct->write32(Endian_SwapBE32(mpEntryOffset)); |
66 | | |
67 | | // Write the attribute IFD offset (zero because we don't write it). |
68 | 2.05k | dataStruct->write32(0); |
69 | | |
70 | | // Write the MP entries for primary image |
71 | 2.05k | dataStruct->write32(Endian_SwapBE32(kMPEntryAttributeFormatJpeg | kMPEntryAttributeTypePrimary)); |
72 | 2.05k | dataStruct->write32(Endian_SwapBE32(primary_image_size)); |
73 | 2.05k | dataStruct->write32(Endian_SwapBE32(primary_image_offset)); |
74 | 2.05k | dataStruct->write16(0); |
75 | 2.05k | dataStruct->write16(0); |
76 | | |
77 | | // Write the MP entries for secondary image |
78 | 2.05k | dataStruct->write32(Endian_SwapBE32(kMPEntryAttributeFormatJpeg)); |
79 | 2.05k | dataStruct->write32(Endian_SwapBE32(secondary_image_size)); |
80 | 2.05k | dataStruct->write32(Endian_SwapBE32(secondary_image_offset)); |
81 | 2.05k | dataStruct->write16(0); |
82 | 2.05k | dataStruct->write16(0); |
83 | | |
84 | 2.05k | return dataStruct; |
85 | 2.05k | } |
86 | | |
87 | | } // namespace ultrahdr |