1 /* dither.h			-*- C++ -*-
2    $Id: dither.h,v 1.2 1997/10/18 04:57:32 elf Exp $
3 
4    written by Marc Singer
5    24 Mar 1997
6 
7    This file is part of the project XO.  See the file README for
8    more information.
9 
10    Copyright (C) 1997 Marc Singer
11 
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of the
15    License, or (at your option) any later version.
16 
17    This program is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    in a file called COPYING along with this program; if not, write to
24    the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
25    02139, USA.
26 
27 */
28 
29 #if !defined (__DITHER_H__)
30 #    define   __DITHER_H__
31 
32 /* ----- Includes */
33 
34 #include <memory.h>
35 
36 #define C_COLOR_MAX 256		/* Total number of colors		*/
37 #define C_SHADES_MAX 256	/* Max number of shades in primary	*/
38 
39 typedef unsigned32 PEL;
40 #define COLOROF(r,g,b) (((r)<<16) + ((g)<<8) + (b))
41 
42 class LDither {
43 protected:
44   int m_cRed;			// Count of red shades
45   int m_cGreen;			// Count of green shades
46   int m_cBlue;			// Count of blue shades
47   int m_cColors;		// Count of all combinations, cRed*cGreen*cBlue
48 
49   void* m_rgRGB;		// Dithering palette RGBQUAD
50   int **m_pMatrix;		// Dithering matrix
51   int m_dim;			// Dimension of dither matrix
52   int m_dim2;			// Dither matrix dimension squared
53 
54   int m_level_red;
55   int m_level_green;
56   int m_level_blue;
57   int m_dither_divisor;
58 
59 #define LEVELS(s) (m_dim2*((shades) - 1) + 1)
60 #define LEVEL5MULT(p) (((p) << 10) + (p))
61 #define LEVEL9MULT(p) (((p) << 11) + (p))
dither(PEL pel,int d,int shades)62   unsigned8 dither (PEL pel, int d, int shades) {
63     return unsigned8 ((LEVELS (shades)*(pel) + (d))/(m_dim2*C_SHADES_MAX)); }
dither_red(PEL pel,int d)64   unsigned8 dither_red (PEL pel, int d) {
65     return unsigned8 ((LEVEL5MULT(pel) + (d)) >> 16); }
dither_green(PEL pel,int d)66   unsigned8 dither_green (PEL pel, int d) {
67     return unsigned8 ((LEVEL9MULT(pel) + (d)) >> 16); }
dither_blue(PEL pel,int d)68   unsigned8 dither_blue (PEL pel, int d) {
69     return unsigned8 ((LEVEL5MULT(pel) + (d)) >> 16); }
levels(int shades)70   int levels (int shades) {
71     return m_dim2*((shades) - 1) + 1; }
72   int matrix_value (int y, int x, int size);
73 
74 public:
LDither()75   LDither () {
76     zero (); }
~LDither()77   ~LDither () {
78     release_this (); }
zero(void)79   void zero (void) {
80     memset (this, 0, sizeof (*this)); }
init(void)81   void init (void) {
82     init (4, 5, 9, 5); }
83   void release_this (void);
84 
color_index(int r,int g,int b)85   int color_index (int r, int g, int b) {
86     return  ((r)*m_cGreen + (g))*m_cBlue + (b); }
87   void create_matrix (int dim);
88   void dither (int x, int y, int cx, int cy,
89 	       unsigned8* pbSrc, unsigned8* pbDst);
dither(int cx,int cy,unsigned8 * pbSrc,unsigned8 * pbDst)90   void dither (int cx, int cy, unsigned8* pbSrc, unsigned8* pbDst) {
91     dither (0, 0, cx, cy, pbSrc, pbDst); }
92   void init (int dim, int cRed, int cGreen, int cBlue);
closest_match(float r,float g,float b)93   int closest_match (float r, float g, float b) {
94     return color_index (int (r*(m_cRed   - 1)),
95 			int (g*(m_cGreen - 1)),
96 			int (b*(m_cBlue  - 1))); }
97 
colors(void)98   int colors (void) {
99     return m_cColors; }
palette(void)100   void* palette (void) {
101     return m_rgRGB; }
102 
103 };
104 
105 
106 #endif  /* __DITHER_H__ */
107