#ifndef __HALFTONE_H
#define __HALFTONE_H
#include <GraphicsDefs.h>
typedef struct {
uchar blue;
uchar green;
uchar red;
uchar alpha;
} ColorRGB32Little;
typedef struct {
uchar alpha;
uchar red;
uchar green;
uchar blue;
} ColorRGB32Big;
typedef union {
ColorRGB32Little little;
ColorRGB32Big big;
} ColorRGB32;
class Halftone;
typedef void (Halftone::*PFN_dither)(uchar* destination, const uchar* source,
int x, int y, int width);
typedef uint (*PFN_gray)(ColorRGB32 c);
class Halftone {
public:
enum DitherType {
kType1,
kType2,
kType3,
kTypeFloydSteinberg,
};
enum GrayFunction {
kMixToGray,
kRedChannel,
kGreenChannel,
kBlueChannel
};
enum Planes {
kPlaneMonochrome1,
kPlaneRGB1,
};
enum BlackValue {
kHighValueMeansBlack,
kLowValueMeansBlack,
};
Halftone(color_space colorSpace, double gamma = 1.4,
double min = 0.0,
DitherType dither_type = kTypeFloydSteinberg);
~Halftone();
void SetPlanes(Planes planes);
void SetBlackValue(BlackValue blackValue);
void Dither(uchar *destination, const uchar *source, int x,
int y, int width);
int GetPixelDepth() const;
const uchar* GetPattern() const;
void SetPattern(const uchar *pattern);
protected:
Halftone(const Halftone &);
Halftone& operator=(const Halftone &);
PFN_gray GetGrayFunction() const;
void SetGrayFunction(PFN_gray gray);
void SetGrayFunction(GrayFunction grayFunction);
void CreateGammaTable(double gamma, double min);
void InitElements(int x, int y, uchar* elements);
uint GetDensity(ColorRGB32 c) const;
uchar ConvertUsingBlackValue(uchar byte) const;
void DitherRGB32(uchar* destination, const uchar* source,
int x, int y, int width);
void InitFloydSteinberg();
void DeleteErrorTables();
void UninitFloydSteinberg();
void SetupErrorBuffer(int x, int y, int width);
void DitherFloydSteinberg(uchar* destination,
const uchar* source, int x, int y, int width);
private:
enum {
kGammaTableSize = 256,
kMaxNumberOfPlanes = 3
};
PFN_dither fDither;
PFN_gray fGray;
int fPixelDepth;
Planes fPlanes;
BlackValue fBlackValue;
const uchar* fPattern;
uint fGammaTable[kGammaTableSize];
int fNumberOfPlanes;
int fCurrentPlane;
int fX;
int fY;
int fWidth;
int* fErrorTables[kMaxNumberOfPlanes];
};
inline int
Halftone::GetPixelDepth() const
{
return fPixelDepth;
}
inline const uchar*
Halftone::GetPattern() const
{
return fPattern;
}
inline void
Halftone::SetPattern(const uchar* pattern)
{
fPattern = pattern;
}
inline PFN_gray
Halftone::GetGrayFunction() const
{
return fGray;
}
inline void
Halftone::SetGrayFunction(PFN_gray gray)
{
fGray = gray;
}
inline uint
Halftone::GetDensity(ColorRGB32 c) const
{
return fGammaTable[fGray(c)];
}
inline uchar
Halftone::ConvertUsingBlackValue(uchar byte) const
{
if (fBlackValue == kHighValueMeansBlack)
return byte;
return ~byte;
}
#endif