source: abuse/trunk/src/imlib/filter.cpp @ 494

Last change on this file since 494 was 494, checked in by Sam Hocevar, 12 years ago

style: remove trailing spaces, fix copyright statements.

File size: 5.2 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com or
8 *  Jonathan Clark.
9 */
10
11#include "config.h"
12
13#include "image.h"
14#include "macs.h"
15#include "filter.h"
16
17extern unsigned char current_background;
18
19filter::filter(palette *from, palette *to)   // creates a conversion filter from one palette to another
20{
21  nc=from->pal_size() > to->pal_size() ? from->pal_size() : to->pal_size();
22  unsigned char *p=fdat=(unsigned char *)malloc(nc);
23  unsigned char *r,*g,*b;
24  r=g=b=(unsigned char *)from->addr();
25  g++;
26  b+=2;
27
28  int dk=to->darkest(1);
29  for (int i=0; i<nc; i++,p++,r+=3,g+=3,b+=3)
30  {
31    *p=to->find_closest(*r,*g,*b);
32
33    // make sure non-blacks don't get remapped to the transparency
34    if ((*r!=0 || *g!=0 || *b!=0) && (to->red(*p)==0 && to->green(*p)==0 && to->blue(*p)==0))
35      *p=dk;
36  }
37
38}
39
40void filter::clear()
41{
42  int i;
43  for (i=0; i<nc; i++)
44    fdat[i]=i;
45}
46
47void filter::max_threshold(int minv, char blank)
48{
49  int i;
50  CONDITION(minv>=0 && minv<nc,"Bad minv");
51  for (i=0; i<minv; i++)
52    fdat[i]=blank;
53}
54
55void filter::min_threshold(int maxv, char blank)
56{
57  int i;
58  CONDITION(maxv>=0 && maxv<nc,"bad maxv value in filter::max_thresh");
59  for (i=nc-1; i>=maxv; i--)
60    fdat[i]=(unsigned) blank;
61}
62
63
64void filter::set(int color_num, char change_to)
65{
66  CONDITION(color_num>=0 && color_num<nc,"Bad colors_num");
67  fdat[color_num]=(unsigned) change_to;
68}
69
70
71filter::filter(int colors)
72{
73  CONDITION(colors>=0 && colors<=256,"bad colors value");
74  nc=colors;
75  make_block(nc);
76  fdat=(unsigned char *)malloc(nc);
77  clear();
78}
79
80void filter::apply(image *im)
81{
82  int x,y;
83  unsigned char *c;
84  CONDITION(im,"null image passed in filter::apply\n");
85  im->lock();
86  for (y=im->height()-1; y>=0; y--)
87  {
88    c=im->scan_line(y);
89    for (x=im->width()-1; x>=0; x--)
90    {
91      CONDITION((unsigned) c[x]<nc,"not enough filter colors");
92      c[x]=fdat[(unsigned) c[x]];
93    }
94  }
95  im->unlock();
96}
97
98
99palette *compare_pal;
100
101int color_compare(void *c1, void *c2)
102{
103  long v1,v2;
104  unsigned char r1,g1,b1,r2,g2,b2;
105  compare_pal->get(  *((unsigned char *)c1),r1,g1,b1);
106  compare_pal->get(  *((unsigned char *)c2),r2,g2,b2);
107  v1=(int)r1*(int)r1+(int)g1*(int)g1+(int)b1*(int)b1;
108  v2=(int)r2*(int)r2+(int)g2*(int)g2+(int)b2*(int)b2;
109  if (v1<v2) return -1;
110  else if (v1>v2) return 1;
111  else return 0;
112}
113
114color_filter::color_filter(palette *pal, int color_bits, void (*stat_fun)(int))
115{
116  color_bits=5;      // hard code 5 for now
117  int r,g,b,rv,gv,bv,
118      c=0,i,max=pal->pal_size(),
119      lshift=8-color_bits;
120  unsigned char *pp;
121
122  long dist_sqr,best;
123  int colors=1<<color_bits;
124  color_table=(unsigned char *)malloc(colors*colors*colors);
125  for (r=0; r<colors; r++)
126  {
127    if (stat_fun) stat_fun(r);
128    rv=r<<lshift;
129    for (g=0; g<colors; g++)
130    {
131      gv=g<<lshift;
132      for (b=0; b<colors; b++)
133      {
134    bv=b<<lshift;
135        best=0x7fffffff;
136        for (i=0,pp=(unsigned char *)pal->addr(); i<max; i++)
137        {
138          register long rd=*(pp++)-rv,
139                        gd=*(pp++)-gv,
140                        bd=*(pp++)-bv;
141
142          dist_sqr=(long)rd*rd+(long)bd*bd+(long)gd*gd;
143          if (dist_sqr<best)
144          { best=dist_sqr;
145            c=i;
146          }
147        }
148        color_table[r*colors*colors+g*colors+b]=c;
149      }
150    }
151  }
152}
153
154color_filter::color_filter(spec_entry *e, bFILE *fp)
155{
156  fp->seek(e->offset,0);
157  fp->read_uint16();
158  int colors=32;
159  color_table=(unsigned char *)malloc(colors*colors*colors);
160  fp->read(color_table,colors*colors*colors);
161}
162
163int color_filter::size()
164{
165  int colors=32;
166  return 2+colors*colors*colors;
167}
168
169int color_filter::write(bFILE *fp)
170{
171  int colors=32;
172  fp->write_uint16(colors);
173  return fp->write(color_table,colors*colors*colors)==colors*colors*colors;
174}
175
176
177void filter::put_image(image *screen, image *im, short x, short y,
178                       char transparent)
179{
180    short cx1, cy1, cx2, cy2, x1 = 0, y1 = 0,
181          x2 = im->width() - 1, y2 = im->height() - 1;
182    screen->get_clip(cx1,cy1,cx2,cy2);
183
184    // see if the image gets clipped off the screen
185    if(x > cx2 || y > cy2 || x + (x2 - x1) < cx1 || y + (y2 - y1) < cy1)
186        return;
187
188    if(x < cx1)
189    {
190        x1 += (cx1 - x);
191        x = cx1;
192    }
193    if(y < cy1)
194    {
195        y1 += (cy1 - y);
196         y = cy1;
197    }
198
199    if(x + x2 - x1 + 1 > cx2)
200        x2 = cx2 - x + x1;
201
202    if(y + y2 - y1 + 1 > cy2)
203        y2 = cy2 - y + y1;
204
205    if(x1 > x2 || y1 > y2)
206        return;
207
208    int xl = x2 - x1 + 1;
209    int yl = y2 - y1 + 1;
210
211    screen->add_dirty(x, y, x + xl - 1, y + yl - 1);
212
213    screen->lock();
214    im->lock();
215
216    uint8_t *pg1 = screen->scan_line(y), *source, *dest;
217    uint8_t *pg2 = im->scan_line(y1);
218    int i;
219    for(int j = 0; j < yl; j++)
220    {
221        for(i = 0, source = &pg2[x1], dest = &pg1[x];
222            i < xl;
223            i++, source++, dest++)
224        {
225            if(!transparent || *source != current_background)
226                *dest=fdat[*source];
227        }
228        pg1 = screen->next_line(y + j, pg1);
229        pg2 = im->next_line(y1 + j, pg2);
230    }
231
232    im->unlock();
233    screen->unlock();
234}
235
Note: See TracBrowser for help on using the repository browser.