#include "stdafx.h" #include "dibsection.hpp" #include "dibsurf.hpp" //lint !e537 #include #include //******************************************************************* // // DESCRIPTION:Implementation file for CDIBSurface support functions // // AUTHOR: Andrew Farrier // // SourceSafe Version: $Revision: 17 $ // //****************************************************************** extern int g_NumDibSurf; void CDIBSurface::ClearData (void) { ASSERT (m_DIBData); m_DIBData->m_UseMask = false; m_DIBData->m_BackBits = NULL; m_DIBData->m_SelectedDC = NULL; m_DIBData->m_SelectedDCRefCount = 0; m_DIBData->m_Mask = NULL; // m_DIBData->m_OldBits=NULL; m_DIBData->m_Data=NULL; m_DIBData->m_UpperLeft=NULL; m_DIBData->m_Width = m_DIBData->m_Height = m_DIBData->m_Pitch = m_DIBData->m_BitDepth = 0; } void CDIBSurface::HLine( int x1, int x2, int y, COLORREF crColor ) { int nWidth = GetWidth(); int nHeight = GetHeight(); if( 0 <= x1 && nWidth > x1 && 0 <= x2 && nWidth > x2 && 0 <= y && nHeight > y ) { int nPixelSize = GetBitDepth() >> 3; BYTE *pBits = GetMem( x1, y ); switch( nPixelSize ) { case 2: // 16-bit { WORD wColor = ConvertColorToWord( crColor ); WORD *pData = (WORD *)pBits; while( x1++ <= x2 ) *pData++ = wColor; break; } case 3: // 24-bit { RGBTRIPLE rgbColor = ConvertColorToTriple( crColor ); RGBTRIPLE *pData = (RGBTRIPLE *)pBits; while( x1++ <= x2 ) *pData++ = rgbColor; break; } case 4: // 32-bit { DWORD dwColor = ConvertColorToLong( crColor ); DWORD *pData = (DWORD *)pBits; while( x1++ <= x2 ) *pData++ = dwColor; break; } default: ASSERT( false ); break; } } } bool CDIBSurface::HighlightFrame (const CRect& inrect,bool up) { int x,y; union { COLORREF color; BYTE value[4]; } color; const int delta=60; CRect therect (inrect); --therect.right; --therect.bottom; for(x=therect.left+1;x (color.value[1],color.value[1]+delta,255); color.value[2] = clamp (color.value[2],color.value[2]+delta,255); color.value[0] = clamp (color.value[0],color.value[0]+delta,255); } else { color.value[1] = clamp (0,color.value[1]-delta,color.value[1]); color.value[2] = clamp (0,color.value[2]-delta,color.value[2]); color.value[0] = clamp (0,color.value[0]-delta,color.value[0]); } SetColor (x,therect.top,color.color); color.color = GetColor (x,therect.bottom); if(up) { color.value[1] = clamp (0,color.value[1]-delta,color.value[1]); color.value[2] = clamp (0,color.value[2]-delta,color.value[2]); color.value[0] = clamp (0,color.value[0]-delta,color.value[0]); } else { color.value[1] = clamp (color.value[1],color.value[1]+delta,255); color.value[2] = clamp (color.value[2],color.value[2]+delta,255); color.value[0] = clamp (color.value[0],color.value[0]+delta,255); } SetColor (x,therect.bottom,color.color); } for(y=therect.top;y (color.value[1],color.value[1]+delta,255); color.value[2] = clamp (color.value[2],color.value[2]+delta,255); color.value[0] = clamp (color.value[0],color.value[0]+delta,255); } else { color.value[1] = clamp (0,color.value[1]-delta,color.value[1]); color.value[2] = clamp (0,color.value[2]-delta,color.value[2]); color.value[0] = clamp (0,color.value[0]-delta,color.value[0]); } SetColor (therect.left,y,color.color); color.color = GetColor (therect.right,y); if(up) { color.value[1] = clamp (0,color.value[1]-delta,color.value[1]); color.value[2] = clamp (0,color.value[2]-delta,color.value[2]); color.value[0] = clamp (0,color.value[0]-delta,color.value[0]); } else { color.value[1] = clamp (color.value[1],color.value[1]+delta,255); color.value[2] = clamp (color.value[2],color.value[2]+delta,255); color.value[0] = clamp (color.value[0],color.value[0]+delta,255); } SetColor (therect.right,y,color.color); } return true; } bool CDIBSurface::SetupLoadedBitmap (HBITMAP hbm) { BITMAP bm; ASSERT (m_DIBData); Destroy (); if(hbm == NULL) return false; g_NumDibSurf++; // // get info about the bitmap // if(GetObject(hbm, sizeof(bm), &bm) == 0) return false; m_DIBData->m_BackBits = hbm; m_DIBData->m_Data = (unsigned char *)bm.bmBits; m_DIBData->m_Width = (UINT) bm.bmWidth; m_DIBData->m_Height = (UINT) abs(bm.bmHeight); m_DIBData->m_BitDepth = bm.bmPlanes * bm.bmBitsPixel; m_DIBData->m_Pitch = bm.bmWidthBytes; // workaround for bug in 95 where 24 images are not quad byte aligned OSVERSIONINFO temp; temp.dwOSVersionInfoSize = sizeof (temp); if(!GetVersionEx (&temp)) return false; if((temp.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) || (m_DIBData->m_BitDepth != 24)) m_DIBData->m_Pitch += ((4-(m_DIBData->m_Pitch&0x03))&0x03); if(bm.bmHeight > 0) m_DIBData->m_Pitch *= -1; if(m_DIBData->m_Pitch < 0) // only the case if we have a bottom-up section m_DIBData->m_UpperLeft = (m_DIBData->m_Data+((-1*m_DIBData->m_Pitch)*(((int)m_DIBData->m_Height)-1))); else m_DIBData->m_UpperLeft = m_DIBData->m_Data; // create a DC to use the DIB section in // m_DIBData->m_BackDC = CreateCompatibleDC (NULL); // select the dib section into the DC from above // m_DIBData->m_OldBits = (HBITMAP) SelectObject (m_DIBData->m_BackDC,m_DIBData->m_BackBits); return true; } //**************************************************************** // // Function Name: CDIBSurface::CopyBitmap // // Description: Will copy hbm to the current DIBSection. Will perform a // stretchblt if needed. You can pass different coordinates if needed // User is responsible for making sure the color tables match // // Returns: true if successful // //**************************************************************** bool CDIBSurface::CopyBitmap(HBITMAP hbm,int x,int y,int dx,int dy) { HDC hdcImage; BITMAP bm; HBITMAP temp; bool err = false; ASSERT (m_DIBData); ASSERT (false); if(hbm) { // // select bitmap into a memoryDC so we can use it. // hdcImage = CreateCompatibleDC(NULL); if(!hdcImage) OutputDebugString("create compatible dc failed\n"); temp = (HBITMAP) SelectObject(hdcImage, hbm); // // get size of the bitmap // if(GetObject(hbm, sizeof(bm), &bm) == 0) // get size of bitmap return false; dx = dx == 0 ? bm.bmWidth : dx; // use the passed size, unless zero dy = dy == 0 ? bm.bmHeight : dy; if(!StretchBlt(0, 0, (int) GetWidth (),(int) GetHeight (), hdcImage, x, y, dx, dy, SRCCOPY)) err = true; SelectObject (hdcImage,temp); DeleteDC(hdcImage); } return err; } //**************************************************************** // // Function Name: CDIBSurface::Create1BitMask // // Description: Parse a 1-bit DIBSurface and create a 1-bit mask // // Returns: true if successful // //**************************************************************** bool CDIBSurface::Create1BitMask (COLORREF colorref) { unsigned char *inmask,*inpic; unsigned char *maskline,*picline; int count; UINT x,y,i; int red,green,blue; int maskpitch,picpitch; int colorindex,value; RGBQUAD colors[2]; ASSERT (m_DIBData); ASSERT (m_DIBData->m_Mask); if(!m_DIBData->m_Mask) return false; HDC dc; dc = GetDC (); if(GetDIBColorTable (dc,0,2,&(colors[0])) == 0) { ReleaseDC (dc); return false; } ReleaseDC (dc); red = colorref & 0xff; green = (colorref>>8)&0xff; blue = (colorref>>16)&0xff; colorindex = -1; for(i=0;i<2;i++) { if(red != colors[i].rgbRed) continue; if(green != colors[i].rgbGreen) continue; if(blue != colors[i].rgbBlue) continue; colorindex = (int) i; break; } if(colorindex == -1) return false; maskline = m_DIBData->m_Mask->GetMem (); maskpitch = m_DIBData->m_Mask->GetPitch (); picline = GetMem (); picpitch = GetPitch (); for(y=0;ym_Height;y++) { inmask = maskline; inpic = picline; *inmask = 0; count = 7; for(x=0;xm_Width;x++,count--) { if(count < 0) { inmask++; *inmask = 0; count = 7; inpic++; } value = ((*inpic)>>count)&0x01; if(value == colorindex) { (*inmask) += (1<m_Mask); if(!m_DIBData->m_Mask) return false; HDC dc; dc = GetDC (); if(GetDIBColorTable (dc,0,16,&(colors[0])) == 0) { ReleaseDC (dc); return false; } ReleaseDC (dc); red = colorref & 0xff; green = (colorref>>8)&0xff; blue = (colorref>>16)&0xff; colorindex = -1; for(i=0;i<16;i++) { if(red != colors[i].rgbRed) continue; if(green != colors[i].rgbGreen) continue; if(blue != colors[i].rgbBlue) continue; colorindex = (int) i; break; } if(colorindex == -1) return false; maskline = m_DIBData->m_Mask->GetMem (); maskpitch = m_DIBData->m_Mask->GetPitch (); picline = GetMem (); picpitch = GetPitch (); for(y=0;ym_Height;y++) { inmask = maskline; inpic = picline; *inmask = 0; count = 7; for(x=0;xm_Width;x++,count--) { if(count < 0) { inmask++; *inmask = 0; count = 7; } if(x&0x01) value = ((*inpic)) & 0x0f; else value = ((*inpic)>>4) & 0x0f; if(value == colorindex) { (*inmask) += (1<m_Mask); if(!m_DIBData->m_Mask) return false; HDC dc; dc = GetDC (); if(GetDIBColorTable (dc,0,256,&(colors[0])) == 0) { ReleaseDC (dc); return false; } ReleaseDC (dc); red = colorref & 0xff; green = (colorref>>8)&0xff; blue = (colorref>>16)&0xff; colorindex = -1; for(i=0;i<256;i++) { if(red != colors[i].rgbRed) continue; if(green != colors[i].rgbGreen) continue; if(blue != colors[i].rgbBlue) continue; colorindex = (int) i; break; } if(colorindex == -1) return false; maskline = m_DIBData->m_Mask->GetMem (); maskpitch = m_DIBData->m_Mask->GetPitch (); picline = GetMem (); picpitch = GetPitch (); for(y=0;ym_Height;y++) { inmask = maskline; inpic = picline; *inmask = 0; count = 7; for(x=0;xm_Width;x++,count--) { if(count < 0) { inmask++; *inmask = 0; count = 7; } value = *inpic; if(value == colorindex) { (*inmask) += (1<m_Mask); if(!m_DIBData->m_Mask) return false; red = colorref & 0xff; green = (colorref>>8)&0xff; blue = (colorref>>16)&0xff; red >>= 3; green >>= 3; blue >>= 3; color = (red<<10)+(green<<5)+blue; maskline = m_DIBData->m_Mask->GetMem (); maskpitch = m_DIBData->m_Mask->GetPitch (); picline = GetMem (); picpitch = GetPitch (); for(y=0;ym_Height;y++) { inmask = maskline; inpic = picline; *inmask = 0; count = 7; for(x=0;xm_Width;x++,count--) { if(count < 0) { inmask++; *inmask = 0; count = 7; } value = (*(inpic+1)<<8) + *(inpic); if(value == color) { (*inmask) += (1<m_Mask); if(!m_DIBData->m_Mask) return false; maskline = m_DIBData->m_Mask->GetMem (); maskpitch = m_DIBData->m_Mask->GetPitch (); picline = GetMem (); picpitch = GetPitch (); for(y=0;ym_Height;y++) { inmask = maskline; inpic = picline; *inmask = 0; count = 7; for(x=0;xm_Width;x++,count--) { if(count < 0) { inmask++; *inmask = 0; count = 7; } curcolor = ((*inpic)<<16) + ((*(inpic+1))<<8) + ((*(inpic+2))); if(curcolor == colorref) { (*inmask) += (1< data; int count=0; int pitch; int red,green,blue; unsigned char *mem; ASSERT (m_DIBData); intcolor = color; srccolor = GetColor (start.x,start.y); if(srccolor == intcolor) return 0; mem = GetMem () + GetLocation (start.x,start.y); pitch = GetPitch (); data.push (FloodData (mem,start)); while(!data.empty ()) { temp = data.top (); data.pop (); intcolor = ((*temp.mem)<<16)+ ((*(temp.mem+1))<<8) + (*(temp.mem+2)); if(intcolor==srccolor) { red = color&0xff; green = (color>>8) & 0xff; blue = (color>>16) & 0xff; mem = temp.mem; (*mem) = blue; mem++; (*mem) = green; mem++; (*mem) = red; mem++; count++; if(temp.where.y != 0) data.push (FloodData (temp.mem-pitch,CPoint(temp.where.x,temp.where.y-1))); if(temp.where.y != (m_DIBData->m_Height-1)) data.push (FloodData (temp.mem+pitch,CPoint(temp.where.x,temp.where.y+1))); if(temp.where.x != 0) data.push (FloodData (temp.mem-3,CPoint(temp.where.x-1,temp.where.y))); if(temp.where.x != (m_DIBData->m_Width-1)) data.push (FloodData (temp.mem+3,CPoint(temp.where.x+1,temp.where.y))); } } return count; } bool CDIBSurface::AlphaBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface *srcdib,const CDIBSurface *alphadib,const int srcx,const int srcy,const int alphasrcx,const int alphasrcy) { float red,green,blue; float sred,sgreen,sblue; float dred,dgreen,dblue; int ired,igreen,iblue; float avalue; int cx,cy; int iaval; int dpitch,spitch,apitch; WORD *dest,*dline; const WORD *src,*sline; const unsigned char *alpha,*aline; dline = (WORD *) (GetMem ()+GetLocation (x,y)); sline = (const WORD *) (srcdib->GetMem () + srcdib->GetLocation (srcx,srcy)); aline = (alphadib->GetMem () + alphadib->GetLocation (alphasrcx,alphasrcy)); dpitch = GetPitch (); dpitch >>= 1; spitch = srcdib->GetPitch (); spitch >>=1; apitch = alphadib->GetPitch (); for(cy = 0;cy < height;cy++) { dest = dline; src = sline; alpha = aline; for(cx = 0;cx < width;cx++) { iaval = *alpha; if(iaval == 0) { } else if(iaval == 255) { *dest = *src; } else { avalue = iaval; dblue = (*dest)&0x001f; dgreen = ((*dest)>>5)&0x001f; dred = ((*dest)>>10)&0x001f; sblue = (*src)&0x001f; sgreen = ((*src)>>5)&0x001f; sred = ((*src)>>10)&0x001f; avalue /= 255.0; red = (sred * avalue) + (dred*(1.0-avalue)); green = (sgreen * avalue) + (dgreen*(1.0-avalue)); blue = (sblue * avalue) + (dblue*(1.0-avalue)); ired = red; igreen = green; iblue = blue; *dest = (ired<<10) + (igreen<<5) + iblue; } dest++; src++; alpha++; } dline += dpitch; sline += spitch; aline += apitch; } return true; } bool CDIBSurface::AlphaBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface *srcdib,const CDIBSurface *alphadib,const int srcx,const int srcy,const int alphasrcx,const int alphasrcy) { float red,green,blue; float sred,sgreen,sblue; float dred,dgreen,dblue; float avalue; int cx,cy; int iaval; int dpitch,spitch,apitch; unsigned char *dest,*dline; const unsigned char *src,*sline; const unsigned char *alpha,*aline; dline = GetMem ()+GetLocation (x,y); sline = srcdib->GetMem () + srcdib->GetLocation (srcx,srcy); aline = alphadib->GetMem () + alphadib->GetLocation (alphasrcx,alphasrcy); dpitch = GetPitch (); spitch = srcdib->GetPitch (); apitch = alphadib->GetPitch (); for(cy = 0;cy < height;cy++) { dest = dline; src = sline; alpha = aline; for(cx = 0;cx < width;cx++) { iaval = *alpha; if(iaval == 0) { } else if(iaval == 255) { *dest = *src; *(dest+1) = *(src+1); *(dest+2) = *(src+2); } else { avalue = iaval; dblue = *dest; dgreen = *(dest+1); dred = *(dest+2); sblue = *src; sgreen = *(src+1); sred = *(src+2); avalue /= 255.0; red = (sred * avalue) + (dred*(1.0-avalue)); green = (sgreen * avalue) + (dgreen*(1.0-avalue)); blue = (sblue * avalue) + (dblue*(1.0-avalue)); *dest = blue; *(dest+1) = green; *(dest+2) = red; } dest += 3; src += 3; alpha++; } dline += dpitch; sline += spitch; aline += apitch; } return true; } bool CDIBSurface::Convert24to16 (void) { ASSERT (m_DIBData); CDIBSurface surf; if(GetBitDepth () == 16) return true; ASSERT (GetBitDepth () == 24); if(GetBitDepth () != 24) return false; if (!surf.Create (GetWidth (),GetHeight (),16)) return false; BYTE *pDestMem = surf.GetMem(); ASSERT (pDestMem); WORD *pDestLine = (WORD *) pDestMem; BYTE *pSrcMem = GetMem (); ASSERT (pSrcMem); BYTE *pSrcLine = pSrcMem; int SrcPitch = GetPitch (); int DestPitch = surf.GetPitch (); DWORD red,green,blue; DWORD rederror=0,greenerror=0,blueerror=0; for (int y = 0; y < GetHeight(); ++y) { rederror = greenerror = blueerror = 0; for (int x=0;x 8) { red += 8; if (red > 255) red = 255; rederror -= 8; } if (greenerror > 8) { green += 8; if (green > 255) green = 255; greenerror -= 8; } if (blueerror > 8) { blue += 8; if (blue > 255) blue = 255; blueerror -= 8; } red >>= 3; green >>= 3; blue >>= 3; *pDestLine++ = (red << 10) | (green << 5) | (blue); } pDestMem += DestPitch; pSrcMem += SrcPitch; pDestLine = (WORD *) pDestMem; pSrcLine = pSrcMem; } if(m_DIBData->m_Mask) { if(!surf.CalcMask ()) return false; HDC dc1,dc2; dc1 = surf.m_DIBData->m_Mask->GetDC (); dc2 = m_DIBData->m_Mask->GetDC (); BitBlt (dc1,0,0,m_DIBData->m_Width,m_DIBData->m_Height,dc2,0,0,SRCCOPY); surf.m_DIBData->m_Mask->ReleaseDC (dc1); m_DIBData->m_Mask->ReleaseDC (dc2); } (*surf.m_RefCount)++; Destroy (); memcpy (m_DIBData,surf.m_DIBData,sizeof (DIBData)); delete surf.m_DIBData; delete surf.m_RefCount; surf.m_DIBData = NULL; surf.m_RefCount = NULL; return true; } namespace { inline BYTE GetIntensity (COLORREF c) { int r = GetRValue (c); int g = GetGValue (c); int b = GetBValue (c); return (299 * r + 587 * g + 114 * b) / 1000; } } bool CDIBSurface::ConvertToGray (void) { ASSERT (m_DIBData); CDIBSurface surf; if(GetBitDepth () == 8) return true; if (!surf.Create (GetWidth (),GetHeight (),8)) return false; BYTE *pDestMem = surf.GetMem(); ASSERT (pDestMem); BYTE *pDestLine = pDestMem; int DestPitch = surf.GetPitch (); for (int y = 0; y < GetHeight(); ++y) { for (int x=0;xm_Mask) { if(!surf.CalcMask ()) return false; HDC dc1,dc2; dc1 = surf.m_DIBData->m_Mask->GetDC (); dc2 = m_DIBData->m_Mask->GetDC (); BitBlt (dc1,0,0,m_DIBData->m_Width,m_DIBData->m_Height,dc2,0,0,SRCCOPY); surf.m_DIBData->m_Mask->ReleaseDC (dc1); m_DIBData->m_Mask->ReleaseDC (dc2); } (*surf.m_RefCount)++; Destroy (); memcpy (m_DIBData,surf.m_DIBData,sizeof (DIBData)); delete surf.m_DIBData; delete surf.m_RefCount; surf.m_DIBData = NULL; surf.m_RefCount = NULL; return true; } bool CDIBSurface::ColorBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,const COLORREF color,bool addred,bool addgreen,bool addblue,CDIBSurface *altmask) { int red,green,blue; int reddiff,greendiff,bluediff; int cx,cy; int mindex; CDIBSurface *maskdib = NULL; int dpitch,spitch,mpitch; WORD *dest; unsigned char *dline; unsigned char *mask,*mline; const WORD *src; const unsigned char *sline; reddiff = (color & 0xff); greendiff = ((color>>8) & 0xff); bluediff = ((color>>16) & 0xff); if(!addred) reddiff *= -1; if(!addgreen) greendiff *= -1; if(!addblue) bluediff *= -1; if(altmask) maskdib = altmask; else if (srcdib->UseMask()) maskdib = srcdib->m_DIBData->m_Mask; dline = GetMem ()+GetLocation (x,y); sline = srcdib->GetMem () + srcdib->GetLocation (srcx,srcy); if(maskdib) { mline = maskdib->GetMem () + maskdib->GetLocation (srcx,srcy); mpitch = maskdib->GetPitch (); } dpitch = GetPitch (); spitch = srcdib->GetPitch (); if(maskdib) { #if 1 /* faster version */ int red_map[32]; int green_map[32]; int blue_map[32]; int i; for (i = 0; i < 32; i += 1) { red_map[i] = clamp (0,reddiff + i,31); green_map[i] = clamp (0,greendiff + i,31); blue_map[i] = clamp (0,bluediff + i,31); } for(cy = 0;cy < height;cy++) { dest = (WORD *) dline; src = (WORD *) sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1<>5)&0x001f]; red = red_map[((*src)>>10)&0x001f]; *dest = (red << 10) | (green << 5) | (blue); } mindex--; dest++; src++ ; } dline += dpitch; sline += spitch; mline += mpitch; } #else for(cy = 0;cy < height;cy++) { dest = (WORD *) dline; src = (WORD *) sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1< (0,((*src)&0x001f)+bluediff,31); green = clamp (0,(((*src)>>5)&0x001f)+greendiff,31); red = clamp (0,(((*src)>>10)&0x001f)+reddiff,31); *dest = (red << 10) | (green << 5) | (blue); } mindex--; dest++; src++ ; } dline += dpitch; sline += spitch; mline += mpitch; } #endif } else { for(cy = 0;cy < height;cy++) { dest = (WORD *) dline; src = (WORD *) sline; for(cx = 0;cx < width;cx++) { blue = clamp (0,((*src)&0x001f)+bluediff,31); green = clamp (0,(((*src)>>5)&0x001f)+greendiff,31); red = clamp (0,(((*src)>>10)&0x001f)+reddiff,31); *dest = (red << 10) | (green << 5) | (blue); dest++; src++; } dline += dpitch; sline += spitch; } } return true; } bool CDIBSurface::ColorBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,const COLORREF color,bool addred,bool addgreen,bool addblue,CDIBSurface *altmask) { int reddiff,greendiff,bluediff; int cx,cy; int mindex; CDIBSurface *maskdib = NULL; int dpitch,spitch,mpitch; unsigned char *dest,*dline; unsigned char *mask,*mline; const unsigned char *src,*sline; reddiff = (color & 0xff); greendiff = ((color>>8) & 0xff); bluediff = ((color>>16) & 0xff); if(!addred) reddiff *= -1; if(!addgreen) greendiff *= -1; if(!addblue) bluediff *= -1; if(altmask) maskdib = altmask; else if (srcdib->UseMask()) maskdib = srcdib->m_DIBData->m_Mask; dline = GetMem ()+GetLocation (x,y); sline = srcdib->GetMem () + srcdib->GetLocation (srcx,srcy); if(maskdib) { mline = maskdib->GetMem () + maskdib->GetLocation (srcx,srcy); mpitch = maskdib->GetPitch (); } dpitch = GetPitch (); spitch = srcdib->GetPitch (); if(maskdib) { for(cy = 0;cy < height;cy++) { dest = dline; src = sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1< (0,(*src)+bluediff,255); *(dest+1) = clamp (0,(*src+1)+greendiff,255); *(dest+2) = clamp (0,(*src+2)+reddiff,255); } mindex--; dest += 3; src += 3; } dline += dpitch; sline += spitch; mline += mpitch; } } else { for(cy = 0;cy < height;cy++) { dest = dline; src = sline; for(cx = 0;cx < width;cx++) { *dest = clamp (0,(*src)+bluediff,255); *(dest+1) = clamp (0,(*src+1)+greendiff,255);; *(dest+2) = clamp (0,(*src+2)+reddiff,255);; dest += 3; src += 3; } dline += dpitch; sline += spitch; } } return true; } bool CDIBSurface::GrayBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,CDIBSurface *altmask) { int red,green,blue; int cx,cy; int mindex; CDIBSurface *maskdib = NULL; int dpitch,spitch,mpitch; WORD *dest; unsigned char *dline; unsigned char *mask,*mline; const WORD *src; const unsigned char *sline; if(altmask) maskdib = altmask; else if (srcdib->UseMask()) maskdib = srcdib->m_DIBData->m_Mask; dline = GetMem ()+GetLocation (x,y); sline = srcdib->GetMem () + srcdib->GetLocation (srcx,srcy); if(maskdib) { mline = maskdib->GetMem () + maskdib->GetLocation (srcx,srcy); mpitch = maskdib->GetPitch (); } dpitch = GetPitch (); spitch = srcdib->GetPitch (); if(maskdib) { for(cy = 0;cy < height;cy++) { dest = (WORD *) dline; src = (WORD *) sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1< (0,(((int)(*src)&0x001f) * 86) >> 10,31); // blue green = clamp (0,((((int)(*src)>>5)&0x001f) * 273) >> 10,31); // green red = clamp (0,((((int)(*src)>>10)&0x001f) * 156) >> 10,31); // red *dest = ((red+green+blue) << 10) | ((red+green+blue) << 5) | (red+green+blue); } mindex--; dest++; src++ ; } dline += dpitch; sline += spitch; mline += mpitch; } } else { #ifdef USE_DITHERING CFloydSteinberg dither; if (!dither.Create (width, height)) { ASSERT (0); return false; } dither.Begin(); #endif for(cy = 0;cy < height;cy++) { #ifdef USE_DITHERING dither.BeginScanLine(); #endif dest = (WORD *) dline; src = (WORD *) sline; for(cx = 0;cx < width;cx++) { const int brightness = 100; const int rmult = (428 * brightness / 100); const int gmult = (1008 * brightness / 100); const int bmult = (612 * brightness / 100); red = rmult * (((*src)>>10)&0x001f); green = gmult * (((*src)>>5)&0x001f); blue = bmult * ((*src)&0x001f); int intensity = (red + green + blue) >> 8; ASSERT (intensity >= 0); ASSERT (intensity < 256); #ifdef USE_DITHERING CDitherIntensity dithintensity (intensity); dither.Dither (dithintensity); dithintensity.i &= (0x1f << 3); dither.Achieved (dithintensity); intensity = dithintensity.i; #endif intensity >>= 3; // convert to 5 bits *dest = (intensity << 10) | (intensity << 5) | intensity; dest++; src++; } dline += dpitch; sline += spitch; } #ifdef USE_DITHERING dither.End(); #endif } return true; } bool CDIBSurface::GrayBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,CDIBSurface *altmask) { int cx,cy; int mindex; CDIBSurface *maskdib = NULL; int red,green,blue,color; int dpitch,spitch,mpitch; unsigned char *dest,*dline; unsigned char *mask,*mline; const unsigned char *src,*sline; if(altmask) maskdib = altmask; else if (srcdib->UseMask()) maskdib = srcdib->m_DIBData->m_Mask; dline = GetMem ()+GetLocation (x,y); sline = srcdib->GetMem () + srcdib->GetLocation (srcx,srcy); if(maskdib) { mline = maskdib->GetMem () + maskdib->GetLocation (srcx,srcy); mpitch = maskdib->GetPitch (); } dpitch = GetPitch (); spitch = srcdib->GetPitch (); if(maskdib) { for(cy = 0;cy < height;cy++) { dest = dline; src = sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1< (0,(*src) * 64.0/255.0,255); // blue green = clamp (0,(*src+1) * 204.0/255.0,255); // green red = clamp (0,(*src+2) * 117.0/255.0,255); // red color = (red + green + blue) / 3; *dest = color; *(dest+1) = color; *(dest+2) = color; } mindex--; dest += 3; src += 3; } dline += dpitch; sline += spitch; mline += mpitch; } } else { for(cy = 0;cy < height;cy++) { dest = dline; src = sline; for(cx = 0;cx < width;cx++) { blue = clamp (0,(*src) * 64.0/255.0, 255); // blue green = clamp (0,(*src+1) * 204.0/255.0,255); // green red = clamp (0,(*src+2) * 117.0/255.0,255); // red color = (red + green + blue) / 3; *dest = color; *(dest+1) = color; *(dest+2) = color; dest += 3; src += 3; } dline += dpitch; sline += spitch; } } return true; } bool CDIBSurface::MultBlt16 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,const float red,const float green,const float blue,CDIBSurface *altmask) { int dred,dgreen,dblue; int cx,cy; int mindex; CDIBSurface *maskdib = NULL; int dpitch,spitch,mpitch; WORD *dest; unsigned char *dline; unsigned char *mask,*mline; const WORD *src; const unsigned char *sline; if(altmask) maskdib = altmask; else if (srcdib->UseMask()) maskdib = srcdib->m_DIBData->m_Mask; dline = GetMem ()+GetLocation (x,y); sline = srcdib->GetMem () + srcdib->GetLocation (srcx,srcy); if(maskdib) { mline = maskdib->GetMem () + maskdib->GetLocation (srcx,srcy); mpitch = maskdib->GetPitch (); } dpitch = GetPitch (); spitch = srcdib->GetPitch (); if(maskdib) { #if 1 /* faster version */ int red_map[32]; int green_map[32]; int blue_map[32]; int i; for (i = 0; i < 32; i += 1) { red_map[i] = clamp (0,red * i,31); green_map[i] = clamp (0,green * i,31); blue_map[i] = clamp (0,blue * i,31); } for(cy = 0;cy < height;cy++) { dest = (WORD *) dline; src = (WORD *) sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1<>5)&0x001f]; dred = red_map[((*src)>>10)&0x001f]; *dest = (dred << 10) | (dgreen << 5) | (dblue); } mindex--; dest++; src++ ; } dline += dpitch; sline += spitch; mline += mpitch; } #else for(cy = 0;cy < height;cy++) { dest = (WORD *) dline; src = (WORD *) sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1< (0,((*src)&0x001f)*blue,31); dgreen = clamp (0,(((*src)>>5)&0x001f)*green,31); dred = clamp (0,(((*src)>>10)&0x001f)*red,31); *dest = (dred << 10) | (dgreen << 5) | (dblue); } mindex--; dest++; src++ ; } dline += dpitch; sline += spitch; mline += mpitch; } #endif } else { for(cy = 0;cy < height;cy++) { dest = (WORD *) dline; src = (WORD *) sline; for(cx = 0;cx < width;cx++) { dblue = clamp (0,((*src)&0x001f)*blue,31); dgreen = clamp (0,(((*src)>>5)&0x001f)*green,31); dred = clamp (0,(((*src)>>10)&0x001f)*red,31); *dest = (dred << 10) | (dgreen << 5) | (dblue); dest++; src++; } dline += dpitch; sline += spitch; } } return true; } bool CDIBSurface::MultBlt24 (const int x,const int y,const int width,const int height,const CDIBSurface* srcdib,const int srcx,const int srcy,const float red,const float green,const float blue,CDIBSurface *altmask) { int cx,cy; int mindex; CDIBSurface *maskdib = NULL; int dpitch,spitch,mpitch; unsigned char *dest,*dline; unsigned char *mask,*mline; const unsigned char *src,*sline; if(altmask) maskdib = altmask; else if (srcdib->UseMask()) maskdib = srcdib->m_DIBData->m_Mask; dline = GetMem ()+GetLocation (x,y); sline = srcdib->GetMem () + srcdib->GetLocation (srcx,srcy); if(maskdib) { mline = maskdib->GetMem () + maskdib->GetLocation (srcx,srcy); mpitch = maskdib->GetPitch (); } dpitch = GetPitch (); spitch = srcdib->GetPitch (); if(maskdib) { for(cy = 0;cy < height;cy++) { dest = dline; src = sline; mask = mline; mindex = 7-(srcx & 0x07); for(cx = 0;cx < width;cx++) { if(mindex < 0) { mindex = 7; mask++; } if(!((*mask) & (1< (0,(*src)*blue,255); *(dest+1) = clamp (0,(*src+1)*green,255); *(dest+2) = clamp (0,(*src+2)*red,255); } mindex--; dest += 3; src += 3; } dline += dpitch; sline += spitch; mline += mpitch; } } else { for(cy = 0;cy < height;cy++) { dest = dline; src = sline; for(cx = 0;cx < width;cx++) { *dest = clamp (0,(*src)*blue,255); *(dest+1) = clamp (0,(*src+1)*green,255);; *(dest+2) = clamp (0,(*src+2)*red,255);; dest += 3; src += 3; } dline += dpitch; sline += spitch; } } return true; }