📄 gdevcd8-beta4.c
字号:
if (*magenta + *yellow + *cyan > 0) { /* if any color at all */
is_color = 1;
/* Test whether we 've already computet the value */
if (*inword == last_color_value) {
/* save a copy of the current color before it will be modified */
last_color_value = *inword;
/* copy the result of the old value onto the new position */
*inword = *last_color;
} else {
/* save a copy of the current color before it will be modified */
last_color_value = *inword;
if ((*cyan >= *magenta)
&& (*magenta >= *yellow)
&& (*yellow > 0)) { /* if any grey component */
DOGCR(cyan, magenta, yellow, black);
} else if ((*cyan >= *yellow)
&& (*yellow >= *magenta)
&& (*magenta > 0)) {
DOGCR(cyan, yellow, magenta, black);
} else if ((*yellow >= *magenta)
&& (*magenta >= *cyan)
&& (*cyan > 0)) {
DOGCR(yellow, magenta, cyan, black);
} else if ((*yellow >= *cyan)
&& (*cyan >= *magenta)
&& (*magenta > 0)) {
DOGCR(yellow, cyan, magenta, black);
} else if ((*magenta >= *yellow)
&& (*yellow >= *cyan)
&& (*cyan > 0)) {
DOGCR(magenta, yellow, cyan, black);
} else if ((*magenta >= *cyan)
&& (*cyan >= *yellow)
&& (*yellow > 0)) {
DOGCR(magenta, cyan, yellow, black);
} else { /* do gamma only if no black */
}
*cyan = *(cvalues + *cyan);
*magenta = *(mvalues + *magenta);
*yellow = *(yvalues + *yellow);
last_color = inword; /* save pointer */
}/* end current_color */
} /* end of if c+m+y > 0 */
*black = *(kvalues + *black);
inword = inword + 1;
} /* end of for bytecount */
return is_color;
}
/* Since resolution can be different on different planes, we need to
rescale the data byte by byte */
private int
rescale_byte_wise2x2(int bytecount, const byte * inbytea, const byte * inbyteb,
byte * outbyte)
{
register int i, j;
int max = bytecount / 2;
for (i = 0; i < max; i += 4) {
j = 2 * i;
/* cyan */
outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5] + inbyteb[j + 1] +
inbyteb[j + 5]) / 4;
/* magenta */
outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6] + inbyteb[j + 2] +
inbyteb[j + 6]) / 4;
/* yellow */
outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7] + inbyteb[j + 3] +
inbyteb[j + 7]) / 4;
}
return max;
}
/* Since resolution can be different on different planes, we need to
rescale the data byte by byte */
private int
rescale_byte_wise2x1(int bytecount, const byte * inbytea, const byte * inbyteb,
byte * outbyte)
{
register int i, j;
int max = bytecount / 2;
for (i = 0; i < max; i += 4) {
j = 2 * i;
/* cyan */
outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5]) / 2;
/* magenta */
outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6]) / 2;
/* yellow */
outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7]) / 2;
}
return max;
}
/* Since resolution can be different on different planes, we need to
rescale the data byte by byte */
private int
rescale_byte_wise1x2(int bytecount, const byte * inbytea, const byte * inbyteb,
byte * outbyte)
{
register int i;
for (i = 0; i < bytecount; i += 4) {
/* cyan */
outbyte[i + 1] = (inbytea[i + 1] + inbyteb[i + 1]) / 2;
/* magenta */
outbyte[i + 2] = (inbytea[i + 2] + inbyteb[i + 2]) / 2;
/* yellow */
outbyte[i + 3] = (inbytea[i + 3] + inbyteb[i + 3]) / 2;
}
return bytecount;
}
/* Since resolution can be different on different planes, we need to
rescale the data byte by byte */
private int
rescale_byte_wise1x1(int bytecount, const byte * inbytea, const byte * inbyteb,
byte * outbyte)
{
register int i;
for (i = 0; i < bytecount; i += 4) {
/* cyan */
outbyte[i + 1] = inbytea[i + 1];
/* magenta */
outbyte[i + 2] = inbytea[i + 2];
/* yellow */
outbyte[i + 3] = inbytea[i + 3];
}
return bytecount;
}
/* MACROS FOR DITHERING (we use macros for compact source and faster code) */
/* Floyd-Steinberg dithering. Often results in a dramatic improvement in
* subjective image quality, but can also produce dramatic increases in
* amount of printer data generated and actual printing time!! Mode 9 2D
* compression is still useful for fairly flat colour or blank areas but its
* compression is much less effective in areas where the dithering has
* effectively randomised the dot distribution. */
#define SHIFT ((I * 8) - 13)
#define C 8
#define BLACKOFFSET (128 << SHIFT) /* distance from min to max */
#define THRESHOLD (128 << SHIFT)
#define MAXVALUE (THRESHOLD + BLACKOFFSET)
/* -64 to 64 */
#define RANDOM ((rand() << SHIFT) % THRESHOLD - (THRESHOLD >> 1))
/* --- needed for the hp850 color -- */
/*
Mode Planes Intensity
Low A 1.0
Medium B 1.5
High A&B 2.0
Note that planes A&B is not the sum of the intensities of plane A and plane B.
Range Planes Max Intensity
0-63 A < 50% 0.5
64-127 A > 50% 1.0
128-191 B > 50% 1.5
192-255 A&B > 50% 2.0
Note some specific values:
Value Planes Intensity
0 0 0.0
32 25% A 0.25
64 50% A 0.5
128 100% A 1.0
129 99% A, 1% B 1.01
192 100% B 1.5
255 100% C 2.0
Keep in mind that only the range 0-63 has a pixel rate <50%. All others
have a pixel rate >50%.
*/
#define COLOROFFSET ( 64 << SHIFT) /* distance between color intensities */
#define THRESHOLDS ( 64 << SHIFT) /* intensity A */
#define THRESHOLDM (128 << SHIFT) /* intensity B */
#define THRESHOLDL (192 << SHIFT) /* intensities A & B */
#define MAXVALUES (THRESHOLDS + COLOROFFSET)
#define MAXVALUEM (THRESHOLDM + COLOROFFSET)
#define MAXVALUEL (THRESHOLDL + COLOROFFSET)
#define CRANDOM ((rand() << SHIFT) % THRESHOLDS - (THRESHOLDS >> 1))
/* --------------------------- */
/* initialise the error_buffer */
private void
init_error_buffer(struct misc_struct * misc_vars,
struct ptr_arrays * data_ptrs)
{
int i;
int *ep;
int *epc;
ep = data_ptrs->errors[0];
epc = data_ptrs->errors_c[0];
if (misc_vars->bits_per_pixel > 4) { /* Randomly seed initial error
buffer */
/* Otherwise, the first dithered rows would look rather uniform */
for (i = 0; i < misc_vars->databuff_size; i++) { /* 600dpi planes */
*ep++ = RANDOM;
}
/* Now for the 2 * 300dpi color planes */
for (i = 0; i < misc_vars->databuff_size_c; i++) {
*epc++ = CRANDOM;
}
}
return;
}
#define FSdither(inP, out, errP, Err, Bit, Offset, Element)\
{\
oldErr = Err;\
Err = (*(errP + Element)\
+ ((Err * 7 + C) >> 4)\
+ ((int)*(inP + Element) << SHIFT));\
if (Err > THRESHOLD || *(inP + Element) == 255 /* b/w optimization */) {\
out |= Bit;\
Err -= MAXVALUE;\
}\
*(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
*(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
}
/* The hp850c has 600dpi black and 300 dpi color. Therefore, we need
an adapted dither algorythm */
private void
FSDlinebw(int scan, int plane_size,
struct error_val_field * error_values,
byte * kP, int n, int * ep, byte * dp)
{
if (scan == 0) { /* going_up */
byte k, bitmask; /* k = outbyte byte, whereas bitmask defines the
bit to be set within k */
int oldErr, i;
for (i = 0; i < plane_size; i++) {
bitmask = 0x80;
for (k = 0; bitmask != 0; bitmask >>= 1) {
/* dp points to the first word of the input data which is in
kcmy-format */
/* k points to the beginning of the first outbut byte, which
is filled up, bit by bit while looping over bytemask */
/* ep points to the first word of the error-plane which
contains the errors kcmy format */
/* err_values->k tempararily holds the error-value */
/* bitmask selects the bit to be set in the outbyte */
/* n gives the offset for the byte selection within
words. With simple cmyk-printing, this should be 4 */
/* 0 points to the active color within the input-word, i.e. 0
= black, 1 = cyan, 2 = yellow, 3 = magenta */
FSdither(dp, k, ep, error_values->k, bitmask, -n, 0);
dp += n, ep += n; /* increment the input and error pointer one
word (=4 byte) further, in order to
convert the next word into an bit */
}
*kP++ = k; /* fill the output-plane byte with the computed byte
and increment the output plane pointer one byte */
}
} else { /* going_down */
byte k, bitmask;
int oldErr, i;
for (i = 0; i < plane_size; i++) {
bitmask = 0x01;
for (k = 0; bitmask != 0; bitmask <<= 1) {
dp -= n, ep -= n;
FSdither(dp, k, ep, error_values->k, bitmask, n, 0);
}
*--kP = k;
}
}
return;
}
/* Since bw has already been dithered for the hp850c, we need
an adapted dither algorythm */
private void
FSDlinec2(int scan, int plane_size,
struct error_val_field *error_values,
byte * cPa, byte * mPa, byte * yPa, int n,
byte * dp, int *ep)
{
if (scan == 0) { /* going_up */
int oldErr, i;
byte ca, ya, ma, bitmask;
for (i = 0; i < plane_size; i++) {
bitmask = 0x80;
ca = ya = ma = 0;
for (ca = 0; bitmask != 0; bitmask >>= 1) {
FSdither(dp, ca, ep, error_values->c, bitmask, -n, n - 3);
FSdither(dp, ma, ep, error_values->m, bitmask, -n, n - 2);
FSdither(dp, ya, ep, error_values->y, bitmask, -n, n - 1);
dp += n, ep += n;
}
*cPa++ = ca;
*mPa++ = ma;
*yPa++ = ya;
}
} else { /* going_down */
byte ca, ya, ma, bitmask;
int oldErr, i;
for (i = 0; i < plane_size; i++) {
bitmask = 0x01;
ca = ya = ma = 0;
for (ca = 0; bitmask != 0; bitmask <<= 1) {
dp -= n, ep -= n;
FSdither(dp, ya, ep, error_values->y, bitmask, n, n - 1);
FSdither(dp, ma, ep, error_values->m, bitmask, n, n - 2);
FSdither(dp, ca, ep, error_values->c, bitmask, n, n - 3);
}
*--yPa = ya;
*--mPa = ma;
*--cPa = ca;
}
}
return;
}
/* while printing on paper, we only use 3 -intensities */
#define FSdither8503(inP, outa, outb, errP, Err, Bit, Offset, Element)\
{\
oldErr = Err;\
Err = (*(errP + Element)\
+ ((Err * 7 + C) >> 4)\
+ ((int) *(inP + Element) << SHIFT));\
if ((Err > THRESHOLDS) && (Err <= THRESHOLDM)) {\
outa |= Bit;\
Err -= MAXVALUES;\
}\
if (Err > THRESHOLDM) {\
outb |= Bit;\
Err -= MAXVALUEM;\
}\
*(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
*(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
}
/* On ordinary paper, we'll only use 3 intensi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -