• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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_movie_box.h"
17 
18 #include <algorithm>
19 
20 namespace {
21     const uint32_t MVHD_MATRIX_OFFSET = 9;
22     const uint32_t MVHD_PREDEFINED_OFFSET = 6;
23     const uint32_t TKHD_MATRIX_OFFSET = 9;
24     const uint32_t VMHD_OPCOLOR_OFFSET = 3;
25     const uint32_t HVC1_RESERVED_OFFSET = 8;
26     const uint32_t HVC1_PREDEFINE_OFFSET = 16;
27     const uint32_t HVC1_SKIP_OFFSET = 50;
28 }
29 
30 namespace OHOS {
31 namespace ImagePlugin {
ParseContentChildren(HeifStreamReader & reader,uint32_t & recursionCount)32 heif_error HeifMoovBox::ParseContentChildren(HeifStreamReader &reader, uint32_t &recursionCount)
33 {
34     return ParseContentChildrenByReadChildren(reader, recursionCount);
35 }
36 
ParseContent(HeifStreamReader & reader)37 heif_error HeifMvhdBox::ParseContent(HeifStreamReader &reader)
38 {
39     ParseFullHeader(reader);
40     if (GetVersion() == HEIF_BOX_VERSION_ONE) {
41         creationTime_ = reader.Read64();
42         modificationTime_ = reader.Read64();
43         timescale_ = reader.Read32();
44         duration_ = reader.Read32();
45     } else {
46         creationTime_ = reader.Read32();
47         modificationTime_ = reader.Read32();
48         timescale_ = reader.Read32();
49         duration_ = reader.Read32();
50     }
51     rate_ = reader.Read32();
52     volume_ = reader.Read16();
53     reserved_ = reader.Read16();
54     reserved2_[0] = reader.Read32();
55     reserved2_[1] = reader.Read32();
56     for (int i = 0; i < MVHD_MATRIX_OFFSET; i++) {
57         matrix_[i] = reader.Read32();
58     }
59     for (int i = 0; i < MVHD_PREDEFINED_OFFSET; i++) {
60         preDefined_[i] = reader.Read32();
61     }
62     nextTrackId_ = reader.Read32();
63     return reader.GetError();
64 }
65 
Write(HeifStreamWriter & writer) const66 heif_error HeifMvhdBox::Write(HeifStreamWriter &writer) const
67 {
68     size_t boxStart = ReserveHeader(writer);
69     if (GetVersion() == HEIF_BOX_VERSION_ONE) {
70         writer.Write64(creationTime_);
71         writer.Write64(modificationTime_);
72         writer.Write32(timescale_);
73         writer.Write64(duration_);
74     } else {
75         writer.Write32(creationTime_);
76         writer.Write32(modificationTime_);
77         writer.Write32(timescale_);
78         writer.Write32(duration_);
79     }
80     writer.Write32(rate_);
81     writer.Write16(volume_);
82     writer.Write16(reserved_);
83     writer.Write32(reserved2_[0]);
84     writer.Write32(reserved2_[1]);
85     for (int i = 0; i < MVHD_MATRIX_OFFSET; i++) {
86         writer.Write32(matrix_[i]);
87     }
88     for (int i = 0; i < MVHD_PREDEFINED_OFFSET; i++) {
89         writer.Write32(preDefined_[i]);
90     }
91     writer.Write32(nextTrackId_);
92     WriteCalculatedHeader(writer, boxStart);
93     return heif_error_ok;
94 }
95 
ParseContentChildren(HeifStreamReader & reader,uint32_t & recursionCount)96 heif_error HeifTrakBox::ParseContentChildren(HeifStreamReader &reader, uint32_t &recursionCount)
97 {
98     return ParseContentChildrenByReadChildren(reader, recursionCount);
99 }
100 
ParseContent(HeifStreamReader & reader)101 heif_error HeifTkhdBox::ParseContent(HeifStreamReader &reader)
102 {
103     ParseFullHeader(reader);
104     if (GetVersion() == HEIF_BOX_VERSION_ONE) {
105         creationTime_ = reader.Read64();
106         modificationTime_ = reader.Read64();
107         trackId_ = reader.Read32();
108         reserved1_ = reader.Read32();
109         duration_ = reader.Read64();
110     } else {
111         creationTime_ = reader.Read32();
112         modificationTime_ = reader.Read32();
113         trackId_ = reader.Read32();
114         reserved1_ = reader.Read32();
115         duration_ = reader.Read32();
116     }
117     reserved2_[0] = reader.Read32();
118     reserved2_[1] = reader.Read32();
119     layer_ = reader.Read16();
120     alternateGroup_ = reader.Read16();
121     volume_ = reader.Read16();
122     reserved3_ = reader.Read16();
123     for (int i = 0; i < TKHD_MATRIX_OFFSET; i++) {
124         matrix_[i] = reader.Read32();
125     }
126     width_ = reader.Read32();
127     height_ = reader.Read32();
128     return reader.GetError();
129 }
130 
Write(HeifStreamWriter & writer) const131 heif_error HeifTkhdBox::Write(HeifStreamWriter &writer) const
132 {
133     size_t boxStart = ReserveHeader(writer);
134     if (GetVersion() == HEIF_BOX_VERSION_ONE) {
135         writer.Write64(creationTime_);
136         writer.Write64(modificationTime_);
137         writer.Write32(trackId_);
138         writer.Write32(reserved1_);
139         writer.Write64(duration_);
140     } else {
141         writer.Write32(creationTime_);
142         writer.Write32(modificationTime_);
143         writer.Write32(trackId_);
144         writer.Write32(reserved1_);
145         writer.Write32(duration_);
146     }
147     writer.Write32(reserved2_[0]);
148     writer.Write32(reserved2_[1]);
149     writer.Write16(layer_);
150     writer.Write16(alternateGroup_);
151     writer.Write16(volume_);
152     writer.Write16(reserved3_);
153     for (int i = 0; i < TKHD_MATRIX_OFFSET; i++) {
154         writer.Write32(matrix_[i]);
155     }
156     writer.Write32(width_);
157     writer.Write32(height_);
158 
159     WriteCalculatedHeader(writer, boxStart);
160     return heif_error_ok;
161 }
162 
ParseContentChildren(HeifStreamReader & reader,uint32_t & recursionCount)163 heif_error HeifMdiaBox::ParseContentChildren(HeifStreamReader &reader, uint32_t &recursionCount)
164 {
165     return ParseContentChildrenByReadChildren(reader, recursionCount);
166 }
167 
ParseContent(HeifStreamReader & reader)168 heif_error HeifMdhdBox::ParseContent(HeifStreamReader &reader)
169 {
170     ParseFullHeader(reader);
171     if (GetVersion() == HEIF_BOX_VERSION_ONE) {
172         creationTime_ = reader.Read64();
173         modificationTime_ = reader.Read64();
174         timescale_ = reader.Read32();
175         duration_ = reader.Read64();
176     } else {
177         creationTime_ = reader.Read32();
178         modificationTime_ = reader.Read32();
179         timescale_ = reader.Read32();
180         duration_ = reader.Read32();
181     }
182     language_ = reader.Read16();
183     preDefined_ = reader.Read16();
184     return reader.GetError();
185 }
186 
Write(HeifStreamWriter & writer) const187 heif_error HeifMdhdBox::Write(HeifStreamWriter &writer) const
188 {
189     size_t boxStart = ReserveHeader(writer);
190     if (GetVersion() == HEIF_BOX_VERSION_ONE) {
191         writer.Write64(creationTime_);
192         writer.Write64(modificationTime_);
193         writer.Write32(timescale_);
194         writer.Write64(duration_);
195     } else {
196         writer.Write32(creationTime_);
197         writer.Write32(modificationTime_);
198         writer.Write32(timescale_);
199         writer.Write32(duration_);
200     }
201     writer.Write16(language_);
202     writer.Write16(preDefined_);
203     WriteCalculatedHeader(writer, boxStart);
204     return heif_error_ok;
205 }
206 
ParseContentChildren(HeifStreamReader & reader,uint32_t & recursionCount)207 heif_error HeifMinfBox::ParseContentChildren(HeifStreamReader &reader, uint32_t &recursionCount)
208 {
209     return ParseContentChildrenByReadChildren(reader, recursionCount);
210 }
211 
ParseContent(HeifStreamReader & reader)212 heif_error HeifVmhdBox::ParseContent(HeifStreamReader &reader)
213 {
214     ParseFullHeader(reader);
215     graphicsMode_ = reader.Read16();
216     for (int i = 0; i < VMHD_OPCOLOR_OFFSET; i++) {
217         opColor_[i] = reader.Read16();
218     }
219     return reader.GetError();
220 }
221 
Write(HeifStreamWriter & writer) const222 heif_error HeifVmhdBox::Write(HeifStreamWriter &writer) const
223 {
224     size_t boxStart = ReserveHeader(writer);
225     writer.Write16(graphicsMode_);
226     for (int i = 0; i < VMHD_OPCOLOR_OFFSET; i++) {
227         writer.Write16(opColor_[i]);
228     }
229     WriteCalculatedHeader(writer, boxStart);
230     return heif_error_ok;
231 }
232 
ParseContentChildren(HeifStreamReader & reader,uint32_t & recursionCount)233 heif_error HeifDinfBox::ParseContentChildren(HeifStreamReader &reader, uint32_t &recursionCount)
234 {
235     return ParseContentChildrenByReadChildren(reader, recursionCount);
236 }
237 
ParseContent(HeifStreamReader & reader)238 heif_error HeifDrefBox::ParseContent(HeifStreamReader &reader)
239 {
240     ParseFullHeader(reader);
241     entryCount_ = reader.Read32();
242     for (uint32_t i = 0; i < entryCount_; i++) {
243         uint32_t recursionCount = 0;
244         std::shared_ptr<HeifBox> entry;
245         heif_error error = HeifBox::MakeFromReader(reader, &entry, recursionCount);
246         if (error != heif_error_ok) {
247             return error;
248         }
249         entries_.push_back(entry);
250     }
251     return reader.GetError();
252 }
253 
Write(HeifStreamWriter & writer) const254 heif_error HeifDrefBox::Write(HeifStreamWriter &writer) const
255 {
256     size_t boxStart = ReserveHeader(writer);
257     writer.Write32(entryCount_);
258     for (const auto& entry : entries_) {
259         entry->Write(writer);
260     }
261     WriteCalculatedHeader(writer, boxStart);
262     return heif_error_ok;
263 }
264 
ParseContentChildren(HeifStreamReader & reader,uint32_t & recursionCount)265 heif_error HeifStblBox::ParseContentChildren(HeifStreamReader &reader, uint32_t &recursionCount)
266 {
267     return ParseContentChildrenByReadChildren(reader, recursionCount);
268 }
269 
ParseContent(HeifStreamReader & reader)270 heif_error HeifStsdBox::ParseContent(HeifStreamReader &reader)
271 {
272     ParseFullHeader(reader);
273     entryCount_ = reader.Read32();
274     for (uint32_t i = 0; i < entryCount_; i++) {
275         uint32_t recursionCount = 0;
276         std::shared_ptr<HeifBox> entry;
277         heif_error error = HeifBox::MakeFromReader(reader, &entry, recursionCount);
278         if (error != heif_error_ok) {
279             return error;
280         }
281         entries_.push_back(entry);
282     }
283     return reader.GetError();
284 }
285 
GetSampleEntryWidthHeight(uint32_t index,uint32_t & width,uint32_t & height)286 heif_error HeifStsdBox::GetSampleEntryWidthHeight(uint32_t index, uint32_t &width, uint32_t &height)
287 {
288     if (index >= entries_.size()) {
289         return heif_error_invalid_index;
290     }
291     if (entries_[index] && entries_[index]->GetBoxType() == BOX_TYPE_HVC1) {
292         auto hvc1Entry = std::dynamic_pointer_cast<HeifHvc1Box>(entries_[index]);
293         width = hvc1Entry->GetWidth();
294         height = hvc1Entry->GetHeight();
295     }
296     return heif_error_ok;
297 }
298 
GetHvccBox(uint32_t index)299 std::shared_ptr<HeifBox> HeifStsdBox::GetHvccBox(uint32_t index)
300 {
301     if (index >= entries_.size()) {
302         return nullptr;
303     }
304     if (entries_[index] && entries_[index]->GetBoxType() == BOX_TYPE_HVC1) {
305         auto hvc1Entry = std::dynamic_pointer_cast<HeifHvc1Box>(entries_[index]);
306         return hvc1Entry->GetHvccBox();
307     }
308     return nullptr;
309 }
310 
Write(HeifStreamWriter & writer) const311 heif_error HeifStsdBox::Write(HeifStreamWriter &writer) const
312 {
313     size_t boxStart = ReserveHeader(writer);
314     writer.Write32(entryCount_);
315     for (const auto& entry : entries_) {
316         entry->Write(writer);
317     }
318     WriteCalculatedHeader(writer, boxStart);
319     return heif_error_ok;
320 }
321 
ParseContent(HeifStreamReader & reader)322 heif_error HeifSttsBox::ParseContent(HeifStreamReader &reader)
323 {
324     ParseFullHeader(reader);
325     entryCount_ = reader.Read32();
326     for (uint32_t i = 0; i < entryCount_; i++) {
327         TimeToSampleEntry entry;
328         entry.sampleCount = reader.Read32();
329         entry.sampleDelta = reader.Read32();
330         entries_.push_back(entry);
331     }
332     return reader.GetError();
333 }
334 
Write(HeifStreamWriter & writer) const335 heif_error HeifSttsBox::Write(HeifStreamWriter &writer) const
336 {
337     size_t boxStart = ReserveHeader(writer);
338     writer.Write32(entryCount_);
339     for (const auto& entry : entries_) {
340         writer.Write32(entry.sampleCount);
341         writer.Write32(entry.sampleDelta);
342     }
343     WriteCalculatedHeader(writer, boxStart);
344     return heif_error_ok;
345 }
346 
ParseContent(HeifStreamReader & reader)347 heif_error HeifStscBox::ParseContent(HeifStreamReader &reader)
348 {
349     ParseFullHeader(reader);
350     entryCount_ = reader.Read32();
351     for (uint32_t i = 0; i < entryCount_; i++) {
352         SampleToChunkEntry entry;
353         entry.firstChunk = reader.Read32();
354         entry.samplesPerChunk = reader.Read32();
355         entry.sampleDescriptionIndex = reader.Read32();
356         entries_.push_back(entry);
357     }
358     return reader.GetError();
359 }
360 
Write(HeifStreamWriter & writer) const361 heif_error HeifStscBox::Write(HeifStreamWriter &writer) const
362 {
363     size_t boxStart = ReserveHeader(writer);
364     writer.Write32(entryCount_);
365     for (const auto& entry : entries_) {
366         writer.Write32(entry.firstChunk);
367         writer.Write32(entry.samplesPerChunk);
368         writer.Write32(entry.sampleDescriptionIndex);
369     }
370     WriteCalculatedHeader(writer, boxStart);
371     return heif_error_ok;
372 }
373 
ParseContent(HeifStreamReader & reader)374 heif_error HeifStcoBox::ParseContent(HeifStreamReader &reader)
375 {
376     ParseFullHeader(reader);
377     entryCount_ = reader.Read32();
378     for (uint32_t i = 0; i < entryCount_; i++) {
379         chunkOffsets_.push_back(reader.Read32());
380     }
381     return reader.GetError();
382 }
383 
GetChunkOffset(uint32_t chunkIndex,uint32_t & chunkOffset)384 heif_error HeifStcoBox::GetChunkOffset(uint32_t chunkIndex, uint32_t &chunkOffset)
385 {
386     if (chunkIndex >= chunkOffsets_.size()) {
387         return heif_error_invalid_index;
388     }
389     chunkOffset = chunkOffsets_[chunkIndex];
390     return heif_error_ok;
391 }
392 
Write(HeifStreamWriter & writer) const393 heif_error HeifStcoBox::Write(HeifStreamWriter &writer) const
394 {
395     size_t boxStart = ReserveHeader(writer);
396     writer.Write32(entryCount_);
397     for (uint32_t offset : chunkOffsets_) {
398         writer.Write32(offset);
399     }
400     WriteCalculatedHeader(writer, boxStart);
401     return heif_error_ok;
402 }
403 
ParseContent(HeifStreamReader & reader)404 heif_error HeifStszBox::ParseContent(HeifStreamReader &reader)
405 {
406     ParseFullHeader(reader);
407     sampleSize_ = reader.Read32();
408     sampleCount_ = reader.Read32();
409     if (sampleSize_ == 0) {
410         for (uint32_t i = 0; i < sampleCount_; i++) {
411             entrySizes_.push_back(reader.Read32());
412         }
413     }
414     return reader.GetError();
415 }
416 
GetSampleSize(uint32_t sampleIndex,uint32_t & sampleSize)417 heif_error HeifStszBox::GetSampleSize(uint32_t sampleIndex, uint32_t &sampleSize)
418 {
419     if (sampleIndex >= entrySizes_.size()) {
420         return heif_error_invalid_index;
421     }
422     sampleSize = entrySizes_[sampleIndex];
423     return heif_error_ok;
424 }
425 
Write(HeifStreamWriter & writer) const426 heif_error HeifStszBox::Write(HeifStreamWriter &writer) const
427 {
428     size_t boxStart = ReserveHeader(writer);
429     writer.Write32(sampleSize_);
430     writer.Write32(sampleCount_);
431     if (sampleSize_ == 0) {
432         for (uint32_t size : entrySizes_) {
433             writer.Write32(size);
434         }
435     }
436     WriteCalculatedHeader(writer, boxStart);
437     return heif_error_ok;
438 }
439 
ParseContent(HeifStreamReader & reader)440 heif_error HeifHvc1Box::ParseContent(HeifStreamReader &reader)
441 {
442     for (uint32_t i = 0; i < HVC1_RESERVED_OFFSET; i++) {
443         reserved_[i] = reader.Read8();
444     }
445     for (uint32_t i = 0; i < HVC1_PREDEFINE_OFFSET; i++) {
446         reader.Read8();
447     }
448     width_ = reader.Read16();
449     height_ = reader.Read16();
450     for (uint32_t i = 0; i < HVC1_SKIP_OFFSET; i++) {
451         reader.Read8();
452     }
453     uint32_t recursionCount = 0;
454     heif_error error = HeifBox::MakeFromReader(reader, &hvccBox_, recursionCount);
455     if (error != heif_error_ok) {
456         return error;
457     }
458     return reader.GetError();
459 }
460 } // namespace ImagePlugin
461 } // namespace OHOS
462