My first GIMP plugin - NDS texture format exporter

The plugin can be found here : The GIMP plugin

Installation

On Linux :

On Windows (need confirmation) :

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;
}