ImagingColors.pas 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. {
  2. $Id$
  3. Vampyre Imaging Library
  4. by Marek Mauder
  5. http://imaginglib.sourceforge.net
  6. The contents of this file are used with permission, subject to the Mozilla
  7. Public License Version 1.1 (the "License"); you may not use this file except
  8. in compliance with the License. You may obtain a copy of the License at
  9. http://www.mozilla.org/MPL/MPL-1.1.html
  10. Software distributed under the License is distributed on an "AS IS" basis,
  11. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  12. the specific language governing rights and limitations under the License.
  13. Alternatively, the contents of this file may be used under the terms of the
  14. GNU Lesser General Public License (the "LGPL License"), in which case the
  15. provisions of the LGPL License are applicable instead of those above.
  16. If you wish to allow use of your version of this file only under the terms
  17. of the LGPL License and not to allow others to use your version of this file
  18. under the MPL, indicate your decision by deleting the provisions above and
  19. replace them with the notice and other provisions required by the LGPL
  20. License. If you do not delete the provisions above, a recipient may use
  21. your version of this file under either the MPL or the LGPL License.
  22. For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html
  23. }
  24. { This unit contains functions for manipulating and converting color values.}
  25. unit ImagingColors;
  26. interface
  27. {$I ImagingOptions.inc}
  28. uses
  29. SysUtils, ImagingTypes, ImagingUtility;
  30. { Converts RGB color to YUV.}
  31. procedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);
  32. { Converts YIV to RGB color.}
  33. procedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);
  34. { Converts RGB color to YCbCr as used in JPEG.}
  35. procedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);
  36. { Converts YCbCr as used in JPEG to RGB color.}
  37. procedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);
  38. { Converts RGB color to YCbCr as used in JPEG.}
  39. procedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);
  40. { Converts YCbCr as used in JPEG to RGB color.}
  41. procedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);
  42. { Converts RGB color to CMY.}
  43. procedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);
  44. { Converts CMY to RGB color.}
  45. procedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);
  46. { Converts RGB color to CMY.}
  47. procedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);
  48. { Converts CMY to RGB color.}
  49. procedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);
  50. { Converts RGB color to CMYK.}
  51. procedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);
  52. { Converts CMYK to RGB color.}
  53. procedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);
  54. { Converts RGB color to CMYK.}
  55. procedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);
  56. { Converts CMYK to RGB color.}
  57. procedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);
  58. { Converts RGB color to YCoCg.}
  59. procedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);
  60. { Converts YCoCg to RGB color.}
  61. procedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);
  62. implementation
  63. procedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);
  64. begin
  65. Y := ClampToByte(Round( 0.257 * R + 0.504 * G + 0.098 * B) + 16);
  66. V := ClampToByte(Round( 0.439 * R - 0.368 * G - 0.071 * B) + 128);
  67. U := ClampToByte(Round(-0.148 * R - 0.291 * G + 0.439 * B) + 128);
  68. end;
  69. procedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);
  70. var
  71. CY, CU, CV: LongInt;
  72. begin
  73. CY := Y - 16;
  74. CU := U - 128;
  75. CV := V - 128;
  76. R := ClampToByte(Round(1.164 * CY - 0.002 * CU + 1.596 * CV));
  77. G := ClampToByte(Round(1.164 * CY - 0.391 * CU - 0.813 * CV));
  78. B := ClampToByte(Round(1.164 * CY + 2.018 * CU - 0.001 * CV));
  79. end;
  80. procedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);
  81. begin
  82. Y := ClampToByte(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));
  83. Cb := ClampToByte(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B + 128));
  84. Cr := ClampToByte(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B + 128));
  85. end;
  86. procedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);
  87. begin
  88. R := ClampToByte(Round(Y + 1.40200 * (Cr - 128)));
  89. G := ClampToByte(Round(Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)));
  90. B := ClampToByte(Round(Y + 1.77200 * (Cb - 128)));
  91. end;
  92. procedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);
  93. begin
  94. Y := ClampToWord(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));
  95. Cb := ClampToWord(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B + 32768));
  96. Cr := ClampToWord(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B + 32768));
  97. end;
  98. procedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);
  99. begin
  100. R := ClampToWord(Round(Y + 1.40200 * (Cr - 32768)));
  101. G := ClampToWord(Round(Y - 0.34414 * (Cb - 32768) - 0.71414 * (Cr - 32768)));
  102. B := ClampToWord(Round(Y + 1.77200 * (Cb - 32768)));
  103. end;
  104. procedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);
  105. begin
  106. C := 255 - R;
  107. M := 255 - G;
  108. Y := 255 - B;
  109. end;
  110. procedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);
  111. begin
  112. R := 255 - C;
  113. G := 255 - M;
  114. B := 255 - Y;
  115. end;
  116. procedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);
  117. begin
  118. C := 65535 - R;
  119. M := 65535 - G;
  120. Y := 65535 - B;
  121. end;
  122. procedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);
  123. begin
  124. R := 65535 - C;
  125. G := 65535 - M;
  126. B := 65535 - Y;
  127. end;
  128. procedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);
  129. begin
  130. RGBToCMY(R, G, B, C, M, Y);
  131. K := Min(C, Min(M, Y));
  132. if K = 255 then
  133. begin
  134. C := 0;
  135. M := 0;
  136. Y := 0;
  137. end
  138. else
  139. begin
  140. C := ClampToByte(Round((C - K) / (255 - K) * 255));
  141. M := ClampToByte(Round((M - K) / (255 - K) * 255));
  142. Y := ClampToByte(Round((Y - K) / (255 - K) * 255));
  143. end;
  144. end;
  145. procedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);
  146. begin
  147. R := (255 - (C - MulDiv(C, K, 255) + K));
  148. G := (255 - (M - MulDiv(M, K, 255) + K));
  149. B := (255 - (Y - MulDiv(Y, K, 255) + K));
  150. end;
  151. procedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);
  152. begin
  153. RGBToCMY16(R, G, B, C, M, Y);
  154. K := Min(C, Min(M, Y));
  155. if K = 65535 then
  156. begin
  157. C := 0;
  158. M := 0;
  159. Y := 0;
  160. end
  161. else
  162. begin
  163. C := ClampToWord(Round((C - K) / (65535 - K) * 65535));
  164. M := ClampToWord(Round((M - K) / (65535 - K) * 65535));
  165. Y := ClampToWord(Round((Y - K) / (65535 - K) * 65535));
  166. end;
  167. end;
  168. procedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);
  169. begin
  170. R := 65535 - (C - MulDiv(C, K, 65535) + K);
  171. G := 65535 - (M - MulDiv(M, K, 65535) + K);
  172. B := 65535 - (Y - MulDiv(Y, K, 65535) + K);
  173. end;
  174. procedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);
  175. begin
  176. // C and Delphi's SHR behaviour differs for negative numbers, use div instead.
  177. Y := ClampToByte(( R + G shl 1 + B + 2) div 4);
  178. Co := ClampToByte(( R shl 1 - B shl 1 + 2) div 4 + 128);
  179. Cg := ClampToByte((-R + G shl 1 - B + 2) div 4 + 128);
  180. end;
  181. procedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);
  182. var
  183. CoInt, CgInt: Integer;
  184. begin
  185. CoInt := Co - 128;
  186. CgInt := Cg - 128;
  187. R := ClampToByte(Y + CoInt - CgInt);
  188. G := ClampToByte(Y + CgInt);
  189. B := ClampToByte(Y - CoInt - CgInt);
  190. end;
  191. {
  192. File Notes:
  193. -- TODOS ----------------------------------------------------
  194. - nothing now
  195. -- 0.26.3 Changes/Bug Fixes ---------------------------------
  196. - Added RGB<>YCoCg conversion functions.
  197. - Fixed RGB>>CMYK conversions.
  198. -- 0.23 Changes/Bug Fixes -----------------------------------
  199. - Added RGB<>CMY(K) converion functions for 16 bit channels
  200. (needed by PSD loading code).
  201. -- 0.21 Changes/Bug Fixes -----------------------------------
  202. - Added some color space conversion functions and LUTs
  203. (RGB/YUV/YCrCb/CMY/CMYK).
  204. -- 0.17 Changes/Bug Fixes -----------------------------------
  205. - unit created (empty!)
  206. }
  207. end.