]>
git.ipfire.org Git - thirdparty/cups.git/blob - filter/image-colorspace.c
2 * "$Id: image-colorspace.c,v 1.17 2000/01/04 13:45:44 mike Exp $"
4 * Colorspace conversions for the Common UNIX Printing System (CUPS).
6 * Copyright 1993-2000 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * ImageWhiteToWhite() - Convert luminance colors to device-dependent
27 * ImageWhiteToRGB() - Convert luminance data to RGB.
28 * ImageWhiteToBlack() - Convert luminance colors to black.
29 * ImageWhiteToCMY() - Convert luminance colors to CMY.
30 * ImageWhiteToCMYK() - Convert luminance colors to CMYK.
31 * ImageRGBToBlack() - Convert RGB data to black.
32 * ImageRGBToCMY() - Convert RGB colors to CMY.
33 * ImageRGBToCMYK() - Convert RGB colors to CMYK.
34 * ImageRGBToWhite() - Convert RGB colors to luminance.
35 * ImageRGBToRGB() - Convert RGB colors to device-dependent RGB.
36 * ImageLut() - Adjust all pixel values with the given LUT.
37 * ImageRGBAdjust() - Adjust the hue and saturation of the given RGB
39 * huerotate() - Rotate the hue, maintaining luminance.
40 * ident() - Make an identity matrix.
41 * mult() - Multiply two matrices.
42 * saturate() - Make a saturation matrix.
43 * xform() - Transform a 3D point using a matrix...
44 * xrotate() - Rotate about the x (red) axis...
45 * yrotate() - Rotate about the y (green) axis...
46 * zrotate() - Rotate about the z (blue) axis...
47 * zshear() - Shear z using x and y...
51 * Include necessary headers...
62 extern int ImageHaveProfile
;
63 extern int ImageDensity
[256];
64 extern int ImageMatrix
[3][3][256];
70 static void huerotate(float [3][3], float);
71 static void ident(float [3][3]);
72 static void mult(float [3][3], float [3][3], float [3][3]);
73 static void saturate(float [3][3], float);
74 static void xform(float [3][3], float, float, float, float *, float *, float *);
75 static void xrotate(float [3][3], float, float);
76 static void yrotate(float [3][3], float, float);
77 static void zrotate(float [3][3], float, float);
78 static void zshear(float [3][3], float, float);
82 * 'ImageWhiteToWhite()' - Convert luminance colors to device-dependent
87 ImageWhiteToWhite(const ib_t
*in
, /* I - Input pixels */
88 ib_t
*out
, /* I - Output pixels */
89 int count
) /* I - Number of pixels */
94 *out
++ = 255 - ImageDensity
[255 - *in
++];
98 memcpy(out
, in
, count
);
103 * 'ImageWhiteToRGB()' - Convert luminance data to RGB.
107 ImageWhiteToRGB(const ib_t
*in
, /* I - Input pixels */
108 ib_t
*out
, /* I - Output pixels */
109 int count
) /* I - Number of pixels */
111 if (ImageHaveProfile
)
114 out
[0] = 255 - ImageDensity
[255 - *in
++];
132 * 'ImageWhiteToBlack()' - Convert luminance colors to black.
136 ImageWhiteToBlack(const ib_t
*in
, /* I - Input pixels */
137 ib_t
*out
, /* I - Output pixels */
138 int count
) /* I - Number of pixels */
140 if (ImageHaveProfile
)
143 *out
++ = ImageDensity
[255 - *in
++];
149 *out
++ = 255 - *in
++;
156 * 'ImageWhiteToCMY()' - Convert luminance colors to CMY.
160 ImageWhiteToCMY(const ib_t
*in
, /* I - Input pixels */
161 ib_t
*out
, /* I - Output pixels */
162 int count
) /* I - Number of pixels */
164 if (ImageHaveProfile
)
167 out
[0] = ImageDensity
[255 - *in
++];
178 *out
++ = 255 - *in
++;
185 * 'ImageWhiteToCMYK()' - Convert luminance colors to CMYK.
189 ImageWhiteToCMYK(const ib_t
*in
, /* I - Input pixels */
190 ib_t
*out
, /* I - Output pixels */
191 int count
) /* I - Number of pixels */
193 if (ImageHaveProfile
)
199 *out
++ = ImageDensity
[255 - *in
++];
208 *out
++ = 255 - *in
++;
215 * 'ImageRGBToBlack()' - Convert RGB data to black.
219 ImageRGBToBlack(const ib_t
*in
, /* I - Input pixels */
220 ib_t
*out
, /* I - Output pixels */
221 int count
) /* I - Number of pixels */
223 if (ImageHaveProfile
)
226 *out
++ = ImageDensity
[255 - (31 * in
[0] + 61 * in
[1] + 8 * in
[2]) / 100];
233 *out
++ = 255 - (31 * in
[0] + 61 * in
[1] + 8 * in
[2]) / 100;
241 * 'ImageRGBToCMY()' - Convert RGB colors to CMY.
245 ImageRGBToCMY(const ib_t
*in
, /* I - Input pixels */
246 ib_t
*out
, /* I - Output pixels */
247 int count
) /* I - Number of pixels */
249 int c
, m
, y
, k
; /* CMYK values */
250 int cc
, cm
, cy
; /* Calibrated CMY values */
253 if (ImageHaveProfile
)
259 k
= min(c
, min(m
, y
));
264 cc
= ImageMatrix
[0][0][c
] +
265 ImageMatrix
[0][1][m
] +
266 ImageMatrix
[0][2][y
] + k
;
267 cm
= ImageMatrix
[1][0][c
] +
268 ImageMatrix
[1][1][m
] +
269 ImageMatrix
[1][2][y
] + k
;
270 cy
= ImageMatrix
[2][0][c
] +
271 ImageMatrix
[2][1][m
] +
272 ImageMatrix
[2][2][y
] + k
;
277 *out
++ = ImageDensity
[255];
279 *out
++ = ImageDensity
[cc
];
284 *out
++ = ImageDensity
[255];
286 *out
++ = ImageDensity
[cm
];
291 *out
++ = ImageDensity
[255];
293 *out
++ = ImageDensity
[cy
];
303 k
= min(c
, min(m
, y
));
305 *out
++ = (255 - in
[1] / 4) * (c
- k
) / 255 + k
;
306 *out
++ = (255 - in
[2] / 4) * (m
- k
) / 255 + k
;
307 *out
++ = (255 - in
[0] / 4) * (y
- k
) / 255 + k
;
315 * 'ImageRGBToCMYK()' - Convert RGB colors to CMYK.
319 ImageRGBToCMYK(const ib_t
*in
, /* I - Input pixels */
320 ib_t
*out
, /* I - Output pixels */
321 int count
)/* I - Number of pixels */
323 int c
, m
, y
, k
, /* CMYK values */
324 km
, /* Maximum K value */
325 diff
; /* Color differences */
326 int cc
, cm
, cy
; /* Calibrated CMY values */
329 if (ImageHaveProfile
)
335 k
= min(c
, min(m
, y
));
337 if ((km
= max(c
, max(m
, y
))) > k
)
344 cc
= (ImageMatrix
[0][0][c
] +
345 ImageMatrix
[0][1][m
] +
346 ImageMatrix
[0][2][y
]);
347 cm
= (ImageMatrix
[1][0][c
] +
348 ImageMatrix
[1][1][m
] +
349 ImageMatrix
[1][2][y
]);
350 cy
= (ImageMatrix
[2][0][c
] +
351 ImageMatrix
[2][1][m
] +
352 ImageMatrix
[2][2][y
]);
357 *out
++ = ImageDensity
[255];
359 *out
++ = ImageDensity
[cc
];
364 *out
++ = ImageDensity
[255];
366 *out
++ = ImageDensity
[cm
];
371 *out
++ = ImageDensity
[255];
373 *out
++ = ImageDensity
[cy
];
375 *out
++ = ImageDensity
[k
];
385 k
= min(c
, min(m
, y
));
387 if ((km
= max(c
, max(m
, y
))) > k
)
405 * 'ImageRGBToWhite()' - Convert RGB colors to luminance.
409 ImageRGBToWhite(const ib_t
*in
, /* I - Input pixels */
410 ib_t
*out
, /* I - Output pixels */
411 int count
) /* I - Number of pixels */
413 if (ImageHaveProfile
)
416 *out
++ = 255 - ImageDensity
[255 - (31 * in
[0] + 61 * in
[1] + 8 * in
[2]) / 100];
423 *out
++ = (31 * in
[0] + 61 * in
[1] + 8 * in
[2]) / 100;
431 * 'ImageRGBToRGB()' - Convert RGB colors to device-dependent RGB.
435 ImageRGBToRGB(const ib_t
*in
, /* I - Input pixels */
436 ib_t
*out
, /* I - Output pixels */
437 int count
) /* I - Number of pixels */
439 int c
, m
, y
, k
; /* CMYK values */
440 int cr
, cg
, cb
; /* Calibrated RGB values */
443 if (ImageHaveProfile
)
449 k
= min(c
, min(m
, y
));
454 cr
= ImageMatrix
[0][0][c
] +
455 ImageMatrix
[0][1][m
] +
456 ImageMatrix
[0][2][y
] + k
;
457 cg
= ImageMatrix
[1][0][c
] +
458 ImageMatrix
[1][1][m
] +
459 ImageMatrix
[1][2][y
] + k
;
460 cb
= ImageMatrix
[2][0][c
] +
461 ImageMatrix
[2][1][m
] +
462 ImageMatrix
[2][2][y
] + k
;
467 *out
++ = 255 - ImageDensity
[255];
469 *out
++ = 255 - ImageDensity
[cr
];
474 *out
++ = 255 - ImageDensity
[255];
476 *out
++ = 255 - ImageDensity
[cg
];
481 *out
++ = 255 - ImageDensity
[255];
483 *out
++ = 255 - ImageDensity
[cb
];
488 memcpy(out
, in
, count
* 3);
493 * 'ImageLut()' - Adjust all pixel values with the given LUT.
497 ImageLut(ib_t
*pixels
, /* IO - Input/output pixels */
498 int count
, /* I - Number of pixels/bytes to adjust */
499 const ib_t
*lut
) /* I - Lookup table */
503 *pixels
= lut
[*pixels
];
511 * 'ImageRGBAdjust()' - Adjust the hue and saturation of the given RGB colors.
515 ImageRGBAdjust(ib_t
*pixels
, /* IO - Input/output pixels */
516 int count
, /* I - Number of pixels to adjust */
517 int saturation
, /* I - Color saturation (%) */
518 int hue
) /* I - Color hue (degrees) */
520 int i
, j
, k
; /* Looping vars */
521 float mat
[3][3]; /* Color adjustment matrix */
522 static int last_sat
= 100, /* Last saturation used */
523 last_hue
= 0; /* Last hue used */
524 static int lut
[3][3][256]; /* Lookup table for matrix */
527 if (saturation
!= last_sat
||
531 * Build the color adjustment matrix...
535 saturate(mat
, saturation
* 0.01);
536 huerotate(mat
, (float)hue
);
539 * Convert the matrix into a 3x3 array of lookup tables...
542 for (i
= 0; i
< 3; i
++)
543 for (j
= 0; j
< 3; j
++)
544 for (k
= 0; k
< 256; k
++)
545 lut
[i
][j
][k
] = mat
[i
][j
] * k
+ 0.5;
548 * Save the saturation and hue to compare later...
551 last_sat
= saturation
;
556 * Adjust each pixel in the given buffer.
561 i
= lut
[0][0][pixels
[0]] +
562 lut
[1][0][pixels
[1]] +
563 lut
[2][0][pixels
[2]];
571 i
= lut
[0][1][pixels
[0]] +
572 lut
[1][1][pixels
[1]] +
573 lut
[2][1][pixels
[2]];
581 i
= lut
[0][2][pixels
[0]] +
582 lut
[1][2][pixels
[1]] +
583 lut
[2][2][pixels
[2]];
598 * The color saturation/hue matrix stuff is provided thanks to Mr. Paul
599 * Haeberli at "http://www.sgi.com/grafica/matrix/index.html".
603 * 'huerotate()' - Rotate the hue, maintaining luminance.
607 huerotate(float mat
[3][3], /* I - Matrix to append to */
608 float rot
) /* I - Hue rotation in degrees */
610 float hmat
[3][3]; /* Hue matrix */
611 float lx
, ly
, lz
; /* Luminance vector */
612 float xrs
, xrc
; /* X rotation sine/cosine */
613 float yrs
, yrc
; /* Y rotation sine/cosine */
614 float zrs
, zrc
; /* Z rotation sine/cosine */
615 float zsx
, zsy
; /* Z shear x/y */
619 * Load the identity matrix...
625 * Rotate the grey vector into positive Z...
630 xrotate(hmat
,xrs
,xrc
);
632 yrs
= -1.0 / sqrt(3.0);
633 yrc
= -M_SQRT2
* yrs
;
634 yrotate(hmat
,yrs
,yrc
);
637 * Shear the space to make the luminance plane horizontal...
640 xform(hmat
, 0.3086, 0.6094, 0.0820, &lx
, &ly
, &lz
);
643 zshear(hmat
, zsx
, zsy
);
649 zrs
= sin(rot
* M_PI
/ 180.0);
650 zrc
= cos(rot
* M_PI
/ 180.0);
652 zrotate(hmat
, zrs
, zrc
);
655 * Unshear the space to put the luminance plane back...
658 zshear(hmat
, -zsx
, -zsy
);
661 * Rotate the grey vector back into place...
664 yrotate(hmat
, -yrs
, yrc
);
665 xrotate(hmat
, -xrs
, xrc
);
668 * Append it to the current matrix...
671 mult(hmat
, mat
, mat
);
676 * 'ident()' - Make an identity matrix.
680 ident(float mat
[3][3]) /* I - Matrix to identify */
695 * 'mult()' - Multiply two matrices.
699 mult(float a
[3][3], /* I - First matrix */
700 float b
[3][3], /* I - Second matrix */
701 float c
[3][3]) /* I - Destination matrix */
703 int x
, y
; /* Looping vars */
704 float temp
[3][3]; /* Temporary matrix */
708 * Multiply a and b, putting the result in temp...
711 for (y
= 0; y
< 3; y
++)
712 for (x
= 0; x
< 3; x
++)
713 temp
[y
][x
] = b
[y
][0] * a
[0][x
] +
718 * Copy temp to c (that way c can be a pointer to a or b).
721 memcpy(c
, temp
, sizeof(temp
));
726 * 'saturate()' - Make a saturation matrix.
730 saturate(float mat
[3][3], /* I - Matrix to append to */
731 float sat
) /* I - Desired color saturation */
733 float smat
[3][3]; /* Saturation matrix */
736 smat
[0][0] = (1.0 - sat
) * 0.3086 + sat
;
737 smat
[0][1] = (1.0 - sat
) * 0.3086;
738 smat
[0][2] = (1.0 - sat
) * 0.3086;
739 smat
[1][0] = (1.0 - sat
) * 0.6094;
740 smat
[1][1] = (1.0 - sat
) * 0.6094 + sat
;
741 smat
[1][2] = (1.0 - sat
) * 0.6094;
742 smat
[2][0] = (1.0 - sat
) * 0.0820;
743 smat
[2][1] = (1.0 - sat
) * 0.0820;
744 smat
[2][2] = (1.0 - sat
) * 0.0820 + sat
;
746 mult(smat
, mat
, mat
);
751 * 'xform()' - Transform a 3D point using a matrix...
755 xform(float mat
[3][3], /* I - Matrix */
756 float x
, /* I - Input X coordinate */
757 float y
, /* I - Input Y coordinate */
758 float z
, /* I - Input Z coordinate */
759 float *tx
, /* O - Output X coordinate */
760 float *ty
, /* O - Output Y coordinate */
761 float *tz
) /* O - Output Z coordinate */
763 *tx
= x
* mat
[0][0] + y
* mat
[1][0] + z
* mat
[2][0];
764 *ty
= x
* mat
[0][1] + y
* mat
[1][1] + z
* mat
[2][1];
765 *tz
= x
* mat
[0][2] + y
* mat
[1][2] + z
* mat
[2][2];
770 * 'xrotate()' - Rotate about the x (red) axis...
774 xrotate(float mat
[3][3], /* I - Matrix */
775 float rs
, /* I - Rotation angle sine */
776 float rc
) /* I - Rotation angle cosine */
778 float rmat
[3][3]; /* I - Rotation matrix */
793 mult(rmat
, mat
, mat
);
798 * 'yrotate()' - Rotate about the y (green) axis...
802 yrotate(float mat
[3][3], /* I - Matrix */
803 float rs
, /* I - Rotation angle sine */
804 float rc
) /* I - Rotation angle cosine */
806 float rmat
[3][3]; /* I - Rotation matrix */
826 * 'zrotate()' - Rotate about the z (blue) axis...
830 zrotate(float mat
[3][3], /* I - Matrix */
831 float rs
, /* I - Rotation angle sine */
832 float rc
) /* I - Rotation angle cosine */
834 float rmat
[3][3]; /* I - Rotation matrix */
854 * 'zshear()' - Shear z using x and y...
858 zshear(float mat
[3][3], /* I - Matrix */
859 float dx
, /* I - X shear */
860 float dy
) /* I - Y shear */
862 float smat
[3][3]; /* Shear matrix */
877 mult(smat
, mat
, mat
);
882 * End of "$Id: image-colorspace.c,v 1.17 2000/01/04 13:45:44 mike Exp $".