1638 lines
43 KiB
C
1638 lines
43 KiB
C
|
#include "generic.h"
|
||
|
|
||
|
#pragma code_seg(_ICM2SEG)
|
||
|
#pragma optimize("",off)
|
||
|
|
||
|
#define TempBfSize 128
|
||
|
#define LINELENG 128
|
||
|
#ifdef ICMDLL
|
||
|
#define ICM2SEG
|
||
|
#endif
|
||
|
|
||
|
static char ICM2SEG NewLine[] = "\n" ;
|
||
|
static char ICM2SEG ASCII85DecodeBegine[] = "<~";
|
||
|
static char ICM2SEG ASCII85DecodeEnd[] = "~> cvx exec ";
|
||
|
|
||
|
|
||
|
// Local functions to deal with output to the memory buffer
|
||
|
|
||
|
static SINT CPLastError;
|
||
|
|
||
|
BOOL EXTERN SetCPLastError(SINT LastError)
|
||
|
{
|
||
|
CPLastError = LastError;
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
SINT EXTERN GetCPLastError()
|
||
|
{
|
||
|
return(CPLastError);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN MemAlloc(SINT Size, HGLOBAL FAR *hMemory, LPMEMPTR lpMH)
|
||
|
{
|
||
|
HGLOBAL hMem;
|
||
|
LPVOID lpMem;
|
||
|
|
||
|
*hMemory = 0;
|
||
|
if(lpMH == NULL )
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
hMem = GlobalAlloc(GHND, Size) ;
|
||
|
if(hMem == 0 )
|
||
|
{
|
||
|
SetCPLastError(CP_MEMORY_ALLOC_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
lpMem = GlobalLock(hMem);
|
||
|
if(lpMem == NULL )
|
||
|
{
|
||
|
GlobalFree(hMem);
|
||
|
SetCPLastError(CP_MEMORY_ALLOC_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpMH = (MEMPTR)lpMem ;
|
||
|
*hMemory = hMem;
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN MemFree(HGLOBAL hMem)
|
||
|
{
|
||
|
if(hMem == NULL )
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
GlobalUnlock(hMem);
|
||
|
GlobalFree(hMem) ;
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Low-level Profile functions - used for individual tag access
|
||
|
|
||
|
#ifndef ICMDLL
|
||
|
BOOL EXTERN LoadCP(LPCSTR filename, HGLOBAL FAR *phMem, LPCHANDLE lpCP)
|
||
|
{
|
||
|
icHeader CPHeader;
|
||
|
HFILE hFile;
|
||
|
SINT Res, CPSize;
|
||
|
MEMPTR mpCP;
|
||
|
|
||
|
*phMem = 0;
|
||
|
if (lpCP == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
hFile = _lopen(filename, READ );
|
||
|
if( hFile == HFILE_ERROR )
|
||
|
{
|
||
|
SetCPLastError(CP_FILE_OPEN_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
Res = _lread(hFile, (LPVOID) &CPHeader, sizeof(CPHeader));
|
||
|
if( (Res == HFILE_ERROR) ||
|
||
|
(Res != sizeof(CPHeader)) )
|
||
|
{
|
||
|
_lclose(hFile);
|
||
|
SetCPLastError(CP_FILE_READ_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
// Make the initial check for validity of the profile
|
||
|
if( SigtoCSIG(CPHeader.magic) != icMagicNumber )
|
||
|
{
|
||
|
_lclose(hFile);
|
||
|
SetCPLastError(CP_FORMAT_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
CPSize = ui32toSINT(CPHeader.size);
|
||
|
if( MemAlloc(CPSize, phMem, (LPMEMPTR) &mpCP) )
|
||
|
{
|
||
|
|
||
|
*lpCP = (CHANDLE) mpCP; // Put the memory pointer as handle
|
||
|
// Read profile into memory
|
||
|
_lseek(hFile, 0L, SEEK_SET);
|
||
|
|
||
|
while(CPSize)
|
||
|
{
|
||
|
Res = _lread(hFile, (LPVOID) mpCP, 4096);
|
||
|
if (Res == HFILE_ERROR)
|
||
|
{
|
||
|
_lclose(hFile);
|
||
|
SetCPLastError(CP_FILE_READ_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
mpCP += Res;
|
||
|
CPSize -= Res;
|
||
|
}
|
||
|
}else
|
||
|
{
|
||
|
*phMem = 0;
|
||
|
_lclose(hFile);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
_lclose(hFile);
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
// Low-level Profile functions - used for individual tag access
|
||
|
|
||
|
BOOL EXTERN LoadCP32(LPCSTR filename, HGLOBAL *phMem, LPCHANDLE lpCP)
|
||
|
{
|
||
|
icHeader CPHeader;
|
||
|
HANDLE hFile;
|
||
|
SINT Res, CPSize;
|
||
|
MEMPTR mpCP;
|
||
|
BOOL Success;
|
||
|
|
||
|
if (lpCP == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
hFile = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||
|
if( hFile == INVALID_HANDLE_VALUE )
|
||
|
{
|
||
|
SetCPLastError(CP_FILE_OPEN_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
Success = ReadFile(hFile, (LPVOID) &CPHeader, sizeof(CPHeader), &Res, NULL);
|
||
|
if( ( !Success ) || (Res != sizeof(CPHeader)) )
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
SetCPLastError(CP_FILE_READ_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
// Make the initial check for validity of the profile
|
||
|
if( SigtoCSIG(CPHeader.magic) != icMagicNumber )
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
SetCPLastError(CP_FORMAT_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
CPSize = ui32toSINT(CPHeader.size);
|
||
|
if( MemAlloc(CPSize, phMem, (LPMEMPTR) &mpCP) )
|
||
|
{
|
||
|
|
||
|
*lpCP = (CHANDLE) mpCP; // Put the memory pointer as handle
|
||
|
// Read profile into memory
|
||
|
SetFilePointer(hFile, 0L, NULL, FILE_BEGIN);
|
||
|
Success = ReadFile(hFile, (LPVOID) (LPVOID)mpCP, CPSize, &Res, NULL);
|
||
|
if (!Success)
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
SetCPLastError(CP_FILE_READ_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
}else
|
||
|
{
|
||
|
CloseHandle(hFile);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
CloseHandle(hFile);
|
||
|
return (TRUE);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
BOOL EXTERN FreeCP(HGLOBAL hMem)
|
||
|
{
|
||
|
return( MemFree(hMem) );
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL EXTERN GetCPElementCount(CHANDLE CP, LPSINT lpCount)
|
||
|
{
|
||
|
lpcpTagList lpTL;
|
||
|
if (lpCount == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
lpTL = (lpcpTagList) &(((lpcpProfile)CP)->count);
|
||
|
*lpCount = ui32toSINT(lpTL->count);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL EXTERN GetCPElementInfo(CHANDLE CP, SINT Index,
|
||
|
LPMEMPTR lpTagData, LPMEMPTR lpElemData)
|
||
|
{
|
||
|
SINT Count;
|
||
|
lpcpTagList lpTL;
|
||
|
|
||
|
if ( (lpTagData == NULL) || (lpElemData == NULL) )
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
lpTL = (lpcpTagList) &(((lpcpProfile)CP)->count);
|
||
|
Count = ui32toSINT(lpTL->count);
|
||
|
if ( Count <= Index )
|
||
|
{
|
||
|
SetCPLastError(CP_OUT_OF_RANGE_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpTagData = ((MEMPTR) &(lpTL->tags[0])) + (Index * sizeof(icTag)) ;
|
||
|
*lpElemData = ((MEMPTR) CP) +
|
||
|
ui32toSINT( ((lpcpTag)*lpTagData)->offset);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Checks if the profile has all required fields for
|
||
|
this specific type of the color profile */
|
||
|
BOOL EXTERN ValidateCP(CHANDLE CP)
|
||
|
{
|
||
|
BOOL Result;
|
||
|
CSIG ProfileClass;
|
||
|
|
||
|
if(GetCPClass(CP, (LPCSIG) &ProfileClass) )
|
||
|
{
|
||
|
// All profiles must have a ProfileDescription and
|
||
|
// a Copyright tags.
|
||
|
|
||
|
if( !DoesCPTagExist(CP, icSigProfileDescriptionTag) ||
|
||
|
!DoesCPTagExist(CP, icSigCopyrightTag ) )
|
||
|
{
|
||
|
SetCPLastError(CP_NOT_FOUND_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
// All profiles, except Device-link, must have a mediaWhitePoint Tag
|
||
|
switch( ProfileClass )
|
||
|
{
|
||
|
case icSigLinkClass : /* 'link' */
|
||
|
if( DoesCPTagExist(CP, icSigAToB0Tag) &&
|
||
|
DoesCPTagExist(CP, icSigProfileSequenceDescTag)
|
||
|
)
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case icSigInputClass: /* 'scnr' */
|
||
|
if( DoesCPTagExist(CP, icSigGrayTRCTag) ||
|
||
|
DoesCPTagExist(CP, icSigAToB0Tag) )
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else if( DoesCPTagExist(CP, icSigGreenColorantTag) )
|
||
|
{
|
||
|
if( DoesCPTagExist(CP, icSigRedColorantTag) &&
|
||
|
DoesCPTagExist(CP, icSigBlueColorantTag) &&
|
||
|
DoesCPTagExist(CP, icSigRedTRCTag) &&
|
||
|
DoesCPTagExist(CP, icSigGreenTRCTag) &&
|
||
|
DoesCPTagExist(CP, icSigBlueTRCTag)
|
||
|
)
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
Result &= DoesCPTagExist(CP, icSigMediaWhitePointTag);
|
||
|
break;
|
||
|
|
||
|
case icSigDisplayClass: /* 'mntr' */
|
||
|
if( DoesCPTagExist(CP, icSigGrayTRCTag) )
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else if( DoesCPTagExist(CP, icSigGreenColorantTag) )
|
||
|
{
|
||
|
if( DoesCPTagExist(CP, icSigRedColorantTag) &&
|
||
|
DoesCPTagExist(CP, icSigBlueColorantTag) &&
|
||
|
DoesCPTagExist(CP, icSigRedTRCTag) &&
|
||
|
DoesCPTagExist(CP, icSigGreenTRCTag) &&
|
||
|
DoesCPTagExist(CP, icSigBlueTRCTag)
|
||
|
)
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
Result &= DoesCPTagExist(CP, icSigMediaWhitePointTag);
|
||
|
break;
|
||
|
|
||
|
case icSigOutputClass: /* 'prtr' */
|
||
|
if( DoesCPTagExist(CP, icSigGrayTRCTag) )
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else if( DoesCPTagExist(CP, icSigAToB0Tag) &&
|
||
|
DoesCPTagExist(CP, icSigAToB1Tag) &&
|
||
|
DoesCPTagExist(CP, icSigAToB2Tag) &&
|
||
|
DoesCPTagExist(CP, icSigBToA0Tag) &&
|
||
|
DoesCPTagExist(CP, icSigBToA1Tag) &&
|
||
|
DoesCPTagExist(CP, icSigBToA2Tag) &&
|
||
|
DoesCPTagExist(CP, icSigGamutTag)
|
||
|
)
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
Result &= DoesCPTagExist(CP, icSigMediaWhitePointTag);
|
||
|
break;
|
||
|
|
||
|
case icSigAbstractClass: /* 'abst' */
|
||
|
if( DoesCPTagExist(CP, icSigAToB0Tag) )
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
Result &= DoesCPTagExist(CP, icSigMediaWhitePointTag);
|
||
|
break;
|
||
|
|
||
|
case icSigColorSpaceClass: /* 'spac' */
|
||
|
if( DoesCPTagExist(CP, icSigAToB0Tag) &&
|
||
|
DoesCPTagExist(CP, icSigBToA0Tag)
|
||
|
)
|
||
|
{
|
||
|
Result = TRUE;
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
Result &= DoesCPTagExist(CP, icSigMediaWhitePointTag);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Result = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
}else
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
if( Result == FALSE )
|
||
|
{
|
||
|
SetCPLastError(CP_NOT_FOUND_ERR);
|
||
|
}
|
||
|
return(Result);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN DoesCPTagExist(CHANDLE CP, CSIG CPTag)
|
||
|
{
|
||
|
SINT Count;
|
||
|
MEMPTR Data;
|
||
|
lpcpTagList lpTL;
|
||
|
|
||
|
lpTL = (lpcpTagList) &(((lpcpProfile)CP)->count);
|
||
|
Count = ui32toSINT(lpTL->count);
|
||
|
Data = (MEMPTR) &(lpTL->tags[0]) ;
|
||
|
while ( Count-- )
|
||
|
{
|
||
|
if( SigtoCSIG( ((lpcpTag)Data)->sig) == CPTag )
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}else
|
||
|
{
|
||
|
Data += sizeof(icTag); // Bump pointer to the next tag
|
||
|
}
|
||
|
}
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL EXTERN GetCPTagIndex(CHANDLE CP, CSIG CPTag, LPSINT lpIndex)
|
||
|
{
|
||
|
SINT Count;
|
||
|
MEMPTR Data;
|
||
|
SINT i;
|
||
|
lpcpTagList lpTL;
|
||
|
|
||
|
if (lpIndex == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
lpTL = (lpcpTagList) &(((lpcpProfile)CP)->count);
|
||
|
Count = ui32toSINT(lpTL->count);
|
||
|
Data = (MEMPTR) &(lpTL->tags[0]) ;
|
||
|
|
||
|
for (i = 0; i < Count; i++ )
|
||
|
{
|
||
|
if( SigtoCSIG( ((lpcpTag)Data)->sig) == CPTag )
|
||
|
{
|
||
|
*lpIndex = i;
|
||
|
return(TRUE);
|
||
|
}else
|
||
|
{
|
||
|
Data += sizeof(icTag); // Bump pointer to the next tag
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetCPLastError(CP_NOT_FOUND_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL EXTERN GetCPTagSig(CHANDLE CP, SINT Index, LPCSIG lpCPTag)
|
||
|
{
|
||
|
MEMPTR TagData, ElemData;
|
||
|
if (lpCPTag == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
if ( GetCPElementInfo(CP, Index, (LPMEMPTR) &TagData,
|
||
|
(LPMEMPTR) &ElemData) )
|
||
|
{
|
||
|
*lpCPTag = SigtoCSIG( ((lpcpTag)TagData)->sig ) ;
|
||
|
}else
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Function applicable to the elements
|
||
|
|
||
|
|
||
|
|
||
|
BOOL EXTERN GetCPElementType(CHANDLE CP, SINT Index, LPCSIG lpCSig)
|
||
|
{
|
||
|
MEMPTR TagData, ElemData;
|
||
|
if ( GetCPElementInfo(CP, Index, (LPMEMPTR) &TagData,
|
||
|
(LPMEMPTR) &ElemData) )
|
||
|
{
|
||
|
*lpCSig = SigtoCSIG( ((lpcpTagBase)ElemData)->sig ) ;
|
||
|
}else
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL EXTERN GetCPElementSize(CHANDLE CP, SINT Index, LPSINT lpSize)
|
||
|
{
|
||
|
MEMPTR TagData, ElemData;
|
||
|
if (lpSize == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if ( GetCPElementInfo(CP, Index, (LPMEMPTR) &TagData,
|
||
|
(LPMEMPTR) &ElemData) )
|
||
|
{
|
||
|
*lpSize = ui32toSINT( ((lpcpTag)TagData)->size );
|
||
|
}else
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPElementDataSize(CHANDLE CP, SINT Index, LPSINT lpSize)
|
||
|
{
|
||
|
MEMPTR TagData, ElemData;
|
||
|
if (lpSize == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if ( GetCPElementInfo(CP, Index, (LPMEMPTR) &TagData,
|
||
|
(LPMEMPTR) &ElemData) )
|
||
|
{
|
||
|
// Changed by jjia 8/24/95
|
||
|
// *lpSize = ui32toSINT( ((lpcpTag)TagData)->size ) -
|
||
|
// sizeof(lpcpTagBase);
|
||
|
*lpSize = ui32toSINT( ((lpcpTag)TagData)->size) -
|
||
|
sizeof(icTagBase) - sizeof(icUInt32Number);
|
||
|
}else
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
// The difference between GetCPElement and GetCPElementData
|
||
|
// is that GetCPElement reads all fields of the element,
|
||
|
// including the data tag, reserved fields and element data,
|
||
|
// while GetCPElementData only reads the actual data.
|
||
|
// Number of bytes that are required to hold the whole data element can be
|
||
|
// obtained by calling the function GetCPElementSize().
|
||
|
// The actulal number of data bytes is determined by
|
||
|
// the call to GetCPElementDataSize().
|
||
|
|
||
|
BOOL EXTERN GetCPElement(CHANDLE CP, SINT Index,
|
||
|
MEMPTR lpData, SINT Size)
|
||
|
{
|
||
|
SINT ElemSize;
|
||
|
MEMPTR TagData, ElemData;
|
||
|
if (lpData == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if ( !GetCPElementInfo(CP, Index, (LPMEMPTR) &TagData,
|
||
|
(LPMEMPTR) &ElemData) )
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
ElemSize = ui32toSINT( ((lpcpTag)TagData)->size);
|
||
|
if(ElemSize > Size )
|
||
|
{
|
||
|
SetCPLastError(CP_NO_MEMORY_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
MemCopy(lpData, ElemData, ElemSize);
|
||
|
return(TRUE);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL EXTERN GetCPElementData(CHANDLE CP, SINT Index,
|
||
|
MEMPTR lpData, SINT Size)
|
||
|
{
|
||
|
SINT ElemSize;
|
||
|
MEMPTR TagData, ElemData;
|
||
|
if (lpData == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if ( !GetCPElementInfo(CP, Index, (LPMEMPTR) &TagData,
|
||
|
(LPMEMPTR) &ElemData) )
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
// Changed by jjia 8/24/95
|
||
|
// ElemData += sizeof(lpcpTagBase);
|
||
|
// ElemSize = ui32toSINT( ((lpcpTag)TagData)->size) -
|
||
|
// sizeof(lpcpTagBase);
|
||
|
ElemData += sizeof(icTagBase) + sizeof(icUInt32Number);
|
||
|
ElemSize = ui32toSINT( ((lpcpTag)TagData)->size) -
|
||
|
sizeof(icTagBase) - sizeof(icUInt32Number);
|
||
|
|
||
|
if(ElemSize > Size )
|
||
|
{
|
||
|
SetCPLastError(CP_NO_MEMORY_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
MemCopy(lpData, ElemData, ElemSize);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
// Check the data format is binary or ascii 8/22/95 jjia
|
||
|
|
||
|
BOOL EXTERN GetCPElementDataType(CHANDLE CP, SINT Index, long far *lpDataType)
|
||
|
{
|
||
|
MEMPTR TagData, ElemData;
|
||
|
|
||
|
if (lpDataType == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if ( !GetCPElementInfo(CP, Index, (LPMEMPTR) &TagData,
|
||
|
(LPMEMPTR) &ElemData) )
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
ElemData += sizeof(icTagBase);
|
||
|
*lpDataType = ui32toSINT( ((icData __huge *)ElemData)->dataFlag);
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN ValidateCPElement(CHANDLE CP, SINT Index)
|
||
|
{
|
||
|
CSIG TagSig, DataSig;
|
||
|
BOOL Result;
|
||
|
if( GetCPTagSig(CP, Index, (LPCSIG) &TagSig) &&
|
||
|
GetCPElementType(CP, Index, (LPCSIG) &DataSig) )
|
||
|
{
|
||
|
switch(TagSig)
|
||
|
{
|
||
|
case icSigAToB0Tag:
|
||
|
case icSigAToB1Tag:
|
||
|
case icSigAToB2Tag:
|
||
|
case icSigBToA0Tag:
|
||
|
case icSigBToA1Tag:
|
||
|
case icSigBToA2Tag:
|
||
|
case icSigGamutTag:
|
||
|
case icSigPreview0Tag:
|
||
|
case icSigPreview1Tag:
|
||
|
case icSigPreview2Tag:
|
||
|
Result = (DataSig == icSigLut16Type) ||
|
||
|
(DataSig == icSigLut8Type) ;
|
||
|
break;
|
||
|
|
||
|
case icSigRedColorantTag:
|
||
|
case icSigGreenColorantTag:
|
||
|
case icSigBlueColorantTag:
|
||
|
case icSigLuminanceTag:
|
||
|
case icSigMediaBlackPointTag:
|
||
|
case icSigMediaWhitePointTag:
|
||
|
Result = (DataSig == icSigXYZType);
|
||
|
break;
|
||
|
|
||
|
case icSigRedTRCTag:
|
||
|
case icSigGreenTRCTag:
|
||
|
case icSigBlueTRCTag:
|
||
|
case icSigGrayTRCTag:
|
||
|
Result = (DataSig == icSigCurveType);
|
||
|
break;
|
||
|
|
||
|
case icSigPs2CRD0Tag:
|
||
|
case icSigPs2CRD1Tag:
|
||
|
case icSigPs2CRD2Tag:
|
||
|
case icSigPs2CRD3Tag:
|
||
|
case icSigPs2CSATag:
|
||
|
case icSigPs2Intent0Tag:
|
||
|
case icSigPs2Intent1Tag:
|
||
|
case icSigPs2Intent2Tag:
|
||
|
case icSigPs2Intent3Tag:
|
||
|
Result = (DataSig == icSigDataType);
|
||
|
break;
|
||
|
|
||
|
case icSigCharTargetTag:
|
||
|
case icSigCopyrightTag:
|
||
|
Result = (DataSig == icSigTextType);
|
||
|
break;
|
||
|
|
||
|
case icSigCalibrationDateTimeTag:
|
||
|
Result = (DataSig == icSigDateTimeType);
|
||
|
break;
|
||
|
|
||
|
case icSigDeviceMfgDescTag:
|
||
|
case icSigDeviceModelDescTag:
|
||
|
case icSigProfileDescriptionTag:
|
||
|
case icSigScreeningDescTag:
|
||
|
case icSigViewingCondDescTag:
|
||
|
Result = (DataSig == icSigTextDescriptionType);
|
||
|
break;
|
||
|
|
||
|
case icSigMeasurementTag:
|
||
|
Result = (DataSig == icSigMeasurementTag);
|
||
|
break;
|
||
|
|
||
|
case icSigNamedColorTag:
|
||
|
Result = (DataSig == icSigNamedColorTag);
|
||
|
break;
|
||
|
|
||
|
case icSigProfileSequenceDescTag:
|
||
|
Result = (DataSig == icSigProfileSequenceDescTag);
|
||
|
break;
|
||
|
|
||
|
case icSigScreeningTag:
|
||
|
Result = (DataSig == icSigScreeningTag);
|
||
|
break;
|
||
|
|
||
|
case icSigTechnologyTag:
|
||
|
Result = (DataSig == icSigSignatureType);
|
||
|
break;
|
||
|
|
||
|
case icSigUcrBgTag:
|
||
|
Result = (DataSig == icSigUcrBgTag);
|
||
|
break;
|
||
|
|
||
|
case icSigViewingConditionsTag:
|
||
|
Result = (DataSig == icSigViewingConditionsTag);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Result = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}else
|
||
|
{
|
||
|
Result = FALSE;
|
||
|
}
|
||
|
return(Result);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Functions that get all information from the Color Profile Header
|
||
|
|
||
|
BOOL EXTERN GetCPSize(CHANDLE CP, LPSINT lpSize)
|
||
|
{
|
||
|
if (lpSize == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpSize = ui32toSINT( ((lpcpHeader)CP)->size);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPCMMType(CHANDLE CP, LPCSIG lpType)
|
||
|
{
|
||
|
if (lpType == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpType = SigtoCSIG( ((lpcpHeader)CP)->cmmId);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPVersion(CHANDLE CP, LPSINT lpVers)
|
||
|
{
|
||
|
if (lpVers == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpVers = ui32toSINT( ((lpcpHeader)CP)->version);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPClass(CHANDLE CP, LPCSIG lpClass)
|
||
|
{
|
||
|
if (lpClass == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpClass = SigtoCSIG( ((lpcpHeader)CP)->deviceClass);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPDevSpace(CHANDLE CP, LPCSIG lpInSpace)
|
||
|
{
|
||
|
if (lpInSpace == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpInSpace = SigtoCSIG( ((lpcpHeader)CP)->colorSpace);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPConnSpace(CHANDLE CP, LPCSIG lpOutSpace)
|
||
|
{
|
||
|
if (lpOutSpace == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpOutSpace = SigtoCSIG( ((lpcpHeader)CP)->pcs);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPTarget(CHANDLE CP, LPCSIG lpTarget)
|
||
|
{
|
||
|
if (lpTarget == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpTarget = SigtoCSIG( ((lpcpHeader)CP)->platform);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPManufacturer(CHANDLE CP, LPCSIG lpManuf)
|
||
|
{
|
||
|
if (lpManuf == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpManuf = SigtoCSIG( ((lpcpHeader)CP)->manufacturer);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPModel(CHANDLE CP, LPCSIG lpModel)
|
||
|
{
|
||
|
if (lpModel == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpModel = SigtoCSIG( ((lpcpHeader)CP)->model);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPFlags(CHANDLE CP, LPSINT lpFlags)
|
||
|
{
|
||
|
if (lpFlags == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpFlags = ui32toSINT( ((lpcpHeader)CP)->flags);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPRenderIntent(CHANDLE CP, LPSINT lpIntent)
|
||
|
{
|
||
|
if (lpIntent == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
*lpIntent = ui32toSINT( ((lpcpHeader)CP)->renderingIntent);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPWhitePoint(CHANDLE CP, LPSFLOAT lpWP)
|
||
|
{
|
||
|
if (lpWP == NULL)
|
||
|
{
|
||
|
SetCPLastError(CP_NULL_POINTER_ERR);
|
||
|
return(FALSE);
|
||
|
}
|
||
|
lpWP[0] = (SFLOAT) si16f16toSFLOAT( ((lpcpHeader)CP)->illuminant.X);
|
||
|
lpWP[1] = (SFLOAT) si16f16toSFLOAT( ((lpcpHeader)CP)->illuminant.Y);
|
||
|
lpWP[2] = (SFLOAT) si16f16toSFLOAT( ((lpcpHeader)CP)->illuminant.Z);
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPAttributes(CHANDLE CP, LPATTRIB lpAttributes)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
BOOL EXTERN GetCPMediaWhitePoint(CHANDLE cp, LPSFLOAT lpMediaWP)
|
||
|
{
|
||
|
HGLOBAL hTempMem;
|
||
|
SINT TempSize;
|
||
|
MEMPTR TempBuff;
|
||
|
MEMPTR lpTable;
|
||
|
SINT i, Index;
|
||
|
|
||
|
if (DoesCPTagExist (cp, icSigMediaWhitePointTag) &&
|
||
|
GetCPTagIndex (cp, icSigMediaWhitePointTag, (LPSINT) & Index) &&
|
||
|
GetCPElementSize (cp, Index, (LPSINT) & TempSize) &&
|
||
|
MemAlloc (TempSize, (HGLOBAL *) & hTempMem, (LPMEMPTR) & TempBuff) &&
|
||
|
GetCPElement (cp, Index, TempBuff, TempSize))
|
||
|
{
|
||
|
lpTable = (MEMPTR) & (((lpcpXYZType) TempBuff)->data);
|
||
|
for (i = 0; i < 3; i++)
|
||
|
{
|
||
|
lpMediaWP[i] = (SFLOAT) si16f16toSFLOAT (lpTable);
|
||
|
lpTable += sizeof (icS15Fixed16Number);
|
||
|
}
|
||
|
MemFree (hTempMem);
|
||
|
return (TRUE);
|
||
|
}
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* GetPS2ColorRenderingIntent
|
||
|
* function:
|
||
|
* this is the function which creates the Intent string
|
||
|
* from the data supplied in the Profile that can be used
|
||
|
* in --findcolorrendering-- operator.
|
||
|
* prototype:
|
||
|
* BOOL EXTERN GetPS2ColorRenderingIntent(
|
||
|
* char *FileName,
|
||
|
* DWORD Intent,
|
||
|
* MEMPTR lpMem,
|
||
|
* LPDWORD lpcbSize )
|
||
|
* parameters:
|
||
|
* FileName -- Color Profile Filename
|
||
|
* Intent -- Intent
|
||
|
* lpMem -- Pointer to the memory block
|
||
|
* lpcbSize -- Size of the memory block
|
||
|
* Returns number of bytes required/transferred
|
||
|
* returns:
|
||
|
* BOOL -- TRUE if the function was successful,
|
||
|
* FALSE otherwise.
|
||
|
*/
|
||
|
BOOL EXTERN GetPS2ColorRenderingIntent(CHANDLE cp, DWORD Intent,
|
||
|
MEMPTR lpMem, LPDWORD lpcbSize)
|
||
|
{
|
||
|
SINT Index;
|
||
|
SINT Size;
|
||
|
|
||
|
if (!cp)
|
||
|
return FALSE;
|
||
|
|
||
|
Size = (SINT) *lpcbSize;
|
||
|
if( ( lpMem == NULL ) || ( Size == 0 ) )
|
||
|
{
|
||
|
lpMem = NULL;
|
||
|
Size = 0;
|
||
|
*lpcbSize = 0;
|
||
|
}
|
||
|
|
||
|
switch(Intent)
|
||
|
{
|
||
|
case icPerceptual:
|
||
|
if( DoesCPTagExist(cp, icSigPs2Intent0Tag) &&
|
||
|
GetCPTagIndex(cp, icSigPs2Intent0Tag, (LPSINT) &Index) &&
|
||
|
GetCPElementDataSize(cp, Index, (LPSINT) &Size) &&
|
||
|
( ( lpMem == NULL ) ||
|
||
|
GetCPElementData(cp, Index, lpMem, Size) ) )
|
||
|
{
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case icRelativeColorimetric:
|
||
|
if( DoesCPTagExist(cp, icSigPs2Intent1Tag) &&
|
||
|
GetCPTagIndex(cp, icSigPs2Intent1Tag, (LPSINT) &Index) &&
|
||
|
GetCPElementDataSize(cp, Index, (LPSINT) &Size) &&
|
||
|
( ( lpMem == NULL ) ||
|
||
|
GetCPElementData(cp, Index, lpMem, Size) ) )
|
||
|
{
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case icSaturation:
|
||
|
if( DoesCPTagExist(cp, icSigPs2Intent2Tag) &&
|
||
|
GetCPTagIndex(cp, icSigPs2Intent2Tag, (LPSINT) &Index) &&
|
||
|
GetCPElementDataSize(cp, Index, (LPSINT) &Size) &&
|
||
|
( ( lpMem == NULL ) ||
|
||
|
GetCPElementData(cp, Index, lpMem, Size ) )
|
||
|
)
|
||
|
{
|
||
|
}
|
||
|
break;
|
||
|
case icAbsoluteColorimetric:
|
||
|
if( DoesCPTagExist(cp, icSigPs2Intent3Tag) &&
|
||
|
GetCPTagIndex(cp, icSigPs2Intent3Tag, (LPSINT) &Index) &&
|
||
|
GetCPElementDataSize(cp, Index, (LPSINT) &Size) &&
|
||
|
( ( lpMem == NULL ) ||
|
||
|
GetCPElementData(cp, Index, lpMem, Size) ) )
|
||
|
{
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
Size = 0 ;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (Size != 0)
|
||
|
{
|
||
|
if (lpMem)
|
||
|
{
|
||
|
lpMem[Size] = '\0';
|
||
|
}
|
||
|
Size ++;
|
||
|
*lpcbSize = (DWORD) Size;
|
||
|
return (TRUE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to check if color matching mathod and icc profile type is
|
||
|
* supported by driver.
|
||
|
* parameters:
|
||
|
|
||
|
* returns:
|
||
|
* BOOL: TRUE or FALSE.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#ifndef ICMDLL
|
||
|
BOOL EXTERN ValidColorSpace(LPPDEVICE lppd, LPICMINFO lpICMI, LPCSIG lpDevCS )
|
||
|
{
|
||
|
icHeader CPHeader;
|
||
|
HFILE hFile;
|
||
|
SINT Res;
|
||
|
CSIG CPColorSpaceTag;
|
||
|
|
||
|
if (NULL == lpICMI)
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
hFile = _lopen(lpICMI->lcsDestFilename, READ);
|
||
|
if( hFile == HFILE_ERROR )
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
Res = _lread(hFile, (LPVOID) &CPHeader, sizeof(CPHeader));
|
||
|
_lclose(hFile);
|
||
|
if( (Res == HFILE_ERROR) || (Res != sizeof(CPHeader)) )
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
// Make the initial check for validity of the profile
|
||
|
if( SigtoCSIG(CPHeader.magic) != icMagicNumber )
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
// Make sure the profile is 'prtr'
|
||
|
// SRGB98
|
||
|
// if( SigtoCSIG(CPHeader.deviceClass) != icSigOutputClass )
|
||
|
// {
|
||
|
// return(FALSE);
|
||
|
// }
|
||
|
CPColorSpaceTag = SigtoCSIG(CPHeader.colorSpace);
|
||
|
*lpDevCS = CPColorSpaceTag; // 247974
|
||
|
|
||
|
switch ( lppd->lpPSExtDevmode->dm.iColorMatchingMethod )
|
||
|
{
|
||
|
case COLOR_MATCHING_ON_HOST:
|
||
|
if ((CPColorSpaceTag == icSigCmyData))
|
||
|
// (CPColorSpaceTag == icSigRgbData))
|
||
|
// (CPColorSpaceTag == icSigGrayData))
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
break;
|
||
|
case COLOR_MATCHING_ON_PRINTER:
|
||
|
if ((CPColorSpaceTag == icSigCmyData))
|
||
|
// (CPColorSpaceTag == icSigGrayData))
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
break;
|
||
|
case COLOR_MATCHING_PRINTER_CALIBRATION:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return (TRUE);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
// Set of functions to output data into memory buffer
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to put the chunk of memory as string of Hex
|
||
|
|
||
|
*/
|
||
|
SINT WriteHexBuffer(MEMPTR lpMem, MEMPTR lpBuff, MEMPTR lpLineStart, DWORD dwBytes)
|
||
|
{
|
||
|
SINT Res;
|
||
|
char TempArray[TempBfSize];
|
||
|
MEMPTR lpOldPtr = lpMem;
|
||
|
|
||
|
for ( ; dwBytes ; dwBytes-- )
|
||
|
{
|
||
|
Res = wsprintf( (MEMPTR)TempArray, (LPSTR) "%2.2x", *lpBuff );
|
||
|
*lpMem++ = TempArray[0];
|
||
|
*lpMem++ = TempArray[1];
|
||
|
lpBuff++;
|
||
|
if (((SINT)(lpMem - lpLineStart)) > MAX_LINELENG)
|
||
|
{
|
||
|
lpLineStart = lpMem;
|
||
|
lpMem += WriteObject(lpMem, NewLine);
|
||
|
}
|
||
|
}
|
||
|
return( (SINT)(lpMem - lpOldPtr));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to put the string into the buffer
|
||
|
|
||
|
*/
|
||
|
SINT WriteNewLineObject(MEMPTR lpMem, MEMPTR Obj)
|
||
|
{
|
||
|
SINT Res1, Res2;
|
||
|
|
||
|
Res1 = lstrlen(NewLine);
|
||
|
MemCopy(lpMem, NewLine, Res1);
|
||
|
|
||
|
lpMem += Res1;
|
||
|
Res2 = lstrlen(Obj);
|
||
|
MemCopy(lpMem, Obj, Res2);
|
||
|
return( Res1 + Res2 );
|
||
|
}
|
||
|
|
||
|
SINT WriteObject(MEMPTR lpMem, MEMPTR Obj)
|
||
|
{
|
||
|
SINT Res;
|
||
|
|
||
|
Res = lstrlen(Obj);
|
||
|
MemCopy(lpMem, Obj, Res);
|
||
|
return( Res );
|
||
|
}
|
||
|
|
||
|
SINT WriteObjectN(MEMPTR lpMem, MEMPTR Obj, SINT n)
|
||
|
{
|
||
|
MemCopy(lpMem, Obj, n);
|
||
|
return( n );
|
||
|
}
|
||
|
/*
|
||
|
|
||
|
* Function to write the integer into the buffer
|
||
|
|
||
|
*/
|
||
|
SINT WriteInt(MEMPTR lpMem, SINT Number)
|
||
|
{
|
||
|
SINT Res;
|
||
|
char TempArray[TempBfSize];
|
||
|
|
||
|
Res = wsprintf( (MEMPTR)TempArray, "%lu ", Number );
|
||
|
MemCopy(lpMem, TempArray, lstrlen(TempArray));
|
||
|
return( Res );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to write the integer into the buffer as hex
|
||
|
|
||
|
*/
|
||
|
SINT WriteHex(MEMPTR lpMem, SINT Number)
|
||
|
{
|
||
|
SINT Res;
|
||
|
char TempArray[TempBfSize];
|
||
|
|
||
|
Res = wsprintf( TempArray, "%2.2x", (int)(Number & 0x00FF) );
|
||
|
MemCopy(lpMem, TempArray, lstrlen(TempArray));
|
||
|
return( Res );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to write the float into the buffer
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT WriteFloat(MEMPTR lpMem, double dFloat)
|
||
|
{
|
||
|
char cSign;
|
||
|
double dInt ;
|
||
|
double dFract ;
|
||
|
LONG lFloat ;
|
||
|
SINT Res;
|
||
|
char TempArray[TempBfSize];
|
||
|
|
||
|
lFloat = (LONG) floor( dFloat * 10000.0 + 0.5);
|
||
|
|
||
|
dFloat = lFloat / 10000.0 ;
|
||
|
|
||
|
dInt = floor(fabs(dFloat));
|
||
|
dFract = fabs(dFloat) - dInt ;
|
||
|
|
||
|
cSign = ' ' ;
|
||
|
if ( dFloat < 0 )
|
||
|
{
|
||
|
cSign = '-' ;
|
||
|
}
|
||
|
|
||
|
Res = wsprintf( (LPSTR) TempArray, (LPSTR) "%c%d.%0.4lu ",
|
||
|
cSign, (WORD) dInt , (DWORD) (dFract *10000.0) );
|
||
|
MemCopy(lpMem, TempArray, lstrlen(TempArray));
|
||
|
return ( Res );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to write the string token into the buffer
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT WriteStringToken(MEMPTR lpMem, BYTE Token, SINT sNum)
|
||
|
{
|
||
|
*lpMem++ = Token;
|
||
|
*lpMem++ = (BYTE)((sNum & 0xFF00) >> 8);
|
||
|
*lpMem++ = (BYTE)(sNum & 0x00FF);
|
||
|
return (3);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to write the Homogeneous Number Array token into the buffer
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT WriteHNAToken(MEMPTR lpMem, BYTE Token, SINT sNum)
|
||
|
{
|
||
|
*lpMem++ = Token;
|
||
|
*lpMem++ = 32; // 16-bit fixed integer, high-order byte first
|
||
|
*lpMem++ = (BYTE)((sNum & 0xFF00) >> 8);
|
||
|
*lpMem++ = (BYTE)(sNum & 0x00FF);
|
||
|
return (4);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to convert 2-bytes unsigned integer to 2-bytes signed
|
||
|
* integer(-32768) and write them to the buffer. High byte first.
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT WriteIntStringU2S(MEMPTR lpMem, MEMPTR lpBuff, SINT sNum)
|
||
|
{
|
||
|
SINT i;
|
||
|
SINT Temp;
|
||
|
|
||
|
for (i = 0; i < sNum; i ++)
|
||
|
{
|
||
|
Temp = ui16toSINT( lpBuff) - 32768;
|
||
|
*lpMem++ = (BYTE)((Temp & 0xFF00) >> 8);
|
||
|
*lpMem++ = (BYTE)(Temp & 0x00FF);
|
||
|
lpBuff += sizeof(icUInt16Number);
|
||
|
}
|
||
|
return(sNum * 2);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to convert 2-bytes unsigned integer to 2-bytes signed
|
||
|
* integer(-32768) and write them to the buffer. Low-order byte first.
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT WriteIntStringU2S_L(MEMPTR lpMem, MEMPTR lpBuff, SINT sNum)
|
||
|
{
|
||
|
SINT i;
|
||
|
SINT Temp;
|
||
|
|
||
|
for (i = 0; i < sNum; i ++)
|
||
|
{
|
||
|
Temp = (SINT)*((PUSHORT)lpBuff) - 32768;
|
||
|
*lpMem++ = (BYTE)((Temp & 0xFF00) >> 8);
|
||
|
*lpMem++ = (BYTE)(Temp & 0x00FF);
|
||
|
lpBuff += sizeof(icUInt16Number);
|
||
|
}
|
||
|
return(sNum * 2);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to put the chunk of memory into buffer
|
||
|
|
||
|
*/
|
||
|
SINT WriteByteString(MEMPTR lpMem, MEMPTR lpBuff, SINT sBytes)
|
||
|
{
|
||
|
SINT i;
|
||
|
|
||
|
for (i = 0; i < sBytes; i ++)
|
||
|
*lpMem++ = *lpBuff++;
|
||
|
|
||
|
return(sBytes);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to put the chunk of memory into buffer
|
||
|
|
||
|
*/
|
||
|
SINT WriteInt2ByteString(MEMPTR lpMem, MEMPTR lpBuff, SINT sBytes)
|
||
|
{
|
||
|
SINT i;
|
||
|
|
||
|
for( i = 0; i < sBytes ; i++)
|
||
|
{
|
||
|
*lpMem++ = (BYTE)(ui16toSINT( lpBuff)/256) ;
|
||
|
lpBuff += sizeof(icUInt16Number);
|
||
|
}
|
||
|
return(sBytes);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to control ascii85 encoding.
|
||
|
* parameters:
|
||
|
* lpDest -- Pointer to the encording result buffer.
|
||
|
* BufSize -- Size of encording result buffer.
|
||
|
* lpSource -- Pointer to the input buffer
|
||
|
* DataSize -- Size of the input buffer
|
||
|
* returns:
|
||
|
* SINT -- Number of bytes actually outputed.
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT WriteASCII85Cont(MEMPTR lpDest, SINT BufSize, MEMPTR lpSource, SINT DataSize)
|
||
|
{
|
||
|
SINT incount;
|
||
|
MEMPTR lpPtr, lpSave;
|
||
|
SINT rem;
|
||
|
SINT bcount;
|
||
|
SINT dex;
|
||
|
unsigned long word;
|
||
|
|
||
|
/* encode the initial 4-tuples */
|
||
|
lpSave = lpDest;
|
||
|
lpPtr = lpSource;
|
||
|
word = 0UL;
|
||
|
bcount = 0;
|
||
|
|
||
|
for (incount = 0; incount < DataSize; incount ++)
|
||
|
{
|
||
|
if ( incount && ((incount % LINELENG) == 0) )
|
||
|
lpDest += WriteObject(lpDest, NewLine);
|
||
|
word = (word<<8);
|
||
|
word |= (BYTE)*lpPtr++;
|
||
|
if (bcount == 3)
|
||
|
{
|
||
|
lpDest += WriteAscii85(lpDest, word, 5);
|
||
|
word = 0UL;
|
||
|
bcount = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bcount ++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* now do the last partial 4-tuple -- if there is one */
|
||
|
/* see the Red Book spec for the rules on how this is done */
|
||
|
if (bcount > 0)
|
||
|
{
|
||
|
rem = 4 - bcount; /* count the remaining bytes */
|
||
|
for (dex = 0; dex < rem; dex ++) /* shift left for each of them */
|
||
|
{
|
||
|
word = (word<<8); /* (equivalent to adding in ZERO's)*/
|
||
|
word |= (BYTE)32;
|
||
|
}
|
||
|
// lpDest += WriteAscii85(lpDest, word, (bcount + 1)); /* output only meaningful
|
||
|
lpDest += WriteAscii85(lpDest, word, 5); /* output only meaningful bytes + 1 */
|
||
|
}
|
||
|
return (lpDest - lpSave);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to convert 4 bytes binary data to 5 bytes ascii85 encorded data.
|
||
|
* parameters:
|
||
|
* lpDest -- Pointer to the encording result buffer.
|
||
|
* inWord -- Input word (4-bytes)
|
||
|
* nBytes -- Number of bytes should be outputed.
|
||
|
* returns:
|
||
|
* SINT -- Number of bytes actually outputed.
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT WriteAscii85(MEMPTR lpDest, unsigned long inWord, SINT nBytes)
|
||
|
{
|
||
|
unsigned long divisor;
|
||
|
int bcount;
|
||
|
BYTE outchar;
|
||
|
MEMPTR lpSave = lpDest;
|
||
|
|
||
|
if ((inWord == 0UL) && (nBytes == 5))
|
||
|
*lpDest++ = 'z';
|
||
|
else
|
||
|
{
|
||
|
divisor = 52200625UL;
|
||
|
for (bcount = 0; bcount < nBytes; bcount ++)
|
||
|
{
|
||
|
outchar = (BYTE)((int)(inWord/divisor) + (int)'!');
|
||
|
*lpDest++ = outchar;
|
||
|
if (bcount < 4)
|
||
|
{
|
||
|
inWord = (inWord % divisor);
|
||
|
divisor =(divisor / 85);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return (SINT)(lpDest - lpSave);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to convert binary data to ascii by performing ASCII85 encording
|
||
|
* parameters:
|
||
|
* lpMem -- A pointer to the buffer.
|
||
|
* as input: contains binary data;
|
||
|
* as output: contains ascii data.
|
||
|
* DataSize -- The size of input binary data.
|
||
|
* BufSize -- The size of buffer pointed by lpMem.
|
||
|
* returns:
|
||
|
* SINT -- Number of bytes actually outputed.
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT ConvertBinaryData2Ascii(MEMPTR lpMem, SINT DataSize, SINT BufSize)
|
||
|
{
|
||
|
MEMPTR intrbuf, Temp;
|
||
|
HANDLE intrhandle;
|
||
|
SINT AsciiDataSize = 0;
|
||
|
|
||
|
if (BufSize >= (SINT)(DataSize/4*5 + sizeof(ASCII85DecodeBegine)+sizeof(ASCII85DecodeEnd) + 2048))
|
||
|
{
|
||
|
if ((intrhandle = GlobalAlloc(GHND, BufSize)) != NULL)
|
||
|
{
|
||
|
if ((intrbuf = (MEMPTR) GlobalLock(intrhandle)) != NULL)
|
||
|
{
|
||
|
Temp = intrbuf;
|
||
|
Temp += WriteObject(Temp, NewLine);
|
||
|
Temp += WriteObject(Temp, ASCII85DecodeBegine);
|
||
|
Temp += WriteObject(Temp, NewLine);
|
||
|
Temp += WriteASCII85Cont(Temp, BufSize, lpMem, DataSize);
|
||
|
Temp += WriteObject(Temp, ASCII85DecodeEnd);
|
||
|
AsciiDataSize = (SINT)(Temp - intrbuf);
|
||
|
lstrcpyn(lpMem, intrbuf, (WORD)AsciiDataSize);
|
||
|
GlobalUnlock(intrhandle);
|
||
|
}
|
||
|
}
|
||
|
GlobalFree(intrhandle);
|
||
|
}
|
||
|
return (AsciiDataSize);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
|
||
|
* Function to check if it is need to convert a CRD from binary to ascii
|
||
|
* parameters:
|
||
|
* CP -- Handle of memory block which contains icm profile.
|
||
|
* Index -- Index of the element data of the profile.
|
||
|
* lpData -- A pointer to the buffer.
|
||
|
* as input: contains binary data;
|
||
|
* as output: contains ascii data.
|
||
|
* BufSize -- The size of the buffer pointed by lpData.
|
||
|
* DataSize -- The size of input binary data.
|
||
|
* AllowBinary -- Allow binary or not(1/0).
|
||
|
* returns:
|
||
|
* SINT -- Number of bytes required/actually outputed.
|
||
|
|
||
|
*/
|
||
|
|
||
|
SINT Convert2Ascii(CHANDLE CP, SINT Index,
|
||
|
MEMPTR lpData, SINT BufSize,
|
||
|
SINT DataSize, BOOL AllowBinary)
|
||
|
{
|
||
|
long DataType;
|
||
|
|
||
|
GetCPElementDataType(CP, Index, &DataType);
|
||
|
if (BufSize == 0)
|
||
|
{
|
||
|
if (AllowBinary)
|
||
|
return (DataSize);
|
||
|
else if (DataType == 0) // Ascii data in Profile
|
||
|
return (DataSize);
|
||
|
else // Keep space for ascii85 encoding.
|
||
|
return (DataSize / 4 * 5 + sizeof(ASCII85DecodeBegine)+sizeof(ASCII85DecodeEnd) + 2048);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (AllowBinary)
|
||
|
return (DataSize);
|
||
|
else if(DataType == 0)
|
||
|
return (DataSize);
|
||
|
else
|
||
|
return (ConvertBinaryData2Ascii(lpData, DataSize, BufSize) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifdef ICMDLL
|
||
|
SINT MemCopy(MEMPTR Dest, MEMPTR Source, SINT Length)
|
||
|
{
|
||
|
SINT i;
|
||
|
|
||
|
for (i = 0; i < Length; i++)
|
||
|
{
|
||
|
Dest[i] = Source[i];
|
||
|
}
|
||
|
return( Length );
|
||
|
}
|
||
|
|
||
|
// SRGB98
|
||
|
BOOL EXTERN InvertMatrix (double FAR * lpInMatrix,
|
||
|
double FAR * lpOutMatrix)
|
||
|
{
|
||
|
double det;
|
||
|
|
||
|
double FAR *a;
|
||
|
double FAR *b;
|
||
|
double FAR *c;
|
||
|
if ((NULL == lpInMatrix) ||
|
||
|
(NULL == lpOutMatrix))
|
||
|
{
|
||
|
return (FALSE);
|
||
|
}
|
||
|
a = (double FAR *) &(lpInMatrix[0]);
|
||
|
b = (double FAR *) &(lpInMatrix[3]);
|
||
|
c = (double FAR *) &(lpInMatrix[6]);
|
||
|
|
||
|
det = a[0] * b[1] * c[2] + a[1] * b[2] * c[0] + a[2] * b[0] * c[1] -
|
||
|
(a[2] * b[1] * c[0] + a[1] * b[0] * c[2] + a[0] * b[2] * c[1]);
|
||
|
|
||
|
if (det == 0.0) // What to do?
|
||
|
{
|
||
|
lpOutMatrix[0] = 1.0;
|
||
|
lpOutMatrix[1] = 0.0;
|
||
|
lpOutMatrix[2] = 0.0;
|
||
|
|
||
|
lpOutMatrix[3] = 0.0;
|
||
|
lpOutMatrix[4] = 1.0;
|
||
|
lpOutMatrix[5] = 0.0;
|
||
|
|
||
|
lpOutMatrix[6] = 0.0;
|
||
|
lpOutMatrix[7] = 0.0;
|
||
|
lpOutMatrix[8] = 1.0;
|
||
|
return (FALSE);
|
||
|
} else
|
||
|
{
|
||
|
lpOutMatrix[0] = (b[1] * c[2] - b[2] * c[1]) / det;
|
||
|
lpOutMatrix[3] = -(b[0] * c[2] - b[2] * c[0]) / det;
|
||
|
lpOutMatrix[6] = (b[0] * c[1] - b[1] * c[0]) / det;
|
||
|
|
||
|
lpOutMatrix[1] = -(a[1] * c[2] - a[2] * c[1]) / det;
|
||
|
lpOutMatrix[4] = (a[0] * c[2] - a[2] * c[0]) / det;
|
||
|
lpOutMatrix[7] = -(a[0] * c[1] - a[1] * c[0]) / det;
|
||
|
|
||
|
lpOutMatrix[2] = (a[1] * b[2] - a[2] * b[1]) / det;
|
||
|
lpOutMatrix[5] = -(a[0] * b[2] - a[2] * b[0]) / det;
|
||
|
lpOutMatrix[8] = (a[0] * b[1] - a[1] * b[0]) / det;
|
||
|
return (TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Crc - 32 BIT ANSI X3.66 CRC checksum files
|
||
|
|
||
|
|
||
|
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
|
||
|
* code or tables extracted from it, as desired without restriction.
|
||
|
*/
|
||
|
|
||
|
static DWORD crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
|
||
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||
|
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||
|
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||
|
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||
|
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||
|
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||
|
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||
|
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||
|
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||
|
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||
|
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||
|
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||
|
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||
|
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||
|
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||
|
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||
|
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||
|
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||
|
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||
|
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||
|
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||
|
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||
|
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||
|
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||
|
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||
|
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||
|
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||
|
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||
|
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||
|
};
|
||
|
|
||
|
DWORD FAR PASCAL crc32(MEMPTR buff, DWORD length)
|
||
|
{
|
||
|
DWORD crc, charcnt;
|
||
|
BYTE c;
|
||
|
|
||
|
|
||
|
crc = 0xFFFFFFFF;
|
||
|
charcnt = 0;
|
||
|
|
||
|
for (charcnt = 0 ; charcnt < length ; charcnt++)
|
||
|
{
|
||
|
c = buff[charcnt] ;
|
||
|
crc = crc_32_tab[(crc ^ c) & 0xff] ^ (crc >> 8);
|
||
|
}
|
||
|
|
||
|
return crc;
|
||
|
}
|
||
|
#endif
|
||
|
|