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.

595 lines
18 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1999-2000
  4. *
  5. * TITLE: Transfer.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: RickTu
  10. *
  11. * DATE: 9/10/99 RickTu
  12. * 2000/11/09 OrenR
  13. *
  14. * DESCRIPTION: This was originally in camera.cpp but was broken out for
  15. * clarity. The functions in this file are responsible for
  16. * transfering the image to the requesting application.
  17. *
  18. *****************************************************************************/
  19. #include <precomp.h>
  20. #pragma hdrstop
  21. #include <gphelper.h>
  22. using namespace Gdiplus;
  23. /*****************************************************************************
  24. CVideoStiUsd::DoBandedTransfer
  25. hand back the given bits in the specified chunk sizes
  26. *****************************************************************************/
  27. STDMETHODIMP
  28. CVideoStiUsd::DoBandedTransfer(MINIDRV_TRANSFER_CONTEXT *pTransCtx,
  29. PBYTE pSrc,
  30. LONG lBytesToTransfer)
  31. {
  32. HRESULT hr = E_FAIL;
  33. DBG_FN("CVideoStiUsd::DoBandedTransfer");
  34. //
  35. // Check for bad args
  36. //
  37. if ((pTransCtx == NULL) ||
  38. (pSrc == NULL) ||
  39. (lBytesToTransfer == 0))
  40. {
  41. hr = E_INVALIDARG;
  42. CHECK_S_OK2(hr, ("CVideoStiUsd::DoBandedTransfer, received "
  43. "NULL param"));
  44. return hr;
  45. }
  46. //
  47. // callback loop
  48. //
  49. LONG lTransferSize = 0;
  50. LONG lPercentComplete = 0;
  51. do
  52. {
  53. PBYTE pDst = pTransCtx->pTransferBuffer;
  54. //
  55. // transfer up to entire buffer size
  56. //
  57. lTransferSize = lBytesToTransfer;
  58. if (lBytesToTransfer > pTransCtx->lBufferSize)
  59. {
  60. lTransferSize = pTransCtx->lBufferSize;
  61. }
  62. //
  63. // copy data
  64. //
  65. DBG_TRC(("memcpy(src=0x%x,dst=0x%x,size=0x%x)",
  66. pDst,
  67. pSrc,
  68. lTransferSize));
  69. memcpy(pDst, pSrc, lTransferSize);
  70. lPercentComplete = 100 * (pTransCtx->cbOffset + lTransferSize);
  71. lPercentComplete /= pTransCtx->lItemSize;
  72. //
  73. // make callback
  74. //
  75. hr = pTransCtx->pIWiaMiniDrvCallBack->MiniDrvCallback(
  76. IT_MSG_DATA,
  77. IT_STATUS_TRANSFER_TO_CLIENT,
  78. lPercentComplete,
  79. pTransCtx->cbOffset,
  80. lTransferSize,
  81. pTransCtx,
  82. 0);
  83. CHECK_S_OK2(hr,("pTransCtx->pWiaMiniDrvCallback->MiniDrvCallback"));
  84. DBG_TRC(("%d percent complete",lPercentComplete));
  85. //
  86. // inc pointers (redundant pointers here)
  87. //
  88. pSrc += lTransferSize;
  89. pTransCtx->cbOffset += lTransferSize;
  90. lBytesToTransfer -= lTransferSize;
  91. if (hr != S_OK)
  92. {
  93. break;
  94. }
  95. } while (lBytesToTransfer > 0);
  96. CHECK_S_OK(hr);
  97. return hr;
  98. }
  99. /*****************************************************************************
  100. CVideoStiUsd::DoTransfer
  101. Transfers the given bits all at once
  102. *****************************************************************************/
  103. STDMETHODIMP
  104. CVideoStiUsd::DoTransfer(MINIDRV_TRANSFER_CONTEXT *pTransCtx,
  105. PBYTE pSrc,
  106. LONG lBytesToTransfer)
  107. {
  108. HRESULT hr = E_FAIL;
  109. DBG_FN("CVideoStiUsd::DoTransfer");
  110. //
  111. // Check for bad args
  112. //
  113. if ((pTransCtx == NULL) ||
  114. (pSrc == NULL) ||
  115. (lBytesToTransfer == 0))
  116. {
  117. hr = E_INVALIDARG;
  118. CHECK_S_OK2(hr, ("CVideoStiUsd::DoTransfer, received "
  119. "NULL param"));
  120. return hr;
  121. }
  122. if (lBytesToTransfer > (LONG)(pTransCtx->lBufferSize - pTransCtx->cbOffset))
  123. {
  124. DBG_TRC(("lBytesToTransfer = %d, (lBufferSize = %d) - "
  125. "(cbOffset = %d) is %d",
  126. lBytesToTransfer,
  127. pTransCtx->lBufferSize,
  128. pTransCtx->cbOffset,
  129. (pTransCtx->lBufferSize - pTransCtx->cbOffset)));
  130. DBG_ERR(("lBytesToTransfer is bigger than supplied buffer!"));
  131. hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
  132. }
  133. else
  134. {
  135. //
  136. // Show 20% completion
  137. //
  138. if (pTransCtx->pIWiaMiniDrvCallBack)
  139. {
  140. pTransCtx->pIWiaMiniDrvCallBack->MiniDrvCallback(
  141. IT_MSG_STATUS,
  142. IT_STATUS_TRANSFER_FROM_DEVICE,
  143. (LONG)20, // Percentage Complete,
  144. 0,
  145. 0,
  146. pTransCtx,
  147. 0);
  148. }
  149. PBYTE pDst = pTransCtx->pTransferBuffer;
  150. pDst += pTransCtx->cbOffset;
  151. //
  152. // copy the bits
  153. //
  154. memcpy(pDst, pSrc, lBytesToTransfer);
  155. hr = S_OK;
  156. // Since we are copying all the bits in one shot, any status
  157. // callback is just a simulation anyway. So lets give enough
  158. // increments to bring the progress dialog up to 100 %.
  159. if (pTransCtx->pIWiaMiniDrvCallBack)
  160. {
  161. // Show 60% completion
  162. pTransCtx->pIWiaMiniDrvCallBack->MiniDrvCallback(
  163. IT_MSG_STATUS,
  164. IT_STATUS_TRANSFER_FROM_DEVICE,
  165. (LONG)60, // Percentage Complete,
  166. 0,
  167. 0,
  168. pTransCtx,
  169. 0);
  170. // Show 90% completion
  171. pTransCtx->pIWiaMiniDrvCallBack->MiniDrvCallback(
  172. IT_MSG_STATUS,
  173. IT_STATUS_TRANSFER_FROM_DEVICE,
  174. (LONG)90, // Percentage Complete,
  175. 0,
  176. 0,
  177. pTransCtx,
  178. 0);
  179. // Show 99% completion
  180. pTransCtx->pIWiaMiniDrvCallBack->MiniDrvCallback(
  181. IT_MSG_STATUS,
  182. IT_STATUS_TRANSFER_FROM_DEVICE,
  183. (LONG)99, // Percentage Complete,
  184. 0,
  185. 0,
  186. pTransCtx,
  187. 0);
  188. // Show 100% completion
  189. pTransCtx->pIWiaMiniDrvCallBack->MiniDrvCallback(
  190. IT_MSG_STATUS,
  191. IT_STATUS_TRANSFER_FROM_DEVICE,
  192. (LONG)100, // Percentage Complete,
  193. 0,
  194. 0,
  195. pTransCtx,
  196. 0);
  197. }
  198. }
  199. CHECK_S_OK(hr);
  200. return hr;
  201. }
  202. /*****************************************************************************
  203. CVideoUsd::StreamJPEGBits
  204. Transfers the JPEG bits of a file
  205. *****************************************************************************/
  206. STDMETHODIMP
  207. CVideoStiUsd::StreamJPEGBits(STILLCAM_IMAGE_CONTEXT *pContext,
  208. MINIDRV_TRANSFER_CONTEXT *pTransCtx,
  209. BOOL bBanded)
  210. {
  211. HRESULT hr = E_FAIL;
  212. PBYTE pSrc = NULL;
  213. DBG_FN("CVideoStiUsd::StreamJPEGBits");
  214. //
  215. // Check for invalid args
  216. //
  217. if ((pContext == NULL) ||
  218. (pContext->pImage == NULL) ||
  219. (pTransCtx == NULL))
  220. {
  221. hr = E_INVALIDARG;
  222. CHECK_S_OK2(hr, ("CVideoStiUsd::StreamJPEGBits received NULL "
  223. "params"));
  224. return hr;
  225. }
  226. //
  227. // try to open mapping to disk file -- we will use this if it is a JPEG
  228. // file because we just want to stream the bits back.
  229. //
  230. CMappedView cmvImage(pContext->pImage->ActualImagePath(),
  231. 0,
  232. OPEN_EXISTING);
  233. pSrc = cmvImage.Bits();
  234. if (pSrc)
  235. {
  236. //
  237. // We only handle 2GB of data (that's all WIA handles as well)
  238. //
  239. LARGE_INTEGER liSize = cmvImage.FileSize();
  240. LONG lBytes = liSize.LowPart;
  241. if (bBanded)
  242. {
  243. hr = DoBandedTransfer(pTransCtx, pSrc, lBytes);
  244. }
  245. else
  246. {
  247. hr = DoTransfer(pTransCtx, pSrc, lBytes);
  248. }
  249. }
  250. CHECK_S_OK(hr);
  251. return hr;
  252. }
  253. /*****************************************************************************
  254. CVideoStiUsd::StreamBMPBits
  255. Transfers the BMP bits of a file
  256. *****************************************************************************/
  257. STDMETHODIMP
  258. CVideoStiUsd::StreamBMPBits(STILLCAM_IMAGE_CONTEXT *pContext,
  259. MINIDRV_TRANSFER_CONTEXT *pTransCtx,
  260. BOOL bBanded)
  261. {
  262. DBG_FN("CVideoStiUsd::StreamBMPBits");
  263. //
  264. // Assume failure
  265. //
  266. HRESULT hr = E_FAIL;
  267. if ((pContext == NULL) ||
  268. (pContext->pImage == NULL) ||
  269. (pTransCtx == NULL))
  270. {
  271. hr = E_INVALIDARG;
  272. CHECK_S_OK2(hr, ("CVideoStiUsd::StreamBMPBits received NULL params"));
  273. return hr;
  274. }
  275. //
  276. // Open the file
  277. //
  278. Bitmap SourceBitmap(CSimpleStringConvert::WideString(
  279. CSimpleString(
  280. pContext->pImage->ActualImagePath())));
  281. if (Ok == SourceBitmap.GetLastStatus())
  282. {
  283. //
  284. // Get the image dimensions
  285. //
  286. UINT nSourceWidth = SourceBitmap.GetWidth();
  287. UINT nSourceHeight = SourceBitmap.GetHeight();
  288. if (nSourceWidth && nSourceHeight)
  289. {
  290. //
  291. // Create the target bitmap
  292. //
  293. Bitmap TargetBitmap( nSourceWidth, nSourceWidth );
  294. if (Ok == TargetBitmap.GetLastStatus())
  295. {
  296. //
  297. // Assume failure
  298. //
  299. bool bDrawSucceeded = false;
  300. //
  301. // Create a graphics object
  302. //
  303. Graphics *pGraphics = Graphics::FromImage(&TargetBitmap);
  304. if (pGraphics)
  305. {
  306. //
  307. // Make sure it is valid
  308. //
  309. if (pGraphics->GetLastStatus() == Ok)
  310. {
  311. //
  312. // Flip the image, if they asked for a BMP
  313. //
  314. if (pTransCtx->guidFormatID == WiaImgFmt_BMP)
  315. {
  316. //
  317. // Set up the parallelogram to flip the image
  318. //
  319. Point SourcePoints[3];
  320. SourcePoints[0].X = 0;
  321. SourcePoints[0].Y = nSourceHeight;
  322. SourcePoints[1].X = nSourceWidth;
  323. SourcePoints[1].Y = nSourceHeight;
  324. SourcePoints[2].X = 0;
  325. SourcePoints[2].Y = 0;
  326. //
  327. // Draw the image, flipped
  328. //
  329. if (pGraphics->DrawImage(&SourceBitmap,
  330. SourcePoints, 3) == Ok)
  331. {
  332. //
  333. // We've got a good target image
  334. //
  335. bDrawSucceeded = true;
  336. }
  337. }
  338. else
  339. {
  340. //
  341. // Draw the image normally
  342. //
  343. if (pGraphics->DrawImage(&SourceBitmap,0,0) == Ok)
  344. {
  345. //
  346. // We've got a good target image
  347. //
  348. bDrawSucceeded = true;
  349. }
  350. }
  351. }
  352. //
  353. // Clean up our dynamically allocated graphics
  354. //
  355. delete pGraphics;
  356. }
  357. if (bDrawSucceeded)
  358. {
  359. Rect rcTarget( 0, 0, nSourceWidth, nSourceHeight );
  360. Gdiplus::BitmapData BitmapData;
  361. //
  362. // Get to the bits of the image
  363. //
  364. if (Ok == TargetBitmap.LockBits(&rcTarget,
  365. ImageLockModeRead,
  366. PixelFormat24bppRGB,
  367. &BitmapData))
  368. {
  369. if (bBanded)
  370. {
  371. //
  372. // This will be our return value
  373. //
  374. hr = DoBandedTransfer(
  375. pTransCtx,
  376. (PBYTE)BitmapData.Scan0,
  377. (BitmapData.Stride * BitmapData.Height));
  378. }
  379. else
  380. {
  381. //
  382. // This will be our return value
  383. //
  384. hr = DoTransfer(
  385. pTransCtx,
  386. (PBYTE)BitmapData.Scan0,
  387. (BitmapData.Stride * BitmapData.Height));
  388. }
  389. TargetBitmap.UnlockBits( &BitmapData );
  390. }
  391. }
  392. }
  393. }
  394. }
  395. CHECK_S_OK(hr);
  396. return hr;
  397. }
  398. /*****************************************************************************
  399. CVideoUsd::LoadImageCB
  400. Loads an image one piece at a time.
  401. *****************************************************************************/
  402. STDMETHODIMP
  403. CVideoStiUsd::LoadImageCB(STILLCAM_IMAGE_CONTEXT *pContext,
  404. MINIDRV_TRANSFER_CONTEXT *pTransCtx,
  405. PLONG plDevErrVal)
  406. {
  407. HRESULT hr = E_FAIL;
  408. DBG_FN("CVideoStiUsd::LoadImageCB");
  409. //
  410. // verify parameters
  411. //
  412. if ((pContext == NULL) ||
  413. (pContext->pImage == NULL) ||
  414. (pTransCtx == NULL))
  415. {
  416. hr = E_INVALIDARG;
  417. CHECK_S_OK2(hr, ("CVideoStiUsd::LoadImageCB received NULL params"));
  418. return hr;
  419. }
  420. if (pTransCtx->guidFormatID == WiaImgFmt_JPEG)
  421. {
  422. hr = StreamJPEGBits( pContext, pTransCtx, TRUE );
  423. }
  424. else if (pTransCtx->guidFormatID == WiaImgFmt_BMP)
  425. {
  426. hr = StreamBMPBits( pContext, pTransCtx, TRUE );
  427. }
  428. else if (pTransCtx->guidFormatID == WiaImgFmt_MEMORYBMP)
  429. {
  430. hr = StreamBMPBits( pContext, pTransCtx, TRUE );
  431. }
  432. else
  433. {
  434. DBG_ERR(("Asking for unsupported format"));
  435. return E_NOTIMPL;
  436. }
  437. CHECK_S_OK(hr);
  438. return hr;
  439. }
  440. /*****************************************************************************
  441. CVideoStiUsd::LoadImage
  442. Loads an image in a single transfer
  443. *****************************************************************************/
  444. STDMETHODIMP
  445. CVideoStiUsd::LoadImage(STILLCAM_IMAGE_CONTEXT *pContext,
  446. MINIDRV_TRANSFER_CONTEXT *pTransCtx,
  447. PLONG plDevErrVal)
  448. {
  449. HRESULT hr = S_OK;
  450. DBG_FN("CVideoStiUsd::LoadImage");
  451. //
  452. // verify some params
  453. //
  454. if ((pContext == NULL) ||
  455. (pTransCtx == NULL))
  456. {
  457. hr = E_INVALIDARG;
  458. CHECK_S_OK2(hr, ("CVideoStiUsd::LoadImage received NULL params"));
  459. return hr;
  460. }
  461. if ((pTransCtx->guidFormatID == WiaImgFmt_BMP))
  462. {
  463. hr = StreamBMPBits( pContext, pTransCtx, FALSE );
  464. }
  465. else if (pTransCtx->guidFormatID == WiaImgFmt_JPEG)
  466. {
  467. hr = StreamJPEGBits( pContext, pTransCtx, FALSE );
  468. }
  469. else
  470. {
  471. DBG_ERR(("Unsupported format"));
  472. return E_NOTIMPL;
  473. }
  474. CHECK_S_OK(hr);
  475. return hr;
  476. }