//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Sun Feb 20 17:26:38 PST 2011
// Last Modified: Sun Feb 20 17:26:44 PST 2011
// Filename: ...sig/examples/all/prthumb.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/prthumb.cpp
// Syntax: C++; museinfo
//
// Description: Create a match location summary from theloc output with
// percent output.
//
#include "humdrum.h"
#include "Matrix.h"
#include "PixelColor.h"
#include "SigString.h"
#include "PerlRegularExpression.h"
#ifndef OLDCPP
#include <iostream>
#include <fstream>
#else
#include <iostream.h>
#include <fstream.h>
#endif
#define GRAY 230
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
void example(void);
void usage(const char* command);
void printImage(Matrix<PixelColor>& image);
void processData(Array<SigString>& data);
void readData(Array<SigString>& data, istream& input);
void readData(Array<SigString>& data, const char* filename);
void getStartStop(int& start, int& stop, Array<char>& field,
int width);
void addDataLine(Matrix<PixelColor>& image, SigString& astring,
int width, int offset, int row);
// global variables
Options options; // database for command-line arguments
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
// process the command-line options
checkOptions(options, argc, argv);
Array<SigString> data;
// figure out the number of input files to process
int numinputs = options.getArgCount();
for (int i=0; i<numinputs || i==0; i++) {
// if no command-line arguments read data file from standard input
if (numinputs < 1) {
readData(data, cin);
} else {
readData(data, options.getArg(i+1));
}
// analyze the input file according to command-line options
processData(data);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// readData --
//
void readData(Array& data, istream& infile) {
data.setSize(100);
data.setSize(0);
data.setGrowth(1123123);
char buffer[10123];
int counter = 0;
while (!infile.eof()) {
infile.getline(buffer, 4096, '\n');
// this line causes an infinite loop occasionally:
//if (infile.eof() && (strcmp(buffer, "") == 0)) {
if (infile.eof()) {
break;
} else if (strcmp(buffer, "") == 0) {
counter++;
if (counter > 10) {
break;
}
} else {
data.increase();
data.last() = buffer;
}
}
}
void readData(Array& data, const char* filename) {
ifstream infile(filename, ios::in);
if (!infile.is_open()) {
cerr << "ERROR cannot open file: " << filename << " for reading" << endl;
exit(1);
}
readData(data, infile);
}
//////////////////////////////
//
// processData --
//
void processData(Array& data) {
PerlRegularExpression pre;
int cols = 50;
int rows = data.getSize() + 2;
int offset = 1;
// PixelColor background(255, 255, 255);
PixelColor background(GRAY, GRAY, GRAY);
Matrix<PixelColor> image(rows, cols, background);
// draw border around image
PixelColor border(GRAY,GRAY,GRAY);
int i;
int j;
for (i=0; i<rows; i++) {
image.cell(i, 0) = border;
image.cell(i, cols-1) = border;
}
for (j=1; j<cols-1; j++) {
image.cell(0, j) = border;
image.cell(rows-1, j) = border;
}
for (i=0; i<data.getSize(); i++) {
addDataLine(image, data[i], cols-2, offset, i+offset);
}
printImage(image);
}
//////////////////////////////
//
// addDataLine -- Add a line of data to the image.
//
void addDataLine(Matrix<PixelColor>& image, SigString& astring, int width,
int offset, int row) {
PixelColor black (0, 0, 0);
PixelColor red (255, 0, 0);
PixelColor orange (255, 100, 0);
PixelColor green (0, 244, 0);
PixelColor blue (90, 90, 255);
PixelColor purple (200, 0, 200);
PixelColor yellowgreen(150, 200, 0);
PixelColor* pixel = &black;
Array<Array<char> > tokens;
tokens.setSize(10000);
tokens.setGrowth(1000000);
tokens.setSize(0);
PerlRegularExpression pre;
PerlRegularExpression pre2;
pre.getTokens(tokens, "\\s+", astring.getBase());
int i, j;
int start, stop;
pre.search(tokens[0], ":(.*):", "");
if (pre.search(pre.getSubmatch(1), "Bassus", "i")) {
pixel = &red;
} else if (pre.search(pre.getSubmatch(), "Contra", "i")) {
pixel = &orange;
} else if (pre.search(pre.getSubmatch(), "Tenor", "i")) {
pixel = &blue;
} else if (pre.search(pre.getSubmatch(), "Altus", "i")) {
pixel = &purple;
} else if (pre.search(pre.getSubmatch(), "Superius", "i")) {
pixel = &green;
} else if (pre.search(pre.getSubmatch(), "Discantus", "i")) {
pixel = &yellowgreen;
}
for (i=1; i<tokens.getSize(); i++) {
getStartStop(start, stop, tokens[i], width);
if (start < 0) {
continue;
}
for (j=start; j<=stop; j++) {
image.cell(row, j+offset) = *pixel;
}
}
}
//////////////////////////////
//
// getStartStop -- return the location of the match in the file
//
void getStartStop(int& start, int& stop, Array& field, int width) {
double start1, stop1;
PerlRegularExpression pre;
if (pre.search(field, "P(\\d+).*-.*P(\\d+)", "")) {
start1 = atoi(pre.getSubmatch(1));
stop1 = atoi(pre.getSubmatch(1));
start = int(start1 / 100.0 * width);
stop = int(stop1 / 100.0 * width);
} else if (pre.search(field, "P(\\d+)", "")) {
start1 = atoi(pre.getSubmatch(1));
start = int(start1 / 100.0 * width);
stop = start;
} else {
start = -1;
stop = -1;
}
}
//////////////////////////////
//
// printImage -- PNM image
//
void printImage(Matrix& image) {
int rows = image.getRowCount();
int cols = image.getColumnCount();
cout << "P3\n"; // indicates text-based PPM image
cout << cols*2 << ' ' << rows*2 << '\n'; // size of image
cout << "255\n"; // number of color levels per pixel
int i, j;
for (i=rows-1; i>=0; i--) {
for (j=0; j<cols; j++) {
cout << image.cell(i,j) << ' ';
cout << image.cell(i,j) << ' ';
}
for (j=0; j<cols; j++) {
cout << image.cell(i,j) << ' ';
cout << image.cell(i,j) << ' ';
}
cout << '\n';
}
}
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("d|debug=b"); // determine bad input line num
opts.define("author=b"); // author of program
opts.define("version=b"); // compilation info
opts.define("example=b"); // example usages
opts.define("h|help=b"); // short description
opts.process(argc, argv);
// handle basic options:
if (opts.getBoolean("author")) {
cout << "Written by Craig Stuart Sapp, "
<< "craig@ccrma.stanford.edu, May 1998" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: Nov 2000" << endl;
cout << "compiled: " << __DATE__ << endl;
cout << MUSEINFO_VERSION << endl;
exit(0);
} else if (opts.getBoolean("help")) {
usage(opts.getCommand());
exit(0);
} else if (opts.getBoolean("example")) {
example();
exit(0);
}
}
//////////////////////////////
//
// example -- example usage of the sonority program
//
void example(void) {
cout <<
" \n"
<< endl;
}
//////////////////////////////
//
// usage -- gives the usage statement for the sonority program
//
void usage(const char* command) {
cout <<
" \n"
<< endl;
}
// md5sum: 5af703745cdb78d39317dd01554631f9 prthumb.cpp [20120404]