Coverage Report

Created: 2018-09-25 14:53

/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