/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at golgotha_source@usa.net (Subject should have "GOLG" in it) ***********************************************************************/ #include "memory/malloc.hh" #include "image/image32.hh" #include "image/image8.hh" #include "palette/pal.hh" #include "error/error.hh" #includei4_color i4_image32::get_pixel(i4_coord x, i4_coord y) { return i4_pal_man.convert_to_32(*paddr(x,y), pal); } void i4_image32::put_pixel(i4_coord x, i4_coord y, w32 color) { *paddr(x,y)=i4_pal_man.convert_32_to(color, &pal->source); } i4_image32::i4_image32(w16 _w, w16 _h, const i4_pal *_pal) { w=_w; h=_h; bpl=_w*4; set_pal(_pal); data=i4_malloc(w*h*4,""); } i4_image32::i4_image32(w16 _w, w16 _h, const i4_pal *_pal, void *_data, int _bpl) { data=_data; bpl=_bpl; pal=_pal; w=_w; h=_h; dont_free_data=i4_T; } i4_image32::~i4_image32() { if (!dont_free_data) i4_free(data); } inline w32 color_dist(w32 c1, w32 c2) { sw32 r1=(c1 & 0xff0000)>>16; sw32 r2=(c2 & 0xff0000)>>16; sw32 g1=(c1 & 0xff00)>>8; sw32 g2=(c2 & 0xff00)>>8; sw32 b1=(c1 & 0xff); sw32 b2=(c2 & 0xff); return (r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2); } inline w16 _32_to_16_565(w32 c) { w8 r = ((c&0xff0000)>>16)>>3; w8 g = ((c&0xff00)>>8)>>2; w8 b = (c&0xff)>>3; return (r<<11) | (g<<5) | b; } i4_image_class *i4_image32::quantize(const i4_pal *pal, w32 skip_colors, i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2) { if (pal->source.pixel_depth!=I4_8BIT) i4_error("palette handle, should be 8 bit"); // first check to make sure the sub image is located within this one if (x1<0) x1=0; if (y1<0) y1=0; if (x2>=width()) x2 = width()-1; if (y2>=height()) y2 = height()-1; if (x2 data; w32 skip_32 = bpl-(x2-x1+1); // pixels to skip per line w32 x,y; w8 closest_color; w32 closest_distance, distance, *color_index; w32 *pal_data=pal->source.lookup; // maps 16 bits color space into closest 8 bit color w8 *lookup_table=(w8 *)i4_malloc(0x10000, "lookup"); // indicates if above color has been calculated yet w8 *table_calced=(w8 *)i4_malloc(0x10000, "table_calced"); memset(table_calced,0,0x10000); // initially no mappings are calculated for (y=y2-y1+1; y; y--) { for (x=x2-x1+1; x; x--) { i4_color color=*pixel32; w16 c16 = _32_to_16_565(color); if (table_calced[c16]) // have we found the closest color to this yet? *pixel8=lookup_table[c16]; else { // find the closest color to this pixel color_index = pal_data+skip_colors; closest_distance = 0xffffffff; for (w32 c=skip_colors; c<256; c++) { distance=color_dist(*color_index,color); if (distance