001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit http://imagingbook.com for additional details. 008 *******************************************************************************/ 009 010package imagingbook.pub.color.image; 011 012/** 013 * This is a utility class with static methods for gamma correction 014 * used by LabColorSpace and LuvColorSpace color spaces. 015 * Implemented with double values for better accuracy. 016 * Should be modified to implement a a subclass of ColorSpace. 017 */ 018public abstract class sRgbUtil { 019 020 // specs according to official sRGB standard: 021 static final double s = 12.92; 022 static final double a0 = 0.0031308; 023 static final double b0 = s * a0; // 0.040449936 024 static final double d = 0.055; 025 static final double gamma = 2.4; 026 027 public static double gammaFwd(double lc) { // input: linear RGB component value in [0,1] 028 return (lc <= a0) ? 029 (lc * s) : 030 ((1 + d) * Math.pow(lc, 1 / gamma) - d); 031 } 032 033 public static double gammaInv(double nc) { // input: nonlinear sRGB component value in [0,1] 034 return (nc <= b0) ? 035 (nc / s) : 036 Math.pow((nc + d) / (1 + d), gamma); 037 } 038 039 public static float[] sRgbToRgb(float[] srgb) { // all components in [0,1] 040 float R = (float) sRgbUtil.gammaInv(srgb[0]); 041 float G = (float) sRgbUtil.gammaInv(srgb[1]); 042 float B = (float) sRgbUtil.gammaInv(srgb[2]); 043 return new float[] { R, G, B }; 044 } 045 046 public static float[] rgbToSrgb(float[] rgb) { // all components in [0,1] 047 float sR = (float) sRgbUtil.gammaFwd(rgb[0]); 048 float sG = (float) sRgbUtil.gammaFwd(rgb[1]); 049 float sB = (float) sRgbUtil.gammaFwd(rgb[2]); 050 return new float[] { sR, sG, sB }; 051 } 052 053 054 public static void main(String[] args) { 055 for (int i = 0; i < 20; i++) { 056 double lc = Math.random(); 057 double nc = gammaFwd(lc); 058 System.out.format("lc = %.8f, nc = %.8f, check = %.8f\n", lc, nc, lc-gammaInv(nc)); 059 } 060 System.out.println("" + (s * a0)); 061 062 } 063 064}