xref: /haiku/headers/libs/print/libprint/Halftone.h (revision e27109c167b6dd62e6ceba4008d685805e10121e)
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
12 typedef 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
20 typedef struct {
21 	uchar alpha; // unused in B_RGB32_BIG
22 	uchar red;
23 	uchar green;
24 	uchar blue;
25 } ColorRGB32Big;
26 
27 typedef union {
28 	ColorRGB32Little little;
29 	ColorRGB32Big    big;
30 } ColorRGB32;
31 
32 class Halftone;
33 
34 typedef void (Halftone::*PFN_dither)(uchar* destination, const uchar* source,
35 	int x, int y, int width);
36 
37 typedef uint (*PFN_gray)(ColorRGB32 c);
38 
39 class Halftone {
40 public:
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 
81 protected:
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 
106 private:
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 
129 inline int
GetPixelDepth()130 Halftone::GetPixelDepth() const
131 {
132 	return fPixelDepth;
133 }
134 
135 
136 inline const uchar*
GetPattern()137 Halftone::GetPattern() const
138 {
139 	return fPattern;
140 }
141 
142 
143 inline void
SetPattern(const uchar * pattern)144 Halftone::SetPattern(const uchar* pattern)
145 {
146 	fPattern = pattern;
147 }
148 
149 
150 inline PFN_gray
GetGrayFunction()151 Halftone::GetGrayFunction() const
152 {
153 	return fGray;
154 }
155 
156 
157 inline void
SetGrayFunction(PFN_gray gray)158 Halftone::SetGrayFunction(PFN_gray gray)
159 {
160 	fGray = gray;
161 }
162 
163 
164 inline uint
GetDensity(ColorRGB32 c)165 Halftone::GetDensity(ColorRGB32 c) const
166 {
167 	return fGammaTable[fGray(c)];
168 }
169 
170 
171 inline uchar
ConvertUsingBlackValue(uchar byte)172 Halftone::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