1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/*
* This file is part of the PulseView project.
*
* Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <cassert>
#include <pv/data/decode/decoder.hpp>
#include <pv/data/decode/row.hpp>
#include <pv/data/decode/rowdata.hpp>
using std::vector;
namespace pv {
namespace data {
namespace decode {
RowData::RowData(Row* row) :
row_(row),
prev_ann_start_sample_(0)
{
assert(row);
}
uint64_t RowData::get_max_sample() const
{
if (annotations_.empty())
return 0;
return annotations_.back().end_sample();
}
uint64_t RowData::get_annotation_count() const
{
return annotations_.size();
}
void RowData::get_annotation_subset(
deque<const pv::data::decode::Annotation*> &dest,
uint64_t start_sample, uint64_t end_sample) const
{
// Determine whether we must apply per-class filtering or not
bool all_ann_classes_enabled = true;
bool all_ann_classes_disabled = true;
uint32_t max_ann_class_id = 0;
for (AnnotationClass* c : row_->ann_classes()) {
if (!c->visible)
all_ann_classes_enabled = false;
else
all_ann_classes_disabled = false;
if (c->id > max_ann_class_id)
max_ann_class_id = c->id;
}
if (all_ann_classes_enabled) {
// No filtering, send everyting out as-is
for (const auto& annotation : annotations_)
if ((annotation.end_sample() > start_sample) &&
(annotation.start_sample() <= end_sample))
dest.push_back(&annotation);
} else {
if (!all_ann_classes_disabled) {
// Filter out invisible annotation classes
vector<size_t> class_visible;
class_visible.resize(max_ann_class_id + 1, 0);
for (AnnotationClass* c : row_->ann_classes())
if (c->visible)
class_visible[c->id] = 1;
for (const auto& annotation : annotations_)
if ((class_visible[annotation.ann_class_id()]) &&
(annotation.end_sample() > start_sample) &&
(annotation.start_sample() <= end_sample))
dest.push_back(&annotation);
}
}
}
void RowData::emplace_annotation(srd_proto_data *pdata)
{
// We insert the annotation in a way so that the annotation list
// is sorted by start sample. Otherwise, we'd have to sort when
// painting, which is expensive
if (pdata->start_sample < prev_ann_start_sample_) {
// Find location to insert the annotation at
auto it = annotations_.end();
do {
it--;
} while ((it->start_sample() > pdata->start_sample) && (it != annotations_.begin()));
// Allow inserting at the front
if (it != annotations_.begin())
it++;
annotations_.emplace(it, pdata, row_);
} else {
annotations_.emplace_back(pdata, row_);
prev_ann_start_sample_ = pdata->start_sample;
}
}
} // namespace decode
} // namespace data
} // namespace pv
|