Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccMatrixMath.cpp
Go to the documentation of this file.
1/** @file
2 File: IccMatrixMath.cpp
3
4 Contains: Implementation of matrix math operations
5
6 Version: V1
7
8 Copyright: See ICC Software License
9*/
10
11/*
12 * The ICC Software License, Version 0.2
13 *
14 *
15 * Copyright (c) 2003-2015 The International Color Consortium. All rights
16 * reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
29 *
30 * 3. In the absence of prior written permission, the names "ICC" and "The
31 * International Color Consortium" must not be used to imply that the
32 * ICC organization endorses or promotes products derived from this
33 * software.
34 *
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
40 * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the The International Color Consortium.
52 *
53 *
54 * Membership in the ICC is encouraged when this software is used for
55 * commercial purposes.
56 *
57 *
58 * For more information on The International Color Consortium, please
59 * see <http://www.color.org/>.
60 *
61 *
62 */
63
64//////////////////////////////////////////////////////////////////////
65// HISTORY:
66//
67// -Initial implementation by Max Derhak 5-15-2003
68// -Added support for Monochrome ICC profile apply by Rohit Patil 12-03-2008
69// -Integrated changes for PCS adjustment by George Pawle 12-09-2008
70//
71//////////////////////////////////////////////////////////////////////
72
73#ifdef WIN32
74#pragma warning( disable: 4786) //disable warning in <list.h>
75#endif
76
77#include "IccMatrixMath.h"
78#include "IccUtil.h"
79#include <cstring>
80#include <cstdio>
81
82#ifdef USEREFICCMAXNAMESPACE
83namespace refIccMAX {
84#endif
85
86/**
87**************************************************************************
88* Name: CIccMatrixMath::CIccMatrixMath
89*
90* Purpose:
91* Constructor
92**************************************************************************
93*/
94CIccMatrixMath::CIccMatrixMath(icUInt16Number nRows, icUInt16Number nCols, bool bInitIdentity/* =false */)
95{
96 int nTotal = nRows * nCols;
97 int nMin = nRows<nCols ? nRows : nCols;
98
99 m_nRows = nRows;
100 m_nCols = nCols;
101 m_vals = new icFloatNumber[nTotal];
102 if (bInitIdentity) {
103 memset(m_vals, 0, nTotal * sizeof(icFloatNumber));
104 int i;
105 for (i=0; i<nMin; i++) {
106 icFloatNumber *row = entry(nRows-1-i);
107 row[nCols-1-i] = 1.0;
108 }
109 }
110}
111
112
113/**
114**************************************************************************
115* Name: CIccMatrixMath::CIccMatrixMath
116*
117* Purpose:
118* Copy Constructor
119**************************************************************************
120*/
122{
123 int nTotal = matrix.m_nRows * matrix.m_nCols;
124 m_nRows = matrix.m_nRows;
125 m_nCols = matrix.m_nCols;
126 m_vals = new icFloatNumber[nTotal];
127 memcpy(m_vals, matrix.m_vals, nTotal*sizeof(icFloatNumber));
128}
129
130
131/**
132**************************************************************************
133* Name: CIccMatrixMath::~CIccMatrixMath
134*
135* Purpose:
136* Destructor
137**************************************************************************
138*/
140{
141 if (m_vals)
142 delete m_vals;
143}
144
145
146/**
147**************************************************************************
148* Name: CIccMatrixMath::VectorMult
149*
150* Purpose:
151* Multiplies pSrc vector passed by a matrix resulting in a pDst vector
152**************************************************************************
153*/
155{
156 int i, j;
157 const icFloatNumber *row = entry(0);
158 for (j=0; j<m_nRows; j++) {
159 pDst[j] = 0.0f;
160 for (i=0; i<m_nCols; i++) {
161 if (row[i]!=0.0)
162 pDst[j] += row[i] * pSrc[i];
163 }
164 row = &row[m_nCols];
165 }
166}
167
168
169/**
170**************************************************************************
171* Name: CIccMatrixMath::dump
172*
173* Purpose:
174* dumps the context of the step
175**************************************************************************
176*/
177void CIccMatrixMath::dumpMtx(std::string &str) const
178{
179 char buf[80];
180 int i, j;
181 const icFloatNumber *row = entry(0);
182 for (j=0; j<m_nRows; j++) {
183 for (i=0; i<m_nCols; i++) {
184 sprintf(buf, ICCMTXSTEPDUMPFMT, row[i]);
185 str += buf;
186 }
187 str += "\n";
188 row = &row[m_nCols];
189 }
190}
191
192
193/**
194**************************************************************************
195* Name: CIccMatrixMath::Mult
196*
197* Purpose:
198* Creates a new CIccMatrixMath that is the result of concatentating
199* another matrix with this matrix. (IE result = matrix * this).
200**************************************************************************
201*/
203{
204 icUInt16Number mCols = matrix->m_nCols;
205 icUInt16Number mRows = matrix->m_nRows;
206
207 if (m_nRows != mCols)
208 return NULL;
209
210 CIccMatrixMath *pNew = new CIccMatrixMath(mRows, m_nCols);
211
212 int i, j, k;
213 for (j=0; j<mRows; j++) {
214 const icFloatNumber *row = matrix->entry(j);
215 for (i=0; i<m_nCols; i++) {
216 icFloatNumber *to = pNew->entry(j, i);
217 const icFloatNumber *from = entry(0, i);
218
219 *to = 0.0f;
220 for (k=0; k<m_nRows; k++) {
221 *to += row[k] * (*from);
222 from += m_nCols;
223 }
224 }
225 }
226
227 return pNew;
228}
229
230/**
231**************************************************************************
232* Name: CIccMatrixMath::VectorScale
233*
234* Purpose:
235* Multiplies each row by values of vector passed in
236**************************************************************************
237*/
239{
240 int i, j;
241 for (j=0; j<m_nRows; j++) {
242 icFloatNumber *row = entry(j);
243 for (i=0; i<m_nCols; i++) {
244 row[i] *= vec[i];
245 }
246 }
247}
248
249/**
250**************************************************************************
251* Name: CIccMatrixMath::Scale
252*
253* Purpose:
254* Multiplies all values in matrix by a single scale factor
255**************************************************************************
256*/
258{
259 int i, j;
260 for (j=0; j<m_nRows; j++) {
261 icFloatNumber *row = entry(j);
262 for (i=0; i<m_nCols; i++) {
263 row[i] *= v;
264 }
265 }
266}
267
268/**
269**************************************************************************
270* Name: CIccMatrixMath::Invert
271*
272* Purpose:
273* Inverts the matrix
274**************************************************************************
275*/
277{
278 if (m_nRows==3 && m_nCols==3) {
279 icMatrixInvert3x3(m_vals);
280 return true;
281 }
282
283 return false;
284}
285
286
287
288/**
289**************************************************************************
290* Name: CIccMatrixMath::RowSum
291*
292* Purpose:
293* Creates a new CIccMatrixMath step that is the result of multiplying the
294* matrix of this object to the scale of another object.
295**************************************************************************
296*/
298{
299 icFloatNumber rv=0;
300 int i;
301 const icFloatNumber *row = entry(nRow);
302
303 for (i=0; i<m_nCols; i++) {
304 rv += row[i];
305 }
306
307 return rv;
308}
309
310
311
312/**
313**************************************************************************
314* Name: CIccMatrixMath::isIdentityMtx
315*
316* Purpose:
317* Determines if applying this step will result in negligible change in data
318**************************************************************************
319*/
321{
322 if (m_nCols!=m_nRows)
323 return false;
324
325 int i, j;
326 for (j=0; j<m_nRows; j++) {
327 for (i=0; i<m_nCols; i++) {
328 icFloatNumber v = *(entry(j, i));
329 if (i==j) {
330 if (v<1.0f-icNearRange || v>1.0f+icNearRange)
331 return false;
332 }
333 else {
334 if (v<-icNearRange ||v>icNearRange)
335 return false;
336 }
337 }
338 }
339
340 return true;
341}
342
343
344/**
345**************************************************************************
346* Name: CIccMatrixMath::SetRange
347*
348* Purpose:
349* Fills a matrix math object that can be used to convert
350* spectral vectors from one spectral range to another using linear interpolation.
351**************************************************************************
352*/
353bool CIccMatrixMath::SetRange(const icSpectralRange &srcRange, const icSpectralRange &dstRange)
354{
355 if (m_nRows != dstRange.steps || m_nCols != srcRange.steps)
356 return false;
357
359 icFloatNumber srcStart = icF16toF(srcRange.start);
360 icFloatNumber srcEnd = icF16toF(srcRange.end);
361 icFloatNumber dstStart = icF16toF(dstRange.start);
362 icFloatNumber dstEnd = icF16toF(dstRange.end);
363 icFloatNumber srcDiff = srcEnd - srcStart;
364 icFloatNumber dstDiff = dstEnd - dstStart;
365 icFloatNumber srcScale = (srcEnd - srcStart) / (srcRange.steps-1);
366 icFloatNumber dstScale = (dstEnd - dstStart ) / (dstRange.steps - 1);
367
368 icFloatNumber *data=entry(0);
369 memset(data, 0, dstRange.steps*srcRange.steps*sizeof(icFloatNumber));
370
371 for (d=0; d<dstRange.steps; d++) {
372 icFloatNumber *r = entry(d);
373 icFloatNumber w = dstStart + (icFloatNumber)d * dstScale;
374 if (w<srcStart) {
375 r[0] = 1.0;
376 }
377 else if (w>=srcEnd) {
378 r[srcRange.steps-1] = 1.0;
379 }
380 else {
381 icUInt16Number p = (icUInt16Number)((w - srcStart) / srcScale);
382 icFloatNumber p2 = (w - (srcStart + p * srcScale)) / srcScale;
383
384 if (p2<0.00001) {
385 r[p] = 1.0f;
386 }
387 else if (p2>0.99999) {
388 r[p+1] = 1.0f;
389 }
390 else {
391 r[p] = 1.0f - p2;
392 r[p+1] = p2;
393 }
394 }
395 }
396
397 return true;
398}
399
400/**
401 **************************************************************************
402 * Name: CIccMatrixMath::rangeMap
403 *
404 * Purpose:
405 * This helper function generates a matrix math object that can be used to convert
406 * spectral vectors from one spectral range to another using linear interpolation.
407 **************************************************************************
408 */
410{
411 if (srcRange.steps != dstRange.steps ||
412 srcRange.start != dstRange.start ||
413 srcRange.end != dstRange.end) {
414 CIccMatrixMath *mtx = new CIccMatrixMath(dstRange.steps, srcRange.steps);
415 mtx->SetRange(srcRange, dstRange);
416
417 return mtx;
418 }
419
420 return NULL;
421}
422
423#ifdef USEREFICCMAXNAMESPACE
424} //namespace refIccMAX
425#endif
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
File: IccCmm.h.
#define icNearRange
#define ICCMTXSTEPDUMPFMT
bool icMatrixInvert3x3(icFloatNumber *M)
Name: icMatrixInvert3x3.
Definition IccUtil.cpp:391
icFloatNumber icF16toF(icFloat16Number num)
Definition IccUtil.cpp:629
File: IccUtil.h.
Type: Class.
icFloatNumber * entry(icUInt16Number nRow, icUInt16Number nCol=0)
icFloatNumber RowSum(icUInt16Number nRow) const
Name: CIccMatrixMath::RowSum.
void VectorScale(const icFloatNumber *vec)
Name: CIccMatrixMath::VectorScale.
icFloatNumber * m_vals
virtual bool isIdentityMtx() const
Name: CIccMatrixMath::isIdentityMtx.
CIccMatrixMath(icUInt16Number nRows, icUInt16Number nCols, bool bInitIdentity=false)
Name: CIccMatrixMath::CIccMatrixMath.
icUInt16Number m_nCols
icUInt16Number m_nRows
CIccMatrixMath * Mult(const CIccMatrixMath *matrix) const
Name: CIccMatrixMath::Mult.
static CIccMatrixMath * rangeMap(const icSpectralRange &from, const icSpectralRange &to)
Name: CIccMatrixMath::rangeMap.
virtual void dumpMtx(std::string &str) const
Name: CIccMatrixMath::dump.
virtual ~CIccMatrixMath()
Name: CIccMatrixMath::~CIccMatrixMath.
virtual void VectorMult(icFloatNumber *pDst, const icFloatNumber *pSrc) const
Name: CIccMatrixMath::VectorMult.
void Scale(icFloatNumber v)
Name: CIccMatrixMath::Scale.
bool SetRange(const icSpectralRange &from, const icSpectralRange &to)
Name: CIccMatrixMath::SetRange.
bool Invert()
Name: CIccMatrixMath::Invert.
unsigned short icUInt16Number
spectral range
icUInt16Number steps
icFloat16Number start
icFloat16Number end