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-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009 010package imagingbook.common.color.adapt; 011 012import imagingbook.common.color.cie.Illuminant; 013 014/** 015 * <p> 016 * This class represents a linear chromatic adaptation transform, mapping XYZ color coordinates from a source white 017 * (reference) point to a target white point. Both white points are passed to the constructor. The actual color mapping 018 * is done by method {@link #applyTo(float[])}. See the Section 14.6 of [1] for additional details and examples. 019 * </p> 020 * <p> 021 * [1] W. Burger, M.J. Burge, <em>Digital Image Processing – An Algorithmic Introduction</em>, 3rd ed, Springer 022 * (2022). 023 * </p> 024 * 025 * @author WB 026 * @version 2022/11/14 027 * @see BradfordAdaptation 028 */ 029public class XYZscalingAdaptation implements ChromaticAdaptation { 030 031 private final double[] W21; // vector with diagonal scale factors 032 033 /** 034 * Returns a {@link XYZscalingAdaptation} instance for the specified white point coordinates. 035 * 036 * @param W1 source white point (to map from) 037 * @param W2 target white point (to map to) 038 * @return a {@link XYZscalingAdaptation} instance 039 */ 040 public static XYZscalingAdaptation getInstance(double[] W1, double[] W2) { 041 return new XYZscalingAdaptation(W1, W2); 042 } 043 044 /** 045 * Returns a {@link XYZscalingAdaptation} instance for the specified illuminants (white points). 046 * 047 * @param illum1 source illuminant (white point to map from) 048 * @param illum2 target illuminant (white point to map to) 049 * @return a {@link XYZscalingAdaptation} instance 050 */ 051 public static XYZscalingAdaptation getInstance(Illuminant illum1, Illuminant illum2) { 052 return getInstance(illum1.getXYZ(), illum2.getXYZ()); 053 } 054 055 /** 056 * Constructor (non-public). 057 */ 058 private XYZscalingAdaptation(double[] XYZ1, double[] XYZ2) { 059 W21 = new double[3]; 060 for (int i = 0; i < 3; i++) { 061 W21[i] = XYZ2[i] / XYZ1[i]; 062 } 063 } 064 065 @Override 066 public float[] applyTo(float[] XYZ1) { 067 final float[] XYZ2 = new float[3]; 068 for (int i = 0; i < 3; i++) { 069 XYZ2[i] = (float) (XYZ1[i] * W21[i]); 070 } 071 return XYZ2; 072 } 073 074 @Override 075 public double[] applyTo(double[] XYZ1) { 076 final double[] XYZ2 = new double[3]; 077 for (int i = 0; i < 3; i++) { 078 XYZ2[i] = XYZ1[i] * W21[i]; 079 } 080 return XYZ2; 081 } 082 083}