Merging r5975 through r6036 from trunk to ogl-es branch.
GLES drivers adapted, but only did make compile-tests. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
143
source/Irrlicht/CImageWriterTGA.cpp
Normal file
143
source/Irrlicht/CImageWriterTGA.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#include "CImageWriterTGA.h"
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_TGA_WRITER_
|
||||
|
||||
#include "CImageLoaderTGA.h"
|
||||
#include "IWriteFile.h"
|
||||
#include "CColorConverter.h"
|
||||
#include "irrString.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace video
|
||||
{
|
||||
|
||||
IImageWriter* createImageWriterTGA()
|
||||
{
|
||||
return new CImageWriterTGA;
|
||||
}
|
||||
|
||||
CImageWriterTGA::CImageWriterTGA()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CImageWriterTGA");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CImageWriterTGA::isAWriteableFileExtension(const io::path& filename) const
|
||||
{
|
||||
return core::hasFileExtension ( filename, "tga" );
|
||||
}
|
||||
|
||||
bool CImageWriterTGA::writeImage(io::IWriteFile *file, IImage *image,u32 param) const
|
||||
{
|
||||
STGAHeader imageHeader;
|
||||
imageHeader.IdLength = 0;
|
||||
imageHeader.ColorMapType = 0;
|
||||
imageHeader.ImageType = 2;
|
||||
imageHeader.FirstEntryIndex[0] = 0;
|
||||
imageHeader.FirstEntryIndex[1] = 0;
|
||||
imageHeader.ColorMapLength = 0;
|
||||
imageHeader.ColorMapEntrySize = 0;
|
||||
imageHeader.XOrigin[0] = 0;
|
||||
imageHeader.XOrigin[1] = 0;
|
||||
imageHeader.YOrigin[0] = 0;
|
||||
imageHeader.YOrigin[1] = 0;
|
||||
imageHeader.ImageWidth = image->getDimension().Width;
|
||||
imageHeader.ImageHeight = image->getDimension().Height;
|
||||
|
||||
// top left of image is the top. the image loader needs to
|
||||
// be fixed to only swap/flip
|
||||
imageHeader.ImageDescriptor = (1 << 5);
|
||||
|
||||
// chances are good we'll need to swizzle data, so i'm going
|
||||
// to convert and write one scan line at a time. it's also
|
||||
// a bit cleaner this way
|
||||
void (*CColorConverter_convertFORMATtoFORMAT)(const void*, s32, void*) = 0;
|
||||
switch(image->getColorFormat())
|
||||
{
|
||||
case ECF_A8R8G8B8:
|
||||
CColorConverter_convertFORMATtoFORMAT
|
||||
= CColorConverter::convert_A8R8G8B8toA8R8G8B8;
|
||||
imageHeader.PixelDepth = 32;
|
||||
imageHeader.ImageDescriptor |= 8;
|
||||
break;
|
||||
case ECF_A1R5G5B5:
|
||||
CColorConverter_convertFORMATtoFORMAT
|
||||
= CColorConverter::convert_A1R5G5B5toA1R5G5B5;
|
||||
imageHeader.PixelDepth = 16;
|
||||
imageHeader.ImageDescriptor |= 1;
|
||||
break;
|
||||
case ECF_R5G6B5:
|
||||
CColorConverter_convertFORMATtoFORMAT
|
||||
= CColorConverter::convert_R5G6B5toA1R5G5B5;
|
||||
imageHeader.PixelDepth = 16;
|
||||
imageHeader.ImageDescriptor |= 1;
|
||||
break;
|
||||
case ECF_R8G8B8:
|
||||
CColorConverter_convertFORMATtoFORMAT
|
||||
= CColorConverter::convert_R8G8B8toR8G8B8;
|
||||
imageHeader.PixelDepth = 24;
|
||||
imageHeader.ImageDescriptor |= 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// couldn't find a color converter
|
||||
if (!CColorConverter_convertFORMATtoFORMAT)
|
||||
return false;
|
||||
|
||||
if (file->write(&imageHeader, sizeof(imageHeader)) != sizeof(imageHeader))
|
||||
return false;
|
||||
|
||||
u8* scan_lines = (u8*)image->getData();
|
||||
if (!scan_lines)
|
||||
return false;
|
||||
|
||||
// size of one pixel in bytes
|
||||
u32 pixel_size = image->getBytesPerPixel();
|
||||
|
||||
// length of one row of the source image in bytes
|
||||
u32 row_stride = (pixel_size * imageHeader.ImageWidth);
|
||||
|
||||
// length of one output row in bytes
|
||||
size_t row_size = ((imageHeader.PixelDepth / 8) * imageHeader.ImageWidth);
|
||||
|
||||
// allocate a row do translate data into
|
||||
u8* row_pointer = new u8[row_size];
|
||||
|
||||
u32 y;
|
||||
for (y = 0; y < imageHeader.ImageHeight; ++y)
|
||||
{
|
||||
// source, length [pixels], destination
|
||||
if (image->getColorFormat()==ECF_R8G8B8)
|
||||
CColorConverter::convert24BitTo24Bit(&scan_lines[y * row_stride], row_pointer, imageHeader.ImageWidth, 1, 0, 0, true);
|
||||
else
|
||||
CColorConverter_convertFORMATtoFORMAT(&scan_lines[y * row_stride], imageHeader.ImageWidth, row_pointer);
|
||||
if (file->write(row_pointer, row_size) != row_size)
|
||||
break;
|
||||
}
|
||||
|
||||
delete [] row_pointer;
|
||||
|
||||
STGAFooter imageFooter;
|
||||
imageFooter.ExtensionOffset = 0;
|
||||
imageFooter.DeveloperOffset = 0;
|
||||
strncpy(imageFooter.Signature, "TRUEVISION-XFILE.", 18);
|
||||
|
||||
if (file->write(&imageFooter, sizeof(imageFooter)) < (s32)sizeof(imageFooter))
|
||||
return false;
|
||||
|
||||
return imageHeader.ImageHeight <= y;
|
||||
}
|
||||
|
||||
} // namespace video
|
||||
} // namespace irr
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user