xref: /haiku/headers/libs/print/libprint/Halftone.h (revision b06a48ab8f30b45916a9c157b992827779182163)
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 typedef void (Halftone::*PFN_dither)(uchar *dst, const uchar *src, int x, int y, int width);
34 typedef uint (*PFN_gray)(ColorRGB32 c);
35 
36 class Halftone {
37 public:
38 	enum DitherType {
39 		kType1,
40 		kType2,
41 		kType3,
42 		kTypeFloydSteinberg,
43 	};
44 	enum GrayFunction {
45 		kMixToGray,
46 		kRedChannel,
47 		kGreenChannel,
48 		kBlueChannel
49 	};
50 	enum Planes {
51 		kPlaneMonochrome1, // 1 bit depth (0 white, 1 black)
52 		kPlaneRGB1,        // 3 planes, 1 bit depth (0 black, 7 white)
53 	};
54 	enum BlackValue {
55 		kHighValueMeansBlack,
56 		kLowValueMeansBlack,
57 	};
58 	Halftone(color_space cs, double gamma = 1.4, double min = 0.0, DitherType dither_type = kTypeFloydSteinberg);
59 	~Halftone();
60 	void setPlanes(Planes planes);
61 	void setBlackValue(BlackValue blackValue);
62 	void dither(uchar *dst, const uchar *src, int x, int y, int width);
63 	int getPixelDepth() const;
64 	const uchar *getPattern() const;
65 	void setPattern(const uchar *pattern);
66 
67 protected:
68 	// PFN_gray: return value of 0 means low density (or black) and value of 255 means high density (or white)
69 	PFN_gray getGrayFunction() const;
70 	void setGrayFunction(PFN_gray gray);
71 	void setGrayFunction(GrayFunction grayFunction);
72 
73 	void createGammaTable(double gamma, double min);
74 	void initElements(int x, int y, uchar *elements);
75 	uint getDensity(ColorRGB32 c) const;
76 	uchar convertUsingBlackValue(uchar byte) const;
77 	void ditherRGB32(uchar *dst, const uchar *src, int x, int y, int width);
78 
79 	void initFloydSteinberg();
80 	void deleteErrorTables();
81 	void uninitFloydSteinberg();
82 	void setupErrorBuffer(int x, int y, int width);
83 	void ditherFloydSteinberg(uchar *dst, const uchar* src, int x, int y, int width);
84 
85 	Halftone(const Halftone &);
86 	Halftone &operator = (const Halftone &);
87 
88 private:
89 	enum {
90 		kGammaTableSize = 256,
91 		kMaxNumberOfPlanes = 3
92 	};
93 	PFN_dither		fDither;
94 	PFN_gray        fGray;
95 	int             fPixelDepth;
96 	Planes          fPlanes;
97 	BlackValue      fBlackValue;
98 	const uchar     *fPattern;
99 	uint            fGammaTable[kGammaTableSize];
100 	int             fNumberOfPlanes;
101 	int             fCurrentPlane;
102 	// fields used for floyd-steinberg dithering
103 	int             fX;
104 	int             fY;
105 	int             fWidth;
106 	int             *fErrorTables[kMaxNumberOfPlanes];
107 };
108 
109 inline int Halftone::getPixelDepth() const
110 {
111 	return fPixelDepth;
112 }
113 
114 inline const uchar * Halftone::getPattern() const
115 {
116 	return fPattern;
117 }
118 
119 inline void Halftone::setPattern(const uchar *pattern)
120 {
121 	fPattern = pattern;
122 }
123 
124 inline PFN_gray Halftone::getGrayFunction() const
125 {
126 	return fGray;
127 }
128 inline void Halftone::setGrayFunction(PFN_gray gray)
129 {
130 	fGray = gray;
131 }
132 
133 inline uint Halftone::getDensity(ColorRGB32 c) const
134 {
135 	return fGammaTable[fGray(c)];
136 }
137 
138 inline uchar Halftone::convertUsingBlackValue(uchar byte) const
139 {
140 	// bits with value = '1' in byte mean black
141 	if (fBlackValue == kHighValueMeansBlack) {
142 		return byte;
143 	} else {
144 		return ~byte;
145 	}
146 }
147 
148 #endif	/* __HALFTONE_H */
149