Leaked source code of windows server 2003
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.

754 lines
27 KiB

  1. #include "precomp.h"
  2. //
  3. // values that the WIA/TWAIN data source provides for capability negotation
  4. //
  5. TW_UINT16 g_VideoUnits[] = {TWUN_PIXELS};
  6. TW_UINT16 g_VideoBitOrder[] = {TWBO_MSBFIRST};
  7. TW_UINT16 g_VideoXferMech[] = {TWSX_NATIVE, TWSX_FILE, TWSX_MEMORY};
  8. TW_UINT16 g_VideoPixelFlavor[] = {TWPF_CHOCOLATE};
  9. TW_UINT16 g_VideoPlanarChunky[] = {TWPC_CHUNKY};
  10. const TW_UINT32 NUM_VIDEOCAPDATA = 23;
  11. CAPDATA VIDEO_CAPDATA[NUM_VIDEOCAPDATA] =
  12. {
  13. //
  14. // Every source must support all five DG_CONTROL / DAT_CAPABILITY operations on:
  15. //
  16. {CAP_XFERCOUNT, TWTY_INT16, TWON_ONEVALUE,
  17. sizeof(TW_INT16), 0, 0, 0, 32767, 1, NULL, NULL
  18. },
  19. //
  20. // Every source must support DG_CONTROL / DAT_CAPABILITY, MSG_GET on:
  21. //
  22. {CAP_SUPPORTEDCAPS, TWTY_UINT16, TWON_ARRAY,
  23. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  24. },
  25. {CAP_UICONTROLLABLE, TWTY_BOOL, TWON_ONEVALUE,
  26. sizeof(TW_BOOL), FALSE, FALSE, FALSE, FALSE, 0, NULL, NULL
  27. },
  28. //
  29. // Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
  30. // MSG_GET, MSG_GETCURRENT, and MSG_GETDEFAULT on:
  31. //
  32. {ICAP_COMPRESSION, TWTY_UINT16, TWON_ENUMERATION,
  33. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  34. },
  35. {ICAP_PLANARCHUNKY, TWTY_UINT16, TWON_ENUMERATION,
  36. sizeof(TW_UINT16), 0, 0, 0, 0, 0, g_VideoPlanarChunky, NULL
  37. },
  38. {ICAP_PHYSICALHEIGHT, TWTY_UINT32, TWON_ONEVALUE,
  39. sizeof(TW_UINT32), 1024, 1024, 1024, 1024, 0, NULL, NULL
  40. },
  41. {ICAP_PHYSICALWIDTH, TWTY_UINT32, TWON_ONEVALUE,
  42. sizeof(TW_UINT32), 1536, 1536, 1536, 1536, 0, NULL, NULL
  43. },
  44. {ICAP_PIXELFLAVOR, TWTY_UINT16, TWON_ENUMERATION,
  45. sizeof(TW_UINT16), 0, 0, 0, 0, 0, g_VideoPixelFlavor, NULL
  46. },
  47. //
  48. // Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
  49. // MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT, MSG_RESET, and MSG_SET on:
  50. //
  51. {ICAP_BITDEPTH, TWTY_UINT16, TWON_ENUMERATION,
  52. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  53. },
  54. {ICAP_BITORDER, TWTY_UINT16, TWON_ENUMERATION,
  55. sizeof(TW_UINT16), 0, 0, 0, 0, 0, g_VideoBitOrder, NULL
  56. },
  57. {ICAP_PIXELTYPE, TWTY_UINT16, TWON_ENUMERATION,
  58. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  59. },
  60. {ICAP_UNITS, TWTY_UINT16, TWON_ENUMERATION,
  61. sizeof(TW_UINT16), 0, 0, 0, 0, 0, g_VideoUnits, NULL
  62. },
  63. {ICAP_XFERMECH, TWTY_UINT16, TWON_ENUMERATION,
  64. sizeof(TW_UINT16), 0, 0, 0, 2, 0, g_VideoXferMech, NULL
  65. },
  66. {ICAP_XRESOLUTION, TWTY_FIX32, TWON_ONEVALUE,
  67. sizeof(TW_FIX32), 75, 75, 75, 75, 0, NULL, NULL
  68. },
  69. {ICAP_YRESOLUTION, TWTY_FIX32, TWON_ONEVALUE,
  70. sizeof(TW_FIX32), 75, 75, 75, 75, 0, NULL, NULL
  71. },
  72. //
  73. // The following capabilities are camera specific capabilities
  74. //
  75. {CAP_THUMBNAILSENABLED, TWTY_BOOL, TWON_ONEVALUE,
  76. sizeof(TW_BOOL), FALSE, FALSE, FALSE, FALSE, 0, NULL, NULL
  77. },
  78. {CAP_CAMERAPREVIEWUI, TWTY_BOOL, TWON_ONEVALUE,
  79. sizeof(TW_BOOL), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
  80. },
  81. {ICAP_IMAGEDATASET, TWTY_UINT32, TWON_RANGE,
  82. sizeof(TW_UINT32), 1, 1, 1, 50, 1, NULL, NULL
  83. },
  84. //
  85. // The following capabilities are provided for application compatiblity only.
  86. //
  87. {ICAP_IMAGEFILEFORMAT, TWTY_UINT16, TWON_ENUMERATION,
  88. sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
  89. },
  90. {CAP_INDICATORS, TWTY_BOOL, TWON_ONEVALUE,
  91. sizeof(TW_BOOL), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
  92. },
  93. {CAP_ENABLEDSUIONLY, TWTY_BOOL, TWON_ONEVALUE,
  94. sizeof(TW_BOOL), FALSE, FALSE, FALSE, FALSE, 0, NULL, NULL
  95. },
  96. {CAP_DEVICEONLINE, TWTY_BOOL, TWON_ONEVALUE,
  97. sizeof(TW_BOOL), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
  98. },
  99. {CAP_SUPPORTEDCAPSEXT, TWTY_BOOL, TWON_ONEVALUE,
  100. sizeof(TW_BOOL), FALSE, FALSE, FALSE, FALSE, 0, NULL, NULL
  101. },
  102. };
  103. TW_UINT16 CWiaVideoDS::OpenDS(PTWAIN_MSG ptwMsg)
  104. {
  105. TW_UINT16 twRc = TWRC_SUCCESS;
  106. TW_UINT16 twCc = TWCC_SUCCESS;
  107. m_bArrayModeAcquisition = FALSE;
  108. m_pulImageIndexes = NULL;
  109. m_lNumValidIndexes = 0;
  110. m_lCurrentArrayIndex = 0;
  111. m_bRangeModeAcquisition = FALSE;
  112. memset(&m_twImageRange,0,sizeof(TW_RANGE));
  113. //
  114. // create capability list
  115. //
  116. twCc = CreateCapList(NUM_VIDEOCAPDATA, VIDEO_CAPDATA);
  117. if (TWCC_SUCCESS != twCc) {
  118. m_twStatus.ConditionCode = twCc;
  119. return TWRC_FAILURE;
  120. }
  121. twRc = CWiaDataSrc::OpenDS(ptwMsg);
  122. if (TWRC_SUCCESS == twRc) {
  123. HRESULT hr = m_pDevice->AcquireImages(NULL, FALSE);
  124. if (SUCCEEDED(hr)) {
  125. //
  126. // get number of pictures taken, for IMAGEDATASET query
  127. //
  128. LONG lNumImages = 0;
  129. m_pDevice->GetNumAcquiredImages(&lNumImages);
  130. CCap *pCap = NULL;
  131. pCap = FindCap(ICAP_IMAGEDATASET);
  132. if (pCap) {
  133. pCap->Set((TW_UINT32)lNumImages,(TW_UINT32)lNumImages,(TW_UINT32)lNumImages,(TW_UINT32)lNumImages,1);
  134. }
  135. hr = m_pDevice->EnumAcquiredImage(0, &m_pCurrentIWiaItem);
  136. if (SUCCEEDED(hr)) {
  137. twRc = GetCommonSettings();
  138. } else {
  139. //
  140. // Video capture devices, can be in a state that there are no still images
  141. // to transfer
  142. //
  143. twRc = GetCommonDefaultSettings();
  144. }
  145. }
  146. }
  147. return twRc;
  148. }
  149. TW_UINT16 CWiaVideoDS::CloseDS(PTWAIN_MSG ptwMsg)
  150. {
  151. DestroyCapList();
  152. return CWiaDataSrc::CloseDS(ptwMsg);
  153. }
  154. TW_UINT16 CWiaVideoDS::SetCapability(CCap *pCap,TW_CAPABILITY *ptwCap)
  155. {
  156. TW_UINT16 twRc = TWRC_SUCCESS;
  157. if (ptwCap->Cap == ICAP_IMAGEDATASET) {
  158. switch(ptwCap->ConType){
  159. case TWON_ONEVALUE:
  160. DBG_TRC(("CWiaVideoDS::SetCapability(), setting ICAP_IMAGEDATASET to a TWON_ONEVALUE"));
  161. //
  162. // implied contiguous image transfer, from 1 to the specified TW_ONEVALUE
  163. //
  164. twRc = CWiaDataSrc::SetCapability(pCap, ptwCap);
  165. break;
  166. case TWON_RANGE:
  167. DBG_TRC(("CWiaVideoDS::SetCapability(), setting ICAP_IMAGEDATASET to a TW_RANGE"));
  168. //
  169. // contiguous image transfer, from MinValue to MaxValue TW_RANGE (using StepSize? or increment by 1?)
  170. //
  171. twRc = SetRangeOfImageIndexes(ptwCap);
  172. break;
  173. case TWON_ARRAY:
  174. DBG_TRC(("CWiaVideoDS::SetCapability(), setting ICAP_IMAGEDATASET to a TW_ARRAY"));
  175. //
  176. // image transfer with specified indexes supplied by the TWAIN application (user)
  177. //
  178. twRc = SetArrayOfImageIndexes(ptwCap);
  179. break;
  180. default:
  181. DBG_WRN(("CWiaVideoDS::SetCapability(), setting ICAP_IMAGEDATASET unknown container type (%d)",ptwCap->ConType));
  182. break;
  183. }
  184. } else {
  185. twRc = CWiaDataSrc::SetCapability(pCap, ptwCap);
  186. if(TWRC_SUCCESS == twRc){
  187. if(m_pCurrentIWiaItem){
  188. twRc = CWiaDataSrc::SetCommonSettings(pCap);
  189. }
  190. }
  191. }
  192. return twRc;
  193. }
  194. TW_UINT16 CWiaVideoDS::SetArrayOfImageIndexes(TW_CAPABILITY *ptwCap)
  195. {
  196. TW_UINT16 twRc = TWRC_FAILURE;
  197. switch (ptwCap->ConType) {
  198. case TWON_ARRAY:
  199. twRc = TWRC_SUCCESS;
  200. break;
  201. default:
  202. DBG_ERR(("CWiaVideoDS::SetArrayOfImageIndexes(), invalid image index container was sent to data source."));
  203. break;
  204. }
  205. if (TWRC_SUCCESS == twRc) {
  206. TW_ARRAY *pArray = (TW_ARRAY*)GlobalLock(ptwCap->hContainer);
  207. if (pArray) {
  208. TW_UINT32 *pUINT32Array = NULL;
  209. pUINT32Array = (TW_UINT32*)pArray->ItemList;
  210. if(pUINT32Array){
  211. if (m_pulImageIndexes) {
  212. delete [] m_pulImageIndexes;
  213. m_pulImageIndexes = NULL;
  214. }
  215. m_lNumValidIndexes = pArray->NumItems;
  216. m_pulImageIndexes = new LONG[m_lNumValidIndexes];
  217. if (m_pulImageIndexes) {
  218. DBG_TRC(("CWiaVideoDS::SetArrayOfImageIndexes(), number of selected images to transfer = %d",m_lNumValidIndexes));
  219. for (int i = 0; i < m_lNumValidIndexes; i++) {
  220. //
  221. // subtract 1 from the supplied index in the application index array, because TWAIN's image index
  222. // array starts at 1 and goes to n. WIA (image) item array is zero-based. This will sync
  223. // up the indexes here, to avoid any strange calculations later on.
  224. //
  225. m_pulImageIndexes[i] = (pUINT32Array[i] - 1);
  226. DBG_TRC(("CWiaVideoDS::SetArrayOfImageIndexes(), image index copied into index array = %d",m_pulImageIndexes[i]));
  227. }
  228. } else {
  229. DBG_ERR(("CWiaVideoDS::SetArrayOfImageIndexes(), could not allocate image index array"));
  230. twRc = TWRC_FAILURE;
  231. }
  232. } else {
  233. DBG_ERR(("CWiaVideoDS::SetArrayOfImageIndexes(), could not assign TW_ARRAY pointer to TW_UINT32 pointer"));
  234. twRc = TWRC_FAILURE;
  235. }
  236. GlobalUnlock(ptwCap->hContainer);
  237. } else {
  238. DBG_ERR(("CWiaVideoDS::SetArrayOfImageIndexes(), could not LOCK the array container for write access"));
  239. twRc = TWRC_FAILURE;
  240. }
  241. }
  242. if(TWRC_SUCCESS == twRc){
  243. m_bArrayModeAcquisition = TRUE;
  244. m_bRangeModeAcquisition = FALSE;
  245. }
  246. return twRc;
  247. }
  248. TW_UINT16 CWiaVideoDS::SetRangeOfImageIndexes(TW_CAPABILITY *ptwCap)
  249. {
  250. TW_UINT16 twRc = TWRC_FAILURE;
  251. switch (ptwCap->ConType) {
  252. case TWON_RANGE:
  253. twRc = TWRC_SUCCESS;
  254. break;
  255. default:
  256. DBG_ERR(("CWiaVideoDS::SetRangeOfImageIndexes(), invalid image index container was sent to data source."));
  257. break;
  258. }
  259. if (TWRC_SUCCESS == twRc) {
  260. TW_RANGE *pRange = (TW_RANGE*)GlobalLock(ptwCap->hContainer);
  261. if (pRange) {
  262. m_bRangeModeAcquisition = TRUE;
  263. memcpy(&m_twImageRange,pRange,sizeof(TW_RANGE));
  264. //
  265. // adjust values to be zero-based to match our stored item list
  266. //
  267. m_twImageRange.CurrentValue -=1;
  268. m_twImageRange.DefaultValue -=1;
  269. m_twImageRange.MaxValue-=1;
  270. m_twImageRange.MinValue-=1;
  271. DBG_TRC(("CWiaVideoDS::SetRangeOfImageIndexes(), Set to the following Range Values"));
  272. DBG_TRC(("m_twImageRange.ItemType = %d",m_twImageRange.ItemType));
  273. DBG_TRC(("m_twImageRange.CurrentValue = %d",m_twImageRange.CurrentValue));
  274. DBG_TRC(("m_twImageRange.DefaultValue = %d",m_twImageRange.DefaultValue));
  275. DBG_TRC(("m_twImageRange.MaxValue = %d",m_twImageRange.MaxValue));
  276. DBG_TRC(("m_twImageRange.MinValue = %d",m_twImageRange.MinValue));
  277. DBG_TRC(("m_twImageRange.StepSize = %d",m_twImageRange.StepSize));
  278. } else {
  279. DBG_ERR(("CWiaVideoDS::SetRangeOfImageIndexes(), could not assign TW_RANGE pointer to TW_RANGE pointer"));
  280. twRc = TWRC_FAILURE;
  281. }
  282. GlobalUnlock(ptwCap->hContainer);
  283. } else {
  284. DBG_ERR(("CWiaVideoDS::SetRangeOfImageIndexes(), could not LOCK the range container for read access"));
  285. twRc = TWRC_FAILURE;
  286. }
  287. if(TWRC_SUCCESS == twRc){
  288. m_bRangeModeAcquisition = TRUE;
  289. m_bArrayModeAcquisition = FALSE;
  290. }
  291. return twRc;
  292. }
  293. TW_UINT16 CWiaVideoDS::EnableDS(TW_USERINTERFACE *pUI)
  294. {
  295. TW_UINT16 twRc = TWRC_FAILURE;
  296. if (DS_STATE_4 == GetTWAINState()) {
  297. HRESULT hr = S_OK;
  298. if (pUI->ShowUI) {
  299. //
  300. // since we were told to show UI, ignore the UI-LESS settings, and
  301. // get a new image item list from the WIA UI.
  302. //
  303. DBG_TRC(("CWiaVideoDS::EnableDS(), TWAIN UI MODE"));
  304. m_pDevice->FreeAcquiredImages();
  305. } else {
  306. DBG_TRC(("CWiaVideoDS::EnableDS(), TWAIN UI-LESS MODE"));
  307. DBG_TRC(("CWiaVideoDS::EnableDS(), TWAIN UI MODE (FORCING UI MODE TO ON)"));
  308. pUI->ShowUI = TRUE; // force UI mode
  309. m_pDevice->FreeAcquiredImages();
  310. }
  311. hr = m_pDevice->AcquireImages(HWND (pUI->ShowUI ? pUI->hParent : NULL),
  312. pUI->ShowUI);
  313. if (S_OK == hr) {
  314. twRc = TWRC_SUCCESS;
  315. LONG lNumImages = 0;
  316. m_pDevice->GetNumAcquiredImages(&lNumImages);
  317. if (lNumImages) {
  318. m_NumIWiaItems = (TW_UINT32)lNumImages;
  319. m_pIWiaItems = new (IWiaItem *[m_NumIWiaItems]);
  320. if (m_pIWiaItems) {
  321. hr = m_pDevice->GetAcquiredImageList(lNumImages, m_pIWiaItems, NULL);
  322. if (FAILED(hr)) {
  323. delete [] m_pIWiaItems;
  324. m_pIWiaItems = NULL;
  325. m_NumIWiaItems = 0;
  326. m_NextIWiaItemIndex = 0;
  327. m_twStatus.ConditionCode = TWCC_BUMMER;
  328. twRc = TWRC_FAILURE;
  329. }
  330. } else {
  331. m_NumIWiaItems = 0;
  332. m_twStatus.ConditionCode = TWCC_LOWMEMORY;
  333. twRc = TWRC_FAILURE;
  334. }
  335. }
  336. } else if(S_FALSE == hr) {
  337. return TWRC_CANCEL;
  338. } else {
  339. m_twStatus.ConditionCode = TWCC_OPERATIONERROR;
  340. twRc = TWRC_FAILURE;
  341. }
  342. if (TWRC_SUCCESS == twRc) {
  343. //
  344. // set current item pointer
  345. //
  346. if(m_bRangeModeAcquisition){
  347. DBG_TRC(("CWiaVideoDS::EnableDS(), RANGE MODE"));
  348. m_pCurrentIWiaItem = m_pIWiaItems[m_twImageRange.MinValue];
  349. m_NextIWiaItemIndex = m_twImageRange.MinValue + 1; // use Step value???
  350. } else if(m_bArrayModeAcquisition){
  351. DBG_TRC(("CWiaVideoDS::EnableDS(), ARRAY MODE"));
  352. m_lCurrentArrayIndex = 0;
  353. m_pCurrentIWiaItem = m_pIWiaItems[m_pulImageIndexes[m_lCurrentArrayIndex]];
  354. if(m_lNumValidIndexes > 1){
  355. m_NextIWiaItemIndex = m_pulImageIndexes[m_lCurrentArrayIndex + 1]; // the next index value
  356. } else {
  357. m_NextIWiaItemIndex = m_lCurrentArrayIndex;
  358. }
  359. } else {
  360. m_pCurrentIWiaItem = m_pIWiaItems[0];
  361. m_NextIWiaItemIndex = 1;
  362. }
  363. //
  364. // set total image count
  365. //
  366. CCap *pcapXferCount = NULL;
  367. TW_UINT32 NumImages = 0;
  368. pcapXferCount = FindCap(CAP_XFERCOUNT);
  369. if (pcapXferCount) {
  370. if(m_bRangeModeAcquisition){
  371. // only images in the specified range (zero-based)
  372. twRc = pcapXferCount->SetCurrent((m_twImageRange.MaxValue - m_twImageRange.MinValue) + 1);
  373. } else if(m_bArrayModeAcquisition){
  374. // only selected images (zero-based)
  375. twRc = pcapXferCount->SetCurrent(m_lNumValidIndexes);
  376. } else {
  377. // all images (zero-based)
  378. twRc = pcapXferCount->SetCurrent(m_NumIWiaItems);
  379. }
  380. NumImages = pcapXferCount->GetCurrent();
  381. } else {
  382. DBG_ERR(("CWiaVideoDS::EnableDS(), could not find CAP_XFERCOUNT in supported CAP list"));
  383. twRc = TWRC_FAILURE;
  384. }
  385. if (TWRC_SUCCESS == twRc) {
  386. //
  387. // set thumbnail count
  388. //
  389. CCap *pDataSet = NULL;
  390. pDataSet = FindCap(ICAP_IMAGEDATASET);
  391. if(pDataSet){
  392. pDataSet->Set((TW_UINT32)NumImages,(TW_UINT32)NumImages,(TW_UINT32)NumImages,(TW_UINT32)NumImages,1);
  393. }
  394. if (m_NumIWiaItems) {
  395. //
  396. // transition to STATE_5, XferReady will transition to STATE_6
  397. //
  398. SetTWAINState(DS_STATE_5);
  399. NotifyXferReady();
  400. } else {
  401. NotifyCloseReq();
  402. //
  403. // transition to STATE_5
  404. //
  405. SetTWAINState(DS_STATE_5);
  406. }
  407. }
  408. }
  409. }
  410. return twRc;
  411. }
  412. TW_UINT16 CWiaVideoDS::OnPendingXfersMsg(PTWAIN_MSG ptwMsg)
  413. {
  414. TW_UINT16 twRc = TWRC_SUCCESS;
  415. CCap *pXferCount;
  416. pXferCount = FindCap(CAP_XFERCOUNT);
  417. if (!pXferCount) {
  418. m_twStatus.ConditionCode = TWCC_BUMMER;
  419. return TWRC_FAILURE;
  420. }
  421. twRc = TWRC_SUCCESS;
  422. switch (ptwMsg->MSG) {
  423. case MSG_GET:
  424. switch (GetTWAINState()) {
  425. case DS_STATE_4:
  426. case DS_STATE_5:
  427. case DS_STATE_6:
  428. case DS_STATE_7:
  429. ((TW_PENDINGXFERS *)ptwMsg->pData)->Count = (TW_INT16)pXferCount->GetCurrent();
  430. DBG_TRC(("CWiaVideoDS::OnPendingXfersMsg(), MSG_GET returning %d",((TW_PENDINGXFERS *)ptwMsg->pData)->Count));
  431. break;
  432. default:
  433. twRc = TWRC_FAILURE;
  434. m_twStatus.ConditionCode = TWCC_SEQERROR;
  435. DSError();
  436. break;
  437. }
  438. break;
  439. case MSG_ENDXFER:
  440. if (DS_STATE_6 == GetTWAINState() || DS_STATE_7 == GetTWAINState()) {
  441. ResetMemXfer();
  442. TW_INT32 Count = 0;
  443. Count = pXferCount->GetCurrent();
  444. Count--;
  445. if (Count <= 0) {
  446. Count = 0;
  447. DBG_TRC(("CWiaVideoDS::OnPendingXfersMsg(), MSG_ENDXFER, 0 (no more images left to transfer)"));
  448. ((TW_PENDINGXFERS *)ptwMsg->pData)->Count = (TW_UINT16)0;
  449. //
  450. // update count now, so NotifyCoseReq can be prepared for reentry by a TWAIN application
  451. //
  452. pXferCount->SetCurrent((TW_UINT32)0);
  453. //
  454. // Transition to STATE_5
  455. //
  456. SetTWAINState(DS_STATE_5);
  457. NotifyCloseReq();
  458. } else {
  459. DBG_TRC(("CWiaVideoDS::OnPendingXfersMsg(), MSG_ENDXFER, %d (more images may be ready to transfer)",Count));
  460. //
  461. // Advance to next image
  462. //
  463. if (m_bRangeModeAcquisition) {
  464. m_NextIWiaItemIndex+=1; // use Step value???
  465. if(m_NextIWiaItemIndex <= (LONG)m_twImageRange.MaxValue){
  466. m_pCurrentIWiaItem = m_pIWiaItems[m_NextIWiaItemIndex];
  467. } else {
  468. DBG_ERR(("CWiaVideoDS::OnPendingXfersMsg(), MSG_ENDXFER, we are over our allowed RANGE index"));
  469. }
  470. } else if (m_bArrayModeAcquisition) {
  471. m_lCurrentArrayIndex++; // advance to next image index
  472. DBG_TRC(("CWiaVideoDS::OnPendingXfersMsg(), MSG_ENDXFER, next image index to acquire = %d",m_pulImageIndexes[m_lCurrentArrayIndex]));
  473. m_NextIWiaItemIndex = m_pulImageIndexes[m_lCurrentArrayIndex];
  474. if(m_NextIWiaItemIndex <= m_lNumValidIndexes){
  475. m_pCurrentIWiaItem = m_pIWiaItems[m_NextIWiaItemIndex];
  476. } else {
  477. DBG_ERR(("CWiaVideoDS::OnPendingXfersMsg(), MSG_ENDXFER, we are over our allowed ARRAY index"));
  478. }
  479. } else {
  480. m_pCurrentIWiaItem = m_pIWiaItems[m_NextIWiaItemIndex++];
  481. }
  482. //
  483. // Transition to STATE_6
  484. //
  485. SetTWAINState(DS_STATE_6);
  486. ((TW_PENDINGXFERS *)ptwMsg->pData)->Count = (TW_UINT16)Count;
  487. }
  488. //
  489. // update count
  490. //
  491. pXferCount->SetCurrent((TW_UINT32)Count);
  492. } else {
  493. twRc = TWRC_FAILURE;
  494. m_twStatus.ConditionCode = TWCC_SEQERROR;
  495. DSError();
  496. }
  497. break;
  498. case MSG_RESET:
  499. if (DS_STATE_6 == GetTWAINState()) {
  500. ((TW_PENDINGXFERS*)ptwMsg->pData)->Count = 0;
  501. pXferCount->SetCurrent((TW_UINT32)0);
  502. ResetMemXfer();
  503. //
  504. // Transition to STATE_5
  505. //
  506. SetTWAINState(DS_STATE_5);
  507. } else {
  508. twRc = TWRC_FAILURE;
  509. m_twStatus.ConditionCode = TWCC_SEQERROR;
  510. DSError();
  511. }
  512. break;
  513. default:
  514. twRc = TWRC_FAILURE;
  515. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  516. DSError();
  517. break;
  518. }
  519. return twRc;
  520. }
  521. TW_UINT16 CWiaVideoDS::OnImageInfoMsg(PTWAIN_MSG ptwMsg)
  522. {
  523. TW_UINT16 twRc = TWRC_FAILURE;
  524. BOOL bThumbailMode = FALSE;
  525. CCap *pCap = NULL;
  526. pCap = FindCap(CAP_THUMBNAILSENABLED);
  527. if (pCap) {
  528. if (pCap->GetCurrent()) {
  529. bThumbailMode = TRUE;
  530. }
  531. } else {
  532. DBG_ERR(("CWiaVideoDS::OnImageInfoMsg(), could not get CAP_THUMBNAILSENABLED capabilty settings"));
  533. }
  534. if (bThumbailMode) {
  535. DBG_TRC(("CWiaVideoDS::OnImageInfoMsg(), Reporting Thumbnail image information"));
  536. TW_IMAGEINFO *ptwImageInfo = NULL;
  537. if (DS_STATE_6 == GetTWAINState()) {
  538. if (MSG_GET == ptwMsg->MSG) {
  539. ptwImageInfo = (TW_IMAGEINFO *)ptwMsg->pData;
  540. HRESULT hr = S_OK;
  541. hr = m_pDevice->GetThumbnailImageInfo(m_pCurrentIWiaItem, &m_MemoryTransferInfo);
  542. if (SUCCEEDED(hr)) {
  543. ptwImageInfo->ImageWidth = (TW_INT32)m_MemoryTransferInfo.mtiWidthPixels;
  544. ptwImageInfo->ImageLength = (TW_INT32)m_MemoryTransferInfo.mtiHeightPixels;
  545. ptwImageInfo->BitsPerPixel = (TW_INT16)m_MemoryTransferInfo.mtiBitsPerPixel;
  546. ptwImageInfo->SamplesPerPixel = (TW_INT16)m_MemoryTransferInfo.mtiNumChannels;
  547. ptwImageInfo->Planar = (TW_BOOL)m_MemoryTransferInfo.mtiPlanar;
  548. //
  549. // set PixelType to corresponding TWAIN pixel type
  550. //
  551. switch (m_MemoryTransferInfo.mtiDataType) {
  552. case WIA_DATA_THRESHOLD:
  553. ptwImageInfo->PixelType = TWPT_BW;
  554. break;
  555. case WIA_DATA_GRAYSCALE:
  556. ptwImageInfo->PixelType = TWPT_GRAY;
  557. break;
  558. case WIA_DATA_COLOR:
  559. default:
  560. ptwImageInfo->PixelType = TWPT_RGB;
  561. break;
  562. }
  563. //
  564. // set compression to NONE
  565. //
  566. ptwImageInfo->Compression = TWCP_NONE;
  567. //
  568. // Unit conversion.......
  569. //
  570. ptwImageInfo->XResolution = FloatToFix32((float)m_MemoryTransferInfo.mtiXResolution);
  571. ptwImageInfo->YResolution = FloatToFix32((float)m_MemoryTransferInfo.mtiYResolution);
  572. twRc = TWRC_SUCCESS;
  573. } else {
  574. m_twStatus.ConditionCode = TWCC_OPERATIONERROR;
  575. twRc = TWRC_FAILURE;
  576. }
  577. if (TWRC_SUCCESS == twRc) {
  578. DBG_TRC(("CWiaVideoDS::OnImageInfoMsg(), Reported Image Information from data source"));
  579. DBG_TRC(("XResolution = %d.%d",ptwImageInfo->XResolution.Whole,ptwImageInfo->XResolution.Frac));
  580. DBG_TRC(("YResolution = %d.%d",ptwImageInfo->YResolution.Whole,ptwImageInfo->YResolution.Frac));
  581. DBG_TRC(("ImageWidth = %d",ptwImageInfo->ImageWidth));
  582. DBG_TRC(("ImageLength = %d",ptwImageInfo->ImageLength));
  583. DBG_TRC(("SamplesPerPixel = %d",ptwImageInfo->SamplesPerPixel));
  584. memset(ptwImageInfo->BitsPerSample,0,sizeof(ptwImageInfo->BitsPerSample));
  585. if (ptwImageInfo->BitsPerPixel < 24) {
  586. ptwImageInfo->BitsPerSample[0] = ptwImageInfo->BitsPerPixel;
  587. } else {
  588. for (int i = 0; i < ptwImageInfo->SamplesPerPixel; i++) {
  589. ptwImageInfo->BitsPerSample[i] = (ptwImageInfo->BitsPerPixel/ptwImageInfo->SamplesPerPixel);
  590. }
  591. }
  592. // (bpp / spp) = bps
  593. DBG_TRC(("BitsPerSample = [%d],[%d],[%d],[%d],[%d],[%d],[%d],[%d]",ptwImageInfo->BitsPerSample[0],
  594. ptwImageInfo->BitsPerSample[1],
  595. ptwImageInfo->BitsPerSample[2],
  596. ptwImageInfo->BitsPerSample[3],
  597. ptwImageInfo->BitsPerSample[4],
  598. ptwImageInfo->BitsPerSample[5],
  599. ptwImageInfo->BitsPerSample[6],
  600. ptwImageInfo->BitsPerSample[7]));
  601. DBG_TRC(("BitsPerPixel = %d",ptwImageInfo->BitsPerPixel));
  602. DBG_TRC(("Planar = %d",ptwImageInfo->Planar));
  603. DBG_TRC(("PixelType = %d",ptwImageInfo->PixelType));
  604. DBG_TRC(("Compression = %d",ptwImageInfo->Compression));
  605. }
  606. } else {
  607. m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
  608. twRc = TWRC_FAILURE;
  609. }
  610. } else {
  611. m_twStatus.ConditionCode = TWCC_SEQERROR;
  612. twRc = TWRC_FAILURE;
  613. }
  614. if (TWRC_SUCCESS != twRc) {
  615. DSError();
  616. }
  617. } else {
  618. twRc = CWiaDataSrc::OnImageInfoMsg(ptwMsg);
  619. }
  620. return twRc;
  621. }
  622. TW_UINT16 CWiaVideoDS::TransferToDIB(HGLOBAL *phDIB)
  623. {
  624. TW_UINT16 twRc = TWRC_FAILURE;
  625. BOOL bThumbailMode = FALSE;
  626. CCap *pCap = NULL;
  627. pCap = FindCap(CAP_THUMBNAILSENABLED);
  628. if (pCap) {
  629. bThumbailMode = pCap->GetCurrent();
  630. }
  631. if(bThumbailMode){
  632. twRc = CWiaDataSrc::TransferToThumbnail(phDIB);
  633. } else {
  634. twRc = CWiaDataSrc::TransferToDIB(phDIB);
  635. }
  636. return twRc;
  637. }