⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdevcd8-beta4.c

📁 printer driver for the HP670, HP690, HP850, HP855 HP870, HP890, HP1100 and HP1600 color printers.
💻 C
📖 第 1 页 / 共 5 页
字号:
    
    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 + -