summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/dye.cpp96
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/dye.h19
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/dyecmd.cpp120
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/imagewriter.cpp24
-rwxr-xr-x[-rw-r--r--]tools/dyecmd/src/imagewriter.h0
5 files changed, 144 insertions, 115 deletions
diff --git a/tools/dyecmd/src/dye.cpp b/tools/dyecmd/src/dye.cpp
index 76b759cc..77da2ebb 100644..100755
--- a/tools/dyecmd/src/dye.cpp
+++ b/tools/dyecmd/src/dye.cpp
@@ -21,16 +21,20 @@
#include <algorithm>
#include <sstream>
+#include <iostream>
#include "dye.h"
Palette::Palette(const std::string &description)
{
+ mLoaded = false;
int size = description.length();
if (size == 0) return;
if (description[0] != '#')
{
- throw;
+ std::cout << "Missing # in the palette description "
+ << "in the third parameter." << std::endl;
+ return;
}
int pos = 1;
@@ -42,25 +46,41 @@ Palette::Palette(const std::string &description)
{
char c = description[pos + i];
int n;
- if ('0' <= c && c <= '9') n = c - '0';
- else if ('A' <= c && c <= 'F') n = c - 'A' + 10;
- else if ('a' <= c && c <= 'f') n = c - 'a' + 10;
+ if ('0' <= c && c <= '9')
+ n = c - '0';
+ else if ('A' <= c && c <= 'F')
+ n = c - 'A' + 10;
+ else if ('a' <= c && c <= 'f')
+ n = c - 'a' + 10;
else
- throw;
+ {
+ std::cout << "invalid Hexadecimal description: "
+ << description << std::endl;
+ return;
+ }
v = (v << 4) | n;
}
Color c = { { v >> 16, v >> 8, v } };
mColors.push_back(c);
pos += 6;
- if (pos == size) return;
- if (description[pos] != ',') break;
+ if (pos == size)
+ {
+ mLoaded = true;
+ return;
+ }
+ if (description[pos] != ',')
+ break;
+
++pos;
}
+
+ mLoaded = true;
}
void Palette::getColor(int intensity, int color[3]) const
{
+ // Return implicit black
if (intensity == 0)
{
color[0] = 0;
@@ -107,6 +127,7 @@ void Palette::getColor(int intensity, int color[3]) const
Dye::Dye(const std::string &description)
{
+ mLoaded = false;
for (int i = 0; i < 7; ++i)
mPalettes[i] = 0;
@@ -121,7 +142,9 @@ Dye::Dye(const std::string &description)
next_pos = length;
if (next_pos <= pos + 3 || description[pos + 1] != ':')
{
- throw;
+ std::cout << "Dyeing: Missing ':' in channel description."
+ << std::endl;
+ return;
}
int i = 0;
switch (description[pos])
@@ -134,12 +157,21 @@ Dye::Dye(const std::string &description)
case 'C': i = 5; break;
case 'W': i = 6; break;
default:
- throw;
+ std::cout << "Dyeing: Invalid channel. Not in [R,G,Y,B,M,C,W]"
+ << std::endl;
+ return;
}
- mPalettes[i] = new Palette(description.substr(pos + 2, next_pos - pos - 2));
+ mPalettes[i] = new Palette(
+ description.substr(pos + 2, next_pos - pos - 2));
+
+ if (!mPalettes[i]->loaded())
+ return;
+
++next_pos;
}
while (next_pos < length);
+
+ mLoaded = true;
}
Dye::~Dye()
@@ -168,47 +200,3 @@ void Dye::update(int color[3]) const
if (mPalettes[i - 1])
mPalettes[i - 1]->getColor(cmax, color);
}
-
-void Dye::instantiate(std::string &target, const std::string &palettes)
-{
- std::string::size_type next_pos = target.find('|');
- if (next_pos == std::string::npos || palettes.empty()) return;
- ++next_pos;
-
- std::ostringstream s;
- s << target.substr(0, next_pos);
- std::string::size_type last_pos = target.length(), pal_pos = 0;
- do
- {
- std::string::size_type pos = next_pos;
- next_pos = target.find(';', pos);
- if (next_pos == std::string::npos) next_pos = last_pos;
- if (next_pos == pos + 1 && pal_pos != std::string::npos)
- {
- std::string::size_type pal_next_pos = palettes.find(';', pal_pos);
- s << target[pos] << ':';
- if (pal_next_pos == std::string::npos)
- {
- s << palettes.substr(pal_pos);
- s << target.substr(next_pos);
- pal_pos = std::string::npos;
- break;
- }
- s << palettes.substr(pal_pos, pal_next_pos - pal_pos);
- pal_pos = pal_next_pos + 1;
- }
- else if (next_pos > pos + 2)
- {
- s << target.substr(pos, next_pos - pos);
- }
- else
- {
- throw;
- }
- s << target[next_pos];
- ++next_pos;
- }
- while (next_pos < last_pos);
-
- target = s.str();
-}
diff --git a/tools/dyecmd/src/dye.h b/tools/dyecmd/src/dye.h
index 5a8fe1b5..922f3370 100644..100755
--- a/tools/dyecmd/src/dye.h
+++ b/tools/dyecmd/src/dye.h
@@ -45,11 +45,19 @@ class Palette
*/
void getColor(int intensity, int color[3]) const;
+ /**
+ * Tells if the palette was successfully loaded.
+ */
+ bool loaded() const
+ { return mLoaded; }
+
private:
struct Color { unsigned char value[3]; };
std::vector< Color > mColors;
+
+ bool mLoaded;
};
/**
@@ -73,15 +81,15 @@ class Dye
~Dye();
/**
- * Modifies a pixel color.
+ * Tells if the dye description was successfully loaded.
*/
- void update(int color[3]) const;
+ bool loaded() const
+ { return mLoaded; }
/**
- * Fills the blank in a dye placeholder with some palette names.
+ * Modifies a pixel color.
*/
- static void instantiate(std::string &target,
- const std::string &palettes);
+ void update(int color[3]) const;
private:
@@ -91,6 +99,7 @@ class Dye
* Red, Green, Yellow, Blue, Magenta, White (or rather gray).
*/
Palette *mPalettes[7];
+ bool mLoaded;
};
#endif
diff --git a/tools/dyecmd/src/dyecmd.cpp b/tools/dyecmd/src/dyecmd.cpp
index 3ae963b7..5e06e500 100644..100755
--- a/tools/dyecmd/src/dyecmd.cpp
+++ b/tools/dyecmd/src/dyecmd.cpp
@@ -29,11 +29,14 @@
using namespace std;
// return values
-#define RETURN_OK 1
-#define INVALID_PARAMETER_LIST 100
-#define INVALID_INPUT_IMAGE 101
-#define INVALID_OUTPUT_IMAGE 102
-#define INVALID_DYE_PARAMETER 105
+enum ReturnValues
+{
+ RETURN_OK = 0,
+ INVALID_PARAMETER_LIST = 100,
+ INVALID_INPUT_IMAGE = 101,
+ INVALID_OUTPUT_IMAGE = 102,
+ INVALID_DYE_PARAMETER = 105
+};
SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye)
{
@@ -49,18 +52,20 @@ SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye)
rgba.alpha = 255;
SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE);
- //SDL_FreeSurface(tmpImage);
+ //SDL_FreeSurface(tmpImage); <-- We'll free the surface later.
Uint32 *pixels = static_cast< Uint32 * >(surf->pixels);
for (Uint32 *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
{
- int alpha = *pixels & 255;
+ int alpha = (*pixels >> rgba.Ashift) & 255;
if (!alpha) continue;
int v[3];
+
v[0] = (*pixels >> rgba.Rshift) & 255;
v[1] = (*pixels >> rgba.Gshift) & 255;
v[2] = (*pixels >> rgba.Bshift) & 255;
dye->update(v);
+
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
*pixels = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | alpha;
#else
@@ -71,53 +76,80 @@ SDL_Surface* recolor(SDL_Surface* tmpImage, Dye* dye)
return surf;
}
+void printHelp()
+{
+ cout << endl
+ << "This tool is used to dye item graphics used by the Mana client "
+ << "according to the specification described here: "
+ << endl << "http://doc.manasource.org/image_dyeing_system"
+ << endl << endl <<
+ "The tool expects 3 parameters:" << endl
+ << "dyecmd <source_image> <target_image> <dye_string>" << endl
+ << "e.g.:" << endl
+ << "dyecmd \"armor-legs-shorts.png\" "
+ <<"\"armor-legs-shorts2.png\" \"W:#222255,6666ff\"" << std::endl;
+}
+
int main(int argc, char* argv[])
{
Dye* dye = NULL;
- SDL_Surface* source = NULL;
+ SDL_Surface* source = NULL, *target = NULL;
+ ReturnValues returnValue = RETURN_OK;
- // not enough or to many parameters
- if (argc != 4)
+ if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
{
- cout << INVALID_PARAMETER_LIST << " - INVALID_PARAMETER_LIST";
- exit(INVALID_PARAMETER_LIST);
+ printHelp();
}
-
- try
+ // not enough or to many parameters
+ else if (argc != 4)
{
- dye = new Dye(argv[3]);
+ cout << INVALID_PARAMETER_LIST << " - INVALID_PARAMETER_LIST";
+ printHelp();
+ returnValue = INVALID_PARAMETER_LIST;
}
- catch (exception &e)
+ else
{
- cout << INVALID_DYE_PARAMETER << " - INVALID_DYE_PARAMETER";
- exit(INVALID_DYE_PARAMETER);
- }
+ // Start dyeing process.
+ string inputFile = argv[1];
+ string outputFile = argv[2];
+ string dyeDescription = argv[3];
- try
- {
- source = IMG_Load(argv[1]);
- if (!source)
+ dye = new Dye(dyeDescription);
+ if (!dye->loaded())
{
- throw;
+ cout << INVALID_DYE_PARAMETER << " - INVALID_DYE_PARAMETER";
+ printHelp();
+ returnValue = INVALID_DYE_PARAMETER;
}
- }
- catch (exception &e)
- {
- cout << INVALID_INPUT_IMAGE << " - INVALID_INPUT_IMAGE";
- exit(INVALID_INPUT_IMAGE);
- }
-
- SDL_Surface* target = recolor(source, dye);
-
- if (!ImageWriter::writePNG(target, argv[2]))
- {
- cout << INVALID_OUTPUT_IMAGE << " - INVALID_OUTPUT_IMAGE";
- exit(INVALID_OUTPUT_IMAGE);
- }
-
- SDL_FreeSurface(source);
- SDL_FreeSurface(target);
- delete dye;
-
- return 0;
+ else
+ {
+ source = IMG_Load(inputFile.c_str());
+ if (!source)
+ {
+ cout << INVALID_INPUT_IMAGE << " - INVALID_INPUT_IMAGE";
+ printHelp();
+ returnValue = INVALID_INPUT_IMAGE;
+ }
+ else
+ {
+ target = recolor(source, dye);
+
+ if (!ImageWriter::writePNG(target, outputFile))
+ {
+ cout << INVALID_OUTPUT_IMAGE << " - INVALID_OUTPUT_IMAGE";
+ printHelp();
+ returnValue = INVALID_OUTPUT_IMAGE;
+ }
+ } // Valid source image file
+ } // Valid dye parameter
+ } // Parameters ok
+
+ if (source)
+ SDL_FreeSurface(source);
+ if (target)
+ SDL_FreeSurface(target);
+ if (dye)
+ delete dye;
+
+ return returnValue;
}
diff --git a/tools/dyecmd/src/imagewriter.cpp b/tools/dyecmd/src/imagewriter.cpp
index 669b3567..d237abbf 100644..100755
--- a/tools/dyecmd/src/imagewriter.cpp
+++ b/tools/dyecmd/src/imagewriter.cpp
@@ -22,6 +22,7 @@
#include "imagewriter.h"
#include <png.h>
+#include <iostream>
#include <string>
#include <SDL/SDL.h>
@@ -32,8 +33,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
FILE *fp = fopen(filename.c_str(), "wb");
if (!fp)
{
- // todo
- // logger->log("could not open file %s for writing", filename.c_str());
+ std::cout << "PNG writer: Could not open file for writing: "
+ << filename << std::endl;
return false;
}
@@ -49,8 +50,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr)
{
- // todo
- // logger->log("Had trouble creating png_structp");
+ std::cout << "PNG writer: Had trouble creating png_structp"
+ << std::endl;
return false;
}
@@ -58,16 +59,15 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- // todo
- // logger->log("Could not create png_info");
+ std::cout << "PNG writer: Could not create png_info" << std::endl;
return false;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- // todo
- // logger->log("problem writing to %s", filename.c_str());
+ std::cout << "PNG writer: problem writing to : "
+ << filename << std::endl;
return false;
}
@@ -86,8 +86,9 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
row_pointers = new png_bytep[surface->h];
if (!row_pointers)
{
- // todo
- // logger->log("Had trouble converting surface to row pointers");
+ std::cout
+ << "PNG writer: Had trouble converting surface to row pointers"
+ << std::endl;
return false;
}
@@ -105,9 +106,8 @@ bool ImageWriter::writePNG(SDL_Surface *surface,
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- if (SDL_MUSTLOCK(surface)) {
+ if (SDL_MUSTLOCK(surface))
SDL_UnlockSurface(surface);
- }
return true;
}
diff --git a/tools/dyecmd/src/imagewriter.h b/tools/dyecmd/src/imagewriter.h
index a8bcdf57..a8bcdf57 100644..100755
--- a/tools/dyecmd/src/imagewriter.h
+++ b/tools/dyecmd/src/imagewriter.h