Skip to content

Instantly share code, notes, and snippets.

@mrwonko
Created June 27, 2012 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrwonko/3004517 to your computer and use it in GitHub Desktop.
Save mrwonko/3004517 to your computer and use it in GitHub Desktop.
FH-Wedel Programmierwettbewerb 2012 - creating TGAs based on program output
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
void printUsage()
{
std::cout<<"Usage: echo [data] | yourProgram | wizualize <width (= height)> <output directory>"<<std::endl;
}
static const unsigned int SHIFT_RED = 16;
static const unsigned int SHIFT_GREEN = 8;
static const unsigned int SHIFT_BLUE = 0;
static const unsigned int SHIFT_ALPHA = 24;
struct Color
{
Color(unsigned char red = 0, unsigned char green = 0, unsigned char blue = 0) : r(red), g(green), b(blue) {}
unsigned char r, g, b;
const unsigned int toInt() const { return ( (255 << SHIFT_ALPHA) | (r << SHIFT_RED) | (g << SHIFT_GREEN) | (b << SHIFT_BLUE) );}
Color& operator ++() // prefix
{
static const unsigned int increment = 32;
if(increment + g > 255)
{
b += increment;
}
g += increment;
}
const bool operator == (const Color& rhs) { return rhs.r == r && rhs.g == g && rhs.b == b;}
};
void writeTGA(const std::string& filename, const unsigned int fieldSize, const std::vector<unsigned int>& field)
{
// write to file
std::ofstream file((filename + ".tga").c_str(), std::ios::binary | std::ios::out);
if(file.fail())
{
std::cerr << "Could not open file " << filename << "!" << std::endl;
return;
}
// TGA Header
file.put(0); // ID length (date & time or other metadata)
file.put(0); // color map type - none
file.put(2); // image type - uncompressed RGB
file.put(0); file.put(0); // color map offset
file.put(0); file.put(0); // color map length
file.put(32); // color map bpp
// image data
file.put(0); file.put(0); // Origin.x
file.put(0); file.put(0); // Origin.y
file.put(fieldSize & 0xFF); file.put((fieldSize & 0xFF00) >> 8); // width
file.put(fieldSize & 0xFF); file.put((fieldSize & 0xFF00) >> 8); // height
file.put(32); // bits per pixel
file.put(1 << 5); // attributes: Y origin at top
file.write(reinterpret_cast<const char*>(field.data()), fieldSize * fieldSize * 4);
// footer
file.put(0); file.put(0); file.put(0); file.put(0); // metadata offset (none)
file.put(0); file.put(0); file.put(0); file.put(0); // developer stuff offset (none)
file << std::string("TRUEVISION-XFILE.");
file.put(0);
file.close();
}
int main(int argc, const char** argv)
{
// Argument parsing
if(argc < 3)
{
printUsage();
return 0;
}
unsigned int fieldSize;
{
std::stringstream ss;
ss << argv[1];
ss >> fieldSize;
if(ss.fail())
{
printUsage();
return 0;
}
}
std::string outputDirectory(argv[2]);
// read & process
static const Color BLACK;
static const Color RED(255, 0, 0);
unsigned int counter = 0;
while(true)
{
std::vector<unsigned int> field;
field.resize(fieldSize * fieldSize, BLACK.toInt());
char curChar;
Color curCol(63, 0, 0);
bool valid = true;
while(true)
{
std::cin.get(curChar);
if(std::cin.fail()) return 0; //exit on end of input
if(curChar == ']') break;
if(curChar == '(')
{
++curCol;
if(curCol == BLACK)
{
++curCol;
}
unsigned short x, y, size;
std::cin >> x;
while(std::cin.get() != ',');
std::cin >> y;
while(std::cin.get() != ',');
std::cin >> size;
while(std::cin.get() != ')');
bool thisOneInvalid = false;
for(unsigned short curX = x; curX < x + size; ++curX)
{
for(unsigned short curY = y; curY < y + size; ++curY)
{
unsigned int& cell = field[curY * fieldSize + curX];
if(cell == BLACK.toInt())
{
cell = curCol.toInt();
}
else
{
cell = RED.toInt();
valid = false;
if(!thisOneInvalid)
{
std::cout<<"Invalid overlapping piece (" << x << ", " << y << ", " << size << ")!\n";
thisOneInvalid = true;
}
}
}
}
}
}
std::cout << (valid ? "Read valid solution." : "Read INVALID solution.") << std::endl;
std::stringstream filename;
filename << outputDirectory;
if(outputDirectory[outputDirectory.size()-1] != '/' && outputDirectory[outputDirectory.size()-1] != '\\' )
{
filename << '/';
}
filename << ++counter;
writeTGA(filename.str(), fieldSize, field);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment