tif_color.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * Copyright (c) 1988-1997 Sam Leffler
  3. * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and
  6. * its documentation for any purpose is hereby granted without fee, provided
  7. * that (i) the above copyright notices and this permission notice appear in
  8. * all copies of the software and related documentation, and (ii) the names of
  9. * Sam Leffler and Silicon Graphics may not be used in any advertising or
  10. * publicity relating to the software without the specific, prior written
  11. * permission of Sam Leffler and Silicon Graphics.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  14. * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16. *
  17. * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  18. * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19. * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20. * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21. * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22. * OF THIS SOFTWARE.
  23. */
  24. /*
  25. * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
  26. * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
  27. * the permission of John Cupitt, the VIPS author.
  28. */
  29. /*
  30. * TIFF Library.
  31. *
  32. * Color space conversion routines.
  33. */
  34. #include "tiffiop.h"
  35. #include <math.h>
  36. /*
  37. * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
  38. */
  39. void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b,
  40. float *X, float *Y, float *Z)
  41. {
  42. TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z);
  43. }
  44. /*
  45. * For CIELab encoded in 16 bits, L is an unsigned integer range [0,65535].
  46. * The a* and b* components are signed integers range [-32768,32767]. The 16
  47. * bit chrominance values are encoded as 256 times the 1976 CIE a* and b*
  48. * values
  49. */
  50. void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a,
  51. int32_t b, float *X, float *Y, float *Z)
  52. {
  53. float L = (float)l * 100.0F / 65535.0F;
  54. float cby, tmp;
  55. if (L < 8.856F)
  56. {
  57. *Y = (L * cielab->Y0) / 903.292F;
  58. cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
  59. }
  60. else
  61. {
  62. cby = (L + 16.0F) / 116.0F;
  63. *Y = cielab->Y0 * cby * cby * cby;
  64. }
  65. tmp = (float)a / 256.0F / 500.0F + cby;
  66. if (tmp < 0.2069F)
  67. *X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
  68. else
  69. *X = cielab->X0 * tmp * tmp * tmp;
  70. tmp = cby - (float)b / 256.0F / 200.0F;
  71. if (tmp < 0.2069F)
  72. *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
  73. else
  74. *Z = cielab->Z0 * tmp * tmp * tmp;
  75. }
  76. #define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5)))
  77. /*
  78. * Convert color value from the XYZ space to RGB.
  79. */
  80. void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
  81. uint32_t *r, uint32_t *g, uint32_t *b)
  82. {
  83. int i;
  84. float Yr, Yg, Yb;
  85. float *matrix = &cielab->display.d_mat[0][0];
  86. /* Multiply through the matrix to get luminosity values. */
  87. Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
  88. Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
  89. Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
  90. /* Clip input */
  91. Yr = TIFFmax(Yr, cielab->display.d_Y0R);
  92. Yg = TIFFmax(Yg, cielab->display.d_Y0G);
  93. Yb = TIFFmax(Yb, cielab->display.d_Y0B);
  94. /* Avoid overflow in case of wrong input values */
  95. Yr = TIFFmin(Yr, cielab->display.d_YCR);
  96. Yg = TIFFmin(Yg, cielab->display.d_YCG);
  97. Yb = TIFFmin(Yb, cielab->display.d_YCB);
  98. /* Turn luminosity to colour value. */
  99. i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
  100. i = TIFFmin(cielab->range, i);
  101. *r = RINT(cielab->Yr2r[i]);
  102. i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
  103. i = TIFFmin(cielab->range, i);
  104. *g = RINT(cielab->Yg2g[i]);
  105. i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
  106. i = TIFFmin(cielab->range, i);
  107. *b = RINT(cielab->Yb2b[i]);
  108. /* Clip output. */
  109. *r = TIFFmin(*r, cielab->display.d_Vrwr);
  110. *g = TIFFmin(*g, cielab->display.d_Vrwg);
  111. *b = TIFFmin(*b, cielab->display.d_Vrwb);
  112. }
  113. #undef RINT
  114. /*
  115. * Allocate conversion state structures and make look_up tables for
  116. * the Yr,Yb,Yg <=> r,g,b conversions.
  117. */
  118. int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display,
  119. float *refWhite)
  120. {
  121. int i;
  122. double dfGamma;
  123. cielab->range = CIELABTORGB_TABLE_RANGE;
  124. _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
  125. /* Red */
  126. dfGamma = 1.0 / cielab->display.d_gammaR;
  127. cielab->rstep =
  128. (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
  129. for (i = 0; i <= cielab->range; i++)
  130. {
  131. cielab->Yr2r[i] = cielab->display.d_Vrwr *
  132. ((float)pow((double)i / cielab->range, dfGamma));
  133. }
  134. /* Green */
  135. dfGamma = 1.0 / cielab->display.d_gammaG;
  136. cielab->gstep =
  137. (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
  138. for (i = 0; i <= cielab->range; i++)
  139. {
  140. cielab->Yg2g[i] = cielab->display.d_Vrwg *
  141. ((float)pow((double)i / cielab->range, dfGamma));
  142. }
  143. /* Blue */
  144. dfGamma = 1.0 / cielab->display.d_gammaB;
  145. cielab->bstep =
  146. (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
  147. for (i = 0; i <= cielab->range; i++)
  148. {
  149. cielab->Yb2b[i] = cielab->display.d_Vrwb *
  150. ((float)pow((double)i / cielab->range, dfGamma));
  151. }
  152. /* Init reference white point */
  153. cielab->X0 = refWhite[0];
  154. cielab->Y0 = refWhite[1];
  155. cielab->Z0 = refWhite[2];
  156. return 0;
  157. }
  158. /*
  159. * Convert color value from the YCbCr space to RGB.
  160. * The colorspace conversion algorithm comes from the IJG v5a code;
  161. * see below for more information on how it works.
  162. */
  163. #define SHIFT 16
  164. #define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5))
  165. #define ONE_HALF ((int32_t)(1 << (SHIFT - 1)))
  166. #define Code2V(c, RB, RW, CR) \
  167. ((((c) - (int32_t)(RB)) * (float)(CR)) / \
  168. (float)(((RW) - (RB) != 0) ? ((RW) - (RB)) : 1))
  169. /* !((f)>=(min)) written that way to deal with NaN */
  170. #define CLAMP(f, min, max) \
  171. ((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f))
  172. #define HICLAMP(f, max) ((f) > (max) ? (max) : (f))
  173. void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr,
  174. uint32_t *r, uint32_t *g, uint32_t *b)
  175. {
  176. int32_t i;
  177. /* XXX: Only 8-bit YCbCr input supported for now */
  178. Y = HICLAMP(Y, 255);
  179. Cb = CLAMP(Cb, 0, 255);
  180. Cr = CLAMP(Cr, 0, 255);
  181. i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
  182. *r = CLAMP(i, 0, 255);
  183. i = ycbcr->Y_tab[Y] +
  184. (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
  185. *g = CLAMP(i, 0, 255);
  186. i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
  187. *b = CLAMP(i, 0, 255);
  188. }
  189. /* Clamp function for sanitization purposes. Normally clamping should not */
  190. /* occur for well behaved chroma and refBlackWhite coefficients */
  191. static float CLAMPw(float v, float vmin, float vmax)
  192. {
  193. if (v < vmin)
  194. {
  195. /* printf("%f clamped to %f\n", v, vmin); */
  196. return vmin;
  197. }
  198. if (v > vmax)
  199. {
  200. /* printf("%f clamped to %f\n", v, vmax); */
  201. return vmax;
  202. }
  203. return v;
  204. }
  205. /*
  206. * Initialize the YCbCr->RGB conversion tables. The conversion
  207. * is done according to the 6.0 spec:
  208. *
  209. * R = Y + Cr*(2 - 2*LumaRed)
  210. * B = Y + Cb*(2 - 2*LumaBlue)
  211. * G = Y
  212. * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
  213. * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
  214. *
  215. * To avoid floating point arithmetic the fractional constants that
  216. * come out of the equations are represented as fixed point values
  217. * in the range 0...2^16. We also eliminate multiplications by
  218. * pre-calculating possible values indexed by Cb and Cr (this code
  219. * assumes conversion is being done for 8-bit samples).
  220. */
  221. int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
  222. {
  223. TIFFRGBValue *clamptab;
  224. int i;
  225. #define LumaRed luma[0]
  226. #define LumaGreen luma[1]
  227. #define LumaBlue luma[2]
  228. clamptab =
  229. (TIFFRGBValue *)((uint8_t *)ycbcr +
  230. TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)));
  231. _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
  232. ycbcr->clamptab = (clamptab += 256);
  233. for (i = 0; i < 256; i++)
  234. clamptab[i] = (TIFFRGBValue)i;
  235. _TIFFmemset(clamptab + 256, 255, 2 * 256); /* v > 255 => 255 */
  236. ycbcr->Cr_r_tab = (int *)(clamptab + 3 * 256);
  237. ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
  238. ycbcr->Cr_g_tab = (int32_t *)(ycbcr->Cb_b_tab + 256);
  239. ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
  240. ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
  241. {
  242. float f1 = 2 - 2 * LumaRed;
  243. int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F));
  244. float f2 = LumaRed * f1 / LumaGreen;
  245. int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F));
  246. float f3 = 2 - 2 * LumaBlue;
  247. int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F));
  248. float f4 = LumaBlue * f3 / LumaGreen;
  249. int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F));
  250. int x;
  251. #undef LumaBlue
  252. #undef LumaGreen
  253. #undef LumaRed
  254. /*
  255. * i is the actual input pixel value in the range 0..255
  256. * Cb and Cr values are in the range -128..127 (actually
  257. * they are in a range defined by the ReferenceBlackWhite
  258. * tag) so there is some range shifting to do here when
  259. * constructing tables indexed by the raw pixel data.
  260. */
  261. for (i = 0, x = -128; i < 256; i++, x++)
  262. {
  263. int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F,
  264. refBlackWhite[5] - 128.0F, 127),
  265. -128.0F * 32, 128.0F * 32);
  266. int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F,
  267. refBlackWhite[3] - 128.0F, 127),
  268. -128.0F * 32, 128.0F * 32);
  269. ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT);
  270. ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT);
  271. ycbcr->Cr_g_tab[i] = D2 * Cr;
  272. ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF;
  273. ycbcr->Y_tab[i] = (int32_t)CLAMPw(
  274. Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255),
  275. -128.0F * 32, 128.0F * 32);
  276. }
  277. }
  278. return 0;
  279. }
  280. #undef HICLAMP
  281. #undef CLAMP
  282. #undef Code2V
  283. #undef SHIFT
  284. #undef ONE_HALF
  285. #undef FIX