File: | IccProfLib/IccMatrixMath.cpp |
Warning: | line 363, column 17 Value stored to 'srcDiff' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 |
83 | namespace refIccMAX { |
84 | #endif |
85 | |
86 | /** |
87 | ************************************************************************** |
88 | * Name: CIccMatrixMath::CIccMatrixMath |
89 | * |
90 | * Purpose: |
91 | * Constructor |
92 | ************************************************************************** |
93 | */ |
94 | CIccMatrixMath::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 | */ |
121 | CIccMatrixMath::CIccMatrixMath(const CIccMatrixMath &matrix) |
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 | */ |
139 | CIccMatrixMath::~CIccMatrixMath() |
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 | */ |
154 | void CIccMatrixMath::VectorMult(icFloatNumber *pDst, const icFloatNumber *pSrc) const |
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 | */ |
177 | void 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" %.8f", 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 | */ |
202 | CIccMatrixMath *CIccMatrixMath::Mult(const CIccMatrixMath *matrix) const |
203 | { |
204 | icUInt16Number mCols = matrix->m_nCols; |
205 | icUInt16Number mRows = matrix->m_nRows; |
206 | |
207 | if (m_nRows != mCols) |
208 | return NULL__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 | */ |
238 | void CIccMatrixMath::VectorScale(const icFloatNumber *vec) |
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 | */ |
257 | void CIccMatrixMath::Scale(icFloatNumber v) |
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 | */ |
276 | bool CIccMatrixMath::Invert() |
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 | */ |
297 | icFloatNumber CIccMatrixMath::RowSum(icUInt16Number nRow) const |
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 | */ |
320 | bool CIccMatrixMath::isIdentityMtx() const |
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-icNearRange0.000001 || v>1.0f+icNearRange0.000001) |
331 | return false; |
332 | } |
333 | else { |
334 | if (v<-icNearRange0.000001 ||v>icNearRange0.000001) |
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 | */ |
353 | bool CIccMatrixMath::SetRange(const icSpectralRange &srcRange, const icSpectralRange &dstRange) |
354 | { |
355 | if (m_nRows != dstRange.steps || m_nCols != srcRange.steps) |
356 | return false; |
357 | |
358 | icUInt16Number d; |
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; |
Value stored to 'srcDiff' during its initialization is never read | |
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 | */ |
409 | CIccMatrixMath *CIccMatrixMath::rangeMap(const icSpectralRange &srcRange, const icSpectralRange &dstRange) |
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__null; |
421 | } |
422 | |
423 | #ifdef USEREFICCMAXNAMESPACE |
424 | } //namespace refIccMAX |
425 | #endif |