/*[]=====================================================================[]*/ /*[] LEADTOOLS for Windows - Version 11 []*/ /*[] []*/ /*[] []*/ /*[] Copyright (c) 1991-2000 LEAD Technologies, Inc. []*/ /*[] All Rights Reserved. []*/ /*[]=====================================================================[]*/ /*---(Feature1)------------------------------------------------------------- LEAD Functions Used. L_FileInfo L_InitBitmap L_LoadBitmap L_ColorResBitmap L_FreeBitmap L_CopyBitmapHandle L_FlipBitmap L_ChangeBitmapIntensity L_SizeBitmap L_AllocateBitmap L_ResizeBitmap L_RotateBitmap L_CreatePaintPalette L_PaintDC We have made the assumption that the user has the knowledge of programing in C and Windows. This example will: 1. load an image from a file, whose name is sent through the command line, to a bitmap as 24 bits per pixel, 2. display the image, 3. colorres the image to 8 bits per pixel, but only the best 50 colors, in a new bitmap handle, and re-display the image, 4. flip and re-display the image, 5. lighten and re-display the image, 6. resize and re-display the image, 7. rotate and re-display the image. Usage: FEATURE1 --------------------------------------------------------------------------*/ #include /* Required for all Windows applications. */ #include /* Windows header for message cracker. */ #include #include "tchar.h" #include "..\\..\\..\\include\\l_bitmap.h" /* LEADTOOLS main header file. */ #include "..\\..\\..\\include\\l_error.h" /* LEADTOOLS error definition header file. */ #include "Feature1.h" /* Application specific header file. */ L_BOOL ExtractCommandData ( ) ; /*---[WinMain]--------------------------------------------------------------- Syntax: int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) Parameters: hInstance Current instance. hPrevInstance previous instance. lpCmdLine command line. nCmdShow show-window type. Prototype: Windows.h Notes: Windows main function, calls initialization function and processes message loop. --------------------------------------------------------------------------*/ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; /* Windows' Message variable for holding messages */ UNLOCKSUPPORT (); if (!hPrevInstance) /* Other instances of app running? */ if (!InitApplication (hInstance)) /* Initialize shared things. */ return (FALSE); /* Exits if unable to initialize. */ ExtractCommandData ( ) ; if (!InitInstance (hInstance, nCmdShow)) /* Do instance initializations. */ return (FALSE); /* Acquire and dispatch messages until a WM_QUIT message is received. */ while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); /* Translates virtual key codes. */ DispatchMessage (&msg); /* Dispatches message to window. */ } return (msg.wParam); /* Returns the value from PostQuitMessage. */ } /*---[InitApplication]------------------------------------------------------ Syntax: L_BOOL InitApplication( HANDLE hInstance ) Parameters: hInstance Current instance. Prototype: Feature1.h Notes: Initializes window class structure and registers window class. --------------------------------------------------------------------------*/ L_BOOL InitApplication (HANDLE hInstance) { WNDCLASS wcWindowClass; wcWindowClass.style = 0; /* Class style(s). */ wcWindowClass.lpfnWndProc = MainWndProc; /* Function to retrieve messages */ /* for windows of this class. */ wcWindowClass.cbClsExtra = 0;/* No per-class extra data. */ wcWindowClass.cbWndExtra = 0;/* No per-window extra data. */ wcWindowClass.hInstance = hInstance; /* Owner. */ wcWindowClass.hIcon = LoadIcon (hInstance, TEXT("LEAD")); wcWindowClass.hCursor = LoadCursor (NULL, IDC_ARROW); wcWindowClass.hbrBackground = GetStockObject (WHITE_BRUSH); wcWindowClass.lpszMenuName = NULL; /* No menu. */ wcWindowClass.lpszClassName = TEXT("LEADWClass"); /* Name. */ /* Register the window class and return the result code. */ return (RegisterClass (&wcWindowClass)); } /*---[InitInstance]---------------------------------------------------------- Syntax: L_BOOL InitInstance( HANDLE hInstance, L_INT nCmdShow ) Parameters: hInstance Current instance. nCmdShow Param for first ShowWindow() call. Prototype: Feature1.h Notes: Creates main window. --------------------------------------------------------------------------*/ L_BOOL InitInstance (HANDLE hInstance, L_INT nCmdShow) { HWND hWnd; /* Window handle. */ /* Create a main window for this application instance. */ Data.FileInfo.uStructSize = sizeof(FILEINFO); if (L_FileInfo (Data.szFilename, &Data.FileInfo, sizeof(FILEINFO), 0, NULL) != SUCCESS) return (FALSE); rWndSize.top = 0; rWndSize.left = 0; rWndSize.bottom = INFOHEIGHT(&Data.FileInfo); rWndSize.right = INFOWIDTH(&Data.FileInfo); AdjustWindowRect (&rWndSize, WS_OVERLAPPEDWINDOW, FALSE); hWnd = CreateWindow ( TEXT("LEADWClass"), TEXT("LEADTOOLS Sample Application"), /* Window title */ WS_OVERLAPPEDWINDOW, /* Window style. */ CW_USEDEFAULT, /* Default horizontal position. */ CW_USEDEFAULT, /* Default vertical position. */ rWndSize.right - rWndSize.left, /* Window width. */ rWndSize.bottom - rWndSize.top, /* Window height. */ NULL, /* Overlapped windows have no parent. */ NULL, /* Use the window class menu. */ hInstance, /* This instance owns this window. */ NULL /* Pointer not needed. */ ); if (hWnd == NULL) return (FALSE); /* If window could not be created, return "failure" */ ShowWindow (hWnd, nCmdShow); /* Show the window. */ UpdateWindow (hWnd); /* Sends WM_PAINT message. */ return (TRUE); } /*---[MainWndProc]----------------------------------------------------------- Syntax: L_INT32 EXT_FUNCTION MainWndProc( HWND hWnd, L_UINT message, WPARAM wParam, LPARAM lParam ) Parameters: hWnd Window handle. message Type of message. wParam Additional information. lParam Additional information. Prototype: Feature1.h Notes: This procedure is responsible for dispatching window messages. --------------------------------------------------------------------------*/ L_INT32 EXT_FUNCTION MainWndProc (HWND hWnd, L_UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { HANDLE_MSG (hWnd, WM_CREATE, Window_OnCreate); HANDLE_MSG (hWnd, WM_TIMER, Window_OnTimer); HANDLE_MSG (hWnd, WM_QUERYNEWPALETTE, Window_OnQueryNewPalette); HANDLE_MSG (hWnd, WM_PALETTECHANGED, Window_OnPaletteChanged); HANDLE_MSG (hWnd, WM_ACTIVATE, Window_OnActivate); HANDLE_MSG (hWnd, WM_PALETTEISCHANGING, Window_OnPaletteChanging); HANDLE_MSG (hWnd, WM_SYSCOLORCHANGE, Window_SysColorChange); HANDLE_MSG (hWnd, WM_PAINT, Window_OnPaint); HANDLE_MSG (hWnd, WM_DESTROY, Window_OnDestroy); } return DefWindowProc (hWnd, Message, wParam, lParam); } /*---[Window_OnCreate]----------------------------------------------------- Syntax: BOOL Window_OnCreate( HWND hwnd, CREATESTRUCT FAR* lpCreateStruct ); Parameters: hWnd Window handle. lpCreateStruct Windows Create Structure. Prototype: Feature1.h Notes: This procedure is responsible for handling WM_CREATE. --------------------------------------------------------------------------*/ BOOL Window_OnCreate (HWND hWnd, CREATESTRUCT FAR * lpCreateStruct) { L_INT nRet; UNREFERENCED_PARAMETER (lpCreateStruct); /* Initialize the bitmap handle to the image width, height, and 24 Bits per pixel. */ L_InitBitmap (&Data.BitmapHandle, sizeof(BITMAPHANDLE), Data.FileInfo.Width, Data.FileInfo.Height, 24); /* Load the image to the bitmap. */ nRet = L_LoadBitmap (Data.szFilename, &Data.BitmapHandle, sizeof(BITMAPHANDLE), 0, ORDER_BGR, NULL, &Data.FileInfo); /* Initialize some globals. */ bFirst = TRUE; bResetCount = TRUE; Data.ProcessNum = DO_COLORRES; if (nRet != SUCCESS) { L_TCHAR buf[1024]; /* Buffer to hold the error message. */ wsprintf (buf, TEXT("Error %d loading %s"), nRet, (LPTSTR) Data.szFilename); MessageBox (hWnd, buf, TEXT("Error"), MB_OK); return (FALSE); /* Failure in creation, so return FALSE. */ } FORWARD_WM_QUERYNEWPALETTE (hWnd, SendMessage); return (TRUE); } /*---[Window_OnTimer]------------------------------------------------------- Syntax: VOID Window_OnTimer( HWND hWnd, UINT id ); Parameters: hWnd Window handle. id ID of the Timer. Prototype: Feature1.h Notes: This procedure is responsible for handling WM_TIMER. --------------------------------------------------------------------------*/ VOID Window_OnTimer (HWND hWnd, UINT id) { L_INT nRet; static HCURSOR hOrigCursor; BITMAPHANDLE NewBitmap; /* For the colorres'd bitmap. */ RECT rcClient; RECT rcWindow; UNREFERENCED_PARAMETER (id); nCount++; /* Increment the Counter. */ /* Has the image been displayed about 3 seconds? (this is reset in the function Window_OnPaint) */ if (nCount == 1) { hOrigCursor = SetCursor (LoadCursor (NULL, IDC_SIZENS)); return; } else if (nCount == 2) { SetCursor (LoadCursor (NULL, IDC_SIZENESW)); return; } SetCursor (LoadCursor (NULL, IDC_WAIT)); /* Let Window_OnPaint reset the counter. */ bResetCount = TRUE; switch (Data.ProcessNum) { case DO_COLORRES: /* Make NewBitmap contain the best 50 colors in an 8-bit bitmap. */ SetWindowText (hWnd, TEXT("Optimizing Image To 50 Colors With Burkes Dithering...")); nRet = L_ColorResBitmap (&Data.BitmapHandle, &NewBitmap, sizeof(BITMAPHANDLE), 8, CRF_OPTIMIZEDPALETTE | CRF_BURKESDITHERING, NULL, NULL, 50, NULL, NULL); if (nRet == SUCCESS) { /* Free the old image data. */ L_FreeBitmap (&Data.BitmapHandle); /* Make Data.BitmapHandle point to the new image data. */ L_CopyBitmapHandle (&Data.BitmapHandle, &NewBitmap, sizeof(BITMAPHANDLE)); SetWindowText (hWnd, TEXT("Image Is Optimized")); FORWARD_WM_QUERYNEWPALETTE (hWnd, SendMessage); } else SetWindowText (hWnd, TEXT("ERROR Optimizing The Image")); Data.ProcessNum = DO_FLIP;/* Next operation is Flip. */ break; case DO_FLIP: /* Flip the image top to bottom. */ SetWindowText (hWnd, TEXT("Flipping Image...")); nRet = L_FlipBitmap (&Data.BitmapHandle); if (nRet == SUCCESS) SetWindowText (hWnd, TEXT("Image Is Flipped")); else SetWindowText (hWnd, TEXT("ERROR Flipping The Image")); Data.ProcessNum = DO_INTENSITY; /* Next operation is Lighten. */ break; case DO_INTENSITY: /* Lighten the bitmap. */ SetWindowText (hWnd, TEXT("Lightening Image...")); nRet = L_ChangeBitmapIntensity (&Data.BitmapHandle, 100); if (nRet == SUCCESS) { SetWindowText (hWnd, TEXT("Image Is Lightened")); FORWARD_WM_QUERYNEWPALETTE (hWnd, SendMessage); } else SetWindowText (hWnd, TEXT("ERROR Lightening The Image")); Data.ProcessNum = DO_RESIZE; /* Next operation is Resize. */ break; case DO_RESIZE: /* You could use L_SizeBitmap to do the same as below. The code would only be as follows: nRet = L_SizeBitmap( &Data.BitmapHandle, 320, 200 ); Data.ProcessNum = DO_ROTATE; */ /* Initialize the new bitmap handle. */ L_InitBitmap (&NewBitmap, sizeof(BITMAPHANDLE), 320, 200, Data.BitmapHandle.BitsPerPixel); /* Allocate the storage to hold the image data. */ nRet = L_AllocateBitmap (&NewBitmap, TYPE_CONV); if (nRet == SUCCESS) { SetWindowText (hWnd, TEXT("Resizing Image...")); /* Resize the image. */ nRet = L_ResizeBitmap (&Data.BitmapHandle, &NewBitmap, SIZE_NORMAL); if (nRet == SUCCESS) { /* Resize the window to accomodate the new image dimensions. */ GetClientRect (hWnd, &rcClient); GetWindowRect (hWnd, &rcWindow); MoveWindow (hWnd, rcWindow.left, rcWindow.top, RECTWIDTH (&rcWindow) + BITMAPWIDTH(&NewBitmap) - RECTWIDTH (&rcClient), RECTHEIGHT (&rcWindow) + BITMAPHEIGHT(&NewBitmap) - RECTHEIGHT (&rcClient), TRUE); SetWindowText (hWnd, TEXT("Image Is Resized")); L_CopyBitmapPalette(&NewBitmap, &Data.BitmapHandle); /* Free the old image data. */ L_FreeBitmap (&Data.BitmapHandle); /* Copy the new bitmap handle into the global bitmap handle. Do NOT call L_FreeBitmap on the NewBitmap after this, or you will lose the image. (Both LEAD BitmapHandles point to the same memory location for the image!) */ L_CopyBitmapHandle (&Data.BitmapHandle, &NewBitmap, sizeof(BITMAPHANDLE)); } else SetWindowText (hWnd, TEXT("ERROR Resizing The Image")); } else SetWindowText (hWnd, TEXT("ERROR Allocating A New Bitmap")); Data.ProcessNum = DO_ROTATE; /* Next operation is Rotate. */ break; case DO_ROTATE: /* Rotate the image 33 degrees clockwise, without resizing. */ SetWindowText (hWnd, TEXT("Rotating Image...")); nRet = L_RotateBitmap (&Data.BitmapHandle, 3300, ROTATE_RESIZE, RGB(0,0,0)); if (nRet == SUCCESS) { /* Resize the window to accomodate the new image dimensions. */ GetClientRect (hWnd, &rcClient); GetWindowRect (hWnd, &rcWindow); MoveWindow (hWnd, rcWindow.left, rcWindow.top, RECTWIDTH (&rcWindow) + BITMAPWIDTH(&Data.BitmapHandle) - RECTWIDTH (&rcClient), RECTHEIGHT (&rcWindow) + BITMAPHEIGHT(&Data.BitmapHandle) - RECTHEIGHT (&rcClient), TRUE); SetWindowText (hWnd, TEXT("Image Is Rotated, Example Is Complete")); } else SetWindowText (hWnd, TEXT("ERROR Rotating The Image, Example Is Complete")); Data.ProcessNum = DO_QUIT; break; } /* Invalidate the entire client region to display the changes. */ InvalidateRect (hWnd, NULL, TRUE); /* Kill the timer if ProcessNum is DO_QUIT. */ if (Data.ProcessNum == DO_QUIT) KillTimer (hWnd, nTimer); SetCursor (hOrigCursor); return; } /*----(Window_OnPaletteChanged)-------------------------------------------- Syntax: VOID Window_OnPaletteChanged( HWND hWnd, HWND hWndPaletteChange ) Parameters: hwnd Handle to a window. hWndPaletteChange Handle to a window that has the palette realized. Prototype: Feature1.h Notes: This procedure is responsible for handling WM_PALETTECHANGED. --------------------------------------------------------------------------*/ VOID Window_OnPaletteChanged (HWND hWnd, HWND hWndPaletteChange) { HDC hDC; HPALETTE hPalette; /* If this window initiated the palette change, do nothing. */ if (hWnd == hWndPaletteChange) return; /* Delete the previous palette, if there is one. */ if (Data.hPalette) { DeleteObject (Data.hPalette); Data.hPalette = NULL; } /* Does this window have a bitmap and a palette? */ if (Data.BitmapHandle.Flags.Allocated) { hDC = GetDC (hWnd); /* Generate a new logical palette (if needed) for painting. */ Data.hPalette = L_CreatePaintPalette (hDC, &Data.BitmapHandle); /* Select and Realize the palette. */ hPalette = SelectPalette (hDC, Data.hPalette, TRUE); RealizePalette (hDC); /* Force a repaint. */ InvalidateRect (hWnd, NULL, FALSE); /* Return the old palette. */ SelectPalette (hDC, hPalette, TRUE); ReleaseDC (hWnd, hDC); } return; } /*----(Window_OnQueryNewPalette)-------------------------------------------- Syntax: BOOL Window_OnQueryNewPalette( HWND hWnd ) Parameters: hWnd Handle to a window. Prototype: Feature1.h Notes: This procedure is responsible for handling WM_QUERYNEWPALETTE. --------------------------------------------------------------------------*/ BOOL Window_OnQueryNewPalette (HWND hWnd) { HDC hDC; HPALETTE hPalette; L_INT nNoColors = 0; /* Delete the previous palette, if there is one. */ if (Data.hPalette) { DeleteObject (Data.hPalette); Data.hPalette = NULL; } if (Data.BitmapHandle.Flags.Allocated) { hDC = GetDC (hWnd); /* Generate a new logical palette (if needed) for painting. */ Data.hPalette = L_CreatePaintPalette (hDC, &Data.BitmapHandle); /* Is a palette needed? */ if (Data.hPalette) { hPalette = SelectPalette (hDC, Data.hPalette, FALSE); nNoColors = RealizePalette (hDC); if (nNoColors) /* If the palette changed, force a WM_PAINT. */ InvalidateRect (hWnd, NULL, FALSE); /* Restore the old palette. */ SelectPalette (hDC, hPalette, TRUE); } ReleaseDC (hWnd, hDC); } return (nNoColors); } /*---[Window_OnActivate]----------------------------------------------------- Syntax: VOID Window_OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized) Parameters: hWnd Window handle. state WA_ACTIVE | WA_CLICKACTIVE | WA_INACTIVE hwndActDeact the winodw habdle that deactivate fMinimized Window is minimized Prototype: Color.h Notes: This procedure is responsible for handling WM_ACTIVATE. --------------------------------------------------------------------------*/ VOID Window_OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized) { if(state!=WA_INACTIVE) Window_OnQueryNewPalette (hwnd); } /*====(Window_OnPaletteChanging)========================================== Description: Enumerates all child windows and asks them to realize their logical palettes beside the physical palette. Syntax : VOID Window_OnPaletteChanging(HWND hwnd, HWND hWndPaletteChange) Parameters : hwnd Handle to a window. hWndPaletteChange Handle to a window that has the palette realized. Return Value: None. ==========================================================================*/ VOID Window_OnPaletteChanging(HWND hWnd, HWND hWndPaletteChange) { Window_OnPaletteChanged (hWnd, hWndPaletteChange); } /*====(Window_SysColorChange)========================================== Syntax: VOID Window_SysColorChange( HWND hWnd ) Parameters: hWnd Handle to a window. Prototype: Loadsave.h Notes: This procedure is responsible for handling WM_SYSCOLORCHANGE. --------------------------------------------------------------------------*/ VOID Window_SysColorChange(HWND hwnd) { Window_OnQueryNewPalette (hwnd); } /*---[Window_OnPaint]------------------------------------------------------- Syntax: VOID Window_OnPaint( HWND hWnd ); Parameters: hWnd Window handle. Prototype: Feature1.h Notes: This procedure is responsible for handling WM_PAINT. --------------------------------------------------------------------------*/ VOID Window_OnPaint (HWND hWnd) { HDC hdc; RECT rc; PAINTSTRUCT ps; HPALETTE hOldPal = NULL; hdc = BeginPaint (hWnd, &ps);/* Get DC */ if (Data.BitmapHandle.Flags.Allocated) /* Do we have an image? */ { if (Data.hPalette) /* Is there a palette that needs to be selected? */ hOldPal = SelectPalette (hdc, Data.hPalette, TRUE); /* Select it */ /* Setup the Destination Rectangle. */ SetRect (&rc, 0, 0, Data.BitmapHandle.Width, Data.BitmapHandle.Height); SetRect (&rc, 0, 0, BITMAPWIDTH(&Data.BitmapHandle), BITMAPHEIGHT(&Data.BitmapHandle)); /* Paint it */ L_PaintDC (hdc, &Data.BitmapHandle, NULL, NULL, &rc, &ps.rcPaint, SRCCOPY); if (Data.hPalette) /* Return old palette, if there is one. */ SelectPalette (hdc, hOldPal, TRUE); if (bResetCount) { bResetCount = FALSE; /* Make sure counter is only reset after image processing has been done in Window_OnTimer. */ nCount = 0; /* Reset the counter for display delay. */ } if (bFirst) { bFirst = FALSE; /* Start a timer to be used for display delay. */ if ((nTimer = SetTimer (hWnd, 1, 1000, 0)) == 0) { MessageBox (hWnd, TEXT("No Timers Are Available!"), TEXT("ERROR - Resources"), MB_OK); /* No timers are available, so quit the application. */ FORWARD_WM_DESTROY (hWnd, PostMessage); } } } EndPaint (hWnd, &ps); /* Return DC */ return; } /*---[Window_OnDestroy]---------------------------------------------------- Syntax: VOID Window_OnDestroy( HWND hWnd ); Parameters: hWnd Window handle. Prototype: Feature1.h Notes: This procedure is responsible for handling WM_DESTROY. --------------------------------------------------------------------------*/ VOID Window_OnDestroy (HWND hWnd) { UNREFERENCED_PARAMETER (hWnd); if (Data.BitmapHandle.Flags.Allocated) /* Do we have an image? */ L_FreeBitmap (&Data.BitmapHandle); if (Data.hPalette) /* Delete palette if there is one. */ DeleteObject (Data.hPalette); PostQuitMessage (0); /* Post WM_QUIT, to end the application. */ } /*---[ExtractCommandData]---------------------------------------------------- Syntax: L_BOOL ExtractCommandData( ); Parameters: None. ProtoType: Feature1.c Notes: - This procedure is responsible for extracting the file name passed through the command line. - You should call this function only in WinMain function. --------------------------------------------------------------------------*/ L_BOOL ExtractCommandData ( ) { LPTSTR pszFirst = NULL; LPTSTR pszCmdLine = NULL; LPTSTR psz = NULL; L_INT nFirstPos = 0 ; L_INT nStringLen = 0 ; pszCmdLine = GetCommandLine(); nStringLen = lstrlen ( pszCmdLine ) + 1 ; // To specify that it is command line or not. if(( pszCmdLine[1] == ':' ) || // Shortcut case ( pszCmdLine[2] == ':' )) //VS case { // 1- TRY TO EXPOSE THE EXE NAME FROM THE COMMAND LINE psz = _tcschr ( pszCmdLine, ':' ) ; if ( NULL == psz ) { return FALSE ; } } else { psz = pszCmdLine ; } pszFirst = _tcschr ( psz + 1, ':' ) ; if ( NULL == pszFirst ) { return FALSE ; } // Calc the char number to the image file name. nFirstPos = pszFirst - pszCmdLine - 1 ; if ( 0 > nFirstPos ) { return FALSE ; } memset (Data.szFilename, 0, sizeof(Data.szFilename)); lstrcpyn ( Data.szFilename, pszFirst - 1, ( nStringLen - nFirstPos ) ) ; return TRUE; }