<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>ColorMatrix.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Mistral Examples Viewer</a> > <a href="../index.html" class="el_bundle">image-core</a> > <a href="index.source.html" class="el_package">it.tidalwave.image</a> > <span class="el_source">ColorMatrix.java</span></div><h1>ColorMatrix.java</h1><pre class="source lang-java linenums">/*
* *********************************************************************************************************************
*
* Mistral: open source imaging engine
* http://tidalwave.it/projects/mistral
*
* Copyright (C) 2003 - 2023 by Tidalwave s.a.s. (http://tidalwave.it)
*
* *********************************************************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* *********************************************************************************************************************
*
* git clone https://bitbucket.org/tidalwave/mistral-src
* git clone https://github.com/tidalwave-it/mistral-src
*
* *********************************************************************************************************************
*/
package it.tidalwave.image;
import java.text.DecimalFormat;
import lombok.extern.slf4j.Slf4j;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
*
**********************************************************************************************************************/
<span class="nc" id="L37">@Slf4j</span>
public class ColorMatrix
{
<span class="nc" id="L40"> private static final DecimalFormat FORMAT = new DecimalFormat("+0.0000;-0.0000");</span>
private static final long SHORT_MASK = 0xffff;
<span class="nc" id="L42"> public static final ColorMatrix XYZ_TO_RGB = new ColorMatrix(new double[]</span>
{
0.412453,
0.357580,
0.180423,
0.212671,
0.715160,
0.072169,
0.019334,
0.119193,
0.950227
});
private final double[] c;
/*******************************************************************************************************************
*
* @param coefficients
*
******************************************************************************************************************/
public ColorMatrix (final double[] coefficients)
<span class="nc" id="L62"> {</span>
<span class="nc" id="L63"> this.c = coefficients;</span>
<span class="nc" id="L64"> }</span>
/*******************************************************************************************************************
*
* FIXME: move to EditableImage
move to EditableImage
*
* @param data
* @param index
*
******************************************************************************************************************/
public final void process (final short[] data, final int index)
{
<span class="nc" id="L76"> final var d0 = compute(0, data, index);</span>
<span class="nc" id="L77"> final var d1 = compute(1, data, index);</span>
<span class="nc" id="L78"> final var d2 = compute(2, data, index);</span>
<span class="nc" id="L79"> data[index + 0] = d0;</span>
<span class="nc" id="L80"> data[index + 1] = d1;</span>
<span class="nc" id="L81"> data[index + 2] = d2;</span>
<span class="nc" id="L82"> }</span>
/*******************************************************************************************************************
*
* @param m
* @return
*
* 012
* 345
* 678
*
******************************************************************************************************************/
public final ColorMatrix product (final ColorMatrix m)
{
<span class="nc" id="L96"> final var r = new double[9];</span>
<span class="nc" id="L98"> r[2] = (c[0] * m.c[2]) + (c[1] * m.c[5]) + (c[2] * m.c[8]);</span>
<span class="nc" id="L99"> r[5] = (c[3] * m.c[2]) + (c[4] * m.c[5]) + (c[5] * m.c[8]);</span>
<span class="nc" id="L100"> r[8] = (c[6] * m.c[2]) + (c[7] * m.c[5]) + (c[8] * m.c[8]);</span>
<span class="nc" id="L102"> r[1] = (c[0] * m.c[1]) + (c[1] * m.c[4]) + (c[2] * m.c[7]);</span>
<span class="nc" id="L103"> r[4] = (c[3] * m.c[1]) + (c[4] * m.c[4]) + (c[5] * m.c[7]);</span>
<span class="nc" id="L104"> r[7] = (c[6] * m.c[1]) + (c[7] * m.c[4]) + (c[8] * m.c[7]);</span>
<span class="nc" id="L106"> r[0] = (c[0] * m.c[0]) + (c[1] * m.c[3]) + (c[2] * m.c[6]);</span>
<span class="nc" id="L107"> r[3] = (c[3] * m.c[0]) + (c[4] * m.c[3]) + (c[5] * m.c[6]);</span>
<span class="nc" id="L108"> r[6] = (c[6] * m.c[0]) + (c[7] * m.c[3]) + (c[8] * m.c[6]);</span>
<span class="nc" id="L110"> return new ColorMatrix(r);</span>
}
/*******************************************************************************************************************
*
*
*
******************************************************************************************************************/
public final void normalizeRows()
{
<span class="nc" id="L120"> var sum = c[0] + c[1] + c[2];</span>
<span class="nc" id="L121"> c[0] /= sum;</span>
<span class="nc" id="L122"> c[1] /= sum;</span>
<span class="nc" id="L123"> c[2] /= sum;</span>
<span class="nc" id="L124"> sum = c[3] + c[4] + c[5];</span>
<span class="nc" id="L125"> c[3] /= sum;</span>
<span class="nc" id="L126"> c[4] /= sum;</span>
<span class="nc" id="L127"> c[5] /= sum;</span>
<span class="nc" id="L128"> sum = c[6] + c[7] + c[8];</span>
<span class="nc" id="L129"> c[6] /= sum;</span>
<span class="nc" id="L130"> c[7] /= sum;</span>
<span class="nc" id="L131"> c[8] /= sum;</span>
<span class="nc" id="L132"> }</span>
/*******************************************************************************************************************
*
* @return
*
******************************************************************************************************************/
public final ColorMatrix inverse()
{
<span class="nc" id="L141"> final var cof0 = +((c[4] * c[8]) - (c[7] * c[5]));</span>
<span class="nc" id="L142"> final var cof1 = -((c[3] * c[8]) - (c[6] * c[5]));</span>
<span class="nc" id="L143"> final var cof2 = +((c[3] * c[7]) - (c[6] * c[4]));</span>
<span class="nc" id="L144"> final var cof3 = -((c[1] * c[8]) - (c[7] * c[2]));</span>
<span class="nc" id="L145"> final var cof4 = +((c[0] * c[8]) - (c[6] * c[2]));</span>
<span class="nc" id="L146"> final var cof5 = -((c[0] * c[7]) - (c[6] * c[1]));</span>
<span class="nc" id="L147"> final var cof6 = +((c[1] * c[5]) - (c[4] * c[2]));</span>
<span class="nc" id="L148"> final var cof7 = -((c[0] * c[5]) - (c[3] * c[2]));</span>
<span class="nc" id="L149"> final var cof8 = +((c[0] * c[4]) - (c[3] * c[1]));</span>
<span class="nc" id="L151"> final var det = (c[0] * cof0) + (c[1] * cof1) + (c[2] * cof2);</span>
<span class="nc" id="L153"> final var nc = new double[9];</span>
<span class="nc" id="L154"> nc[0] = cof0 / det;</span>
<span class="nc" id="L155"> nc[1] = cof3 / det;</span>
<span class="nc" id="L156"> nc[2] = cof6 / det;</span>
<span class="nc" id="L157"> nc[3] = cof1 / det;</span>
<span class="nc" id="L158"> nc[4] = cof4 / det;</span>
<span class="nc" id="L159"> nc[5] = cof7 / det;</span>
<span class="nc" id="L160"> nc[6] = cof2 / det;</span>
<span class="nc" id="L161"> nc[7] = cof5 / det;</span>
<span class="nc" id="L162"> nc[8] = cof8 / det;</span>
<span class="nc" id="L164"> final var result = new ColorMatrix(nc);</span>
<span class="nc" id="L166"> log.trace("inverse(" + this + ") = " + result);</span>
// logger.finest(">>>> det = " + det);
<span class="nc" id="L169"> return result;</span>
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public final String toString()
{
<span class="nc" id="L180"> final var buffer = new StringBuilder("[");</span>
<span class="nc bnc" id="L182" title="All 2 branches missed."> for (var i = 0; i < c.length; i++)</span>
{
<span class="nc bnc" id="L184" title="All 2 branches missed."> if (i > 0)</span>
{
<span class="nc" id="L186"> buffer.append(",");</span>
}
<span class="nc" id="L189"> buffer.append(FORMAT.format(c[i]));</span>
}
<span class="nc" id="L192"> buffer.append("]");</span>
<span class="nc" id="L194"> return buffer.toString();</span>
}
/*******************************************************************************************************************
*
* @param data
* @return
*
******************************************************************************************************************/
private short compute (final int channel, final short[] data, final int index)
{
<span class="nc" id="L205"> final var c0 = c[(channel * 3) + 0];</span>
<span class="nc" id="L206"> final var c1 = c[(channel * 3) + 1];</span>
<span class="nc" id="L207"> final var c2 = c[(channel * 3) + 2];</span>
<span class="nc" id="L209"> final var f = (c0 * (data[index + 0] & SHORT_MASK)) + (c1 * (data[index + 1] & SHORT_MASK))</span>
+ (c2 * (data[index + 2] & SHORT_MASK));
<span class="nc" id="L211"> final var x = (int)f;</span>
<span class="nc bnc" id="L213" title="All 2 branches missed."> if (x < 0)</span>
{
<span class="nc" id="L215"> return 0;</span>
}
<span class="nc bnc" id="L218" title="All 2 branches missed."> return (short)((x <= SHORT_MASK) ? x : SHORT_MASK);</span>
}
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.7.202105040129</span></div></body></html>