/work/obj-fuzz/dist/include/MP4Interval.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #ifndef INTERVAL_H_ |
6 | | #define INTERVAL_H_ |
7 | | |
8 | | #include "nsTArray.h" |
9 | | #include <algorithm> |
10 | | |
11 | | namespace mozilla |
12 | | { |
13 | | |
14 | | template <typename T> |
15 | | struct MP4Interval |
16 | | { |
17 | | MP4Interval() : start(0), end(0) {} |
18 | | MP4Interval(T aStart, T aEnd) : start(aStart), end(aEnd) |
19 | | { |
20 | | MOZ_ASSERT(aStart <= aEnd); |
21 | | } |
22 | | T Length() { return end - start; } |
23 | | MP4Interval Intersection(const MP4Interval& aOther) const |
24 | | { |
25 | | T s = start > aOther.start ? start : aOther.start; |
26 | | T e = end < aOther.end ? end : aOther.end; |
27 | | if (s > e) { |
28 | | return MP4Interval(); |
29 | | } |
30 | | return MP4Interval(s, e); |
31 | | } |
32 | | bool Contains(const MP4Interval& aOther) const |
33 | | { |
34 | | return aOther.start >= start && aOther.end <= end; |
35 | | } |
36 | | bool operator==(const MP4Interval& aOther) const |
37 | | { |
38 | | return start == aOther.start && end == aOther.end; |
39 | | } |
40 | | bool operator!=(const MP4Interval& aOther) const { return !(*this == aOther); } |
41 | | bool IsNull() const |
42 | 0 | { |
43 | 0 | return end == start; |
44 | 0 | } |
45 | | MP4Interval Extents(const MP4Interval& aOther) const |
46 | | { |
47 | | if (IsNull()) { |
48 | | return aOther; |
49 | | } |
50 | | return MP4Interval(std::min(start, aOther.start), |
51 | | std::max(end, aOther.end)); |
52 | | } |
53 | | |
54 | | T start; |
55 | | T end; |
56 | | |
57 | | static void SemiNormalAppend(nsTArray<MP4Interval<T>>& aIntervals, |
58 | | MP4Interval<T> aMP4Interval) |
59 | | { |
60 | | if (!aIntervals.IsEmpty() && |
61 | | aIntervals.LastElement().end == aMP4Interval.start) { |
62 | | aIntervals.LastElement().end = aMP4Interval.end; |
63 | | } else { |
64 | | aIntervals.AppendElement(aMP4Interval); |
65 | | } |
66 | | } |
67 | | |
68 | | static void Normalize(const nsTArray<MP4Interval<T>>& aIntervals, |
69 | | nsTArray<MP4Interval<T>>* aNormalized) |
70 | | { |
71 | | if (!aNormalized || !aIntervals.Length()) { |
72 | | MOZ_ASSERT(aNormalized); |
73 | | return; |
74 | | } |
75 | | MOZ_ASSERT(aNormalized->IsEmpty()); |
76 | | |
77 | | nsTArray<MP4Interval<T>> sorted; |
78 | | sorted = aIntervals; |
79 | | sorted.Sort(Compare()); |
80 | | |
81 | | MP4Interval<T> current = sorted[0]; |
82 | | for (size_t i = 1; i < sorted.Length(); i++) { |
83 | | MOZ_ASSERT(sorted[i].start <= sorted[i].end); |
84 | | if (current.Contains(sorted[i])) { |
85 | | continue; |
86 | | } |
87 | | if (current.end >= sorted[i].start) { |
88 | | current.end = sorted[i].end; |
89 | | } else { |
90 | | aNormalized->AppendElement(current); |
91 | | current = sorted[i]; |
92 | | } |
93 | | } |
94 | | aNormalized->AppendElement(current); |
95 | | } |
96 | | |
97 | | static void Intersection(const nsTArray<MP4Interval<T>>& a0, |
98 | | const nsTArray<MP4Interval<T>>& a1, |
99 | | nsTArray<MP4Interval<T>>* aIntersection) |
100 | | { |
101 | | MOZ_ASSERT(IsNormalized(a0)); |
102 | | MOZ_ASSERT(IsNormalized(a1)); |
103 | | size_t i0 = 0; |
104 | | size_t i1 = 0; |
105 | | while (i0 < a0.Length() && i1 < a1.Length()) { |
106 | | MP4Interval i = a0[i0].Intersection(a1[i1]); |
107 | | if (i.Length()) { |
108 | | aIntersection->AppendElement(i); |
109 | | } |
110 | | if (a0[i0].end < a1[i1].end) { |
111 | | i0++; |
112 | | // Assert that the array is sorted |
113 | | MOZ_ASSERT(i0 == a0.Length() || a0[i0 - 1].start < a0[i0].start); |
114 | | } else { |
115 | | i1++; |
116 | | // Assert that the array is sorted |
117 | | MOZ_ASSERT(i1 == a1.Length() || a1[i1 - 1].start < a1[i1].start); |
118 | | } |
119 | | } |
120 | | } |
121 | | |
122 | | static bool IsNormalized(const nsTArray<MP4Interval<T>>& aIntervals) |
123 | | { |
124 | | for (size_t i = 1; i < aIntervals.Length(); i++) { |
125 | | if (aIntervals[i - 1].end >= aIntervals[i].start) { |
126 | | return false; |
127 | | } |
128 | | } |
129 | | return true; |
130 | | } |
131 | | |
132 | | struct Compare |
133 | | { |
134 | | bool Equals(const MP4Interval<T>& a0, const MP4Interval<T>& a1) const |
135 | | { |
136 | | return a0.start == a1.start && a0.end == a1.end; |
137 | | } |
138 | | |
139 | | bool LessThan(const MP4Interval<T>& a0, const MP4Interval<T>& a1) const |
140 | | { |
141 | | return a0.start < a1.start; |
142 | | } |
143 | | }; |
144 | | }; |
145 | | } |
146 | | |
147 | | #endif |