PALMAP.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:13k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /****************************************************************************
  2.  *
  3.  *  PALMAP.C
  4.  *
  5.  *  Stream handler to map to a palette.
  6.  *
  7.  ***************************************************************************/
  8. /**************************************************************************
  9.  *
  10.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13.  *  PURPOSE.
  14.  *
  15.  *  Copyright (C) 1992 - 1997 Microsoft Corporation.  All Rights Reserved.
  16.  *
  17.  **************************************************************************/
  18. #define INC_OLE2
  19. #include <windows.h>
  20. #include <windowsx.h>
  21. #include <mmsystem.h>
  22. #include <vfw.h>
  23. #include <string.h>
  24. #include "dibmap.h"
  25. #include "palmap.h"
  26. #include "palmap.rc"
  27. #define INITGUID
  28. #include <initguid.h>
  29. // Bring in the external GUIDs we need. Apparently compobj.lib doesn't define
  30. DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0);
  31. HINSTANCE ghMod;
  32. STDAPI AVIStreamMakePalette(
  33. PAVISTREAM pavi,
  34. LONG lSkip,
  35. HPALETTE FAR *lphpal,
  36. LPBYTE lp16to8,
  37. int nColors)
  38. {
  39. LPHISTOGRAM lpHist = NULL;
  40. LONG l, lEnd;
  41. LONG lRet = AVIERR_OK;
  42. PGETFRAME pgf = NULL;
  43. if (!pavi || !lphpal || nColors < 2 || nColors > 256)
  44. return ResultFromScode(AVIERR_BADPARAM);
  45. if (lSkip < 1)
  46. lSkip = 1;
  47. lpHist = InitHistogram(NULL);
  48. if (!lpHist)
  49. return ResultFromScode(AVIERR_MEMORY);
  50. pgf = AVIStreamGetFrameOpen(pavi, NULL);
  51. l = AVIStreamStart(pavi);
  52. lEnd = l + AVIStreamLength(pavi);
  53. for (l = AVIStreamStart(pavi), lEnd = l + AVIStreamLength(pavi);
  54. l < lEnd;
  55. l += lSkip) {
  56. LPBITMAPINFOHEADER lpbi;
  57. lpbi = AVIStreamGetFrame(pgf, l);
  58. if (!lpbi) {
  59. lRet = AVIERR_INTERNAL;
  60. goto error;
  61. }
  62. DibHistogram(lpbi, NULL, 0, 0, -1, -1, lpHist);
  63. }
  64. *lphpal = HistogramPalette(lpHist, lp16to8, nColors);
  65. if (!*lphpal)
  66. lRet = AVIERR_MEMORY;
  67. error:
  68. if (pgf)
  69. AVIStreamGetFrameClose(pgf);
  70. if (lpHist)
  71. FreeHistogram(lpHist);
  72. return ResultFromScode(lRet);
  73. }
  74. typedef struct {
  75. IAVIStreamVtbl FAR * lpVtbl;
  76. ULONG ulRefCount;
  77. //
  78. // instance data
  79. //
  80. PAVISTREAM pavi;
  81. PGETFRAME pgf;
  82. AVISTREAMINFO sinfo;
  83. HPALETTE hpal;
  84. LPBYTE lp16to8;
  85. LONG lLastFrame;
  86. LPBITMAPINFOHEADER lpdibLast;
  87. } PALMAPSTREAM, FAR*PPALMAPSTREAM;
  88. ///////////////////////////////////////////////////////////////////////////
  89. ///////////////////////////////////////////////////////////////////////////
  90. HRESULT STDMETHODCALLTYPE PalMapStreamQueryInterface(
  91. PAVISTREAM ps,
  92. REFIID riid,
  93. LPVOID FAR* ppvObj);
  94. HRESULT STDMETHODCALLTYPE PalMapStreamCreate(
  95. PAVISTREAM ps,
  96. LONG lParam1,
  97. LONG lParam2);
  98. ULONG STDMETHODCALLTYPE PalMapStreamAddRef(
  99. PAVISTREAM ps);
  100. ULONG STDMETHODCALLTYPE PalMapStreamRelease(
  101. PAVISTREAM ps);
  102. HRESULT STDMETHODCALLTYPE PalMapStreamInfo(
  103. PAVISTREAM ps,
  104. AVISTREAMINFOW FAR * psi,
  105. LONG lSize);
  106. LONG STDMETHODCALLTYPE PalMapStreamFindKeyFrame(
  107. PAVISTREAM ps,
  108. LONG lPos,
  109. LONG lFlags);
  110. HRESULT STDMETHODCALLTYPE PalMapStreamReadFormat(
  111. PAVISTREAM ps,
  112. LONG lPos,
  113. LPVOID lpFormat,
  114. LONG FAR *lpcbFormat);
  115. HRESULT STDMETHODCALLTYPE PalMapStreamSetFormat(
  116. PAVISTREAM ps,
  117. LONG lPos,
  118. LPVOID lpFormat,
  119. LONG cbFormat);
  120. HRESULT STDMETHODCALLTYPE PalMapStreamRead(
  121. PAVISTREAM ps,
  122. LONG lStart,
  123. LONG lSamples,
  124. LPVOID lpBuffer,
  125. LONG cbBuffer,
  126. LONG FAR * plBytes,
  127. LONG FAR * plSamples);
  128. HRESULT STDMETHODCALLTYPE PalMapStreamWrite(
  129. PAVISTREAM ps,
  130. LONG lStart,
  131. LONG lSamples,
  132. LPVOID lpBuffer,
  133. LONG cbBuffer,
  134. DWORD dwFlags,
  135. LONG FAR *plSampWritten,
  136. LONG FAR *plBytesWritten);
  137. HRESULT STDMETHODCALLTYPE PalMapStreamDelete(
  138. PAVISTREAM ps,
  139. LONG lStart,
  140. LONG lSamples);
  141. HRESULT STDMETHODCALLTYPE PalMapStreamReadData(
  142. PAVISTREAM ps,
  143. DWORD fcc,
  144. LPVOID lp,
  145. LONG FAR *lpcb);
  146. HRESULT STDMETHODCALLTYPE PalMapStreamWriteData(
  147. PAVISTREAM ps,
  148. DWORD fcc,
  149. LPVOID lp,
  150. LONG cb);
  151. HRESULT STDMETHODCALLTYPE PalMapStreamSetInfo(
  152.         PAVISTREAM ps,
  153.         AVISTREAMINFOW FAR * psi,
  154.         LONG lSize);
  155. IAVIStreamVtbl PalMapStreamHandler = {
  156. PalMapStreamQueryInterface,
  157. PalMapStreamAddRef,
  158. PalMapStreamRelease,
  159. PalMapStreamCreate,
  160. PalMapStreamInfo,
  161. PalMapStreamFindKeyFrame,
  162. PalMapStreamReadFormat,
  163. PalMapStreamSetFormat,
  164. PalMapStreamRead,
  165. PalMapStreamWrite,
  166. PalMapStreamDelete,
  167. PalMapStreamReadData,
  168. PalMapStreamWriteData,
  169.         PalMapStreamSetInfo
  170. };
  171. STDAPI AVICreateMappedStream(PAVISTREAM FAR *ppsMapped,
  172. PAVISTREAM ps,
  173. int nColors)
  174. {
  175. PPALMAPSTREAM pavi;
  176. HRESULT hr;
  177. *ppsMapped = 0;
  178. pavi = (PPALMAPSTREAM) GlobalAllocPtr(GHND, sizeof(PALMAPSTREAM));
  179. if (pavi == NULL)
  180. return ResultFromScode(AVIERR_MEMORY);
  181. pavi->lpVtbl = &PalMapStreamHandler;
  182. hr = (pavi->lpVtbl->Create)((PAVISTREAM) pavi, (LONG) ps, nColors);
  183. if (hr != NOERROR) {
  184. (pavi->lpVtbl->Release)((PAVISTREAM) pavi);
  185. return hr;
  186. }
  187. *ppsMapped = (PAVISTREAM) pavi;
  188. return AVIERR_OK;
  189. }
  190. ///////////////////////////////////////////////////////////////////////////
  191. //
  192. //  PalMapStreamOpen()
  193. //
  194. //  open a single stream of a particular type from a AVI file.
  195. //
  196. //  params:
  197. //      szFile      - PAVISTREAM
  198. //      fccType     - must be streamtypeVIDEO
  199. //      lParam     - nColors
  200. //
  201. //  returns:
  202. //      a PAVISTREAM for the specifed stream or NULL.
  203. //
  204. ///////////////////////////////////////////////////////////////////////////
  205. HRESULT STDMETHODCALLTYPE PalMapStreamCreate(
  206. PAVISTREAM ps,
  207. LONG lParam1,
  208. LONG lParam2)
  209. {
  210. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  211. TCHAR achTemp[128];
  212. TCHAR achTemplate[64];
  213. LONG lRet = AVIERR_OK;
  214. pavi->ulRefCount = 1;
  215. AVIStreamAddRef((PAVISTREAM) lParam1);
  216. pavi->pavi = (PAVISTREAM) lParam1;
  217. AVIStreamInfo(pavi->pavi, &pavi->sinfo, sizeof(pavi->sinfo));
  218. if (pavi->sinfo.fccType != streamtypeVIDEO) {
  219. lRet = AVIERR_INTERNAL;
  220. goto error;
  221. }
  222. pavi->pgf = AVIStreamGetFrameOpen(pavi->pavi, NULL);
  223. if (!pavi->pgf) {
  224. lRet = AVIERR_INTERNAL;
  225. goto error;
  226. }
  227. pavi->sinfo.fccHandler = 0;
  228. // Fix up stream name
  229. LoadString(ghMod, IDS_STREAMNAME, achTemplate,
  230. sizeof(achTemplate) / sizeof(TCHAR));
  231. wsprintf(achTemp, achTemplate, pavi->sinfo.szName, lParam2);
  232. lstrcpyn(pavi->sinfo.szName, achTemp,
  233. sizeof(pavi->sinfo.szName) / sizeof(TCHAR));
  234. pavi->sinfo.szName[sizeof(pavi->sinfo.szName) / sizeof(TCHAR) - 1] =
  235.                 TEXT('');
  236. // default to 256 colors
  237. if (lParam2 < 2 || lParam2 > 256)
  238. lParam2 = 256;
  239. pavi->lp16to8 = GlobalAllocPtr(GMEM_MOVEABLE, 32768L);
  240. if (!pavi->lp16to8) {
  241. lRet = AVIERR_MEMORY;
  242. goto error;
  243. }
  244. lRet = GetScode(AVIStreamMakePalette(pavi->pavi,
  245. AVIStreamLength(pavi->pavi) / 30,
  246. &pavi->hpal, pavi->lp16to8,
  247. (int) lParam2));
  248. pavi->lLastFrame = -1;
  249. error:
  250. return ResultFromScode(lRet);
  251. }
  252. ///////////////////////////////////////////////////////////////////////////
  253. //
  254. //  PalMapStreamQueryInterface()
  255. //
  256. //      let other people know what interfaces we support
  257. //
  258. ///////////////////////////////////////////////////////////////////////////
  259. HRESULT STDMETHODCALLTYPE PalMapStreamQueryInterface(
  260. PAVISTREAM ps,
  261. REFIID riid,
  262. LPVOID FAR* ppvObj)
  263. {
  264. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  265. if (IsEqualIID(riid, &IID_IUnknown))
  266. *ppvObj = ps;
  267. else if (IsEqualIID(riid, &IID_IAVIStream))
  268. *ppvObj = ps;
  269. else
  270. return ResultFromScode(E_NOINTERFACE);
  271. pavi->ulRefCount++;
  272. return NOERROR;
  273. }
  274. ///////////////////////////////////////////////////////////////////////////
  275. //
  276. //  PalMapStreamAddRef()
  277. //
  278. //      increase the reference count of the stream
  279. //
  280. ///////////////////////////////////////////////////////////////////////////
  281. ULONG STDMETHODCALLTYPE PalMapStreamAddRef(
  282. PAVISTREAM ps)
  283. {
  284. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  285. return ++pavi->ulRefCount;
  286. }
  287. ///////////////////////////////////////////////////////////////////////////
  288. //
  289. //  PalMapStreamRelease()
  290. //
  291. //      close a PalMapStream stream
  292. //
  293. ///////////////////////////////////////////////////////////////////////////
  294. ULONG STDMETHODCALLTYPE PalMapStreamRelease(
  295. PAVISTREAM ps)
  296. {
  297. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  298. if (!pavi)
  299. return 0;
  300. if (--pavi->ulRefCount)
  301. return pavi->ulRefCount;
  302. if (pavi->pgf)
  303. AVIStreamGetFrameClose(pavi->pgf);
  304. pavi->pgf = 0;
  305. if (pavi->pavi)
  306. AVIStreamClose(pavi->pavi);
  307. pavi->pavi = 0;
  308. if (pavi->lp16to8) {
  309. GlobalFreePtr(pavi->lp16to8);
  310. pavi->lp16to8 = 0;
  311. }
  312. if (pavi->hpal) {
  313. DeletePalette(pavi->hpal);
  314. pavi->hpal = 0;
  315. }
  316. if (pavi->lpdibLast) {
  317. GlobalFreePtr(pavi->lpdibLast);
  318. pavi->lpdibLast = 0;
  319. }
  320. GlobalFreePtr(pavi);
  321. return 0;
  322. }
  323. ///////////////////////////////////////////////////////////////////////////
  324. ///////////////////////////////////////////////////////////////////////////
  325. HRESULT STDMETHODCALLTYPE PalMapStreamReadFormat(
  326. PAVISTREAM ps,
  327. LONG lPos,
  328. LPVOID lpFormat,
  329. LONG FAR *lpcbFormat)
  330. {
  331. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  332. LONG lSize;
  333. PalMapStreamRead(ps, lPos, 1, NULL, 0, NULL, NULL);
  334. if (pavi->lpdibLast == 0)
  335. return ResultFromScode(AVIERR_INTERNAL);
  336. lSize = pavi->lpdibLast->biSize
  337. + pavi->lpdibLast->biClrUsed * sizeof(RGBQUAD);
  338. if (lpFormat)
  339. hmemcpy(lpFormat, pavi->lpdibLast,
  340. min(*lpcbFormat, lSize));
  341. *lpcbFormat = lSize;
  342. return 0;
  343. }
  344. LONG STDMETHODCALLTYPE PalMapStreamFindKeyFrame(
  345. PAVISTREAM ps,
  346. LONG lPos,
  347. LONG lFlags)
  348. {
  349. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  350. return lPos;
  351. }
  352. ///////////////////////////////////////////////////////////////////////////
  353. ///////////////////////////////////////////////////////////////////////////
  354. HRESULT STDMETHODCALLTYPE PalMapStreamInfo(
  355. PAVISTREAM ps,
  356. AVISTREAMINFOW FAR * psi,        // OLE interfaces are ALWAYS UNICODE
  357. LONG lSize)
  358. {
  359. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  360. if (psi)
  361. hmemcpy(psi, &pavi->sinfo, min(lSize, sizeof(pavi->sinfo)));
  362. return 0;
  363. }
  364. ///////////////////////////////////////////////////////////////////////////
  365. ///////////////////////////////////////////////////////////////////////////
  366. HRESULT STDMETHODCALLTYPE PalMapStreamRead(
  367. PAVISTREAM ps,
  368. LONG lStart,
  369. LONG lSamples,
  370. LPVOID lpBuffer,
  371. LONG cbBuffer,
  372. LONG FAR * plBytes,
  373. LONG FAR * plSamples)
  374. {
  375. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  376. LPBITMAPINFOHEADER lpbi;
  377. LPVOID lp;
  378. if (lStart != pavi->lLastFrame) {
  379. pavi->lLastFrame = -1;
  380. lpbi = AVIStreamGetFrame(pavi->pgf, lStart);
  381. if (!lpbi)
  382. goto ReadNothing;
  383. if (pavi->lpdibLast) {
  384. GlobalFreePtr(pavi->lpdibLast);
  385. pavi->lpdibLast = 0;
  386. }
  387. pavi->lpdibLast = DibReduce(lpbi, NULL, pavi->hpal, pavi->lp16to8);
  388. pavi->lLastFrame = lStart;
  389. }
  390. lpbi = pavi->lpdibLast;
  391. //
  392. // a NULL buffer means return the size buffer needed to read
  393. // the given sample.
  394. //
  395. lp = (LPBYTE) lpbi + lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
  396. if (plBytes)
  397. *plBytes = lpbi->biSizeImage;
  398. if (plSamples)
  399. *plSamples = 1;
  400. if (lpBuffer) {
  401. if (cbBuffer >= (LONG) lpbi->biSizeImage)
  402. hmemcpy(lpBuffer, lp, lpbi->biSizeImage);
  403. else
  404. goto ReadNothing;
  405. }
  406. return 0;
  407. ReadNothing:
  408. if (plBytes)
  409. *plBytes = 0;
  410. if (plSamples)
  411. *plSamples = 0;
  412. return ResultFromScode(AVIERR_BUFFERTOOSMALL);
  413. }
  414. //
  415. //
  416. // Extra unimplemented functions.....
  417. //
  418. //
  419. //
  420. HRESULT STDMETHODCALLTYPE PalMapStreamReadData(
  421. PAVISTREAM ps,
  422. DWORD fcc,
  423. LPVOID lp,
  424. LONG FAR *lpcb)
  425. {
  426. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  427. return ResultFromScode(AVIERR_UNSUPPORTED);
  428. }
  429. HRESULT STDMETHODCALLTYPE PalMapStreamSetFormat(
  430. PAVISTREAM ps,
  431. LONG lPos,
  432. LPVOID lpFormat,
  433. LONG cbFormat)
  434. {
  435. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  436. return ResultFromScode(AVIERR_UNSUPPORTED);
  437. }
  438. HRESULT STDMETHODCALLTYPE PalMapStreamWriteData(
  439. PAVISTREAM ps,
  440. DWORD fcc,
  441. LPVOID lp,
  442. LONG cb)
  443. {
  444. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  445. return ResultFromScode(AVIERR_UNSUPPORTED);
  446. }
  447. HRESULT STDMETHODCALLTYPE PalMapStreamWrite(
  448. PAVISTREAM ps,
  449. LONG lStart,
  450. LONG lSamples,
  451. LPVOID lpBuffer,
  452. LONG cbBuffer,
  453. DWORD dwFlags,
  454. LONG FAR *plSampWritten,
  455. LONG FAR *plBytesWritten)
  456. {
  457. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  458. return ResultFromScode(AVIERR_UNSUPPORTED);
  459. }
  460. HRESULT STDMETHODCALLTYPE PalMapStreamDelete(
  461. PAVISTREAM ps,
  462. LONG lStart,
  463. LONG lSamples)
  464. {
  465. PPALMAPSTREAM pavi = (PPALMAPSTREAM) ps;
  466. return ResultFromScode(AVIERR_UNSUPPORTED);
  467. }
  468. HRESULT STDMETHODCALLTYPE PalMapStreamSetInfo(
  469.    PAVISTREAM ps,
  470.    AVISTREAMINFOW FAR * psi,
  471.    LONG lSize)
  472. {
  473. return ResultFromScode(AVIERR_UNSUPPORTED);
  474. }
  475. EXTERN_C int CALLBACK WEP(
  476. BOOL fSystemExit)
  477. {
  478. return TRUE;
  479. }
  480. EXTERN_C BOOL APIENTRY DllMain(HANDLE, DWORD, LPVOID);
  481. EXTERN_C BOOL APIENTRY DllMain(
  482. HANDLE hModule,
  483. DWORD dwReason,
  484. LPVOID lpReserved )
  485. {
  486. switch( dwReason)
  487. {
  488. case DLL_PROCESS_ATTACH:
  489. if(ghMod == NULL)
  490. ghMod = (HMODULE)hModule;
  491. break;
  492. case DLL_THREAD_ATTACH:
  493. break;
  494. case DLL_THREAD_DETACH:
  495. break;
  496. case DLL_PROCESS_DETACH:
  497. break;
  498. }
  499. return TRUE;
  500. }