You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
525 lines
12 KiB
525 lines
12 KiB
/**************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORP., 2002
|
|
*
|
|
* TITLE: scanapi.cpp
|
|
*
|
|
* VERSION: 1.1
|
|
*
|
|
* DATE: 05 March, 2002
|
|
*
|
|
* DESCRIPTION:
|
|
* Fake Scanner device library. This is a fake scanner library, intended
|
|
* to simulate a scanner device. This should only be used for testing
|
|
* purposes.
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "pch.h"
|
|
#include "scanapi.h"
|
|
#include <time.h>
|
|
|
|
CFakeScanAPI::CFakeScanAPI()
|
|
{
|
|
m_lLastEvent = ID_FAKE_NOEVENT;
|
|
m_hrLastADFError = S_OK;
|
|
m_bGreen = TRUE;
|
|
m_dwBytesWrittenSoFAR = 0;
|
|
m_TotalDataInDevice = 0;
|
|
m_PagesInADF = MAX_PAGE_CAPACITY;
|
|
|
|
memset(&m_RawDataInfo, 0,sizeof(RAW_DATA_INFORMATION));
|
|
memset(&m_SrcDataInfo, 0,sizeof(RAW_DATA_INFORMATION));
|
|
}
|
|
|
|
CFakeScanAPI::~CFakeScanAPI()
|
|
{
|
|
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_Initialize()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_GetRootPropertyInfo(PROOT_ITEM_INFORMATION pRootItemInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Fill in Root item property defaults
|
|
//
|
|
|
|
if (m_lMode == UNKNOWN_FEEDER_ONLY_SCANNER_MODE) {
|
|
pRootItemInfo->DocumentFeederCaps = FEEDER;
|
|
pRootItemInfo->DocumentFeederStatus = FEED_READY;
|
|
pRootItemInfo->DocumentFeederHReg = CENTERED;
|
|
pRootItemInfo->DocumentFeederReg = CENTERED;
|
|
} else {
|
|
pRootItemInfo->DocumentFeederCaps = FEEDER|FLATBED;
|
|
pRootItemInfo->DocumentFeederStatus = FLAT_READY;
|
|
pRootItemInfo->DocumentFeederHReg = LEFT_JUSTIFIED;
|
|
pRootItemInfo->DocumentFeederReg = LEFT_JUSTIFIED;
|
|
}
|
|
|
|
pRootItemInfo->DocumentFeederWidth = 8500;
|
|
pRootItemInfo->DocumentFeederHeight = 11000;
|
|
pRootItemInfo->DocumentFeederHReg = LEFT_JUSTIFIED;
|
|
pRootItemInfo->DocumentFeederReg = LEFT_JUSTIFIED;
|
|
pRootItemInfo->DocumentFeederVReg = TOP_JUSTIFIED;
|
|
pRootItemInfo->MaxPageCapacity = MAX_PAGE_CAPACITY;
|
|
pRootItemInfo->MaxScanTime = MAX_SCANNING_TIME;
|
|
pRootItemInfo->OpticalXResolution = 300;
|
|
pRootItemInfo->OpticalYResolution = 300;
|
|
pRootItemInfo->ScanBedWidth = 8500;
|
|
pRootItemInfo->ScanBedHeight = 11000;
|
|
|
|
//
|
|
// copy firmware version in string form to WCHAR array
|
|
//
|
|
|
|
lstrcpyW(pRootItemInfo->FirmwareVersion,L"1.0a");
|
|
|
|
return hr;
|
|
}
|
|
HRESULT CFakeScanAPI::FakeScanner_GetTopPropertyInfo(PTOP_ITEM_INFORMATION pTopItemInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
pTopItemInfo->bUseResolutionList = TRUE; // use default resolution list
|
|
|
|
pTopItemInfo->Brightness.lInc = 1;
|
|
pTopItemInfo->Brightness.lMax = 1000;
|
|
pTopItemInfo->Brightness.lMin = -1000;
|
|
pTopItemInfo->Brightness.lNom = 0;
|
|
|
|
pTopItemInfo->Contrast.lInc = 1;
|
|
pTopItemInfo->Contrast.lMax = 1000;
|
|
pTopItemInfo->Contrast.lMin = -1000;
|
|
pTopItemInfo->Contrast.lNom = 0;
|
|
|
|
pTopItemInfo->Threshold.lInc = 1;
|
|
pTopItemInfo->Threshold.lMax = 1000;
|
|
pTopItemInfo->Threshold.lMin = -1000;
|
|
pTopItemInfo->Threshold.lNom = 0;
|
|
|
|
pTopItemInfo->lMaxLampWarmupTime = MAX_LAMP_WARMUP_TIME;
|
|
pTopItemInfo->lMinimumBufferSize = 262140;
|
|
|
|
pTopItemInfo->XResolution.lInc = 1;
|
|
pTopItemInfo->XResolution.lMax = 600;
|
|
pTopItemInfo->XResolution.lMin = 75;
|
|
pTopItemInfo->XResolution.lNom = 150;
|
|
|
|
pTopItemInfo->YResolution.lInc = 1;
|
|
pTopItemInfo->YResolution.lMax = 600;
|
|
pTopItemInfo->YResolution.lMin = 75;
|
|
pTopItemInfo->YResolution.lNom = 150;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_Scan(LONG lState, PBYTE pData, DWORD dwBytesToRead, PDWORD pdwBytesWritten)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (lState) {
|
|
case SCAN_START:
|
|
m_dwBytesWrittenSoFAR = 0;
|
|
m_TotalDataInDevice = CalcRandomDeviceDataTotalBytes();
|
|
break;
|
|
case SCAN_CONTINUE:
|
|
break;
|
|
case SCAN_END:
|
|
m_bGreen = TRUE; // set back to green
|
|
return S_OK;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (NULL != pData) {
|
|
switch (m_RawDataInfo.bpp) {
|
|
case 24:
|
|
{
|
|
//
|
|
// write green data for color
|
|
//
|
|
|
|
BYTE *pTempData = pData;
|
|
for (DWORD dwBytes = 0; dwBytes < dwBytesToRead; dwBytes+=3) {
|
|
if (m_bGreen) {
|
|
pTempData[0] = 0;
|
|
pTempData[1] = 128; // green
|
|
pTempData[2] = 0;
|
|
} else {
|
|
pTempData[0] = 0;
|
|
pTempData[1] = 0;
|
|
pTempData[2] = 128; // blue
|
|
}
|
|
pTempData += 3;
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
case 8:
|
|
default:
|
|
|
|
//
|
|
// write simple gray for grayscale,
|
|
// write vertical B/W stripes for threshold
|
|
//
|
|
|
|
if (m_bGreen) {
|
|
memset(pData,128,dwBytesToRead);
|
|
} else {
|
|
memset(pData,200,dwBytesToRead);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// fill out bytes written
|
|
//
|
|
|
|
if (NULL != pdwBytesWritten) {
|
|
*pdwBytesWritten = dwBytesToRead;
|
|
}
|
|
|
|
if (m_bGreen) {
|
|
m_bGreen = FALSE;
|
|
} else {
|
|
m_bGreen = TRUE;
|
|
}
|
|
|
|
if (m_lMode == UNKNOWN_FEEDER_ONLY_SCANNER_MODE) {
|
|
|
|
//
|
|
// keep track of bytes written so far
|
|
//
|
|
|
|
if (m_TotalDataInDevice == 0) {
|
|
|
|
//
|
|
// no data left in device
|
|
//
|
|
|
|
*pdwBytesWritten = 0;
|
|
return hr;
|
|
}
|
|
|
|
if ((LONG)dwBytesToRead > m_TotalDataInDevice) {
|
|
|
|
//
|
|
// only give what is left in device
|
|
//
|
|
|
|
*pdwBytesWritten = dwBytesToRead;
|
|
m_TotalDataInDevice = 0;
|
|
} else {
|
|
|
|
//
|
|
// give full amount requested
|
|
//
|
|
|
|
m_TotalDataInDevice -= dwBytesToRead;
|
|
if (m_TotalDataInDevice < 0) {
|
|
m_TotalDataInDevice = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_SetDataType(LONG lDataType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
switch (lDataType) {
|
|
case WIA_DATA_COLOR:
|
|
m_RawDataInfo.bpp = 24;
|
|
break;
|
|
case WIA_DATA_THRESHOLD:
|
|
m_RawDataInfo.bpp = 1;
|
|
break;
|
|
case WIA_DATA_GRAYSCALE:
|
|
m_RawDataInfo.bpp = 8;
|
|
break;
|
|
default:
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_SetXYResolution(LONG lXResolution, LONG lYResolution)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
m_RawDataInfo.lXRes = lXResolution;
|
|
m_RawDataInfo.lYRes = lYResolution;
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_SetSelectionArea(LONG lXPos, LONG lYPos, LONG lXExt, LONG lYExt)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// record RAW data width and height
|
|
//
|
|
|
|
m_RawDataInfo.lWidthPixels = lXExt;
|
|
m_RawDataInfo.lHeightPixels = lYExt;
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_SetContrast(LONG lContrast)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// do nothing.. we are not concerned with Contrast
|
|
//
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_SetIntensity(LONG lIntensity)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// do nothing.. we are not concerned with Intensity
|
|
//
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_DisableDevice()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_EnableDevice()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_DeviceOnline()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_Diagnostic()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_GetBedWidthAndHeight(PLONG pWidth, PLONG pHeight)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
//
|
|
// get our Root item settings, so we can use the width and height values
|
|
//
|
|
|
|
ROOT_ITEM_INFORMATION RootItemInfo;
|
|
hr = FakeScanner_GetRootPropertyInfo(&RootItemInfo);
|
|
if (SUCCEEDED(hr)) {
|
|
*pWidth = RootItemInfo.ScanBedWidth;
|
|
*pHeight = RootItemInfo.ScanBedHeight;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// standard device operations
|
|
//
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_ResetDevice()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_SetEmulationMode(LONG lDeviceMode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (lDeviceMode) {
|
|
case UNKNOWN_FEEDER_ONLY_SCANNER_MODE:
|
|
m_lMode = UNKNOWN_FEEDER_ONLY_SCANNER_MODE;
|
|
break;
|
|
case FLATBED_SCANNER_MODE:
|
|
m_lMode = FLATBED_SCANNER_MODE;
|
|
break;
|
|
default:
|
|
m_lMode = 0;
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Automatic document feeder functions
|
|
//
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_ADFHasPaper()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// check paper count
|
|
//
|
|
|
|
if (m_PagesInADF <= 0) {
|
|
hr = S_FALSE;
|
|
m_PagesInADF = MAX_PAGE_CAPACITY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_ADFAvailable()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// check ADF on-line
|
|
//
|
|
|
|
if (!m_ADFIsAvailable) {
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_ADFFeedPage()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (S_OK != FakeScanner_ADFHasPaper()) {
|
|
|
|
//
|
|
// set paper empty error code
|
|
//
|
|
|
|
hr = WIA_ERROR_PAPER_EMPTY;
|
|
}
|
|
|
|
//
|
|
// update paper count for ADF
|
|
//
|
|
|
|
m_PagesInADF--;
|
|
|
|
if (m_PagesInADF <0) {
|
|
m_PagesInADF = 0;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_ADFUnFeedPage()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_ADFStatus()
|
|
{
|
|
return m_hrLastADFError;
|
|
}
|
|
|
|
HRESULT CFakeScanAPI::FakeScanner_ADFAttached()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
LONG CFakeScanAPI::WidthToDIBWidth(LONG lWidth)
|
|
{
|
|
return(lWidth+3)&0xfffffffc;
|
|
}
|
|
|
|
LONG CFakeScanAPI::CalcTotalImageSize()
|
|
{
|
|
LONG lTotalSize = 0;
|
|
switch (m_RawDataInfo.bpp) {
|
|
case 1:
|
|
lTotalSize = ((m_RawDataInfo.lHeightPixels * m_RawDataInfo.lWidthPixels) + 7) / 8;
|
|
break;
|
|
case 8:
|
|
lTotalSize = m_RawDataInfo.lHeightPixels * m_RawDataInfo.lWidthPixels;
|
|
break;
|
|
case 24:
|
|
lTotalSize = (m_RawDataInfo.lHeightPixels * m_RawDataInfo.lWidthPixels) * 3;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return lTotalSize;
|
|
}
|
|
|
|
LONG CFakeScanAPI::CalcRawByteWidth()
|
|
{
|
|
LONG lRawWidthBytes = 0;
|
|
switch (m_RawDataInfo.bpp) {
|
|
case 1:
|
|
lRawWidthBytes = ((m_RawDataInfo.lWidthPixels) + 7) / 8;
|
|
break;
|
|
case 8:
|
|
lRawWidthBytes = m_RawDataInfo.lWidthPixels;
|
|
break;
|
|
case 24:
|
|
lRawWidthBytes = (m_RawDataInfo.lWidthPixels) * 3;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return lRawWidthBytes;
|
|
}
|
|
|
|
LONG CFakeScanAPI::CalcSrcByteWidth()
|
|
{
|
|
LONG lSrcWidthBytes = 0;
|
|
switch (m_SrcDataInfo.bpp) {
|
|
case 1:
|
|
lSrcWidthBytes = ((m_SrcDataInfo.lWidthPixels) + 7) / 8;
|
|
break;
|
|
case 8:
|
|
lSrcWidthBytes = m_SrcDataInfo.lWidthPixels;
|
|
break;
|
|
case 24:
|
|
lSrcWidthBytes = (m_SrcDataInfo.lWidthPixels) * 3;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return lSrcWidthBytes;
|
|
}
|
|
|
|
LONG CFakeScanAPI::CalcRandomDeviceDataTotalBytes()
|
|
{
|
|
LONG lTotalBytes = 0;
|
|
srand((unsigned)time(NULL));
|
|
LONG lPageLengthInches = ((rand()%17) + 5);// max 22 inches, and min of 5 inches
|
|
LONG lImageHeight = m_RawDataInfo.lYRes * lPageLengthInches;
|
|
lTotalBytes = (CalcRawByteWidth() * lImageHeight);
|
|
return lTotalBytes;
|
|
}
|
|
|
|
HRESULT CreateFakeScanner(CFakeScanAPI **ppFakeScanAPI, LONG lMode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if (ppFakeScanAPI) {
|
|
*ppFakeScanAPI = NULL;
|
|
*ppFakeScanAPI = new CFakeScanAPI;
|
|
if (NULL == *ppFakeScanAPI) {
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
CFakeScanAPI* pScanAPI = (CFakeScanAPI*)*ppFakeScanAPI;
|
|
pScanAPI->FakeScanner_SetEmulationMode(lMode);
|
|
}
|
|
return hr;
|
|
}
|
|
|