Created
June 27, 2012 14:44
-
-
Save mrwonko/3004517 to your computer and use it in GitHub Desktop.
FH-Wedel Programmierwettbewerb 2012 - creating TGAs based on program output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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