in wia/ProdScan/Validate.cpp [56:595]
HRESULT CWiaDriver::ValidateFormatProperties(
_In_ BYTE* pWiasContext,
_In_ WIA_PROPERTY_CONTEXT* pPropertyContext,
UINT nDocumentHandlingSelect)
{
HRESULT hr = S_OK;
LONG lDataType = WIA_DATA_COLOR;
LONG lIntent = WIA_INTENT_NONE;
LONG lDepth = 24;
LONG lChannelsPerPixel = 3;
LONG lBitsPerChannel = 8;
GUID guidFormat = WiaImgFmt_UNDEFINED;
LONG lCompression = WIA_COMPRESSION_NONE;
BSTR bstrFileExtension = NULL;
BYTE bRawBitsPerChannel[3] = {};
BOOL bDataTypeChanged = FALSE;
BOOL bIntentChanged = FALSE;
BOOL bImageTypeIntentChanged = FALSE;
BOOL bDepthChanged = FALSE;
BOOL bFormatChanged = FALSE;
BOOL bCompressionChanged = FALSE;
PROPSPEC ps[3] = {};
ULONG nPropSpec = 0;
if ((!pWiasContext) || (!pPropertyContext))
{
hr = E_INVALIDARG;
WIAEX_ERROR((g_hInst, "Invalid parameters, hr = 0x%08X", hr));
}
if (SUCCEEDED(hr))
{
//
// Check which color properties have been changed (ignore failures).
// Note that the Auto item supports only format, tymed and compression:
//
if ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect))
{
wiasIsPropChanged(WIA_IPA_DATATYPE, pPropertyContext, &bDataTypeChanged);
wiasIsPropChanged(WIA_IPS_CUR_INTENT, pPropertyContext, &bIntentChanged);
wiasIsPropChanged(WIA_IPA_DEPTH, pPropertyContext, &bDepthChanged);
}
wiasIsPropChanged(WIA_IPA_FORMAT, pPropertyContext, &bFormatChanged);
wiasIsPropChanged(WIA_IPA_COMPRESSION, pPropertyContext, &bCompressionChanged);
if ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect))
{
//
// Read the current WIA_IPS_CUR_INTENT value:
//
if (SUCCEEDED(hr))
{
hr = wiasReadPropLong(pWiasContext, WIA_IPS_CUR_INTENT, &lIntent, NULL, TRUE);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Error reading current WIA_IPS_CUR_INTENT, hr = 0x%08X", hr));
}
}
//
// When the intent is changed check if an image type intent flag is set:
//
if (SUCCEEDED(hr))
{
bImageTypeIntentChanged = (BOOL)(bIntentChanged && (WIA_INTENT_IMAGE_TYPE_MASK & lIntent));
}
}
}
//
// Read the other current property values (no matter if each respective property was changed or not):
//
if (SUCCEEDED(hr) && (bDataTypeChanged || bIntentChanged || bDepthChanged) &&
((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect)))
{
hr = wiasReadPropLong(pWiasContext, WIA_IPA_DATATYPE, &lDataType, NULL, TRUE);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_DATATYPE, hr = 0x%08X", hr));
}
if (SUCCEEDED(hr))
{
hr = wiasReadPropLong(pWiasContext, WIA_IPA_DEPTH, &lDepth, NULL, TRUE);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_DEPTH, hr = 0x%08X", hr));
}
}
}
if (SUCCEEDED(hr) && (bFormatChanged || bCompressionChanged))
{
hr = wiasReadPropLong(pWiasContext, WIA_IPA_COMPRESSION, &lCompression, NULL, TRUE);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_COMPRESSION, hr = 0x%08X", hr));
}
if (SUCCEEDED(hr))
{
hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormat, NULL, TRUE);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Error reading current WIA_IPA_FORMAT, hr = 0x%08X", hr));
}
}
}
//
// If the application changed the image type intent the driver must consider
// that WIA_IPA_DATA_TYPE was changed to the value apropriate for the new
// intent no matter if the application set WIA_IPA_DATA_TYPE and to what value:
//
if (SUCCEEDED(hr) && bImageTypeIntentChanged)
{
//
// If multiple color intents are set at the same time consider
// just one and give the highest priority to highest bitdepth:
//
if (WIA_INTENT_IMAGE_TYPE_COLOR & lIntent)
{
bDataTypeChanged = TRUE;
lDataType = WIA_DATA_COLOR;
}
else if (WIA_INTENT_IMAGE_TYPE_GRAYSCALE & lIntent)
{
bDataTypeChanged = TRUE;
lDataType = WIA_DATA_GRAYSCALE;
}
}
//
// Validate the new current values against the total supported values for
// each of the changed properties with write access in this category:
//
// WIA_IPA_DATATYPE
// WIA_IPS_CUR_INTENT
// WIA_IPA_DEPTH
// WIA_IPA_FORMAT
// WIA_IPA_TYMED (skipped here since its value cannot be changed for this driver)
// WIA_IPA_COMPRESSION
//
// This sample driver can validate color and format properties separately
// since none of its color modes (WIA_IPA_DATATYPE and WIA_IPA_DEPTH
// combinations) are dependent on format changes (WIA_IPA_FORMAT,
// WIA_IPA_TYMED -ignored here- and WIA_IPA_COMPRESSION combinations).
// If the driver would also support WIA_DATA_BW, WIA_COMPRESSION_G4
// and WiaImgFmt_TIFF the driver would need to validate all the color
// and format properties together (for example WIA_DATA_BW and
// WIA_COMPRESSION_G4 do neither work with WiaImgFmt_EXIF).
//
if (SUCCEEDED(hr) && ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect)) &&
(bDataTypeChanged || bIntentChanged || bDepthChanged))
{
nPropSpec = 0;
if (bDataTypeChanged)
{
ps[nPropSpec].ulKind = PRSPEC_PROPID;
ps[nPropSpec].propid = WIA_IPA_DATATYPE;
nPropSpec++;
}
if (bIntentChanged)
{
ps[nPropSpec].ulKind = PRSPEC_PROPID;
ps[nPropSpec].propid = WIA_IPS_CUR_INTENT;
nPropSpec++;
}
if (bDepthChanged)
{
ps[nPropSpec].ulKind = PRSPEC_PROPID;
ps[nPropSpec].propid = WIA_IPA_DEPTH;
nPropSpec++;
}
hr = wiasValidateItemProperties(pWiasContext, nPropSpec, ps);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Invalid color property value(s) requested, hr = 0x%08X", hr));
}
}
if (SUCCEEDED(hr) && (bFormatChanged || bCompressionChanged))
{
nPropSpec = 0;
if (bFormatChanged)
{
ps[nPropSpec].ulKind = PRSPEC_PROPID;
ps[nPropSpec].propid = WIA_IPA_FORMAT;
nPropSpec++;
}
if (bCompressionChanged)
{
ps[nPropSpec].ulKind = PRSPEC_PROPID;
ps[nPropSpec].propid = WIA_IPA_COMPRESSION;
nPropSpec++;
}
hr = wiasValidateItemProperties(pWiasContext, nPropSpec, ps);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Invalid format property value(s) requested, hr = 0x%08X", hr));
}
}
//
// Additional validation for WIA_IPA_DATATYPE and WIA_IPA_DEPTH:
//
if (SUCCEEDED(hr) && ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect)) &&
(bDataTypeChanged || bDepthChanged))
{
if (bDataTypeChanged && bDepthChanged)
{
if (((WIA_DATA_COLOR == lDataType) && (8 == lDepth)) ||
((WIA_DATA_GRAYSCALE == lDataType) && (24 == lDepth)))
{
hr = E_INVALIDARG;
WIAEX_ERROR((g_hInst, "Unsupported data type (%u) - depth (%u) combination requested, hr = 0x%08X",
lDataType, lDepth, hr));
}
}
else if (bDataTypeChanged && (!bDepthChanged))
{
if (WIA_DATA_COLOR == lDataType)
{
lDepth = 24;
}
else if (WIA_DATA_GRAYSCALE == lDataType)
{
lDepth = 8;
}
else if (WIA_DATA_AUTO == lDataType)
{
lDepth = WIA_DEPTH_AUTO;
}
}
else if ((!bDataTypeChanged) && bDepthChanged)
{
if (8 == lDepth)
{
lDataType = WIA_DATA_GRAYSCALE;
}
else if (24 == lDepth)
{
lDataType = WIA_DATA_COLOR;
}
else if (WIA_DEPTH_AUTO == lDepth)
{
lDataType = WIA_DATA_AUTO;
}
}
}
//
// Additional validation for WIA_IPA_FORMAT and WIA_IPA_COMPRESSION (skipped for the
// sample non-image sources since those do not support compresssed data transfers):
//
if (SUCCEEDED(hr) && ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect) ||
(AUTO_SOURCE == nDocumentHandlingSelect)) && (bFormatChanged || bCompressionChanged))
{
if (bFormatChanged && (!bCompressionChanged))
{
//
// If WIA_IPA_FORMAT if changed alone, update WIA_IPA_COMPRESSION to match:
//
if (IsEqualGUID(guidFormat, WiaImgFmt_EXIF))
{
lCompression = WIA_COMPRESSION_JPEG;
}
else if (IsEqualGUID(guidFormat, WiaImgFmt_BMP) || IsEqualGUID(guidFormat, WiaImgFmt_RAW))
{
lCompression = WIA_COMPRESSION_NONE;
}
}
else if ((!bFormatChanged) && bCompressionChanged)
{
//
// If WIA_IPA_COMPRESSION if changed alone, update WIA_IPA_FORMAT to match:
//
if ((WIA_COMPRESSION_JPEG == lCompression) || (WIA_COMPRESSION_AUTO == lCompression))
{
guidFormat = WiaImgFmt_EXIF;
}
else if (WIA_COMPRESSION_NONE == lCompression)
{
guidFormat = WiaImgFmt_BMP;
}
}
else if (bFormatChanged && bCompressionChanged)
{
//
// If both WIA_IPA_FORMAT and WIA_IPA_COMPRESSION are changed, verify that their values work together:
//
if (((WIA_COMPRESSION_NONE == lCompression) && IsEqualGUID(guidFormat, WiaImgFmt_EXIF)) ||
(((WIA_COMPRESSION_JPEG == lCompression) || (WIA_COMPRESSION_AUTO == lCompression)) &&
(IsEqualGUID(guidFormat, WiaImgFmt_BMP) || IsEqualGUID(guidFormat, WiaImgFmt_RAW))))
{
hr = E_INVALIDARG;
WIAEX_ERROR((g_hInst, "Unsupported file format - compression mode combination, hr = 0x%08X", hr));
}
}
}
//
// Update current values:
//
if (SUCCEEDED(hr) && ((FLAT == nDocumentHandlingSelect) || (FEED == nDocumentHandlingSelect)) &&
(bDataTypeChanged || bIntentChanged || bDepthChanged))
{
//
// WIA_IPA_DATATYPE:
//
hr = wiasWritePropLong(pWiasContext, WIA_IPA_DATATYPE, lDataType);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_DATATYPE, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPA_DATATYPE, pPropertyContext, TRUE);
}
//
// WIA_IPS_CUR_INTENT
//
// If an image type intent is set we must make sure it matches the current WIA_IPA_DATATYPE.
// Don't do anything if the application changes any of the other intent flags.
//
if (SUCCEEDED(hr) && (lIntent & WIA_INTENT_IMAGE_TYPE_MASK))
{
//
// Reset all current image type intent flags.
//
lIntent &= ~ WIA_INTENT_IMAGE_TYPE_MASK;
//
// .. and add just the one apropriate with the current WIA_IPA_DATATYPE value:
//
switch (lDataType)
{
case WIA_DATA_COLOR:
lIntent |= WIA_INTENT_IMAGE_TYPE_COLOR;
break;
case WIA_DATA_GRAYSCALE:
lIntent |= WIA_INTENT_IMAGE_TYPE_GRAYSCALE;
}
hr = wiasWritePropLong(pWiasContext, WIA_IPS_CUR_INTENT, lIntent);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPS_CUR_INTENT, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPS_CUR_INTENT, pPropertyContext, TRUE);
}
}
//
// WIA_IPA_DEPTH:
//
if (SUCCEEDED(hr))
{
hr = wiasWritePropLong(pWiasContext, WIA_IPA_DEPTH, lDepth);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_DEPTH, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPA_DEPTH, pPropertyContext, TRUE);
}
}
//
// WIA_IPA_CHANNELS_PER_PIXEL:
//
if (SUCCEEDED(hr))
{
lChannelsPerPixel = (24 == lDepth) ? 3 : 1;
hr = wiasWritePropLong(pWiasContext, WIA_IPA_CHANNELS_PER_PIXEL, lChannelsPerPixel);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_CHANNELS_PER_PIXEL, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPA_CHANNELS_PER_PIXEL, pPropertyContext, TRUE);
}
}
//
// WIA_IPA_BITS_PER_CHANNEL:
//
if (SUCCEEDED(hr))
{
lBitsPerChannel = 8;
hr = wiasWritePropLong(pWiasContext, WIA_IPA_BITS_PER_CHANNEL, lBitsPerChannel);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_BITS_PER_CHANNEL, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPA_BITS_PER_CHANNEL, pPropertyContext, TRUE);
}
}
//
// WIA_IPA_RAW_BITS_PER_CHANNEL
//
if (SUCCEEDED(hr))
{
for (int i = 0; i < lChannelsPerPixel; i++)
{
bRawBitsPerChannel[i] = 8;
}
hr = wiasWritePropBin(pWiasContext, WIA_IPA_RAW_BITS_PER_CHANNEL, lChannelsPerPixel, bRawBitsPerChannel);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_RAW_BITS_PER_CHANNEL, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPA_RAW_BITS_PER_CHANNEL, pPropertyContext, TRUE);
}
}
}
if (SUCCEEDED(hr) && (bFormatChanged || bCompressionChanged))
{
//
// WIA_IPA_COMPRESSION:
//
if (SUCCEEDED(hr))
{
hr = wiasWritePropLong(pWiasContext, WIA_IPA_COMPRESSION, lCompression);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_COMPRESSION, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPA_COMPRESSION, pPropertyContext, TRUE);
}
}
//
// WIA_IPA_FORMAT:
//
if (SUCCEEDED(hr))
{
hr = wiasWritePropGuid(pWiasContext, WIA_IPA_FORMAT, guidFormat);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_FORMAT, hr = 0x%08X", hr));
}
else
{
wiasSetPropChanged(WIA_IPA_COMPRESSION, pPropertyContext, TRUE);
}
}
//
// WIA_IPA_FILENAME_EXTENSION:
//
if (SUCCEEDED(hr))
{
if (IsEqualGUID(guidFormat, WiaImgFmt_BMP))
{
bstrFileExtension = SysAllocString(FILE_EXT_BMP);
}
else if (IsEqualGUID(guidFormat, WiaImgFmt_EXIF))
{
bstrFileExtension = SysAllocString(FILE_EXT_JPG);
}
else if (IsEqualGUID(guidFormat, WiaImgFmt_RAW) || IsEqualGUID(guidFormat, WiaImgFmt_RAWBAR) ||
IsEqualGUID(guidFormat, WiaImgFmt_RAWPAT) || IsEqualGUID(guidFormat, WiaImgFmt_RAWMIC))
{
bstrFileExtension = SysAllocString(FILE_EXT_RAW);
}
else if (IsEqualGUID(guidFormat, WiaImgFmt_CSV))
{
bstrFileExtension = SysAllocString(FILE_EXT_CSV);
}
else if (IsEqualGUID(guidFormat, WiaImgFmt_TXT))
{
bstrFileExtension = SysAllocString(FILE_EXT_TXT);
}
else if (IsEqualGUID(guidFormat, WiaImgFmt_XMLBAR) || IsEqualGUID(guidFormat, WiaImgFmt_XMLPAT) ||
IsEqualGUID(guidFormat, WiaImgFmt_XMLMIC))
{
bstrFileExtension = SysAllocString(FILE_EXT_XML);
}
else
{
hr = E_FAIL;
WIAEX_ERROR((g_hInst, "Unsupported file format, hr = 0x%08X", hr));
}
}
if (SUCCEEDED(hr) && (!bstrFileExtension))
{
hr = E_OUTOFMEMORY;
WIAEX_ERROR((g_hInst, "Unable to allocate memory for new file extension, hr = 0x%08X", hr));
}
if (SUCCEEDED(hr))
{
hr = wiasWritePropStr(pWiasContext, WIA_IPA_FILENAME_EXTENSION, bstrFileExtension);
if (FAILED(hr))
{
WIAEX_ERROR((g_hInst, "Failed to update WIA_IPA_FILENAME_EXTENSION, hr = 0x%08X", hr));
}
}
}
if (bstrFileExtension)
{
SysFreeString(bstrFileExtension);
}
return hr;
}