A Fast Bresenham Type Algorithm For Drawing Ellipses by John Kennedy
[xy_vsfilter.git] / src / filters / BaseClasses / winutil.h
blobc4748036a8f8a2a62dc089a9a309f448176079ea
1 //------------------------------------------------------------------------------
2 // File: WinUtil.h
3 //
4 // Desc: DirectShow base classes - defines generic handler classes.
5 //
6 // Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.
7 //------------------------------------------------------------------------------
10 // Make sure that you call PrepareWindow to initialise the window after
11 // the object has been constructed. It is a separate method so that
12 // derived classes can override useful methods like MessageLoop. Also
13 // any derived class must call DoneWithWindow in its destructor. If it
14 // doesn't a message may be retrieved and call a derived class member
15 // function while a thread is executing the base class destructor code
17 #ifndef __WINUTIL__
18 #define __WINUTIL__
20 const int DEFWIDTH = 320; // Initial window width
21 const int DEFHEIGHT = 240; // Initial window height
22 const int CAPTION = 256; // Maximum length of caption
23 const int TIMELENGTH = 50; // Maximum length of times
24 const int PROFILESTR = 128; // Normal profile string
25 const WORD PALVERSION = 0x300; // GDI palette version
26 const LONG PALETTE_VERSION = (LONG) 1; // Initial palette version
27 const COLORREF VIDEO_COLOUR = 0; // Defaults to black background
28 const HANDLE hMEMORY = (HANDLE) (-1); // Says to open as memory file
30 #define WIDTH(x) ((*(x)).right - (*(x)).left)
31 #define HEIGHT(x) ((*(x)).bottom - (*(x)).top)
32 #define SHOWSTAGE TEXT("WM_SHOWSTAGE")
33 #define SHOWSTAGETOP TEXT("WM_SHOWSTAGETOP")
34 #define REALIZEPALETTE TEXT("WM_REALIZEPALETTE")
36 class AM_NOVTABLE CBaseWindow
38 protected:
40 HINSTANCE m_hInstance; // Global module instance handle
41 HWND m_hwnd; // Handle for our window
42 HDC m_hdc; // Device context for the window
43 LONG m_Width; // Client window width
44 LONG m_Height; // Client window height
45 BOOL m_bActivated; // Has the window been activated
46 LPTSTR m_pClassName; // Static string holding class name
47 DWORD m_ClassStyles; // Passed in to our constructor
48 DWORD m_WindowStyles; // Likewise the initial window styles
49 DWORD m_WindowStylesEx; // And the extended window styles
50 UINT m_ShowStageMessage; // Have the window shown with focus
51 UINT m_ShowStageTop; // Makes the window WS_EX_TOPMOST
52 UINT m_RealizePalette; // Makes us realize our new palette
53 HDC m_MemoryDC; // Used for fast BitBlt operations
54 HPALETTE m_hPalette; // Handle to any palette we may have
55 BYTE m_bNoRealize; // Don't realize palette now
56 BYTE m_bBackground; // Should we realise in background
57 BYTE m_bRealizing; // already realizing the palette
58 CCritSec m_WindowLock; // Serialise window object access
59 BOOL m_bDoGetDC; // Should this window get a DC
60 bool m_bDoPostToDestroy; // Use PostMessage to destroy
61 CCritSec m_PaletteLock; // This lock protects m_hPalette.
62 // It should be held anytime the
63 // program use the value of m_hPalette.
65 // Maps windows message procedure into C++ methods
66 friend LRESULT CALLBACK WndProc(HWND hwnd, // Window handle
67 UINT uMsg, // Message ID
68 WPARAM wParam, // First parameter
69 LPARAM lParam); // Other parameter
71 virtual LRESULT OnPaletteChange(HWND hwnd, UINT Message);
73 public:
75 CBaseWindow(BOOL bDoGetDC = TRUE, bool bPostToDestroy = false);
77 #ifdef DEBUG
78 virtual ~CBaseWindow();
79 #endif
81 virtual HRESULT DoneWithWindow();
82 virtual HRESULT PrepareWindow();
83 virtual HRESULT InactivateWindow();
84 virtual HRESULT ActivateWindow();
85 virtual BOOL OnSize(LONG Width, LONG Height);
86 virtual BOOL OnClose();
87 virtual RECT GetDefaultRect();
88 virtual HRESULT UninitialiseWindow();
89 virtual HRESULT InitialiseWindow(HWND hwnd);
91 HRESULT CompleteConnect();
92 HRESULT DoCreateWindow();
94 HRESULT PerformanceAlignWindow();
95 HRESULT DoShowWindow(LONG ShowCmd);
96 void PaintWindow(BOOL bErase);
97 void DoSetWindowForeground(BOOL bFocus);
98 virtual HRESULT SetPalette(HPALETTE hPalette);
99 void SetRealize(BOOL bRealize)
101 m_bNoRealize = !bRealize;
104 // Jump over to the window thread to set the current palette
105 HRESULT SetPalette();
106 void UnsetPalette(void);
107 virtual HRESULT DoRealisePalette(BOOL bForceBackground = FALSE);
109 void LockPaletteLock();
110 void UnlockPaletteLock();
112 virtual BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
113 { return FALSE; };
115 // Access our window information
117 bool WindowExists();
118 LONG GetWindowWidth();
119 LONG GetWindowHeight();
120 HWND GetWindowHWND();
121 HDC GetMemoryHDC();
122 HDC GetWindowHDC();
124 #ifdef DEBUG
125 HPALETTE GetPalette();
126 #endif // DEBUG
128 // This is the window procedure the derived object should override
130 virtual LRESULT OnReceiveMessage(HWND hwnd, // Window handle
131 UINT uMsg, // Message ID
132 WPARAM wParam, // First parameter
133 LPARAM lParam); // Other parameter
135 // Must be overriden to return class and window styles
137 virtual LPTSTR GetClassWindowStyles(
138 DWORD *pClassStyles, // Class styles
139 DWORD *pWindowStyles, // Window styles
140 DWORD *pWindowStylesEx) PURE; // Extended styles
144 // This helper class is entirely subservient to the owning CBaseWindow object
145 // All this object does is to split out the actual drawing operation from the
146 // main object (because it was becoming too large). We have a number of entry
147 // points to set things like the draw device contexts, to implement the actual
148 // drawing and to set the destination rectangle in the client window. We have
149 // no critical section locking in this class because we are used exclusively
150 // by the owning window object which looks after serialising calls into us
152 // If you want to use this class make sure you call NotifyAllocator once the
153 // allocate has been agreed, also call NotifyMediaType with a pointer to a
154 // NON stack based CMediaType once that has been set (we keep a pointer to
155 // the original rather than taking a copy). When the palette changes call
156 // IncrementPaletteVersion (easiest thing to do is to also call this method
157 // in the SetMediaType method most filters implement). Finally before you
158 // start rendering anything call SetDrawContext so that we can get the HDCs
159 // for drawing from the CBaseWindow object we are given during construction
161 class CDrawImage
163 protected:
165 CBaseWindow *m_pBaseWindow; // Owning video window object
166 CRefTime m_StartSample; // Start time for the current sample
167 CRefTime m_EndSample; // And likewise it's end sample time
168 HDC m_hdc; // Main window device context
169 HDC m_MemoryDC; // Offscreen draw device context
170 RECT m_TargetRect; // Target destination rectangle
171 RECT m_SourceRect; // Source image rectangle
172 BOOL m_bStretch; // Do we have to stretch the images
173 BOOL m_bUsingImageAllocator; // Are the samples shared DIBSECTIONs
174 CMediaType *m_pMediaType; // Pointer to the current format
175 int m_perfidRenderTime; // Time taken to render an image
176 LONG m_PaletteVersion; // Current palette version cookie
178 // Draw the video images in the window
180 void SlowRender(IMediaSample *pMediaSample);
181 void FastRender(IMediaSample *pMediaSample);
182 void DisplaySampleTimes(IMediaSample *pSample);
183 void UpdateColourTable(HDC hdc,BITMAPINFOHEADER *pbmi);
184 void SetStretchMode();
186 public:
188 // Used to control the image drawing
190 CDrawImage(CBaseWindow *pBaseWindow);
191 BOOL DrawImage(IMediaSample *pMediaSample);
192 BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample,
193 LPRECT lprcSrc, LPRECT lprcDst);
194 void SetDrawContext();
195 void SetTargetRect(RECT *pTargetRect);
196 void SetSourceRect(RECT *pSourceRect);
197 void GetTargetRect(RECT *pTargetRect);
198 void GetSourceRect(RECT *pSourceRect);
199 virtual RECT ScaleSourceRect(const RECT *pSource);
201 // Handle updating palettes as they change
203 LONG GetPaletteVersion();
204 void ResetPaletteVersion();
205 void IncrementPaletteVersion();
207 // Tell us media types and allocator assignments
209 void NotifyAllocator(BOOL bUsingImageAllocator);
210 void NotifyMediaType(CMediaType *pMediaType);
211 BOOL UsingImageAllocator();
213 // Called when we are about to draw an image
215 void NotifyStartDraw() {
216 MSR_START(m_perfidRenderTime);
219 // Called when we complete an image rendering
221 void NotifyEndDraw() {
222 MSR_STOP(m_perfidRenderTime);
227 // This is the structure used to keep information about each GDI DIB. All the
228 // samples we create from our allocator will have a DIBSECTION allocated to
229 // them. When we receive the sample we know we can BitBlt straight to an HDC
231 typedef struct tagDIBDATA {
233 LONG PaletteVersion; // Current palette version in use
234 DIBSECTION DibSection; // Details of DIB section allocated
235 HBITMAP hBitmap; // Handle to bitmap for drawing
236 HANDLE hMapping; // Handle to shared memory block
237 BYTE *pBase; // Pointer to base memory address
239 } DIBDATA;
242 // This class inherits from CMediaSample and uses all of it's methods but it
243 // overrides the constructor to initialise itself with the DIBDATA structure
244 // When we come to render an IMediaSample we will know if we are using our own
245 // allocator, and if we are, we can cast the IMediaSample to a pointer to one
246 // of these are retrieve the DIB section information and hence the HBITMAP
248 class CImageSample : public CMediaSample
250 protected:
252 DIBDATA m_DibData; // Information about the DIBSECTION
253 BOOL m_bInit; // Is the DIB information setup
255 public:
257 // Constructor
259 CImageSample(CBaseAllocator *pAllocator,
260 TCHAR *pName,
261 HRESULT *phr,
262 LPBYTE pBuffer,
263 LONG length);
265 // Maintain the DIB/DirectDraw state
267 void SetDIBData(DIBDATA *pDibData);
268 DIBDATA *GetDIBData();
272 // This is an allocator based on the abstract CBaseAllocator base class that
273 // allocates sample buffers in shared memory. The number and size of these
274 // are determined when the output pin calls Prepare on us. The shared memory
275 // blocks are used in subsequent calls to GDI CreateDIBSection, once that
276 // has been done the output pin can fill the buffers with data which will
277 // then be handed to GDI through BitBlt calls and thereby remove one copy
279 class CImageAllocator : public CBaseAllocator
281 protected:
283 CBaseFilter *m_pFilter; // Delegate reference counts to
284 CMediaType *m_pMediaType; // Pointer to the current format
286 // Used to create and delete samples
288 HRESULT Alloc();
289 void Free();
291 // Manage the shared DIBSECTION and DCI/DirectDraw buffers
293 HRESULT CreateDIB(LONG InSize,DIBDATA &DibData);
294 STDMETHODIMP CheckSizes(ALLOCATOR_PROPERTIES *pRequest);
295 virtual CImageSample *CreateImageSample(LPBYTE pData,LONG Length);
297 public:
299 // Constructor and destructor
301 CImageAllocator(CBaseFilter *pFilter,TCHAR *pName,HRESULT *phr);
302 #ifdef DEBUG
303 ~CImageAllocator();
304 #endif
306 STDMETHODIMP_(ULONG) NonDelegatingAddRef();
307 STDMETHODIMP_(ULONG) NonDelegatingRelease();
308 void NotifyMediaType(CMediaType *pMediaType);
310 // Agree the number of buffers to be used and their size
312 STDMETHODIMP SetProperties(
313 ALLOCATOR_PROPERTIES *pRequest,
314 ALLOCATOR_PROPERTIES *pActual);
318 // This class is a fairly specialised helper class for image renderers that
319 // have to create and manage palettes. The CBaseWindow class looks after
320 // realising palettes once they have been installed. This class can be used
321 // to create the palette handles from a media format (which must contain a
322 // VIDEOINFO structure in the format block). We try to make the palette an
323 // identity palette to maximise performance and also only change palettes
324 // if actually required to (we compare palette colours before updating).
325 // All the methods are virtual so that they can be overriden if so required
327 class CImagePalette
329 protected:
331 CBaseWindow *m_pBaseWindow; // Window to realise palette in
332 CBaseFilter *m_pFilter; // Media filter to send events
333 CDrawImage *m_pDrawImage; // Object who will be drawing
334 HPALETTE m_hPalette; // The palette handle we own
336 public:
338 CImagePalette(CBaseFilter *pBaseFilter,
339 CBaseWindow *pBaseWindow,
340 CDrawImage *pDrawImage);
342 #ifdef DEBUG
343 virtual ~CImagePalette();
344 #endif
346 static HPALETTE MakePalette(const VIDEOINFOHEADER *pVideoInfo, LPSTR szDevice);
347 HRESULT RemovePalette();
348 static HRESULT MakeIdentityPalette(PALETTEENTRY *pEntry,INT iColours, LPSTR szDevice);
349 HRESULT CopyPalette(const CMediaType *pSrc,CMediaType *pDest);
350 BOOL ShouldUpdate(const VIDEOINFOHEADER *pNewInfo,const VIDEOINFOHEADER *pOldInfo);
351 HRESULT PreparePalette(const CMediaType *pmtNew,const CMediaType *pmtOld,LPSTR szDevice);
353 BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, LPRECT lprcSrc, LPRECT lprcDst)
355 return m_pDrawImage->DrawVideoImageHere(hdc, pMediaSample, lprcSrc,lprcDst);
360 // Another helper class really for video based renderers. Most such renderers
361 // need to know what the display format is to some degree or another. This
362 // class initialises itself with the display format. The format can be asked
363 // for through GetDisplayFormat and various other accessor functions. If a
364 // filter detects a display format change (perhaps it gets a WM_DEVMODECHANGE
365 // message then it can call RefreshDisplayType to reset that format). Also
366 // many video renderers will want to check formats as they are proposed by
367 // source filters. This class provides methods to check formats and only
368 // accept those video formats that can be efficiently drawn using GDI calls
370 class CImageDisplay : public CCritSec
372 protected:
374 // This holds the display format; biSize should not be too big, so we can
375 // safely use the VIDEOINFO structure
376 VIDEOINFO m_Display;
378 static DWORD CountSetBits(const DWORD Field);
379 static DWORD CountPrefixBits(const DWORD Field);
380 static BOOL CheckBitFields(const VIDEOINFO *pInput);
382 public:
384 // Constructor and destructor
386 CImageDisplay();
388 // Used to manage BITMAPINFOHEADERs and the display format
390 const VIDEOINFO *GetDisplayFormat();
391 HRESULT RefreshDisplayType(LPSTR szDeviceName);
392 static BOOL CheckHeaderValidity(const VIDEOINFO *pInput);
393 static BOOL CheckPaletteHeader(const VIDEOINFO *pInput);
394 BOOL IsPalettised();
395 WORD GetDisplayDepth();
397 // Provide simple video format type checking
399 HRESULT CheckMediaType(const CMediaType *pmtIn);
400 HRESULT CheckVideoType(const VIDEOINFO *pInput);
401 HRESULT UpdateFormat(VIDEOINFO *pVideoInfo);
402 const DWORD *GetBitMasks(const VIDEOINFO *pVideoInfo);
404 BOOL GetColourMask(DWORD *pMaskRed,
405 DWORD *pMaskGreen,
406 DWORD *pMaskBlue);
409 // Convert a FORMAT_VideoInfo to FORMAT_VideoInfo2
410 STDAPI ConvertVideoInfoToVideoInfo2(AM_MEDIA_TYPE *pmt);
412 #endif // __WINUTIL__