/* * Halftone.h * Copyright 1999-2000 Y.Takagi. All Rights Reserved. */ #ifndef __HALFTONE_H #define __HALFTONE_H #include // definition for B_RGB32 (=B_RGB32_LITTLE) and B_RGBA32 typedef struct { uchar blue; uchar green; uchar red; uchar alpha; // unused in B_RGB32 } ColorRGB32Little; // definition for B_RGB32_BIG and B_RGBA32_BIG typedef struct { uchar alpha; // unused in B_RGB32_BIG uchar red; uchar green; uchar blue; } ColorRGB32Big; typedef union { ColorRGB32Little little; ColorRGB32Big big; } ColorRGB32; class Halftone; typedef void (Halftone::*PFN_dither)(uchar *dst, const uchar *src, 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, // 1 bit depth (0 white, 1 black) kPlaneRGB1, // 3 planes, 1 bit depth (0 black, 7 white) }; enum BlackValue { kHighValueMeansBlack, kLowValueMeansBlack, }; Halftone(color_space cs, double gamma = 1.4, double min = 0.0, DitherType dither_type = kTypeFloydSteinberg); ~Halftone(); void setPlanes(Planes planes); void setBlackValue(BlackValue blackValue); void dither(uchar *dst, const uchar *src, int x, int y, int width); int getPixelDepth() const; const uchar *getPattern() const; void setPattern(const uchar *pattern); protected: // PFN_gray: return value of 0 means low density (or black) and value of 255 means high density (or white) 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 *dst, const uchar *src, int x, int y, int width); void initFloydSteinberg(); void deleteErrorTables(); void uninitFloydSteinberg(); void setupErrorBuffer(int x, int y, int width); void ditherFloydSteinberg(uchar *dst, const uchar* src, int x, int y, int width); Halftone(const Halftone &); Halftone &operator = (const Halftone &); 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; // fields used for floyd-steinberg dithering 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 { // bits with value = '1' in byte mean black if (fBlackValue == kHighValueMeansBlack) { return byte; } else { return ~byte; } } #endif /* __HALFTONE_H */