ImagingColors.pas 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. {
  2. Vampyre Imaging Library
  3. by Marek Mauder
  4. https://github.com/galfar/imaginglib
  5. https://imaginglib.sourceforge.io
  6. - - - - -
  7. This Source Code Form is subject to the terms of the Mozilla Public
  8. License, v. 2.0. If a copy of the MPL was not distributed with this
  9. file, You can obtain one at https://mozilla.org/MPL/2.0.
  10. }
  11. { This unit contains functions for manipulating and converting color values.}
  12. unit ImagingColors;
  13. interface
  14. {$I ImagingOptions.inc}
  15. uses
  16. SysUtils, ImagingTypes, ImagingUtility;
  17. const
  18. { Color constants in ifA8R8G8B8 format.}
  19. pcClear = $00000000;
  20. pcBlack = $FF000000;
  21. pcWhite = $FFFFFFFF;
  22. pcMaroon = $FF800000;
  23. pcGreen = $FF008000;
  24. pcOlive = $FF808000;
  25. pcNavy = $FF000080;
  26. pcPurple = $FF800080;
  27. pcTeal = $FF008080;
  28. pcGray = $FF808080;
  29. pcSilver = $FFC0C0C0;
  30. pcRed = $FFFF0000;
  31. pcLime = $FF00FF00;
  32. pcYellow = $FFFFFF00;
  33. pcBlue = $FF0000FF;
  34. pcFuchsia = $FFFF00FF;
  35. pcAqua = $FF00FFFF;
  36. pcLtGray = $FFC0C0C0;
  37. pcDkGray = $FF808080;
  38. { Converts RGB color to YUV.}
  39. procedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);
  40. { Converts YIV to RGB color.}
  41. procedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);
  42. { Converts RGB color to YCbCr as used in JPEG.}
  43. procedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);
  44. { Converts YCbCr as used in JPEG to RGB color.}
  45. procedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);
  46. { Converts RGB color to YCbCr as used in JPEG.}
  47. procedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);
  48. { Converts YCbCr as used in JPEG to RGB color.}
  49. procedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);
  50. { Converts RGB color to CMY.}
  51. procedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);
  52. { Converts CMY to RGB color.}
  53. procedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);
  54. { Converts RGB color to CMY.}
  55. procedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);
  56. { Converts CMY to RGB color.}
  57. procedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);
  58. { Converts RGB color to CMYK.}
  59. procedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);
  60. { Converts CMYK to RGB color.}
  61. procedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);
  62. { Converts RGB color to CMYK.}
  63. procedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);
  64. { Converts CMYK to RGB color.}
  65. procedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);
  66. { Converts RGB color to YCoCg.}
  67. procedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);
  68. { Converts YCoCg to RGB color.}
  69. procedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);
  70. //procedure RGBToHSL(R, G, B: Byte; var H, S, L: Byte);
  71. //procedure HSLToRGB(H, S, L: Byte; var R, G, B: Byte);
  72. implementation
  73. procedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);
  74. begin
  75. Y := ClampToByte(Round( 0.257 * R + 0.504 * G + 0.098 * B) + 16);
  76. V := ClampToByte(Round( 0.439 * R - 0.368 * G - 0.071 * B) + 128);
  77. U := ClampToByte(Round(-0.148 * R - 0.291 * G + 0.439 * B) + 128);
  78. end;
  79. procedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);
  80. var
  81. CY, CU, CV: LongInt;
  82. begin
  83. CY := Y - 16;
  84. CU := U - 128;
  85. CV := V - 128;
  86. R := ClampToByte(Round(1.164 * CY - 0.002 * CU + 1.596 * CV));
  87. G := ClampToByte(Round(1.164 * CY - 0.391 * CU - 0.813 * CV));
  88. B := ClampToByte(Round(1.164 * CY + 2.018 * CU - 0.001 * CV));
  89. end;
  90. procedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);
  91. begin
  92. Y := ClampToByte(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));
  93. Cb := ClampToByte(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B + 128));
  94. Cr := ClampToByte(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B + 128));
  95. end;
  96. procedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);
  97. begin
  98. R := ClampToByte(Round(Y + 1.40200 * (Cr - 128)));
  99. G := ClampToByte(Round(Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)));
  100. B := ClampToByte(Round(Y + 1.77200 * (Cb - 128)));
  101. end;
  102. procedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);
  103. begin
  104. Y := ClampToWord(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));
  105. Cb := ClampToWord(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B + 32768));
  106. Cr := ClampToWord(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B + 32768));
  107. end;
  108. procedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);
  109. begin
  110. R := ClampToWord(Round(Y + 1.40200 * (Cr - 32768)));
  111. G := ClampToWord(Round(Y - 0.34414 * (Cb - 32768) - 0.71414 * (Cr - 32768)));
  112. B := ClampToWord(Round(Y + 1.77200 * (Cb - 32768)));
  113. end;
  114. procedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);
  115. begin
  116. C := 255 - R;
  117. M := 255 - G;
  118. Y := 255 - B;
  119. end;
  120. procedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);
  121. begin
  122. R := 255 - C;
  123. G := 255 - M;
  124. B := 255 - Y;
  125. end;
  126. procedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);
  127. begin
  128. C := 65535 - R;
  129. M := 65535 - G;
  130. Y := 65535 - B;
  131. end;
  132. procedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);
  133. begin
  134. R := 65535 - C;
  135. G := 65535 - M;
  136. B := 65535 - Y;
  137. end;
  138. procedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);
  139. begin
  140. RGBToCMY(R, G, B, C, M, Y);
  141. K := Min(C, Min(M, Y));
  142. if K = 255 then
  143. begin
  144. C := 0;
  145. M := 0;
  146. Y := 0;
  147. end
  148. else
  149. begin
  150. C := ClampToByte(Round((C - K) / (255 - K) * 255));
  151. M := ClampToByte(Round((M - K) / (255 - K) * 255));
  152. Y := ClampToByte(Round((Y - K) / (255 - K) * 255));
  153. end;
  154. end;
  155. procedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);
  156. begin
  157. R := (255 - (C - MulDiv(C, K, 255) + K));
  158. G := (255 - (M - MulDiv(M, K, 255) + K));
  159. B := (255 - (Y - MulDiv(Y, K, 255) + K));
  160. end;
  161. procedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);
  162. begin
  163. RGBToCMY16(R, G, B, C, M, Y);
  164. K := Min(C, Min(M, Y));
  165. if K = 65535 then
  166. begin
  167. C := 0;
  168. M := 0;
  169. Y := 0;
  170. end
  171. else
  172. begin
  173. C := ClampToWord(Round((C - K) / (65535 - K) * 65535));
  174. M := ClampToWord(Round((M - K) / (65535 - K) * 65535));
  175. Y := ClampToWord(Round((Y - K) / (65535 - K) * 65535));
  176. end;
  177. end;
  178. procedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);
  179. begin
  180. R := 65535 - (C - MulDiv(C, K, 65535) + K);
  181. G := 65535 - (M - MulDiv(M, K, 65535) + K);
  182. B := 65535 - (Y - MulDiv(Y, K, 65535) + K);
  183. end;
  184. procedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);
  185. begin
  186. // C and Delphi's SHR behaviour differs for negative numbers, use div instead.
  187. Y := ClampToByte(( R + G shl 1 + B + 2) div 4);
  188. Co := ClampToByte(( R shl 1 - B shl 1 + 2) div 4 + 128);
  189. Cg := ClampToByte((-R + G shl 1 - B + 2) div 4 + 128);
  190. end;
  191. procedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);
  192. var
  193. CoInt, CgInt: Integer;
  194. begin
  195. CoInt := Co - 128;
  196. CgInt := Cg - 128;
  197. R := ClampToByte(Y + CoInt - CgInt);
  198. G := ClampToByte(Y + CgInt);
  199. B := ClampToByte(Y - CoInt - CgInt);
  200. end;
  201. {
  202. File Notes:
  203. -- TODOS ----------------------------------------------------
  204. - nothing now
  205. -- 0.26.3 Changes/Bug Fixes ---------------------------------
  206. - Added RGB<>YCoCg conversion functions.
  207. - Fixed RGB>>CMYK conversions.
  208. -- 0.23 Changes/Bug Fixes -----------------------------------
  209. - Added RGB<>CMY(K) conversion functions for 16 bit channels
  210. (needed by PSD loading code).
  211. -- 0.21 Changes/Bug Fixes -----------------------------------
  212. - Added some color space conversion functions and LUTs
  213. (RGB/YUV/YCrCb/CMY/CMYK).
  214. -- 0.17 Changes/Bug Fixes -----------------------------------
  215. - unit created (empty!)
  216. }
  217. end.