ImagingColors.pas 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. { Converts RGB color to YUV.}
  18. procedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);
  19. { Converts YIV to RGB color.}
  20. procedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);
  21. { Converts RGB color to YCbCr as used in JPEG.}
  22. procedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);
  23. { Converts YCbCr as used in JPEG to RGB color.}
  24. procedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);
  25. { Converts RGB color to YCbCr as used in JPEG.}
  26. procedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);
  27. { Converts YCbCr as used in JPEG to RGB color.}
  28. procedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);
  29. { Converts RGB color to CMY.}
  30. procedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);
  31. { Converts CMY to RGB color.}
  32. procedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);
  33. { Converts RGB color to CMY.}
  34. procedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);
  35. { Converts CMY to RGB color.}
  36. procedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);
  37. { Converts RGB color to CMYK.}
  38. procedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);
  39. { Converts CMYK to RGB color.}
  40. procedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);
  41. { Converts RGB color to CMYK.}
  42. procedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);
  43. { Converts CMYK to RGB color.}
  44. procedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);
  45. { Converts RGB color to YCoCg.}
  46. procedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);
  47. { Converts YCoCg to RGB color.}
  48. procedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);
  49. //procedure RGBToHSL(R, G, B: Byte; var H, S, L: Byte);
  50. //procedure HSLToRGB(H, S, L: Byte; var R, G, B: Byte);
  51. implementation
  52. procedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);
  53. begin
  54. Y := ClampToByte(Round( 0.257 * R + 0.504 * G + 0.098 * B) + 16);
  55. V := ClampToByte(Round( 0.439 * R - 0.368 * G - 0.071 * B) + 128);
  56. U := ClampToByte(Round(-0.148 * R - 0.291 * G + 0.439 * B) + 128);
  57. end;
  58. procedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);
  59. var
  60. CY, CU, CV: LongInt;
  61. begin
  62. CY := Y - 16;
  63. CU := U - 128;
  64. CV := V - 128;
  65. R := ClampToByte(Round(1.164 * CY - 0.002 * CU + 1.596 * CV));
  66. G := ClampToByte(Round(1.164 * CY - 0.391 * CU - 0.813 * CV));
  67. B := ClampToByte(Round(1.164 * CY + 2.018 * CU - 0.001 * CV));
  68. end;
  69. procedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);
  70. begin
  71. Y := ClampToByte(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));
  72. Cb := ClampToByte(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B + 128));
  73. Cr := ClampToByte(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B + 128));
  74. end;
  75. procedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);
  76. begin
  77. R := ClampToByte(Round(Y + 1.40200 * (Cr - 128)));
  78. G := ClampToByte(Round(Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)));
  79. B := ClampToByte(Round(Y + 1.77200 * (Cb - 128)));
  80. end;
  81. procedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);
  82. begin
  83. Y := ClampToWord(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));
  84. Cb := ClampToWord(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B + 32768));
  85. Cr := ClampToWord(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B + 32768));
  86. end;
  87. procedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);
  88. begin
  89. R := ClampToWord(Round(Y + 1.40200 * (Cr - 32768)));
  90. G := ClampToWord(Round(Y - 0.34414 * (Cb - 32768) - 0.71414 * (Cr - 32768)));
  91. B := ClampToWord(Round(Y + 1.77200 * (Cb - 32768)));
  92. end;
  93. procedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);
  94. begin
  95. C := 255 - R;
  96. M := 255 - G;
  97. Y := 255 - B;
  98. end;
  99. procedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);
  100. begin
  101. R := 255 - C;
  102. G := 255 - M;
  103. B := 255 - Y;
  104. end;
  105. procedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);
  106. begin
  107. C := 65535 - R;
  108. M := 65535 - G;
  109. Y := 65535 - B;
  110. end;
  111. procedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);
  112. begin
  113. R := 65535 - C;
  114. G := 65535 - M;
  115. B := 65535 - Y;
  116. end;
  117. procedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);
  118. begin
  119. RGBToCMY(R, G, B, C, M, Y);
  120. K := Min(C, Min(M, Y));
  121. if K = 255 then
  122. begin
  123. C := 0;
  124. M := 0;
  125. Y := 0;
  126. end
  127. else
  128. begin
  129. C := ClampToByte(Round((C - K) / (255 - K) * 255));
  130. M := ClampToByte(Round((M - K) / (255 - K) * 255));
  131. Y := ClampToByte(Round((Y - K) / (255 - K) * 255));
  132. end;
  133. end;
  134. procedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);
  135. begin
  136. R := (255 - (C - MulDiv(C, K, 255) + K));
  137. G := (255 - (M - MulDiv(M, K, 255) + K));
  138. B := (255 - (Y - MulDiv(Y, K, 255) + K));
  139. end;
  140. procedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);
  141. begin
  142. RGBToCMY16(R, G, B, C, M, Y);
  143. K := Min(C, Min(M, Y));
  144. if K = 65535 then
  145. begin
  146. C := 0;
  147. M := 0;
  148. Y := 0;
  149. end
  150. else
  151. begin
  152. C := ClampToWord(Round((C - K) / (65535 - K) * 65535));
  153. M := ClampToWord(Round((M - K) / (65535 - K) * 65535));
  154. Y := ClampToWord(Round((Y - K) / (65535 - K) * 65535));
  155. end;
  156. end;
  157. procedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);
  158. begin
  159. R := 65535 - (C - MulDiv(C, K, 65535) + K);
  160. G := 65535 - (M - MulDiv(M, K, 65535) + K);
  161. B := 65535 - (Y - MulDiv(Y, K, 65535) + K);
  162. end;
  163. procedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);
  164. begin
  165. // C and Delphi's SHR behaviour differs for negative numbers, use div instead.
  166. Y := ClampToByte(( R + G shl 1 + B + 2) div 4);
  167. Co := ClampToByte(( R shl 1 - B shl 1 + 2) div 4 + 128);
  168. Cg := ClampToByte((-R + G shl 1 - B + 2) div 4 + 128);
  169. end;
  170. procedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);
  171. var
  172. CoInt, CgInt: Integer;
  173. begin
  174. CoInt := Co - 128;
  175. CgInt := Cg - 128;
  176. R := ClampToByte(Y + CoInt - CgInt);
  177. G := ClampToByte(Y + CgInt);
  178. B := ClampToByte(Y - CoInt - CgInt);
  179. end;
  180. {
  181. File Notes:
  182. -- TODOS ----------------------------------------------------
  183. - nothing now
  184. -- 0.26.3 Changes/Bug Fixes ---------------------------------
  185. - Added RGB<>YCoCg conversion functions.
  186. - Fixed RGB>>CMYK conversions.
  187. -- 0.23 Changes/Bug Fixes -----------------------------------
  188. - Added RGB<>CMY(K) conversion functions for 16 bit channels
  189. (needed by PSD loading code).
  190. -- 0.21 Changes/Bug Fixes -----------------------------------
  191. - Added some color space conversion functions and LUTs
  192. (RGB/YUV/YCrCb/CMY/CMYK).
  193. -- 0.17 Changes/Bug Fixes -----------------------------------
  194. - unit created (empty!)
  195. }
  196. end.