Hey guys this is my first post so please be nice lol.

(Background information)

Im playing an online MMO and wish to edit the textures but the the textures are in SPR format.
Now i have a GIMP plugin that can open the SPRs and view the multiple BMPs but i cannot repack the BMPs into the correct SPR format

I have the source code to read the SPRs in GIMP but as i stated above I cannot export the multiple BMPS back to the SPR format

Here is the code to open the SPRs

 
spr.c
Code:
/* GPLed. based on GIMP bmp plugin */
#include <errno.h>
#include <glib/gstdio.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>

#include "goonzu-spr.h"

static void query(void);
static void run(const gchar *name, gint nparams, const GimpParam *param,
                gint *nreturn_vals, GimpParam **return_vals); 
static ReadSPR(const gchar *name, GError **error);
static gint32 ReadImage(const char* filename, FILE *fd, SPR_Header *header,
                        SPR_Record records[], gushort pallet[SPR_PALLET_SIZE], GError **error);
static gboolean ReadPixels(FILE *fd, SPR_Record *record, guchar *buf, gint num_pixels);

static gint32 ToL (const guchar *puffer)
{
  return (puffer[0] | puffer[1] << 8 | puffer[2] << 16 | puffer[3] << 24);
}

static gint16 ToS (const guchar *puffer)
{
  return (puffer[0] | puffer[1] << 8);
}

const GimpPlugInInfo PLUG_IN_INFO = {
    NULL,
    NULL,
    query,
    run,
};

MAIN()

static void query(void) 
{
    static const GimpParamDef load_args[] = {
        { GIMP_PDB_INT32,  "run-mode",     "Interactive, no-interactive" },
        { GIMP_PDB_STRING, "filename",     "The name of the file to load" },
        { GIMP_PDB_STRING, "raw-filename", "The name entered" },
    };
    static const GimpParamDef load_return_vals[] = {
        { GIMP_PDB_IMAGE, "image", "Output image" },
    };

    gimp_install_procedure(LOAD_PROC,
                           "Loads files of Goonzu (Kunshu) SPR file format",
                           "Loads files of Goonzu (Kunshu) SPR file format",
                           "testsan",
                           "testsan",
                           "2009",
                           "Goonzu (Kunshu) SPR image",
                           NULL,
                           GIMP_PLUGIN,
                           G_N_ELEMENTS(load_args),
                           G_N_ELEMENTS(load_return_vals),
                           load_args, load_return_vals);

    gimp_register_magic_load_handler(LOAD_PROC, "spr", "", "0,string,\\x90\\x01");
}

static void run(const gchar *name, gint nparams, const GimpParam *param,
                gint *nreturn_vals, GimpParam **return_vals)
{
    static GimpParam   values[2];
    GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
    gint32             image_ID;
    gint32             drawable_ID;
    GimpExportReturn   export = GIMP_EXPORT_CANCEL;
    GError            *error = NULL;

    *nreturn_vals = 1;
    *return_vals = values;
    values[0].type          = GIMP_PDB_STATUS;
    values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;

    if (strcmp(name, LOAD_PROC) == 0) {
        image_ID = ReadSPR(param[1].data.d_string, &error);
        if (image_ID != -1) {
            *nreturn_vals = 2;
            values[1].type = GIMP_PDB_IMAGE;
            values[1].data.d_image = image_ID;
        } else {
            status = GIMP_PDB_EXECUTION_ERROR;
        }
    } else {
        status = GIMP_PDB_CALLING_ERROR;
    }

    if (status != GIMP_PDB_SUCCESS && error) {
        *nreturn_vals = 2;
        values[1].type          = GIMP_PDB_STRING;
        values[1].data.d_string = error->message;
    }

    values[0].data.d_status = status;
}

static ReadSPR(const gchar *name, GError **error)
{
    FILE       *fd;
    gint32      image_ID;
    guchar      buffer[SPR_RECORD_SIZE * SPR_MAX_RECORD_COUNT]; /* FIXME */
    SPR_Header  header;
    SPR_Record  records[SPR_MAX_RECORD_COUNT];
    gushort     pallet[SPR_PALLET_SIZE];
    gint        i;

    fd = g_fopen(name, "rb");

    if (!fd) {
        g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno),
                    "Could not open '%s' for reading: %s",
                    gimp_filename_to_utf8(name), g_strerror(errno));
        return -1;
    }

    gimp_progress_init_printf("Opening '%s'",gimp_filename_to_utf8(name));

    if (!ReadOK(fd, buffer, SPR_HEADER_SIZE)) {
        goto invalid_error;
    }

    if (ToS(&buffer[0x00]) != 0x0190) {
        goto invalid_error;
    }
    
    header.width         = ToL(&buffer[0x08]);
    header.height        = ToL(&buffer[0x0C]);
    header.total_width   = ToL(&buffer[0x10]);
    header.total_height  = ToL(&buffer[0x14]);
    header.pallet_offset = ToL(&buffer[0x18]);
    header.count         = buffer[0x3C];

    if (header.count == 0 || header.width == 0 || header.height == 0 ||
        header.width > header.total_width || header.height > header.total_height ||
        (header.count * header.width * header.height != header.total_width * header.total_height)) {
        goto invalid_error;
    }
    
    if (!ReadOK(fd, buffer, SPR_RECORD_SIZE * SPR_MAX_RECORD_COUNT)) {
        goto invalid_error;
    }

    for (i = 0; i < header.count; i++) {
        records[i].offset = ToL(&buffer[i * SPR_RECORD_SIZE + 4]);
    }

    fseek(fd, SPR_DATA_OFFSET + header.pallet_offset, SEEK_SET);
    if (!ReadOK(fd, pallet, SPR_PALLET_SIZE)) {
        goto invalid_error;
    }

    image_ID = ReadImage(name, fd, &header, records, pallet, error);
    fclose(fd);

    if (image_ID < 0) {
        return -1;
    }

    return image_ID;

invalid_error:
    g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                "'%s' is not a valid SPR file",
                gimp_filename_to_utf8(name));
    fclose(fd);
    return -1;
}


static gint32 ReadImage(const char* filename, FILE *fd, SPR_Header *header,
                        SPR_Record records[], gushort pallet[SPR_PALLET_SIZE], GError **error)
{
    gint32        image;
    gint32        layer;
    GimpDrawable *drawable;
    guchar       *dest;
    gint          i;
    GimpPixelRgn  pixel_rgn;
    guchar        gimp_cmap[256 * 3];
    gchar         layer_name[32];
    gint          r, g, b;
    
    image = gimp_image_new(header->width, header->height, GIMP_INDEXED);

    gimp_image_set_filename(image, filename);

    dest = g_malloc0(header->width * header->height);

    for (i = 0; i < header->count; i++) {
        sprintf(layer_name, "image%03d", i);
        layer = gimp_layer_new(image, layer_name,
                               header->width, header->height,
                               GIMP_INDEXED_IMAGE, 100, GIMP_NORMAL_MODE);
        gimp_image_add_layer(image, layer, i);
        drawable = gimp_drawable_get(layer);
        
        ReadPixels(fd, &records[i], dest, header->width * header->height);
        gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE);
        gimp_pixel_rgn_set_rect(&pixel_rgn, dest, 0, 0, drawable->width, drawable->height);
    
        gimp_progress_update((gdouble)i / header->count);

        gimp_drawable_flush(drawable);
        gimp_drawable_detach(drawable);
    }

    for (i = 0; i < 256; i++) {
        b = pallet[i]         & 0x1F;
        g = (pallet[i] >> 5)  & 0x3F;
        r = (pallet[i] >> 11) & 0x1F;
        gimp_cmap[i*3  ] = (r << 3) | (r >> 2);
        gimp_cmap[i*3+1] = (g << 2) | (g >> 4);
        gimp_cmap[i*3+2] = (b << 3) | (b >> 2);
    }
    gimp_image_set_colormap(image, gimp_cmap, 256);

    gimp_progress_update(1);

    g_free(dest);

    return image;
}

static gboolean ReadPixels(FILE *fd, SPR_Record *record, guchar *buf, gint num_pixels)
{
    gint i, j;
    guchar v, len;

    fseek(fd, SPR_DATA_OFFSET + record->offset, SEEK_SET);
    i = 0;
    while (i < num_pixels) {
        if (!ReadOK(fd, &v, 1)) {
            return FALSE;
        }
        if (v == 0xFE) {
            if (!ReadOK(fd, &len, 1)) {
                return FALSE;
            }
            for (j = 0; (j < len) && (i < num_pixels); j++) {
                *(buf+i) = 0xFE;
                i++;
            }
        } else {
            *(buf+i) = v;
            i++;
        }
    }

    return TRUE;
}


 
spr.h
Code:
#ifndef __GOONZU_SPR_H__
#define __GOONZU_SPR_H__

#define LOAD_PROC "file-goonzu-spr-load"

#define ReadOK(file,buffer,len)  (fread(buffer, len, 1, file) != 0)

typedef struct SPR_Header_Rec
{
    gchar  magic[2];
    gchar  unknown0[6];
    gulong width;
    gulong height;
    gulong total_width;
    gulong total_height;
    gulong pallet_offset;
    gchar  unknown1[0x20];
    guchar count;
    guchar unknown2[3];
} SPR_Header;

typedef struct SPR_Record_Rec
{
    gulong unknown0;
    gulong offset;
    gulong unknown1;
} SPR_Record;

#define SPR_HEADER_SIZE 0x40
#define SPR_MAX_RECORD_COUNT 256
#define SPR_RECORD_SIZE 12
#define SPR_PALLET_SIZE 512
#define SPR_DATA_OFFSET 0xC40

#endif  /* __GOONZU_SPR_H__ */


Help will be much appreciated