diff --git a/source/g3d_viewer/main.cpp b/source/g3d_viewer/main.cpp index a66ae276..39caf152 100644 --- a/source/g3d_viewer/main.cpp +++ b/source/g3d_viewer/main.cpp @@ -781,9 +781,9 @@ void MainWindow::saveScreenshot() { string path = screenShotsPath; if(isdir(path.c_str()) == true) { - //Config &config= Config::getInstance(); - //string fileFormat = config.getString("ScreenShotFileType","png"); - string fileFormat = "png"; + Config &config= Config::getInstance(); + string fileFormat = config.getString("ScreenShotFileType","png"); + //string fileFormat = "png"; for(int i=0; i < 5000; ++i) { path = screenShotsPath; diff --git a/source/g3d_viewer/renderer.cpp b/source/g3d_viewer/renderer.cpp index 4bc0934e..9a405057 100644 --- a/source/g3d_viewer/renderer.cpp +++ b/source/g3d_viewer/renderer.cpp @@ -2,7 +2,7 @@ #include "graphics_factory_gl.h" #include "graphics_interface.h" -#include +//#include #include using namespace Shared::Graphics; diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 155b2437..7cecd32a 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -865,13 +865,13 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n%s=x=textureformat=keepsmallest\t\t\tconvert a model file or folder to the current g3d version format.",GAME_ARGS[GAME_ARG_CONVERT_MODELS]); printf("\n \t\tWhere x is a filename or folder containing the g3d model(s)."); - printf("\n \t\tWhere textureformat is an optional supported texture format to convert to (tga,bmp,png)."); + printf("\n \t\tWhere textureformat is an optional supported texture format to convert to (tga,bmp,jpg,png)."); printf("\n \t\tWhere keepsmallest is an optional flag indicating to keep original texture if its filesize is smaller than the converted format."); printf("\n \t\texample: %s %s=techs/megapack/factions/tech/units/castle/models/castle.g3d=png=keepsmallest",argv0,GAME_ARGS[GAME_ARG_CONVERT_MODELS]); printf("\n%s=x=textureformat\t\t\tconvert a texture file or folder to the format textureformat.",GAME_ARGS[GAME_ARG_CONVERT_TEXTURES]); printf("\n \t\tWhere x is a filename or folder containing the texture(s)."); - printf("\n \t\tWhere textureformat is a supported texture format to convert to (tga,bmp,png)."); + printf("\n \t\tWhere textureformat is a supported texture format to convert to (tga,bmp,jpg,png)."); printf("\n \t\texample: %s %s=data/core/misc_textures/fire_particle.tga=png",argv0,GAME_ARGS[GAME_ARG_CONVERT_TEXTURES]); printf("\n%s\t\tdisables stack backtrace on errors.",GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]); diff --git a/source/shared_lib/include/graphics/pixmap.h b/source/shared_lib/include/graphics/pixmap.h index feb9731a..6ecdc91f 100644 --- a/source/shared_lib/include/graphics/pixmap.h +++ b/source/shared_lib/include/graphics/pixmap.h @@ -116,6 +116,23 @@ public: virtual void write(uint8 *pixels); }; +class PixmapIoJpg: public PixmapIo { +private: + FILE *file; + string path; + +public: + PixmapIoJpg(); + virtual ~PixmapIoJpg(); + + virtual void openRead(const string &path); + virtual void read(uint8 *pixels); + virtual void read(uint8 *pixels, int components); + + virtual void openWrite(const string &path, int w, int h, int components); + virtual void write(uint8 *pixels); +}; + // ===================================================== // class Pixmap1D // ===================================================== @@ -179,6 +196,7 @@ public: void saveBmp(const string &path); void saveTga(const string &path); void savePng(const string &path); + void saveJpg(const string &path); //get int getW() const {return w;} diff --git a/source/shared_lib/sources/graphics/model.cpp b/source/shared_lib/sources/graphics/model.cpp index a67cb55b..d866f292 100644 --- a/source/shared_lib/sources/graphics/model.cpp +++ b/source/shared_lib/sources/graphics/model.cpp @@ -568,9 +568,17 @@ void Mesh::save(int meshIndex, const string &dir, FILE *f, TextureManager *textu textureDeleteList[file] = textureDeleteList[file] + 1; } } - //else if(convertTextureToFormat == "jpg") { - // texture->getPixmap()->saveJpg(file); - //} + else if(convertTextureToFormat == "jpg") { + texture->getPixmap()->saveJpg(file); + newSize = getFileSize(file); + if(keepsmallest == false || newSize <= originalSize) { + textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; + } + else { + printf("Texture will not be converted, keeping smallest texture [%s]\n",texture->getPath().c_str()); + textureDeleteList[file] = textureDeleteList[file] + 1; + } + } else if(convertTextureToFormat == "png") { texture->getPixmap()->savePng(file); newSize = getFileSize(file); diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index 76d2cec5..7bdfcbec 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -22,6 +22,7 @@ #include "FileReader.h" #include "ImageReaders.h" #include +#include #include #include @@ -559,6 +560,128 @@ void PixmapIoPng::write(uint8 *pixels) { */ } + + + + + + +// ===================================================== +// class PixmapIoJpg +// ===================================================== + +PixmapIoJpg::PixmapIoJpg() { + file= NULL; +} + +PixmapIoJpg::~PixmapIoJpg() { + if(file!=NULL){ + fclose(file); + file=NULL; + } +} + +void PixmapIoJpg::openRead(const string &path) { + + throw runtime_error("PixmapIoJpg::openRead not implemented!"); +} + +void PixmapIoJpg::read(uint8 *pixels) { + throw runtime_error("PixmapIoJpg::read not implemented!"); +} + +void PixmapIoJpg::read(uint8 *pixels, int components) { + + throw runtime_error("PixmapIoJpg::read #2 not implemented!"); +} + +void PixmapIoJpg::openWrite(const string &path, int w, int h, int components) { + this->path = path; + this->w= w; + this->h= h; + this->components= components; + + file= fopen(path.c_str(),"wb"); + if (file == NULL) { + throw runtime_error("Can't open JPG file for writing: "+ path); + } +} + +void PixmapIoJpg::write(uint8 *pixels) { + /* + * alpha channel is not supported for jpeg. strip it. + */ + unsigned char * tmpbytes = NULL; + if(components == 4) { + int n = w * h; + unsigned char *dst = tmpbytes = (unsigned char *) malloc(n*3); + const unsigned char *src = pixels; + for (int i = 0; i < n; i++) { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + src++; + } + components = 3; + } + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + + /* this is a pointer to one row of image data */ + JSAMPROW row_pointer[1]; + + cinfo.err = jpeg_std_error( &jerr ); + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, file); + + /* Setting the parameters of the output file here */ + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; // no alpha channel for jpeg + cinfo.in_color_space = JCS_RGB; + /* default compression parameters, we shouldn't be worried about these */ + jpeg_set_defaults( &cinfo ); + /* Now do the compression .. */ + jpeg_start_compress( &cinfo, TRUE ); + + /* use stripped alpha channel bytes */ + if(tmpbytes) { + pixels = tmpbytes; + } + + // OpenGL writes from bottom to top. + // libjpeg goes from top to bottom. + // flip lines. + uint8 *flip = (uint8 *)malloc(sizeof(uint8) * w * h * 3); + + for (int y = 0;y < h; ++y) { + for (int x = 0;x < w; ++x) { + flip[(y * w + x) * 3] = pixels[((h - 1 - y) * w + x) * 3]; + flip[(y * w + x) * 3 + 1] = pixels[((h - 1 - y) * w + x) * 3 + 1]; + flip[(y * w + x) * 3 + 2] = pixels[((h - 1 - y) * w + x) * 3 + 2]; + } + } + + /* like reading a file, this time write one row at a time */ + while( cinfo.next_scanline < cinfo.image_height ) { + row_pointer[0] = &flip[ cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; + jpeg_write_scanlines( &cinfo, row_pointer, 1 ); + } + if (tmpbytes) { + free(tmpbytes); + tmpbytes=NULL; + } + free(flip); + flip=NULL; + + /* similar to read file, clean up after we're done compressing */ + jpeg_finish_compress( &cinfo ); + jpeg_destroy_compress( &cinfo ); + //fclose( outfile ); + /* success code is 1! */ +} + // ===================================================== // class Pixmap1D // ===================================================== @@ -774,6 +897,9 @@ void Pixmap2D::save(const string &path) { else if(toLower(extension) == "tga") { saveTga(path); } + else if(toLower(extension) == "jpg") { + saveJpg(path); + } else if(toLower(extension) == "png") { savePng(path); } @@ -793,12 +919,19 @@ void Pixmap2D::saveTga(const string &path) { pst.openWrite(path, w, h, components); pst.write(pixels); } + +void Pixmap2D::saveJpg(const string &path) { + PixmapIoJpg pst; + pst.openWrite(path, w, h, components); + pst.write(pixels); +} + void Pixmap2D::savePng(const string &path) { PixmapIoPng pst; pst.openWrite(path, w, h, components); pst.write(pixels); - } + void Pixmap2D::getPixel(int x, int y, uint8 *value) const { for(int i=0; i