1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "box/item_info_box.h"
17
18 namespace OHOS {
19 namespace ImagePlugin {
ParseContentChildren(HeifStreamReader & reader,uint32_t & recursionCount)20 heif_error HeifIinfBox::ParseContentChildren(HeifStreamReader &reader, uint32_t &recursionCount)
21 {
22 recursionCount++;
23 if (recursionCount > MAX_RECURSION_COUNT) {
24 return heif_error_too_many_recursion;
25 }
26 ParseFullHeader(reader);
27 uint8_t boxVersion = GetVersion();
28 uint32_t entryCount = (boxVersion == HEIF_BOX_VERSION_ZERO) ? reader.Read16() : reader.Read32();
29 if (entryCount == 0) {
30 return heif_error_ok;
31 }
32 return ReadChildren(reader, recursionCount);
33 }
34
InferFullBoxVersion()35 void HeifIinfBox::InferFullBoxVersion()
36 {
37 SetVersion(children_.size() > 0xFFFF ? HEIF_BOX_VERSION_ONE : HEIF_BOX_VERSION_ZERO);
38 }
39
Write(HeifStreamWriter & writer) const40 heif_error HeifIinfBox::Write(HeifStreamWriter &writer) const
41 {
42 size_t boxStart = ReserveHeader(writer);
43 uint8_t boxVersion = GetVersion();
44 writer.Write(boxVersion > HEIF_BOX_VERSION_ZERO ? UINT32_BYTES_NUM : UINT16_BYTES_NUM, children_.size());
45 heif_error err = WriteChildren(writer);
46 WriteCalculatedHeader(writer, boxStart);
47 return err;
48 }
49
ParseContent(HeifStreamReader & reader)50 heif_error HeifInfeBox::ParseContent(HeifStreamReader &reader)
51 {
52 ParseFullHeader(reader);
53
54 uint8_t boxVersion = GetVersion();
55 if (boxVersion <= HEIF_BOX_VERSION_ONE) {
56 itemId_ = reader.Read16();
57 itemProtectionIndex_ = reader.Read16();
58 itemName_ = reader.ReadString();
59 contentType_ = reader.ReadString();
60 contentEncoding_ = reader.ReadString();
61 } else if (boxVersion >= HEIF_BOX_VERSION_TWO) {
62 isHidden_ = (GetFlags() & 0x01);
63 itemId_ = boxVersion == HEIF_BOX_VERSION_TWO ? reader.Read16() : reader.Read32();
64 itemProtectionIndex_ = reader.Read16();
65 uint32_t itemType = reader.Read32();
66 if (itemType != 0) {
67 itemType_ = code_to_fourcc(itemType);
68 }
69 itemName_ = reader.ReadString();
70 if (itemType == ITEM_TYPE_MIME) {
71 contentType_ = reader.ReadString();
72 contentEncoding_ = reader.ReadString();
73 } else if (itemType == ITEM_TYPE_URI) {
74 itemUriType_ = reader.ReadString();
75 }
76 }
77
78 return reader.GetError();
79 }
80
InferFullBoxVersion()81 void HeifInfeBox::InferFullBoxVersion()
82 {
83 uint8_t version = GetVersion();
84 if (isHidden_ || !itemType_.empty()) {
85 version = std::max(version, (uint8_t)HEIF_BOX_VERSION_TWO);
86 }
87 if (itemId_ > 0xFFFF) {
88 version = std::max(version, (uint8_t)HEIF_BOX_VERSION_THREE);
89 }
90 SetVersion(version);
91 }
92
SetHidden(bool hidden)93 void HeifInfeBox::SetHidden(bool hidden)
94 {
95 isHidden_ = hidden;
96 SetFlags(isHidden_ ? (GetFlags() | 0x01) : (GetFlags() & ~(0x00000001)));
97 }
98
Write(HeifStreamWriter & writer) const99 heif_error HeifInfeBox::Write(HeifStreamWriter &writer) const
100 {
101 size_t boxStart = ReserveHeader(writer);
102
103 uint8_t boxVersion = GetVersion();
104 if (boxVersion <= HEIF_BOX_VERSION_ONE) {
105 writer.Write16(itemId_);
106 writer.Write16(itemProtectionIndex_);
107
108 writer.Write(itemName_);
109 writer.Write(contentType_);
110 writer.Write(contentEncoding_);
111 }
112
113 if (boxVersion >= HEIF_BOX_VERSION_TWO) {
114 if (boxVersion == HEIF_BOX_VERSION_TWO) {
115 writer.Write16(itemId_);
116 } else if (boxVersion == HEIF_BOX_VERSION_THREE) {
117 writer.Write32(itemId_);
118 }
119
120 writer.Write16(itemProtectionIndex_);
121
122 if (itemType_.empty()) {
123 writer.Write32(0);
124 } else {
125 writer.Write32(fourcc_to_code(itemType_.c_str()));
126 }
127
128 writer.Write(itemName_);
129 if (itemType_ == "mime") {
130 writer.Write(contentType_);
131 writer.Write(contentEncoding_);
132 } else if (itemType_ == "uri ") {
133 writer.Write(itemUriType_);
134 }
135 }
136
137 WriteCalculatedHeader(writer, boxStart);
138 return heif_error_ok;
139 }
140
ParseContent(HeifStreamReader & reader)141 heif_error HeifPtimBox::ParseContent(HeifStreamReader &reader)
142 {
143 ParseFullHeader(reader);
144 uint8_t boxVersion = GetVersion();
145 itemId_ = boxVersion == HEIF_BOX_VERSION_ZERO ? reader.Read16() : reader.Read32();
146 return reader.GetError();
147 }
148
InferFullBoxVersion()149 void HeifPtimBox::InferFullBoxVersion()
150 {
151 SetVersion(itemId_ <= 0xFFFF ? HEIF_BOX_VERSION_ZERO : HEIF_BOX_VERSION_ONE);
152 }
153
Write(HeifStreamWriter & writer) const154 heif_error HeifPtimBox::Write(HeifStreamWriter &writer) const
155 {
156 size_t boxStart = ReserveHeader(writer);
157
158 if (GetVersion() == HEIF_BOX_VERSION_ZERO) {
159 writer.Write16(itemId_);
160 } else {
161 writer.Write32(itemId_);
162 }
163
164 WriteCalculatedHeader(writer, boxStart);
165 return heif_error_ok;
166 }
167 } // namespace ImagePlugin
168 } // namespace OHOS
169