File: | IccProfLib/IccTagMPE.cpp |
Warning: | line 1628, column 13 Value stored to 'nInput' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /** @file |
2 | File: IccTagMpe.cpp |
3 | |
4 | Contains: Implementation of MultiProcessElementType Tag |
5 | |
6 | Version: V1 |
7 | |
8 | Copyright: (c) see ICC Software License |
9 | */ |
10 | |
11 | /* |
12 | * The ICC Software License, Version 0.2 |
13 | * |
14 | * |
15 | * Copyright (c) 2003-2012 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 1-30-2006 |
68 | // |
69 | ////////////////////////////////////////////////////////////////////// |
70 | |
71 | #ifdef WIN32 |
72 | #pragma warning( disable: 4786) //disable warning in <list.h> |
73 | #endif |
74 | |
75 | #include <stdio.h> |
76 | #include <math.h> |
77 | #include <string.h> |
78 | #include <stdlib.h> |
79 | #include "IccTagMPE.h" |
80 | #include "IccIO.h" |
81 | #include "IccMpeFactory.h" |
82 | #include <map> |
83 | #include "IccUtil.h" |
84 | |
85 | #ifdef USEREFICCMAXNAMESPACE |
86 | namespace refIccMAX { |
87 | #endif |
88 | |
89 | /** |
90 | ****************************************************************************** |
91 | * Name: CIccApplyMpe::CIccApplyMpe |
92 | * |
93 | * Purpose: |
94 | * |
95 | * Args: |
96 | * |
97 | * Return: |
98 | ******************************************************************************/ |
99 | CIccApplyMpe::CIccApplyMpe(CIccMultiProcessElement *pElem) |
100 | { |
101 | m_pElem = pElem; |
102 | } |
103 | |
104 | |
105 | /** |
106 | ****************************************************************************** |
107 | * Name: CIccApplyMpe::~CIccApplyMpe |
108 | * |
109 | * Purpose: |
110 | * |
111 | * Args: |
112 | * |
113 | * Return: |
114 | ******************************************************************************/ |
115 | CIccApplyMpe::~CIccApplyMpe() |
116 | { |
117 | } |
118 | |
119 | |
120 | /** |
121 | ****************************************************************************** |
122 | * Name: CIccMultiProcessElement::Create |
123 | * |
124 | * Purpose: |
125 | * |
126 | * Args: |
127 | * |
128 | * Return: |
129 | ******************************************************************************/ |
130 | CIccMultiProcessElement* CIccMultiProcessElement::Create(icElemTypeSignature sig) |
131 | { |
132 | return CIccMpeCreator::CreateElement(sig); |
133 | } |
134 | |
135 | /** |
136 | ****************************************************************************** |
137 | * Name: CIccMultiProcessElement::GetNewApply() |
138 | * |
139 | * Purpose: |
140 | * |
141 | * Args: |
142 | * |
143 | * Return: |
144 | ******************************************************************************/ |
145 | CIccApplyMpe* CIccMultiProcessElement::GetNewApply( CIccApplyTagMpe *pApplyTag ) |
146 | { |
147 | return new CIccApplyMpe(this); |
148 | } |
149 | |
150 | |
151 | /** |
152 | ****************************************************************************** |
153 | * Name: CIccMpeUnknown::CIccMpeUnknown |
154 | * |
155 | * Purpose: |
156 | * |
157 | * Args: |
158 | * |
159 | * Return: |
160 | ******************************************************************************/ |
161 | CIccMpeUnknown::CIccMpeUnknown() |
162 | { |
163 | m_sig = icSigUnknownElemType((icElemTypeSignature) 0x3f3f3f3f); |
164 | m_nReserved = 0; |
165 | m_nInputChannels = 0; |
166 | m_nOutputChannels = 0; |
167 | m_nSize = 0; |
168 | m_pData = 0; |
169 | } |
170 | |
171 | /** |
172 | ****************************************************************************** |
173 | * Name: CIccMpeUnknown::CIccMpeUnknown |
174 | * |
175 | * Purpose: |
176 | * |
177 | * Args: |
178 | * |
179 | * Return: |
180 | ******************************************************************************/ |
181 | CIccMpeUnknown::CIccMpeUnknown(const CIccMpeUnknown &elem) |
182 | { |
183 | m_sig = elem.m_sig; |
184 | m_nReserved = elem.m_nReserved; |
185 | m_nInputChannels = elem.m_nInputChannels; |
186 | m_nOutputChannels = elem.m_nOutputChannels; |
187 | m_nSize = elem.m_nSize; |
188 | if (m_nSize) { |
189 | m_pData = (icUInt8Number*)malloc(m_nSize); |
190 | memcpy(m_pData, elem.m_pData, m_nSize); |
191 | } |
192 | else |
193 | m_pData = NULL__null; |
194 | } |
195 | |
196 | /** |
197 | ****************************************************************************** |
198 | * Name: CIccMpeUnknown::operator= |
199 | * |
200 | * Purpose: |
201 | * |
202 | * Args: |
203 | * |
204 | * Return: |
205 | ******************************************************************************/ |
206 | CIccMpeUnknown &CIccMpeUnknown::operator=(const CIccMpeUnknown &elem) |
207 | { |
208 | if (m_pData) |
209 | free(m_pData); |
210 | |
211 | m_sig = elem.m_sig; |
212 | m_nReserved = elem.m_nReserved; |
213 | m_nInputChannels = elem.m_nInputChannels; |
214 | m_nOutputChannels = elem.m_nOutputChannels; |
215 | m_nSize = elem.m_nSize; |
216 | if (m_nSize) { |
217 | m_pData = (icUInt8Number*)malloc(m_nSize); |
218 | memcpy(m_pData, elem.m_pData, m_nSize); |
219 | } |
220 | else |
221 | m_pData = NULL__null; |
222 | |
223 | return (*this); |
224 | } |
225 | |
226 | /** |
227 | ****************************************************************************** |
228 | * Name: CIccMpeUnknown::~CIccMpeUnknown |
229 | * |
230 | * Purpose: |
231 | * |
232 | * Args: |
233 | * |
234 | * Return: |
235 | ******************************************************************************/ |
236 | CIccMpeUnknown::~CIccMpeUnknown() |
237 | { |
238 | if (m_pData) |
239 | free(m_pData); |
240 | } |
241 | |
242 | /** |
243 | ****************************************************************************** |
244 | * Name: CIccMpeUnknown::SetType |
245 | * |
246 | * Purpose: |
247 | * |
248 | * Args: |
249 | * |
250 | * Return: |
251 | ******************************************************************************/ |
252 | void CIccMpeUnknown::SetType(icElemTypeSignature sig) |
253 | { |
254 | m_sig = sig; |
255 | } |
256 | |
257 | /** |
258 | ****************************************************************************** |
259 | * Name: CIccMpeUnknown::Describe |
260 | * |
261 | * Purpose: |
262 | * |
263 | * Args: |
264 | * |
265 | * Return: |
266 | ******************************************************************************/ |
267 | void CIccMpeUnknown::SetChannels(icUInt16Number nInputChannels, icUInt16Number nOutputChannels) |
268 | { |
269 | m_nInputChannels = nInputChannels; |
270 | m_nOutputChannels = nOutputChannels; |
271 | } |
272 | |
273 | /** |
274 | ****************************************************************************** |
275 | * Name: CIccMpeUnknown::Describe |
276 | * |
277 | * Purpose: |
278 | * |
279 | * Args: |
280 | * |
281 | * Return: |
282 | ******************************************************************************/ |
283 | void CIccMpeUnknown::Describe(std::string &sDescription) |
284 | { |
285 | icChar buf[128], sigbuf[40]; |
286 | |
287 | sprintf(buf, "Unknown Element(%s) Type of %u Bytes.", |
288 | icGetSig(sigbuf, m_sig), m_nSize); |
289 | sDescription += buf; |
290 | |
291 | sDescription += "\r\n\r\nData Follows:\r\n"; |
292 | |
293 | icMemDump(sDescription, m_pData, m_nSize); |
294 | |
295 | } |
296 | |
297 | /** |
298 | ****************************************************************************** |
299 | * Name: CIccMpeUnknown::SetDataSize |
300 | * |
301 | * Purpose: |
302 | * |
303 | * Args: |
304 | * |
305 | * Return: |
306 | ******************************************************************************/ |
307 | bool CIccMpeUnknown::SetDataSize(icUInt32Number nSize, bool bZeroData/*=true*/) |
308 | { |
309 | bool rv = true; |
310 | if (m_pData) |
311 | free(m_pData); |
312 | |
313 | m_nSize = nSize; |
314 | if (m_nSize) { |
315 | m_pData = (icUInt8Number*)malloc(m_nSize); |
316 | if (!m_pData) { |
317 | rv = false; |
318 | m_nSize = 0; |
319 | } |
320 | } |
321 | else |
322 | m_pData = NULL__null; |
323 | |
324 | return rv; |
325 | } |
326 | |
327 | /** |
328 | ****************************************************************************** |
329 | * Name: CIccMpeUnknown::Read |
330 | * |
331 | * Purpose: |
332 | * |
333 | * Args: |
334 | * |
335 | * Return: |
336 | ******************************************************************************/ |
337 | bool CIccMpeUnknown::Read(icUInt32Number nSize, CIccIO *pIO) |
338 | { |
339 | icUInt32Number nHeaderSize = sizeof(icTagTypeSignature) + |
340 | sizeof(icUInt32Number) + |
341 | sizeof(icUInt16Number) + |
342 | sizeof(icUInt16Number); |
343 | |
344 | if (nHeaderSize > nSize) |
345 | return false; |
346 | |
347 | if (!pIO) { |
348 | return false; |
349 | } |
350 | |
351 | if (!pIO->Read32(&m_sig)) |
352 | return false; |
353 | |
354 | if (!pIO->Read32(&m_nReserved)) |
355 | return false; |
356 | |
357 | if (!pIO->Read16(&m_nInputChannels)) |
358 | return false; |
359 | |
360 | if (!pIO->Read16(&m_nOutputChannels)) |
361 | return false; |
362 | |
363 | icUInt32Number nDataSize = nSize - nHeaderSize; |
364 | |
365 | if (nDataSize) { |
366 | if (!SetDataSize(nDataSize, false)) |
367 | return false; |
368 | |
369 | if (pIO->Read8(m_pData, nDataSize)!=(icInt32Number)nDataSize) |
370 | return false; |
371 | } |
372 | |
373 | return true; |
374 | } |
375 | |
376 | /** |
377 | ****************************************************************************** |
378 | * Name: CIccMpeUnknown::Write |
379 | * |
380 | * Purpose: |
381 | * |
382 | * Args: |
383 | * |
384 | * Return: |
385 | ******************************************************************************/ |
386 | bool CIccMpeUnknown::Write(CIccIO *pIO) |
387 | { |
388 | if (!pIO) |
389 | return false; |
390 | |
391 | //icUInt32Number elemStart = pIO->Tell(); |
392 | |
393 | if (!pIO->Write32(&m_sig)) |
394 | return false; |
395 | |
396 | if (!pIO->Write32(&m_nReserved)) |
397 | return false; |
398 | |
399 | if (!pIO->Write16(&m_nInputChannels)) |
400 | return false; |
401 | |
402 | if (!pIO->Write16(&m_nOutputChannels)) |
403 | return false; |
404 | |
405 | if (m_nSize) { |
406 | if (pIO->Write8(m_pData, m_nSize)!=(icInt32Number)m_nSize) |
407 | return false; |
408 | } |
409 | |
410 | return true; |
411 | } |
412 | |
413 | /** |
414 | ****************************************************************************** |
415 | * Name: CIccMpeUnknown::Validate |
416 | * |
417 | * Purpose: |
418 | * |
419 | * Args: |
420 | * |
421 | * Return: |
422 | ******************************************************************************/ |
423 | icValidateStatus CIccMpeUnknown::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/) const |
424 | { |
425 | CIccInfo Info; |
426 | icChar buf[40]; |
427 | std::string sSigPathName = Info.GetSigPathName(sigPath); |
428 | |
429 | sReport += icMsgValidateCriticalError; |
430 | sReport += sSigPathName; |
431 | sReport += " - Contains unknown processing element type ("; |
432 | icGetSig(buf, m_sig, true); |
433 | sReport += buf; |
434 | sReport += ").\r\n"; |
435 | |
436 | return icValidateCriticalError; |
437 | } |
438 | |
439 | |
440 | /** |
441 | ****************************************************************************** |
442 | * Name: CIccProcessElement::Validate |
443 | * |
444 | * Purpose: |
445 | * |
446 | * Args: |
447 | * |
448 | * Return: |
449 | ******************************************************************************/ |
450 | icValidateStatus CIccMultiProcessElement::Validate(std::string sigPath, std::string &sReport, const CIccTagMultiProcessElement* pMPE/*=NULL*/) const |
451 | { |
452 | icValidateStatus rv = icValidateOK; |
453 | |
454 | CIccInfo Info; |
455 | std::string sSigPathName = Info.GetSigPathName(sigPath+icGetSigPath(GetType())); |
456 | if (m_nReserved!=0) { |
457 | sReport += icMsgValidateNonCompliant; |
458 | sReport += sSigPathName; |
459 | sReport += " - Reserved Value must be zero.\r\n"; |
460 | |
461 | rv = icValidateNonCompliant; |
462 | } |
463 | |
464 | return rv; |
465 | } |
466 | |
467 | |
468 | /** |
469 | ****************************************************************************** |
470 | * Name: CIccDblPixelBuffer::CIccDblPixelBuffer |
471 | * |
472 | * Purpose: |
473 | * |
474 | * Args: |
475 | * |
476 | * Return: |
477 | ******************************************************************************/ |
478 | CIccDblPixelBuffer::CIccDblPixelBuffer() |
479 | { |
480 | m_nMaxChannels = 0; |
481 | m_nLastNumChannels = 0; |
482 | m_pixelBuf1 = NULL__null; |
483 | m_pixelBuf2 = NULL__null; |
484 | } |
485 | |
486 | |
487 | /** |
488 | ****************************************************************************** |
489 | * Name: CIccDblPixelBuffer::CIccDblPixelBuffer |
490 | * |
491 | * Purpose: |
492 | * |
493 | * Args: |
494 | * |
495 | * Return: |
496 | ******************************************************************************/ |
497 | CIccDblPixelBuffer::CIccDblPixelBuffer(const CIccDblPixelBuffer &buf) |
498 | { |
499 | m_nMaxChannels = buf.m_nMaxChannels; |
500 | if (m_nMaxChannels) { |
501 | m_pixelBuf1 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber)); |
502 | if (m_pixelBuf1) |
503 | memcpy(m_pixelBuf1, buf.m_pixelBuf1, m_nMaxChannels*sizeof(icFloatNumber)); |
504 | |
505 | m_pixelBuf2 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber)); |
506 | if (m_pixelBuf2) |
507 | memcpy(m_pixelBuf2, buf.m_pixelBuf2, m_nMaxChannels*sizeof(icFloatNumber)); |
508 | } |
509 | else { |
510 | m_pixelBuf1 = NULL__null;; |
511 | m_pixelBuf2 = NULL__null; |
512 | } |
513 | } |
514 | |
515 | |
516 | /** |
517 | ****************************************************************************** |
518 | * Name: CIccDblPixelBuffer::CIccDblPixelBuffer |
519 | * |
520 | * Purpose: |
521 | * |
522 | * Args: |
523 | * |
524 | * Return: |
525 | ******************************************************************************/ |
526 | CIccDblPixelBuffer& CIccDblPixelBuffer::operator=(const CIccDblPixelBuffer &buf) |
527 | { |
528 | Clean(); |
529 | |
530 | m_nMaxChannels = buf.m_nMaxChannels; |
531 | if (m_nMaxChannels) { |
532 | m_pixelBuf1 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber)); |
533 | if (m_pixelBuf1) |
534 | memcpy(m_pixelBuf1, buf.m_pixelBuf1, m_nMaxChannels*sizeof(icFloatNumber)); |
535 | |
536 | m_pixelBuf2 = (icFloatNumber*)malloc(m_nMaxChannels*sizeof(icFloatNumber)); |
537 | if (m_pixelBuf2) |
538 | memcpy(m_pixelBuf2, buf.m_pixelBuf2, m_nMaxChannels*sizeof(icFloatNumber)); |
539 | } |
540 | else { |
541 | m_pixelBuf1 = NULL__null;; |
542 | m_pixelBuf2 = NULL__null; |
543 | } |
544 | |
545 | return *this; |
546 | } |
547 | |
548 | /** |
549 | ****************************************************************************** |
550 | * Name: CIccDblPixelBuffer::~CIccDblPixelBuffer |
551 | * |
552 | * Purpose: |
553 | * |
554 | * Args: |
555 | * |
556 | * Return: |
557 | ******************************************************************************/ |
558 | CIccDblPixelBuffer::~CIccDblPixelBuffer() |
559 | { |
560 | Clean(); |
561 | } |
562 | |
563 | |
564 | /** |
565 | ****************************************************************************** |
566 | * Name: CIccDblPixelBuffer::CIccDblPixelBuffer |
567 | * |
568 | * Purpose: |
569 | * |
570 | * Args: |
571 | * |
572 | * Return: |
573 | ******************************************************************************/ |
574 | void CIccDblPixelBuffer::Clean() |
575 | { |
576 | if (m_pixelBuf1) { |
577 | free(m_pixelBuf1); |
578 | m_pixelBuf1 = NULL__null; |
579 | } |
580 | if (m_pixelBuf2) { |
581 | free(m_pixelBuf2); |
582 | m_pixelBuf2 = NULL__null; |
583 | } |
584 | m_nMaxChannels = 0; |
585 | m_nLastNumChannels = 0; |
586 | } |
587 | |
588 | /** |
589 | ****************************************************************************** |
590 | * Name: CIccDblPixelBuffer::CIccDblPixelBuffer |
591 | * |
592 | * Purpose: |
593 | * |
594 | * Args: |
595 | * |
596 | * Return: |
597 | ******************************************************************************/ |
598 | bool CIccDblPixelBuffer::Begin() |
599 | { |
600 | m_pixelBuf1 = (icFloatNumber*)calloc(m_nMaxChannels, sizeof(icFloatNumber)); |
601 | m_pixelBuf2 = (icFloatNumber*)calloc(m_nMaxChannels, sizeof(icFloatNumber)); |
602 | |
603 | return (!m_nMaxChannels || (m_pixelBuf1!=NULL__null && m_pixelBuf2!=NULL__null)); |
604 | } |
605 | |
606 | |
607 | /** |
608 | ****************************************************************************** |
609 | * Name: CIccApplyTagMpe::CIccApplyTagMpe |
610 | * |
611 | * Purpose: |
612 | * |
613 | * Args: |
614 | * |
615 | * Return: |
616 | ******************************************************************************/ |
617 | CIccApplyTagMpe::CIccApplyTagMpe(CIccTagMultiProcessElement *pTag) |
618 | { |
619 | m_pTag = pTag; |
620 | m_list = NULL__null; |
621 | } |
622 | |
623 | |
624 | /** |
625 | ****************************************************************************** |
626 | * Name: CIccApplyTagMpe::~CIccApplyTagMpe |
627 | * |
628 | * Purpose: |
629 | * |
630 | * Args: |
631 | * |
632 | * Return: |
633 | ******************************************************************************/ |
634 | CIccApplyTagMpe::~CIccApplyTagMpe() |
635 | { |
636 | if (m_list) { |
637 | CIccApplyMpeList::iterator i; |
638 | |
639 | for (i=m_list->begin(); i!=m_list->end(); i++) { |
640 | delete i->ptr; |
641 | } |
642 | |
643 | delete m_list; |
644 | } |
645 | } |
646 | |
647 | |
648 | /** |
649 | ****************************************************************************** |
650 | * Name: CIccApplyTagMpe::CIccApplyTagMpe |
651 | * |
652 | * Purpose: |
653 | * |
654 | * Args: |
655 | * |
656 | * Return: |
657 | ******************************************************************************/ |
658 | bool CIccApplyTagMpe::AppendElem(CIccMultiProcessElement *pElem) |
659 | { |
660 | if (!m_list) |
661 | m_list = new CIccApplyMpeList(); |
662 | |
663 | if (!m_list) |
664 | return false; |
665 | |
666 | CIccApplyMpe *pApply = pElem->GetNewApply(this); |
667 | |
668 | if (!pApply) |
669 | return false; |
670 | |
671 | CIccApplyMpePtr ptr; |
672 | |
673 | ptr.ptr = pApply; |
674 | m_list->push_back(ptr); |
675 | |
676 | return true; |
677 | } |
678 | |
679 | |
680 | /** |
681 | ****************************************************************************** |
682 | * Name: CIccTagMultiProcessElement::CIccTagMultiProcessElement |
683 | * |
684 | * Purpose: |
685 | * |
686 | * Args: |
687 | * |
688 | * Return: |
689 | ******************************************************************************/ |
690 | CIccTagMultiProcessElement::CIccTagMultiProcessElement(icUInt16Number nInputChannels/* =0 */, icUInt16Number nOutputChannels/* =0 */) |
691 | { |
692 | m_nReserved = 0; |
693 | m_list = NULL__null; |
694 | m_nProcElements = 0; |
695 | m_position = NULL__null; |
696 | |
697 | m_nInputChannels = nInputChannels; |
698 | m_nOutputChannels = nOutputChannels; |
699 | |
700 | m_pAppliedPCC = NULL__null; |
701 | m_pProfilePCC = NULL__null; |
702 | |
703 | m_pCmmEnvVarLookup = NULL__null; |
704 | } |
705 | |
706 | /** |
707 | ****************************************************************************** |
708 | * Name: CIccTagMultiProcessElement::CIccTagMultiProcessElement |
709 | * |
710 | * Purpose: |
711 | * |
712 | * Args: |
713 | * |
714 | * Return: |
715 | ******************************************************************************/ |
716 | CIccTagMultiProcessElement::CIccTagMultiProcessElement(const CIccTagMultiProcessElement &lut) |
717 | { |
718 | m_position = NULL__null; |
719 | m_list = NULL__null; |
720 | |
721 | m_nReserved = lut.m_nReserved; |
722 | |
723 | if (lut.m_list) { |
724 | m_list = new CIccMultiProcessElementList(); |
725 | |
726 | CIccMultiProcessElementList::iterator i; |
727 | CIccMultiProcessElementPtr ptr; |
728 | |
729 | for (i=lut.m_list->begin(); i!= lut.m_list->end(); i++) { |
730 | ptr.ptr = (CIccMultiProcessElement*)i->ptr->NewCopy(); |
731 | m_list->push_back(ptr); |
732 | } |
733 | } |
734 | m_nInputChannels = lut.m_nInputChannels; |
735 | m_nOutputChannels = lut.m_nOutputChannels; |
736 | |
737 | if (lut.m_nProcElements && lut.m_position) { |
738 | m_position = (icPositionNumber*)malloc(lut.m_nProcElements*sizeof(icPositionNumber)); |
739 | if (m_position) { |
740 | memcpy(m_position, lut.m_position, lut.m_nProcElements*sizeof(icPositionNumber)); |
741 | } |
742 | m_nProcElements = lut.m_nProcElements; |
743 | } |
744 | |
745 | m_pAppliedPCC = lut.m_pAppliedPCC; |
746 | m_pProfilePCC = lut.m_pProfilePCC; |
747 | |
748 | m_pCmmEnvVarLookup = lut.m_pCmmEnvVarLookup; |
749 | } |
750 | |
751 | /** |
752 | ****************************************************************************** |
753 | * Name: &operator= |
754 | * |
755 | * Purpose: |
756 | * |
757 | * Args: |
758 | * |
759 | * Return: |
760 | ******************************************************************************/ |
761 | CIccTagMultiProcessElement &CIccTagMultiProcessElement::operator=(const CIccTagMultiProcessElement &lut) |
762 | { |
763 | Clean(); |
764 | |
765 | m_nReserved = lut.m_nReserved; |
766 | |
767 | if (lut.m_list) { |
768 | m_list = new CIccMultiProcessElementList(); |
769 | |
770 | CIccMultiProcessElementList::iterator i; |
771 | CIccMultiProcessElementPtr ptr; |
772 | |
773 | for (i=lut.m_list->begin(); i!= lut.m_list->end(); i++) { |
774 | ptr.ptr = (CIccMultiProcessElement*)i->ptr->NewCopy(); |
775 | m_list->push_back(ptr); |
776 | } |
777 | } |
778 | m_nInputChannels = lut.m_nInputChannels; |
779 | m_nOutputChannels = lut.m_nOutputChannels; |
780 | |
781 | if (lut.m_nProcElements && lut.m_position) { |
782 | m_position = (icPositionNumber*)malloc(lut.m_nProcElements*sizeof(icPositionNumber)); |
783 | if (m_position) { |
784 | memcpy(m_position, lut.m_position, lut.m_nProcElements*sizeof(icPositionNumber)); |
785 | } |
786 | m_nProcElements = lut.m_nProcElements; |
787 | } |
788 | |
789 | m_pAppliedPCC = lut.m_pAppliedPCC; |
790 | m_pProfilePCC = lut.m_pProfilePCC; |
791 | |
792 | m_pCmmEnvVarLookup = lut.m_pCmmEnvVarLookup; |
793 | |
794 | return *this; |
795 | } |
796 | |
797 | /** |
798 | ****************************************************************************** |
799 | * Name: CIccTagMultiProcessElement::~CIccTagMultiProcessElement |
800 | * |
801 | * Purpose: |
802 | * |
803 | * Args: |
804 | * |
805 | * Return: |
806 | ******************************************************************************/ |
807 | CIccTagMultiProcessElement::~CIccTagMultiProcessElement() |
808 | { |
809 | Clean(); |
810 | } |
811 | |
812 | typedef std::map<CIccMultiProcessElement*, icPositionNumber> CIccLutPtrMap; |
813 | typedef std::map<icUInt32Number, CIccMultiProcessElement*> CIccLutOffsetMap; |
814 | /** |
815 | ****************************************************************************** |
816 | * Name: CIccTagMultiProcessElement::Clean |
817 | * |
818 | * Purpose: |
819 | * |
820 | * Args: |
821 | * |
822 | * Return: |
823 | ******************************************************************************/ |
824 | void CIccTagMultiProcessElement::Clean() |
825 | { |
826 | if (m_list) { |
827 | CIccLutPtrMap map; |
828 | CIccMultiProcessElementList::iterator i; |
829 | |
830 | for (i=m_list->begin(); i!=m_list->end(); i++) { |
831 | if (!map[i->ptr].offset) { |
832 | map[i->ptr].offset = 1; |
833 | delete i->ptr; |
834 | } |
835 | } |
836 | |
837 | delete m_list; |
838 | m_list = NULL__null; |
839 | } |
840 | |
841 | if (m_position) { |
842 | free(m_position); |
843 | m_position = NULL__null; |
844 | } |
845 | |
846 | m_nProcElements = 0; |
847 | } |
848 | |
849 | /** |
850 | ****************************************************************************** |
851 | * Name: CIccTagMultiProcessElement::IsSupported |
852 | * |
853 | * Purpose: |
854 | * |
855 | * Args: |
856 | * |
857 | * Return: |
858 | ******************************************************************************/ |
859 | bool CIccTagMultiProcessElement::IsSupported() |
860 | { |
861 | if (m_list) { |
862 | CIccMultiProcessElementList::iterator i; |
863 | |
864 | for (i=m_list->begin(); i!=m_list->end(); i++) { |
865 | if (!i->ptr->IsSupported()) |
866 | return false; |
867 | } |
868 | } |
869 | |
870 | return true; |
871 | } |
872 | |
873 | |
874 | |
875 | /** |
876 | ****************************************************************************** |
877 | * Name: CIccTagMultiProcessElement::Describe |
878 | * |
879 | * Purpose: |
880 | * |
881 | * Args: |
882 | * |
883 | * Return: |
884 | ******************************************************************************/ |
885 | void CIccTagMultiProcessElement::Describe(std::string &sDescription) |
886 | { |
887 | icChar buf[128]; |
888 | |
889 | sprintf(buf, "BEGIN MULTI_PROCESS_ELEMENT_TAG %d %d\r\n", m_nInputChannels, m_nOutputChannels); |
890 | sDescription += buf; |
891 | sDescription += "\r\n"; |
892 | |
893 | CIccMultiProcessElementList::iterator i; |
894 | int j; |
895 | |
896 | for (j=0, i=m_list->begin(); i!=m_list->end(); j++, i++) { |
897 | sprintf(buf, "PROCESS_ELEMENT #%d\r\n", j+1); |
898 | sDescription += buf; |
899 | i->ptr->Describe(sDescription); |
900 | sDescription += "\r\n"; |
901 | } |
902 | sDescription += "END MULTI_PROCESS_ELEMENT_TAG\r\n"; |
903 | } |
904 | |
905 | /** |
906 | ****************************************************************************** |
907 | * Name: CIccTagMultiProcessElement::Attach |
908 | * |
909 | * Purpose: |
910 | * |
911 | * Args: |
912 | * |
913 | * Return: |
914 | ******************************************************************************/ |
915 | void CIccTagMultiProcessElement::Attach(CIccMultiProcessElement *pElement) |
916 | { |
917 | if (!m_list) { |
918 | m_list = new CIccMultiProcessElementList(); |
919 | } |
920 | |
921 | CIccMultiProcessElementPtr ptr; |
922 | |
923 | ptr.ptr = pElement; |
924 | |
925 | m_list->push_back(ptr); |
926 | } |
927 | |
928 | /** |
929 | ****************************************************************************** |
930 | * Name: CIccTagMultiProcessElement::Insert |
931 | * |
932 | * Purpose: |
933 | * |
934 | * Args: |
935 | * |
936 | * Return: |
937 | ******************************************************************************/ |
938 | void CIccTagMultiProcessElement::Insert(CIccMultiProcessElement *pElement) |
939 | { |
940 | if (!m_list) { |
941 | m_list = new CIccMultiProcessElementList(); |
942 | } |
943 | |
944 | CIccMultiProcessElementPtr ptr; |
945 | |
946 | ptr.ptr = pElement; |
947 | |
948 | m_list->push_front(ptr); |
949 | } |
950 | |
951 | |
952 | /** |
953 | ****************************************************************************** |
954 | * Name: CIccTagMultiProcessElement::Read |
955 | * |
956 | * Purpose: |
957 | * |
958 | * Args: |
959 | * |
960 | * Return: |
961 | ******************************************************************************/ |
962 | bool CIccTagMultiProcessElement::Read(icUInt32Number size, CIccIO *pIO) |
963 | { |
964 | icTagTypeSignature sig; |
965 | |
966 | icUInt32Number headerSize = sizeof(icTagTypeSignature) + |
967 | sizeof(icUInt32Number) + |
968 | sizeof(icUInt8Number) + |
969 | sizeof(icUInt8Number) + |
970 | sizeof(icUInt16Number); |
971 | |
972 | if (headerSize > size) |
973 | return false; |
974 | |
975 | if (!pIO) { |
976 | return false; |
977 | } |
978 | |
979 | Clean(); |
980 | |
981 | icUInt32Number tagStart = pIO->Tell(); |
982 | |
983 | if (!pIO->Read32(&sig)) |
984 | return false; |
985 | |
986 | if (!pIO->Read32(&m_nReserved)) |
987 | return false; |
988 | |
989 | if (!pIO->Read16(&m_nInputChannels)) |
990 | return false; |
991 | |
992 | if (!pIO->Read16(&m_nOutputChannels)) |
993 | return false; |
994 | |
995 | if (!pIO->Read32(&m_nProcElements)) |
996 | return false; |
997 | |
998 | if (headerSize + (icUInt64Number)m_nProcElements*sizeof(icUInt32Number) > size) |
999 | return false; |
1000 | |
1001 | m_list = new CIccMultiProcessElementList(); |
1002 | |
1003 | if (!m_list) |
1004 | return false; |
1005 | |
1006 | icUInt32Number i; |
1007 | |
1008 | m_position = (icPositionNumber*)calloc(m_nProcElements, sizeof(icPositionNumber)); |
1009 | |
1010 | if (!m_position) |
1011 | return false; |
1012 | |
1013 | CIccLutOffsetMap loadedElements; |
1014 | |
1015 | for (i=0; i<m_nProcElements; i++) { |
1016 | if (!pIO->Read32(&m_position[i].offset)) |
1017 | return false; |
1018 | if (!pIO->Read32(&m_position[i].size)) |
1019 | return false; |
1020 | } |
1021 | |
1022 | CIccMultiProcessElementPtr ptr; |
1023 | icElemTypeSignature sigElem; |
1024 | |
1025 | for (i=0; i<m_nProcElements; i++) { |
1026 | if (m_position[i].offset+m_position[i].size > size) { |
1027 | return false; |
1028 | } |
1029 | |
1030 | //Use hash to cache offset duplication |
1031 | CIccMultiProcessElement *element = loadedElements[m_position[i].offset]; |
1032 | if (!element) { |
1033 | icUInt32Number pos = tagStart + m_position[i].offset; |
1034 | |
1035 | if (pIO->Seek(pos, icSeekSet)!=(icInt32Number)pos) { |
1036 | return false; |
1037 | } |
1038 | |
1039 | if (!pIO->Read32(&sigElem)) { |
1040 | return false; |
1041 | } |
1042 | |
1043 | if (pIO->Seek(pos, icSeekSet)!=(icInt32Number)pos) { |
1044 | return false; |
1045 | } |
1046 | |
1047 | element = CIccMultiProcessElement::Create(sigElem); |
1048 | if (!element) { |
1049 | return false; |
1050 | } |
1051 | |
1052 | if (!element->Read(m_position[i].size, pIO)) { |
1053 | delete element; |
1054 | return false; |
1055 | } |
1056 | |
1057 | loadedElements[m_position[i].offset] = element; |
1058 | } |
1059 | ptr.ptr = element; |
1060 | |
1061 | m_list->push_back(ptr); |
1062 | } |
1063 | |
1064 | return true; |
1065 | } |
1066 | |
1067 | /** |
1068 | ****************************************************************************** |
1069 | * Name: CIccTagMultiProcessElement::Write |
1070 | * |
1071 | * Purpose: |
1072 | * |
1073 | * Args: |
1074 | * |
1075 | * Return: |
1076 | ******************************************************************************/ |
1077 | bool CIccTagMultiProcessElement::Write(CIccIO *pIO) |
1078 | { |
1079 | icTagTypeSignature sig = GetType(); |
1080 | |
1081 | if (!pIO) |
1082 | return false; |
1083 | |
1084 | icUInt32Number tagStart = pIO->Tell(); |
1085 | |
1086 | if (!pIO->Write32(&sig)) |
1087 | return false; |
1088 | |
1089 | if (!pIO->Write32(&m_nReserved)) |
1090 | return false; |
1091 | |
1092 | if (!pIO->Write16(&m_nInputChannels)) |
1093 | return false; |
1094 | |
1095 | if (!pIO->Write16(&m_nOutputChannels)) |
1096 | return false; |
1097 | |
1098 | if (m_list) { |
1099 | m_nProcElements = (icUInt32Number)m_list->size(); |
1100 | } |
1101 | else { |
1102 | m_nProcElements = 0; |
1103 | } |
1104 | |
1105 | if (!pIO->Write32(&m_nProcElements)) |
1106 | return false; |
1107 | |
1108 | if (m_nProcElements) { |
1109 | icUInt32Number offsetPos = pIO->Tell(); |
1110 | |
1111 | if (m_position) { |
1112 | delete [] m_position; |
1113 | } |
1114 | |
1115 | m_position = (icPositionNumber*)calloc(m_nProcElements, sizeof(icPositionNumber)); |
1116 | |
1117 | if (!m_position) |
1118 | return false; |
1119 | |
1120 | //Write an empty position table |
1121 | icUInt32Number j, zeros[2] = { 0, 0 }; |
1122 | for (j=0; j<m_nProcElements; j++) { |
1123 | if (pIO->Write32(zeros, 2)!=2) |
1124 | return false; |
1125 | } |
1126 | |
1127 | CIccLutPtrMap map; |
1128 | CIccMultiProcessElementList::iterator i; |
1129 | icUInt32Number start, end; |
1130 | icPositionNumber position; |
1131 | |
1132 | //Write out each process element |
1133 | for (j=0, i=m_list->begin(); i!=m_list->end(); i++, j++) { |
1134 | if (map.find(i->ptr)==map.end()) { |
1135 | start = pIO->Tell(); |
1136 | |
1137 | if (!i->ptr->Write(pIO)) |
1138 | return false; |
1139 | |
1140 | end = pIO->Tell(); |
1141 | |
1142 | if (!pIO->Align32()) |
1143 | return false; |
1144 | |
1145 | position.offset = start - tagStart; |
1146 | position.size = end - start; |
1147 | |
1148 | map[i->ptr] = position; |
1149 | } |
1150 | m_position[j] = map[i->ptr]; |
1151 | } |
1152 | |
1153 | icUInt32Number endPos = pIO->Tell(); |
1154 | |
1155 | if (pIO->Seek(offsetPos, icSeekSet)<0) |
1156 | return false; |
1157 | |
1158 | for (j=0; j<m_nProcElements; j++) { |
1159 | if (!pIO->Write32(&m_position[j].offset)) |
1160 | return false; |
1161 | if (!pIO->Write32(&m_position[j].size)) |
1162 | return false; |
1163 | } |
1164 | |
1165 | if (pIO->Seek(endPos, icSeekSet)<0) |
1166 | return false; |
1167 | } |
1168 | |
1169 | return true; |
1170 | } |
1171 | |
1172 | /** |
1173 | ****************************************************************************** |
1174 | * Name: CIccTagMultiProcessElement::GetElement |
1175 | * |
1176 | * Purpose: |
1177 | * |
1178 | * Args: |
1179 | * |
1180 | * Return: |
1181 | ******************************************************************************/ |
1182 | CIccMultiProcessElement *CIccTagMultiProcessElement::GetElement(int nIndex) |
1183 | { |
1184 | if (!m_list) |
1185 | return NULL__null; |
1186 | |
1187 | CIccMultiProcessElementList::iterator i; |
1188 | int j; |
1189 | |
1190 | for(i=m_list->begin(), j=0; j<nIndex && i!=m_list->end(); i++, j++); |
1191 | |
1192 | if (i!=m_list->end()) |
1193 | return i->ptr; |
1194 | |
1195 | return NULL__null; |
1196 | } |
1197 | |
1198 | /** |
1199 | ****************************************************************************** |
1200 | * Name: CIccTagMultiProcessElement::GetNextElemIterator |
1201 | * |
1202 | * Purpose: |
1203 | * |
1204 | * Args: |
1205 | * |
1206 | * Return: |
1207 | ******************************************************************************/ |
1208 | void CIccTagMultiProcessElement::GetNextElemIterator(CIccMultiProcessElementList::iterator &itr) |
1209 | { |
1210 | itr++; |
1211 | } |
1212 | |
1213 | /** |
1214 | ****************************************************************************** |
1215 | * Name: CIccTagMultiProcessElement::IsLateBinding |
1216 | * |
1217 | * Purpose: |
1218 | * |
1219 | * Args: |
1220 | * |
1221 | * Return: |
1222 | ******************************************************************************/ |
1223 | bool CIccTagMultiProcessElement::IsLateBinding() const |
1224 | { |
1225 | if (!m_list) |
1226 | return false; |
1227 | |
1228 | CIccMultiProcessElementList::const_iterator i; |
1229 | |
1230 | for (i = m_list->begin(); i!= m_list->end(); i++) { |
1231 | if (i->ptr->IsLateBinding()) { |
1232 | return true; |
1233 | } |
1234 | } |
1235 | |
1236 | return false; |
1237 | } |
1238 | |
1239 | /** |
1240 | ****************************************************************************** |
1241 | * Name: CIccTagMultiProcessElement::IsLateBindingReflectance |
1242 | * |
1243 | * Purpose: |
1244 | * |
1245 | * Args: |
1246 | * |
1247 | * Return: |
1248 | ******************************************************************************/ |
1249 | bool CIccTagMultiProcessElement::IsLateBindingReflectance() const |
1250 | { |
1251 | if (!m_list) |
1252 | return false; |
1253 | |
1254 | CIccMultiProcessElementList::const_iterator i; |
1255 | |
1256 | for (i = m_list->begin(); i!= m_list->end(); i++) { |
1257 | if (i->ptr->IsLateBindingReflectance()) { |
1258 | return true; |
1259 | } |
1260 | } |
1261 | |
1262 | return false; |
1263 | } |
1264 | |
1265 | /** |
1266 | ****************************************************************************** |
1267 | * Name: CIccTagMultiProcessElement::Begin |
1268 | * |
1269 | * Purpose: |
1270 | * Initialize for application of processing element |
1271 | * |
1272 | * Args: |
1273 | * nInterp defines interpolation to use for N-Dimensional LUTs |
1274 | * pPCC provides Profile Connection Conditions (only expected to be valid during call to Begin) |
1275 | * |
1276 | * Return: |
1277 | * true if initialization successful, false if not |
1278 | ******************************************************************************/ |
1279 | bool CIccTagMultiProcessElement::Begin(icElemInterp nInterp /*=icElemInterpLinear*/, |
1280 | IIccProfileConnectionConditions *pProfilePCC /*= NULL*/, |
1281 | IIccProfileConnectionConditions *pAppliedPCC /*= NULL*/, |
1282 | IIccCmmEnvVarLookup *pCmmEnvVarLookup /*= NULL*/) |
1283 | { |
1284 | if (!m_list || !m_list->size()) { |
1285 | if (m_nInputChannels != m_nOutputChannels) |
1286 | return false; |
1287 | else |
1288 | return true; |
1289 | } |
1290 | |
1291 | m_pProfilePCC = pProfilePCC; |
1292 | m_pAppliedPCC = pAppliedPCC; |
1293 | m_pCmmEnvVarLookup = pCmmEnvVarLookup; |
1294 | |
1295 | CIccMultiProcessElementList::iterator i; |
1296 | |
1297 | m_nBufChannels=0; |
1298 | |
1299 | //Now we initialize each processing element checking channel matching as we go |
1300 | CIccMultiProcessElement *last=NULL__null; |
1301 | i = m_list->begin(); |
1302 | if (i->ptr->NumInputChannels() != m_nInputChannels) |
1303 | return false; |
1304 | |
1305 | for (; i!= m_list->end(); i++) { |
1306 | if (last) { |
1307 | if (i->ptr->NumInputChannels() != last->NumOutputChannels()) |
1308 | return false; |
1309 | } |
1310 | last = i->ptr; |
1311 | |
1312 | if (m_nBufChannels<last->NumOutputChannels()) |
1313 | m_nBufChannels = last->NumOutputChannels(); |
1314 | |
1315 | if (!last->Begin(nInterp, this)) |
1316 | return false; |
1317 | } |
1318 | |
1319 | //The output channels must match |
1320 | if (last && last->NumOutputChannels() != m_nOutputChannels) |
1321 | return false; |
1322 | |
1323 | m_pAppliedPCC = NULL__null; |
1324 | m_pProfilePCC = NULL__null; |
1325 | |
1326 | return true; |
1327 | } |
1328 | |
1329 | |
1330 | |
1331 | |
1332 | /** |
1333 | ****************************************************************************** |
1334 | * Name: CIccTagMultiProcessElement::ElementIndex |
1335 | * |
1336 | * Purpose: |
1337 | * |
1338 | * Args: |
1339 | * |
1340 | * Return: |
1341 | ******************************************************************************/ |
1342 | icInt32Number CIccTagMultiProcessElement::ElementIndex(CIccMultiProcessElement *pElem) |
1343 | { |
1344 | CIccMultiProcessElementList::iterator i; |
1345 | icInt32Number n; |
1346 | |
1347 | for (n=0, i=m_list->begin(); i!= m_list->end(); i++, n++) { |
1348 | if (i->ptr == pElem) |
1349 | break; |
1350 | } |
1351 | if (i==m_list->end()) |
1352 | n=-1; |
1353 | |
1354 | return n; |
1355 | } |
1356 | |
1357 | CIccMultiProcessElementList::iterator CIccTagMultiProcessElement::GetFirstElem() |
1358 | { |
1359 | return m_list->begin(); |
1360 | } |
1361 | |
1362 | CIccMultiProcessElementList::iterator CIccTagMultiProcessElement::GetLastElem() |
1363 | { |
1364 | return m_list->end(); |
1365 | } |
1366 | |
1367 | |
1368 | /** |
1369 | ****************************************************************************** |
1370 | * Name: CIccTagMultiProcessElement::GetNewApply |
1371 | * |
1372 | * Purpose: |
1373 | * |
1374 | * Args: |
1375 | * |
1376 | * Return: |
1377 | ******************************************************************************/ |
1378 | CIccApplyTagMpe *CIccTagMultiProcessElement::GetNewApply() |
1379 | { |
1380 | CIccApplyTagMpe *pApply = new CIccApplyTagMpe(this); |
1381 | |
1382 | if (!pApply) |
1383 | return NULL__null; |
1384 | |
1385 | CIccDblPixelBuffer *pApplyBuf = pApply->GetBuf(); |
1386 | pApplyBuf->UpdateChannels(m_nBufChannels); |
1387 | if (!pApplyBuf->Begin()) { |
1388 | delete pApply; |
1389 | return NULL__null; |
1390 | } |
1391 | |
1392 | if (!m_list || !m_list->size()) |
1393 | return pApply; |
1394 | |
1395 | CIccMultiProcessElementList::iterator i, last; |
1396 | last = GetLastElem(); |
1397 | for (i=GetFirstElem(); i!=last;) { |
1398 | pApply->AppendElem(i->ptr); |
1399 | |
1400 | GetNextElemIterator(i); |
1401 | } |
1402 | |
1403 | return pApply; |
1404 | } |
1405 | |
1406 | |
1407 | /** |
1408 | ****************************************************************************** |
1409 | * Name: CIccTagMultiProcessElement::Apply |
1410 | * |
1411 | * Purpose: |
1412 | * |
1413 | * Args: |
1414 | * |
1415 | * Return: |
1416 | ******************************************************************************/ |
1417 | void CIccTagMultiProcessElement::Apply(CIccApplyTagMpe *pApply, icFloatNumber *pDestPixel, const icFloatNumber *pSrcPixel) const |
1418 | { |
1419 | if (!pApply || !pApply->GetList() || !pApply->GetList()->size()) { |
1420 | memcpy(pDestPixel, pSrcPixel, m_nInputChannels*sizeof(icFloatNumber)); |
1421 | return; |
1422 | } |
1423 | |
1424 | CIccDblPixelBuffer *pApplyBuf = pApply->GetBuf(); |
1425 | CIccApplyMpeIter i = pApply->begin(); |
1426 | CIccApplyMpeIter next; |
1427 | |
1428 | next = i; |
1429 | next++; |
1430 | |
1431 | if (next==pApply->end()) { |
1432 | //Elements rely on pDestPixel != pSrcPixel |
1433 | if (pSrcPixel==pDestPixel) { |
1434 | i->ptr->Apply(pApplyBuf->GetDstBuf(), pSrcPixel); |
1435 | memcpy(pDestPixel, pApplyBuf->GetDstBuf(), m_nOutputChannels*sizeof(icFloatNumber)); |
1436 | } |
1437 | else { |
1438 | i->ptr->Apply(pDestPixel, pSrcPixel); |
1439 | } |
1440 | } |
1441 | else { |
1442 | i->ptr->Apply(pApplyBuf->GetDstBuf(), pSrcPixel); |
1443 | i++; |
1444 | next++; |
1445 | pApplyBuf->Switch(); |
1446 | |
1447 | while (next != pApply->end()) { |
1448 | CIccMultiProcessElement *pElem = i->ptr->GetElem(); |
1449 | |
1450 | if (!pElem->IsAcs()) { |
1451 | i->ptr->Apply(pApplyBuf->GetDstBuf(), pApplyBuf->GetSrcBuf()); |
1452 | pApplyBuf->Switch(); |
1453 | } |
1454 | |
1455 | i++; |
1456 | next++; |
1457 | } |
1458 | |
1459 | i->ptr->Apply(pDestPixel, pApplyBuf->GetSrcBuf()); |
1460 | } |
1461 | } |
1462 | |
1463 | |
1464 | /** |
1465 | ****************************************************************************** |
1466 | * Name: CIccTagMultiProcessElement::Validate |
1467 | * |
1468 | * Purpose: |
1469 | * |
1470 | * Args: |
1471 | * |
1472 | * Return: |
1473 | ******************************************************************************/ |
1474 | icValidateStatus CIccTagMultiProcessElement::Validate(std::string sigPath, std::string &sReport, |
1475 | const CIccProfile* pProfile /*=NULL*/) const |
1476 | { |
1477 | icValidateStatus rv = icValidateOK; |
1478 | |
1479 | CIccInfo Info; |
1480 | std::string sSigPathName = Info.GetSigPathName(sigPath); |
1481 | bool bMatchChannels = true; |
1482 | |
1483 | if (!m_list || !m_list->size()) { |
1484 | if (m_nInputChannels != m_nOutputChannels) { |
1485 | sReport += icMsgValidateCriticalError; |
1486 | sReport += sSigPathName; |
1487 | sReport += " No processing elements and input and output channels do not match!\r\n"; |
1488 | rv = icMaxStatus(rv, icValidateCriticalError); |
1489 | } |
1490 | else { |
1491 | sReport += icMsgValidateWarning; |
1492 | sReport += sSigPathName; |
1493 | sReport += " No processing elements.\r\n"; |
1494 | rv = icMaxStatus(rv, icValidateWarning); |
1495 | } |
1496 | } |
1497 | |
1498 | if (!pProfile) { |
1499 | sReport += icMsgValidateWarning; |
1500 | sReport += sSigPathName; |
1501 | sReport += " - Tag validation incomplete: Pointer to profile unavailable.\r\n"; |
1502 | rv = icMaxStatus(rv, icValidateWarning); |
1503 | return rv; |
1504 | } |
1505 | icUInt32Number nInput, nOutput; |
1506 | |
1507 | //Check # of channels |
1508 | switch(icGetFirstSigPathSig(sigPath)) { |
1509 | case icSigAToB0Tag: |
1510 | case icSigAToB1Tag: |
1511 | case icSigAToB2Tag: |
1512 | case icSigAToB3Tag: |
1513 | { |
1514 | nInput = icGetSpaceSamples(pProfile->m_Header.colorSpace); |
1515 | if (m_nInputChannels != nInput) { |
1516 | sReport += icMsgValidateCriticalError; |
1517 | sReport += sSigPathName; |
1518 | sReport += " - Incorrect number of input channels.\r\n"; |
1519 | rv = icMaxStatus(rv, icValidateCriticalError); |
1520 | } |
1521 | |
1522 | nOutput = icGetSpaceSamples(pProfile->m_Header.pcs); |
1523 | if (m_nOutputChannels != nOutput) { |
1524 | sReport += icMsgValidateCriticalError; |
1525 | sReport += sSigPathName; |
1526 | sReport += " - Incorrect number of output channels.\r\n"; |
1527 | rv = icMaxStatus(rv, icValidateCriticalError); |
1528 | } |
1529 | |
1530 | break; |
1531 | } |
1532 | case icSigBToA0Tag: |
1533 | case icSigBToA1Tag: |
1534 | case icSigBToA2Tag: |
1535 | case icSigBToA3Tag: |
1536 | { |
1537 | nInput = icGetSpaceSamples(pProfile->m_Header.pcs); |
1538 | if (m_nInputChannels!=nInput) { |
1539 | sReport += icMsgValidateCriticalError; |
1540 | sReport += sSigPathName; |
1541 | sReport += " - Incorrect number of input channels.\r\n"; |
1542 | rv = icMaxStatus(rv, icValidateCriticalError); |
1543 | } |
1544 | |
1545 | nOutput = icGetSpaceSamples(pProfile->m_Header.colorSpace); |
1546 | if (m_nOutputChannels!=nOutput) { |
1547 | sReport += icMsgValidateCriticalError; |
1548 | sReport += sSigPathName; |
1549 | sReport += " - Incorrect number of output channels.\r\n"; |
1550 | rv = icMaxStatus(rv, icValidateCriticalError); |
1551 | } |
1552 | |
1553 | break; |
1554 | } |
1555 | case icSigDToB0Tag: |
1556 | case icSigDToB1Tag: |
1557 | case icSigDToB2Tag: |
1558 | case icSigDToB3Tag: |
1559 | { |
1560 | nInput = icGetSpaceSamples(pProfile->m_Header.colorSpace); |
1561 | if (m_nInputChannels != nInput) { |
1562 | sReport += icMsgValidateCriticalError; |
1563 | sReport += sSigPathName; |
1564 | sReport += " - Incorrect number of input channels.\r\n"; |
1565 | rv = icMaxStatus(rv, icValidateCriticalError); |
1566 | } |
1567 | |
1568 | nOutput = icGetSpectralSpaceSamples(&pProfile->m_Header); |
1569 | if (m_nOutputChannels != nOutput) { |
1570 | sReport += icMsgValidateCriticalError; |
1571 | sReport += sSigPathName; |
1572 | sReport += " - Incorrect number of output channels.\r\n"; |
1573 | rv = icMaxStatus(rv, icValidateCriticalError); |
1574 | } |
1575 | |
1576 | break; |
1577 | } |
1578 | case icSigBToD0Tag: |
1579 | case icSigBToD1Tag: |
1580 | case icSigBToD2Tag: |
1581 | case icSigBToD3Tag: |
1582 | { |
1583 | nInput = icGetSpectralSpaceSamples(&pProfile->m_Header); |
1584 | if (m_nInputChannels!=nInput) { |
1585 | sReport += icMsgValidateCriticalError; |
1586 | sReport += sSigPathName; |
1587 | sReport += " - Incorrect number of input channels.\r\n"; |
1588 | rv = icMaxStatus(rv, icValidateCriticalError); |
1589 | } |
1590 | |
1591 | nOutput = icGetSpaceSamples(pProfile->m_Header.colorSpace); |
1592 | if (m_nOutputChannels!=nOutput) { |
1593 | sReport += icMsgValidateCriticalError; |
1594 | sReport += sSigPathName; |
1595 | sReport += " - Incorrect number of output channels.\r\n"; |
1596 | rv = icMaxStatus(rv, icValidateCriticalError); |
1597 | } |
1598 | |
1599 | break; |
1600 | } |
1601 | case icSigCustomToStandardPccTag: |
1602 | case icSigStandardToCustomPccTag: |
1603 | { |
1604 | if (m_nInputChannels != 3) { |
1605 | sReport += icMsgValidateCriticalError; |
1606 | sReport += sSigPathName; |
1607 | sReport += " - Incorrect number of input channels.\r\n"; |
1608 | rv = icMaxStatus(rv, icValidateCriticalError); |
1609 | } |
1610 | |
1611 | if (m_nOutputChannels != 3) { |
1612 | sReport += icMsgValidateCriticalError; |
1613 | sReport += sSigPathName; |
1614 | sReport += " - Incorrect number of output channels.\r\n"; |
1615 | rv = icMaxStatus(rv, icValidateCriticalError); |
1616 | } |
1617 | |
1618 | break; |
1619 | } |
1620 | case icSigBRDFAToB0Tag: |
1621 | case icSigBRDFAToB1Tag: |
1622 | case icSigBRDFAToB2Tag: |
1623 | case icSigBRDFAToB3Tag: |
1624 | { |
1625 | switch(icGetFirstSigPathSig(sigPath)) { |
1626 | case icSigBrdfTransformMbr: |
1627 | //TODO: Initialize input and output |
1628 | nInput = nOutput = 0; |
Value stored to 'nInput' is never read | |
1629 | break; |
1630 | |
1631 | case icSigBrdfLightTransformMbr: |
1632 | //TODO: Initialize input and output |
1633 | nInput = nOutput = 0; |
1634 | break; |
1635 | |
1636 | case icSigBrdfOutputTransformMbr: |
1637 | //TODO: Initialize input and output |
1638 | nInput = nOutput = 0; |
1639 | break; |
1640 | |
1641 | default: |
1642 | break; |
1643 | } |
1644 | break; |
1645 | } |
1646 | case icSigBRDFDToB0Tag: |
1647 | case icSigBRDFDToB1Tag: |
1648 | case icSigBRDFDToB2Tag: |
1649 | case icSigBRDFDToB3Tag: |
1650 | { |
1651 | switch(icGetFirstSigPathSig(sigPath)) { |
1652 | case icSigBrdfTransformMbr: |
1653 | //TODO: Initialize input and output |
1654 | nInput = nOutput = 0; |
1655 | break; |
1656 | |
1657 | case icSigBrdfLightTransformMbr: |
1658 | //TODO: Initialize input and output |
1659 | nInput = nOutput = 0; |
1660 | break; |
1661 | |
1662 | case icSigBrdfOutputTransformMbr: |
1663 | //TODO: Initialize input and output |
1664 | nInput = nOutput = 0; |
1665 | break; |
1666 | |
1667 | default: |
1668 | break; |
1669 | } |
1670 | break; |
1671 | } |
1672 | |
1673 | case icSigMToA0Tag: |
1674 | { |
1675 | nInput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs); |
1676 | if (m_nInputChannels != nInput) { |
1677 | sReport += icMsgValidateCriticalError; |
1678 | sReport += sSigPathName; |
1679 | sReport += " - Incorrect number of input channels.\r\n"; |
1680 | rv = icMaxStatus(rv, icValidateCriticalError); |
1681 | } |
1682 | |
1683 | nOutput = icGetSpaceSamples(pProfile->m_Header.colorSpace); |
1684 | if (m_nOutputChannels != nOutput) { |
1685 | sReport += icMsgValidateCriticalError; |
1686 | sReport += sSigPathName; |
1687 | sReport += " - Incorrect number of output channels.\r\n"; |
1688 | rv = icMaxStatus(rv, icValidateCriticalError); |
1689 | } |
1690 | |
1691 | break; |
1692 | } |
1693 | |
1694 | case icSigAToM0Tag: |
1695 | { |
1696 | nInput = icGetSpaceSamples(pProfile->m_Header.colorSpace); |
1697 | if (m_nInputChannels != nInput) { |
1698 | sReport += icMsgValidateCriticalError; |
1699 | sReport += sSigPathName; |
1700 | sReport += " - Incorrect number of input channels.\r\n"; |
1701 | rv = icMaxStatus(rv, icValidateCriticalError); |
1702 | } |
1703 | |
1704 | nOutput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs); |
1705 | if (m_nOutputChannels != nOutput) { |
1706 | sReport += icMsgValidateCriticalError; |
1707 | sReport += sSigPathName; |
1708 | sReport += " - Incorrect number of output channels.\r\n"; |
1709 | rv = icMaxStatus(rv, icValidateCriticalError); |
1710 | } |
1711 | |
1712 | break; |
1713 | } |
1714 | |
1715 | case icSigMToB0Tag: |
1716 | case icSigMToB1Tag: |
1717 | case icSigMToB2Tag: |
1718 | case icSigMToB3Tag: |
1719 | { |
1720 | nInput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs); |
1721 | if (m_nInputChannels != nInput) { |
1722 | sReport += icMsgValidateCriticalError; |
1723 | sReport += sSigPathName; |
1724 | sReport += " - Incorrect number of input channels.\r\n"; |
1725 | rv = icMaxStatus(rv, icValidateCriticalError); |
1726 | } |
1727 | |
1728 | nOutput = icGetSpaceSamples(pProfile->m_Header.pcs); |
1729 | if (m_nOutputChannels != nOutput) { |
1730 | sReport += icMsgValidateCriticalError; |
1731 | sReport += sSigPathName; |
1732 | sReport += " - Incorrect number of output channels.\r\n"; |
1733 | rv = icMaxStatus(rv, icValidateCriticalError); |
1734 | } |
1735 | |
1736 | break; |
1737 | } |
1738 | |
1739 | case icSigMToS0Tag: |
1740 | case icSigMToS1Tag: |
1741 | case icSigMToS2Tag: |
1742 | case icSigMToS3Tag: |
1743 | { |
1744 | nInput = icGetMaterialColorSpaceSamples(pProfile->m_Header.mcs); |
1745 | if (m_nInputChannels != nInput) { |
1746 | sReport += icMsgValidateCriticalError; |
1747 | sReport += sSigPathName; |
1748 | sReport += " - Incorrect number of input channels.\r\n"; |
1749 | rv = icMaxStatus(rv, icValidateCriticalError); |
1750 | } |
1751 | |
1752 | nOutput = icGetSpectralSpaceSamples(&pProfile->m_Header); |
1753 | if (m_nOutputChannels != nOutput) { |
1754 | sReport += icMsgValidateCriticalError; |
1755 | sReport += sSigPathName; |
1756 | sReport += " - Incorrect number of output channels.\r\n"; |
1757 | rv = icMaxStatus(rv, icValidateCriticalError); |
1758 | } |
1759 | |
1760 | break; |
1761 | } |
1762 | |
1763 | default: |
1764 | sReport += icMsgValidateWarning; |
1765 | sReport += sSigPathName; |
1766 | sReport += " - Unknown tag - Cannot validate input and output channels!\r\n"; |
1767 | rv = icMaxStatus(rv, icValidateWarning); |
1768 | bMatchChannels = false; |
1769 | break; |
1770 | } |
1771 | |
1772 | if (!m_list || !m_list->size()) { |
1773 | return rv; |
1774 | } |
1775 | |
1776 | CIccMultiProcessElementList::iterator i = m_list->begin(); |
1777 | CIccMultiProcessElement *last=NULL__null; |
1778 | |
1779 | if (bMatchChannels && i->ptr->NumInputChannels() != m_nInputChannels) { |
1780 | sReport += icMsgValidateCriticalError; |
1781 | sReport += sSigPathName; |
1782 | sReport += "Mis-matching number of input channels in first process element!\r\n"; |
1783 | return icValidateCriticalError; |
1784 | } |
1785 | |
1786 | for (; i!= m_list->end(); i++) { |
1787 | if (last) { |
1788 | if (i->ptr->NumInputChannels() != last->NumOutputChannels()) { |
1789 | sReport += icMsgValidateCriticalError; |
1790 | sReport += sSigPathName; |
1791 | |
1792 | sReport += "("; |
1793 | sReport += last->GetClassName(); |
1794 | sReport += "->"; |
1795 | sReport += i->ptr->GetClassName(); |
1796 | |
1797 | sReport += " Mis-matching number of channels in last process element!\r\n"; |
1798 | return icValidateCriticalError; |
1799 | } |
1800 | } |
1801 | last = i->ptr; |
1802 | |
1803 | rv = icMaxStatus(rv, last->Validate(sigPath+icGetSigPath(GetType()), sReport, this)); |
1804 | } |
1805 | |
1806 | if (bMatchChannels && last && last->NumOutputChannels() != m_nOutputChannels) { |
1807 | sReport += icMsgValidateCriticalError; |
1808 | sReport += sSigPathName; |
1809 | sReport += " Mis-matching number of output channels!\r\n"; |
1810 | return icValidateCriticalError; |
1811 | } |
1812 | |
1813 | return rv; |
1814 | } |
1815 | |
1816 | #ifdef USEREFICCMAXNAMESPACE |
1817 | } //namespace refIccMAX |
1818 | #endif |