My first GIMP plugin - NDS texture format exporter
The plugin can be found here : The GIMP plugin
Installation
On Linux :
- Copy "nds_export.py" to
~/.gimp-2.6/plug-ins/
- Make it runable :
chmod a+x nds_export.py
On Windows (need confirmation) :
- As it's a python script you need to install Python and PyGTK/PyCairo before installing Gimp (or else gimp won't install it's python-fu plugin).
- http://python.org/download/releases/2.6.1/
- http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.12/ (take the python 2.6 version)
- http://ftp.gnome.org/pub/GNOME/binaries/win32/pycairo/1.4/ (take the python 2.6 version)
- Copy "nds_export.py" to
C:\Program Files\GIMP-2.0\lib\gimp\2.0\plug-ins
File structure
char[4] file header : "a3i5", "a5i3", "RGBx", "RGBA", "256c", "16co"
uint32 width
uint32 height
u8[] image data
A3I5 & A5I3 : width x height x 1 byte (alpha and index - 8bit by pixel)
RGB16 : width x height x 0.5 byte (index - 4bit by pixel)
RGB256 : width x height x 1 byte (index - 8bit by pixel)
RGB & RGBA : width x height x 2 bytes (raw color (with alpha in RGBA) - 16bit by pixel)
u16[] palette data: nbcolor x 2 bytes (not present in RGB & RGBA format)
Sample code
union ImagePtr {
u8* data8;
u16* data16;
u32* data32;
void* dataVoid;
};
//---------------------------------------------------------------------------------------------------------------------
// Identify the textuer type and load it
// @return : the loaded texture type in GL_TEXTURE_TYPE_ENUM, 0 on error
//---------------------------------------------------------------------------------------------------------------------
GL_TEXTURE_TYPE_ENUM TextureManager::loadImage(sImage *image, ImagePtr dataPtr)
//---------------------------------------------------------------------------------------------------------------------
{
if (dataPtr.data8[0] == 'a' && dataPtr.data8[1] == '3' && dataPtr.data8[2] == 'i' && dataPtr.data8[3] == '5')
return loadImageA3I5(image, dataPtr);
else if (dataPtr.data8[0] == 'a' && dataPtr.data8[1] == '5' && dataPtr.data8[2] == 'i' && dataPtr.data8[3] == '3')
return loadImageA5I3(image, dataPtr);
else if (dataPtr.data8[0] == 'R' && dataPtr.data8[1] == 'G' && dataPtr.data8[2] == 'B' && dataPtr.data8[3] == 'x')
return loadImageRGB(image, dataPtr);
else if (dataPtr.data8[0] == 'R' && dataPtr.data8[1] == 'G' && dataPtr.data8[2] == 'B' && dataPtr.data8[3] == 'A')
return loadImageRGBA(image, dataPtr);
else if (dataPtr.data8[0] == '2' && dataPtr.data8[1] == '5' && dataPtr.data8[2] == '6' && dataPtr.data8[3] == 'c')
return loadImageRGB256(image, dataPtr);
else if (dataPtr.data8[0] == '1' && dataPtr.data8[1] == '6' && dataPtr.data8[2] == 'c' && dataPtr.data8[3] == 'o')
return loadImageRGB16(image, dataPtr);
return 0;
}
//---------------------------------------------------------------------------------------------------------------------
GL_TEXTURE_TYPE_ENUM TextureManager::loadImageA3I5(sImage *image, ImagePtr dataPtr)
//---------------------------------------------------------------------------------------------------------------------
{
sassert( dataPtr.data8[0] == 'a' && dataPtr.data8[1] == '3' && dataPtr.data8[2] == 'i' && dataPtr.data8[3] == '5', "This file does not have the goode header (a3i5)");
image->height = dataPtr.data32[2];
image->width = dataPtr.data32[1];
image->bpp = 8;
image->image.data8 = (u8*)malloc(image->width * image->height);
swiFastCopy((uint32*)(dataPtr.data8+12), image->image.data32 , ((image->width * image->height) >> 2) | COPY_MODE_WORD);// the size is >> 2 ( == /4 ) to use 32bit copy
image->palette = (u16*)malloc(64);
swiFastCopy((uint32*)(dataPtr.data8+(12+image->width*image->height)), image->palette , 16 | COPY_MODE_WORD); // copy 16 x 32 bits ( == 32 x 16bit )
return GL_RGB32_A3;
}
//---------------------------------------------------------------------------------------------------------------------
GL_TEXTURE_TYPE_ENUM TextureManager::loadImageA5I3(sImage *image, ImagePtr dataPtr)
//---------------------------------------------------------------------------------------------------------------------
{
sassert( dataPtr.data8[0] == 'a' && dataPtr.data8[1] == '5' && dataPtr.data8[2] == 'i' && dataPtr.data8[3] == '3', "This file does not have the good header (a5i3)");
image->height = dataPtr.data32[2];
image->width = dataPtr.data32[1];
image->bpp = 8;
image->image.data8 = (u8*)malloc(image->width * image->height);
swiFastCopy((uint32*)(dataPtr.data8+12), image->image.data32 , ((image->width * image->height) >> 2) | COPY_MODE_WORD); // the size is >> 2 ( == /4 ) to use 32bit copy
image->palette = (u16*)malloc(64);
swiFastCopy((uint32*)(dataPtr.data8+(12+image->width*image->height)), image->palette , 4 | COPY_MODE_WORD); // copy 4 32 bits ( == 8 x 16bit )
return GL_RGB8_A5;
}
//---------------------------------------------------------------------------------------------------------------------
GL_TEXTURE_TYPE_ENUM TextureManager::loadImageRGB (sImage *image, ImagePtr dataPtr)
//---------------------------------------------------------------------------------------------------------------------
{
sassert( dataPtr.data8[0] == 'R' && dataPtr.data8[1] == 'G' && dataPtr.data8[2] == 'B' && dataPtr.data8[3] == 'x', "This file does not have the good header (RGBx)");
image->height = dataPtr.data32[2];
image->width = dataPtr.data32[1];
image->bpp = 16;
image->image.data8 = (u8*)malloc((image->width * image->height)<<1);
swiFastCopy((uint32*)(dataPtr.data8+12), image->image.data32 , ((image->width * image->height) >> 1) | COPY_MODE_WORD); // the size is >> 1 ( == /2 ) to use 32bit copy
image->palette = NULL;
return GL_RGB;
}
//---------------------------------------------------------------------------------------------------------------------
GL_TEXTURE_TYPE_ENUM TextureManager::loadImageRGBA(sImage *image, ImagePtr dataPtr)
//---------------------------------------------------------------------------------------------------------------------
{
sassert( dataPtr.data8[0] == 'R' && dataPtr.data8[1] == 'G' && dataPtr.data8[2] == 'B' && dataPtr.data8[3] == 'A', "This file does not have the good header (RGBA)");
image->height = dataPtr.data32[2];
image->width = dataPtr.data32[1];
image->bpp = 16;
image->image.data8 = (u8*)malloc((image->width * image->height)<<1);
swiFastCopy((uint32*)(dataPtr.data8+12), image->image.data32 , ((image->width * image->height) >> 1) | COPY_MODE_WORD); // the size is >> 1 ( == /2 ) to use 32bit copy
image->palette = NULL;
return GL_RGBA;
}
//---------------------------------------------------------------------------------------------------------------------
GL_TEXTURE_TYPE_ENUM TextureManager::loadImageRGB256(sImage *image, ImagePtr dataPtr)
//---------------------------------------------------------------------------------------------------------------------
{
sassert( dataPtr.data8[0] == '2' && dataPtr.data8[1] == '5' && dataPtr.data8[2] == '6' && dataPtr.data8[3] == 'c', "This file does not have the good header (a5i3)");
image->height = dataPtr.data32[2];
image->width = dataPtr.data32[1];
image->bpp = 8;
image->image.data8 = (u8*)malloc(image->width * image->height);
swiFastCopy((uint32*)(dataPtr.data8+12), image->image.data32 , ((image->width * image->height) >> 2) | COPY_MODE_WORD); // the size is >> 2 ( == /4 ) to use 32bit copy
image->palette = (u16*)malloc(64);
swiFastCopy((uint32*)(dataPtr.data8+(12+image->width*image->height)), image->palette , 128 | COPY_MODE_WORD); // copy 128 x 32 bits ( == 256 x 16bit )
return GL_RGB256;
}
//---------------------------------------------------------------------------------------------------------------------
GL_TEXTURE_TYPE_ENUM TextureManager::loadImageRGB16(sImage *image, ImagePtr dataPtr)
//---------------------------------------------------------------------------------------------------------------------
{
sassert( dataPtr.data8[0] == '1' && dataPtr.data8[1] == '6' && dataPtr.data8[2] == 'c' && dataPtr.data8[3] == 'o', "This file does not have the good header (16co)");
image->height = dataPtr.data32[2];
image->width = dataPtr.data32[1];
image->bpp = 4;
image->image.data8 = (u8*)malloc((image->width * image->height) >> 1);
swiFastCopy((uint32*)(dataPtr.data8+12), image->image.data32 , ((image->width * image->height) >> 3) | COPY_MODE_WORD); // the size is >> 3 ( == /8 ) to use 32bit copy
image->palette = (u16*)malloc(64);
swiFastCopy((uint32*)(dataPtr.data8+(12+image->width*image->height)), image->palette , 8 | COPY_MODE_WORD); // copy 8 x 32 bits ( == 16 x 16bit )
return GL_RGB16;
}