Quote:
Originally Posted by Matthijs
Remember this is work in progress.
|
Adding a Mono4 mode solves some of the issues you all are encountering, after all, with the fixes to the gray calculation Mono8 is now back to being "perfect". The issue with image quality is in converting it to Mono4 for the iLiad.
You need to be careful with adding Mono4 as to not break binary compatibility, it must be added to the end of the enums.
splash/SplashTypes.h
Code:
splashModeBGRA8 // 1 byte per component, 4 bytes per pixel:
// BGRABGRA...
#if SPLASH_CMYK
,
splashModeCMYK8, // 1 byte per component, 4 bytes per pixel:
// CMYKCMYK...
splashModeACMYK8 // 1 byte per component, 5 bytes per pixel:
// ACMYKACMYK
#endif
,splashModeMono4 // 1 byte per component, 1 pixel per byte,
// most significant 4 bits contain pixel value
};
Adding this means you can do the gamma adjustment for the fonts etc...
An example of splashModeMono4 in action in my Poppler.
Code:
struct SplashOutImageData {
ImageStream *imgStr;
GfxImageColorMap *colorMap;
SplashColorPtr lookup;
int *maskColors;
SplashColorMode colorMode;
int width, height, y;
};
int *_ed_errors = NULL;
GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr line) {
SplashOutImageData *imgData = (SplashOutImageData *)data;
Guchar *p;
SplashColorPtr q, col;
GfxRGB rgb;
GfxGray gray;
#if SPLASH_CMYK
GfxCMYK cmyk;
#endif
int nComps, x;
if ((imgData->colorMode == splashModeMono4) &&
(imgData->y == 0)) {
// If we have an error distribution array, free it (must have had an
// error with previous image...)
if (_ed_errors) {
gfree(_ed_errors);
}
// Need to allocate error distribution array and zero it.
_ed_errors = (int *)gmalloc((imgData->width + 2) * 4);
memset(_ed_errors, 0, (imgData->width + 2) * 4);
}
if (imgData->y == imgData->height) {
// If we have an error distribution array, free it
if (_ed_errors) {
gfree(_ed_errors);
_ed_errors = NULL;
}
return gFalse;
}
nComps = imgData->colorMap->getNumPixelComps();
if (imgData->lookup) {
switch (imgData->colorMode) {
case splashModeMono4:
{
int origGrey = 0;
int grey = 0;
int error = 0;
int errorRight = 0;
int errorDownRight = 0;
for (x = 0, p = imgData->imgStr->getLine(), q = line;
x < imgData->width;
++x, p += nComps) {
origGrey = imgData->lookup[*p] + errorRight + _ed_errors[x+1];
// Convert pixel to Mono 4, clip < 0 and > Mono 4
if (origGrey <= 0) {
grey = 0;
} else if (origGrey >= 0x00ff) {
grey = 0x00ff; // No error for white of 255
} else {
grey = origGrey & 0x00f0;
}
// Put Mono 4 pixel with distributed error back
*q++ = grey;
// Calculate error
error = origGrey - grey;
// Distribute error
errorRight = (error * 7) >> 4;
_ed_errors[x] += (error * 3) >> 4;
_ed_errors[x+1] = ((error * 5) >> 4) + errorDownRight;
errorDownRight = error >> 4;
}
}
break;
case splashModeMono1:
case splashModeMono8: