/*
* 2ooM: The Master of Orion II Reverse Engineering Project
* Routines for rendering LBX images to a GdkPixbuf.
* Copyright (C) 2010 Nick Bowler
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see .
*/
#include
#include
#include
#include "render.h"
#include "image.h"
/* LBX images can have up to three palettes, with each superseding the last. */
struct lbx_colour palette_external[256];
struct lbx_colour palette_internal[256];
struct lbx_colour palette_override[256];
static inline unsigned scale6to8(unsigned x)
{
assert(x <= 0x3f);
return x*0xff / 0x3f;
}
static void get_colour(unsigned char index, unsigned char out[static 4])
{
struct lbx_colour *colour;
if (palette_override[index].active)
colour = palette_override + index;
else if (palette_internal[index].active)
colour = palette_internal + index;
else if (palette_external[index].active)
colour = palette_external + index;
else
colour = &(struct lbx_colour) { .red = 0x3f, .blue = 0x3f };
out[0] = scale6to8(colour->red);
out[1] = scale6to8(colour->green);
out[2] = scale6to8(colour->blue);
out[3] = -1; /* opaque */
}
int render_to_pixbuf(struct lbx_image *image, GdkPixbuf *pixbuf, unsigned frame)
{
unsigned char **framedata, **framemask, *outbuf;
unsigned stride;
assert(image->width == gdk_pixbuf_get_width(pixbuf));
assert(image->height == gdk_pixbuf_get_height(pixbuf));
framedata = lbx_img_getframe(image, frame);
g_return_val_if_fail(framedata, -1);
framemask = lbx_img_getmask(image);
outbuf = gdk_pixbuf_get_pixels(pixbuf);
stride = gdk_pixbuf_get_rowstride(pixbuf);
for (unsigned i = 0; i < image->height; i++) {
unsigned char (*px)[4] = (void *)(outbuf + i*stride);
for (unsigned j = 0; j < image->width; j++) {
if (framemask[i][j])
get_colour(framedata[i][j], px[j]);
else
px[j][3] = 0; /* transparent */
}
}
return 0;
}