mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Rip out dataspecs everywhere.
This commit is contained in:
42
lib/bitmap.cc
Normal file
42
lib/bitmap.cc
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "fmt/format.h"
|
||||
#include "dep/agg/include/agg2d.h"
|
||||
#include "dep/stb/stb_image_write.h"
|
||||
#include "utils.h"
|
||||
#include "bitmap.h"
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
|
||||
Bitmap::Bitmap(const std::string filename, unsigned width, unsigned height):
|
||||
filename(filename),
|
||||
width(width),
|
||||
height(height),
|
||||
initialised(true)
|
||||
{}
|
||||
|
||||
Agg2D& Bitmap::painter()
|
||||
{
|
||||
if (!_painter)
|
||||
{
|
||||
_bitmap.resize(width * height * 4, 255);
|
||||
_painter.reset(new Agg2D());
|
||||
_painter->attach(&_bitmap[0], width, height, width*4);
|
||||
}
|
||||
return *_painter;
|
||||
}
|
||||
|
||||
void Bitmap::save()
|
||||
{
|
||||
if (endsWith(filename, ".png"))
|
||||
stbi_write_png(filename.c_str(), width, height, 4, &_bitmap[0], width*4);
|
||||
else if (endsWith(filename, ".bmp"))
|
||||
stbi_write_bmp(filename.c_str(), width, height, 4, &_bitmap[0]);
|
||||
else if (endsWith(filename, ".tga"))
|
||||
stbi_write_tga(filename.c_str(), width, height, 4, &_bitmap[0]);
|
||||
else if (endsWith(filename, ".jpg"))
|
||||
stbi_write_jpg(filename.c_str(), width, height, 4, &_bitmap[0], 80);
|
||||
else
|
||||
Error() << "don't know how to write that image format";
|
||||
}
|
||||
|
||||
24
lib/bitmap.h
Normal file
24
lib/bitmap.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef BITMAP_H
|
||||
#define BITMAP_H
|
||||
|
||||
class Agg2D;
|
||||
|
||||
class Bitmap
|
||||
{
|
||||
public:
|
||||
Bitmap(const std::string filename, unsigned width, unsigned height);
|
||||
|
||||
Agg2D& painter();
|
||||
void save();
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> _bitmap;
|
||||
std::unique_ptr<Agg2D> _painter;
|
||||
public:
|
||||
std::string filename;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
bool initialised : 1;
|
||||
};
|
||||
|
||||
#endif
|
||||
195
lib/dataspec.cc
195
lib/dataspec.cc
@@ -1,195 +0,0 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "fmt/format.h"
|
||||
#include "dep/agg/include/agg2d.h"
|
||||
#include "dep/stb/stb_image_write.h"
|
||||
#include "utils.h"
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
|
||||
MissingModifierException::MissingModifierException(const std::string& mod):
|
||||
mod(mod),
|
||||
std::runtime_error(fmt::format("missing mandatory modifier '{}'", mod))
|
||||
{}
|
||||
|
||||
std::vector<std::string> DataSpec::split(
|
||||
const std::string& s, const std::string& delimiter)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
|
||||
if (!s.empty())
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t end = 0;
|
||||
size_t len = 0;
|
||||
do
|
||||
{
|
||||
end = s.find(delimiter,start);
|
||||
len = end - start;
|
||||
std::string token = s.substr(start, len);
|
||||
ret.emplace_back( token );
|
||||
start += len + delimiter.length();
|
||||
}
|
||||
while (end != std::string::npos);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::set<unsigned> DataSpec::parseRange(const std::string& data)
|
||||
{
|
||||
static const std::regex DATA_REGEX("([0-9]+)(?:(?:-([0-9]+))|(?:\\+([0-9]+)))?(?:x([0-9]+))?");
|
||||
|
||||
std::set<unsigned> result;
|
||||
for (auto& data : split(data, ","))
|
||||
{
|
||||
int start = 0;
|
||||
int count = 1;
|
||||
int step = 1;
|
||||
|
||||
std::smatch dmatch;
|
||||
if (!std::regex_match(data, dmatch, DATA_REGEX))
|
||||
Error() << "invalid data in mod '" << data << "'";
|
||||
|
||||
start = std::stoi(dmatch[1]);
|
||||
if (!dmatch[2].str().empty())
|
||||
count = std::stoi(dmatch[2]) - start + 1;
|
||||
if (!dmatch[3].str().empty())
|
||||
count = std::stoi(dmatch[3]);
|
||||
if (!dmatch[4].str().empty())
|
||||
step = std::stoi(dmatch[4]);
|
||||
|
||||
if (count < 0)
|
||||
Error() << "mod '" << data << "' specifies an illegal quantity";
|
||||
|
||||
for (int i = start; i < (start+count); i += step)
|
||||
result.insert(i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DataSpec::Modifier DataSpec::parseMod(const std::string& spec)
|
||||
{
|
||||
static const std::regex MOD_REGEX("([a-z]*)=([-x+0-9,]*)");
|
||||
|
||||
std::smatch match;
|
||||
if (!std::regex_match(spec, match, MOD_REGEX))
|
||||
Error() << "invalid data modifier syntax '" << spec << "'";
|
||||
|
||||
Modifier m;
|
||||
m.name = match[1];
|
||||
m.source = spec;
|
||||
m.data = parseRange(match[2]);
|
||||
return m;
|
||||
}
|
||||
|
||||
void DataSpec::set(const std::string& spec)
|
||||
{
|
||||
std::vector<std::string> words = split(spec, ":");
|
||||
if (words.size() == 0)
|
||||
return;
|
||||
|
||||
filename = words[0];
|
||||
if (words.size() > 1)
|
||||
{
|
||||
for (size_t i = 1; i < words.size(); i++)
|
||||
{
|
||||
auto mod = parseMod(words[i]);
|
||||
modifiers[mod.name] = mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const DataSpec::Modifier& DataSpec::at(const std::string& mod) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return modifiers.at(mod);
|
||||
}
|
||||
catch (const std::out_of_range& e)
|
||||
{
|
||||
throw MissingModifierException(mod);
|
||||
}
|
||||
}
|
||||
|
||||
bool DataSpec::has(const std::string& mod) const
|
||||
{
|
||||
return modifiers.find(mod) != modifiers.end();
|
||||
}
|
||||
|
||||
DataSpec::operator std::string(void) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << filename;
|
||||
|
||||
for (const auto& mod : modifiers)
|
||||
ss << ':' << mod.second.source;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
BitmapSpec::BitmapSpec(const DataSpec& spec)
|
||||
{
|
||||
try
|
||||
{
|
||||
filename = spec.filename;
|
||||
|
||||
if (!spec.has("w") && !spec.has("h"))
|
||||
{
|
||||
width = height = 0;
|
||||
initialised = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = spec.at("w").only();
|
||||
height = spec.at("h").only();
|
||||
initialised = true;
|
||||
}
|
||||
}
|
||||
catch (const MissingModifierException& e)
|
||||
{
|
||||
Error() << e.what() << " in imagespec '" << spec << "'";
|
||||
}
|
||||
|
||||
for (const auto& e : spec.modifiers)
|
||||
{
|
||||
const auto name = e.second.name;
|
||||
if ((name != "w") && (name != "h"))
|
||||
Error() << fmt::format("unknown fluxspec modifier '{}'", name);
|
||||
}
|
||||
}
|
||||
|
||||
BitmapSpec::BitmapSpec(const std::string filename, unsigned width, unsigned height):
|
||||
filename(filename),
|
||||
width(width),
|
||||
height(height),
|
||||
initialised(true)
|
||||
{}
|
||||
|
||||
Agg2D& BitmapSpec::painter()
|
||||
{
|
||||
if (!_painter)
|
||||
{
|
||||
_bitmap.resize(width * height * 4, 255);
|
||||
_painter.reset(new Agg2D());
|
||||
_painter->attach(&_bitmap[0], width, height, width*4);
|
||||
}
|
||||
return *_painter;
|
||||
}
|
||||
|
||||
void BitmapSpec::save()
|
||||
{
|
||||
if (endsWith(filename, ".png"))
|
||||
stbi_write_png(filename.c_str(), width, height, 4, &_bitmap[0], width*4);
|
||||
else if (endsWith(filename, ".bmp"))
|
||||
stbi_write_bmp(filename.c_str(), width, height, 4, &_bitmap[0]);
|
||||
else if (endsWith(filename, ".tga"))
|
||||
stbi_write_tga(filename.c_str(), width, height, 4, &_bitmap[0]);
|
||||
else if (endsWith(filename, ".jpg"))
|
||||
stbi_write_jpg(filename.c_str(), width, height, 4, &_bitmap[0], 80);
|
||||
else
|
||||
Error() << "don't know how to write that image format";
|
||||
}
|
||||
|
||||
135
lib/dataspec.h
135
lib/dataspec.h
@@ -1,135 +0,0 @@
|
||||
#ifndef DATASPEC_H
|
||||
#define DATASPEC_H
|
||||
|
||||
class MissingModifierException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
MissingModifierException(const std::string& mod);
|
||||
const std::string mod;
|
||||
};
|
||||
|
||||
class DataSpec
|
||||
{
|
||||
public:
|
||||
struct Modifier
|
||||
{
|
||||
std::string name;
|
||||
std::set<unsigned> data;
|
||||
std::string source;
|
||||
|
||||
bool operator == (const Modifier& other) const
|
||||
{ return (name == other.name) && (data == other.data); }
|
||||
|
||||
bool operator != (const Modifier& other) const
|
||||
{ return (name != other.name) || (data != other.data); }
|
||||
|
||||
unsigned only() const
|
||||
{
|
||||
if (data.size() != 1)
|
||||
Error() << "modifier " << name << " can only have one value";
|
||||
return *(data.begin());
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
static std::vector<std::string> split(
|
||||
const std::string& s, const std::string& delimiter);
|
||||
static std::set<unsigned> parseRange(const std::string& spec);
|
||||
|
||||
static Modifier parseMod(const std::string& spec);
|
||||
|
||||
public:
|
||||
DataSpec(const std::string& spec)
|
||||
{ set(spec); }
|
||||
|
||||
void set(const std::string& spec);
|
||||
operator std::string () const;
|
||||
|
||||
const Modifier& at(const std::string& mod) const;
|
||||
bool has(const std::string& mod) const;
|
||||
|
||||
unsigned atOr(const std::string& mod, unsigned value) const
|
||||
{ return has(mod) ? at(mod).only() : value; }
|
||||
|
||||
std::string filename;
|
||||
std::map<std::string, Modifier> modifiers;
|
||||
};
|
||||
|
||||
static inline std::ostream& operator << (std::ostream& os, const DataSpec& dataSpec)
|
||||
{ os << (std::string)dataSpec; return os; }
|
||||
|
||||
class DataSpecFlag : public Flag
|
||||
{
|
||||
public:
|
||||
DataSpecFlag(const std::vector<std::string>& names, const std::string helptext,
|
||||
const std::string& defaultValue):
|
||||
Flag(names, helptext),
|
||||
_value(defaultValue)
|
||||
{}
|
||||
|
||||
const DataSpec& get() const
|
||||
{ checkInitialised(); return _value; }
|
||||
|
||||
operator const DataSpec& () const
|
||||
{ return get(); }
|
||||
|
||||
bool hasArgument() const { return true; }
|
||||
const std::string defaultValueAsString() const { return _value; }
|
||||
void set(const std::string& value) { _value.set(value); }
|
||||
|
||||
private:
|
||||
DataSpec _value;
|
||||
};
|
||||
|
||||
class RangeFlag : public Flag
|
||||
{
|
||||
public:
|
||||
RangeFlag(const std::vector<std::string>& names, const std::string helptext,
|
||||
const std::string& defaultValue):
|
||||
Flag(names, helptext),
|
||||
_stringValue(defaultValue),
|
||||
_value(DataSpec::parseRange(defaultValue))
|
||||
{}
|
||||
|
||||
const std::set<unsigned>& get() const
|
||||
{ checkInitialised(); return _value; }
|
||||
|
||||
operator const std::set<unsigned>& () const
|
||||
{ return get(); }
|
||||
|
||||
bool hasArgument() const { return true; }
|
||||
const std::string defaultValueAsString() const { return _stringValue; }
|
||||
|
||||
void set(const std::string& value)
|
||||
{
|
||||
_stringValue = value;
|
||||
_value = DataSpec::parseRange(value);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _stringValue;
|
||||
std::set<unsigned> _value;
|
||||
};
|
||||
|
||||
class Agg2D;
|
||||
|
||||
class BitmapSpec
|
||||
{
|
||||
public:
|
||||
BitmapSpec(const DataSpec& dataSpec);
|
||||
BitmapSpec(const std::string filename, unsigned width, unsigned height);
|
||||
|
||||
Agg2D& painter();
|
||||
void save();
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> _bitmap;
|
||||
std::unique_ptr<Agg2D> _painter;
|
||||
public:
|
||||
std::string filename;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
bool initialised : 1;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "sql.h"
|
||||
#include "bytes.h"
|
||||
#include "protocol.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "decoders/fluxmapreader.h"
|
||||
#include "lib/fluxsink/fluxsink.pb.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "proto.h"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "sql.h"
|
||||
#include "bytes.h"
|
||||
#include "protocol.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "decoders/fluxmapreader.h"
|
||||
#include "lib/fluxsink/fluxsink.pb.h"
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "sql.h"
|
||||
#include "bytes.h"
|
||||
#include "protocol.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "decoders/fluxmapreader.h"
|
||||
#include "lib/fluxsink/fluxsink.pb.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsource/fluxsource.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "proto.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagereader/imagereader.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagereader/imagereader.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagereader/imagereader.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagereader/imagereader.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagereader/imagereader.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagewriter/imagewriter.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "reader.h"
|
||||
#include "fluxmap.h"
|
||||
#include "sql.h"
|
||||
#include "dataspec.h"
|
||||
#include "decoders/decoders.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "sql.h"
|
||||
#include "protocol.h"
|
||||
#include "usb/usb.h"
|
||||
#include "dataspec.h"
|
||||
#include "encoders/encoders.h"
|
||||
#include "fluxsource/fluxsource.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
|
||||
@@ -304,10 +304,10 @@ buildlibrary libbackend.a \
|
||||
arch/tids990/encoder.cc \
|
||||
arch/victor9k/decoder.cc \
|
||||
arch/zilogmcz/decoder.cc \
|
||||
lib/bitmap.cc \
|
||||
lib/bytes.cc \
|
||||
lib/crc.cc \
|
||||
lib/csvreader.cc \
|
||||
lib/dataspec.cc \
|
||||
lib/decoders/decoders.cc \
|
||||
lib/decoders/fluxmapreader.cc \
|
||||
lib/decoders/fmmfm.cc \
|
||||
@@ -465,7 +465,6 @@ runtest bitaccumulator-test tests/bitaccumulator.cc
|
||||
runtest bytes-test tests/bytes.cc
|
||||
runtest compression-test tests/compression.cc
|
||||
runtest csvreader-test tests/csvreader.cc
|
||||
runtest dataspec-test tests/dataspec.cc
|
||||
runtest flags-test tests/flags.cc
|
||||
runtest fluxpattern-test tests/fluxpattern.cc
|
||||
runtest fmmfm-test tests/fmmfm.cc
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "usb/usb.h"
|
||||
#include "dataspec.h"
|
||||
#include "bitmap.h"
|
||||
#include "fluxmap.h"
|
||||
#include "decoders/fluxmapreader.h"
|
||||
#include "writer.h"
|
||||
@@ -53,10 +53,20 @@ static StringFlag writeCsv(
|
||||
"Write detailed CSV data",
|
||||
"");
|
||||
|
||||
static DataSpecFlag writeImg(
|
||||
static StringFlag writeImg(
|
||||
{ "--write-img" },
|
||||
"Draw a graph of the response data",
|
||||
":w=640:h=480");
|
||||
"analysis.png");
|
||||
|
||||
static IntFlag imgWidth(
|
||||
{ "--width" },
|
||||
"Width of output graph",
|
||||
800);
|
||||
|
||||
static IntFlag imgHeight(
|
||||
{ "--height" },
|
||||
"Height of output graph",
|
||||
600);
|
||||
|
||||
/* This is the Turbo colourmap.
|
||||
* https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html
|
||||
@@ -286,16 +296,16 @@ int mainAnalyseDriveResponse(int argc, const char* argv[])
|
||||
}
|
||||
}
|
||||
|
||||
BitmapSpec bitmapSpec(writeImg);
|
||||
if (!bitmapSpec.filename.empty())
|
||||
Bitmap bitmap(writeImg, imgWidth, imgHeight);
|
||||
if (!bitmap.filename.empty())
|
||||
{
|
||||
Agg2D& painter = bitmapSpec.painter();
|
||||
Agg2D& painter = bitmap.painter();
|
||||
painter.clearAll(0xdd, 0xdd, 0xdd);
|
||||
|
||||
const double MARGIN = 30;
|
||||
agg::rect_d drawableBounds = {
|
||||
MARGIN*1.5, MARGIN,
|
||||
bitmapSpec.width - MARGIN, bitmapSpec.height - MARGIN
|
||||
bitmap.width - MARGIN, bitmap.height - MARGIN
|
||||
};
|
||||
agg::rect_d colourbarBounds = {
|
||||
drawableBounds.x2 - MARGIN, drawableBounds.y1,
|
||||
@@ -347,7 +357,7 @@ int mainAnalyseDriveResponse(int argc, const char* argv[])
|
||||
painter.lineColor(0, 0, 0);
|
||||
painter.rectangle(graphBounds.x1, graphBounds.y1, graphBounds.x2, graphBounds.y2);
|
||||
painter.rectangle(colourbarBounds.x1, drawableBounds.y1, drawableBounds.x2, drawableBounds.y2);
|
||||
bitmapSpec.save();
|
||||
bitmap.save();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "bitmap.h"
|
||||
#include "fluxmap.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
@@ -20,10 +20,20 @@ static StringFlag source(
|
||||
"CSV file produced by reader",
|
||||
"");
|
||||
|
||||
static DataSpecFlag writeImg(
|
||||
static StringFlag writeImg(
|
||||
{ "--img", "-o" },
|
||||
"Draw a graph of the disk layout",
|
||||
":w=800:h=600");
|
||||
"disklayout.png");
|
||||
|
||||
static IntFlag imgWidth(
|
||||
{ "--width" },
|
||||
"Width of output graph",
|
||||
800);
|
||||
|
||||
static IntFlag imgHeight(
|
||||
{ "--height" },
|
||||
"Height of output graph",
|
||||
600);
|
||||
|
||||
static IntFlag period(
|
||||
{ "--visualiser-period" },
|
||||
@@ -47,16 +57,16 @@ static const int TRACKS = 83;
|
||||
|
||||
void visualiseSectorsToFile(const SectorSet& sectors, const std::string& filename)
|
||||
{
|
||||
BitmapSpec bitmapSpec(writeImg);
|
||||
if (bitmapSpec.filename.empty())
|
||||
Bitmap bitmap(writeImg, imgWidth, imgHeight);
|
||||
if (bitmap.filename.empty())
|
||||
Error() << "you must specify an image filename to write to";
|
||||
|
||||
Agg2D& painter = bitmapSpec.painter();
|
||||
Agg2D& painter = bitmap.painter();
|
||||
painter.clearAll(0xff, 0xff, 0xff);
|
||||
|
||||
const double radians_per_ns = 2.0*M_PI / (period*1e6);
|
||||
const double available_width = bitmapSpec.width;
|
||||
const double available_height = bitmapSpec.height;
|
||||
const double available_width = bitmap.width;
|
||||
const double available_height = bitmap.height;
|
||||
const double panel_centre = (sideToDraw == -1)
|
||||
? (available_width / 4)
|
||||
: (available_width / 2);
|
||||
@@ -152,7 +162,7 @@ void visualiseSectorsToFile(const SectorSet& sectors, const std::string& filenam
|
||||
break;
|
||||
}
|
||||
|
||||
bitmapSpec.save();
|
||||
bitmap.save();
|
||||
}
|
||||
|
||||
static void check_for_error()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include "sector.h"
|
||||
#include "sectorset.h"
|
||||
#include "imagereader/imagereader.h"
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "sectorset.h"
|
||||
#include "record.h"
|
||||
#include "proto.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "fluxsource/fluxsource.h"
|
||||
#include "arch/brother/brother.h"
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "sectorset.h"
|
||||
#include "record.h"
|
||||
#include "proto.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsource/fluxsource.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "arch/brother/brother.h"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "usb/usb.h"
|
||||
#include "dataspec.h"
|
||||
#include "protocol.h"
|
||||
#include "proto.h"
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "sectorset.h"
|
||||
#include "record.h"
|
||||
#include "proto.h"
|
||||
#include "dataspec.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "arch/brother/brother.h"
|
||||
#include "arch/ibm/ibm.h"
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "dataspec.h"
|
||||
#include <assert.h>
|
||||
|
||||
static void test_split(void)
|
||||
{
|
||||
assert((DataSpec::split("1,2,3", ",")
|
||||
== std::vector<std::string>{"1", "2", "3"}));
|
||||
assert((DataSpec::split(",2,3", ",")
|
||||
== std::vector<std::string>{"", "2", "3"}));
|
||||
assert((DataSpec::split(",2,", ",")
|
||||
== std::vector<std::string>{"", "2", ""}));
|
||||
assert((DataSpec::split("2", ",")
|
||||
== std::vector<std::string>{"2"}));
|
||||
assert((DataSpec::split("", ",")
|
||||
== std::vector<std::string>()));
|
||||
}
|
||||
|
||||
static void test_parserange(void)
|
||||
{
|
||||
assert(DataSpec::parseRange("")
|
||||
== std::set<unsigned>());
|
||||
assert(DataSpec::parseRange("1")
|
||||
== std::set<unsigned>({1}));
|
||||
assert(DataSpec::parseRange("1,3,5")
|
||||
== std::set<unsigned>({1, 3, 5}));
|
||||
assert(DataSpec::parseRange("1,1,1")
|
||||
== std::set<unsigned>({1}));
|
||||
assert(DataSpec::parseRange("2-3")
|
||||
== std::set<unsigned>({2, 3}));
|
||||
assert(DataSpec::parseRange("2+3")
|
||||
== std::set<unsigned>({2, 3, 4}));
|
||||
assert(DataSpec::parseRange("2+3x2")
|
||||
== std::set<unsigned>({2, 4}));
|
||||
assert(DataSpec::parseRange("9,2+3x2")
|
||||
== std::set<unsigned>({2, 4, 9}));
|
||||
}
|
||||
|
||||
static void test_parsemod(void)
|
||||
{
|
||||
assert(DataSpec::parseMod("x=1")
|
||||
== (DataSpec::Modifier{"x", {1}}));
|
||||
assert(DataSpec::parseMod("x=1,3,5")
|
||||
== (DataSpec::Modifier{"x", {1, 3, 5}}));
|
||||
assert(DataSpec::parseMod("x=1,1,1")
|
||||
== (DataSpec::Modifier{"x", {1}}));
|
||||
assert(DataSpec::parseMod("x=2-3")
|
||||
== (DataSpec::Modifier{"x", {2, 3}}));
|
||||
assert(DataSpec::parseMod("x=2+3")
|
||||
== (DataSpec::Modifier{"x", {2, 3, 4}}));
|
||||
assert(DataSpec::parseMod("x=2+3x2")
|
||||
== (DataSpec::Modifier{"x", {2, 4}}));
|
||||
assert(DataSpec::parseMod("x=9,2+3x2")
|
||||
== (DataSpec::Modifier{"x", {2, 4, 9}}));
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
test_split();
|
||||
test_parserange();
|
||||
test_parsemod();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user