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; i Create(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; }