mirror of
https://github.com/id-Software/GtkRadiant.git
synced 2026-03-19 16:39:26 +01:00
The GtkRadiant sources as originally released under the GPL license.
This commit is contained in:
8
plugins/image/.cvsignore
Normal file
8
plugins/image/.cvsignore
Normal file
@@ -0,0 +1,8 @@
|
||||
Debug
|
||||
Release
|
||||
*.d
|
||||
*.plg
|
||||
*.BAK
|
||||
*.mak
|
||||
*.ncb
|
||||
*.opt
|
||||
207
plugins/image/bmp.cpp
Normal file
207
plugins/image/bmp.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "bmp.h"
|
||||
|
||||
#include "ifilesystem.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
#include "imagelib.h"
|
||||
#include "bytestreamutils.h"
|
||||
|
||||
|
||||
typedef unsigned char PaletteEntry[4];
|
||||
typedef struct
|
||||
{
|
||||
char id[2];
|
||||
unsigned long fileSize;
|
||||
unsigned long reserved0;
|
||||
unsigned long bitmapDataOffset;
|
||||
unsigned long bitmapHeaderSize;
|
||||
unsigned long width;
|
||||
unsigned long height;
|
||||
unsigned short planes;
|
||||
unsigned short bitsPerPixel;
|
||||
unsigned long compression;
|
||||
unsigned long bitmapDataSize;
|
||||
unsigned long hRes;
|
||||
unsigned long vRes;
|
||||
unsigned long colors;
|
||||
unsigned long importantColors;
|
||||
PaletteEntry palette[256];
|
||||
} BMPHeader_t;
|
||||
|
||||
class ReadPixel8
|
||||
{
|
||||
PaletteEntry* m_palette;
|
||||
public:
|
||||
ReadPixel8(PaletteEntry* palette) : m_palette(palette)
|
||||
{
|
||||
}
|
||||
void operator()(PointerInputStream& inputStream, byte*& pixbuf) const
|
||||
{
|
||||
byte palIndex;
|
||||
inputStream.read(&palIndex, 1);
|
||||
*pixbuf++ = m_palette[palIndex][2];
|
||||
*pixbuf++ = m_palette[palIndex][1];
|
||||
*pixbuf++ = m_palette[palIndex][0];
|
||||
*pixbuf++ = 0xff;
|
||||
}
|
||||
};
|
||||
|
||||
class ReadPixel16
|
||||
{
|
||||
public:
|
||||
void operator()(PointerInputStream& inputStream, byte*& pixbuf) const
|
||||
{
|
||||
unsigned short shortPixel;
|
||||
inputStream.read(reinterpret_cast<byte*>(&shortPixel), sizeof(unsigned short)); //!\todo Is this endian safe?
|
||||
*pixbuf++ = static_cast<byte>(shortPixel & (31 << 10)) >> 7;
|
||||
*pixbuf++ = static_cast<byte>(shortPixel & (31 << 5)) >> 2;
|
||||
*pixbuf++ = static_cast<byte>(shortPixel & (31)) << 3;
|
||||
*pixbuf++ = 0xff;
|
||||
}
|
||||
};
|
||||
|
||||
class ReadPixel24
|
||||
{
|
||||
public:
|
||||
void operator()(PointerInputStream& inputStream, byte*& pixbuf) const
|
||||
{
|
||||
byte bgr[3];
|
||||
inputStream.read(bgr, 3);
|
||||
*pixbuf++ = bgr[2];
|
||||
*pixbuf++ = bgr[1];
|
||||
*pixbuf++ = bgr[0];
|
||||
*pixbuf++ = 255;
|
||||
}
|
||||
};
|
||||
|
||||
class ReadPixel32
|
||||
{
|
||||
public:
|
||||
void operator()(PointerInputStream& inputStream, byte*& pixbuf) const
|
||||
{
|
||||
byte bgra[4];
|
||||
inputStream.read(bgra, 4);
|
||||
*pixbuf++ = bgra[2];
|
||||
*pixbuf++ = bgra[1];
|
||||
*pixbuf++ = bgra[0];
|
||||
*pixbuf++ = bgra[3];
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ReadPixel>
|
||||
void ReadBMP(PointerInputStream& inputStream, byte* bmpRGBA, int rows, int columns, ReadPixel readPixel)
|
||||
{
|
||||
for (int row = rows - 1; row >= 0; row--)
|
||||
{
|
||||
byte* pixbuf = bmpRGBA + row * columns * 4;
|
||||
|
||||
for (int column = 0; column < columns; column++)
|
||||
{
|
||||
readPixel(inputStream, pixbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image* LoadBMPBuff(PointerInputStream& inputStream, std::size_t length)
|
||||
{
|
||||
BMPHeader_t bmpHeader;
|
||||
inputStream.read(reinterpret_cast<byte*>(bmpHeader.id), 2);
|
||||
bmpHeader.fileSize = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.reserved0 = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.bitmapDataOffset = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.bitmapHeaderSize = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.width = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.height = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.planes = istream_read_uint16_le(inputStream);
|
||||
bmpHeader.bitsPerPixel = istream_read_uint16_le(inputStream);
|
||||
bmpHeader.compression = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.bitmapDataSize = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.hRes = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.vRes = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.colors = istream_read_uint32_le(inputStream);
|
||||
bmpHeader.importantColors = istream_read_uint32_le(inputStream);
|
||||
|
||||
if (bmpHeader.bitsPerPixel == 8)
|
||||
{
|
||||
int paletteSize = bmpHeader.colors * 4;
|
||||
inputStream.read(reinterpret_cast<byte*>(bmpHeader.palette), paletteSize);
|
||||
}
|
||||
|
||||
if (bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M')
|
||||
{
|
||||
globalErrorStream() << "LoadBMP: only Windows-style BMP files supported\n";
|
||||
return 0;
|
||||
}
|
||||
if (bmpHeader.fileSize != length)
|
||||
{
|
||||
globalErrorStream() << "LoadBMP: header size does not match file size (" << Unsigned(bmpHeader.fileSize) << " vs. " << Unsigned(length) << ")\n";
|
||||
return 0;
|
||||
}
|
||||
if (bmpHeader.compression != 0)
|
||||
{
|
||||
globalErrorStream() << "LoadBMP: only uncompressed BMP files supported\n";
|
||||
return 0;
|
||||
}
|
||||
if (bmpHeader.bitsPerPixel < 8)
|
||||
{
|
||||
globalErrorStream() << "LoadBMP: monochrome and 4-bit BMP files not supported\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
int columns = bmpHeader.width;
|
||||
int rows = bmpHeader.height;
|
||||
if (rows < 0)
|
||||
rows = -rows;
|
||||
|
||||
RGBAImage* image = new RGBAImage(columns, rows);
|
||||
|
||||
switch(bmpHeader.bitsPerPixel)
|
||||
{
|
||||
case 8:
|
||||
ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel8(bmpHeader.palette));
|
||||
break;
|
||||
case 16:
|
||||
ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel16());
|
||||
break;
|
||||
case 24:
|
||||
ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel24());
|
||||
break;
|
||||
case 32:
|
||||
ReadBMP(inputStream, image->getRGBAPixels(), rows, columns, ReadPixel32());
|
||||
break;
|
||||
default:
|
||||
globalErrorStream() << "LoadBMP: illegal pixel_size '" << bmpHeader.bitsPerPixel << "'\n";
|
||||
image->release();
|
||||
return 0;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
Image* LoadBMP(ArchiveFile& file)
|
||||
{
|
||||
ScopedArchiveBuffer buffer(file);
|
||||
PointerInputStream inputStream(buffer.buffer);
|
||||
return LoadBMPBuff(inputStream, buffer.length);
|
||||
}
|
||||
31
plugins/image/bmp.h
Normal file
31
plugins/image/bmp.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined (INCLUDED_BMP_H)
|
||||
#define INCLUDED_BMP_H
|
||||
|
||||
class Image;
|
||||
class ArchiveFile;
|
||||
|
||||
Image* LoadBMP(ArchiveFile& file);
|
||||
|
||||
#endif
|
||||
|
||||
56
plugins/image/dds.cpp
Normal file
56
plugins/image/dds.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "dds.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ifilesystem.h"
|
||||
#include "iarchive.h"
|
||||
#include "idatastream.h"
|
||||
|
||||
#include "ddslib.h"
|
||||
#include "imagelib.h"
|
||||
|
||||
Image* LoadDDSBuff(const byte* buffer)
|
||||
{
|
||||
int width, height;
|
||||
ddsPF_t pixelFormat;
|
||||
if(DDSGetInfo(reinterpret_cast<ddsBuffer_t*>(const_cast<byte*>(buffer)), &width, &height, &pixelFormat) == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RGBAImage* image = new RGBAImage(width, height);
|
||||
|
||||
if(DDSDecompress(reinterpret_cast<ddsBuffer_t*>(const_cast<byte*>(buffer)), image->getRGBAPixels()) == -1)
|
||||
{
|
||||
image->release();
|
||||
return 0;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
Image* LoadDDS(ArchiveFile& file)
|
||||
{
|
||||
ScopedArchiveBuffer buffer(file);
|
||||
return LoadDDSBuff(buffer.buffer);
|
||||
}
|
||||
30
plugins/image/dds.h
Normal file
30
plugins/image/dds.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_DDS_H)
|
||||
#define INCLUDED_DDS_H
|
||||
|
||||
class Image;
|
||||
class ArchiveFile;
|
||||
|
||||
Image* LoadDDS(ArchiveFile& file);
|
||||
|
||||
#endif
|
||||
162
plugins/image/image.cpp
Normal file
162
plugins/image/image.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include "ifilesystem.h"
|
||||
#include "iimage.h"
|
||||
|
||||
#include "jpeg.h"
|
||||
#include "tga.h"
|
||||
#include "bmp.h"
|
||||
#include "pcx.h"
|
||||
#include "dds.h"
|
||||
|
||||
|
||||
#include "modulesystem/singletonmodule.h"
|
||||
|
||||
class ImageDependencies : public GlobalFileSystemModuleRef
|
||||
{
|
||||
};
|
||||
|
||||
class ImageTGAAPI
|
||||
{
|
||||
_QERPlugImageTable m_imagetga;
|
||||
public:
|
||||
typedef _QERPlugImageTable Type;
|
||||
STRING_CONSTANT(Name, "tga");
|
||||
|
||||
ImageTGAAPI()
|
||||
{
|
||||
m_imagetga.loadImage = LoadTGA;
|
||||
}
|
||||
_QERPlugImageTable* getTable()
|
||||
{
|
||||
return &m_imagetga;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SingletonModule<ImageTGAAPI> ImageTGAModule;
|
||||
|
||||
ImageTGAModule g_ImageTGAModule;
|
||||
|
||||
|
||||
class ImageJPGAPI
|
||||
{
|
||||
_QERPlugImageTable m_imagejpg;
|
||||
public:
|
||||
typedef _QERPlugImageTable Type;
|
||||
STRING_CONSTANT(Name, "jpg");
|
||||
|
||||
ImageJPGAPI()
|
||||
{
|
||||
m_imagejpg.loadImage = LoadJPG;
|
||||
}
|
||||
_QERPlugImageTable* getTable()
|
||||
{
|
||||
return &m_imagejpg;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SingletonModule<ImageJPGAPI, ImageDependencies> ImageJPGModule;
|
||||
|
||||
ImageJPGModule g_ImageJPGModule;
|
||||
|
||||
|
||||
class ImageBMPAPI
|
||||
{
|
||||
_QERPlugImageTable m_imagebmp;
|
||||
public:
|
||||
typedef _QERPlugImageTable Type;
|
||||
STRING_CONSTANT(Name, "bmp");
|
||||
|
||||
ImageBMPAPI()
|
||||
{
|
||||
m_imagebmp.loadImage = LoadBMP;
|
||||
}
|
||||
_QERPlugImageTable* getTable()
|
||||
{
|
||||
return &m_imagebmp;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SingletonModule<ImageBMPAPI, ImageDependencies> ImageBMPModule;
|
||||
|
||||
ImageBMPModule g_ImageBMPModule;
|
||||
|
||||
|
||||
class ImagePCXAPI
|
||||
{
|
||||
_QERPlugImageTable m_imagepcx;
|
||||
public:
|
||||
typedef _QERPlugImageTable Type;
|
||||
STRING_CONSTANT(Name, "pcx");
|
||||
|
||||
ImagePCXAPI()
|
||||
{
|
||||
m_imagepcx.loadImage = LoadPCX32;
|
||||
}
|
||||
_QERPlugImageTable* getTable()
|
||||
{
|
||||
return &m_imagepcx;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SingletonModule<ImagePCXAPI, ImageDependencies> ImagePCXModule;
|
||||
|
||||
ImagePCXModule g_ImagePCXModule;
|
||||
|
||||
|
||||
class ImageDDSAPI
|
||||
{
|
||||
_QERPlugImageTable m_imagedds;
|
||||
public:
|
||||
typedef _QERPlugImageTable Type;
|
||||
STRING_CONSTANT(Name, "dds");
|
||||
|
||||
ImageDDSAPI()
|
||||
{
|
||||
m_imagedds.loadImage = LoadDDS;
|
||||
}
|
||||
_QERPlugImageTable* getTable()
|
||||
{
|
||||
return &m_imagedds;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SingletonModule<ImageDDSAPI, ImageDependencies> ImageDDSModule;
|
||||
|
||||
ImageDDSModule g_ImageDDSModule;
|
||||
|
||||
|
||||
extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server)
|
||||
{
|
||||
GlobalErrorStream::instance().setOutputStream(server.getErrorStream());
|
||||
GlobalOutputStream::instance().setOutputStream(server.getOutputStream());
|
||||
GlobalDebugMessageHandler::instance().setHandler(server.getDebugMessageHandler());
|
||||
GlobalModuleServer::instance().set(server);
|
||||
|
||||
g_ImageTGAModule.selfRegister();
|
||||
g_ImageJPGModule.selfRegister();
|
||||
g_ImageBMPModule.selfRegister();
|
||||
g_ImagePCXModule.selfRegister();
|
||||
g_ImageDDSModule.selfRegister();
|
||||
}
|
||||
166
plugins/image/image.dsp
Normal file
166
plugins/image/image.dsp
Normal file
@@ -0,0 +1,166 @@
|
||||
# Microsoft Developer Studio Project File - Name="image" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=image - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "image.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "image.mak" CFG="image - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "image - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "image - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "image"
|
||||
# PROP Scc_LocalPath "..\.."
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "image - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
F90=df.exe
|
||||
# ADD BASE F90 /compile_only /include:"Release/" /libs:dll /nologo /warn:nofileopt /dll
|
||||
# ADD F90 /compile_only /include:"Release/" /libs:dll /nologo /warn:nofileopt /dll
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMAGE_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /O2 /I "..\..\include" /I "..\..\..\gtk2-win32\include\glib-2.0" /I "..\..\..\gtk2-win32\lib\glib-2.0\include" /I "..\common" /I "..\..\libs" /I "..\..\libs\jpeg6" /I "..\..\..\STLPort\stlport" /I "..\..\..\libxml2\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMAGE_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 glib-2.0.lib jpeg6.lib /nologo /dll /machine:I386 /def:".\image.def" /libpath:"../../libs/jpeg6/release" /libpath:"..\..\..\gtk2-win32\lib\\"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
# Begin Special Build Tool
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Desc=Copy to dir...
|
||||
PostBuild_Cmds=copy Release\image.dll "../../install/modules"
|
||||
# End Special Build Tool
|
||||
|
||||
!ELSEIF "$(CFG)" == "image - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
F90=df.exe
|
||||
# ADD BASE F90 /check:bounds /compile_only /debug:full /include:"Debug/" /libs:dll /nologo /warn:argument_checking /warn:nofileopt /dll
|
||||
# ADD F90 /check:bounds /compile_only /debug:full /include:"Debug/" /libs:dll /nologo /warn:argument_checking /warn:nofileopt /dll
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMAGE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\..\include" /I "..\..\..\gtk2-win32\include\glib-2.0" /I "..\..\..\gtk2-win32\lib\glib-2.0\include" /I "..\common" /I "..\..\libs" /I "..\..\libs\jpeg6" /I "..\..\..\STLPort\stlport" /I "..\..\..\libxml2\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMAGE_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 glib-2.0.lib jpeg6.lib /nologo /dll /debug /machine:I386 /def:".\image.def" /pdbtype:sept /libpath:"../../libs/jpeg6/debug" /libpath:"..\..\..\gtk2-win32\lib\\"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
# Begin Special Build Tool
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Desc=Copy to dir...
|
||||
PostBuild_Cmds=copy Debug\image.dll "../../install/modules"
|
||||
# End Special Build Tool
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "image - Win32 Release"
|
||||
# Name "image - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bmp.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\image.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\image.def
|
||||
# PROP Exclude_From_Build 1
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jpeg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\pcx.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tga.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bmp.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\image.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jpeg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\pcx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tga.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
25
plugins/image/image.h
Normal file
25
plugins/image/image.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_IMAGE_H)
|
||||
#define INCLUDED_IMAGE_H
|
||||
|
||||
#endif
|
||||
7
plugins/image/imageq3.def
Normal file
7
plugins/image/imageq3.def
Normal file
@@ -0,0 +1,7 @@
|
||||
; imageq3.def : Declares the module parameters for the DLL.
|
||||
|
||||
LIBRARY "ImageQ3"
|
||||
|
||||
EXPORTS
|
||||
; Explicit exports can go here
|
||||
Radiant_RegisterModules @1
|
||||
231
plugins/image/imageq3.vcproj
Normal file
231
plugins/image/imageq3.vcproj
Normal file
@@ -0,0 +1,231 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="imageq3"
|
||||
ProjectGUID="{0A0D3519-2ADD-4B47-A890-746170B2CCD8}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../include;../../libs;"../../../STLPort-4.6/stlport";"../../../gtk2-2.4/include/glib-2.0";"../../../gtk2-2.4/lib/glib-2.0/include""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;IMAGEQ3_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
MinimalRebuild="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
BasicRuntimeChecks="0"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="FALSE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
BrowseInformation="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4610;4510;4512;4505;4100;4127"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/imageq3.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""
|
||||
IgnoreDefaultLibraryNames="msvcprtd.lib"
|
||||
ModuleDefinitionFile="$(ProjectName).def"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/imageq3.pdb"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(OutDir)/imageq3.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy "$(TargetPath)" "$(SolutionDir)install\modules"
|
||||
copy "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)install\modules""/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OptimizeForWindowsApplication="FALSE"
|
||||
AdditionalIncludeDirectories="../../include;../../libs;"../../../STLPort-4.6/stlport";"../../../gtk2-2.4/include/glib-2.0";"../../../gtk2-2.4/lib/glib-2.0/include""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IMAGEQ3_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
ExceptionHandling="FALSE"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="FALSE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4610;4510;4512;4505;4100;4127"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/imageq3.dll"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""
|
||||
IgnoreDefaultLibraryNames="msvcprt.lib"
|
||||
ModuleDefinitionFile="$(ProjectName).def"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
ImportLibrary="$(OutDir)/imageq3.lib"
|
||||
TargetMachine="1"
|
||||
FixedBaseAddress="0"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy "$(TargetPath)" "$(SolutionDir)install\modules"
|
||||
copy "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)install\modules""/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="src"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\image.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\image.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="modules"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\bmp.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\bmp.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dds.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dds.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jpeg.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\jpeg.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pcx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pcx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tga.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tga.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\..\debug.py">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="python "$(SolutionDir)debug.py""
|
||||
AdditionalDependencies=""$(SolutionDir)install\modules\$(TargetName).pdb""
|
||||
Outputs=""$(TargetDir)$(TargetName).pdb""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="python "$(SolutionDir)debug.py""
|
||||
AdditionalDependencies=""$(SolutionDir)install\modules\$(TargetName).pdb""
|
||||
Outputs=""$(TargetDir)$(TargetName).pdb""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\imageq3.def">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="python "$(SolutionDir)touch.py" "$(TargetPath)"
|
||||
"
|
||||
AdditionalDependencies=""$(SolutionDir)install\modules\$(TargetFileName)""
|
||||
Outputs=""$(TargetPath)""/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="python "$(SolutionDir)touch.py" "$(TargetPath)"
|
||||
"
|
||||
AdditionalDependencies=""$(SolutionDir)install\modules\$(TargetFileName)""
|
||||
Outputs=""$(TargetPath)""/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
406
plugins/image/jpeg.cpp
Normal file
406
plugins/image/jpeg.cpp
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
Copyright (c) 2001, Loki software, inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
Neither the name of Loki software nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// Functions to load JPEG files from a buffer, based on jdatasrc.c
|
||||
//
|
||||
// Leonardo Zide (leo@lokigames.com)
|
||||
//
|
||||
|
||||
#include "jpeg.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
#include "radiant_jpeglib.h"
|
||||
#include "jpeg6/jerror.h"
|
||||
}
|
||||
|
||||
#include "ifilesystem.h"
|
||||
|
||||
#include "imagelib.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
/* Expanded data source object for stdio input */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_source_mgr pub; /* public fields */
|
||||
|
||||
int src_size;
|
||||
JOCTET * src_buffer;
|
||||
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
boolean start_of_file; /* have we gotten any data yet? */
|
||||
} my_source_mgr;
|
||||
|
||||
typedef my_source_mgr * my_src_ptr;
|
||||
|
||||
#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize source --- called by jpeg_read_header
|
||||
* before any data is actually read.
|
||||
*/
|
||||
|
||||
static void my_init_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* We reset the empty-input-file flag for each image,
|
||||
* but we don't clear the input buffer.
|
||||
* This is correct behavior for reading a series of images from one source.
|
||||
*/
|
||||
src->start_of_file = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill the input buffer --- called whenever buffer is emptied.
|
||||
*
|
||||
* In typical applications, this should read fresh data into the buffer
|
||||
* (ignoring the current state of next_input_byte & bytes_in_buffer),
|
||||
* reset the pointer & count to the start of the buffer, and return TRUE
|
||||
* indicating that the buffer has been reloaded. It is not necessary to
|
||||
* fill the buffer entirely, only to obtain at least one more byte.
|
||||
*
|
||||
* There is no such thing as an EOF return. If the end of the file has been
|
||||
* reached, the routine has a choice of ERREXIT() or inserting fake data into
|
||||
* the buffer. In most cases, generating a warning message and inserting a
|
||||
* fake EOI marker is the best course of action --- this will allow the
|
||||
* decompressor to output however much of the image is there. However,
|
||||
* the resulting error message is misleading if the real problem is an empty
|
||||
* input file, so we handle that case specially.
|
||||
*
|
||||
* In applications that need to be able to suspend compression due to input
|
||||
* not being available yet, a FALSE return indicates that no more data can be
|
||||
* obtained right now, but more may be forthcoming later. In this situation,
|
||||
* the decompressor will return to its caller (with an indication of the
|
||||
* number of scanlines it has read, if any). The application should resume
|
||||
* decompression after it has loaded more data into the input buffer. Note
|
||||
* that there are substantial restrictions on the use of suspension --- see
|
||||
* the documentation.
|
||||
*
|
||||
* When suspending, the decompressor will back up to a convenient restart point
|
||||
* (typically the start of the current MCU). next_input_byte & bytes_in_buffer
|
||||
* indicate where the restart point will be if the current call returns FALSE.
|
||||
* Data beyond this point must be rescanned after resumption, so move it to
|
||||
* the front of the buffer rather than discarding it.
|
||||
*/
|
||||
|
||||
static boolean my_fill_input_buffer (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
size_t nbytes;
|
||||
|
||||
if (src->src_size > INPUT_BUF_SIZE)
|
||||
nbytes = INPUT_BUF_SIZE;
|
||||
else
|
||||
nbytes = src->src_size;
|
||||
|
||||
memcpy (src->buffer, src->src_buffer, nbytes);
|
||||
src->src_buffer += nbytes;
|
||||
src->src_size -= nbytes;
|
||||
|
||||
if (nbytes <= 0) {
|
||||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
||||
/* Insert a fake EOI marker */
|
||||
src->buffer[0] = (JOCTET) 0xFF;
|
||||
src->buffer[1] = (JOCTET) JPEG_EOI;
|
||||
nbytes = 2;
|
||||
}
|
||||
|
||||
src->pub.next_input_byte = src->buffer;
|
||||
src->pub.bytes_in_buffer = nbytes;
|
||||
src->start_of_file = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Skip data --- used to skip over a potentially large amount of
|
||||
* uninteresting data (such as an APPn marker).
|
||||
*
|
||||
* Writers of suspendable-input applications must note that skip_input_data
|
||||
* is not granted the right to give a suspension return. If the skip extends
|
||||
* beyond the data currently in the buffer, the buffer can be marked empty so
|
||||
* that the next read will cause a fill_input_buffer call that can suspend.
|
||||
* Arranging for additional bytes to be discarded before reloading the input
|
||||
* buffer is the application writer's problem.
|
||||
*/
|
||||
|
||||
static void my_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* Just a dumb implementation for now. Could use fseek() except
|
||||
* it doesn't work on pipes. Not clear that being smart is worth
|
||||
* any trouble anyway --- large skips are infrequent.
|
||||
*/
|
||||
if (num_bytes > 0) {
|
||||
while (num_bytes > (long) src->pub.bytes_in_buffer) {
|
||||
num_bytes -= (long) src->pub.bytes_in_buffer;
|
||||
(void) my_fill_input_buffer(cinfo);
|
||||
/* note we assume that fill_input_buffer will never return FALSE,
|
||||
* so suspension need not be handled.
|
||||
*/
|
||||
}
|
||||
src->pub.next_input_byte += (size_t) num_bytes;
|
||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* An additional method that can be provided by data source modules is the
|
||||
* resync_to_restart method for error recovery in the presence of RST markers.
|
||||
* For the moment, this source module just uses the default resync method
|
||||
* provided by the JPEG library. That method assumes that no backtracking
|
||||
* is possible.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Terminate source --- called by jpeg_finish_decompress
|
||||
* after all data has been read. Often a no-op.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
static void my_term_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for input from a stdio stream.
|
||||
* The caller must have already opened the stream, and is responsible
|
||||
* for closing it after finishing decompression.
|
||||
*/
|
||||
|
||||
static void jpeg_buffer_src (j_decompress_ptr cinfo, void* buffer, int bufsize)
|
||||
{
|
||||
my_src_ptr src;
|
||||
|
||||
/* The source object and input buffer are made permanent so that a series
|
||||
* of JPEG images can be read from the same file by calling jpeg_stdio_src
|
||||
* only before the first one. (If we discarded the buffer at the end of
|
||||
* one image, we'd likely lose the start of the next one.)
|
||||
* This makes it unsafe to use this manager and a different source
|
||||
* manager serially with the same JPEG object. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
sizeof (my_source_mgr));
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->buffer = (JOCTET *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
INPUT_BUF_SIZE * sizeof (JOCTET));
|
||||
}
|
||||
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->pub.init_source = my_init_source;
|
||||
src->pub.fill_input_buffer = my_fill_input_buffer;
|
||||
src->pub.skip_input_data = my_skip_input_data;
|
||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
||||
src->pub.term_source = my_term_source;
|
||||
src->src_buffer = (JOCTET *)buffer;
|
||||
src->src_size = bufsize;
|
||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
static char errormsg[JMSG_LENGTH_MAX];
|
||||
|
||||
typedef struct my_jpeg_error_mgr
|
||||
{
|
||||
struct jpeg_error_mgr pub; // "public" fields
|
||||
jmp_buf setjmp_buffer; // for return to caller
|
||||
} bt_jpeg_error_mgr;
|
||||
|
||||
static void my_jpeg_error_exit (j_common_ptr cinfo)
|
||||
{
|
||||
my_jpeg_error_mgr* myerr = (bt_jpeg_error_mgr*) cinfo->err;
|
||||
|
||||
(*cinfo->err->format_message) (cinfo, errormsg);
|
||||
|
||||
longjmp (myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
// stash a scanline
|
||||
static void j_putRGBScanline (unsigned char* jpegline, int widthPix, unsigned char* outBuf, int row)
|
||||
{
|
||||
int offset = row * widthPix * 4;
|
||||
int count;
|
||||
|
||||
for (count = 0; count < widthPix; count++)
|
||||
{
|
||||
unsigned char iRed, iBlu, iGrn;
|
||||
unsigned char *oRed, *oBlu, *oGrn, *oAlp;
|
||||
|
||||
iRed = *(jpegline + count * 3 + 0);
|
||||
iGrn = *(jpegline + count * 3 + 1);
|
||||
iBlu = *(jpegline + count * 3 + 2);
|
||||
|
||||
oRed = outBuf + offset + count * 4 + 0;
|
||||
oGrn = outBuf + offset + count * 4 + 1;
|
||||
oBlu = outBuf + offset + count * 4 + 2;
|
||||
oAlp = outBuf + offset + count * 4 + 3;
|
||||
|
||||
*oRed = iRed;
|
||||
*oGrn = iGrn;
|
||||
*oBlu = iBlu;
|
||||
*oAlp = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// stash a scanline
|
||||
static void j_putRGBAScanline (unsigned char* jpegline, int widthPix, unsigned char* outBuf, int row)
|
||||
{
|
||||
int offset = row * widthPix * 4;
|
||||
int count;
|
||||
|
||||
for (count = 0; count < widthPix; count++)
|
||||
{
|
||||
unsigned char iRed, iBlu, iGrn, iAlp;
|
||||
unsigned char *oRed, *oBlu, *oGrn, *oAlp;
|
||||
|
||||
iRed = *(jpegline + count * 4 + 0);
|
||||
iGrn = *(jpegline + count * 4 + 1);
|
||||
iBlu = *(jpegline + count * 4 + 2);
|
||||
iAlp = *(jpegline + count * 4 + 3);
|
||||
|
||||
oRed = outBuf + offset + count * 4 + 0;
|
||||
oGrn = outBuf + offset + count * 4 + 1;
|
||||
oBlu = outBuf + offset + count * 4 + 2;
|
||||
oAlp = outBuf + offset + count * 4 + 3;
|
||||
|
||||
*oRed = iRed;
|
||||
*oGrn = iGrn;
|
||||
*oBlu = iBlu;
|
||||
|
||||
//!\todo fix jpeglib, it leaves alpha channel uninitialised
|
||||
#if 1
|
||||
*oAlp = 255;
|
||||
#else
|
||||
*oAlp = iAlp;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// stash a gray scanline
|
||||
static void j_putGrayScanlineToRGB (unsigned char* jpegline, int widthPix, unsigned char* outBuf, int row)
|
||||
{
|
||||
int offset = row * widthPix * 4;
|
||||
int count;
|
||||
|
||||
for (count = 0; count < widthPix; count++)
|
||||
{
|
||||
unsigned char iGray;
|
||||
unsigned char *oRed, *oBlu, *oGrn, *oAlp;
|
||||
|
||||
// get our grayscale value
|
||||
iGray = *(jpegline + count);
|
||||
|
||||
oRed = outBuf + offset + count * 4;
|
||||
oGrn = outBuf + offset + count * 4 + 1;
|
||||
oBlu = outBuf + offset + count * 4 + 2;
|
||||
oAlp = outBuf + offset + count * 4 + 3;
|
||||
|
||||
*oRed = iGray;
|
||||
*oGrn = iGray;
|
||||
*oBlu = iGray;
|
||||
*oAlp = 255;
|
||||
}
|
||||
}
|
||||
|
||||
static Image* LoadJPGBuff_(const void *src_buffer, int src_size)
|
||||
{
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct my_jpeg_error_mgr jerr;
|
||||
|
||||
cinfo.err = jpeg_std_error (&jerr.pub);
|
||||
jerr.pub.error_exit = my_jpeg_error_exit;
|
||||
|
||||
if (setjmp (jerr.setjmp_buffer)) //< TODO: use c++ exceptions instead of setjmp/longjmp to handle errors
|
||||
{
|
||||
globalErrorStream() << "WARNING: JPEG library error: " << errormsg << "\n";
|
||||
jpeg_destroy_decompress (&cinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
jpeg_create_decompress (&cinfo);
|
||||
jpeg_buffer_src (&cinfo, const_cast<void*>(src_buffer), src_size);
|
||||
jpeg_read_header (&cinfo, TRUE);
|
||||
jpeg_start_decompress (&cinfo);
|
||||
|
||||
int row_stride = cinfo.output_width * cinfo.output_components;
|
||||
|
||||
RGBAImage* image = new RGBAImage(cinfo.output_width, cinfo.output_height);
|
||||
|
||||
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height)
|
||||
{
|
||||
jpeg_read_scanlines (&cinfo, buffer, 1);
|
||||
|
||||
if (cinfo.out_color_components == 4)
|
||||
j_putRGBAScanline (buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline-1);
|
||||
else if (cinfo.out_color_components == 3)
|
||||
j_putRGBScanline (buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline-1);
|
||||
else if (cinfo.out_color_components == 1)
|
||||
j_putGrayScanlineToRGB (buffer[0], cinfo.output_width, image->getRGBAPixels(), cinfo.output_scanline-1);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress (&cinfo);
|
||||
jpeg_destroy_decompress (&cinfo);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
Image* LoadJPG(ArchiveFile& file)
|
||||
{
|
||||
ScopedArchiveBuffer buffer(file);
|
||||
return LoadJPGBuff_(buffer.buffer, static_cast<int>(buffer.length));
|
||||
}
|
||||
|
||||
40
plugins/image/jpeg.h
Normal file
40
plugins/image/jpeg.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (c) 2001, Loki software, inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
Neither the name of Loki software nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined (INCLUDED_JPEG_H)
|
||||
#define INCLUDED_JPEG_H
|
||||
|
||||
class Image;
|
||||
class ArchiveFile;
|
||||
|
||||
Image* LoadJPG(ArchiveFile& file);
|
||||
|
||||
#endif
|
||||
|
||||
222
plugins/image/pcx.cpp
Normal file
222
plugins/image/pcx.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "pcx.h"
|
||||
|
||||
#include "ifilesystem.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "imagelib.h"
|
||||
#include "bytestreamutils.h"
|
||||
|
||||
/*
|
||||
=================================================================
|
||||
|
||||
PCX LOADING
|
||||
|
||||
=================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char manufacturer;
|
||||
unsigned char version;
|
||||
unsigned char encoding;
|
||||
unsigned char bits_per_pixel;
|
||||
unsigned short xmin, ymin, xmax, ymax;
|
||||
unsigned short hres, vres;
|
||||
unsigned char palette[48];
|
||||
unsigned char reserved;
|
||||
unsigned char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
unsigned char filler[58];
|
||||
unsigned char data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
/*
|
||||
==============
|
||||
LoadPCX
|
||||
==============
|
||||
*/
|
||||
|
||||
struct PCXRLEPacket
|
||||
{
|
||||
byte data;
|
||||
int length;
|
||||
};
|
||||
|
||||
inline void ByteStream_readPCXRLEPacket(PointerInputStream& inputStream, PCXRLEPacket& packet)
|
||||
{
|
||||
byte d;
|
||||
inputStream.read(&d, 1);
|
||||
if((d & 0xC0) == 0xC0)
|
||||
{
|
||||
packet.length = d & 0x3F;
|
||||
inputStream.read(&packet.data, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.length = 1;
|
||||
packet.data = d;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadPCXBuff(byte* buffer, std::size_t len, byte **pic, byte **palette, int *width, int *height )
|
||||
{
|
||||
*pic = 0;
|
||||
|
||||
pcx_t pcx;
|
||||
int x, y, lsize;
|
||||
byte *out, *pix;
|
||||
|
||||
/* parse the PCX file */
|
||||
|
||||
PointerInputStream inputStream(buffer);
|
||||
|
||||
pcx.manufacturer = istream_read_byte(inputStream);
|
||||
pcx.version = istream_read_byte(inputStream);
|
||||
pcx.encoding = istream_read_byte(inputStream);
|
||||
pcx.bits_per_pixel = istream_read_byte(inputStream);
|
||||
pcx.xmin = istream_read_int16_le(inputStream);
|
||||
pcx.ymin = istream_read_int16_le(inputStream);
|
||||
pcx.xmax = istream_read_int16_le(inputStream);
|
||||
pcx.ymax = istream_read_int16_le(inputStream);
|
||||
pcx.hres = istream_read_int16_le(inputStream);
|
||||
pcx.vres = istream_read_int16_le(inputStream);
|
||||
inputStream.read(pcx.palette, 48);
|
||||
pcx.reserved = istream_read_byte(inputStream);
|
||||
pcx.color_planes = istream_read_byte(inputStream);
|
||||
pcx.bytes_per_line = istream_read_int16_le(inputStream);
|
||||
pcx.palette_type = istream_read_int16_le(inputStream);
|
||||
inputStream.read(pcx.filler, 58);
|
||||
|
||||
|
||||
if (pcx.manufacturer != 0x0a
|
||||
|| pcx.version != 5
|
||||
|| pcx.encoding != 1
|
||||
|| pcx.bits_per_pixel != 8)
|
||||
return;
|
||||
|
||||
if (width)
|
||||
*width = pcx.xmax+1;
|
||||
if (height)
|
||||
*height = pcx.ymax+1;
|
||||
|
||||
if (!pic)
|
||||
return;
|
||||
|
||||
out = (byte *)malloc ( (pcx.ymax+1) * (pcx.xmax+1) );
|
||||
|
||||
*pic = out;
|
||||
pix = out;
|
||||
|
||||
/* RR2DO2: pcx fix */
|
||||
lsize = pcx.color_planes * pcx.bytes_per_line;
|
||||
|
||||
/* go scanline by scanline */
|
||||
for( y = 0; y <= pcx.ymax; y++, pix += pcx.xmax + 1 )
|
||||
{
|
||||
/* do a scanline */
|
||||
for( x=0; x <= pcx.xmax; )
|
||||
{
|
||||
/* RR2DO2 */
|
||||
PCXRLEPacket packet;
|
||||
ByteStream_readPCXRLEPacket(inputStream, packet);
|
||||
|
||||
while(packet.length-- > 0)
|
||||
{
|
||||
pix[ x++ ] = packet.data;
|
||||
}
|
||||
}
|
||||
|
||||
/* RR2DO2: discard any other data */
|
||||
PCXRLEPacket packet;
|
||||
while( x < lsize )
|
||||
{
|
||||
ByteStream_readPCXRLEPacket(inputStream, packet);
|
||||
x++;
|
||||
}
|
||||
while( packet.length-- > 0 )
|
||||
{
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
/* validity check */
|
||||
if( std::size_t(inputStream.get() - buffer) > len)
|
||||
{
|
||||
*pic = 0;
|
||||
}
|
||||
|
||||
if (palette)
|
||||
{
|
||||
*palette = (byte *)malloc(768);
|
||||
memcpy (*palette, buffer + len - 768, 768);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
LoadPCX32
|
||||
==============
|
||||
*/
|
||||
Image* LoadPCX32Buff(byte* buffer, std::size_t length)
|
||||
{
|
||||
byte *palette;
|
||||
byte *pic8;
|
||||
int i, c, p, width, height;
|
||||
byte *pic32;
|
||||
|
||||
LoadPCXBuff(buffer, length, &pic8, &palette, &width, &height);
|
||||
if (!pic8)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
RGBAImage* image = new RGBAImage(width, height);
|
||||
c = (width) * (height);
|
||||
pic32 = image->getRGBAPixels();
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
p = pic8[i];
|
||||
pic32[0] = palette[p * 3];
|
||||
pic32[1] = palette[p * 3 + 1];
|
||||
pic32[2] = palette[p * 3 + 2];
|
||||
pic32[3] = 255;
|
||||
pic32 += 4;
|
||||
}
|
||||
|
||||
free (pic8);
|
||||
free (palette);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
Image* LoadPCX32(ArchiveFile& file)
|
||||
{
|
||||
ScopedArchiveBuffer buffer(file);
|
||||
return LoadPCX32Buff(buffer.buffer, buffer.length);
|
||||
}
|
||||
|
||||
30
plugins/image/pcx.h
Normal file
30
plugins/image/pcx.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined (INCLUDED_PCX_H)
|
||||
#define INCLUDED_PCX_H
|
||||
|
||||
class Image;
|
||||
class ArchiveFile;
|
||||
|
||||
Image* LoadPCX32(ArchiveFile& file);
|
||||
|
||||
#endif
|
||||
420
plugins/image/tga.cpp
Normal file
420
plugins/image/tga.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "tga.h"
|
||||
|
||||
#include "ifilesystem.h"
|
||||
#include "iarchive.h"
|
||||
#include "idatastream.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "generic/bitfield.h"
|
||||
#include "imagelib.h"
|
||||
#include "bytestreamutils.h"
|
||||
|
||||
// represents x,y origin of tga image being decoded
|
||||
class Flip00 {}; // no flip
|
||||
class Flip01 {}; // vertical flip only
|
||||
class Flip10 {}; // horizontal flip only
|
||||
class Flip11 {}; // both
|
||||
|
||||
template<typename PixelDecoder>
|
||||
void image_decode(PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip00&)
|
||||
{
|
||||
RGBAPixel* end = image.pixels + (image.height * image.width);
|
||||
for(RGBAPixel* row = end; row != image.pixels; row -= image.width)
|
||||
{
|
||||
for(RGBAPixel* pixel = row - image.width; pixel != row; ++pixel)
|
||||
{
|
||||
decode(istream, *pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PixelDecoder>
|
||||
void image_decode(PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip01&)
|
||||
{
|
||||
RGBAPixel* end = image.pixels + (image.height * image.width);
|
||||
for(RGBAPixel* row = image.pixels; row != end; row += image.width)
|
||||
{
|
||||
for(RGBAPixel* pixel = row; pixel != row + image.width; ++pixel)
|
||||
{
|
||||
decode(istream, *pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PixelDecoder>
|
||||
void image_decode(PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip10&)
|
||||
{
|
||||
RGBAPixel* end = image.pixels + (image.height * image.width);
|
||||
for(RGBAPixel* row = end; row != image.pixels; row -= image.width)
|
||||
{
|
||||
for(RGBAPixel* pixel = row; pixel != row - image.width;)
|
||||
{
|
||||
decode(istream, *--pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PixelDecoder>
|
||||
void image_decode(PointerInputStream& istream, PixelDecoder& decode, RGBAImage& image, const Flip11&)
|
||||
{
|
||||
RGBAPixel* end = image.pixels + (image.height * image.width);
|
||||
for(RGBAPixel* row = image.pixels; row != end; row += image.width)
|
||||
{
|
||||
for(RGBAPixel* pixel = row + image.width; pixel != row;)
|
||||
{
|
||||
decode(istream, *--pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void istream_read_gray(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
istream.read(&pixel.blue, 1);
|
||||
pixel.red = pixel.green = pixel.blue;
|
||||
pixel.alpha = 0xff;
|
||||
}
|
||||
|
||||
inline void istream_read_rgb(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
istream.read(&pixel.blue, 1);
|
||||
istream.read(&pixel.green, 1);
|
||||
istream.read(&pixel.red, 1);
|
||||
pixel.alpha = 0xff;
|
||||
}
|
||||
|
||||
inline void istream_read_rgba(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
istream.read(&pixel.blue, 1);
|
||||
istream.read(&pixel.green, 1);
|
||||
istream.read(&pixel.red, 1);
|
||||
istream.read(&pixel.alpha, 1);
|
||||
}
|
||||
|
||||
class TargaDecodeGrayPixel
|
||||
{
|
||||
public:
|
||||
void operator()(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
istream_read_gray(istream, pixel);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Flip>
|
||||
void targa_decode_grayscale(PointerInputStream& istream, RGBAImage& image, const Flip& flip)
|
||||
{
|
||||
TargaDecodeGrayPixel decode;
|
||||
image_decode(istream, decode, image, flip);
|
||||
}
|
||||
|
||||
class TargaDecodeRGBPixel
|
||||
{
|
||||
public:
|
||||
void operator()(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
istream_read_rgb(istream, pixel);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Flip>
|
||||
void targa_decode_rgb(PointerInputStream& istream, RGBAImage& image, const Flip& flip)
|
||||
{
|
||||
TargaDecodeRGBPixel decode;
|
||||
image_decode(istream, decode, image, flip);
|
||||
}
|
||||
|
||||
class TargaDecodeRGBAPixel
|
||||
{
|
||||
public:
|
||||
void operator()(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
istream_read_rgba(istream, pixel);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Flip>
|
||||
void targa_decode_rgba(PointerInputStream& istream, RGBAImage& image, const Flip& flip)
|
||||
{
|
||||
TargaDecodeRGBAPixel decode;
|
||||
image_decode(istream, decode, image, flip);
|
||||
}
|
||||
|
||||
typedef byte TargaPacket;
|
||||
typedef byte TargaPacketSize;
|
||||
|
||||
inline void targa_packet_read_istream(TargaPacket& packet, PointerInputStream& istream)
|
||||
{
|
||||
istream.read(&packet, 1);
|
||||
}
|
||||
|
||||
inline bool targa_packet_is_rle(const TargaPacket& packet)
|
||||
{
|
||||
return (packet & 0x80) != 0;
|
||||
}
|
||||
|
||||
inline TargaPacketSize targa_packet_size(const TargaPacket& packet)
|
||||
{
|
||||
return 1 + (packet & 0x7f);
|
||||
}
|
||||
|
||||
|
||||
class TargaDecodeRGBPixelRLE
|
||||
{
|
||||
TargaPacketSize m_packetSize;
|
||||
RGBAPixel m_pixel;
|
||||
TargaPacket m_packet;
|
||||
public:
|
||||
TargaDecodeRGBPixelRLE() : m_packetSize(0)
|
||||
{
|
||||
}
|
||||
void operator()(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
if(m_packetSize == 0)
|
||||
{
|
||||
targa_packet_read_istream(m_packet, istream);
|
||||
m_packetSize = targa_packet_size(m_packet);
|
||||
|
||||
if(targa_packet_is_rle(m_packet))
|
||||
{
|
||||
istream_read_rgb(istream, m_pixel);
|
||||
}
|
||||
}
|
||||
|
||||
if(targa_packet_is_rle(m_packet))
|
||||
{
|
||||
pixel = m_pixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
istream_read_rgb(istream, pixel);
|
||||
}
|
||||
|
||||
--m_packetSize;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Flip>
|
||||
void targa_decode_rle_rgb(PointerInputStream& istream, RGBAImage& image, const Flip& flip)
|
||||
{
|
||||
TargaDecodeRGBPixelRLE decode;
|
||||
image_decode(istream, decode, image, flip);
|
||||
}
|
||||
|
||||
class TargaDecodeRGBAPixelRLE
|
||||
{
|
||||
TargaPacketSize m_packetSize;
|
||||
RGBAPixel m_pixel;
|
||||
TargaPacket m_packet;
|
||||
public:
|
||||
TargaDecodeRGBAPixelRLE() : m_packetSize(0)
|
||||
{
|
||||
}
|
||||
void operator()(PointerInputStream& istream, RGBAPixel& pixel)
|
||||
{
|
||||
if(m_packetSize == 0)
|
||||
{
|
||||
targa_packet_read_istream(m_packet, istream);
|
||||
m_packetSize = targa_packet_size(m_packet);
|
||||
|
||||
if(targa_packet_is_rle(m_packet))
|
||||
{
|
||||
istream_read_rgba(istream, m_pixel);
|
||||
}
|
||||
}
|
||||
|
||||
if(targa_packet_is_rle(m_packet))
|
||||
{
|
||||
pixel = m_pixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
istream_read_rgba(istream, pixel);
|
||||
}
|
||||
|
||||
--m_packetSize;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Flip>
|
||||
void targa_decode_rle_rgba(PointerInputStream& istream, RGBAImage& image, const Flip& flip)
|
||||
{
|
||||
TargaDecodeRGBAPixelRLE decode;
|
||||
image_decode(istream, decode, image, flip);
|
||||
}
|
||||
|
||||
struct TargaHeader
|
||||
{
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
};
|
||||
|
||||
inline void targa_header_read_istream(TargaHeader& targa_header, PointerInputStream& istream)
|
||||
{
|
||||
targa_header.id_length = istream_read_byte(istream);
|
||||
targa_header.colormap_type = istream_read_byte(istream);
|
||||
targa_header.image_type = istream_read_byte(istream);
|
||||
|
||||
targa_header.colormap_index = istream_read_int16_le(istream);
|
||||
targa_header.colormap_length = istream_read_int16_le(istream);
|
||||
targa_header.colormap_size = istream_read_byte(istream);
|
||||
targa_header.x_origin = istream_read_int16_le(istream);
|
||||
targa_header.y_origin = istream_read_int16_le(istream);
|
||||
targa_header.width = istream_read_int16_le(istream);
|
||||
targa_header.height = istream_read_int16_le(istream);
|
||||
targa_header.pixel_size = istream_read_byte(istream);
|
||||
targa_header.attributes = istream_read_byte(istream);
|
||||
|
||||
if (targa_header.id_length != 0)
|
||||
istream.seek(targa_header.id_length); // skip TARGA image comment
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
class ScopeDelete
|
||||
{
|
||||
Type* m_value;
|
||||
ScopeDelete(const ScopeDelete&);
|
||||
ScopeDelete& operator=(const ScopeDelete&);
|
||||
public:
|
||||
ScopeDelete(Type* value) : m_value(value)
|
||||
{
|
||||
}
|
||||
~ScopeDelete()
|
||||
{
|
||||
delete m_value;
|
||||
}
|
||||
Type* get_pointer() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Flip>
|
||||
Image* Targa_decodeImageData(const TargaHeader& targa_header, PointerInputStream& istream, const Flip& flip)
|
||||
{
|
||||
RGBAImage* image = new RGBAImage(targa_header.width, targa_header.height);
|
||||
|
||||
if (targa_header.image_type == 2 || targa_header.image_type == 3)
|
||||
{
|
||||
switch (targa_header.pixel_size)
|
||||
{
|
||||
case 8:
|
||||
targa_decode_grayscale(istream, *image, flip);
|
||||
break;
|
||||
case 24:
|
||||
targa_decode_rgb(istream, *image, flip);
|
||||
break;
|
||||
case 32:
|
||||
targa_decode_rgba(istream, *image, flip);
|
||||
break;
|
||||
default:
|
||||
globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n";
|
||||
image->release();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (targa_header.image_type == 10)
|
||||
{
|
||||
switch (targa_header.pixel_size)
|
||||
{
|
||||
case 24:
|
||||
targa_decode_rle_rgb(istream, *image, flip);
|
||||
break;
|
||||
case 32:
|
||||
targa_decode_rle_rgba(istream, *image, flip);
|
||||
break;
|
||||
default:
|
||||
globalErrorStream() << "LoadTGA: illegal pixel_size '" << targa_header.pixel_size << "'\n";
|
||||
image->release();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
const unsigned int TGA_FLIP_HORIZONTAL = 0x10;
|
||||
const unsigned int TGA_FLIP_VERTICAL = 0x20;
|
||||
|
||||
Image* LoadTGABuff(const byte* buffer)
|
||||
{
|
||||
PointerInputStream istream(buffer);
|
||||
TargaHeader targa_header;
|
||||
|
||||
targa_header_read_istream(targa_header, istream);
|
||||
|
||||
if (targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3)
|
||||
{
|
||||
globalErrorStream() << "LoadTGA: TGA type " << targa_header.image_type << " not supported\n";
|
||||
globalErrorStream() << "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (targa_header.colormap_type != 0)
|
||||
{
|
||||
globalErrorStream() << "LoadTGA: colormaps not supported\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((targa_header.pixel_size != 32 && targa_header.pixel_size != 24)
|
||||
&& targa_header.image_type != 3)
|
||||
{
|
||||
globalErrorStream() << "LoadTGA: Only 32 or 24 bit images supported\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
|
||||
&& !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL))
|
||||
{
|
||||
return Targa_decodeImageData(targa_header, istream, Flip00());
|
||||
}
|
||||
if(!bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
|
||||
&& bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL))
|
||||
{
|
||||
return Targa_decodeImageData(targa_header, istream, Flip01());
|
||||
}
|
||||
if(bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
|
||||
&& !bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL))
|
||||
{
|
||||
return Targa_decodeImageData(targa_header, istream, Flip10());
|
||||
}
|
||||
if(bitfield_enabled(targa_header.attributes, TGA_FLIP_HORIZONTAL)
|
||||
&& bitfield_enabled(targa_header.attributes, TGA_FLIP_VERTICAL))
|
||||
{
|
||||
return Targa_decodeImageData(targa_header, istream, Flip11());
|
||||
}
|
||||
|
||||
// unreachable
|
||||
return 0;
|
||||
}
|
||||
|
||||
Image* LoadTGA(ArchiveFile& file)
|
||||
{
|
||||
ScopedArchiveBuffer buffer(file);
|
||||
return LoadTGABuff(buffer.buffer);
|
||||
}
|
||||
31
plugins/image/tga.h
Normal file
31
plugins/image/tga.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined (INCLUDED_TGA_H)
|
||||
#define INCLUDED_TGA_H
|
||||
|
||||
class Image;
|
||||
class ArchiveFile;
|
||||
|
||||
Image* LoadTGA(ArchiveFile& file);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user