diff options
Diffstat (limited to 'tools')
-rwxr-xr-x[-rw-r--r--] | tools/dyecmd/src/dye.cpp | 96 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/dyecmd/src/dye.h | 19 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/dyecmd/src/dyecmd.cpp | 120 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/dyecmd/src/imagewriter.cpp | 24 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/dyecmd/src/imagewriter.h | 0 |
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 |