www.pudn.com > Cimage.zip > CIMAGEB.CPP


/* 
 * File:	cimageb.cc 
 * Purpose:	Platform Independent Image Base Class (Windows version) 
 * Author:	Alejandro Aguilar Sierra 
 * Created:	1995 
 * Copyright:	(c) 1995 Alejandro Aguilar Sierra  
 */ 
 
#include "stdafx.h" 
#include  
#include "cmap.h" 
#include "cimageb.h" 
#include "dibutils.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
void 
CImageImpl::Create(int width, int height, int depth, int colortype) 
{ 
  Width = width; Height = height; Depth = depth; 
  ColorType = (colortype>=0) ? colortype: ((Depth>8) ? COLORTYPE_COLOR: 0); 
 
  if (lpbi) 
    GlobalFreePtr(lpbi); 
  RawImage = 0; 
  if (imagePalette) 
    delete imagePalette; 
  imagePalette = 0; 
  if (lpbi = DibCreate(Depth, Width, Height))  { 
		RawImage = (ImagePointerType)DibPtr(lpbi); 
		EffWidth = (long)(((long)Width*Depth + 31) / 32) * 4; 
  } 
} 
 
CImageImpl::~CImageImpl ( ) 
{ 
  if (lpbi)  { 
	 GlobalFreePtr(lpbi); 
	 delete imagePalette; 
  } 
} 
 
 
int CImageImpl::GetIndex(int x, int y) 
{ 
  if (!Inside(x, y) || (Depth>8)) return -1; 
 
  ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3); 
  int index = (int)(*ImagePointer); 
  return index; 
} 
 
BOOL CImageImpl::GetRGB(int x, int y, byte* r, byte* g, byte* b) 
{ 
  if (!Inside(x, y)) return FALSE; 
 
  if (imagePalette) { 
	 return imagePalette->GetRGB(GetIndex(x, y), r, g, b); 
/*	 PALETTEENTRY entry; 
	 ::GetPaletteEntries((HPALETTE) (*imagePalette), GetIndex(x, y), 1, &entry); 
	 *r = entry.peRed; 
	 *g = entry.peGreen; 
	 *b = entry.peBlue;  */ 
  } else { 
	 ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3); 
	 *b = ImagePointer[0]; 
	 *g = ImagePointer[1]; 
	 *r = ImagePointer[2]; 
  } 
  return TRUE; 
} 
 
 
BOOL CImageImpl::SetIndex(int x, int y, int index) 
{ 
  if (!Inside(x, y) || (Depth>8)) return FALSE; 
 
  ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3); 
  *ImagePointer = index; 
 
  return TRUE; 
} 
 
BOOL CImageImpl::SetRGB(int x, int y, byte r, byte g, byte b) 
{ 
  if (!Inside(x, y)) return FALSE; 
 
  if (ColorType & COLORTYPE_PALETTE) 
  { 
	 if (!imagePalette) return FALSE; 
	 SetIndex(x, y, imagePalette->GetPixel(r, g, b)); 
 
  } else { 
	 ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3); 
	 ImagePointer[0] = b; 
	 ImagePointer[1] = g; 
	 ImagePointer[2] = r; 
  } 
 
  return TRUE; 
} 
 
BOOL CImageImpl::SetPalette(CImagePalette* colourmap) 
{ 
  if (!colourmap) 
	 return FALSE; 
  ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR); 
  imagePalette = colourmap; 
  return DibSetUsage(lpbi, (HPALETTE) (*imagePalette), CIMAGE_COLORS ); 
} 
 
BOOL 
CImageImpl::SetPalette(int n, byte *r, byte *g, byte *b) 
{ 
  imagePalette = new CImagePalette(); 
  if (!imagePalette) 
	 return FALSE; 
 
  if (!g) g = r; 
  if (!b) b = g; 
  imagePalette->Create(n, r, g, b); 
  ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR); 
  return DibSetUsage(lpbi, (HPALETTE) (*imagePalette), CIMAGE_COLORS ); 
} 
 
BOOL 
CImageImpl::SetPalette(int n, rgb_color_struct *rgb_struct) 
{ 
  if (imagePalette) 
    AfxMessageBox("CImageImpl::imagePalette already exists!"); 
     
  imagePalette = new CImagePalette(); 
  if (!imagePalette) 
	 return FALSE; 
 
  byte r[256], g[256], b[256]; 
 
  for(int i=0; iCreate(n, r, g, b); 
  ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR); 
  return DibSetUsage(lpbi, (HPALETTE) (*imagePalette), CIMAGE_COLORS ); 
} 
 
BOOL CImageImpl::Draw(CDC *cdc, int x, int y, int dx, int dy, int xs, int ys) 
{ 
  if (lpbi) 
  { 
	 HDC dc = cdc->GetSafeHdc(); 
 
	 if (dc)   { 
		::RealizePalette(dc); 
		if (dx==-1)  dx = GetWidth(); 
		if (dy==-1)  dy = GetHeight(); 
 
		SetDIBitsToDevice(dc, x, y, dx, dy, xs, 0, ys, dy, 
			RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS ); 
	 } 
	 return TRUE; 
  } 
  else 
	 return FALSE; 
 
} 
 
BOOL CImageImpl::Stretch(CDC *cdc, int xd, int yd, int dxd, int dyd, 
	 int xs, int ys, int dxs, int dys) 
{ 
  if (lpbi) 
  { 
	HDC dc =  cdc->GetSafeHdc(); 
 
	 if (dc)   { 
		if (dxd==-1) dxd = GetWidth(); 
		if (dyd==-1) dyd = GetHeight(); 
		if (dxs==-1) dxs = Width - xs; 
		if (dys==-1) dys = Height - ys; 
		::RealizePalette(dc); 
 
#ifdef WIN32       // Paul Shirley's patch 
		SetStretchBltMode(dc, COLORONCOLOR); 
#else 
		SetStretchBltMode(dc, STRETCH_DELETESCANS); 
#endif 
 
	  if (bgindex == -1) 
	  { 
			StretchDIBits(dc, xd, yd, dxd, dyd, xs, ys, dxs, dys, 
				RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS, SRCCOPY); 
		} 
		else 
		{ 
			//HDC tmpdc = CreateCompatibleDC(dc); 
			//HBITMAP tmpbmp = CreateCompatibleBitmap(dc, dxd, dyd); 
			//SelectObject(tmpdc, tmpbmp); 
			//BitBlt(tmpdc, 0, 0, dxd, dyd, dc, xd, yd, SRCCOPY); 
 
			unsigned char* save_index = new unsigned char[Height*Width]; 
			int black = imagePalette->GetPixel(0, 0, 0); 
			int white = imagePalette->GetPixel(255, 255, 255); 
 
			// Make background white and foreground black to use as mask... 
 
			int x, y; 
 
			for (y = 0; y < Height; y++) 
				for (x = 0; x < Width; x++) 
				{ 
					long i = ((long)y*Width)+x; 
					save_index[i] = (unsigned char)GetIndex(x, y); 
 
					if (GetIndex(x, y) == bgindex) 
						SetIndex(x, y, white); 
					else 
						SetIndex(x, y, black); 
				} 
 
			// AND into the canvas, this will preserve the background but 
			// turn the foreground white... 
 
			//StretchDIBits(tmpdc, 0, 0, dxd, dyd, xs, ys, dxs, dys, 
			StretchDIBits(dc, xd, yd, dxd, dyd, xs, ys, dxs, dys, 
				RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS, SRCAND); 
 
			// Restore foreground & make background black... 
 
			for (y = 0; y < Height; y++) 
				for (x = 0; x < Width; x++) 
				{ 
					long i = ((long)y*Width)+x; 
					SetIndex(x, y, save_index[i]); 
 
					if (GetIndex(x, y) == bgindex) 
						SetIndex(x, y, black); 
				} 
 
			// OR into the canvas, this will preserve the background but 
			// copy the foreground... 
 
			//StretchDIBits(tmpdc, 0, 0, dxd, dyd, xs, ys, dxs, dys, 
			StretchDIBits(dc, xd, yd, dxd, dyd, xs, ys, dxs, dys, 
				RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS, SRCPAINT); 
 
			for (y = 0; y < Height; y++) 
				for (x = 0; x < Width; x++) 
				{ 
					long i = ((long)y*Width)+x; 
					SetIndex(x, y, save_index[i]); 
				} 
 
			delete [] save_index; 
 
			//BitBlt(dc, xd, yd, dxd, dyd, tmpdc, 0, 0, SRCCOPY); 
			//DeleteDC(tmpdc); 
			//DeleteObject(tmpbmp); 
		} 
	 } 
	 return TRUE; 
  } 
  else 
	 return FALSE; 
} 
 
void CImageImpl::TransferBits(CImageImpl *from) 
{ 
  if (lpbi) 
  { 
    GlobalFreePtr(lpbi); 
    lpbi = NULL; 
  } 
  if (imagePalette) 
  { 
    delete imagePalette; 
    imagePalette = NULL; 
  } 
 
  lpbi = from->lpbi; 
  bgindex = from->bgindex; 
  imagePalette = from->imagePalette; 
  RawImage = from->RawImage; 
  Width = from->Width; 
  Height = from->Height; 
  Depth = from->Depth; 
  ColorType = from->ColorType; 
  EffWidth = from->EffWidth; 
   
  from->RawImage = NULL; 
  from->lpbi = NULL; 
  from->imagePalette = NULL; 
}