Click here to Skip to main content
15,886,021 members
Articles / Desktop Programming / MFC

FreeImage Display Demo

Rate me:
Please Sign up or sign in to vote.
3.98/5 (20 votes)
4 Jun 2008Public Domain17 min read 97.1K   10.4K   54  
How to display a bitmap in your MFC SDI application using FreeImage. Various rescaling algorithms considered.
//	FreeImage Display Demo v3.0

//	Copyright (C) 2008 monday2000@yandex.ru
//
//	This program is free software; you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation; either version 2 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program; if not, write to the Free Software
//	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//	http://www.gnu.org/copyleft/gpl.html

// fi_testDoc.cpp : implementation of the CFi_testDoc class
//

#include "stdafx.h"
#include "fi_test.h"

#include "fi_testDoc.h"
#include "fi_testView.h"

#include "MainFrm.h" // <- added for Status Bar namefile display

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) ;

/////////////////////////////////////////////////////////////////////
// CFi_testDoc

IMPLEMENT_DYNCREATE(CFi_testDoc, CDocument)

BEGIN_MESSAGE_MAP(CFi_testDoc, CDocument)
//{{AFX_MSG_MAP(CFi_testDoc)
ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateFileSaveAs)
ON_UPDATE_COMMAND_UI(ID_FILE_CLOSE, OnUpdateFileClose)
ON_UPDATE_COMMAND_UI(ID_FIT_IMAGE, OnUpdateButtonFit)
ON_COMMAND(ID_FIT_IMAGE, OnButtonFit)
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
	ON_UPDATE_COMMAND_UI(ID_SCALE_PNM, OnUpdateScalePnm)
	ON_UPDATE_COMMAND_UI(ID_SCALE_BOX, OnUpdateScaleBox)
	ON_UPDATE_COMMAND_UI(ID_SCALE_BILINEAR, OnUpdateScaleBilinear)
	ON_COMMAND(ID_SCALE_PNM, OnScalePnm)
	ON_COMMAND(ID_SCALE_BILINEAR, OnScaleBilinear)
	ON_COMMAND(ID_SCALE_BOX, OnScaleBox)
	ON_COMMAND(ID_SCALE_LINEAR, OnScaleLinear)
	ON_UPDATE_COMMAND_UI(ID_SCALE_LINEAR, OnUpdateScaleLinear)
	ON_COMMAND(ID_SCALE_NO_FILTER, OnScaleNoFilter)
	ON_UPDATE_COMMAND_UI(ID_SCALE_NO_FILTER, OnUpdateScaleNoFilter)
	ON_COMMAND(ID_SCALE_CLOSEST, OnScaleClosest)
	ON_UPDATE_COMMAND_UI(ID_SCALE_CLOSEST, OnUpdateScaleClosest)
	//}}AFX_MSG_MAP
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
ON_COMMAND_RANGE(ID_FILE_MRU_FILE1, ID_FILE_MRU_FILE4, OnOpenRecentFile)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////
// CFi_testDoc construction/destruction

CFi_testDoc::CFi_testDoc()
{
	// TODO: add one-time construction code here
	
	m_dib = NULL;
	
	m_dib2 = NULL;
	
	m_NoEraseFlag = false;	
	
	CClientDC dc (NULL);
	
	m_dcOffscreen.CreateCompatibleDC(&dc);
	
	m_view_init_height = 0;
	
	m_view_init_width = 0;
	
	m_dcBitmapHolder.CreateCompatibleDC(&dc);

	m_fit_height = false;

	m_dib_w = 0;

	m_dib_h = 0;

	m_ResampleMode = 6;

}

CFi_testDoc::~CFi_testDoc()
{
	m_dcOffscreen.DeleteDC();	
}

BOOL CFi_testDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;
	
	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)
	
	return TRUE;	
}

/////////////////////////////////////////////////////////////////////

void CFi_testDoc::OnFileOpen()
{
	// TODO: Add your command handler code here	
	
	// If a file is opened - displaying its name on the Status Bar
	// while an opened file-dialog is onscreen
	
	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);
	
	if (m_dib)		
	{
		
		CString PaneText = pFr->m_wndStatusBar.GetPaneText(0);
		
		if (PaneText == "Ready") 
			
			pFr->m_wndStatusBar.SetPaneText(0, m_strFilename);
	}
	
	TCHAR strFilter[] = {TEXT(GRAPH_FILES_FILTER)};
	
	//TCHAR strFilter[] = {TEXT("Tif and Bmp files|*.bmp;*.tif|All files (*.*)|*.*||")};
	
	CString FileName;
	
	CFileDialog dlg(TRUE, NULL, NULL, 0, strFilter);
	
	if( dlg.DoModal() == IDOK )
		
		FileName = dlg.GetPathName();
	
	else return;
	
	OpenBitmapFile(FileName);
}

/////////////////////////////////////////////////////////////////////

BOOL CFi_testDoc::OpenBitmapFile(CString FileName) 
{
	FreeImage_SetOutputMessage(FreeImageErrorHandler);
	
	FIBITMAP* temp_dib;
	
	temp_dib = GenericLoader(FileName.GetBuffer(FileName.GetLength()), 0);
	
	if (temp_dib == NULL) 
	{
		AfxMessageBox("The file can not be opened");
		
		return false;
	}
	
	if (!m_dib)	{
		//  MSDN article Q108587 HOWTO: Get Current CDocument or CView from Anywhere
		CFi_testView* pView = (CFi_testView*)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
		
		ASSERT_VALID(pView);
		
		CRect rcClient;
		
		pView->GetClientRect(&rcClient);
		
		// Remember the view client area initial sizes
		
		m_view_init_height = rcClient.Height();
		
		m_view_init_width = rcClient.Width();
	}
	
	if (m_dib) OnFileClose(); // if a previous file is open - close it
	
	m_dib = temp_dib;
	
	m_strFilename = FileName; // Remember the opened file name
	
	m_dib_w = FreeImage_GetWidth(m_dib);
	
    m_dib_h = FreeImage_GetHeight(m_dib);
	
	double scale_height, scale_width;
	
	scale_height = (double)m_dib_h / m_view_init_height; // vert fit value
	
	scale_width = (double)m_dib_w / m_view_init_width; // horz fit value
	
	// Get the biggest dimension (width or height) which has to be
	// fitted into the client area
	
	m_fit_height = false;
	
	// Seek the tightest fit
	
	if (scale_height > scale_width) m_fit_height = true;
	
	double zoom;
	
	if (m_fit_height) zoom = (double)m_dib_h / m_view_init_height;
	
	else  zoom = (double)m_dib_w / m_view_init_width;

	
	if (zoom < 1) zoom = 1; // if an image is originally smaller than
	// the client area - do not enlarge it (to fit the client area)
	
	m_zoom_fit = zoom; // Remember the "Zoom Fit" zoom value
	
	DisplayBitmap(zoom);
	
	// Add the filename to the MRU list manually - since we changed the default OnCommand routing
	
	AfxGetApp()->AddToRecentFileList(m_strFilename.GetBuffer(m_strFilename.GetLength()));
	
	m_MRU_CalledFlag = false; // whether a MRU item was clicked


	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	CMenu* pSubMenu1 = pMenu->GetSubMenu(1);

	//pSubMenu1->EnableMenuItem(5, MF_BYPOSITION | MF_ENABLED);

			
	pFr->m_wndStatusBar.SetPaneText(0, m_strFilename);
	
	return true;
}

/////////////////////////////////////////////////////////////////////

BOOL CFi_testDoc::DisplayBitmap(double zoom)
{
	if (m_dib2)
	{
		FreeImage_Unload(m_dib2);
		
		m_dib2 = NULL;	
	}

	if (FreeImage_GetImageType(m_dib) != FIT_BITMAP)
	{
		AfxMessageBox("Displaying the non-FIT_BITMAP files is currently not implemented.");

		if (m_dib) OnFileClose();	
	}

	// this code chunk is taken out of the CResizeEngine::scale method
	// (called from FreeImage_Rescale)
	unsigned bpp_dst = FreeImage_GetBPP(m_dib);
	if(bpp_dst == 1) {
		// convert output to 8-bit
		bpp_dst = 8;
	}

	// Calculate the zoomed image width
	m_zdib_width = (int)(FreeImage_GetWidth(m_dib)/zoom);
	
	// Calculate the zoomed image height
    m_zdib_height = (int)(FreeImage_GetHeight(m_dib)/zoom);

	m_OffscreenSize.x = max(m_view_init_width, m_zdib_width);
	
	m_OffscreenSize.y = max(m_view_init_height, m_zdib_height);
	
	// Allocate the "empty" FIBITMAP - just as a BITMAPINFO holder
	m_dib2 = FreeImage_AllocateT(FreeImage_GetImageType(m_dib),
		
		1, 1, // this is a one-by-one pixel sized bitmap ("empty")
		
		bpp_dst,
		
		FreeImage_GetRedMask(m_dib),
		
		FreeImage_GetGreenMask(m_dib),
		
		FreeImage_GetBlueMask(m_dib));

	if (!m_dib2) return false;	

	m_pbih = FreeImage_GetInfoHeader(m_dib2);	

	m_pbih->biWidth = m_OffscreenSize.x; // replace 1 by the real backbitmap width

	m_pbih->biHeight = m_OffscreenSize.y; // replace 1 by the real backbitmap height

	m_pbi = FreeImage_GetInfo(m_dib2);	// now we have a full-fledged
	// BITMAPINFO structure for our rescaled image

	// this code chunk is taken out of the CResizeEngine::scale method
	// (called from FreeImage_Rescale)

	RGBQUAD *dst_pal = FreeImage_GetPalette(m_dib2);

	if(bpp_dst == 8)  // build the palette if needed
	{
		if(FreeImage_GetColorType(m_dib) == FIC_MINISWHITE)
		
			// build an inverted greyscale palette			
			for(int i = 0; i < 256; i++)
			
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)(255 - i);			
		 else 
		
			// build a greyscale palette			
			for(int i = 0; i < 256; i++) 
			
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)i;		
	}	

	CFi_testView* pView = (CFi_testView*)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	
	ASSERT_VALID(pView);	
	
	CRect rcClient;
	
	pView->GetClientRect(&rcClient);	
	
	// Create the DIB Section
	
	HBITMAP hBitmap = CreateDIBSection (NULL, m_pbi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, 0) ;
	
	if (hBitmap == NULL) return false;
	
	m_OffscreenBitmap.Attach(hBitmap);

	m_pOldBtmp = m_dcOffscreen.SelectObject(&m_OffscreenBitmap);

	// Fill the background bitmap with a backcolor
	m_dcOffscreen.FillSolidRect(0, 0, m_OffscreenSize.x,
		m_OffscreenSize.y, RGB(160, 160, 160));

	// Fill the DIB Section bitmap buffer (e.g. content to be displayed)

	// This function is remade out of pnmscalefixed scaling algorithm
	// from the netpbm project (the sourcecode is taken from WinDjView
	// Scaling.cpp)
	// It rescales a src FIBITMAP and places the result into
	// the provided BYTE* m_pBits buffer

	BOOL res = false;

	switch (m_ResampleMode)
	{

	case 6:

	res = LeptonicaScaleBySamplingLow(m_dib, m_zdib_width, m_zdib_height, m_OffscreenSize, m_pBits, dst_pal);

	}

	if (!res)	
	{
		FreeImage_Unload(m_dib2);
		
		m_dib2 = NULL;
		
		return false;
	}	
			   
	pView->SetNewScrollSizes(); // equal to the image width and height	
	
	// Set the initial screen position of an image to be displayed
	
	if (m_zdib_width > m_view_init_width)
		// the image width is bigger than the client area width
		
		// Scroll an image half-width so that it would be width-centered
		
		pView->SetScrollPos(SB_HORZ, (m_zdib_width-m_view_init_width)/2);
	
	
	if (m_zdib_height > m_view_init_height)	
		// the image height is bigger than the client area height
		
		// Scroll an image half-height so that it would be height-centered
		
		pView->SetScrollPos(SB_VERT, (m_zdib_height-m_view_init_height)/2);
	
	
	m_zoom = zoom; // Remember the current zoom value
	
	UpdateAllViews (NULL);
	
	return true;
}

//////////////////////////////////////////////////////////////////////

/*
BOOL CFi_testDoc::DisplayBitmap(double zoom)
{
	if (m_dib2)
	{
		FreeImage_Unload(m_dib2);
		
		m_dib2 = NULL;	
	}

	if (FreeImage_GetImageType(m_dib) != FIT_BITMAP)
	{
		AfxMessageBox("Displaying the non-FIT_BITMAP files is currently not implemented.");

		if (m_dib) OnFileClose();	
	}

	// this code chunk is taken out of the CResizeEngine::scale method
	// (called from FreeImage_Rescale)
	unsigned bpp_dst = FreeImage_GetBPP(m_dib);
	if(bpp_dst == 1) {
		// convert output to 8-bit
		bpp_dst = 8;
	}

	// Calculate the zoomed image width
	m_zdib_width = (int)(FreeImage_GetWidth(m_dib)/zoom);
	
	// Calculate the zoomed image height
    m_zdib_height = (int)(FreeImage_GetHeight(m_dib)/zoom);
	
	// Allocate the "empty" FIBITMAP - just as a BITMAPINFO holder
	m_dib2 = FreeImage_AllocateT(FreeImage_GetImageType(m_dib),
		
		1, 1, // this is a one-by-one pixel sized bitmap ("empty")
		
		bpp_dst,
		
		FreeImage_GetRedMask(m_dib),
		
		FreeImage_GetGreenMask(m_dib),
		
		FreeImage_GetBlueMask(m_dib));

	if (!m_dib2) return false;	

	m_pbih = FreeImage_GetInfoHeader(m_dib2);	

	m_pbih->biWidth = m_zdib_width; // replace 1 by the real rescaled width

	m_pbih->biHeight = m_zdib_height; // replace 1 by the real rescaled height

	m_pbi = FreeImage_GetInfo(m_dib2);	// now we have a full-fledged
	// BITMAPINFO structure for our rescaled image

	// this code chunk is taken out of the CResizeEngine::scale method
	// (called from FreeImage_Rescale)

	RGBQUAD *dst_pal = FreeImage_GetPalette(m_dib2);

	if(bpp_dst == 8)  // build the palette if needed
	{
		if(FreeImage_GetColorType(m_dib) == FIC_MINISWHITE)
		
			// build an inverted greyscale palette			
			for(int i = 0; i < 256; i++)
			
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)(255 - i);			
		 else 
		
			// build a greyscale palette			
			for(int i = 0; i < 256; i++) 
			
				dst_pal[i].rgbRed = dst_pal[i].rgbGreen =
					dst_pal[i].rgbBlue = (BYTE)i;		
	}	

	CFi_testView* pView = (CFi_testView*)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	
	ASSERT_VALID(pView);	
	
	CRect rcClient;
	
	pView->GetClientRect(&rcClient);	
	
	// Create the DIB Section
	
	HBITMAP hBitmap = CreateDIBSection (NULL, m_pbi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, 0) ;
	
	if (hBitmap == NULL) return false;
	
    m_Bitmap.Attach(hBitmap);
	
	// Put the image into the CDC-holder
	m_pOldBitmap = m_dcBitmapHolder.SelectObject(&m_Bitmap);

	// Fill the DIB Section bitmap buffer (e.g. content to be displayed)

	// This function is remade out of pnmscalefixed scaling algorithm
	// from the netpbm project (the sourcecode is taken from WinDjView
	// Scaling.cpp)
	// It rescales a src FIBITMAP and places the result into
	// the provided BYTE* m_pBits buffer

	BOOL res = false;

	switch (m_ResampleMode)
	{
	case 1:

	if(bpp_dst == 8)

	res = RescalePnm8(m_dib, m_zdib_width, m_zdib_height, m_pBits, dst_pal);

	else

	res = RescalePnm(m_dib, m_zdib_width, m_zdib_height, m_pBits);

	break;

	case 2:

	res = FI_Rescale2(m_dib, m_zdib_width, m_zdib_height,

		FILTER_BILINEAR, bpp_dst, m_pBits);
	break;

	case 3:

	res = FI_Rescale2(m_dib,m_zdib_width, m_zdib_height,
		
		FILTER_BOX, bpp_dst, m_pBits);
	break;

	case 4:

	if(bpp_dst == 8)
	
	LeptonicaScaleGrayLILow(m_dib, m_zdib_width, m_zdib_height, m_pBits, dst_pal, true);

	else

	LeptonicaScaleColorLILow(m_dib, m_zdib_width, m_zdib_height, m_pBits, true);

	res = true;	

	break;

	case 5:

	if(bpp_dst == 8)
	
	LeptonicaScaleGrayLILow(m_dib, m_zdib_width, m_zdib_height, m_pBits, dst_pal, false);

	else

	LeptonicaScaleColorLILow(m_dib, m_zdib_width, m_zdib_height, m_pBits, false);

	res = true;

	break;

	case 6:

	res = LeptonicaScaleBySamplingLow(m_dib, m_zdib_width, m_zdib_height, m_pBits, dst_pal);

	}

	if (!res)	
	{
		FreeImage_Unload(m_dib2);
		
		m_dib2 = NULL;
		
		return false;
	}

	m_OffscreenSize.x = max(m_view_init_width, m_zdib_width);
	
	m_OffscreenSize.y = max(m_view_init_height, m_zdib_height);
	
	// Create a background bitmap with a maximum viewable size
	m_OffscreenBitmap.CreateCompatibleBitmap(&m_dcBitmapHolder, 
		m_OffscreenSize.x, m_OffscreenSize.y);
	
	m_pOldBtmp = m_dcOffscreen.SelectObject(&m_OffscreenBitmap);
	
	// Fill the background bitmap with a backcolor
	m_dcOffscreen.FillSolidRect(0, 0, m_OffscreenSize.x,
		m_OffscreenSize.y, RGB(160, 160, 160));	
	
	// Put the image-bitmap onto the center of the background bitmap
	// (all this - in the memory device context yet)

	m_dcOffscreen.BitBlt((m_OffscreenSize.x - m_zdib_width)/2, 
		
		(m_OffscreenSize.y - m_zdib_height)/2, m_zdib_width, 
		
		m_zdib_height, &m_dcBitmapHolder, 0, 0, SRCCOPY);

	pView->SetNewScrollSizes(); // equal to the image width and height	
	
	// Set the initial screen position of an image to be displayed
	
	if (m_zdib_width > m_view_init_width)
		// the image width is bigger than the client area width
		
		// Scroll an image half-width so that it would be width-centered
		
		pView->SetScrollPos(SB_HORZ, (m_zdib_width-m_view_init_width)/2);
	
	
	if (m_zdib_height > m_view_init_height)	
		// the image height is bigger than the client area height
		
		// Scroll an image half-height so that it would be height-centered
		
		pView->SetScrollPos(SB_VERT, (m_zdib_height-m_view_init_height)/2);
	
	
	m_zoom = zoom; // Remember the current zoom value
	
	UpdateAllViews (NULL);
	
	return true;
}
*/
//////////////////////////////////////////////////////////////////////

BOOL CFi_testDoc::OnOpenRecentFile(UINT nID)
{
	
	CString FileName;
	
	CFi_testApp* pApp = (CFi_testApp*)AfxGetApp();
	
	pApp->GetRecentFilename(FileName, nID);
	
	m_MRU_CalledFlag = true;
	
	if (!OpenBitmapFile(FileName)) pApp->RemoveRecentFilename(nID);
	
	return true;
}

/////////////////////////////////////////////////////////////////////

// CMainFrame message handlers

void CFi_testDoc::OnFileClose() 
{
	// TODO: Add your command handler code here
	
	if (m_dib)
	{
		// free the loaded FIBITMAP
		FreeImage_Unload(m_dib);
		
		m_dib = NULL;
		
		m_pbi = NULL;
		
		m_pbih = NULL;
	}
	
	else return; // no file open
	
	if (m_dib2)
	{
		FreeImage_Unload(m_dib2);
		
		m_dib2 = NULL;	
	}
	
	m_dcOffscreen.SelectObject(m_pOldBitmap);
	
	m_OffscreenBitmap.DeleteObject();
	
	m_pOldBitmap = NULL;
	
	m_dcBitmapHolder.SelectObject(m_pOldBtmp);
	
	m_Bitmap.DeleteObject();
	
	m_pOldBtmp = NULL;
	
	CFi_testView* pView = (CFi_testView*)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	
	ASSERT_VALID(pView);
	
	if (!m_MRU_CalledFlag)
	/*
	Remove the (no more needed) scroll bars here if you don't open a new
	file right after you close the current one (e.g. having clicked 
	(previously) an item in the MRU list.
	*/	
	pView->ResetScrollSizes();	
	
	/*
	Otherwise (you have earlier clicked an item in the MRU list) 
	DO NOT remove the scroll bars HERE - because this will ALSO 
	automatically reset the "initial scroll position" of the current 
	bitmap - e.g. the current bitmap will be "scrolled" to the upper left
	corner - and this unwanted "scrolling" will produce here a 
	wrong-background-erase bug.
	*/
	else m_MRU_CalledFlag = false;


	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	CMenu* pSubMenu1 = pMenu->GetSubMenu(1);

	pSubMenu1->EnableMenuItem(5, MF_BYPOSITION | MF_GRAYED);
	
	
	UpdateAllViews (NULL);
}

/////////////////////////////////////////////////////////////////////

// CFi_testDoc serialization

void CFi_testDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////
// CFi_testDoc diagnostics

#ifdef _DEBUG
void CFi_testDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CFi_testDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////
// CFi_testDoc commands

/**
FreeImage error handler
@param fif Format / Plugin responsible for the error 
@param message Error message
*/
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) 
{
	CString Error_Message;
	
	Error_Message += FreeImage_GetFormatFromFIF(fif);
	
	Error_Message += " ";
	
	Error_Message += message;
	
	AfxMessageBox(Error_Message);
}

/////////////////////////////////////////////////////////////////////

/** Generic image loader

  @param lpszPathName Pointer to the full file name
  @param flag Optional load flag constant
  @return Returns the loaded dib if successful, returns NULL otherwise
*/

FIBITMAP* CFi_testDoc::GenericLoader(const char* lpszPathName, int flag)
{	
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	// check the file signature and deduce its format
	// (the second argument is currently not used by FreeImage)
	
	fif = FreeImage_GetFileType(lpszPathName, 0);
	
	if(fif == FIF_UNKNOWN)
	{
		// no signature ?
		// try to guess the file format from the file extension
		fif = FreeImage_GetFIFFromFilename(lpszPathName);
	}
	
	// check that the plugin has reading capabilities ...
	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))
	{
		// ok, let's load the file
		FIBITMAP *dib = FreeImage_Load(fif, lpszPathName, flag);
		
		// unless a bad file format, we are done !
		return dib;
	}
	
	return NULL;
}

/////////////////////////////////////////////////////////////////////

void CFi_testDoc::OnUpdateFileSaveAs(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);
}

/////////////////////////////////////////////////////////////////////

void CFi_testDoc::OnUpdateFileClose(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);
}

/////////////////////////////////////////////////////////////////////

void CFi_testDoc::OnUpdateButtonFit(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);	
}

/////////////////////////////////////////////////////////////////////

void CFi_testDoc::OnButtonFit() 
{
	// TODO: Add your command handler code here
	
	if (m_dib)	
	{
		
		m_dcOffscreen.SelectObject(m_pOldBitmap);
		
		m_OffscreenBitmap.DeleteObject();
		
		m_pOldBitmap = NULL;
		
		
		m_dcBitmapHolder.SelectObject(m_pOldBtmp);
		
		m_Bitmap.DeleteObject();
		
		m_pOldBtmp = NULL;
		
		
		CFi_testView* pView = (CFi_testView*)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
		
		ASSERT_VALID(pView);
		
		m_NoEraseFlag = true;
		
		DisplayBitmap(m_zoom_fit);
		
	}	
}

/////////////////////////////////////////////////////////////////////

void CFi_testDoc::OnFileSaveAs() 
{
	// TODO: Add your command handler code here
	
	if (m_dib)
	{
		
		TCHAR strFilter[] = {TEXT("Bmp files|*.bmp||")};	
		
		CFileDialog dlg(FALSE, "bmp", NULL, OFN_OVERWRITEPROMPT, strFilter);
		
		if (dlg.DoModal() == IDOK)
			
			FreeImage_Save(FIF_BMP, m_dib, dlg.GetPathName(), 0);
		
		else return;
		
	}
}


void CFi_testDoc::OnUpdateScalePnm(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here

	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);	
}

void CFi_testDoc::OnUpdateScaleBox(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here

	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);	
}

void CFi_testDoc::OnUpdateScaleBilinear(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here

	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);	
}

void CFi_testDoc::OnUpdateScaleLinear(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);	
}

void CFi_testDoc::OnUpdateScaleNoFilter(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);
}

void CFi_testDoc::OnUpdateScaleClosest(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (m_dib)
		
		pCmdUI->Enable(TRUE);
	
	else
		
		pCmdUI->Enable(FALSE);	
}

void CFi_testDoc::OnScalePnm() 
{
	// TODO: Add your command handler code here

	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	pMenu->CheckMenuItem (ID_SCALE_PNM, MF_CHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BILINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BOX, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_LINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_NO_FILTER, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_CLOSEST, MF_UNCHECKED);

	m_ResampleMode = 1;

	DisplayBitmap(m_zoom);
}

void CFi_testDoc::OnScaleBilinear() 
{
	// TODO: Add your command handler code here

	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	pMenu->CheckMenuItem (ID_SCALE_PNM, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BILINEAR, MF_CHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BOX, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_LINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_NO_FILTER, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_CLOSEST, MF_UNCHECKED);

	m_ResampleMode = 2;

	DisplayBitmap(m_zoom);	
}


void CFi_testDoc::OnScaleBox() 
{
	// TODO: Add your command handler code here

	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	pMenu->CheckMenuItem (ID_SCALE_PNM, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BILINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BOX, MF_CHECKED);

	pMenu->CheckMenuItem (ID_SCALE_LINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_NO_FILTER, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_CLOSEST, MF_UNCHECKED);

	m_ResampleMode = 3;

	DisplayBitmap(m_zoom);	
}


void CFi_testDoc::OnScaleLinear() 
{
	// TODO: Add your command handler code here

	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	pMenu->CheckMenuItem (ID_SCALE_PNM, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BILINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BOX, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_LINEAR, MF_CHECKED);

	pMenu->CheckMenuItem (ID_SCALE_NO_FILTER, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_CLOSEST, MF_UNCHECKED);

	m_ResampleMode = 4;

	DisplayBitmap(m_zoom);	
}


void CFi_testDoc::OnScaleNoFilter() 
{
	// TODO: Add your command handler code here

	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	pMenu->CheckMenuItem (ID_SCALE_PNM, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BILINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BOX, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_LINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_NO_FILTER, MF_CHECKED);

	pMenu->CheckMenuItem (ID_SCALE_CLOSEST, MF_UNCHECKED);

	m_ResampleMode = 5;

	DisplayBitmap(m_zoom);	
}

void CFi_testDoc::OnScaleClosest() 
{
	// TODO: Add your command handler code here

	CMainFrame* pFr = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	ASSERT_VALID(pFr);

	CMenu* pMenu = pFr->GetMenu();

	pMenu->CheckMenuItem (ID_SCALE_PNM, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BILINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_BOX, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_LINEAR, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_NO_FILTER, MF_UNCHECKED);

	pMenu->CheckMenuItem (ID_SCALE_CLOSEST, MF_CHECKED);

	m_ResampleMode = 6;

	DisplayBitmap(m_zoom);	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions