Windows2000/private/ntos/w32/ntgdi/icm/adobe/aug98/dll32/csprof.c
2020-09-30 17:12:32 +02:00

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