diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp index 91d290f331..ec396761c5 100644 --- a/apps/essimporter/converter.cpp +++ b/apps/essimporter/converter.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include #include @@ -15,12 +17,14 @@ namespace { - void convertImage(char* data, int size, int width, int height, Ogre::PixelFormat pf, const std::string& out) + void convertImage(char* data, int size, int width, int height, GLenum pf, const std::string& out) { - Ogre::Image screenshot; - Ogre::DataStreamPtr stream (new Ogre::MemoryDataStream(data, size)); - screenshot.loadRawData(stream, width, height, 1, pf); - screenshot.save(out); + osg::ref_ptr image (new osg::Image); + image->allocateImage(width, height, 1, pf, GL_UNSIGNED_BYTE); + memcpy(image->data(), data, size); + image->flipVertical(); + + osgDB::writeImageFile(*image, out); } @@ -71,17 +75,20 @@ namespace ESSImport data.resize(esm.getSubSize()); esm.getExact(&data[0], data.size()); - Ogre::DataStreamPtr stream (new Ogre::MemoryDataStream(&data[0], data.size())); - mGlobalMapImage.loadRawData(stream, maph.size, maph.size, 1, Ogre::PF_BYTE_RGB); + mGlobalMapImage = new osg::Image; + mGlobalMapImage->allocateImage(maph.size, maph.size, 1, GL_RGB, GL_UNSIGNED_BYTE); + memcpy(mGlobalMapImage->data(), &data[0], data.size()); + // to match openmw size - mGlobalMapImage.resize(maph.size*2, maph.size*2, Ogre::Image::FILTER_BILINEAR); + // FIXME: filtering? + mGlobalMapImage->scaleImage(maph.size*2, maph.size*2, 1, GL_UNSIGNED_BYTE); } void ConvertFMAP::write(ESM::ESMWriter &esm) { - int numcells = mGlobalMapImage.getWidth() / 18; // NB truncating, doesn't divide perfectly + int numcells = mGlobalMapImage->s() / 18; // NB truncating, doesn't divide perfectly // with the 512x512 map the game has by default - int cellSize = mGlobalMapImage.getWidth()/numcells; + int cellSize = mGlobalMapImage->s()/numcells; // Note the upper left corner of the (0,0) cell should be at (width/2, height/2) @@ -90,12 +97,14 @@ namespace ESSImport mContext->mGlobalMapState.mBounds.mMinY = -(numcells-1)/2; mContext->mGlobalMapState.mBounds.mMaxY = numcells/2; - Ogre::Image image2; - std::vector data; + osg::ref_ptr image2 (new osg::Image); int width = cellSize*numcells; int height = cellSize*numcells; + std::vector data; data.resize(width*height*4, 0); - image2.loadDynamicImage(&data[0], width, height, Ogre::PF_BYTE_RGBA); + + image2->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); + memcpy(image2->data(), &data[0], data.size()); for (std::set >::const_iterator it = mContext->mExploredCells.begin(); it != mContext->mExploredCells.end(); ++it) { @@ -108,8 +117,8 @@ namespace ESSImport continue; } - int imageLeftSrc = mGlobalMapImage.getWidth()/2; - int imageTopSrc = mGlobalMapImage.getHeight()/2; + int imageLeftSrc = mGlobalMapImage->s()/2; + int imageTopSrc = mGlobalMapImage->t()/2; imageLeftSrc += it->first * cellSize; imageTopSrc -= it->second * cellSize; int imageLeftDst = width/2; @@ -118,13 +127,31 @@ namespace ESSImport imageTopDst -= it->second * cellSize; for (int x=0; xdata(imageLeftSrc+x, imageTopSrc+y, 0); + *(unsigned int*)image2->data(imageLeftDst+x, imageTopDst+y, 0) = col; + } + } + + std::stringstream ostream; + osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); + if (!readerwriter) + { + std::cerr << "can't write global map image, no png readerwriter found" << std::endl; + return; + } + + image2->flipVertical(); + + osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*image2, ostream); + if (!result.success()) + { + std::cerr << "can't write global map image: " << result.message() << std::endl; + return; } - Ogre::DataStreamPtr encoded = image2.encode("png"); - mContext->mGlobalMapState.mImageData.resize(encoded->size()); - encoded->read(&mContext->mGlobalMapState.mImageData[0], encoded->size()); + std::string outData = ostream.str(); + mContext->mGlobalMapState.mImageData = std::vector(outData.begin(), outData.end()); esm.startRecord(ESM::REC_GMAP); mContext->mGlobalMapState.save(esm); @@ -194,7 +221,7 @@ namespace ESSImport std::ostringstream filename; filename << "fog_" << cell.mData.mX << "_" << cell.mData.mY << ".tga"; - convertImage((char*)&newcell.mFogOfWar[0], newcell.mFogOfWar.size()*4, 16, 16, Ogre::PF_BYTE_RGBA, filename.str()); + convertImage((char*)&newcell.mFogOfWar[0], newcell.mFogOfWar.size()*4, 16, 16, GL_RGBA, filename.str()); } } diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 5711e6754b..f00b254385 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -1,7 +1,8 @@ #ifndef OPENMW_ESSIMPORT_CONVERTER_H #define OPENMW_ESSIMPORT_CONVERTER_H -#include +#include +#include #include #include @@ -311,7 +312,7 @@ public: virtual void write(ESM::ESMWriter &esm); private: - Ogre::Image mGlobalMapImage; + osg::ref_ptr mGlobalMapImage; }; class ConvertCell : public Converter diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index d5ed43b8a0..3959a8f5cc 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -1,7 +1,8 @@ #include "importer.hpp" #include -#include +#include +#include #include #include @@ -32,13 +33,48 @@ namespace void writeScreenshot(const ESM::Header& fileHeader, ESM::SavedGame& out) { - Ogre::Image screenshot; - std::vector screenshotData = fileHeader.mSCRS; // MemoryDataStream doesn't work with const data :( - Ogre::DataStreamPtr screenshotStream (new Ogre::MemoryDataStream(&screenshotData[0], screenshotData.size())); - screenshot.loadRawData(screenshotStream, 128, 128, 1, Ogre::PF_BYTE_BGRA); - Ogre::DataStreamPtr encoded = screenshot.encode("jpg"); - out.mScreenshot.resize(encoded->size()); - encoded->read(&out.mScreenshot[0], encoded->size()); + if (fileHeader.mSCRS.size() != 128*128*4) + { + std::cerr << "unexpected screenshot size " << std::endl; + return; + } + + osg::ref_ptr image (new osg::Image); + image->allocateImage(128, 128, 1, GL_RGB, GL_UNSIGNED_BYTE); + + // need to convert pixel format from BGRA to RGB as the jpg readerwriter doesn't support it otherwise + std::vector::const_iterator it = fileHeader.mSCRS.begin(); + for (int y=0; y<128; ++y) + { + for (int x=0; x<128; ++x) + { + *(image->data(x,y)+2) = *it++; + *(image->data(x,y)+1) = *it++; + *image->data(x,y) = *it++; + it++; // skip alpha + } + } + + image->flipVertical(); + + std::stringstream ostream; + + osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("jpg"); + if (!readerwriter) + { + std::cerr << "can't write screenshot: no jpg readerwriter found" << std::endl; + return; + } + + osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*image, ostream); + if (!result.success()) + { + std::cerr << "can't write screenshot: " << result.message() << " code " << result.status() << std::endl; + return; + } + + std::string data = ostream.str(); + out.mScreenshot = std::vector(data.begin(), data.end()); } } @@ -203,10 +239,6 @@ namespace ESSImport void Importer::run() { - // construct Ogre::Root to gain access to image codecs - Ogre::LogManager logman; - Ogre::Root root; - ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncoding)); ESM::ESMReader esm; esm.open(mEssFile);