📄 cmimg.cpp
字号:
/*++
Routine Name:
CColorManagedImage::GetKeyName
Routine Description:
Method to obtain a unique key for the resource being handled
Arguments:
pbstrKeyName - Pointer to a string to hold the generated key
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CColorManagedImage::GetKeyName(
__deref_out BSTR* pbstrKeyName
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(pbstrKeyName, E_POINTER)))
{
if (m_bstrBitmapURI.Length() > 0)
{
*pbstrKeyName = NULL;
//
// The full URI to the bitmap resource concatenated with any associated
// profile is a suitable key
//
try
{
CStringXDW cstrKey(m_bstrBitmapURI);
cstrKey += m_bstrSrcProfileURI;
*pbstrKeyName = cstrKey.AllocSysString();
}
catch (CXDException& e)
{
hr = e;
}
}
else
{
hr = E_PENDING;
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CColorManagedImage::GetResURI
Routine Description:
Method to obtain the URI of the resource being handled
Arguments:
pbstrResURI - Pointer to a string to hold the resource URI
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CColorManagedImage::GetResURI(
__deref_out BSTR* pbstrResURI
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(pbstrResURI, E_POINTER)))
{
*pbstrResURI = NULL;
if (m_bstrBitmapURI.Length() > 0)
{
try
{
//
// Create a URI from the original bitmap URI and the current tick count
//
CStringXDW cstrFileName(m_bstrBitmapURI);
CStringXDW cstrFileExt(PathFindExtension(cstrFileName));
INT indFileExt = cstrFileName.Find(cstrFileExt);
if (indFileExt > -1)
{
cstrFileName.Delete(indFileExt, cstrFileExt.GetLength());
}
//
// Create a unique name for the bitmap for this print session using GetTickCount()
//
CStringXDW cstrURI;
cstrURI.Format(L"%s_%u.wdp", cstrFileName, GetTickCount());
SysFreeString(*pbstrResURI);
*pbstrResURI = cstrURI.AllocSysString();
}
catch (CXDException& e)
{
hr = e;
}
}
else
{
hr = E_PENDING;
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CColorManagedImage::SetSrcProfile
Routine Description:
Method to set the source color profile given a particular source bitmap
Arguments:
pSrcBmp - Pointer to the source bitmap
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CColorManagedImage::SetSrcProfile(
__in CBmpConverter* pSrcBmp
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(pSrcBmp, E_POINTER)))
{
//
// Update the source profile based on the source bitmap. The source profile
// is set according to the following rules:
//
// If the profile is embeded
// Use the embedded profile
// Else if the profile is specified in the ImageSource mark-up
// Use the profile in the container
// Else
// If the profile is RGB <= 16 bpc
// Use sRGB profile as source
// Else if the profile is RGB > 16 bpc
// Use scRGB profile as source
// Else if the profile is CMYK
// Use SWOP profile as source
//
if (pSrcBmp->HasColorProfile())
{
IWICColorContext* pSrcContext = NULL;
UINT cbBuffer = 0;
PBYTE pBuffer = NULL;
UINT cbActual = 0;
//
// We have a profile embedded in the bitmap - extract and set as the source profile
//
if (SUCCEEDED(hr = pSrcBmp->GetColorContext(&pSrcContext)) &&
SUCCEEDED(hr = pSrcContext->GetProfileBytes(cbBuffer, pBuffer, &cbActual)))
{
if (cbActual > 0)
{
pBuffer = new BYTE[cbActual];
cbBuffer = cbActual;
if (SUCCEEDED(hr = CHECK_POINTER(pBuffer, E_OUTOFMEMORY)) &&
SUCCEEDED(hr = pSrcContext->GetProfileBytes(cbBuffer, pBuffer, &cbActual)))
{
//
// Set the source profile in the profile manager. Note: in this instance the profile name is
// no used to load the profile, merely to cache the profile. The bitmap URI uniquely idenitifies
// the bitmap and hence the embedded profile and is appropriate as a cache name
//
hr = m_pProfManager->SetSrcProfileFromBuffer(m_bstrBitmapURI, pBuffer, cbBuffer);
}
if (pBuffer != NULL)
{
delete[] pBuffer;
pBuffer = NULL;
}
}
else
{
RIP("Zero length profile.\n");
hr = E_FAIL;
}
}
}
else if (m_bstrSrcProfileURI.Length() > 0)
{
//
// The mark-up references a profile in the XPS document - get the profile manager
// to extract it and set as the source profile
//
hr = m_pProfManager->SetSrcProfileFromContainer(m_bstrSrcProfileURI);
}
else
{
//
// Deduce the source profile from the source bitmap format
//
switch (pSrcBmp->GetPixelFormat())
{
case kWICPixelFormatDontCare:
case kWICPixelFormat1bppIndexed:
case kWICPixelFormat2bppIndexed:
case kWICPixelFormat4bppIndexed:
case kWICPixelFormat8bppIndexed:
case kWICPixelFormatBlackWhite:
case kWICPixelFormat2bppGray:
case kWICPixelFormat4bppGray:
case kWICPixelFormat8bppGray:
case kWICPixelFormat16bppBGR555:
case kWICPixelFormat16bppBGR565:
case kWICPixelFormat16bppGray:
case kWICPixelFormat24bppBGR:
case kWICPixelFormat24bppRGB:
case kWICPixelFormat32bppBGR:
case kWICPixelFormat32bppBGRA:
case kWICPixelFormat32bppPBGRA:
case kWICPixelFormat32bppBGR101010:
case kWICPixelFormat48bppRGB:
case kWICPixelFormat64bppRGBA:
case kWICPixelFormat64bppPRGBA:
{
hr = m_pProfManager->SetSrcProfileFromColDir(L"sRGB Color Space Profile.icm");
}
break;
case kWICPixelFormat48bppRGBFixedPoint:
case kWICPixelFormat96bppRGBFixedPoint:
case kWICPixelFormat128bppRGBAFloat:
case kWICPixelFormat128bppPRGBAFloat:
case kWICPixelFormat128bppRGBFloat:
case kWICPixelFormat64bppRGBAFixedPoint:
case kWICPixelFormat64bppRGBFixedPoint:
case kWICPixelFormat128bppRGBAFixedPoint:
case kWICPixelFormat128bppRGBFixedPoint:
case kWICPixelFormat64bppRGBAHalf:
case kWICPixelFormat64bppRGBHalf:
case kWICPixelFormat48bppRGBHalf:
case kWICPixelFormat32bppRGBE:
case kWICPixelFormat16bppGrayHalf:
case kWICPixelFormat32bppGrayFloat:
case kWICPixelFormat32bppGrayFixedPoint:
case kWICPixelFormat16bppGrayFixedPoint:
{
hr = m_pProfManager->SetSrcProfileFromColDir(L"xdwscRGB.icc");
}
break;
case kWICPixelFormat32bppCMYK:
case kWICPixelFormat64bppCMYK:
case kWICPixelFormat40bppCMYKAlpha:
case kWICPixelFormat80bppCMYKAlpha:
{
hr = m_pProfManager->SetSrcProfileFromColDir(L"xdCMYKPrinter.icc");
}
break;
default:
{
RIP("No acceptable default profile.\n");
hr = HRESULT_FROM_WIN32(ERROR_PROFILE_NOT_FOUND);
}
break;
}
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CColorManagedImage::TransformScanLines
Routine Description:
Given source and destination scanline iterators, this method applies the
requiresite color transform
Arguments:
pSrcScans - Pointer to the source scanline iterator
pDstScans - Pointer to the destination scanline iterator
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CColorManagedImage::TransformScanLines(
__in CScanIterator* pSrcScans,
__in CScanIterator* pDstScans
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(pSrcScans, E_POINTER)) &&
SUCCEEDED(hr = CHECK_POINTER(pDstScans, E_POINTER)))
{
try
{
//
// Apply the transform
//
HTRANSFORM hTransform = NULL;
BOOL bCanUseWCS = FALSE;
if (SUCCEEDED(hr = m_pProfManager->GetColorTransform(&hTransform, &bCanUseWCS)))
{
PBYTE pDstData = NULL;
BMFORMAT bmSrcFormat;
UINT cSrcWidth = 0;
UINT cSrcHeight = 0;
UINT cbSrcStride = 0;
PBYTE pSrcData = NULL;
BMFORMAT bmDstFormat;
UINT cDstWidth = 0;
UINT cDstHeight = 0;
UINT cbDstStride = 0;
//
// While the source andd destination have scanlines remaining to process...
//
while (!pDstScans->Finished() &&
!pSrcScans->Finished() &&
SUCCEEDED(hr))
{
//
// ...retrieve the scan buffers (these may have been processed to remove alpha data)...
//
if (SUCCEEDED(hr = pSrcScans->GetScanBuffer(&pSrcData, &bmSrcFormat, &cSrcWidth, &cSrcHeight, &cbSrcStride)) &&
SUCCEEDED(hr = pDstScans->GetScanBuffer(&pDstData, &bmDstFormat, &cDstWidth, &cDstHeight, &cbDstStride)))
{
//
// ...translate the scanline data...
//
if (TranslateBitmapBits(hTransform,
pSrcData,
bmSrcFormat,
cSrcWidth,
cSrcHeight,
cbSrcStride,
pDstData,
bmDstFormat,
cbDstStride,
NULL,
0))
{
//
// ...and commit the data to the destination bitmap before incrementing to the next scanline.
//
hr = pDstScans->Commit(*pSrcScans);
(*pSrcScans)++;
(*pDstScans)++;
}
else
{
RIP("Translate bitmap bits failed.\n");
hr = GetLastErrorAsHResult();
}
}
}
}
}
catch (CXDException& e)
{
hr = e;
}
}
ERR_ON_HR(hr);
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -