📄 wictobmscn.cpp
字号:
}
}
else
{
//
// Set the out buffer pointer and size to the WIC pixel data
//
m_pData = pWicPxData;
m_cbData = cbWicPxData;
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CWICToBMFormatScan::Commit
Routine Description:
Commits the internal scanline data to the WIC data buffer
Arguments:
pWicPxData - Pointer to the WIC data
cbWicPxData - Count of bytes in the WIC data buffer
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CWICToBMFormatScan::Commit(
__in_bcount(cbWicPxData) PBYTE pWicPxData,
__in CONST UINT cbWicPxData
)
{
HRESULT hr = m_bInitialized ? S_OK : E_PENDING;
COLORDATATYPE srcColType = COLOR_BYTE;
EICMPixelFormat eICMFormSrc = kBM_RGBTRIPLETS;
COLORDATATYPE dstColType = COLOR_BYTE;
EICMPixelFormat eICMFormDst = kBM_RGBTRIPLETS;
//
// Validate input
//
if (SUCCEEDED(hr) &&
SUCCEEDED(hr = CHECK_POINTER(pWicPxData, E_POINTER)))
{
if (m_convData.m_pixFormTarget >= kWICPixelFormatMin &&
m_convData.m_pixFormTarget < kWICPixelFormatMax)
{
//
// Set up the destination and source formats
//
eICMFormDst = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_bmFormTarget;
dstColType = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_colDataType;
if (m_convData.m_bmFormTarget < kICMPixelFormatMax &&
m_convData.m_bmFormTarget >= kICMPixelFormatMin)
{
eICMFormSrc = m_convData.m_bmFormTarget;
srcColType = g_lutBMFormatData[eICMFormSrc].m_colDataType;
}
else
{
hr = E_FAIL;
}
}
else
{
hr = E_FAIL;
}
}
//
// Validate source and destination formats
//
if (SUCCEEDED(hr))
{
if (eICMFormSrc < kICMPixelFormatMin ||
eICMFormSrc >= kICMPixelFormatMax ||
eICMFormDst < kICMPixelFormatMin ||
eICMFormDst >= kICMPixelFormatMax)
{
RIP("Invalid pixel format.\n");
hr = E_FAIL;
}
else if (srcColType < COLOR_BYTE ||
srcColType > COLOR_S2DOT13FIXED ||
dstColType < COLOR_BYTE ||
dstColType > COLOR_S2DOT13FIXED)
{
RIP("Invalid color data type.\n");
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
if (pWicPxData != m_pData)
{
//
// We need to convert the scan buffer and write back into the WIC buffer
//
PBYTE pDst = pWicPxData;
UINT cDstChannels = g_lutWICToBMFormat[m_convData.m_pixFormTarget].m_cChannels;
size_t cbDstBytesPerPixel = g_lutColorDataSize[dstColType] * cDstChannels;
PBYTE pSrc = m_pScanBuffer;
UINT cSrcChannels = g_lutBMFormatData[eICMFormSrc].m_cChannels;
size_t cbSrcBytesPerPixel = g_lutColorDataSize[srcColType] * cSrcChannels;
PBYTE pSrcEnd = pSrc + m_cbScanBuffer;
PBYTE pDstEnd = pDst + cbWicPxData;
if (srcColType == m_convData.m_colDataType)
{
while (pSrc < pSrcEnd &&
pDst < pDstEnd)
{
if (pDst + cbSrcBytesPerPixel < pDstEnd)
{
CopyMemory(pDst, pSrc, cbSrcBytesPerPixel);
}
pSrc += cbSrcBytesPerPixel;
pDst += cbDstBytesPerPixel;
}
}
else
{
//
// We should only ever be required to convert from 16 bpc RGB to floating point
// and fixed point scRGB formats
//
if (eICMFormSrc == kBM_16b_RGB &&
(eICMFormDst == kBM_32b_scRGB ||
eICMFormDst == kBM_32b_scARGB))
{
WORD* pSrcData = reinterpret_cast<WORD*>(pSrc);
FLOAT* pDstData = reinterpret_cast<FLOAT*>(pDst);
UINT cAlpha = eICMFormDst == kBM_32b_scARGB ? 1 : 0;
while (pSrcData <= reinterpret_cast<WORD*>(pSrcEnd) - cSrcChannels &&
pDstData <= reinterpret_cast<FLOAT*>(pDstEnd) - cDstChannels)
{
pDstData += cAlpha;
for (UINT cChan = 0;
cChan < (cDstChannels - cAlpha) && cChan < cSrcChannels;
cChan++)
{
//
// Note: We are only converting to FLOAT and not applying gamma modification
// as the transform should account for this given the input scRGB ICC source profile.
//
pDstData[cChan] = (4.0f * static_cast<FLOAT>(pSrcData[cChan]) / kMaxWordAsFloat) - 2.0f;
}
pSrcData += cSrcChannels;
pDstData += cDstChannels - cAlpha;
}
}
else if (eICMFormSrc == kBM_16b_RGB &&
(eICMFormDst == kBM_S2DOT13FIXED_scRGB ||
eICMFormDst == kBM_S2DOT13FIXED_scARGB))
{
WORD* pSrcData = reinterpret_cast<WORD*>(pSrc);
WORD* pDstData = reinterpret_cast<WORD*>(pDst);
UINT cAlpha = eICMFormDst == kBM_S2DOT13FIXED_scARGB ? 1 : 0;
while (pSrcData <= reinterpret_cast<WORD*>(pSrcEnd) - cSrcChannels &&
pDstData <= reinterpret_cast<WORD*>(pDstEnd) - cDstChannels)
{
pDstData += cAlpha;
for (UINT cChan = 0;
cChan < (cDstChannels - cAlpha) && cChan < cSrcChannels;
cChan++)
{
//
// Note: We are only converting to S2DOT13FIXED and not applying gamma modification
// as the transform should account for this given the input scRGB ICC source profile.
//
pDstData[cChan] = pSrcData[cChan] & kS2Dot13Neg ?
pSrcData[cChan] ^ kS2Dot13Neg : pSrcData[cChan] ^ 0xFFFF;
}
pSrcData += cSrcChannels;
pDstData += cDstChannels - cAlpha;
}
}
else
{
hr = E_NOTIMPL;
}
}
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CWICToBMFormatScan::GetData
Routine Description:
Retrieves the BMFORMAT buffer ready for processing
Arguments:
ppData - Pointer to a pointer that recieves the address of the data buffer.
Note: the buffer is only valid for the lifetime of the CWICToBMFormatScan object.
pBmFormat - Pointer to a BMFORMAT enum that recieves the type
pcWidth - Pointer to storage that recieves the pixel width
pcbStride - Pointer to storage that recieves the scanline stride
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CWICToBMFormatScan::GetData(
__deref_out_bcount(*pcbStride) PBYTE* ppData,
__out BMFORMAT* pBmFormat,
__out UINT* pcWidth,
__out UINT* pcbStride
)
{
HRESULT hr = S_OK;
if (SUCCEEDED(hr = CHECK_POINTER(ppData, E_POINTER)) &&
SUCCEEDED(hr = CHECK_POINTER(pBmFormat, E_POINTER)) &&
SUCCEEDED(hr = CHECK_POINTER(pcWidth, E_POINTER)) &&
SUCCEEDED(hr = CHECK_POINTER(pcbStride, E_POINTER)) &&
SUCCEEDED(hr = CHECK_POINTER(m_pData, E_PENDING)))
{
if (m_convData.m_bmFormTarget >= kICMPixelFormatMin &&
m_convData.m_bmFormTarget < kICMPixelFormatMax)
{
*pBmFormat = g_lutBMFormatData[m_convData.m_bmFormTarget].m_bmFormat;
*pcWidth = m_cWidth;
*ppData = m_pData;
*pcbStride = static_cast<UINT>(m_cbData);
}
else
{
hr = E_FAIL;
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CWICToBMFormatScan::CreateScanBuffer
Routine Description:
Creates the intermediate scanline buffer
Arguments:
cWidth - Pixel width of the scanline
Return Value:
HRESULT
S_OK - On success
E_* - On error
--*/
HRESULT
CWICToBMFormatScan::CreateScanBuffer(
__in CONST UINT cWidth,
__in CONST SIZE_T cbDataType,
__in CONST UINT cChannels
)
{
HRESULT hr = S_OK;
if (cWidth > MAX_PIXELWIDTH_COUNT ||
cbDataType > MAX_COLDATATYPE_SIZE ||
cChannels > MAX_COLCHANNEL_COUNT)
{
hr = E_INVALIDARG;
}
size_t cbScanBuffer = 0;
if (SUCCEEDED(hr))
{
if (FAILED(SizeTMult(cWidth, cbDataType, &cbScanBuffer)) ||
FAILED(SizeTMult(cbScanBuffer, cChannels, &cbScanBuffer)))
{
hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
}
}
if (SUCCEEDED(hr))
{
if (cbScanBuffer != m_cbScanBuffer)
{
FreeScanBuffer();
m_pScanBuffer = new BYTE[cbScanBuffer];
if (SUCCEEDED(hr = CHECK_POINTER(m_pScanBuffer, E_OUTOFMEMORY)))
{
m_cbScanBuffer = cbScanBuffer;
}
}
}
ERR_ON_HR(hr);
return hr;
}
/*++
Routine Name:
CWICToBMFormatScan::FreeScanBuffer
Routine Description:
Free the intermediate scanline buffer
Arguments:
None
Return Value:
None
--*/
VOID
CWICToBMFormatScan::FreeScanBuffer(
VOID
)
{
if (m_pScanBuffer != NULL)
{
delete[] m_pScanBuffer;
m_pScanBuffer = NULL;
}
m_cbScanBuffer = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -