//--------------------------------------------------------------------------- #include #pragma hdrstop #include "TPMemory.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "ltdis_bu.lib" #pragma link "ltkrn_bu.lib" #pragma link "ltfil_bu.lib" #pragma link "ltimgefx_bu.lib" //--------------------------------------------------------------------------- // hotfix of undefined of min/max #define min(X,Y) (XY?X:Y) //--------------------------------------------------------------------------- // TPBitmap //--------------------------------------------------------------------------- __fastcall TPBitmap::TPBitmap() { FMemory = FData = NULL; } //--------------------------------------------------------------------------- __fastcall TPBitmap::~TPBitmap() { Destroy(); } //--------------------------------------------------------------------------- // Public Methods //--------------------------------------------------------------------------- bool __fastcall TPBitmap::Create(LONG width, LONG height, WORD bpp) { int n; Destroy(); /*FBytesPerLine = (bpp*width)/8; if((bpp*width)%8) FBytesPerLine++;*/ // <-- ÀÌ°Ô ¸ÂÁö¸¸ ÀÌ¹Ì À߸øµÈ ¹æ¹ýÀ¸·Î »ç¿ëµÈ °÷ÀÌ ³Ê¹« // ¸¹¾Æ¼­ °íÄ¥ ¼ö°¡ ¾ø´Ù. ¶§¹®¿¡ ¾î¶² ºÎºÐ¿¡¼­´Â // Ä¡¸íÀûÀÎ access violationÀÌ ¹ß»ýÇϱ⵵ ÇÑ´Ù if (bpp<8) { n = 1<<(bpp-1); FBytesPerLine = (width-1)/n+1; } else { FBytesPerLine = width*(bpp>>3); } n = FBytesPerLine&3; if (n) FBytesPerLine += 4-n; //////////////////////////////////// FWidth = width; FHeight = height; FBitsPerPixel = bpp; FMemory = GlobalAlloc(GHND, FBytesPerLine*FHeight); return FMemory!=NULL; } //--------------------------------------------------------------------------- void __fastcall TPBitmap::Destroy() { if (FMemory) { Unlock(); GlobalFree(FMemory); FMemory = NULL; } } //--------------------------------------------------------------------------- void __fastcall TPBitmap::Fill(Byte v) { memset(FData, v, FBytesPerLine*FHeight); } //--------------------------------------------------------------------------- BYTE *__fastcall TPBitmap::Lock() { if (FMemory) FData = (BYTE *)GlobalLock(FMemory); return FData; } //--------------------------------------------------------------------------- void __fastcall TPBitmap::Unlock() { if (FData) { //FMemory = GlobalHandle(FData); GlobalUnlock(FMemory); FData = NULL; } } //--------------------------------------------------------------------------- bool __fastcall TPBitmap::LoadFromFile(HANDLE fh, TCompressMethod cm) { BYTE *dst = NULL; if (FData) dst = FData; else { if ((dst = (BYTE *)GlobalLock(FMemory))==NULL) goto fail; } if (!TPUncompress(fh, dst, FBytesPerLine*FHeight, cm)) goto fail; if (FData==NULL) { // ¿ø·¡ unlock »óÅ¿´´Ù¸é ±×°ÍÀ¸·Î µ¹¸² //FMemory = GlobalHandle(dst); GlobalUnlock(FMemory); dst = NULL; } return true; fail: if (dst) { if (FData==NULL) { // ¿ø·¡ unlock »óÅ¿´´Ù¸é ±×°ÍÀ¸·Î µ¹¸² //FMemory = GlobalHandle(dst); GlobalUnlock(FMemory); dst = NULL; } } return false; } //--------------------------------------------------------------------------- bool __fastcall TPBitmap::SaveToFile(HANDLE fh, TCompressMethod cm) { BYTE *src = NULL; if (FData) src = FData; else { if ((src = (BYTE *)GlobalLock(FMemory))==NULL) goto fail; } if (!TPCompress(fh, src, FBytesPerLine*FHeight, cm)) goto fail; if (FData==NULL) { // ¿ø·¡ unlock »óÅ¿´´Ù¸é ±×°ÍÀ¸·Î µ¹¸² //FMemory = GlobalHandle(src); GlobalUnlock(FMemory); src = NULL; } return true; fail: if (src) { if (FData==NULL) { //FMemory = GlobalHandle(src); GlobalUnlock(FMemory); src = NULL; } } return false; } //--------------------------------------------------------------------- void __fastcall TPBitmap::LoadFromMemory(BYTE *src, bool down) { BYTE *dst = FData; int y, w = FWidth; switch (FBitsPerPixel) { case 16: w *= 2; break; case 24: w *= 3; break; } if (down) { dst += (FHeight-1)*FBytesPerLine; for (y=FHeight-1; y>=0; y--) { memcpy(dst, src, w); src += w; dst -= FBytesPerLine; } } else { for (y=0; y=0; y--) { memcpy(dst, src, w); src -= FBytesPerLine; dst += w; } } else { for (y=0; y8 ? CRF_BYTEORDERBGR : CRF_OPTIMIZEDPALETTE, NULL, 0, NULL, NULL, NULL); } else { if (FWidth>0 && FHeight>0) { L_CreateBitmap(&FHandle, sizeof(BITMAPHANDLE), TYPE_CONV, FWidth, FHeight, bpp, ORDER_BGR, NULL, TOP_LEFT, NULL, NULL); } } FBitsPerPixel = bpp; if (FOnPropertyChange) FOnPropertyChange(); } } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::SetCoordinateSystem(TCoordinateSystem Value) { if (Value!=FCoordinateSystem) { if (FHandle.Flags.Allocated) L_FlipBitmap(&FHandle); FCoordinateSystem = Value; if (FOnPropertyChange) FOnPropertyChange(); } } //--------------------------------------------------------------------- // Public Function //--------------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::Create(int width, int height, int bpp, RGBQUAD *rgb) { Destroy(); if (L_CreateBitmap(&FHandle, sizeof(BITMAPHANDLE), TYPE_CONV, width, height, bpp, ORDER_BGR, NULL, TOP_LEFT, NULL, NULL)!=SUCCESS) return false; if (bpp==8 && rgb) { // bpp<=8 ¿¡¼­ bpp==8·Î º¯°æ... 2001.09.22 by jeegeo if (L_PutBitmapColors(&FHandle, 0, 1<Handle = hDC; FIsUse = true; return Canvas; fail: if (Canvas) delete Canvas; return NULL; } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::DeleteCanvas(TCanvas *Canvas) { if (Canvas) { HDC dc = Canvas->Handle; delete Canvas; if (dc) L_DeleteLeadDC(dc); } FIsUse = false; } /*--------------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::Lock() { int nColorData; ResetRegion(); FDIB = L_ChangeToDIB(&FHandle); if (FDIB==NULL) goto fail; FBitmapInfo = (BITMAPINFO *)GlobalLock(FDIB); if (FBitmapInfo==NULL) goto fail; nColorData = FBitmapInfo->bmiHeader.biBitCount<=8 ? 1<bmiHeader.biBitCount : 0; FBits = (BYTE *)FBitmapInfo+sizeof(BITMAPINFOHEADER)+nColorData*sizeof(RGBQUAD); return true; fail: if (FDIB) { if (FBitmapInfo) { GlobalUnlock(FDIB); FDIB = NULL; } FDIB = NULL; } return false; } //--------------------------------------------------------------------------- void __fastcall TTexpiaBitmap::Unlock() { L_ChangeFromDIB(&FHandle, FDIB); FDIB = FBitmapInfo = NULL; FBits = NULL; SetRegion(); } */ //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::GetColors(int nIndex, int nCount, RGBQUAD *pPalette) { if (FHandle.Flags.Allocated) { L_GetBitmapColors(&FHandle, nIndex, nCount, pPalette); } } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::PutColors(int nIndex, int nCount, RGBQUAD *pPalette) { if (FHandle.Flags.Allocated) { L_PutBitmapColors(&FHandle, nIndex, nCount, pPalette); } } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::ConvertColorSpace(TColorSpace Value) { HGLOBAL hBuf = NULL; Byte *pBuf = NULL, *p; int i, j, h, n; if (Value!=FColorSpace) { n = FHandle.Height; while (true) { hBuf = GlobalAlloc(GMEM_MOVEABLE, n*FHandle.BytesPerLine); if (hBuf) break; n >>= 1; if (n<=0) goto fail; } if ((pBuf = (Byte *)GlobalLock(hBuf))==NULL) goto fail; if (n>1) { for (i=0; i 8) { return L_GetPixelColor(&FHandle, Y, X); //ÀÛ¾÷±¸¿ª³»¸¸ ÀÛ¾÷ÇÔ } else { L_AccessBitmap(&FHandle); L_GetBitmapRowCol(&FHandle, &v, Y, X, 1); L_ReleaseBitmap(&FHandle); return v; } */ L_UCHAR v; L_UCHAR p[3]; if (FBitsPerPixel == 8) { L_AccessBitmap(&FHandle); L_GetBitmapRowCol(&FHandle, &v, Y, X, 1); L_ReleaseBitmap(&FHandle); return v; } else if (FBitsPerPixel == 24) { //¸ðµç¿µ¿ª¿¡¼­ ÀÛ¾÷ÇÔ L_AccessBitmap(&FHandle); L_GetBitmapRowCol(&FHandle, p, Y, X, 3); L_ReleaseBitmap(&FHandle); return RGB(p[2], p[1], p[0]); } else { return L_GetPixelColor(&FHandle, Y, X); } } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::PutPixelColor(int X, int Y, COLORREF Color) { /* if (FBitsPerPixel > 8) { L_PutPixelColor(&FHandle, Y, X, Color); //ÀÛ¾÷±¸¿ª³»¸¸ ÀÛ¾÷ÇÔ } else { L_AccessBitmap(&FHandle); L_PutBitmapRowCol(&FHandle, (L_UCHAR L_FAR *)&Color, Y, X, 1); L_ReleaseBitmap(&FHandle); } */ if (FBitsPerPixel == 8) { L_AccessBitmap(&FHandle); L_PutBitmapRowCol(&FHandle, (L_UCHAR *)&Color, Y, X, 1); L_ReleaseBitmap(&FHandle); } else if (FBitsPerPixel == 24) { //¸ðµç¿µ¿ª¿¡¼­ ÀÛ¾÷ÇÔ L_UCHAR p[3]; p[2] = Color & 0xFF; p[1] = (Color >> 8) & 0xFF; p[0] = (Color >> 16) & 0xFF; L_AccessBitmap(&FHandle); L_PutBitmapRowCol(&FHandle, p, Y, X, 3); L_ReleaseBitmap(&FHandle); } else { L_PutPixelColor(&FHandle, Y, X, Color); } } //--------------------------------------------------------------------- HRGN __fastcall TTexpiaBitmap::GetRegion(bool isRemove) { RGNXFORM XForm; HRGN hRgn = 0; if (L_BitmapHasRgn(&FHandle)) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; L_GetBitmapRgnHandle(&FHandle, &XForm, &hRgn); if (isRemove) L_FreeBitmapRgn(&FHandle); } return hRgn; } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::PutRegion(HRGN hRgn, UINT uCombineMode) { RGNXFORM XForm; XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; L_SetBitmapRgnHandle(&FHandle, &XForm, hRgn, uCombineMode); } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::PutRegion(RECT rc, UINT uCombineMode) { RGNXFORM XForm; XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; L_SetBitmapRgnRect(&FHandle, &XForm, &rc, uCombineMode); } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::RemoveRegion() { if (L_BitmapHasRgn(&FHandle)) L_FreeBitmapRgn(&FHandle); } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::Copy(TTexpiaBitmap *pBitmap, DWORD dwRop) { RGNXFORM XForm; HDC dcSrc = NULL, dcDst = NULL; HRGN FRegion; bool bRegion; RGBQUAD rgb[256]; if (FHandle.Flags.Allocated) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; bRegion = false; if (L_BitmapHasRgn(&FHandle)) { L_GetBitmapRgnHandle(&FHandle, &XForm, &FRegion); L_FreeBitmapRgn(&FHandle); bRegion = true; } if ((dcSrc = pBitmap->CreateDC())==NULL) goto fail; if ((dcDst = L_CreateLeadDC(&FHandle))==NULL) goto fail; BitBlt(dcDst, 0, 0, FWidth, FHeight, dcSrc, 0, 0, dwRop); L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); if (bRegion) { L_SetBitmapRgnHandle(&FHandle, &XForm, FRegion, L_RGN_SET); DeleteObject(FRegion); } } else { if (pBitmap->BitsPerPixel == 8) { pBitmap->GetColors(0, 256, rgb); if (!Create(pBitmap->Width, pBitmap->Height, pBitmap->BitsPerPixel, rgb)) goto fail; } else { if (!Create(pBitmap->Width, pBitmap->Height, pBitmap->BitsPerPixel)) goto fail; } if ((dcSrc = pBitmap->CreateDC())==NULL) goto fail; if ((dcDst = L_CreateLeadDC(&FHandle))==NULL) goto fail; BitBlt(dcDst, 0, 0, FWidth, FHeight, dcSrc, 0, 0, dwRop); L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); } FColorSpace = pBitmap->ColorSpace; return true; fail: if (dcDst) L_DeleteLeadDC(dcDst); if (dcSrc) pBitmap->DeleteDC(dcSrc); return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::Copy(int nXDst, int nYDst, int nWidth, int nHeight, TTexpiaBitmap *pBitmap, int nXSrc, int nYSrc, DWORD dwRop) { RGNXFORM XForm; HDC dcSrc = NULL, dcDst = NULL; HRGN FRegion; bool bRegion; if (FHandle.Flags.Allocated) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; bRegion = false; if (L_BitmapHasRgn(&FHandle)) { L_GetBitmapRgnHandle(&FHandle, &XForm, &FRegion); L_FreeBitmapRgn(&FHandle); bRegion = true; } if ((dcSrc = pBitmap->CreateDC())==NULL) goto fail; if ((dcDst = L_CreateLeadDC(&FHandle))==NULL) goto fail; BitBlt(dcDst, nXDst, nYDst, nWidth, nHeight, dcSrc, nXSrc, nYSrc, dwRop); L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); if (bRegion) { L_SetBitmapRgnHandle(&FHandle, &XForm, FRegion, L_RGN_SET); DeleteObject(FRegion); } } return true; fail: if (dcSrc) { if (dcDst) L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); } return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::CopyFromRect(TTexpiaBitmap *pBitmap, int nXSrc, int nYSrc, DWORD dwRop) { RGNXFORM XForm; HDC dcSrc = NULL, dcDst = NULL; HRGN FRegion; bool bRegion; if (FHandle.Flags.Allocated) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; bRegion = false; if (L_BitmapHasRgn(&FHandle)) { L_GetBitmapRgnHandle(&FHandle, &XForm, &FRegion); L_FreeBitmapRgn(&FHandle); bRegion = true; } if ((dcSrc = pBitmap->CreateDC())==NULL) goto fail; if ((dcDst = L_CreateLeadDC(&FHandle))==NULL) goto fail; BitBlt(dcDst, 0, 0, FWidth, FHeight, dcSrc, nXSrc, nYSrc, dwRop); L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); FColorSpace = pBitmap->ColorSpace; if (bRegion) { L_SetBitmapRgnHandle(&FHandle, &XForm, FRegion, L_RGN_SET); DeleteObject(FRegion); } } return true; fail: if (dcSrc) { if (dcDst) L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); } return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::CopyToRect(int nXDst, int nYDst, TTexpiaBitmap *pBitmap, DWORD dwRop) { RGNXFORM XForm; HDC dcSrc = NULL, dcDst = NULL; HRGN FRegion; bool bRegion; if (FHandle.Flags.Allocated) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; bRegion = false; if (L_BitmapHasRgn(&FHandle)) { L_GetBitmapRgnHandle(&FHandle, &XForm, &FRegion); L_FreeBitmapRgn(&FHandle); bRegion = true; } if ((dcSrc = pBitmap->CreateDC())==NULL) goto fail; if ((dcDst = L_CreateLeadDC(&FHandle))==NULL) goto fail; BitBlt(dcDst, nXDst, nYDst, pBitmap->Width, pBitmap->Height, dcSrc, 0, 0, dwRop); L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); if (bRegion) { L_SetBitmapRgnHandle(&FHandle, &XForm, FRegion, L_RGN_SET); DeleteObject(FRegion); } } return true; fail: if (dcSrc) { if (dcDst) L_DeleteLeadDC(dcDst); pBitmap->DeleteDC(dcSrc); } return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::FastBitBlt(int nXDst, int nYDst, int nWidth, int nHeight, TTexpiaBitmap *bmSrc, int nXSrc, int nYSrc, DWORD dwRop){ // speedup by jeegeo // dwRop ´Â ÇöÀç SRCCOPY, SRCAND, NOTSRCCOPY, SRCPAINT ±â´É»Ó! //ÇÊ¿äÇÏ¸é ¸¸µå½´! by jeegeo BYTE *dst, *src; int w=0,h=0,bpp1,bpp2; ////////////////////////// WHITENESS if(!bmSrc) { if(dwRop==WHITENESS){ if(!StartScanLine()) return false; if(BitsPerPixel==24){ for(int i=0;i>3)) |= (0x80 >> (j&7)) ; } PutScanLine(nYDst+i); } } StopScanLine(); return true; } else { return false; } } ////////////////////////// WHITENESS // if(FIsUse) return false; // if(bmSrc->IsUse) return false; if(nWidth<=0||nHeight<=0) return false; if(nXDst>=Width||nYDst>=Height) return false; if(nXSrc>=bmSrc->Width||nYSrc>=bmSrc->Height) return false; bpp1 = BitsPerPixel; bpp2 = bmSrc->BitsPerPixel; w = min(bmSrc->Width-nXSrc,min(Width-nXDst,nWidth)); h = min(bmSrc->Height-nYSrc,min(Height-nYDst,nHeight)); if(!StartScanLine()) return false; if (!bmSrc->StartScanLine()) return false; if(bpp2==bpp1){ if(dwRop==SRCCOPY){ if(bpp1==24) { for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(dst + ((nXDst+j)>>3)) |= (0x80 >> ((nXDst+j)&7)) ; } else { *(dst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } } PutScanLine(nYDst+i); } } } else if(dwRop==NOTSRCCOPY) { if(bpp1==24) { for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(dst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } else { *(dst + ((nXDst+j)>>3)) |= (0x80 >> ((nXDst+j)&7)) ; } } PutScanLine(nYDst+i); } } } else if(dwRop==SRCAND) { if(bpp1==24) { for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ continue; } else { *(dst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } } PutScanLine(nYDst+i); } } } else if(dwRop==SRCPAINT){ if(bpp1==24) { for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;jGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(dst + ((nXDst+j)>>3)) |= (0x80 >> ((nXDst+j)&7)) ; } else { continue; } } PutScanLine(nYDst+i); } } } else if(dwRop==WHITENESS){ if(bpp1==24) { for(int i=0;i>3)) |= (0x80 >> ((nXDst+j)&7)) ; } PutScanLine(nYDst+i); } } } } else if(bpp1==24&&bpp2==1){ if(dwRop==SRCCOPY){ for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(dst+3*nXDst+3*j) = 255; *(dst+3*nXDst+3*j+1) = 255; *(dst+3*nXDst+3*j+2) = 255; } else { *(dst+3*nXDst+3*j) = 0; *(dst+3*nXDst+3*j+1) = 0; *(dst+3*nXDst+3*j+2) = 0; } } PutScanLine(nYDst+i); } } else if(dwRop==NOTSRCCOPY) { for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(dst+3*nXDst+3*j) = 0; *(dst+3*nXDst+3*j+1) = 0; *(dst+3*nXDst+3*j+2) = 0; } else { *(dst+3*nXDst+3*j) = 255; *(dst+3*nXDst+3*j+1) = 255; *(dst+3*nXDst+3*j+2) = 255; } } PutScanLine(nYDst+i); } } else if(dwRop==SRCAND) { for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ continue; } else { *(dst+3*nXDst+3*j) = 0; *(dst+3*nXDst+3*j+1) = 0; *(dst+3*nXDst+3*j+2) = 0; } } PutScanLine(nYDst+i); } } else if(dwRop==SRCPAINT){ for(int i=0;iGetScanLine(nYSrc+i); for(int j=0;j>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(dst+3*nXDst+3*j) = 255; *(dst+3*nXDst+3*j+1) = 255; *(dst+3*nXDst+3*j+2) = 255; } else { continue; } } PutScanLine(nYDst+i); } } else if(dwRop==WHITENESS){ for(int i=0;iStopScanLine(); return true; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::FastStretchBlt(int nXDst, int nYDst, int nDWidth, int nDHeight, TTexpiaBitmap *bmSrc, int nXSrc, int nYSrc, int nSWidth, int nSHeight, DWORD dwRop){ // speedup by jeegeo // dwRop ´Â ÇöÀç SRCCOPY ±â´É»Ó! //ÇÊ¿äÇÏ¸é ¸¸µå½´! by jeegeo BYTE *dst, *src; long sw=0,sh=0,dw=0,dh=0,bpp1,bpp2; // if(FIsUse) return false; // if(bmSrc->IsUse) return false; if(!bmSrc) return false; if(nDWidth<=0||nDHeight<=0) return false; if(bmSrc->Width<=0||bmSrc->Height<=0) return false; if(nXDst>=Width||nYDst>=Height) return false; if(nXSrc>=bmSrc->Width||nYSrc>=bmSrc->Height) return false; bpp1 = BitsPerPixel; bpp2 = bmSrc->BitsPerPixel; sw = nSWidth;//min(bmSrc->Width-nXSrc,nSWidth); dw = nDWidth;//min(Width-nXDst,nDWidth); sh = nSHeight;//min(bmSrc->Height-nYSrc,nSHeight); dh = nDHeight;//min(Height-nYDst,nDHeight); if(bpp2!=bpp1) return false; // bpp°¡ ´Ù¸£¸é ¾ÈµÊ // dwRop ¼öÁ¤½Ã¿¡´Â º¯°æ ¹Ù¶÷ if(!StartScanLine()) return false; if (!bmSrc->StartScanLine()) return false; if(bpp1==24) { for(long i=0;i=bmSrc->Height || nYDst+(i/sh)>=Height ) { break; } src = bmSrc->GetScanLine(nYSrc+(i*sh/dh)); dst = GetScanLine(nYDst+i); for(long j=0;j=bmSrc->Width || nXDst+j>=Width ) break; *(dst+3*nXDst+3*j) = *(src+3*nXSrc+3*(j*sw/dw)); *(dst+3*nXDst+3*j+1) = *(src+3*nXSrc+3*(j*sw/dw)+1); *(dst+3*nXDst+3*j+2) = *(src+3*nXSrc+3*(j*sw/dw)+2); } PutScanLine(nYDst+i); } } else if(bpp1==8){ for(long i=0;i=bmSrc->Height || nYDst+(i/sh)>=Height ) { break; } src = bmSrc->GetScanLine(nYSrc+(i*sh/dh)); dst = GetScanLine(nYDst+i); for(long j=0;j=bmSrc->Width || nXDst+j>=Width ) break; *(dst+nXDst+j) = *(src+nXSrc+(j*sw/dw)); } PutScanLine(nYDst+i); } } else if(bpp1==1){ for(long i=0;i=bmSrc->Height || nYDst+(i/sh)>=Height ) { break; } src = bmSrc->GetScanLine(nYSrc+(i*sh/dh)); dst = GetScanLine(nYDst+i); for(long j=0;j=bmSrc->Width || nXDst+j>=Width ) break; if( ( *(src + ((nXSrc+(j*sw/dw))>>3)) ) & (0x80 >> ((nXSrc+(j*sw/dw))&7)) ){ *(dst + ((nXDst+j)>>3)) |= (0x80 >> ((nXDst+j)&7)) ; } else { *(dst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } } PutScanLine(nYDst+i); } } StopScanLine(); bmSrc->StopScanLine(); return true; } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::LoadFromMemory(BYTE *mp, int bpl, bool down) { int y; L_AccessBitmap(&FHandle); if (down) { for (y=FHeight-1; y>=0; y--) { L_PutBitmapRow(&FHandle, mp, y, bpl); mp += bpl; } } else { for (y=0; y=0; y--) { L_GetBitmapRow(&FHandle, mp, y, bpl); mp += bpl; } } else { for (y=0; y> 3)) & (0x80 >> (x & 7))) { *src |= mm; } x++; if (x >= r.right) break; if (mm == 1) { src++; mm = 0x80; *src = 0; } else mm >>= 1; } mp += bpl; } L_ReleaseBitmap(&FHandle); } else { w = r.right-r.left; p = r.left; if (FBitsPerPixel == 16){ w *= 2; p *= 2; } else if (FBitsPerPixel == 24) { w *= 3; p *= 3; } L_AccessBitmap(&FHandle); for (y=r.top; y8) { if (FHandle.BitsPerPixel!=24) { L_ColorResBitmap(&FHandle, &FHandle, sizeof(BITMAPHANDLE), 24, CRF_BYTEORDERBGR, NULL, NULL, 0, NULL, NULL); } } else { L_ColorResBitmap(&FHandle, &FHandle, sizeof(BITMAPHANDLE), 8, CRF_OPTIMIZEDPALETTE, NULL, NULL, 250, NULL, NULL); } FBitsPerPixel = FHandle.BitsPerPixel; FWidth = FHandle.Width; FHeight = FHandle.Height; FDotsPerInch = FileInfo.XResolution; // By GreenFish ÇØ»óµµ ¹®Á¦ return true; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::SaveToFile(AnsiString fn, int nFormat) { return L_SaveBitmap(fn.c_str(), &FHandle, sizeof(BITMAPHANDLE), nFormat, FBitsPerPixel, 0) == SUCCESS; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::SaveToFile(AnsiString fn, int nFormat, int QFactor) { //EXTFILEOPTION ExtFileOption; //L_GetExtFileOption(&ExtFileOption); //ExtFileOption.Passes = 0; //L_SetExtFileOption(&ExtFileOption); //return L_SaveBitmap(fn.c_str(), &FHandle, nFormat, FBitsPerPixel, QFactor) == SUCCESS; // LEADTOOLS V10 -> 15 : EXTFILEOPTION -> SAVEFILEOPTION - by monkman (2007.06.15) SAVEFILEOPTION SaveFileOption; L_GetDefaultSaveFileOption(&SaveFileOption, sizeof(SAVEFILEOPTION)); SaveFileOption.Passes = 0; return L_SaveBitmap(fn.c_str(), &FHandle, nFormat, FBitsPerPixel, QFactor, &SaveFileOption) == SUCCESS; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::LoadFromTexpiaFile(HANDLE fh, TCompressMethod cm) { BYTE *pMem = NULL; if ((pMem = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FHandle.BytesPerLine*FHeight))==NULL) goto fail; if (!TPUncompress(fh, pMem, FHandle.BytesPerLine*FHeight, cm)) goto fail; LoadFromMemory(pMem, FHandle.BytesPerLine); HeapFree(GetProcessHeap(), 0, pMem); return true; fail: if (pMem) HeapFree(GetProcessHeap(), 0, pMem); return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::SaveToTexpiaFile(HANDLE fh, TCompressMethod cm) { BYTE *pMem = NULL; if ((pMem = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FHandle.BytesPerLine*FHeight))==NULL) goto fail; SaveToMemory(pMem, FHandle.BytesPerLine); if (!TPCompress(fh, pMem, FHandle.BytesPerLine*FHeight, cm)) goto fail; HeapFree(GetProcessHeap(), 0, pMem); return true; fail: if (pMem) HeapFree(GetProcessHeap(), 0, pMem); return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::SaveToTexpiaFile(HANDLE fh, RECT r, TCompressMethod cm) { int width, height, n, bpl; BYTE *pMem = NULL; width = r.right-r.left; height = r.bottom-r.top; if (FHandle.BitsPerPixel == 1) bpl = (width-1)/8+1; else bpl = width*(FHandle.BitsPerPixel>>3); n = bpl&3; if (n) bpl += 4-n; if ((pMem = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bpl*height))==NULL) goto fail; if (!SaveToFileMemory(pMem, bpl, r)) goto fail; if (!TPCompress(fh, pMem, bpl*height, cm)) goto fail; HeapFree(GetProcessHeap(), 0, pMem); return true; fail: if (pMem) HeapFree(GetProcessHeap(), 0, pMem); return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::StartScanLine() { if (!FHandle.Flags.Allocated) return false; // if (FIsUse) return false; ShareCount++; if(hBuffer!=NULL||pBuffer[0]!=NULL) return true; hBuffer = GlobalAlloc(GHND, FHandle.BytesPerLine); if (hBuffer==NULL) goto fail; pBuffer[0] = (BYTE *)GlobalLock(hBuffer); if (pBuffer[0]==NULL) goto fail; L_AccessBitmap(&FHandle); // FIsUse = true; return true; fail: StopScanLine(); return false; } //--------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::StartScanLineN(int n) { int i; if (!FHandle.Flags.Allocated) return false; // if (FIsUse) return false; ShareCount++; if(hBuffer!=NULL||pBuffer[0]!=NULL) return true; hBuffer = GlobalAlloc(GHND, n*FHandle.BytesPerLine); if (hBuffer==NULL) goto fail; pBuffer[0] = (BYTE *)GlobalLock(hBuffer); if (pBuffer[0]==NULL) goto fail; for (i=1; i0) return; if(ShareCount<0){ ShareCount = 0; } if (hBuffer) { if (pBuffer[0]) { L_ReleaseBitmap(&FHandle); //hBuffer = GlobalHandle(pBuffer[0]); // GHND==GMEM_MOVEABLE|GMEM_ZEROINIT, GHND·Î ÇÒ´çµÈ °ÍÀº ÇÚµéÀÌ ¹Ù²î¹Ç·Î ´Ù½Ã¾ò´Â´Ù GlobalUnlock(hBuffer); pBuffer[0] = NULL; } GlobalFree(hBuffer); hBuffer = NULL; } // FIsUse = false; } //--------------------------------------------------------------------- Byte *__fastcall TTexpiaBitmap::GetScanLine(int y) { L_GetBitmapRow(&FHandle, pBuffer[0], y, FHandle.BytesPerLine); return pBuffer[0]; } //--------------------------------------------------------------------- Byte *__fastcall TTexpiaBitmap::GetScanLineN(int y, int n) { L_GetBitmapRow(&FHandle, pBuffer[n], y, FHandle.BytesPerLine); return pBuffer[n]; } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::PutScanLine(int y) { L_PutBitmapRow(&FHandle, pBuffer[0], y, FHandle.BytesPerLine); } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::PutScanLineN(int y, int n) { L_PutBitmapRow(&FHandle, pBuffer[n], y, FHandle.BytesPerLine); } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::PutScanLine(int y, Byte *p) { L_PutBitmapRow(&FHandle, p, y, FHandle.BytesPerLine); } //--------------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::IsUseScanLine(){ if(hBuffer||pBuffer[0]) return true; else return false; } //--------------------------------------------------------------------- void __fastcall TTexpiaBitmap::FillRect(RECT Range, COLORREF Color) { RGNXFORM XForm; HRGN FRegion; bool bRegion; if (FHandle.Flags.Allocated) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; bRegion = false; if (L_BitmapHasRgn(&FHandle)) { L_GetBitmapRgnHandle(&FHandle, &XForm, &FRegion); L_FreeBitmapRgn(&FHandle); bRegion = true; } L_SetBitmapRgnRect(&FHandle, &XForm, &Range, L_RGN_SET); L_FillBitmap(&FHandle, Color); if (bRegion) { L_SetBitmapRgnHandle(&FHandle, &XForm, FRegion, L_RGN_SET); DeleteObject(FRegion); } else { L_FreeBitmapRgn(&FHandle); } } } //--------------------------------------------------------------------------- void __fastcall TTexpiaBitmap::FloodFill(TPoint start, TFloodFillRead read, TFloodFillSave save, TRect &rcBound, TRect *pZone) { int x, y, savex, savey, xr, xl; TPoint now, *sp; TList *stack; Byte *p; TRect rcZone = pZone ? *pZone : Rect(0, 0, FWidth, FHeight); stack = new TList; rcBound.Left = start.x; rcBound.Right = start.x+1; rcBound.Top = start.y; rcBound.Bottom = start.y+1; stack->Add(new TPoint(start)); StartScanLine(); while (stack->Count) { sp = (TPoint *)stack->Last(); stack->Remove(sp); x = sp->x; y = sp->y; delete sp; if (yrcBound.Bottom-1) rcBound.Bottom = y+1; p = GetScanLine(y); save(p, x); savex = x; while (1) { x++; if (xrcBound.Right-1) rcBound.Right = xr+1; x = savex; while (1) { x--; if (x>=rcZone.Left && read(p, x)) save(p, x); else break; } xl = x+1; if (xlrcBound.Right-1) rcBound.Right = xl+1; PutScanLine(y); x = xl; savey = y; y++; if (yAdd(new TPoint(now)); } } // } x = xl; } y = savey; y--; if (y>=rcZone.Top) { p = GetScanLine(y); // if (y>=rcZone.Top) { while (x<=xr) { if (!read(p, x)) x++; else { while (1) { if (x<=xr) { if (read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } } } StopScanLine(); delete stack; } //--------------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::FloodFillMask(TPoint start, TFloodFillRead read, TFloodFillSave save, TRect &rcBound, TPBitmap *Mask, TRect *pZone) { int x, y, savex, savey, xr, xl; TPoint now, *sp; TList *stack = NULL; Byte *p, *m; TRect rcZone = pZone ? *pZone : Rect(0, 0, FWidth, FHeight); if (Mask==NULL) return false; if (!Mask->Create(FWidth, FHeight, 1)) return false; if ((stack = new TList)==NULL) goto fail; rcBound.Left = start.x; rcBound.Right = start.x+1; rcBound.Top = start.y; rcBound.Bottom = start.y+1; stack->Add(new TPoint(start)); StartScanLine(); Mask->Lock(); Mask->Fill(0); while (stack->Count) { sp = (TPoint *)stack->Last(); stack->Remove(sp); x = sp->x; y = sp->y; delete sp; if (yrcBound.Bottom-1) rcBound.Bottom = y+1; p = GetScanLine(y); m = Mask->ScanLine(y); *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); savex = x; while (1) { x++; if (x>3))&(0x80>>(x&7)))==0 && read(p, x)) { *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); } else break; } xr = x-1; if (xrrcBound.Right-1) rcBound.Right = xr+1; x = savex; while (1) { x--; if (x>=rcZone.Left && (*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) { *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); } else break; } xl = x+1; if (xlrcBound.Right-1) rcBound.Right = xl+1; x = xl; savey = y; y++; if (yScanLine(y); // if (y>3))&(0x80>>(x&7))) || !read(p, x)) x++; else { while (1) { if (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } x = xl; } y = savey; y--; if (y>=rcZone.Top) { p = GetScanLine(y); m = Mask->ScanLine(y); // if (y>=rcZone.Top) { while (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7))) || !read(p, x)) x++; else { while (1) { if (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } } } Mask->Unlock(); StopScanLine(); delete stack; return true; fail: if (stack) delete stack; return false; } //--------------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::Rotate(int nAngle, bool fResize, COLORREF crFill) { //if (L_RotateBitmapFine(&FHandle, nAngle, fResize, crFill)<1) return false; // LEADTOOLS V10 -> 15 : L_RotateBitmapFine -> L_RotateBitmap - by monkman (2007.06.15) if (fResize) { if (L_RotateBitmap(&FHandle, nAngle, ROTATE_RESIZE, crFill)<1) return false; } else { if (L_RotateBitmap(&FHandle, nAngle, 0, crFill)<1) return false; } if (fResize) { FWidth = FHandle.Width; FHeight = FHandle.Height; } return true; } //--------------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::Flip(void) { if (L_FlipBitmap(&FHandle)<1) return false; return true; } //--------------------------------------------------------------------------- bool __fastcall TTexpiaBitmap::Reverse(void) { if (L_ReverseBitmap(&FHandle)<1) return false; return true; } //---------------------------------------------------------------------------