2005-11-14 22:08:35 +03:00
|
|
|
/*
|
|
|
|
* 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;
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
typedef void (Halftone::*PFN_dither)(uchar* destination, const uchar* source,
|
|
|
|
int x, int y, int width);
|
|
|
|
|
2005-11-14 22:08:35 +03:00
|
|
|
typedef uint (*PFN_gray)(ColorRGB32 c);
|
|
|
|
|
|
|
|
class Halftone {
|
|
|
|
public:
|
|
|
|
enum DitherType {
|
|
|
|
kType1,
|
|
|
|
kType2,
|
|
|
|
kType3,
|
|
|
|
kTypeFloydSteinberg,
|
|
|
|
};
|
2010-12-08 23:07:22 +03:00
|
|
|
|
2005-11-14 22:08:35 +03:00
|
|
|
enum GrayFunction {
|
|
|
|
kMixToGray,
|
|
|
|
kRedChannel,
|
|
|
|
kGreenChannel,
|
|
|
|
kBlueChannel
|
|
|
|
};
|
2010-12-08 23:07:22 +03:00
|
|
|
|
2005-11-14 22:08:35 +03:00
|
|
|
enum Planes {
|
|
|
|
kPlaneMonochrome1, // 1 bit depth (0 white, 1 black)
|
|
|
|
kPlaneRGB1, // 3 planes, 1 bit depth (0 black, 7 white)
|
|
|
|
};
|
2010-12-08 23:07:22 +03:00
|
|
|
|
2005-11-14 22:08:35 +03:00
|
|
|
enum BlackValue {
|
|
|
|
kHighValueMeansBlack,
|
|
|
|
kLowValueMeansBlack,
|
|
|
|
};
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
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);
|
2005-11-14 22:08:35 +03:00
|
|
|
|
|
|
|
protected:
|
2010-12-08 23:07:22 +03:00
|
|
|
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);
|
2005-11-14 22:08:35 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
enum {
|
|
|
|
kGammaTableSize = 256,
|
|
|
|
kMaxNumberOfPlanes = 3
|
|
|
|
};
|
2010-12-08 23:07:22 +03:00
|
|
|
|
2005-11-14 22:08:35 +03:00
|
|
|
PFN_dither fDither;
|
2010-12-08 23:07:22 +03:00
|
|
|
PFN_gray fGray;
|
|
|
|
int fPixelDepth;
|
|
|
|
Planes fPlanes;
|
|
|
|
BlackValue fBlackValue;
|
|
|
|
const uchar* fPattern;
|
|
|
|
uint fGammaTable[kGammaTableSize];
|
|
|
|
int fNumberOfPlanes;
|
|
|
|
int fCurrentPlane;
|
2005-11-14 22:08:35 +03:00
|
|
|
// fields used for floyd-steinberg dithering
|
2010-12-08 23:07:22 +03:00
|
|
|
int fX;
|
|
|
|
int fY;
|
|
|
|
int fWidth;
|
|
|
|
int* fErrorTables[kMaxNumberOfPlanes];
|
2005-11-14 22:08:35 +03:00
|
|
|
};
|
|
|
|
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
inline int
|
|
|
|
Halftone::GetPixelDepth() const
|
2005-11-14 22:08:35 +03:00
|
|
|
{
|
|
|
|
return fPixelDepth;
|
|
|
|
}
|
|
|
|
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
inline const uchar*
|
|
|
|
Halftone::GetPattern() const
|
2005-11-14 22:08:35 +03:00
|
|
|
{
|
|
|
|
return fPattern;
|
|
|
|
}
|
|
|
|
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
inline void
|
|
|
|
Halftone::SetPattern(const uchar* pattern)
|
2005-11-14 22:08:35 +03:00
|
|
|
{
|
|
|
|
fPattern = pattern;
|
|
|
|
}
|
|
|
|
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
inline PFN_gray
|
|
|
|
Halftone::GetGrayFunction() const
|
2005-11-14 22:08:35 +03:00
|
|
|
{
|
|
|
|
return fGray;
|
|
|
|
}
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
|
|
|
|
inline void
|
|
|
|
Halftone::SetGrayFunction(PFN_gray gray)
|
2005-11-14 22:08:35 +03:00
|
|
|
{
|
|
|
|
fGray = gray;
|
|
|
|
}
|
|
|
|
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
inline uint
|
|
|
|
Halftone::GetDensity(ColorRGB32 c) const
|
2005-11-14 22:08:35 +03:00
|
|
|
{
|
|
|
|
return fGammaTable[fGray(c)];
|
|
|
|
}
|
|
|
|
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
inline uchar
|
|
|
|
Halftone::ConvertUsingBlackValue(uchar byte) const
|
2005-11-14 22:08:35 +03:00
|
|
|
{
|
|
|
|
// bits with value = '1' in byte mean black
|
2010-12-08 23:07:22 +03:00
|
|
|
if (fBlackValue == kHighValueMeansBlack)
|
2005-11-14 22:08:35 +03:00
|
|
|
return byte;
|
2010-12-08 23:07:22 +03:00
|
|
|
|
|
|
|
return ~byte;
|
2005-11-14 22:08:35 +03:00
|
|
|
}
|
|
|
|
|
2010-12-08 23:07:22 +03:00
|
|
|
|
2005-11-14 22:08:35 +03:00
|
|
|
#endif /* __HALFTONE_H */
|