< prev index next >

src/java.desktop/share/native/liblcms/cmsio0.c

Print this page




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2017 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 246 
 247 
 248 static
 249 cmsBool  MemoryClose(struct _cms_io_handler* iohandler)
 250 {
 251     FILEMEM* ResData = (FILEMEM*) iohandler ->stream;
 252 
 253     if (ResData ->FreeBlockOnClose) {
 254 
 255         if (ResData ->Block) _cmsFree(iohandler ->ContextID, ResData ->Block);
 256     }
 257 
 258     _cmsFree(iohandler ->ContextID, ResData);
 259     _cmsFree(iohandler ->ContextID, iohandler);
 260 
 261     return TRUE;
 262 }
 263 
 264 // Create a iohandler for memory block. AccessMode=='r' assumes the iohandler is going to read, and makes
 265 // a copy of the memory block for letting user to free the memory after invoking open profile. In write
 266 // mode ("w"), Buffere points to the begin of memory block to be written.
 267 cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buffer, cmsUInt32Number size, const char* AccessMode)
 268 {
 269     cmsIOHANDLER* iohandler = NULL;
 270     FILEMEM* fm = NULL;
 271 
 272     _cmsAssert(AccessMode != NULL);
 273 
 274     iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
 275     if (iohandler == NULL) return NULL;
 276 
 277     switch (*AccessMode) {
 278 
 279     case 'r':
 280         fm = (FILEMEM*) _cmsMallocZero(ContextID, sizeof(FILEMEM));
 281         if (fm == NULL) goto Error;
 282 
 283         if (Buffer == NULL) {
 284             cmsSignalError(ContextID, cmsERROR_READ, "Couldn't read profile from NULL pointer");
 285             goto Error;
 286         }


 645 }
 646 
 647 
 648 // Creates a new tag entry
 649 static
 650 cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
 651 {
 652     int i;
 653 
 654     // Search for the tag
 655     i = _cmsSearchTag(Icc, sig, FALSE);
 656     if (i >= 0) {
 657 
 658         // Already exists? delete it
 659         _cmsDeleteTagByPos(Icc, i);
 660         *NewPos = i;
 661     }
 662     else  {
 663 
 664         // No, make a new one
 665 
 666         if (Icc -> TagCount >= MAX_TABLE_TAG) {
 667             cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG);
 668             return FALSE;
 669         }
 670 
 671         *NewPos = (int) Icc ->TagCount;
 672         Icc -> TagCount++;
 673     }
 674 
 675     return TRUE;
 676 }
 677 
 678 
 679 // Check existence
 680 cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
 681 {
 682        _cmsICCPROFILE*  Icc = (_cmsICCPROFILE*) (void*) hProfile;
 683        return _cmsSearchTag(Icc, sig, FALSE) >= 0;
 684 }
 685 
 686 
 687 
 688 // Enforces that the profile version is per. spec.
 689 // Operates on the big endian bytes from the profile.
 690 // Called before converting to platform endianness.
 691 // Byte 0 is BCD major version, so max 9.
 692 // Byte 1 is 2 BCD digits, one per nibble.
 693 // Reserved bytes 2 & 3 must be 0.
 694 static
 695 cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
 696 {
 697     cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
 698     cmsUInt8Number temp1;
 699     cmsUInt8Number temp2;
 700 
 701     if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09;
 702     temp1 = (cmsUInt8Number) (*(pByte+1) & 0xf0);
 703     temp2 = (cmsUInt8Number) (*(pByte+1) & 0x0f);
 704     if (temp1 > 0x90U) temp1 = 0x90U;
 705     if (temp2 > 0x09U) temp2 = 0x09U;
 706     *(pByte+1) = (cmsUInt8Number)(temp1 | temp2);
 707     *(pByte+2) = (cmsUInt8Number)0;


1579 
1580     // Search for support on this tag
1581     TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
1582     if (TagDescriptor == NULL) {
1583 
1584         char String[5];
1585 
1586         _cmsTagSignature2String(String, sig);
1587 
1588         // An unknown element was found.
1589         cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
1590         goto Error;     // Unsupported.
1591     }
1592 
1593     // if supported, get type and check if in list
1594     BaseType = _cmsReadTypeBase(io);
1595     if (BaseType == 0) goto Error;
1596 
1597     if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
1598 
1599     TagSize  -= 8;       // Alredy read by the type base logic
1600 
1601     // Get type handler
1602     TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
1603     if (TypeHandler == NULL) goto Error;
1604     LocalTypeHandler = *TypeHandler;
1605 
1606 
1607     // Read the tag
1608     Icc -> TagTypeHandlers[n] = TypeHandler;
1609 
1610     LocalTypeHandler.ContextID = Icc ->ContextID;
1611     LocalTypeHandler.ICCVersion = Icc ->Version;
1612     Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
1613 
1614     // The tag type is supported, but something wrong happened and we cannot read the tag.
1615     // let know the user about this (although it is just a warning)
1616     if (Icc -> TagPtrs[n] == NULL) {
1617 
1618         char String[5];
1619 
1620         _cmsTagSignature2String(String, sig);
1621         cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
1622         goto Error;
1623     }
1624 
1625     // This is a weird error that may be a symptom of something more serious, the number of
1626     // stored item is actually less than the number of required elements.
1627     if (ElemCount < TagDescriptor ->ElemCount) {
1628 
1629         char String[5];
1630 
1631         _cmsTagSignature2String(String, sig);
1632         cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d",
1633             String, TagDescriptor ->ElemCount, ElemCount);

1634     }
1635 
1636 
1637     // Return the data
1638     _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1639     return Icc -> TagPtrs[n];
1640 
1641 
1642     // Return error and unlock tha data
1643 Error:
1644     _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1645     return NULL;
1646 }
1647 
1648 
1649 // Get true type of data
1650 cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig)
1651 {
1652     _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
1653     cmsTagTypeHandler* TypeHandler;


1810         Offset   = Icc ->TagOffsets[i];
1811         TagSize  = Icc ->TagSizes[i];
1812 
1813         // read the data directly, don't keep copy
1814         if (data != NULL) {
1815 
1816             if (BufferSize < TagSize)
1817                 TagSize = BufferSize;
1818 
1819             if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error;
1820             if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error;
1821 
1822             _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1823             return TagSize;
1824         }
1825 
1826         _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1827         return Icc ->TagSizes[i];
1828     }
1829 
1830     // The data has been already read, or written. But wait!, maybe the user choosed to save as
1831     // raw data. In this case, return the raw data directly
1832     if (Icc ->TagSaveAsRaw[i]) {
1833 
1834         if (data != NULL)  {
1835 
1836             TagSize  = Icc ->TagSizes[i];
1837             if (BufferSize < TagSize)
1838                 TagSize = BufferSize;
1839 
1840             memmove(data, Icc ->TagPtrs[i], TagSize);
1841 
1842             _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1843             return TagSize;
1844         }
1845 
1846         _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1847         return Icc ->TagSizes[i];
1848     }
1849 
1850     // Already readed, or previously set by cmsWriteTag(). We need to serialize that
1851     // data to raw in order to maintain consistency.
1852 
1853     _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1854     Object = cmsReadTag(hProfile, sig);
1855     if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
1856 
1857     if (Object == NULL) goto Error;
1858 
1859     // Now we need to serialize to a memory block: just use a memory iohandler
1860 
1861     if (data == NULL) {
1862         MemIO = cmsOpenIOhandlerFromNULL(cmsGetProfileContextID(hProfile));
1863     } else{
1864         MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w");
1865     }
1866     if (MemIO == NULL) goto Error;
1867 
1868     // Obtain type handling for the tag
1869     TypeHandler = Icc ->TagTypeHandlers[i];
1870     TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2020 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 246 
 247 
 248 static
 249 cmsBool  MemoryClose(struct _cms_io_handler* iohandler)
 250 {
 251     FILEMEM* ResData = (FILEMEM*) iohandler ->stream;
 252 
 253     if (ResData ->FreeBlockOnClose) {
 254 
 255         if (ResData ->Block) _cmsFree(iohandler ->ContextID, ResData ->Block);
 256     }
 257 
 258     _cmsFree(iohandler ->ContextID, ResData);
 259     _cmsFree(iohandler ->ContextID, iohandler);
 260 
 261     return TRUE;
 262 }
 263 
 264 // Create a iohandler for memory block. AccessMode=='r' assumes the iohandler is going to read, and makes
 265 // a copy of the memory block for letting user to free the memory after invoking open profile. In write
 266 // mode ("w"), Buffer points to the begin of memory block to be written.
 267 cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buffer, cmsUInt32Number size, const char* AccessMode)
 268 {
 269     cmsIOHANDLER* iohandler = NULL;
 270     FILEMEM* fm = NULL;
 271 
 272     _cmsAssert(AccessMode != NULL);
 273 
 274     iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
 275     if (iohandler == NULL) return NULL;
 276 
 277     switch (*AccessMode) {
 278 
 279     case 'r':
 280         fm = (FILEMEM*) _cmsMallocZero(ContextID, sizeof(FILEMEM));
 281         if (fm == NULL) goto Error;
 282 
 283         if (Buffer == NULL) {
 284             cmsSignalError(ContextID, cmsERROR_READ, "Couldn't read profile from NULL pointer");
 285             goto Error;
 286         }


 645 }
 646 
 647 
 648 // Creates a new tag entry
 649 static
 650 cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
 651 {
 652     int i;
 653 
 654     // Search for the tag
 655     i = _cmsSearchTag(Icc, sig, FALSE);
 656     if (i >= 0) {
 657 
 658         // Already exists? delete it
 659         _cmsDeleteTagByPos(Icc, i);
 660         *NewPos = i;
 661     }
 662     else  {
 663 
 664         // No, make a new one

 665         if (Icc -> TagCount >= MAX_TABLE_TAG) {
 666             cmsSignalError(Icc ->ContextID, cmsERROR_RANGE, "Too many tags (%d)", MAX_TABLE_TAG);
 667             return FALSE;
 668         }
 669 
 670         *NewPos = (int) Icc ->TagCount;
 671         Icc -> TagCount++;
 672     }
 673 
 674     return TRUE;
 675 }
 676 
 677 
 678 // Check existence
 679 cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
 680 {
 681        _cmsICCPROFILE*  Icc = (_cmsICCPROFILE*) (void*) hProfile;
 682        return _cmsSearchTag(Icc, sig, FALSE) >= 0;
 683 }
 684 


 685 // Enforces that the profile version is per. spec.
 686 // Operates on the big endian bytes from the profile.
 687 // Called before converting to platform endianness.
 688 // Byte 0 is BCD major version, so max 9.
 689 // Byte 1 is 2 BCD digits, one per nibble.
 690 // Reserved bytes 2 & 3 must be 0.
 691 static
 692 cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
 693 {
 694     cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
 695     cmsUInt8Number temp1;
 696     cmsUInt8Number temp2;
 697 
 698     if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09;
 699     temp1 = (cmsUInt8Number) (*(pByte+1) & 0xf0);
 700     temp2 = (cmsUInt8Number) (*(pByte+1) & 0x0f);
 701     if (temp1 > 0x90U) temp1 = 0x90U;
 702     if (temp2 > 0x09U) temp2 = 0x09U;
 703     *(pByte+1) = (cmsUInt8Number)(temp1 | temp2);
 704     *(pByte+2) = (cmsUInt8Number)0;


1576 
1577     // Search for support on this tag
1578     TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
1579     if (TagDescriptor == NULL) {
1580 
1581         char String[5];
1582 
1583         _cmsTagSignature2String(String, sig);
1584 
1585         // An unknown element was found.
1586         cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
1587         goto Error;     // Unsupported.
1588     }
1589 
1590     // if supported, get type and check if in list
1591     BaseType = _cmsReadTypeBase(io);
1592     if (BaseType == 0) goto Error;
1593 
1594     if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
1595 
1596     TagSize  -= 8;       // Already read by the type base logic
1597 
1598     // Get type handler
1599     TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
1600     if (TypeHandler == NULL) goto Error;
1601     LocalTypeHandler = *TypeHandler;
1602 
1603 
1604     // Read the tag
1605     Icc -> TagTypeHandlers[n] = TypeHandler;
1606 
1607     LocalTypeHandler.ContextID = Icc ->ContextID;
1608     LocalTypeHandler.ICCVersion = Icc ->Version;
1609     Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
1610 
1611     // The tag type is supported, but something wrong happened and we cannot read the tag.
1612     // let know the user about this (although it is just a warning)
1613     if (Icc -> TagPtrs[n] == NULL) {
1614 
1615         char String[5];
1616 
1617         _cmsTagSignature2String(String, sig);
1618         cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
1619         goto Error;
1620     }
1621 
1622     // This is a weird error that may be a symptom of something more serious, the number of
1623     // stored item is actually less than the number of required elements.
1624     if (ElemCount < TagDescriptor ->ElemCount) {
1625 
1626         char String[5];
1627 
1628         _cmsTagSignature2String(String, sig);
1629         cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d",
1630             String, TagDescriptor ->ElemCount, ElemCount);
1631         goto Error;
1632     }
1633 
1634 
1635     // Return the data
1636     _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1637     return Icc -> TagPtrs[n];
1638 
1639 
1640     // Return error and unlock tha data
1641 Error:
1642     _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1643     return NULL;
1644 }
1645 
1646 
1647 // Get true type of data
1648 cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig)
1649 {
1650     _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
1651     cmsTagTypeHandler* TypeHandler;


1808         Offset   = Icc ->TagOffsets[i];
1809         TagSize  = Icc ->TagSizes[i];
1810 
1811         // read the data directly, don't keep copy
1812         if (data != NULL) {
1813 
1814             if (BufferSize < TagSize)
1815                 TagSize = BufferSize;
1816 
1817             if (!Icc ->IOhandler ->Seek(Icc ->IOhandler, Offset)) goto Error;
1818             if (!Icc ->IOhandler ->Read(Icc ->IOhandler, data, 1, TagSize)) goto Error;
1819 
1820             _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1821             return TagSize;
1822         }
1823 
1824         _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1825         return Icc ->TagSizes[i];
1826     }
1827 
1828     // The data has been already read, or written. But wait!, maybe the user chose to save as
1829     // raw data. In this case, return the raw data directly
1830     if (Icc ->TagSaveAsRaw[i]) {
1831 
1832         if (data != NULL)  {
1833 
1834             TagSize  = Icc ->TagSizes[i];
1835             if (BufferSize < TagSize)
1836                 TagSize = BufferSize;
1837 
1838             memmove(data, Icc ->TagPtrs[i], TagSize);
1839 
1840             _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1841             return TagSize;
1842         }
1843 
1844         _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1845         return Icc ->TagSizes[i];
1846     }
1847 
1848     // Already read, or previously set by cmsWriteTag(). We need to serialize that
1849     // data to raw in order to maintain consistency.
1850 
1851     _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
1852     Object = cmsReadTag(hProfile, sig);
1853     if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return 0;
1854 
1855     if (Object == NULL) goto Error;
1856 
1857     // Now we need to serialize to a memory block: just use a memory iohandler
1858 
1859     if (data == NULL) {
1860         MemIO = cmsOpenIOhandlerFromNULL(cmsGetProfileContextID(hProfile));
1861     } else{
1862         MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w");
1863     }
1864     if (MemIO == NULL) goto Error;
1865 
1866     // Obtain type handling for the tag
1867     TypeHandler = Icc ->TagTypeHandlers[i];
1868     TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);


< prev index next >