Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
IccSparseMatrix.cpp
Go to the documentation of this file.
1#include "IccSparseMatrix.h"
2
3#include <cstring>
4
5CIccSparseMatrix::CIccSparseMatrix(void *pMatrix, icUInt32Number nSize, icSparseMatrixType nType, bool bInitFromData/*=false*/)
6{
7 m_pMatrix = (unsigned char*)pMatrix;
8 m_nRawSize = nSize;
9 m_nType = nType;
10 m_Data = NULL;
11
12 if (bInitFromData) {
13 icUInt16Number nRows = *((icUInt16Number*)pMatrix);
15 Init(nRows, nCols);
16 }
17 else {
18 m_nRows = 0;
19 m_nCols = 0;
20 m_nMaxEntries = 0;
21 m_RowStart = NULL;
22 m_ColumnIndices = NULL;
23 }
24}
25
27{
28 m_pMatrix = mtx.m_pMatrix;
30 m_nType = mtx.m_nType;
31
32 if (mtx.m_Data) {
33 switch (m_nType) {
36 break;
39 break;
42 break;
45 break;
48 default:
49 m_Data = NULL;
50 }
51 }
52
53 if (m_Data) {
54 Init(mtx.m_nRows, mtx.m_nCols);
55 }
56 else {
57 m_nRows = 0;
58 m_nCols = 0;
59 m_nMaxEntries = 0;
60 m_RowStart = NULL;
61 m_ColumnIndices = NULL;
62 }
63}
64
66{
67 if (m_Data)
68 delete m_Data;
69}
70
72{
73 m_pMatrix = mtx.m_pMatrix;
75 m_nType = mtx.m_nType;
76
77 if (mtx.m_Data) {
78 if (m_Data)
79 delete m_Data;
80
81 switch (m_nType) {
84 break;
87 break;
90 break;
93 break;
96 default:
97 m_Data = NULL;
98 }
99 }
100
101 if (m_Data) {
102 Init(mtx.m_nRows, mtx.m_nCols);
103 }
104 else {
105 m_nRows = 0;
106 m_nCols = 0;
107 m_nMaxEntries = 0;
108 }
109
110 return *this;
111}
112
113void CIccSparseMatrix::Reset(void *pMatrix, icUInt32Number nSize, icSparseMatrixType nType, bool bInitFromData/*=true*/)
114{
115 if (m_Data)
116 delete m_Data;
117
118 m_pMatrix = (unsigned char*)pMatrix;
119 m_nRawSize = nSize;
120 m_nType = nType;
121 m_Data = NULL;
122
123 if (bInitFromData) {
124 icUInt16Number nRows = *((icUInt16Number*)pMatrix);
126 Init(nRows, nCols);
127 }
128 else {
129 m_nRows = 0;
130 m_nCols = 0;
131 m_nMaxEntries = 0;
132 m_RowStart = NULL;
133 m_ColumnIndices = NULL;
134 }
135}
136
137
138bool CIccSparseMatrix::Init(icUInt16Number nRows, icUInt16Number nCols, bool bSetData/*=false*/)
139{
140 if (!m_pMatrix)
141 return false;
142
144
145 if (m_Data)
146 delete m_Data;
147
148 switch (m_nType) {
151 break;
154 break;
157 break;
160 break;
163 break;
164 default:
165 m_nRows = 0;
166 m_nCols = 0;
167 if (bSetData) {
168 Dim[0] = 0;
169 Dim[1] = 0;
170 }
171 m_Data = NULL;
172 m_RowStart = NULL;
173 m_ColumnIndices = NULL;
174 m_nMaxEntries = 0;
175 return false;
176 }
177 m_nRows = nRows;
178 m_nCols = nCols;
179 if (bSetData) {
180 Dim[0] = nRows;
181 Dim[1] = nCols;
182 }
183
184 icUInt32Number coloffset = 2*sizeof(icUInt16Number) + (nRows+1)*sizeof(icUInt32Number);
185 icUInt16Number nTypeSize = m_Data->size();
186
187 if (coloffset+(nTypeSize-1) >m_nRawSize) {
188 m_nRows = 0;
189 m_nCols = 0;
190 if (bSetData) {
191 Dim[0] = 0;
192 Dim[1] = 0;
193 }
194 m_Data = NULL;
195 m_RowStart = NULL;
196 m_ColumnIndices = NULL;
197 m_nMaxEntries = 0;
198 return false;
199 }
200
201 m_nMaxEntries = (m_nRawSize - coloffset - (nTypeSize-1)) / (nTypeSize+sizeof(icUInt16Number));
202
203 icUInt32Number dataoffset = ((icUInt32Number)((coloffset + m_nMaxEntries*sizeof(icUInt16Number) + nTypeSize-1) / nTypeSize)) * nTypeSize;
204
207
208 m_Data->init(m_pMatrix+dataoffset);
209
210 return true;
211}
212
214{
215 memset(m_pMatrix + 2*sizeof(icUInt16Number), 0, m_nRawSize-2*sizeof(icUInt16Number));
216}
217
219{
220 if (!mtx.m_Data || !mtx.m_pMatrix)
221 return false;
222
223 if (!Init(mtx.m_nRows, mtx.m_nCols))
224 return false;
225
226 memcpy(m_RowStart, mtx.m_RowStart, (m_nRows+1)*sizeof(icUInt32Number));
229
230 for (i=0; i<nEntries; i++) {
231 m_Data->set(i, mtx.m_Data->get(i));
232 }
233
234 return true;
235}
236
238{
239 if (!m_Data)
240 return false;
241
242 Clear();
243
244 int r, c;
245 icUInt32Number nEntry = 0;
246
247 for (r=0; r<(int)m_nRows; r++) {
248 m_RowStart[r] = (icUInt16Number)nEntry;
249 for (c=0; c<(int)m_nCols; c++) {
250 if (icNotZero(*pData)) {
251 if (nEntry+1 > m_nMaxEntries)
252 return false;
253 m_ColumnIndices[nEntry] = c;
254 m_Data->set(nEntry, *pData);
255 nEntry++;
256 }
257 pData++;
258 }
259 }
260 m_RowStart[r] = (icUInt16Number)nEntry;
261
262 return true;
263}
264
266{
267 if (!m_Data)
268 return false;
269
270 int r;
271 icUInt32Number e, le;
273
274 for (r=0, e=0; r<(int)m_nRows; r++) {
275 icFloatNumber v=0.0f;
276
277 le = m_RowStart[r+1];
278
279 for (; e<le; e++, ci++) {
280 v += m_Data->get(e)*pVector[*ci];
281 }
282 pResult[r]=v;
283 }
284 return true;
285}
286
287
289{
290 if (mtx1.m_nRows != mtx2.m_nRows || mtx1.m_nCols != mtx2.m_nCols)
291 return false;
292
293 if (mtx1.m_nRows != m_nRows || mtx2.m_nCols != m_nCols) {
294 if (!Init(mtx1.m_nRows, mtx2.m_nCols))
295 return false;
296 }
297
298 icUInt32Number pos=0;
299 int r=0, i, j;
300 int fA, fB, nA, nB, offA, offB, iA, iB;
301
302 for (r=0; r<(int)m_nRows; r++) {
303 fA = (int)mtx1.m_RowStart[r];
304 fB = (int)mtx2.m_RowStart[r];
305 nA = (int)(mtx1.m_RowStart[r+1] - fA);
306 nB = (int)(mtx2.m_RowStart[r+1] - fA);
307
308 m_RowStart[r] = (icUInt16Number)pos;
309
310 if (nA && nB) {
311 i=j=0;
312
313 while(i<nA || j<nB) {
314 if (pos >= m_nMaxEntries)
315 return false;
316
317 if (i<nA && j<nB) {
318 offA = fA+i;
319 offB = fB+j;
320 iA = mtx1.m_ColumnIndices[offA];
321 iB = mtx2.m_ColumnIndices[offB];
322
323 if (iA<iB) {
324 m_ColumnIndices[pos] = iA;
325 m_Data->set(pos, d1*mtx1.m_Data->get(offA));
326 i++;
327 }
328 else if (iB<iA) {
329 m_ColumnIndices[pos] = iB;
330 m_Data->set(pos, d2*mtx2.m_Data->get(offB));
331 j++;
332 }
333 else {
334 m_ColumnIndices[pos] = iA;
335 m_Data->set(pos, d1*mtx1.m_Data->get(offA) + d2*mtx2.m_Data->get(offB));
336 i++;
337 j++;
338 }
339 pos++;
340 }
341 else if (i<nA) {
342 offA = fA+i;
343 iA = mtx1.m_ColumnIndices[offA];
344
345 m_ColumnIndices[pos] = iA;
346 m_Data->set(pos, d1 * mtx1.m_Data->get(offA));
347 }
348 else {
349 offB = fB+j;
350 iB = mtx2.m_ColumnIndices[offB];
351
352 m_ColumnIndices[pos] = iB;
353 m_Data->set(pos, d2 * mtx2.m_Data->get(offB));
354 }
355 }
356 }
357 else if (nA) {
358 if (pos+nA >= m_nMaxEntries)
359 return false;
360
361 memcpy(&m_ColumnIndices[pos], &mtx1.m_ColumnIndices[fA], nA);
362
363 for (i=0; i<nA; i++) {
364 m_Data->set(pos++, d1 * mtx1.m_Data->get(fA+i));
365 }
366 }
367 else if (nB) {
368 if (pos+nB >= m_nMaxEntries)
369 return false;
370
371 memcpy(&m_ColumnIndices[pos], &mtx2.m_ColumnIndices[fB], nB);
372
373 for (i=0; i<nB; i++) {
374 m_Data->set(pos++, d2 * mtx2.m_Data->get(fB+i));
375 }
376 }
378 }
379
380 return true;
381}
382
383
385{
386 if (mtx1.m_nRows != mtx2.m_nRows || mtx1.m_nCols != mtx2.m_nCols)
387 return false;
388
389 if (mtx1.m_nRows != m_nRows || mtx2.m_nCols != m_nCols) {
390 if (!Init(mtx1.m_nRows, mtx2.m_nCols))
391 return false;
392 }
393
394 icUInt32Number pos=0;
395 int r=0, i, j;
396 int fA, fB, nA, nB, offA, offB, iA, iB;
397
398 for (r=0; r<(int)m_nRows; r++) {
399 fA = (int)mtx1.m_RowStart[r];
400 fB = (int)mtx2.m_RowStart[r];
401 nA = (int)(mtx1.m_RowStart[r+1] - fA);
402 nB = (int)(mtx2.m_RowStart[r+1] - fA);
403
404 m_RowStart[r] = (icUInt16Number)pos;
405
406 if (nA && nB) {
407 i=j=0;
408
409 while(i<nA || j<nB) {
410 if (pos >= m_nMaxEntries)
411 return false;
412
413 if (i<nA && j<nB) {
414 offA = fA+i;
415 offB = fB+j;
416 iA = mtx1.m_ColumnIndices[offA];
417 iB = mtx2.m_ColumnIndices[offB];
418
419 if (iA<iB) {
420 m_ColumnIndices[pos] = iA;
421 m_Data->set(pos, 1.0f);
422 i++;
423 }
424 else if (iB<iA) {
425 m_ColumnIndices[pos] = iB;
426 m_Data->set(pos, 1.0f);
427 j++;
428 }
429 else {
430 m_ColumnIndices[pos] = iA;
431 m_Data->set(pos, 1.0f);
432 i++;
433 j++;
434 }
435 pos++;
436 }
437 else if (i<nA) {
438 offA = fA+i;
439 iA = mtx1.m_ColumnIndices[offA];
440
441 m_ColumnIndices[pos] = iA;
442 m_Data->set(pos, 1.0f);
443 }
444 else {
445 offB = fB+j;
446 iB = mtx2.m_ColumnIndices[offB];
447
448 m_ColumnIndices[pos] = iB;
449 m_Data->set(pos, 1.0f);
450 }
451 }
452 }
453 else if (nA) {
454 if (pos+nA >= m_nMaxEntries)
455 return false;
456
457 memcpy(&m_ColumnIndices[pos], &mtx1.m_ColumnIndices[fA], nA);
458
459 for (i=0; i<nA; i++) {
460 m_Data->set(pos++, 1.0f);
461 }
462 }
463 else if (nB) {
464 if (pos+nB >= m_nMaxEntries)
465 return false;
466
467 memcpy(&m_ColumnIndices[pos], &mtx2.m_ColumnIndices[fB], nB);
468
469 for (i=0; i<nB; i++) {
470 m_Data->set(pos++, 1.0f);
471 }
472 }
474 }
475
476 return true;
477}
478
479
481{
482 if (!m_Data || !m_RowStart || !m_ColumnIndices)
483 return false;
484
485 int r, i;
486 for (r=0; r<(int)m_nRows; r++) {
487 if (m_RowStart[r]>m_RowStart[r+1])
488 return false;
489
490 for (i=m_RowStart[r]; i<(int)m_RowStart[r+1]-1; i++) {
492 return false;
493 }
495 return false;
496 }
497 return true;
498}
499
501{
502 return (nMemSize - 4 - 4*(nRows+1) - (nTypeSize-1)) / (nTypeSize+2);
503}
504
506{
507 icUInt32Number off = ((4 + 4*(nRows+1) + 2*nMaxEntries + (nTypeSize-1))/nTypeSize)*nTypeSize;
508 return off + nTypeSize*nMaxEntries;
509}
510
512{
513 switch(nType) {
515 return sizeof(icUInt8Number);
516
518 return sizeof(icUInt16Number);
519
521 return sizeof(icFloat16Number);
522
524 return sizeof(icFloat16Number);
525
527 return sizeof(icFloatNumber);
528
529 default:
530 break;
531 }
532
533 return 0;
534}
float icFloatNumber
All floating point operations/variables in IccProfLib use the icFloatNumber data type.
Definition IccDefs.h:100
File: IccSparseMatrix.h.
#define icNotZero(v)
Definition IccUtil.h:89
unsigned int icUInt32Number
bool FillFromFullMatrix(icFloatNumber *pData)
bool Union(const CIccSparseMatrix &mtx1, const CIccSparseMatrix &mtx2)
static icUInt32Number MaxEntries(icUInt32Number nMemSize, icUInt16Number nRows, icUInt8Number nTypeSize)
bool Interp(icFloatNumber d1, const CIccSparseMatrix &mtx1, icFloatNumber d2, const CIccSparseMatrix &mtx2)
icUInt16Number * m_ColumnIndices
IIccSparseMatrixEntry * m_Data
virtual ~CIccSparseMatrix(void)
icUInt8Number * m_pMatrix
bool MultiplyVector(icFloatNumber *pResult, const icFloatNumber *pVector) const
void Reset(void *pMatrix, icUInt32Number nSize, icSparseMatrixType nType, bool bInitFromData=true)
CIccSparseMatrix & operator=(const CIccSparseMatrix &mtx)
icUInt16Number m_nCols
bool Copy(const CIccSparseMatrix &mtx)
static icUInt32Number MemSize(icUInt32Number nMaxEntries, icUInt16Number nRows, icUInt8Number nTypeSize)
icSparseMatrixType m_nType
icUInt32Number m_nRawSize
CIccSparseMatrix(void *pMatrix=NULL, icUInt32Number nSize=0, icSparseMatrixType nType=((icSparseMatrixType) 0x0000), bool bInitFromData=false)
icUInt32Number m_nMaxEntries
icUInt16Number m_nRows
icUInt16Number * m_RowStart
static icUInt8Number EntrySize(icSparseMatrixType nType)
bool Init(icUInt16Number nRows, icUInt16Number nCols, bool bSetData=false)
virtual void set(int index, icFloatNumber value)=0
virtual icFloatNumber get(int index) const =0
virtual void init(void *pData)=0
virtual icUInt8Number size() const =0
unsigned char icUInt8Number
Number definitions.
icSparseMatrixType
@ icSparseMatrixUInt16
@ icSparseMatrixFloat32
@ icSparseMatrixFloat16
@ icSparseMatrixUInt8
unsigned short icUInt16Number
icUInt16Number icFloat16Number
IEEE float storage numbers.
#define icSparseMatrixFloatNum
Convenience Enum Definition - Not defined in ICC specification.