home *** CD-ROM | disk | FTP | other *** search
-
- /****************************************************************************
- *
- * WRITEAVI.C
- *
- * Creates the file OUTPUT.AVI, an AVI file consisting of a rotating clock
- * face. This program demonstrates using the functions in AVIEASY.C to make
- * writing AVI files simple.
- *
- * Copyright (c) 1992-1993 Microsoft Corporation. All Rights Reserved.
- *
- * You have a royalty-free right to use, modify, reproduce and
- * distribute the Sample Files (and/or any modified version) in
- * any way you find useful, provided that you agree that
- * Microsoft has no warranty obligations or liability for any
- * Sample Application Files which are modified.
- *
- ***************************************************************************/
-
- #include <windows.h>
- #include <mmsystem.h>
- #include "avieasy.h"
-
- //
- // Our movie is 160x120 and 15 frames long
- //
- #define BITMAP_X 160
- #define BITMAP_Y 120
- #define N_FRAMES 15
-
- #ifndef WIN32
- #define CODE _based(_segname("_CODE"))
- #define STACK _based(_segname("_STACK"))
- #else
- #define CODE
- #define STACK
- #endif
-
- //
- // A quick lookup table for Sin and Cos values
- //
- static int CODE aSin[N_FRAMES] = {
- 0, 40, 74, 95, 99,
- 86, 58, 20, -20, -58,
- -86, -99, -95, -74, -40,
- } ;
-
- static int CODE aCos[N_FRAMES] = {
- 100, 91, 66, 30, -10,
- -49, -80, -97, -97, -80,
- -50, -10, 30, 66, 91,
- } ;
-
- static char CODE sz02U[] = "%02u";
-
- static void FreeFrames( LPBITMAPINFOHEADER FAR *alpbi) ;
- static void MakeFrames(LPBITMAPINFOHEADER FAR *alpbi, UINT bits, UINT wXSize,UINT wYSize ) ;
- static HANDLE MakeDib( HBITMAP hbitmap, UINT bits ) ;
-
-
- //
- // Our main message loop... we don't have a window, we just pop up a dialog
- // box, write the file, and quit
- //
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR szCmdLine, int sw)
- {
- LPBITMAPINFOHEADER alpbi[N_FRAMES];
- HAVI havi;
- int i;
-
- alpbi[0] = NULL;
-
- if (MessageBox(NULL, "This program writes some DIBs into a file called OUTPUT.AVI. "
- "We apologize for the lack of a user interface.",
- "WriteAVI Sample",
- MB_OKCANCEL) == IDCANCEL)
- return 0;
-
- //
- // Set up the bitmaps for the file in an array
- //
- MakeFrames(alpbi, 8, BITMAP_X, BITMAP_Y);
-
- //
- // Since we are writing an AVI file with a single video stream, we have
- // a helper function that will do both the avifileOpen and avifileAddStream
- // for us
- //
- aviVideoOpen(&havi, "output.avi", alpbi[0], 0);
-
- //
- // Now write out each video frame. Again, since this is a file with only
- // 1 stream (a video stream) we can use this function instead of
- // avifileWrite to save a little work
- //
- for (i = 0; i < N_FRAMES; i++)
- aviVideoWriteFrame(havi, alpbi[i], NULL, AVIIF_KEYFRAME);
-
- //
- // Now close the file
- //
- avifileClose(havi);
-
- //
- // Free the resources used to store the frames
- //
- FreeFrames(alpbi);
-
- return 0;
- }
-
- //
- // Fill an array of LPBI's with the frames for this movie
- //
- static void MakeFrames(LPBITMAPINFOHEADER FAR *alpbi, UINT bits, UINT wXSize,UINT wYSize )
- {
- HDC hdc ;
- HDC hdcMem ;
- HBITMAP hbitmap,hbitmapOld ;
- HPEN hpen3,hpen1,hpenwhite,hpenOld ;
- HFONT hfont,hfontOld ;
- HBRUSH hbrush,hbrushOld ;
- RECT rc ;
- RECT rcFrameNo ;
- int wXCent,wYCent ;
- int cxPixInch ;
- int cyPixInch ;
- int cxPixels ;
- int cyPixels ;
- int radius ;
- int x0,y0,x1,y1 ;
- int i,j ;
- char ach[3] ;
-
- //
- // Make sure our resources are freed
- //
- FreeFrames(alpbi);
-
- //
- // Find the centre of the movie
- //
- wXCent = wXSize/2 ;
- wYCent = wYSize/2 ;
-
- hdc = GetDC(NULL) ;
- hdcMem = CreateCompatibleDC(NULL) ;
-
- //
- // We need some gray and white brushes and pens, and a bitmap
- //
- hpen3 = CreatePen(PS_SOLID,3,RGB(128,128,128)) ;
- hpen1 = CreatePen(PS_SOLID,1,RGB(64,64,64));
- hpenwhite = CreatePen(PS_SOLID,1,RGB(255,255,255)) ;
- hpenOld = SelectObject(hdcMem,hpen3) ;
- hbrush = CreateSolidBrush(RGB(192,192,192)) ;
- hbrushOld = SelectObject(hdcMem,hbrush) ;
- hbitmap = CreateCompatibleBitmap(hdc,wXSize,wYSize) ;
- hbitmapOld = SelectObject(hdcMem,hbitmap) ;
-
- cxPixInch = GetDeviceCaps(hdc,LOGPIXELSX) ;
- cyPixInch = GetDeviceCaps(hdc,LOGPIXELSY) ;
-
- //
- // What radius of circle can we fit in this frame? Make sure it's round
- // regardless of the aspect ratio
- //
- radius = ( wXSize < wYSize ) ? wXSize : (wYSize*cxPixInch)/cyPixInch ;
- radius = ( radius * 95 ) / 200 ;
-
- //
- // Make a Rectangle in the centre where the number will go
- //
- /* x0 = radius / sqrt(2) */
- x0 = (radius*100)/141 ;
- y0 = (x0*cyPixInch)/cxPixInch ;
- x0 = (x0*9)/10 ;
- y0 = (y0*9)/10 ;
- SetRect( &rcFrameNo,wXCent-x0,wYCent-y0,wXCent+x0,wYCent+y0 ) ;
-
- //
- // Move the rectangle in a little and make a font big enough for it
- //
- x0 = (x0*9)/10 ;
- y0 = (y0*9)/10 ;
-
- hfont = CreateFont(
- y0*2,
- x0,
- 0,
- 0,
- FW_BOLD,
- 0,
- 0,
- 0,
- ANSI_CHARSET,
- OUT_DEVICE_PRECIS,
- CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY,
- DEFAULT_PITCH|FF_SWISS,
- NULL
- ) ;
-
- hfontOld = SelectObject(hdcMem,hfont) ;
-
- //
- // Now walk through and make all the frames
- //
- for ( i=0; i<N_FRAMES; i++ )
- {
- //
- // Fill the whole frame with white
- //
- SetRect(&rc,0,0,wXSize,wYSize) ;
- FillRect(hdcMem,&rc,(HBRUSH)GetStockObject(WHITE_BRUSH)) ;
-
- //
- // Draw the circle inside the previously calculated radius
- //
- cxPixels = radius ;
- cyPixels = (cxPixels*cyPixInch)/cxPixInch ;
-
- SelectObject(hdcMem,hpen3) ;
- Ellipse(hdcMem,wXCent-cxPixels,wYCent-cyPixels,wXCent+cxPixels,
- wYCent+cyPixels) ;
-
- SelectObject(hdcMem,hpen1) ;
-
- //
- // Draw the number in the previously calculated area
- //
- wsprintf(ach,sz02U,i+1) ;
-
- SetBkColor(hdcMem,RGB(192,192,192)) ;
- SetTextColor(hdcMem,RGB(255,255,255)) ;
- ExtTextOut(
- hdcMem,
- rcFrameNo.left,rcFrameNo.top+(rcFrameNo.bottom-rcFrameNo.top)/20,
- ETO_CLIPPED,
- &rcFrameNo,
- ach,
- 2,
- NULL);
-
- //
- // Draw tic marks around the inside of the circle in equal divisions
- //
- for ( j=0; j<N_FRAMES; j++ )
- {
- x0 = (radius*aSin[j])/100 ;
- y0 = (radius*aCos[j])/100 ;
- x1 = (((radius*aSin[j])/100)*11)/12 ;
- y1 = (((radius*aCos[j])/100)*11)/12 ;
-
- y0 = -(y0*cyPixInch)/cxPixInch ;
- y1 = -(y1*cyPixInch)/cxPixInch ;
-
- MoveTo(hdcMem,wXCent+x0,wYCent+y0) ;
- LineTo(hdcMem,wXCent+x1,wYCent+y1) ;
- }
-
- //
- // Now draw the hand of the clock in the appropriate position
- //
- x1 = (((radius*aSin[i])/100)*5)/8 ;
- y1 = (((radius*aCos[i])/100)*5)/8 ;
- y1 = -(y1*cyPixInch)/cxPixInch ;
-
- MoveTo(hdcMem,wXCent,wYCent) ;
- LineTo(hdcMem,wXCent+x1,wYCent+y1) ;
-
- //
- // Make this into a DIB and stuff it into the array
- //
- alpbi[i] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hbitmap, bits));
-
- //
- // For an error, just duplicate the last frame if we can
- //
- if (alpbi[i] == NULL && i )
- alpbi[i] = alpbi[i-1] ;
- }
-
- //
- // Select all the old objects back and delete resources
- //
- SelectObject(hdcMem,hpenOld) ;
- SelectObject(hdcMem,hbrushOld) ;
- SelectObject(hdcMem,hbitmapOld) ;
- SelectObject(hdcMem,hfontOld) ;
- DeleteObject(hpen1) ;
- DeleteObject(hpen3) ;
- DeleteObject(hpenwhite) ;
- DeleteObject(hbrush) ;
- DeleteObject(hbitmap) ;
- DeleteObject(hfont) ;
- DeleteObject(hdcMem) ;
- ReleaseDC(NULL,hdc) ;
- }
-
- //
- // Walk through our array of LPBI's and free them
- //
- static void FreeFrames(LPBITMAPINFOHEADER FAR *alpbi)
- {
- UINT w ;
-
- if (!alpbi[0])
- return ;
-
- //
- // Don't free a frame if it's a duplicate of the previous one
- //
- for (w=0; w<N_FRAMES; w++)
- if (alpbi[w] && alpbi[w] != alpbi[w-1])
- GlobalFree(SELECTOROF(alpbi[w]));
-
- for (w=0; w<N_FRAMES; w++)
- alpbi[w] = NULL;
- }
-
- /*
- ** MakeDib(hbitmap)
- **
- ** Take the given bitmap and transform it into a DIB with parameters:
- **
- ** BitsPerPixel: 8
- ** Colors: palette
- **
- */
- static HANDLE MakeDib( HBITMAP hbitmap, UINT bits )
- {
- HANDLE hdib ;
- HDC hdc ;
-
- BITMAP bitmap ;
- UINT wLineLen ;
- DWORD dwSize ;
- DWORD wColSize ;
- LPBITMAPINFOHEADER lpbi ;
- LPBYTE lpBits ;
-
- GetObject(hbitmap,sizeof(BITMAP),&bitmap) ;
-
- //
- // DWORD align the width of the DIB
- // Figure out the size of the colour table
- // Calculate the size of the DIB
- //
- wLineLen = (bitmap.bmWidth*bits+31)/32 * 4;
- wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<<bits : 0);
- dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
- (DWORD)(UINT)wLineLen*(DWORD)(UINT)bitmap.bmHeight;
-
- //
- // Allocate room for a DIB and set the LPBI fields
- //
- if ((hdib = GlobalAlloc(GHND,dwSize)) == (HANDLE)NULL)
- return hdib ;
-
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib) ;
-
- lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
- lpbi->biWidth = bitmap.bmWidth ;
- lpbi->biHeight = bitmap.bmHeight ;
- lpbi->biPlanes = 1 ;
- lpbi->biBitCount = bits ;
- lpbi->biCompression = BI_RGB ;
- lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ;
- lpbi->biXPelsPerMeter = 0 ;
- lpbi->biYPelsPerMeter = 0 ;
- lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
- lpbi->biClrImportant = 0 ;
-
- //
- // Get the bits from the bitmap and stuff them after the LPBI
- //
- lpBits = (LPBYTE)(lpbi+1)+wColSize ;
-
- hdc = CreateCompatibleDC(NULL) ;
-
- GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi,
- DIB_RGB_COLORS);
-
- DeleteDC(hdc) ;
-
- return hdib ;
- }
-