343 lines
9.4 KiB
C++
343 lines
9.4 KiB
C++
|
/****************************************************************************
|
||
|
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
||
|
|
||
|
http://www.genesis-3d.com.cn
|
||
|
|
||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
of this software and associated documentation files (the "Software"), to deal
|
||
|
in the Software without restriction, including without limitation the rights
|
||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
copies of the Software, and to permit persons to whom the Software is
|
||
|
furnished to do so, subject to the following conditions:
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included in
|
||
|
all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
|
THE SOFTWARE.
|
||
|
****************************************************************************/
|
||
|
#include "stdneb.h"
|
||
|
#include "resource/resource_stdneb.h"
|
||
|
#include "imageoperations.h"
|
||
|
#include "foundation/io/stream.h"
|
||
|
#include "foundation/io/ioserver.h"
|
||
|
|
||
|
|
||
|
// must define FREEIMAGE_LIB when use FreeImage as static lib
|
||
|
#define FREEIMAGE_LIB
|
||
|
// use free image to load image
|
||
|
#include "FreeImage/FreeImage.h"
|
||
|
|
||
|
// freeimage 3.9.1~3.11.0 interoperability fix
|
||
|
#ifndef FREEIMAGE_COLORORDER
|
||
|
// we have freeimage 3.9.1, define these symbols in such way as 3.9.1 really work (do not use 3.11.0 definition, as color order was changed between these two versions on Apple systems)
|
||
|
#define FREEIMAGE_COLORORDER_BGR 0
|
||
|
#define FREEIMAGE_COLORORDER_RGB 1
|
||
|
#if defined(FREEIMAGE_BIGENDIAN)
|
||
|
#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB
|
||
|
#else
|
||
|
#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_BGR
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifndef __WIN32__
|
||
|
|
||
|
//#error // @todo in iphone
|
||
|
|
||
|
// Color order is actually RGB on iPhone
|
||
|
//#if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
|
||
|
//#define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB
|
||
|
//#endif
|
||
|
|
||
|
#endif
|
||
|
|
||
|
namespace Resources
|
||
|
{
|
||
|
|
||
|
using namespace Math;
|
||
|
|
||
|
__ImplementClass(ImageOperations, 'IMOP', Core::RefCounted)
|
||
|
|
||
|
#define FOURCC(c0, c1, c2, c3) (c0 | (c1 << 8) | (c2 << 16) | (c3 << 24))
|
||
|
typedef uint uint32; // static_assert sizeof(uint)==4 later
|
||
|
typedef ushort uint16; // static_assert sizeof(uint16)==2 later
|
||
|
typedef ubyte uint8; // static_assert sizeof(uint16)==1 later
|
||
|
|
||
|
#include "addons/resource/DDS_Header.h"
|
||
|
|
||
|
ImageOperations::ImageOperations()
|
||
|
{
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
ImageOperations::~ImageOperations()
|
||
|
{}
|
||
|
#if __OSX__
|
||
|
|
||
|
#else
|
||
|
//------------------------------------------------------------------------
|
||
|
// Save dib to disk file to use native IO via memory stream instead of FreeImage IO
|
||
|
bool SaveToFile(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, const IO::URI& uri)
|
||
|
{
|
||
|
n_assert(dib);
|
||
|
bool ret = false;
|
||
|
FIMEMORY* hMem = FreeImage_OpenMemory();
|
||
|
if( FreeImage_SaveToMemory(fif,dib,hMem) )
|
||
|
{
|
||
|
// Note: After FreeImage_SaveToMemory hMem points at the end of memory stream
|
||
|
#if NEBULA3_DEBUG
|
||
|
long filememSize = FreeImage_TellMemory(hMem); // address of hMem equals the size of the file
|
||
|
#endif
|
||
|
FreeImage_SeekMemory(hMem,0,SEEK_SET);
|
||
|
IO::IoServer* ioServer = IO::IoServer::Instance();
|
||
|
n_assert(ioServer);
|
||
|
GPtr<IO::Stream> stream = ioServer->CreateFileStream(uri);
|
||
|
if ( stream )
|
||
|
{
|
||
|
stream->SetAccessMode(IO::Stream::WriteAccess);
|
||
|
if ( stream->Open() )
|
||
|
{
|
||
|
const int BufSize = 1024;
|
||
|
char buf[BufSize];
|
||
|
unsigned readCount = 0;
|
||
|
#if NEBULA3_DEBUG
|
||
|
long writeSize = 0;
|
||
|
#endif
|
||
|
do
|
||
|
{
|
||
|
readCount = FreeImage_ReadMemory(buf, 1, BufSize, hMem);
|
||
|
n_assert(readCount<=BufSize);
|
||
|
if ( readCount > 0 )
|
||
|
{
|
||
|
stream->Write(buf,readCount);
|
||
|
#if NEBULA3_DEBUG
|
||
|
writeSize += readCount;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
while ( readCount == BufSize );
|
||
|
|
||
|
#if NEBULA3_DEBUG
|
||
|
n_assert(writeSize==filememSize);
|
||
|
#endif
|
||
|
|
||
|
stream->Close();
|
||
|
ret = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FreeImage_CloseMemory(hMem);
|
||
|
return ret;
|
||
|
}
|
||
|
#endif
|
||
|
#if __OSX__
|
||
|
|
||
|
#else
|
||
|
//------------------------------------------------------------------------
|
||
|
bool ImageOperations::CreateTGAImageResAndSave(const Util::String &fileName, const int width, const int height, const Color32 &defaultColor)
|
||
|
{
|
||
|
FIBITMAP *dib = FreeImage_Allocate(width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
|
||
|
if (!dib)
|
||
|
{
|
||
|
n_warning("Create tga image res error.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
RGBQUAD rgbBkColor;
|
||
|
rgbBkColor.rgbRed = defaultColor.r;
|
||
|
rgbBkColor.rgbGreen = defaultColor.g;
|
||
|
rgbBkColor.rgbBlue = defaultColor.b;
|
||
|
rgbBkColor.rgbReserved = defaultColor.a;
|
||
|
|
||
|
//FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib); //for test
|
||
|
FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
|
||
|
switch(color_type)
|
||
|
{
|
||
|
case FIC_RGBALPHA:
|
||
|
{
|
||
|
//TODO(KouYan): To optimize, assign a value at a time
|
||
|
for (int y=0; y<height; y++)
|
||
|
{
|
||
|
for (int x=0; x<width; x++)
|
||
|
{
|
||
|
FreeImage_SetPixelColor(dib, x, y, &rgbBkColor);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
{
|
||
|
n_warning("CreateTGAImageResAndSave():do not support color type.");
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool ret = SaveToFile(FIF_TARGA, dib, fileName);
|
||
|
FreeImage_Unload(dib);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
bool ImageOperations::SaveTGAImage(const Util::String &imagePath, const GPtr<Resources::ImageRes> &res)
|
||
|
{
|
||
|
n_assert(imagePath.IsValid());
|
||
|
|
||
|
const SizeT width = res->GetWidth();
|
||
|
const SizeT height = res->GetHeight();
|
||
|
|
||
|
FIBITMAP *dib = FreeImage_Allocate(width, height, 32);
|
||
|
if (!dib)
|
||
|
{
|
||
|
n_warning("Create tga image res error.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
RGBQUAD rgbBkColor;
|
||
|
Math::ColorF tmpBuf;
|
||
|
|
||
|
FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
|
||
|
switch(color_type)
|
||
|
{
|
||
|
case FIC_RGBALPHA:
|
||
|
{
|
||
|
//TODO(KouYan): To optimize, assign a value at a time
|
||
|
for (int y=0; y<height; y++)
|
||
|
{
|
||
|
for (int x=0; x<width; x++)
|
||
|
{
|
||
|
res->GetPixels(x, y, 1, 1, 0, &tmpBuf);
|
||
|
rgbBkColor.rgbRed = n_scalartoByte(tmpBuf.r);
|
||
|
rgbBkColor.rgbGreen = n_scalartoByte(tmpBuf.g);
|
||
|
rgbBkColor.rgbBlue = n_scalartoByte(tmpBuf.b);
|
||
|
rgbBkColor.rgbReserved = n_scalartoByte(tmpBuf.a);
|
||
|
FreeImage_SetPixelColor(dib, x, y, &rgbBkColor);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
{
|
||
|
n_warning("CreateTGAImageResAndSave():do not support color type.");
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
FreeImage_FlipVertical(dib);
|
||
|
bool ret = SaveToFile(FIF_TARGA, dib, imagePath);
|
||
|
FreeImage_Unload(dib);
|
||
|
|
||
|
/*FIMEMORY* fiMem = FreeImage_OpenMemory( data, static_cast<DWORD>(size) );
|
||
|
FIBITMAP* fiBitmap = FreeImage_LoadFromMemory( (FREE_IMAGE_FORMAT)fileType, fiMem );
|
||
|
|
||
|
if (fiMem && fiBitmap)
|
||
|
{
|
||
|
ret = FreeImage_Save((FREE_IMAGE_FORMAT)fileType, fiBitmap, imagePath.AsCharPtr(), 0);
|
||
|
FreeImage_Unload(fiBitmap);
|
||
|
FreeImage_CloseMemory(fiMem);
|
||
|
}*/
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
//------------------------------------------------------------------------------
|
||
|
void ImageOperations::SaveDDSCubeImage(uint32 height_ , uint32 width_ ,const Util::String& fileName , void* data, int size)
|
||
|
{
|
||
|
DDSHeader ddsh;
|
||
|
unsigned int headerSize = sizeof(DDSHeader);
|
||
|
|
||
|
const uint value = 0x00;
|
||
|
Memory::Fill(&ddsh,headerSize,value);
|
||
|
|
||
|
ddsh.size = headerSize;
|
||
|
ddsh.flags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
|
||
|
ddsh.height = height_;
|
||
|
ddsh.width = width_;
|
||
|
|
||
|
ddsh.flags |= DDSD_PITCH;
|
||
|
|
||
|
ddsh.sizeOrPitch = ((width_ * 4 * 8 + 31) & -32) >> 3;
|
||
|
|
||
|
ddsh.pixelFormat.size = sizeof(DDSPixelFormat);
|
||
|
|
||
|
ddsh.pixelFormat.flags = DDPF_RGBA;
|
||
|
ddsh.pixelFormat.rgbBits = 32;
|
||
|
ddsh.pixelFormat.redMask = 0x00ff0000;
|
||
|
ddsh.pixelFormat.greenMask = 0x0000ff00;
|
||
|
ddsh.pixelFormat.blueMask = 0x000000ff;
|
||
|
|
||
|
|
||
|
ddsh.pixelFormat.flags |= DDPF_ALPHAPIXELS;
|
||
|
ddsh.pixelFormat.alphaMask = 0xff000000;
|
||
|
|
||
|
|
||
|
ddsh.caps.caps1 = DDSCAPS_TEXTURE;
|
||
|
ddsh.caps.caps1 |= DDSCAPS_COMPLEX;
|
||
|
ddsh.caps.caps2 = DDSCAPS2_CUBEMAP |
|
||
|
DDSCAPS2_CUBEMAP_POSITIVEX|
|
||
|
DDSCAPS2_CUBEMAP_NEGATIVEX|
|
||
|
DDSCAPS2_CUBEMAP_POSITIVEY|
|
||
|
DDSCAPS2_CUBEMAP_NEGATIVEY|
|
||
|
DDSCAPS2_CUBEMAP_POSITIVEZ|
|
||
|
DDSCAPS2_CUBEMAP_NEGATIVEZ;
|
||
|
|
||
|
|
||
|
const char* DDSName = "DDS ";
|
||
|
|
||
|
IO::URI tmpUri;
|
||
|
tmpUri.Set(fileName.AsCharPtr());
|
||
|
GPtr<IO::Stream> srcStream = IO::IoServer::Instance()->CreateFileStream(tmpUri);
|
||
|
srcStream->SetAccessMode(IO::Stream::WriteAccess);
|
||
|
|
||
|
if (srcStream->Open())
|
||
|
{
|
||
|
srcStream->Write(DDSName,4);
|
||
|
srcStream->Write(&ddsh,sizeof(DDSHeader));
|
||
|
srcStream->Write(data,size);
|
||
|
|
||
|
srcStream->Close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ImageOperations::HorizontalFlipImage( void* data,const int size ,const int width,const int height)
|
||
|
{
|
||
|
|
||
|
FIBITMAP *dib = FreeImage_Allocate(width, height, 32);
|
||
|
if (!dib)
|
||
|
{
|
||
|
n_warning("Create tga image res error.");
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
|
||
|
switch(color_type)
|
||
|
{
|
||
|
case FIC_RGBALPHA:
|
||
|
{
|
||
|
|
||
|
BYTE* src = FreeImage_GetBits(dib);
|
||
|
Memory::CopyToGraphicsMemory(data,src,size);
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
{
|
||
|
n_warning("HorizontalFlipImage():do not support color type.");
|
||
|
FreeImage_Unload(dib);
|
||
|
return ;
|
||
|
}
|
||
|
}
|
||
|
FreeImage_FlipHorizontal(dib);
|
||
|
|
||
|
BYTE* src = FreeImage_GetBits(dib);
|
||
|
|
||
|
Memory::CopyToGraphicsMemory(src,data,size);
|
||
|
|
||
|
FreeImage_Unload(dib);
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
}
|