haiku/headers/libs/print/libprint/Halftone.h

183 lines
3.4 KiB
C++

/*
* Halftone.h
* Copyright 1999-2000 Y.Takagi. All Rights Reserved.
*/
#ifndef __HALFTONE_H
#define __HALFTONE_H
#include <GraphicsDefs.h>
// 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* 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, // 1 bit depth (0 white, 1 black)
kPlaneRGB1, // 3 planes, 1 bit depth (0 black, 7 white)
};
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: 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* 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;
// 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;
return ~byte;
}
#endif /* __HALFTONE_H */