1/*
2 * Halftone.h
3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
4 */
5
6#ifndef __HALFTONE_H
7#define __HALFTONE_H
8
9#include <GraphicsDefs.h>
10
11// definition for B_RGB32 (=B_RGB32_LITTLE) and B_RGBA32
12typedef struct {
13	uchar blue;
14	uchar green;
15	uchar red;
16	uchar alpha; // unused in B_RGB32
17} ColorRGB32Little;
18
19// definition for B_RGB32_BIG and B_RGBA32_BIG
20typedef struct {
21	uchar alpha; // unused in B_RGB32_BIG
22	uchar red;
23	uchar green;
24	uchar blue;
25} ColorRGB32Big;
26
27typedef union {
28	ColorRGB32Little little;
29	ColorRGB32Big    big;
30} ColorRGB32;
31
32class Halftone;
33
34typedef void (Halftone::*PFN_dither)(uchar* destination, const uchar* source,
35	int x, int y, int width);
36
37typedef uint (*PFN_gray)(ColorRGB32 c);
38
39class Halftone {
40public:
41	enum DitherType {
42		kType1,
43		kType2,
44		kType3,
45		kTypeFloydSteinberg,
46	};
47
48	enum GrayFunction {
49		kMixToGray,
50		kRedChannel,
51		kGreenChannel,
52		kBlueChannel
53	};
54
55	enum Planes {
56		kPlaneMonochrome1, // 1 bit depth (0 white, 1 black)
57		kPlaneRGB1,        // 3 planes, 1 bit depth (0 black, 7 white)
58	};
59
60	enum BlackValue {
61		kHighValueMeansBlack,
62		kLowValueMeansBlack,
63	};
64
65					Halftone(color_space colorSpace, double gamma = 1.4,
66						double min = 0.0,
67						DitherType dither_type = kTypeFloydSteinberg);
68					~Halftone();
69
70			void	SetPlanes(Planes planes);
71			void	SetBlackValue(BlackValue blackValue);
72
73			void	Dither(uchar *destination, const uchar *source, int x,
74						int y, int width);
75
76			int		GetPixelDepth() const;
77
78			const uchar*	GetPattern() const;
79			void			SetPattern(const uchar *pattern);
80
81protected:
82			Halftone(const Halftone &);
83
84			Halftone&	operator=(const Halftone &);
85
86			// PFN_gray: return value of 0 means low density (or black) and
87			// value of 255 means high density (or white)
88			PFN_gray	GetGrayFunction() const;
89			void		SetGrayFunction(PFN_gray gray);
90			void		SetGrayFunction(GrayFunction grayFunction);
91
92			void		CreateGammaTable(double gamma, double min);
93			void		InitElements(int x, int y, uchar* elements);
94			uint		GetDensity(ColorRGB32 c) const;
95			uchar		ConvertUsingBlackValue(uchar byte) const;
96			void		DitherRGB32(uchar* destination, const uchar* source,
97							int x, int y, int width);
98
99			void		InitFloydSteinberg();
100			void		DeleteErrorTables();
101			void		UninitFloydSteinberg();
102			void		SetupErrorBuffer(int x, int y, int width);
103			void		DitherFloydSteinberg(uchar* destination,
104							const uchar* source, int x, int y, int width);
105
106private:
107	enum {
108		kGammaTableSize = 256,
109		kMaxNumberOfPlanes = 3
110	};
111
112	PFN_dither		fDither;
113	PFN_gray		fGray;
114	int				fPixelDepth;
115	Planes			fPlanes;
116	BlackValue		fBlackValue;
117	const uchar*	fPattern;
118	uint			fGammaTable[kGammaTableSize];
119	int				fNumberOfPlanes;
120	int				fCurrentPlane;
121	// fields used for floyd-steinberg dithering
122	int				fX;
123	int				fY;
124	int				fWidth;
125	int*			fErrorTables[kMaxNumberOfPlanes];
126};
127
128
129inline int
130Halftone::GetPixelDepth() const
131{
132	return fPixelDepth;
133}
134
135
136inline const uchar*
137Halftone::GetPattern() const
138{
139	return fPattern;
140}
141
142
143inline void
144Halftone::SetPattern(const uchar* pattern)
145{
146	fPattern = pattern;
147}
148
149
150inline PFN_gray
151Halftone::GetGrayFunction() const
152{
153	return fGray;
154}
155
156
157inline void
158Halftone::SetGrayFunction(PFN_gray gray)
159{
160	fGray = gray;
161}
162
163
164inline uint
165Halftone::GetDensity(ColorRGB32 c) const
166{
167	return fGammaTable[fGray(c)];
168}
169
170
171inline uchar
172Halftone::ConvertUsingBlackValue(uchar byte) const
173{
174	// bits with value = '1' in byte mean black
175	if (fBlackValue == kHighValueMeansBlack)
176		return byte;
177
178	return ~byte;
179}
180
181
182#endif	/* __HALFTONE_H */
183