Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

color.c

Go to the documentation of this file.
00001 /****************************Module*Header******************************\ 00002 * Module Name: COLOR.C 00003 * 00004 * Module Descripton: Functions for color matching outside the DC 00005 * 00006 * Warnings: 00007 * 00008 * Issues: 00009 * 00010 * Public Routines: 00011 * 00012 * Created: 23 April 1996 00013 * Author: Srinivasan Chandrasekar [srinivac] 00014 * 00015 * Copyright (c) 1996, 1997 Microsoft Corporation 00016 \***********************************************************************/ 00017 00018 #include "mscms.h" 00019 #include "wingdip.h" /* for LCS_DEVICE_CMYK */ 00020 00021 // 00022 // Local functions 00023 // 00024 00025 HTRANSFORM InternalCreateColorTransform(LPLOGCOLORSPACE, HPROFILE, HPROFILE, DWORD); 00026 BOOL InternalRegisterCMM(PTSTR, DWORD, PTSTR); 00027 BOOL InternalUnregisterCMM(PTSTR, DWORD); 00028 DWORD GetBitmapBytes(BMFORMAT, DWORD, DWORD); 00029 00030 00031 /****************************************************************************** 00032 * 00033 * CreateColorTransform 00034 * 00035 * Function: 00036 * These are the ANSI & Unicode wrappers for InternalCreateColorTransform. 00037 * Please see InternalCreateColorTransform for more details on this 00038 * function. 00039 * 00040 * Arguments: 00041 * pLogColorSpace - pointer to LOGCOLORSPACE structure identifying 00042 * source color space 00043 * hDestProfile - handle identifing the destination profile object 00044 * hTargetProfile - handle identifing the target profile object 00045 * dwFlags - optimization flags 00046 * 00047 * Returns: 00048 * Handle to color transform if successful, NULL otherwise 00049 * 00050 ******************************************************************************/ 00051 00052 #ifdef UNICODE // Windows NT version 00053 00054 HTRANSFORM WINAPI CreateColorTransformA( 00055 LPLOGCOLORSPACEA pLogColorSpace, 00056 HPROFILE hDestProfile, 00057 HPROFILE hTargetProfile, 00058 DWORD dwFlags 00059 ) 00060 { 00061 LOGCOLORSPACEW wLCS; 00062 00063 TRACEAPI((__TEXT("CreateColorTransformA\n"))); 00064 00065 // 00066 // Validate parameter before we touch it 00067 // 00068 00069 if (IsBadReadPtr(pLogColorSpace, sizeof(LOGCOLORSPACEA))) 00070 { 00071 WARNING((__TEXT("Invalid parameter to CreateColorTransform\n"))); 00072 SetLastError(ERROR_INVALID_PARAMETER); 00073 return NULL; 00074 } 00075 00076 CopyMemory(&wLCS, pLogColorSpace, sizeof(LOGCOLORSPACEA)); 00077 wLCS.lcsSize = sizeof(LOGCOLORSPACEW); 00078 00079 // 00080 // Convert filename to Unicode and call the internal version 00081 // 00082 00083 if (! MultiByteToWideChar(CP_ACP, 0, pLogColorSpace->lcsFilename, -1, 00084 wLCS.lcsFilename, MAX_PATH)) 00085 { 00086 WARNING((__TEXT("Error converting LogColorSpace filename to Unicode\n"))); 00087 return NULL; 00088 } 00089 00090 return InternalCreateColorTransform(&wLCS, hDestProfile, hTargetProfile, dwFlags); 00091 } 00092 00093 00094 HTRANSFORM WINAPI CreateColorTransformW( 00095 LPLOGCOLORSPACEW pLogColorSpace, 00096 HPROFILE hDestProfile, 00097 HPROFILE hTargetProfile, 00098 DWORD dwFlags 00099 ) 00100 { 00101 TRACEAPI((__TEXT("CreateColorTransformW\n"))); 00102 00103 // 00104 // Internal version is Unicode in Windows NT, call it directly 00105 // 00106 00107 return InternalCreateColorTransform(pLogColorSpace, hDestProfile, hTargetProfile, dwFlags); 00108 } 00109 00110 #else // Windows 95 version 00111 00112 HTRANSFORM WINAPI CreateColorTransformA( 00113 LPLOGCOLORSPACEA pLogColorSpace, 00114 HPROFILE hDestProfile, 00115 HPROFILE hTargetProfile, 00116 DWORD dwFlags 00117 ) 00118 { 00119 TRACEAPI((__TEXT("CreateColorTransformA\n"))); 00120 00121 // 00122 // Internal version is ANSI in Windows 95, call it directly 00123 // 00124 00125 return InternalCreateColorTransform(pLogColorSpace, hDestProfile, hTargetProfile, dwFlags); 00126 } 00127 00128 00129 HTRANSFORM WINAPI CreateColorTransformW( 00130 LPLOGCOLORSPACEW pLogColorSpace, 00131 HPROFILE hDestProfile, 00132 HPROFILE hTargetProfile, 00133 DWORD dwFlags 00134 ) 00135 { 00136 LOGCOLORSPACEA aLCS; 00137 BOOL bUsedDefaultChar; 00138 00139 TRACEAPI((__TEXT("CreateColorTransformW\n"))); 00140 00141 // 00142 // Validate parameter before we touch it 00143 // 00144 00145 if (IsBadReadPtr(pLogColorSpace, sizeof(LOGCOLORSPACEW))) 00146 { 00147 WARNING((__TEXT("Invalid parameter to CreateColorTransform\n"))); 00148 SetLastError(ERROR_INVALID_PARAMETER); 00149 return NULL; 00150 } 00151 00152 CopyMemory(&aLCS, pLogColorSpace, sizeof(LOGCOLORSPACEA)); 00153 aLCS.lcsSize = sizeof(LOGCOLORSPACEA); 00154 00155 // 00156 // Convert filename to ANSI and call the internal version 00157 // 00158 00159 if (! WideCharToMultiByte(CP_ACP, 0, pLogColorSpace->lcsFilename, -1, 00160 aLCS.lcsFilename, MAX_PATH, NULL, &bUsedDefaultChar) || 00161 bUsedDefaultChar) 00162 { 00163 WARNING((__TEXT("Error converting LogColorSpace filename to ANSI\n"))); 00164 return NULL; 00165 } 00166 00167 return InternalCreateColorTransform(&aLCS, hDestProfile, hTargetProfile, dwFlags); 00168 } 00169 00170 #endif 00171 00172 00173 /****************************************************************************** 00174 * 00175 * CreateMultiProfileTransform 00176 * 00177 * Function: 00178 * This functions creates a color transform from a set of profiles. 00179 * 00180 * Arguments: 00181 * pahProfiles - pointer to array of handles of profiles 00182 * nProfiles - number of profiles in array 00183 * padwIntent - array of intents to use 00184 * nIntents - size of array - can be 1 or nProfiles 00185 * dwFlags - optimization flags 00186 * indexPreferredCMM - one based index of profile which specifies 00187 * preferred CMM to use. 00188 * 00189 * Returns: 00190 * Handle to color transform if successful, NULL otherwise 00191 * 00192 ******************************************************************************/ 00193 00194 HTRANSFORM WINAPI CreateMultiProfileTransform( 00195 PHPROFILE pahProfiles, 00196 DWORD nProfiles, 00197 PDWORD padwIntent, 00198 DWORD nIntents, 00199 DWORD dwFlags, 00200 DWORD indexPreferredCMM 00201 ) 00202 { 00203 PPROFOBJ pProfObj; 00204 PCMMOBJ pCMMObj = NULL; 00205 DWORD cmmID; 00206 HTRANSFORM hxform = NULL; 00207 PTRANSFORMOBJ pxformObj; 00208 DWORD i; 00209 00210 TRACEAPI((__TEXT("CreateMultiProfileTransform\n"))); 00211 00212 // 00213 // Validate parameters 00214 // 00215 00216 if (nProfiles < 1 || 00217 indexPreferredCMM > nProfiles || 00218 IsBadReadPtr(pahProfiles, nProfiles * sizeof(HANDLE)) || 00219 padwIntent == NULL || 00220 ((nIntents != nProfiles) && (nIntents != 1)) || 00221 IsBadReadPtr(padwIntent, nIntents * sizeof(DWORD))) 00222 { 00223 WARNING((__TEXT("Invalid parameter to CreateMultiProfileTransform\n"))); 00224 SetLastError(ERROR_INVALID_PARAMETER); 00225 return NULL; 00226 } 00227 00228 for (i=0; i<nProfiles; i++) 00229 { 00230 if (pahProfiles[i] == NULL || 00231 ! ValidHandle(pahProfiles[i], OBJ_PROFILE)) 00232 { 00233 WARNING((__TEXT("Invalid profile passed to CreateMultiProfileTransform\n"))); 00234 SetLastError(ERROR_INVALID_PARAMETER); 00235 return NULL; 00236 } 00237 00238 pProfObj = (PPROFOBJ)HDLTOPTR(pahProfiles[i]); 00239 00240 ASSERT(pProfObj != NULL); 00241 00242 // 00243 // Quick check on the integrity of the profile 00244 // 00245 00246 if (!ValidProfile(pProfObj)) 00247 { 00248 WARNING((__TEXT("Invalid profile passed to CreateMultiProfileTransform\n"))); 00249 SetLastError(ERROR_INVALID_PROFILE); 00250 return NULL; 00251 } 00252 00253 ASSERT(pProfObj->pView != NULL); 00254 00255 if (i+1 == indexPreferredCMM) 00256 { 00257 // 00258 // Get ID of preferred CMM 00259 // 00260 00261 cmmID = HEADER(pProfObj)->phCMMType; 00262 cmmID = FIX_ENDIAN(cmmID); 00263 } 00264 } 00265 00266 if (indexPreferredCMM == INDEX_DONT_CARE) 00267 { 00268 pCMMObj = GetPreferredCMM(); 00269 } 00270 else 00271 { 00272 // 00273 // Get CMM associated with preferred profile 00274 // 00275 00276 pCMMObj = GetColorMatchingModule(cmmID); 00277 } 00278 00279 // 00280 // Finally try Windows default CMM 00281 // 00282 00283 if (!pCMMObj) 00284 { 00285 pCMMObj = GetColorMatchingModule(CMM_WINDOWS_DEFAULT); 00286 if (!pCMMObj) 00287 { 00288 RIP((__TEXT("Default CMM not found\n"))); 00289 SetLastError(ERROR_INVALID_CMM); 00290 return NULL; 00291 } 00292 } 00293 00294 // 00295 // Allocate an object on the heap for the transform 00296 // 00297 00298 hxform = AllocateHeapObject(OBJ_TRANSFORM); 00299 if (!hxform) 00300 { 00301 WARNING((__TEXT("Could not allocate transform object\n"))); 00302 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00303 ReleaseColorMatchingModule(pCMMObj); 00304 return NULL; 00305 } 00306 00307 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 00308 00309 ASSERT(pxformObj != NULL); 00310 00311 ASSERT(pCMMObj->fns.pCMCreateMultiProfileTransform != NULL); 00312 00313 pxformObj->pCMMObj = pCMMObj; 00314 pxformObj->objHdr.dwUseCount = 1; 00315 00316 pxformObj->hcmxform = pCMMObj->fns.pCMCreateMultiProfileTransform( 00317 pahProfiles, 00318 nProfiles, 00319 padwIntent, 00320 nIntents, 00321 dwFlags); 00322 00323 TERSE((__TEXT("CMCreateMultiProfileTransform returned 0x%x\n"), pxformObj->hcmxform)); 00324 00325 // 00326 // If return value from CMM is less than 256, then it is an error code 00327 // 00328 00329 if (pxformObj->hcmxform <= TRANSFORM_ERROR) 00330 { 00331 WARNING((__TEXT("CMCreateMultiProfileTransform failed\n"))); 00332 if (GetLastError() == ERROR_SUCCESS) 00333 { 00334 WARNING((__TEXT("CMM did not set error code\n"))); 00335 SetLastError(ERROR_INVALID_PROFILE); 00336 } 00337 ReleaseColorMatchingModule(pxformObj->pCMMObj); 00338 pxformObj->objHdr.dwUseCount--; // decrement before freeing 00339 FreeHeapObject(hxform); 00340 hxform = NULL; 00341 } 00342 00343 return hxform; 00344 } 00345 00346 00347 /****************************************************************************** 00348 * 00349 * DeleteColorTransform 00350 * 00351 * Function: 00352 * This functions deletes a color transform and frees all associated 00353 * memory. 00354 * 00355 * Arguments: 00356 * hxform - handle to color transform to delete 00357 * 00358 * Returns: 00359 * TRUE if successful, FALSE otherwise 00360 * 00361 ******************************************************************************/ 00362 00363 BOOL WINAPI DeleteColorTransform( 00364 HTRANSFORM hxform 00365 ) 00366 { 00367 PTRANSFORMOBJ pxformObj; 00368 BOOL rc; 00369 00370 TRACEAPI((__TEXT("DeleteColorTransform\n"))); 00371 00372 // 00373 // Validate parameters 00374 // 00375 00376 if (!ValidHandle(hxform, OBJ_TRANSFORM)) 00377 { 00378 WARNING((__TEXT("Invalid parameter to DeleteColorTransform\n"))); 00379 SetLastError(ERROR_INVALID_PARAMETER); 00380 return FALSE; 00381 } 00382 00383 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 00384 00385 ASSERT(pxformObj != NULL); 00386 00387 ASSERT(pxformObj->objHdr.dwUseCount > 0); 00388 00389 // 00390 // Decrease object count, and delete if it goes to zero. 00391 // The following code retains the object and returns failure if the CMM 00392 // fails the delete transform operation. 00393 // 00394 00395 pxformObj->objHdr.dwUseCount--; 00396 00397 if (pxformObj->objHdr.dwUseCount == 0) 00398 { 00399 ASSERT(pxformObj->pCMMObj != NULL); 00400 00401 rc = pxformObj->pCMMObj->fns.pCMDeleteTransform(pxformObj->hcmxform); 00402 if (!rc) 00403 { 00404 pxformObj->objHdr.dwUseCount++; // set count back 00405 return FALSE; 00406 } 00407 ReleaseColorMatchingModule(pxformObj->pCMMObj); 00408 FreeHeapObject(hxform); 00409 } 00410 00411 return TRUE; 00412 } 00413 00414 00415 /****************************************************************************** 00416 * 00417 * TranslateColors 00418 * 00419 * Function: 00420 * This functions translates an array of color strcutures using the 00421 * given transform 00422 * 00423 * Arguments: 00424 * hxform - handle to color transform to use 00425 * paInputcolors - pointer to array of input colors 00426 * nColors - number of colors in the array 00427 * ctInput - color type of input 00428 * paOutputColors - pointer to buffer to get translated colors 00429 * ctOutput - output color type 00430 * 00431 * Comments: 00432 * Input and output color types must be consistent with the transform 00433 * 00434 * Returns: 00435 * TRUE if successful, FALSE otherwise 00436 * 00437 ******************************************************************************/ 00438 00439 BOOL WINAPI TranslateColors( 00440 HTRANSFORM hxform, 00441 PCOLOR paInputColors, 00442 DWORD nColors, 00443 COLORTYPE ctInput, 00444 PCOLOR paOutputColors, 00445 COLORTYPE ctOutput 00446 ) 00447 { 00448 PTRANSFORMOBJ pxformObj; 00449 BOOL rc; 00450 00451 TRACEAPI((__TEXT("TranslateColors\n"))); 00452 00453 // 00454 // Validate parameters 00455 // 00456 00457 if (!ValidHandle(hxform, OBJ_TRANSFORM) || 00458 (nColors == 0) || 00459 IsBadReadPtr(paInputColors, nColors*sizeof(COLOR)) || 00460 IsBadWritePtr(paOutputColors, nColors*sizeof(COLOR))) 00461 { 00462 WARNING((__TEXT("Invalid parameter to TranslateColors\n"))); 00463 SetLastError(ERROR_INVALID_PARAMETER); 00464 return FALSE; 00465 } 00466 00467 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 00468 00469 ASSERT(pxformObj != NULL); 00470 00471 ASSERT(pxformObj->pCMMObj != NULL); 00472 00473 rc = pxformObj->pCMMObj->fns.pCMTranslateColors( 00474 pxformObj->hcmxform, 00475 paInputColors, 00476 nColors, 00477 ctInput, 00478 paOutputColors, 00479 ctOutput); 00480 00481 return rc; 00482 } 00483 00484 00485 /****************************************************************************** 00486 * 00487 * CheckColors 00488 * 00489 * Function: 00490 * This functions checks if an array of colors fall within the output 00491 * gamut of the given transform 00492 * 00493 * Arguments: 00494 * hxform - handle to color transform to use 00495 * paInputcolors - pointer to array of input colors 00496 * nColors - number of colors in the array 00497 * ctInput - color type of input 00498 * paResult - pointer to buffer to hold the result 00499 * 00500 * Comments: 00501 * Input color type must be consistent with the transform 00502 * 00503 * Returns: 00504 * TRUE if successful, FALSE otherwise 00505 * 00506 ******************************************************************************/ 00507 00508 BOOL WINAPI CheckColors( 00509 HTRANSFORM hxform, 00510 PCOLOR paInputColors, 00511 DWORD nColors, 00512 COLORTYPE ctInput, 00513 PBYTE paResult 00514 ) 00515 { 00516 PTRANSFORMOBJ pxformObj; 00517 BOOL rc; 00518 00519 TRACEAPI((__TEXT("CheckColors\n"))); 00520 00521 // 00522 // Validate parameters 00523 // 00524 00525 if (!ValidHandle(hxform, OBJ_TRANSFORM) || 00526 (nColors == 0) || 00527 IsBadReadPtr(paInputColors, nColors * sizeof(COLOR)) || 00528 IsBadWritePtr(paResult, nColors * sizeof(BYTE))) 00529 { 00530 WARNING((__TEXT("Invalid parameter to CheckColors\n"))); 00531 SetLastError(ERROR_INVALID_PARAMETER); 00532 return FALSE; 00533 } 00534 00535 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 00536 00537 ASSERT(pxformObj != NULL); 00538 00539 ASSERT(pxformObj->pCMMObj != NULL); 00540 00541 rc = pxformObj->pCMMObj->fns.pCMCheckColors( 00542 pxformObj->hcmxform, 00543 paInputColors, 00544 nColors, 00545 ctInput, 00546 paResult); 00547 00548 return rc; 00549 } 00550 00551 00552 /****************************************************************************** 00553 * 00554 * TranslateBitmapBits 00555 * 00556 * Function: 00557 * This functions translates the colors of a bitmap using the 00558 * given transform 00559 * 00560 * Arguments: 00561 * hxform - handle to color transform to use 00562 * pSrcBits - pointer to source bitmap 00563 * bmInput - input bitmap format 00564 * dwWidth - width in pixels of each scanline 00565 * dwHeight - number of scanlines in bitmap 00566 * dwInputStride - number of bytes from beginning of one scanline to next 00567 * in input buffer, 0 means DWORD aligned 00568 * pDestBits - pointer to destination bitmap to store results 00569 * bmOutput - output bitmap format 00570 * dwOutputStride - number of bytes from beginning of one scanline to next 00571 * in output buffer, 0 means DWORD aligned 00572 * pfnCallback - callback function to report progress 00573 * ulCallbackData - parameter to callback function 00574 * 00575 * Comments: 00576 * Input and output bitmap formats must be consistent with the transform 00577 * 00578 * Returns: 00579 * TRUE if successful, FALSE otherwise 00580 * 00581 ******************************************************************************/ 00582 00583 BOOL WINAPI TranslateBitmapBits( 00584 HTRANSFORM hxform, 00585 PVOID pSrcBits, 00586 BMFORMAT bmInput, 00587 DWORD dwWidth, 00588 DWORD dwHeight, 00589 DWORD dwInputStride, 00590 PVOID pDestBits, 00591 BMFORMAT bmOutput, 00592 DWORD dwOutputStride, 00593 PBMCALLBACKFN pfnCallback, 00594 LPARAM ulCallbackData 00595 ) 00596 { 00597 PTRANSFORMOBJ pxformObj; 00598 DWORD nBytes, cbSize; 00599 BOOL rc; 00600 00601 TRACEAPI((__TEXT("TranslateBitmapBits\n"))); 00602 00603 // 00604 // Calculate number of bytes input bitmap should be 00605 // 00606 00607 if (dwInputStride) 00608 cbSize = dwInputStride * dwHeight; 00609 else 00610 cbSize = GetBitmapBytes(bmInput, dwWidth, dwHeight); 00611 00612 // 00613 // Calculate number of bytes output bitmap should be 00614 // 00615 00616 if (dwOutputStride) 00617 nBytes = dwOutputStride * dwHeight; 00618 else 00619 nBytes = GetBitmapBytes(bmOutput, dwWidth, dwHeight); 00620 00621 // 00622 // Validate parameters 00623 // 00624 00625 if (nBytes == 0 || 00626 cbSize == 0 || 00627 !ValidHandle(hxform, OBJ_TRANSFORM) || 00628 IsBadReadPtr(pSrcBits, cbSize) || 00629 IsBadWritePtr(pDestBits, nBytes) || 00630 (pfnCallback && IsBadCodePtr((FARPROC)pfnCallback))) 00631 { 00632 WARNING((__TEXT("Invalid parameter to TranslateBitmapBits\n"))); 00633 SetLastError(ERROR_INVALID_PARAMETER); 00634 return FALSE; 00635 } 00636 00637 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 00638 00639 ASSERT(pxformObj != NULL); 00640 00641 ASSERT(pxformObj->pCMMObj != NULL); 00642 00643 rc = pxformObj->pCMMObj->fns.pCMTranslateRGBsExt( 00644 pxformObj->hcmxform, 00645 pSrcBits, 00646 bmInput, 00647 dwWidth, 00648 dwHeight, 00649 dwInputStride, 00650 pDestBits, 00651 bmOutput, 00652 dwOutputStride, 00653 pfnCallback, 00654 ulCallbackData); 00655 00656 return rc; 00657 } 00658 00659 00660 /****************************************************************************** 00661 * 00662 * CheckBitmapBits 00663 * 00664 * Function: 00665 * This functions checks if the colors of a bitmap fall within the 00666 * output gamut of the given transform 00667 * 00668 * Arguments: 00669 * hxform - handle to color transform to use 00670 * pSrcBits - pointer to source bitmap 00671 * bmInput - input bitmap format 00672 * dwWidth - width in pixels of each scanline 00673 * dwHeight - number of scanlines in bitmap 00674 * dwStride - number of bytes from beginning of one scanline to next 00675 * paResult - pointer to buffer to hold the result 00676 * pfnCallback - callback function to report progress 00677 * ulCallbackData - parameter to callback function 00678 * 00679 * Comments: 00680 * Input bitmap format must be consistent with the transform 00681 * 00682 * Returns: 00683 * TRUE if successful, FALSE otherwise 00684 * 00685 ******************************************************************************/ 00686 00687 BOOL WINAPI CheckBitmapBits( 00688 HTRANSFORM hxform, 00689 PVOID pSrcBits, 00690 BMFORMAT bmInput, 00691 DWORD dwWidth, 00692 DWORD dwHeight, 00693 DWORD dwStride, 00694 PBYTE paResult, 00695 PBMCALLBACKFN pfnCallback, 00696 LPARAM ulCallbackData 00697 ) 00698 { 00699 PTRANSFORMOBJ pxformObj; 00700 DWORD cbSize; 00701 BOOL rc; 00702 00703 TRACEAPI((__TEXT("CheckBitmapBits\n"))); 00704 00705 // 00706 // Calculate number of bytes input bitmap should be 00707 // 00708 00709 if (dwStride) 00710 cbSize = dwStride*dwHeight; 00711 else 00712 cbSize = GetBitmapBytes(bmInput, dwWidth, dwHeight); 00713 00714 // 00715 // Validate parameters 00716 // 00717 00718 if (!ValidHandle(hxform, OBJ_TRANSFORM) || 00719 cbSize == 0 || 00720 IsBadReadPtr(pSrcBits, cbSize) || 00721 IsBadWritePtr(paResult, dwWidth*dwHeight) || 00722 (pfnCallback && IsBadCodePtr((FARPROC)pfnCallback))) 00723 { 00724 WARNING((__TEXT("Invalid parameter to CheckBitmapBits\n"))); 00725 SetLastError(ERROR_INVALID_PARAMETER); 00726 return FALSE; 00727 } 00728 00729 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 00730 00731 ASSERT(pxformObj != NULL); 00732 00733 ASSERT(pxformObj->pCMMObj != NULL); 00734 00735 rc = pxformObj->pCMMObj->fns.pCMCheckRGBs( 00736 pxformObj->hcmxform, 00737 pSrcBits, 00738 bmInput, 00739 dwWidth, 00740 dwHeight, 00741 dwStride, 00742 paResult, 00743 pfnCallback, 00744 ulCallbackData); 00745 00746 return rc; 00747 } 00748 00749 00750 /****************************************************************************** 00751 * 00752 * GetCMMInfo 00753 * 00754 * Function: 00755 * This functions retrieves information about the CMM that created the 00756 * given transform 00757 * 00758 * Arguments: 00759 * hxform - handle to color transform 00760 * dwInfo - Can be one of the following: 00761 * CMM_WIN_VERSION: Version of Windows support 00762 * CMM_DLL_VERSION: Version of CMM 00763 * CMM_IDENT: CMM signature registered with ICC 00764 * 00765 * Returns: 00766 * For CMM_WIN_VERSION, it returns the Windows version it was written for. 00767 * For CMM_DLL_VERSION, it returns the version number of the CMM DLL. 00768 * For CMM_IDENT, it returns the CMM signature registered with the ICC. 00769 * If the function fails it returns zero. 00770 * 00771 ******************************************************************************/ 00772 00773 DWORD WINAPI GetCMMInfo( 00774 HTRANSFORM hxform, 00775 DWORD dwInfo 00776 ) 00777 { 00778 PTRANSFORMOBJ pxformObj; 00779 BOOL rc; 00780 00781 TRACEAPI((__TEXT("GetCMMInfo\n"))); 00782 00783 // 00784 // Validate parameters 00785 // 00786 00787 if (!ValidHandle(hxform, OBJ_TRANSFORM) || 00788 (dwInfo != CMM_WIN_VERSION && 00789 dwInfo != CMM_DLL_VERSION && 00790 dwInfo != CMM_IDENT 00791 ) 00792 ) 00793 { 00794 WARNING((__TEXT("Invalid parameter to GetCMMInfo\n"))); 00795 SetLastError(ERROR_INVALID_PARAMETER); 00796 return FALSE; 00797 } 00798 00799 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 00800 00801 ASSERT(pxformObj != NULL); 00802 00803 ASSERT(pxformObj->pCMMObj != NULL); 00804 00805 rc = pxformObj->pCMMObj->fns.pCMGetInfo(dwInfo); 00806 00807 return rc; 00808 } 00809 00810 00811 /****************************************************************************** 00812 * 00813 * RegisterCMM 00814 * 00815 * Function: 00816 * These are the ANSI and Unicode wrappers. For more information on this 00817 * function, see InternalRegisterCMM. 00818 * 00819 * Arguments: 00820 * pMachineName - name identifying machine on which the CMM should be 00821 * registered 00822 * cmmID - ID of CMM to register 00823 * pCMMdll - pointer to CMM dll to register 00824 * 00825 * Returns: 00826 * TRUE if successful, FALSE otherwise 00827 * 00828 ******************************************************************************/ 00829 00830 #ifdef UNICODE // Windows NT version 00831 00832 BOOL WINAPI RegisterCMMA( 00833 PCSTR pMachineName, 00834 DWORD cmmID, 00835 PCSTR pCMMdll 00836 ) 00837 { 00838 PWSTR pwszMachineName = NULL; // Unicode machine name 00839 PWSTR pwszCMMdll = NULL; // Unicode CMM dll path 00840 BOOL rc = TRUE; // return code 00841 00842 TRACEAPI((__TEXT("RegisterCMMA\n"))); 00843 00844 // 00845 // Convert machine name to Unicode 00846 // 00847 00848 if (pMachineName) 00849 { 00850 rc = ConvertToUnicode(pMachineName, &pwszMachineName, TRUE); 00851 } 00852 else 00853 pwszMachineName = NULL; 00854 00855 // 00856 // Convert pCMMdll to Unicode 00857 // 00858 00859 rc = rc && ConvertToUnicode(pCMMdll, &pwszCMMdll, TRUE); 00860 00861 00862 // 00863 // Call the internal Unicode function 00864 // 00865 00866 rc = rc && InternalRegisterCMM(pwszMachineName, cmmID, pwszCMMdll); 00867 00868 // 00869 // Free memory before leaving 00870 // 00871 00872 if (pwszMachineName) 00873 { 00874 MemFree(pwszMachineName); 00875 } 00876 00877 if (pwszCMMdll) 00878 { 00879 MemFree(pwszCMMdll); 00880 } 00881 00882 return rc; 00883 } 00884 00885 00886 BOOL WINAPI RegisterCMMW( 00887 PCWSTR pMachineName, 00888 DWORD cmmID, 00889 PCWSTR pCMMdll 00890 ) 00891 { 00892 TRACEAPI((__TEXT("RegisterCMMW\n"))); 00893 00894 // 00895 // Internal version is Unicode in Windows NT, call it directly 00896 // 00897 00898 return InternalRegisterCMM((PWSTR)pMachineName, cmmID, (PWSTR)pCMMdll); 00899 } 00900 00901 #else // Windows 95 version 00902 00903 BOOL WINAPI RegisterCMMA( 00904 PCSTR pMachineName, 00905 DWORD cmmID, 00906 PCSTR pCMMdll 00907 ) 00908 { 00909 TRACEAPI((__TEXT("RegisterCMMA\n"))); 00910 00911 // 00912 // Internal version is ANSI in Windows 95, call it directly 00913 // 00914 00915 return InternalRegisterCMM((PSTR)pMachineName, cmmID, (PSTR)pCMMdll); 00916 } 00917 00918 00919 BOOL WINAPI RegisterCMMW( 00920 PCWSTR pMachineName, 00921 DWORD cmmID, 00922 PCWSTR pCMMdll 00923 ) 00924 { 00925 PSTR pszMachineName = NULL; // Ansi machine name 00926 PSTR pszCMMdll = NULL; // Ansi CMM dll path 00927 BOOL rc = TRUE; // return code 00928 00929 TRACEAPI((__TEXT("RegisterCMMW\n"))); 00930 00931 // 00932 // Convert machine name to Ansi 00933 // 00934 00935 if (pMachineName) 00936 { 00937 rc = ConvertToAnsi(pMachineName, &pszMachineName, TRUE); 00938 } 00939 else 00940 pszMachineName = NULL; 00941 00942 // 00943 // Convert pCMMdll to Ansi 00944 // 00945 00946 rc = rc && ConvertToAnsi(pCMMdll, &pszCMMdll, TRUE); 00947 00948 // 00949 // Call the internal Ansi function 00950 // 00951 00952 rc = rc && InternalRegisterCMM(pszMachineName, cmmID, pszCMMdll); 00953 00954 // 00955 // Free memory before leaving 00956 // 00957 00958 if (pszMachineName) 00959 { 00960 MemFree(pszMachineName); 00961 } 00962 00963 if (pszCMMdll) 00964 { 00965 MemFree(pszCMMdll); 00966 } 00967 00968 return rc; 00969 } 00970 00971 #endif 00972 00973 00974 /****************************************************************************** 00975 * 00976 * UnregisterCMM 00977 * 00978 * Function: 00979 * These are the ANSI and Unicode wrappers. For more information on this 00980 * function, see InternalUnregisterCMM. 00981 * 00982 * Arguments: 00983 * pMachineName - name identifying machine on which the CMM is 00984 * registered 00985 * cmmID - ID of CMM to unregister 00986 * 00987 * Returns: 00988 * TRUE if successful, FALSE otherwise 00989 * 00990 ******************************************************************************/ 00991 00992 #ifdef UNICODE // Windows NT version 00993 00994 BOOL WINAPI UnregisterCMMA( 00995 PCSTR pMachineName, 00996 DWORD cmmID 00997 ) 00998 { 00999 PWSTR pwszMachineName = NULL; // Unicode machine name 01000 BOOL rc = TRUE; // return code 01001 01002 TRACEAPI((__TEXT("UnregisterCMMA\n"))); 01003 01004 // 01005 // Convert machine name to Unicode 01006 // 01007 01008 if (pMachineName) 01009 { 01010 rc = ConvertToUnicode(pMachineName, &pwszMachineName, TRUE); 01011 } 01012 else 01013 pwszMachineName = NULL; 01014 01015 // 01016 // Call the internal Unicode function 01017 // 01018 01019 rc = rc && InternalUnregisterCMM(pwszMachineName, cmmID); 01020 01021 // 01022 // Free memory before leaving 01023 // 01024 01025 if (pwszMachineName) 01026 { 01027 MemFree(pwszMachineName); 01028 } 01029 01030 return rc; 01031 } 01032 01033 01034 BOOL WINAPI UnregisterCMMW( 01035 PCWSTR pMachineName, 01036 DWORD cmmID 01037 ) 01038 { 01039 TRACEAPI((__TEXT("UnregisterCMMW\n"))); 01040 01041 // 01042 // Internal version is Unicode in Windows NT, call it directly 01043 // 01044 01045 return InternalUnregisterCMM((PWSTR)pMachineName, cmmID); 01046 } 01047 01048 #else // Windows 95 version 01049 01050 BOOL WINAPI UnregisterCMMA( 01051 PCSTR pMachineName, 01052 DWORD cmmID 01053 ) 01054 { 01055 TRACEAPI((__TEXT("UnregisterCMMA\n"))); 01056 01057 // 01058 // Internal version is ANSI in Windows 95, call it directly 01059 // 01060 01061 return InternalUnregisterCMM((PSTR)pMachineName, cmmID); 01062 } 01063 01064 01065 BOOL WINAPI UnregisterCMMW( 01066 PCWSTR pMachineName, 01067 DWORD cmmID 01068 ) 01069 { 01070 PSTR pszMachineName = NULL; // Ansi machine name 01071 BOOL rc = TRUE; // return code 01072 01073 TRACEAPI((__TEXT("UnregisterCMMW\n"))); 01074 01075 // 01076 // Convert machine name to Ansi 01077 // 01078 01079 if (pMachineName) 01080 { 01081 rc = ConvertToAnsi(pMachineName, &pszMachineName, TRUE); 01082 } 01083 else 01084 pszMachineName = NULL; 01085 01086 // 01087 // Call the internal Ansi function 01088 // 01089 01090 rc = rc && InternalUnregisterCMM(pszMachineName, cmmID); 01091 01092 // 01093 // Free memory before leaving 01094 // 01095 01096 if (pszMachineName) 01097 { 01098 MemFree(pszMachineName); 01099 } 01100 01101 return rc; 01102 } 01103 01104 #endif 01105 01106 01107 /****************************************************************************** 01108 * 01109 * SelectCMM 01110 * 01111 * Function: 01112 * This function allows an application to select the preferred CMM to use 01113 * 01114 * Arguments: 01115 * cmmID - ID of preferred CMM to use 01116 * 01117 * Returns: 01118 * TRUE if successful, FALSE otherwise 01119 * 01120 ******************************************************************************/ 01121 01122 BOOL WINAPI SelectCMM( 01123 DWORD dwCMMType 01124 ) 01125 { 01126 PCMMOBJ pCMMObj = NULL; 01127 01128 TRACEAPI((__TEXT("SelectCMM\n"))); 01129 01130 if (dwCMMType) 01131 { 01132 pCMMObj = GetColorMatchingModule(dwCMMType); 01133 if (!pCMMObj) 01134 { 01135 SetLastError(ERROR_INVALID_CMM); 01136 return FALSE; 01137 } 01138 } 01139 01140 // 01141 // Update Preferred CMM 01142 // 01143 EnterCriticalSection(&critsec); // Critical Section 01144 gpPreferredCMM = pCMMObj; 01145 LeaveCriticalSection(&critsec); // Critical Section 01146 01147 return TRUE; 01148 } 01149 01150 01151 /*****************************************************************************/ 01152 /***************************** Internal Functions ****************************/ 01153 /*****************************************************************************/ 01154 01155 /****************************************************************************** 01156 * 01157 * InternalCreateColorTransform 01158 * 01159 * Function: 01160 * This functions creates a color transform that translates from 01161 * the logcolorspace to the optional target device color space to the 01162 * destination device color space. 01163 * 01164 * Arguments: 01165 * pLogColorSpace - pointer to LOGCOLORSPACE structure identifying 01166 * source color space 01167 * hDestProfile - handle identifing the destination profile object 01168 * hTargetProfile - handle identifing the target profile object 01169 * dwFlags - optimization flags 01170 * 01171 * Returns: 01172 * Handle to color transform if successful, NULL otherwise 01173 * 01174 ******************************************************************************/ 01175 01176 HTRANSFORM InternalCreateColorTransform( 01177 LPLOGCOLORSPACE pLogColorSpace, 01178 HPROFILE hDestProfile, 01179 HPROFILE hTargetProfile, 01180 DWORD dwFlags 01181 ) 01182 { 01183 PPROFOBJ pDestProfObj, pTargetProfObj = NULL; 01184 PCMMOBJ pCMMObj; 01185 DWORD cmmID; 01186 HTRANSFORM hxform = NULL; 01187 PTRANSFORMOBJ pxformObj; 01188 LPLOGCOLORSPACE pLCS; 01189 01190 // 01191 // Validate parameters 01192 // 01193 01194 if (!pLogColorSpace || 01195 IsBadReadPtr(pLogColorSpace, sizeof(LOGCOLORSPACE)) || 01196 pLogColorSpace->lcsSignature != LCS_SIGNATURE || 01197 pLogColorSpace->lcsVersion < 0x00000400 || 01198 !hDestProfile || 01199 !ValidHandle(hDestProfile, OBJ_PROFILE) || 01200 ((hTargetProfile != NULL) && 01201 !ValidHandle(hTargetProfile, OBJ_PROFILE) 01202 ) 01203 ) 01204 { 01205 WARNING((__TEXT("Invalid parameter to CreateColorTransform\n"))); 01206 SetLastError(ERROR_INVALID_PARAMETER); 01207 return NULL; 01208 } 01209 01210 // 01211 // Allocate LogColorSpace and copy incoming data. 01212 // Leave space for passing in two handles below it 01213 // 01214 01215 pLCS = (LPLOGCOLORSPACE)MemAlloc(sizeof(LOGCOLORSPACE) + 2*sizeof(HPROFILE)); 01216 if (!pLCS) 01217 { 01218 WARNING((__TEXT("Could not allocate LogColorSpace"))); 01219 return NULL; 01220 } 01221 CopyMemory((PVOID)pLCS, (PVOID)pLogColorSpace, sizeof(LOGCOLORSPACE)); 01222 01223 // 01224 // Copy handles below this structure 01225 // 01226 01227 *((PHPROFILE)((PBYTE)pLCS+sizeof(LOGCOLORSPACE))) = hDestProfile; 01228 *((PHPROFILE)((PBYTE)pLCS+sizeof(LOGCOLORSPACE)+sizeof(HPROFILE))) = hTargetProfile; 01229 01230 // 01231 // If input color space is a predefined color space, 01232 // find the right profile to use 01233 // 01234 01235 if (pLCS->lcsCSType > LCS_DEVICE_CMYK) 01236 { 01237 DWORD cbSize = MAX_PATH; 01238 01239 if (! GetStandardColorSpaceProfile(NULL, pLCS->lcsCSType, 01240 pLCS->lcsFilename, &cbSize)) 01241 { 01242 WARNING((__TEXT("Could not get profile for predefined color space 0x%x\n"), pLCS->lcsCSType)); 01243 goto EndCreateColorTransform; 01244 } 01245 } 01246 01247 pDestProfObj = (PPROFOBJ)HDLTOPTR(hDestProfile); 01248 01249 ASSERT(pDestProfObj != NULL); 01250 01251 // 01252 // Quick check on the integrity of the profile before calling the CMM 01253 // 01254 01255 if (!ValidProfile(pDestProfObj)) 01256 { 01257 WARNING((__TEXT("Invalid dest profile passed to CreateColorTransform\n"))); 01258 SetLastError(ERROR_INVALID_PROFILE); 01259 goto EndCreateColorTransform; 01260 } 01261 01262 // 01263 // If target profile is given, get the profile object and check integrity 01264 // 01265 01266 if (hTargetProfile) 01267 { 01268 pTargetProfObj = (PPROFOBJ)HDLTOPTR(hTargetProfile); 01269 01270 ASSERT(pTargetProfObj != NULL); 01271 01272 if (!ValidProfile(pTargetProfObj)) 01273 { 01274 WARNING((__TEXT("Invalid target profile passed to CreateColorTransform\n"))); 01275 SetLastError(ERROR_INVALID_PROFILE); 01276 goto EndCreateColorTransform; 01277 } 01278 } 01279 01280 // 01281 // Check if application specified CMM is present 01282 // 01283 01284 pCMMObj = GetPreferredCMM(); 01285 if (!pCMMObj) 01286 { 01287 // 01288 // Get CMM associated with destination profile. If it does not exist, 01289 // get default CMM. 01290 // 01291 01292 cmmID = HEADER(pDestProfObj)->phCMMType; 01293 cmmID = FIX_ENDIAN(cmmID); 01294 01295 pCMMObj = GetColorMatchingModule(cmmID); 01296 if (!pCMMObj) 01297 { 01298 TERSE((__TEXT("CMM associated with profile could not be found"))); 01299 01300 pCMMObj = GetColorMatchingModule(CMM_WINDOWS_DEFAULT); 01301 if (!pCMMObj) 01302 { 01303 RIP((__TEXT("Default CMM not found\n"))); 01304 SetLastError(ERROR_INVALID_CMM); 01305 goto EndCreateColorTransform; 01306 } 01307 } 01308 } 01309 01310 // 01311 // Allocate an object on the heap for the transform 01312 // 01313 01314 hxform = AllocateHeapObject(OBJ_TRANSFORM); 01315 if (!hxform) 01316 { 01317 WARNING((__TEXT("Could not allocate transform object\n"))); 01318 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01319 ReleaseColorMatchingModule(pCMMObj); 01320 goto EndCreateColorTransform; 01321 } 01322 01323 pxformObj = (PTRANSFORMOBJ)HDLTOPTR(hxform); 01324 01325 ASSERT(pxformObj != NULL); 01326 01327 // 01328 // Call into CMM to create a color transform 01329 // 01330 01331 ASSERT(pCMMObj->fns.pCMCreateTransformExt != NULL); 01332 01333 ASSERT(pDestProfObj->pView != NULL); 01334 01335 ASSERT(!pTargetProfObj || pTargetProfObj->pView); 01336 01337 pxformObj->pCMMObj = pCMMObj; 01338 pxformObj->objHdr.dwUseCount = 1; 01339 01340 pxformObj->hcmxform = pCMMObj->fns.pCMCreateTransformExt( 01341 pLCS, 01342 pDestProfObj->pView, 01343 pTargetProfObj ? pTargetProfObj->pView : NULL, 01344 dwFlags); 01345 01346 TERSE((__TEXT("CMCreateTransform returned 0x%x\n"), pxformObj->hcmxform)); 01347 01348 // 01349 // If return value from CMM is less than 256, then it is an error code 01350 // 01351 01352 if (pxformObj->hcmxform <= TRANSFORM_ERROR) 01353 { 01354 WARNING((__TEXT("CMCreateTransform failed\n"))); 01355 if (GetLastError() == ERROR_SUCCESS) 01356 { 01357 WARNING((__TEXT("CMM did not set error code\n"))); 01358 SetLastError(ERROR_INVALID_PROFILE); 01359 } 01360 ReleaseColorMatchingModule(pxformObj->pCMMObj); 01361 pxformObj->objHdr.dwUseCount--; // decrement before freeing 01362 FreeHeapObject(hxform); 01363 hxform = NULL; 01364 } 01365 01366 EndCreateColorTransform: 01367 MemFree(pLCS); 01368 01369 return hxform; 01370 } 01371 01372 /****************************************************************************** 01373 * 01374 * InternalRegisterCMM 01375 * 01376 * Function: 01377 * This function associates an ID with a CMM DLL, so that we can use 01378 * the ID in profiles to find the CMM to use when creating a transform. 01379 * 01380 * Arguments: 01381 * pMachineName - name identifying machine on which the CMM should be 01382 * registered 01383 * cmmID - ID of CMM to register 01384 * pCMMdll - pointer to CMM dll to register 01385 * 01386 * Returns: 01387 * TRUE if successful, FALSE otherwise 01388 * 01389 ******************************************************************************/ 01390 01391 BOOL InternalRegisterCMM( 01392 PTSTR pMachineName, 01393 DWORD cmmID, 01394 PTSTR pCMMdll 01395 ) 01396 { 01397 PCMMOBJ pCMMObj; 01398 HKEY hkCMM; 01399 DWORD dwErr; 01400 BOOL rc = TRUE; 01401 int i; 01402 TCHAR szCMMID[5]; 01403 01404 // 01405 // Validate parameters 01406 // 01407 01408 if (!pCMMdll || IsBadReadPtr(pCMMdll, lstrlen(pCMMdll)*sizeof(TCHAR))) 01409 { 01410 WARNING((__TEXT("Invalid parameter to RegisterCMM\n"))); 01411 SetLastError(ERROR_INVALID_PARAMETER); 01412 return FALSE; 01413 } 01414 01415 01416 // 01417 // Only local installs are allowed now 01418 // 01419 01420 if (pMachineName) 01421 { 01422 WARNING((__TEXT("Remote CMM registration attempted, failing...\n"))); 01423 SetLastError(ERROR_INVALID_PARAMETER); 01424 return FALSE; 01425 } 01426 01427 // 01428 // Check if the CMM actually exists, and it's valid CMM 01429 // 01430 01431 rc = ValidColorMatchingModule(cmmID,pCMMdll); 01432 01433 if (rc) 01434 { 01435 // 01436 // Open the registry key for ICMatchers 01437 // 01438 01439 if ((dwErr = RegCreateKey(HKEY_LOCAL_MACHINE, gszICMatcher, &hkCMM)) != ERROR_SUCCESS) 01440 { 01441 ERR((__TEXT("Could not open ICMatcher registry key: %d\n"), dwErr)); 01442 SetLastError(dwErr); 01443 return FALSE; 01444 } 01445 01446 // 01447 // Make a string with the CMM ID 01448 // 01449 01450 for (i=0; i<4; i++) 01451 { 01452 szCMMID[i] = (TCHAR)(((char*)&cmmID)[3-i]); 01453 } 01454 szCMMID[4] = '\0'; 01455 01456 // 01457 // Set the file name of the CMM dll in the registry 01458 // 01459 01460 if ((dwErr = RegSetValueEx(hkCMM, (PTSTR)szCMMID, 0, REG_SZ, (BYTE *)pCMMdll, 01461 (lstrlen(pCMMdll)+1)*sizeof(TCHAR))) != ERROR_SUCCESS) 01462 { 01463 WARNING((__TEXT("Could not set CMM dll in the registry %s: %d\n"), szCMMID, dwErr)); 01464 SetLastError(dwErr); 01465 rc = FALSE; 01466 } 01467 01468 RegCloseKey(hkCMM); 01469 } 01470 01471 return rc; 01472 } 01473 01474 01475 01476 /****************************************************************************** 01477 * 01478 * InternalUnregisterCMM 01479 * 01480 * Function: 01481 * This function unregisters a CMM from the system by dissociating the 01482 * ID from the CMM dll in the registry. 01483 * 01484 * Arguments: 01485 * pMachineName - name identifying machine on which the CMM is 01486 * registered 01487 * cmmID - ID of CMM to unregister 01488 * 01489 * Returns: 01490 * TRUE if successful, FALSE otherwise 01491 * 01492 ******************************************************************************/ 01493 01494 BOOL InternalUnregisterCMM( 01495 PTSTR pMachineName, 01496 DWORD cmmID 01497 ) 01498 { 01499 HKEY hkCMM; 01500 TCHAR szCMMID[5]; 01501 DWORD dwErr; 01502 BOOL rc = TRUE; 01503 01504 // 01505 // Only local installs are allowed now 01506 // 01507 01508 if (pMachineName) 01509 { 01510 WARNING((__TEXT("Remote CMM unregistration attempted, failing...\n"))); 01511 SetLastError(ERROR_INVALID_PARAMETER); 01512 return FALSE; 01513 } 01514 01515 // 01516 // Open the registry key for ICMatchers 01517 // 01518 01519 if ((dwErr = RegOpenKey(HKEY_LOCAL_MACHINE, gszICMatcher, &hkCMM)) != ERROR_SUCCESS) 01520 { 01521 ERR((__TEXT("Could not open ICMatcher registry key: %d\n"), dwErr)); 01522 SetLastError(dwErr); 01523 return FALSE; 01524 } 01525 01526 // 01527 // Make a string with the CMM ID 01528 // 01529 01530 szCMMID[0] = ((char *)&cmmID)[3]; 01531 szCMMID[1] = ((char *)&cmmID)[2]; 01532 szCMMID[2] = ((char *)&cmmID)[1]; 01533 szCMMID[3] = ((char *)&cmmID)[0]; 01534 szCMMID[4] = '\0'; 01535 01536 // 01537 // Delete the file name of the CMM dll from the registry 01538 // 01539 01540 if ((dwErr = RegDeleteValue(hkCMM, (PTSTR)szCMMID)) != ERROR_SUCCESS) 01541 { 01542 WARNING((__TEXT("Could not delete CMM dll from the registry %s: %d\n"), szCMMID, dwErr)); 01543 SetLastError(dwErr); 01544 rc = FALSE; 01545 } 01546 01547 RegCloseKey(hkCMM); 01548 01549 return rc; 01550 } 01551 01552 01553 /****************************************************************************** 01554 * 01555 * GetBitmapBytes 01556 * 01557 * Function: 01558 * This functions returns number of bytes required for a bitmap given 01559 * the format, the width in pixels and number of scanlines 01560 * 01561 * Arguments: 01562 * bmFmt - format of bitmap 01563 * deWidth - number of pixels per scanline 01564 * dwHeight - number of scanlines in bitmap 01565 * 01566 * Returns: 01567 * Number of bytes required for bitmap on success, 0 on failure 01568 * 01569 ******************************************************************************/ 01570 01571 DWORD GetBitmapBytes( 01572 BMFORMAT bmFmt, 01573 DWORD dwWidth, 01574 DWORD dwHeight 01575 ) 01576 { 01577 DWORD nBytes; 01578 01579 switch (bmFmt) 01580 { 01581 // 01582 // 1 byte per pixel 01583 // 01584 01585 case BM_GRAY: 01586 nBytes = dwWidth; 01587 break; 01588 01589 // 01590 // 2 bytes per pixel 01591 // 01592 01593 case BM_x555RGB: 01594 case BM_x555XYZ: 01595 case BM_x555Yxy: 01596 case BM_x555Lab: 01597 case BM_x555G3CH: 01598 case BM_16b_GRAY: 01599 case BM_565RGB: 01600 nBytes = dwWidth*2; 01601 break; 01602 01603 // 01604 // 3 bytes per pixel 01605 // 01606 01607 case BM_BGRTRIPLETS: 01608 case BM_RGBTRIPLETS: 01609 case BM_XYZTRIPLETS: 01610 case BM_YxyTRIPLETS: 01611 case BM_LabTRIPLETS: 01612 case BM_G3CHTRIPLETS: 01613 nBytes = dwWidth*3; 01614 break; 01615 01616 // 01617 // 4 bytes per pixel 01618 // 01619 01620 case BM_xRGBQUADS: 01621 case BM_xBGRQUADS: 01622 #if 0 01623 case BM_xXYZQUADS: 01624 case BM_xYxyQUADS: 01625 case BM_xLabQUADS: 01626 #endif 01627 case BM_xG3CHQUADS: 01628 case BM_KYMCQUADS: 01629 case BM_CMYKQUADS: 01630 case BM_10b_RGB: 01631 case BM_10b_XYZ: 01632 case BM_10b_Yxy: 01633 case BM_10b_Lab: 01634 case BM_10b_G3CH: 01635 case BM_NAMED_INDEX: 01636 nBytes = dwWidth*4; 01637 break; 01638 01639 // 01640 // 5 bytes per pixel 01641 // 01642 01643 case BM_5CHANNEL: 01644 nBytes = dwWidth*5; 01645 break; 01646 01647 // 01648 // 6 bytes per pixel 01649 // 01650 01651 case BM_16b_RGB: 01652 case BM_16b_XYZ: 01653 case BM_16b_Yxy: 01654 case BM_16b_Lab: 01655 case BM_16b_G3CH: 01656 case BM_6CHANNEL: 01657 nBytes = dwWidth*6; 01658 break; 01659 01660 // 01661 // 7 bytes per pixel 01662 // 01663 01664 case BM_7CHANNEL: 01665 nBytes = dwWidth*7; 01666 break; 01667 01668 // 01669 // 8 bytes per pixel 01670 // 01671 01672 case BM_8CHANNEL: 01673 nBytes = dwWidth*8; 01674 break; 01675 01676 // 01677 // Error case 01678 // 01679 01680 default: 01681 nBytes = 0; 01682 break; 01683 } 01684 01685 // 01686 // Align to DWORD boundary 01687 // 01688 01689 nBytes = (nBytes + 3) & ~3; 01690 01691 return nBytes*dwHeight; 01692 } 01693 01694 01695

Generated on Sat May 15 19:39:29 2004 for test by doxygen 1.3.7