Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5098 clevermous 1
/*
2
 * Highly optimised dithering 16 bits -> 8 bits.
3
 * The formulas were taken in Mesa (Bob Mercier mercier@hollywood.cinenet.net).
4
 */
5
 
6
#include 
7
#include 
8
#include "zbuffer.h"
9
/*#include */
10
 
11
#if defined(TGL_FEATURE_8_BITS)
12
 
13
#define _R	5
14
#define _G	9
15
#define _B	5
16
#define _DX	4
17
#define _DY	4
18
#define _D	(_DX*_DY)
19
#define _MIX(r,g,b)	( ((g)<<6) | ((b)<<3) | (r) )
20
 
21
#define DITHER_TABLE_SIZE (1 << 15)
22
 
23
#define DITHER_INDEX(r,g,b) ((b) + (g) * _B + (r) * (_B * _G))
24
 
25
#define MAXC	256
26
static int kernel8[_DY*_DX] = {
27
 
28
   12 * MAXC,  4 * MAXC, 14 * MAXC,  6 * MAXC,
29
    3 * MAXC, 11 * MAXC,  1 * MAXC,  9 * MAXC,
30
   15 * MAXC,  7 * MAXC, 13 * MAXC,  5 * MAXC,
31
};
32
 
33
/* we build the color table and the lookup table */
34
 
35
void ZB_initDither(ZBuffer *zb,int nb_colors,
36
		   unsigned char *color_indexes,int *color_table)
37
{
38
  int c,r,g,b,i,index,r1,g1,b1;
39
 
40
  if (nb_colors < (_R * _G * _B)) {
41
    fprintf(stderr,"zdither: not enough colors\n");
42
    exit(1);
43
  }
44
 
45
  for(i=0;i
46
 
47
  zb->nb_colors=nb_colors;
48
  zb->ctable=gl_malloc(nb_colors * sizeof(int));
49
 
50
  for (r = 0; r < _R; r++) {
51
    for (g = 0; g < _G; g++) {
52
      for (b = 0; b < _B; b++) {
53
	r1=(r*255) / (_R - 1);
54
	g1=(g*255) / (_G - 1);
55
	b1=(b*255) / (_B - 1);
56
	index=DITHER_INDEX(r,g,b);
57
	c=(r1 << 16) | (g1 << 8) | b1;
58
	zb->ctable[index]=c;
59
	color_table[index]=c;
60
      }
61
    }
62
  }
63
 
64
  zb->dctable=gl_malloc( DITHER_TABLE_SIZE );
65
 
66
  for(i=0;i
67
    r=(i >> 12) & 0x7;
68
    g=(i >> 8) & 0xF;
69
    b=(i >> 3) & 0x7;
70
    index=DITHER_INDEX(r,g,b);
71
    zb->dctable[i]=color_indexes[index];
72
  }
73
}
74
 
75
void ZB_closeDither(ZBuffer *zb)
76
{
77
    gl_free(zb->ctable);
78
    gl_free(zb->dctable);
79
}
80
 
81
#if 0
82
int ZDither_lookupColor(int r,int g,int b)
83
{
84
  unsigned char *ctable=zdither_color_table;
85
  return ctable[_MIX(_DITH0(_R, r), _DITH0(_G, g),_DITH0(_B, b))];
86
}
87
#endif
88
 
89
 
90
#define DITHER_PIXEL2(a)			\
91
{ \
92
  register int v,t,r,g,c;			\
93
  v=*(unsigned int *)(pp+(a));                  \
94
  g=(v & 0x07DF07DF) + g_d; \
95
  r=(((v & 0xF800F800) >> 2) + r_d) & 0x70007000; \
96
  t=r | g; \
97
  c=ctable[t & 0xFFFF] | (ctable[t >> 16] << 8); \
98
  *(unsigned short *)(dest+(a))=c; 	\
99
}
100
 
101
/* NOTE: all the memory access are 16 bit aligned, so if buf or
102
   linesize are not multiple of 2, it cannot work efficiently (or
103
   hang!) */
104
 
105
void ZB_ditherFrameBuffer(ZBuffer *zb,unsigned char *buf,
106
			  int linesize)
107
{
108
  int xk,yk,x,y,c1,c2;
109
  unsigned char *dest1;
110
  unsigned short *pp1;
111
  int r_d,g_d,b_d;
112
  unsigned char *ctable=zb->dctable;
113
  register unsigned char *dest;
114
  register unsigned short *pp;
115
 
116
  assert( ((long)buf & 1) == 0 && (linesize & 1) == 0);
117
 
118
  for(yk=0;yk<4;yk++) {
119
    for(xk=0;xk<4;xk+=2) {
120
#if BYTE_ORDER == BIG_ENDIAN
121
      c1=kernel8[yk*4+xk+1];
122
      c2=kernel8[yk*4+xk];
123
#else
124
      c1=kernel8[yk*4+xk];
125
      c2=kernel8[yk*4+xk+1];
126
#endif
127
      r_d=((c1 << 2) & 0xF800) >> 2;
128
      g_d=(c1 >> 4) & 0x07C0;
129
      b_d=(c1 >> 9) & 0x001F;
130
 
131
      r_d|=(((c2 << 2) & 0xF800) >> 2) << 16;
132
      g_d|=((c2 >> 4) & 0x07C0) << 16;
133
      b_d|=((c2 >> 9) & 0x001F) << 16;
134
      g_d=b_d | g_d;
135
 
136
      dest1=buf + (yk * linesize) + xk;
137
      pp1=zb->pbuf + (yk * zb->xsize) + xk;
138
 
139
      for(y=yk;yysize;y+=4) {
140
	dest=dest1;
141
	pp=pp1;
142
	for(x=xk;xxsize;x+=16) {
143
 
144
	  DITHER_PIXEL2(0);
145
	  DITHER_PIXEL2(1*4);
146
	  DITHER_PIXEL2(2*4);
147
	  DITHER_PIXEL2(3*4);
148
 
149
	  pp+=16;
150
	  dest+=16;
151
	}
152
	dest1+=linesize*4;
153
	pp1+=zb->xsize*4;
154
      }
155
    }
156
  }
157
}
158
 
159
#endif