Page 1 of 1

writeContentsToFile

Posted: Mon Aug 22, 2011 5:45 pm
by vilgeits
I don't know if this is the proper section to put this, if not could be this considered as a patch?
If the correct way to deal with this is a patch and you want to summit it yourself there is no problem :D

I miss from some time ago the option to choose quality of the saved .jpg files (probably the most used format) but this is really easy to fix (all this funcions are fixes over existing ones)

OgreFreeImageCodec.h

Code: Select all

        void codeToFile(MemoryDataStreamPtr& input, const String& outFileName, CodecDataPtr& pData,int jpgQuality  = 0) const;
OgreFreeImageCodec.cpp

Code: Select all

void FreeImageCodec::codeToFile(MemoryDataStreamPtr& input, 
        const String& outFileName, Codec::CodecDataPtr& pData,int jpgQuality) const
    {
		// Set error handler
		FreeImage_SetOutputMessage(FreeImageSaveErrorHandler);

		FIBITMAP* fiBitmap = encode(input, pData);
		if((FREE_IMAGE_FORMAT)mFreeImageType != (FREE_IMAGE_FORMAT)FREE_IMAGE_FORMAT::FIF_JPEG)
		{
		   FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str());
		}
		else
		{
		   switch(jpgQuality)
		   {
				case 0:
					FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str(),JPEG_QUALITYSUPERB+JPEG_OPTIMIZE+JPEG_BASELINE);
					break;
				case 1:
					FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str(),JPEG_QUALITYGOOD+JPEG_OPTIMIZE+JPEG_BASELINE);
					break;
				case 2:
					FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str(),JPEG_QUALITYNORMAL+JPEG_OPTIMIZE+JPEG_BASELINE);
					break;
				case 3:
					FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str(),JPEG_QUALITYAVERAGE+JPEG_OPTIMIZE+JPEG_BASELINE);
					break;
				default:
					FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str(),JPEG_QUALITYBAD+JPEG_OPTIMIZE+JPEG_BASELINE);
					break;
			}
		}
		FreeImage_Unload(fiBitmap);


    }


OgreImage.h

Code: Select all

void save(const String& filename, int jpgQuality=0);
OgreImage.cpp

Code: Select all

void Image::save(const String& filename,int jpgQuality)
	{
		if( !m_pBuffer )
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No image data loaded", 
				"Image::save");
		}

		String strExt;
		size_t pos = filename.find_last_of(".");
		if( pos == String::npos )
			OGRE_EXCEPT(
			Exception::ERR_INVALIDPARAMS, 
			"Unable to save image file '" + filename + "' - invalid extension.",
			"Image::save" );

		while( pos != filename.length() - 1 )
			strExt += filename[++pos];

		Codec * pCodec = Codec::getCodec(strExt);
		if( !pCodec )
			OGRE_EXCEPT(
			Exception::ERR_INVALIDPARAMS, 
			"Unable to save image file '" + filename + "' - invalid extension.",
			"Image::save" );

		ImageCodec::ImageData* imgData = OGRE_NEW ImageCodec::ImageData();
		imgData->format = m_eFormat;
		imgData->height = m_uHeight;
		imgData->width = m_uWidth;
		imgData->depth = m_uDepth;
		imgData->size = m_uSize;
		// Wrap in CodecDataPtr, this will delete
		Codec::CodecDataPtr codeDataPtr(imgData);
		// Wrap memory, be sure not to delete when stream destroyed
		MemoryDataStreamPtr wrapper(OGRE_NEW MemoryDataStream(m_pBuffer, m_uSize, false));

		pCodec->codeToFile(wrapper, filename, codeDataPtr,jpgQuality);
	}


OgreRenderTarget.h

Code: Select all

void writeContentsToFile(const String& filename,const int jpgQuality=0);
virtual String writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix,const int jpgQuality=0);
OgreRenderTarget.cpp

Code: Select all

 String RenderTarget::writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix,const int jpgQuality)
    {
        struct tm *pTime;
        time_t ctTime; time(&ctTime);
        pTime = localtime( &ctTime );
        Ogre::StringStream oss;
        oss	<< std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1)
            << std::setw(2) << std::setfill('0') << pTime->tm_mday
            << std::setw(2) << std::setfill('0') << (pTime->tm_year + 1900)
            << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour
            << std::setw(2) << std::setfill('0') << pTime->tm_min
            << std::setw(2) << std::setfill('0') << pTime->tm_sec
            << std::setw(3) << std::setfill('0') << (mTimer->getMilliseconds() % 1000);
        String filename = filenamePrefix + oss.str() + filenameSuffix;
        writeContentsToFile(filename,jpgQuality);
        return filename;

    }

void RenderTarget::writeContentsToFile(const String& filename,const int jpgQuality)
	{
		PixelFormat pf = suggestPixelFormat();

		uchar *data = OGRE_ALLOC_T(uchar, mWidth * mHeight * PixelUtil::getNumElemBytes(pf), MEMCATEGORY_RENDERSYS);
		PixelBox pb(mWidth, mHeight, 1, pf, data);

		copyContentsToMemory(pb);

		Image().loadDynamicImage(data, mWidth, mHeight, 1, pf, false, 1, 0).save(filename,jpgQuality);

		OGRE_FREE(data, MEMCATEGORY_RENDERSYS);
	}


Just to keep the same scheme:
OgreDDSCodec.h

Code: Select all

void codeToFile(MemoryDataStreamPtr& input, const String& outFileName, CodecDataPtr& pData,int jpgQuality=0) const;
OgreDDSCodec.cpp

Code: Select all

void DDSCodec::codeToFile(MemoryDataStreamPtr& input, const String& outFileName, Codec::CodecDataPtr& pData,int jpgQuality) 

Re: writeContentsToFile

Posted: Mon Aug 22, 2011 5:47 pm
by vilgeits
It simply ads a new (int) optional parameter to writeContentsToFile and writeContentsToTimestampedFile that indicates the quality:
- 0 ->Superb
- 1->Good
- 2->Normal
- 3->Average
- Other->bad

by default 0 (SuperB) is used.

Re: writeContentsToFile

Posted: Sun Aug 28, 2011 9:27 pm
by spacegaier