source: golgotha/src/i4/image/image32.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 4.0 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "memory/malloc.hh"
10#include "image/image32.hh"
11#include "image/image8.hh"
12#include "palette/pal.hh"
13#include "error/error.hh"
14#include <string.h>
15
16i4_color i4_image32::get_pixel(i4_coord x, i4_coord y)
17{   
18  return i4_pal_man.convert_to_32(*paddr(x,y), pal);
19}
20 
21void i4_image32::put_pixel(i4_coord x, i4_coord y, w32 color)
22{
23  *paddr(x,y)=i4_pal_man.convert_32_to(color, &pal->source);
24}
25
26i4_image32::i4_image32(w16 _w, w16 _h, const i4_pal *_pal)
27{
28  w=_w;
29  h=_h;
30  bpl=_w*4;
31  set_pal(_pal);
32  data=i4_malloc(w*h*4,""); 
33}
34
35i4_image32::i4_image32(w16 _w, w16 _h, const i4_pal *_pal,
36                       void *_data, int _bpl)
37{
38  data=_data;
39  bpl=_bpl;
40  pal=_pal;
41  w=_w;
42  h=_h;
43
44  dont_free_data=i4_T;
45}
46
47
48i4_image32::~i4_image32()
49{
50  if (!dont_free_data)
51    i4_free(data);
52}
53
54inline w32 color_dist(w32 c1, w32 c2)
55{
56  sw32 r1=(c1 & 0xff0000)>>16;
57  sw32 r2=(c2 & 0xff0000)>>16;
58
59  sw32 g1=(c1 & 0xff00)>>8;
60  sw32 g2=(c2 & 0xff00)>>8;
61
62  sw32 b1=(c1 & 0xff);
63  sw32 b2=(c2 & 0xff);
64
65  return (r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2);
66}
67
68inline w16 _32_to_16_565(w32 c)
69{
70  w8 r = ((c&0xff0000)>>16)>>3;
71
72  w8 g = ((c&0xff00)>>8)>>2;
73
74  w8 b = (c&0xff)>>3;
75
76  return (r<<11) | (g<<5) | b;   
77}
78
79
80i4_image_class *i4_image32::quantize(const i4_pal *pal,
81                                     w32 skip_colors,
82                                     i4_coord x1, i4_coord y1,
83                                     i4_coord x2, i4_coord y2)
84{
85
86  if (pal->source.pixel_depth!=I4_8BIT)
87    i4_error("palette handle, should be 8 bit");
88
89  // first check to make sure the sub image is located within this one
90  if (x1<0) x1=0;
91  if (y1<0) y1=0;
92
93  if (x2>=width()) 
94    x2 = width()-1;
95
96  if (y2>=height())
97    y2 = height()-1; 
98
99  if (x2<x1 || y2<y1)
100    return 0;
101
102
103  i4_image8 *im8 = new i4_image8(x2-x1+1,
104                                 y2-y1+1,
105                                 pal);
106     
107
108  w32 *pixel32 = (w32 *)((w8 *)data + x1*4 + y1*bpl);
109  w8 *pixel8 = (w8 *)im8->data;
110
111  w32 skip_32 = bpl-(x2-x1+1);   // pixels to skip per line
112  w32 x,y;
113
114  w8  closest_color;
115  w32 closest_distance,
116      distance,
117      *color_index;
118
119  w32 *pal_data=pal->source.lookup;
120
121 
122  // maps 16 bits color space into closest 8 bit color
123  w8 *lookup_table=(w8 *)i4_malloc(0x10000, "lookup");
124   
125  // indicates if above color has been calculated yet
126  w8 *table_calced=(w8 *)i4_malloc(0x10000, "table_calced");
127 
128  memset(table_calced,0,0x10000);     // initially no mappings are calculated
129
130  for (y=y2-y1+1; y; y--)
131  {
132    for (x=x2-x1+1; x; x--)
133    {
134      i4_color color=*pixel32;
135
136
137      w16 c16 = _32_to_16_565(color);
138      if (table_calced[c16])           // have we found the closest color to this yet?
139        *pixel8=lookup_table[c16];
140      else
141      {
142        // find the closest color to this pixel
143        color_index = pal_data+skip_colors;
144        closest_distance = 0xffffffff;
145
146        for (w32 c=skip_colors; c<256; c++)
147        {
148          distance=color_dist(*color_index,color);
149          if (distance<closest_distance)
150          {
151            closest_distance=distance;
152            closest_color=c;
153          }
154          color_index++;
155        }
156
157        table_calced[c16]=1;
158        lookup_table[c16]=closest_color;
159        *pixel8=closest_color;
160      }
161
162      ++pixel32;
163      ++pixel8;
164    }
165
166    pixel32+=skip_32;
167  }
168
169  i4_free(lookup_table);
170  i4_free(table_calced);
171
172  return im8;
173}
Note: See TracBrowser for help on using the repository browser.