| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include <svpm.h> |
| |
| #define _SV_SALBMP_CXX |
| #include <rtl/alloc.h> |
| #include <vcl/salbtype.hxx> |
| #include <os2/salgdi.h> |
| #include <os2/saldata.hxx> |
| #include <os2/salbmp.h> |
| #include <vcl/bitmap.hxx> // for BitmapSystemData |
| #include <string.h> |
| |
| #ifndef __H_FT2LIB |
| #include <os2/wingdi.h> |
| #include <ft2lib.h> |
| #endif |
| |
| // ----------- |
| // - Inlines - |
| // ----------- |
| |
| inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const PM_BYTE cIndex ) |
| { |
| PM_BYTE rByte = pScanline[ nX >> 1 ]; |
| |
| ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) : |
| ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) ); |
| } |
| |
| // ------------- |
| // - Os2SalBitmap - |
| // ------------- |
| |
| Os2SalBitmap::Os2SalBitmap() : |
| mhDIB ( 0 ), |
| mhDIB1Subst ( 0 ), |
| mhDDB ( 0 ), |
| mnBitCount ( 0 ) |
| { |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| Os2SalBitmap::~Os2SalBitmap() |
| { |
| Destroy(); |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| bool Os2SalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle ) |
| { |
| sal_Bool bRet = TRUE; |
| |
| if( bDIB ) |
| mhDIB = (HANDLE) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap ); |
| else |
| mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap ); |
| |
| if( mhDIB ) |
| { |
| // bitmap-header is the beginning of memory block |
| PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) mhDIB; |
| |
| maSize = Size( pBIH->cx, pBIH->cy ); |
| mnBitCount = pBIH->cBitCount; |
| |
| if( mnBitCount ) |
| mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24; |
| } |
| else if( mhDDB ) |
| { |
| BITMAPINFOHEADER2 aDDBInfoHeader; |
| |
| aDDBInfoHeader.cbFix = sizeof( aDDBInfoHeader ); |
| |
| if( GpiQueryBitmapInfoHeader( mhDDB, &aDDBInfoHeader ) ) |
| { |
| maSize = Size( aDDBInfoHeader.cx, aDDBInfoHeader.cy ); |
| mnBitCount = aDDBInfoHeader.cPlanes * aDDBInfoHeader.cBitCount; |
| |
| if( mnBitCount ) |
| { |
| mnBitCount = ( mnBitCount <= 1 ) ? 1 : |
| ( mnBitCount <= 4 ) ? 4 : |
| ( mnBitCount <= 8 ) ? 8 : 24; |
| } |
| } |
| else |
| { |
| mhDDB = 0; |
| bRet = FALSE; |
| } |
| |
| } |
| else |
| bRet = FALSE; |
| |
| return bRet; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| bool Os2SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal ) |
| { |
| bool bRet = FALSE; |
| |
| mhDIB = ImplCreateDIB( rSize, nBitCount, rPal ); |
| |
| if( mhDIB ) |
| { |
| maSize = rSize; |
| mnBitCount = nBitCount; |
| bRet = TRUE; |
| } |
| |
| return bRet; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| bool Os2SalBitmap::Create( const SalBitmap& rSSalBitmap ) |
| { |
| bool bRet = FALSE; |
| const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); |
| |
| if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB ) |
| { |
| HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB, |
| rSalBitmap.mhDIB != 0 ); |
| |
| if( hNewHdl ) |
| { |
| if( rSalBitmap.mhDIB ) |
| mhDIB = (HANDLE) hNewHdl; |
| else if( rSalBitmap.mhDDB ) |
| mhDDB = (HBITMAP) hNewHdl; |
| |
| maSize = rSalBitmap.maSize; |
| mnBitCount = rSalBitmap.mnBitCount; |
| bRet = TRUE; |
| } |
| } |
| |
| return bRet; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| bool Os2SalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics ) |
| { |
| bool bRet = FALSE; |
| const Os2SalBitmap& rSalBmp = static_cast<const Os2SalBitmap&>(rSSalBmp); |
| Os2SalGraphics* pGraphics = static_cast<Os2SalGraphics*>(pSGraphics); |
| |
| if( rSalBmp.mhDIB ) |
| { |
| HPS hPS = pGraphics->mhPS; |
| HBITMAP hNewDDB; |
| BITMAPINFOHEADER2 aInfoHeader; |
| const Size aSize( rSalBmp.GetSize() ); |
| long nFormat[ 2 ]; |
| |
| memset( &aInfoHeader, 0, sizeof( aInfoHeader ) ); |
| aInfoHeader.cbFix = 16; |
| aInfoHeader.cx = aSize.Width(); |
| aInfoHeader.cy = aSize.Height(); |
| |
| GpiQueryDeviceBitmapFormats( hPS, 2L, (PLONG) &nFormat ); |
| aInfoHeader.cPlanes = nFormat[ 0 ]; |
| aInfoHeader.cBitCount = nFormat[ 1 ]; |
| |
| // ! wegen Postscript-Treiber |
| if( !aInfoHeader.cBitCount ) |
| aInfoHeader.cBitCount = 24; |
| else if( ( aInfoHeader.cPlanes == 1 ) && ( aInfoHeader.cBitCount == 1 ) ) |
| aInfoHeader.cBitCount = 4; |
| |
| // BitCount == 1 ist wegen aller moeglichen Treiberfehler nicht moeglich |
| if( rSalBmp.GetBitCount() == 1 ) |
| { |
| HANDLE hTmp = ImplCreateDIB4FromDIB1( rSalBmp.mhDIB ); |
| PBYTE pBits = (PBYTE) hTmp + *(ULONG*) hTmp + ImplGetDIBColorCount( hTmp ) * sizeof( RGB2 ); |
| |
| hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) hTmp ); |
| rtl_freeMemory( (void*)hTmp ); |
| } |
| else |
| { |
| PBYTE pBits = (PBYTE) rSalBmp.mhDIB + *(ULONG*) rSalBmp.mhDIB + ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGB2 ); |
| hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) rSalBmp.mhDIB ); |
| } |
| |
| aInfoHeader.cbFix = sizeof( aInfoHeader ); |
| |
| if( hNewDDB && GpiQueryBitmapInfoHeader( hNewDDB, &aInfoHeader ) ) |
| { |
| mhDDB = hNewDDB; |
| maSize = Size( aInfoHeader.cx, aInfoHeader.cy ); |
| mnBitCount = aInfoHeader.cPlanes * aInfoHeader.cBitCount; |
| |
| if( mnBitCount ) |
| { |
| mnBitCount = ( mnBitCount <= 1 ) ? 1 : |
| ( mnBitCount <= 4 ) ? 4 : |
| ( mnBitCount <= 8 ) ? 8 : 24; |
| } |
| |
| bRet = TRUE; |
| } |
| else if( hNewDDB ) |
| GpiDeleteBitmap( hNewDDB ); |
| } |
| |
| return bRet; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| bool Os2SalBitmap::Create( const SalBitmap& rSSalBmp, USHORT nNewBitCount ) |
| { |
| bool bRet = FALSE; |
| const Os2SalBitmap& rSalBmp = static_cast<const Os2SalBitmap&>(rSSalBmp); |
| |
| if( rSalBmp.mhDDB ) |
| { |
| mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() ); |
| |
| if( mhDIB ) |
| { |
| // bitmap-header is the beginning of memory block |
| PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB; |
| const int nLines = (int) rSalBmp.maSize.Height(); |
| PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBI + ImplGetDIBColorCount( mhDIB ) * sizeof( RGB2 ); |
| SIZEL aSizeL = { rSalBmp.maSize.Width(), nLines }; |
| HAB hAB = GetSalData()->mhAB; |
| DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
| HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); |
| HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); |
| HBITMAP hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, rSalBmp.mhDDB ); |
| |
| if( GpiQueryBitmapBits( hMemPS, 0, nLines, pBits, pBI ) == nLines ) |
| { |
| maSize = rSalBmp.maSize; |
| mnBitCount = nNewBitCount; |
| bRet = TRUE; |
| } |
| else |
| { |
| rtl_freeMemory( (void*)mhDIB ); |
| mhDIB = 0; |
| } |
| |
| Ft2SetBitmap( hMemPS, hMemOld ); |
| Ft2DestroyPS( hMemPS ); |
| DevCloseDC( hMemDC ); |
| } |
| } |
| |
| return bRet; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| void Os2SalBitmap::Destroy() |
| { |
| if( mhDIB ) |
| rtl_freeMemory( (void*)mhDIB ); |
| else if( mhDDB ) |
| GpiDeleteBitmap( mhDDB ); |
| |
| if( mhDIB1Subst ) |
| { |
| rtl_freeMemory( (void*)mhDIB1Subst ); |
| mhDIB1Subst = NULL; |
| } |
| |
| maSize = Size(); |
| mnBitCount = 0; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| void Os2SalBitmap::ImplReplacehDIB1Subst( HANDLE hDIB1Subst ) |
| { |
| if( mhDIB1Subst ) |
| rtl_freeMemory( (void*)mhDIB1Subst ); |
| |
| mhDIB1Subst = hDIB1Subst; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| USHORT Os2SalBitmap::ImplGetDIBColorCount( HANDLE hDIB ) |
| { |
| USHORT nColors = 0; |
| |
| if( hDIB ) |
| { |
| // bitmap infos can be found at the beginning of the memory |
| PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hDIB; |
| |
| if( pBIH->cBitCount <= 8 ) |
| { |
| if( pBIH->cclrUsed ) |
| nColors = (USHORT) pBIH->cclrUsed; |
| else |
| nColors = 1 << pBIH->cBitCount; |
| } |
| } |
| |
| return nColors; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| HANDLE Os2SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBits, const BitmapPalette& rPal ) |
| { |
| DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24, "Unsupported BitCount!" ); |
| |
| HANDLE hDIB = 0; |
| |
| if ( rSize.Width() && rSize.Height() && ( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24 ) ) |
| { |
| const ULONG nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height(); |
| const USHORT nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0; |
| |
| hDIB = (HANDLE) rtl_allocateZeroMemory( sizeof( BITMAPINFOHEADER2 ) + nColors * sizeof( RGB2 ) + nImageSize ); |
| |
| if( hDIB ) |
| { |
| // bitmap infos can be found at the beginning of the memory |
| PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB; |
| PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI; |
| |
| pBIH->cbFix = sizeof( BITMAPINFOHEADER2 ); |
| pBIH->cx = rSize.Width(); |
| pBIH->cy = rSize.Height(); |
| pBIH->cPlanes = 1; |
| pBIH->cBitCount = nBits; |
| pBIH->ulCompression = BCA_UNCOMP; // BI_RGB; |
| pBIH->cbImage = nImageSize; |
| pBIH->cxResolution = 0; |
| pBIH->cyResolution = 0; |
| pBIH->cclrUsed = 0; |
| pBIH->cclrImportant = 0; |
| |
| // Rest auf 0 setzen |
| memset( (PBYTE) &pBIH->usUnits, 0, (PBYTE) pBI->argbColor - (PBYTE) &pBIH->usUnits ); |
| |
| if( nColors ) |
| { |
| const USHORT nMinCount = Min( nColors, rPal.GetEntryCount() ); |
| |
| if( nMinCount ) |
| memcpy( pBI->argbColor, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGB2 ) ); |
| } |
| } |
| } |
| |
| return hDIB; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| HANDLE Os2SalBitmap::ImplCreateDIB4FromDIB1( HANDLE hDIB1 ) |
| { |
| PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB1; |
| PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI; |
| PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBIH + Os2SalBitmap::ImplGetDIBColorCount( hDIB1 ) * sizeof( RGB2 ); |
| ULONG nWidth = pBIH->cx, nHeight = pBIH->cy; |
| ULONG nAligned = AlignedWidth4Bytes( nWidth ); |
| ULONG nAligned4 = AlignedWidth4Bytes( nWidth << 2 ); |
| ULONG nSize4 = sizeof( BITMAPINFOHEADER2 ) + ( sizeof( RGB2 ) << 4 ) + nAligned4 * nHeight; |
| PBYTE pDIB4 = (PBYTE) rtl_allocateZeroMemory( nSize4 ); |
| PBITMAPINFO2 pBI4 = (PBITMAPINFO2) pDIB4; |
| PBITMAPINFOHEADER2 pBIH4 = (PBITMAPINFOHEADER2) pBI4; |
| PM_BYTE aMap[ 4 ] = { 0x00, 0x01, 0x10, 0x11 }; |
| |
| memset( pBIH4, 0, sizeof( BITMAPINFOHEADER2 ) ); |
| pBIH4->cbFix = sizeof( BITMAPINFOHEADER2 ); |
| pBIH4->cx = nWidth; |
| pBIH4->cy = nHeight; |
| pBIH4->cPlanes = 1; |
| pBIH4->cBitCount = 4; |
| |
| // die ersten beiden Eintraege der 1Bit-Farbtabelle kopieren |
| memcpy( pBI4->argbColor, pBI->argbColor, sizeof( RGB2 ) << 1 ); |
| |
| PBYTE pBits4 = (PBYTE) pBI4 + *(ULONG*) pBIH4 + ( sizeof( RGB2 ) << 4 ); |
| |
| // 4Bit-DIB-Bilddaten setzen |
| for( ULONG nY = 0UL; nY < nHeight; nY++ ) |
| { |
| PBYTE pTmp = pBits; pBits += nAligned; |
| PBYTE pTmp4 = pBits4; pBits4 += nAligned4; |
| |
| for( ULONG nX = 0UL; nX < nWidth; nX += 8UL ) |
| { |
| *pTmp4++ = aMap[ ( *pTmp >> 6 ) & 3 ]; |
| *pTmp4++ = aMap[ ( *pTmp >> 4 ) & 3 ]; |
| *pTmp4++ = aMap[ ( *pTmp >> 2 ) & 3 ]; |
| *pTmp4++ = aMap[ *pTmp++ & 3 ]; |
| } |
| } |
| |
| return (HANDLE) pDIB4; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| HANDLE Os2SalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, bool bDIB ) |
| { |
| HANDLE hCopy = 0; |
| |
| if( bDIB && hHdl ) |
| { |
| PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hHdl; |
| const ULONG nSize = sizeof( BITMAPINFOHEADER2 ) |
| + ImplGetDIBColorCount( hHdl ) * sizeof( RGB2 ) + |
| ( pBIH->cbImage ? pBIH->cbImage : AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) ); |
| |
| PM_BYTE* pCopy = (PM_BYTE*)rtl_allocateZeroMemory( nSize ); |
| memcpy( pCopy, (PM_BYTE*) hHdl, nSize ); |
| hCopy = (HANDLE) pCopy; |
| } |
| else if( hHdl ) |
| { |
| HAB hAB = GetSalData()->mhAB; |
| HDC hSrcMemDC; |
| HDC hDestMemDC; |
| HPS hSrcMemPS; |
| HPS hDestMemPS; |
| HBITMAP hCopyBitmap; |
| BITMAPINFOHEADER2 aInfoHeader; |
| DEVOPENSTRUC aDevOpenStruc; |
| SIZEL size; |
| |
| aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 ); |
| GpiQueryBitmapInfoHeader( hHdl, &aInfoHeader ); |
| size.cx = aInfoHeader.cx; |
| size.cy = aInfoHeader.cy; |
| |
| // Memory DCs erzeugen |
| aDevOpenStruc.pszLogAddress = 0; |
| aDevOpenStruc.pszDriverName = (PSZ)"DISPLAY"; |
| |
| hSrcMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 ); |
| hDestMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 ); |
| |
| // Memory PSs erzeugen |
| hSrcMemPS = Ft2CreatePS( hAB, hSrcMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); |
| hDestMemPS = Ft2CreatePS( hAB, hDestMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); |
| |
| Ft2SetBitmap( hSrcMemPS, hHdl ); |
| |
| if( !hHdl ) |
| { |
| memset( &aInfoHeader, 0, sizeof( BITMAPINFOHEADER2 ) ); |
| aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 ); |
| aInfoHeader.cx = 0; |
| aInfoHeader.cy = 0; |
| aInfoHeader.cPlanes = 1; |
| aInfoHeader.cBitCount = 1; |
| } |
| |
| hCopy = GpiCreateBitmap( hDestMemPS, &aInfoHeader, 0, NULL, NULL ); |
| Ft2SetBitmap( hDestMemPS, hCopy ); |
| |
| POINTL pts[3]; |
| |
| pts[0].x = 0; |
| pts[0].y = 0; |
| pts[1].x = size.cx; |
| pts[1].y = size.cy; |
| pts[2].x = 0; |
| pts[2].y = 0; |
| |
| GpiBitBlt( hDestMemPS, hSrcMemPS, 3, pts, ROP_SRCCOPY, BBO_IGNORE ); |
| |
| Ft2SetBitmap( hSrcMemPS, (HBITMAP)0L); |
| Ft2SetBitmap( hDestMemPS, (HBITMAP)0L); |
| Ft2Associate( hSrcMemPS, NULLHANDLE ); |
| Ft2Associate( hDestMemPS, NULLHANDLE ); |
| Ft2DestroyPS( hSrcMemPS ); |
| Ft2DestroyPS( hDestMemPS ); |
| DevCloseDC( hSrcMemDC ); |
| DevCloseDC( hDestMemDC ); |
| } |
| |
| return hCopy; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| BitmapBuffer* Os2SalBitmap::AcquireBuffer( bool bReadOnly ) |
| { |
| BitmapBuffer* pBuffer = NULL; |
| |
| if( mhDIB ) |
| { |
| // bitmap infos can be found at the beginning of the memory |
| PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB; |
| PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI; |
| |
| if( ( pBIH->ulCompression == BCA_RLE4 ) || ( pBIH->ulCompression == BCA_RLE8 ) ) |
| { |
| Size aSizePix( pBIH->cx, pBIH->cy ); |
| HANDLE hNewDIB = ImplCreateDIB( aSizePix, pBIH->cBitCount, BitmapPalette() ); |
| |
| if( hNewDIB ) |
| { |
| // bitmap infos can be found at the beginning of the memory |
| PBITMAPINFO2 pNewBI = (PBITMAPINFO2) hNewDIB; |
| PBITMAPINFOHEADER2 pNewBIH = (PBITMAPINFOHEADER2) pNewBI; |
| const USHORT nColorCount = ImplGetDIBColorCount( hNewDIB ); |
| const ULONG nOffset = *(ULONG*) pBI + nColorCount * sizeof( RGB2 ); |
| PM_BYTE* pOldBits = (PM_BYTE*) pBI + nOffset; |
| PM_BYTE* pNewBits = (PM_BYTE*) pNewBI + nOffset; |
| |
| memcpy( pNewBI, pBI, nOffset ); |
| pNewBIH->ulCompression = 0; |
| ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->ulCompression == BCA_RLE4 ); |
| |
| rtl_freeMemory( (void*)mhDIB ); |
| |
| mhDIB = hNewDIB; |
| pBI = pNewBI; |
| pBIH = pNewBIH; |
| } |
| } |
| |
| if( pBIH->cPlanes == 1 ) |
| { |
| pBuffer = new BitmapBuffer; |
| |
| pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP | |
| ( pBIH->cBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL : |
| pBIH->cBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL : |
| pBIH->cBitCount == 8 ? BMP_FORMAT_8BIT_PAL : |
| pBIH->cBitCount == 16 ? BMP_FORMAT_16BIT_TC_LSB_MASK : |
| pBIH->cBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR : |
| pBIH->cBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL ); |
| |
| if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) ) |
| { |
| pBuffer->mnWidth = maSize.Width(); |
| pBuffer->mnHeight = maSize.Height(); |
| pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->cBitCount ); |
| pBuffer->mnBitCount = (USHORT) pBIH->cBitCount; |
| |
| if( pBuffer->mnBitCount <= 8 ) |
| { |
| const USHORT nPalCount = ImplGetDIBColorCount( mhDIB ); |
| |
| pBuffer->maPalette.SetEntryCount( nPalCount ); |
| |
| if( nPalCount ) |
| memcpy( pBuffer->maPalette.ImplGetColorBuffer(), pBI->argbColor, nPalCount * sizeof( RGB2 ) ); |
| |
| pBuffer->mpBits = (sal_uInt8*) pBI + *(ULONG*) pBI + nPalCount * sizeof( RGB2 ); |
| } |
| else |
| pBuffer->mpBits = (sal_uInt8*) pBI + *(ULONG*) pBI; |
| } |
| else |
| { |
| delete pBuffer; |
| pBuffer = NULL; |
| } |
| } |
| } |
| |
| if( pBuffer && mhDIB1Subst ) |
| { |
| rtl_freeMemory( (void*)mhDIB1Subst ); |
| mhDIB1Subst = 0; |
| } |
| |
| return pBuffer; |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| void Os2SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) |
| { |
| if( pBuffer ) |
| { |
| if( mhDIB ) |
| { |
| if( !bReadOnly && !!pBuffer->maPalette ) |
| { |
| // bitmap infos can be found at the beginning of the memory |
| PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB; |
| const USHORT nCount = pBuffer->maPalette.GetEntryCount(); |
| |
| if( nCount ) |
| memcpy( pBI->argbColor, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGB2 ) ); |
| } |
| } |
| |
| delete pBuffer; |
| } |
| } |
| |
| // ------------------------------------------------------------------ |
| |
| void Os2SalBitmap::ImplDecodeRLEBuffer( const PM_BYTE* pSrcBuf, PM_BYTE* pDstBuf, |
| const Size& rSizePixel, bool bRLE4 ) |
| { |
| HPBYTE pRLE = (HPBYTE) pSrcBuf; |
| HPBYTE pDIB = (HPBYTE) pDstBuf; |
| HPBYTE pRow = (HPBYTE) pDstBuf; |
| ULONG nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) ); |
| HPBYTE pLast = pDIB + rSizePixel.Height() * nWidthAl - 1; |
| ULONG nCountByte; |
| ULONG nRunByte; |
| ULONG nX = 0; |
| ULONG i; |
| PM_BYTE cTmp; |
| sal_Bool bEndDecoding = FALSE; |
| |
| if( pRLE && pDIB ) |
| { |
| do |
| { |
| if( !( nCountByte = *pRLE++ ) ) |
| { |
| nRunByte = *pRLE++; |
| |
| if( nRunByte > 2UL ) |
| { |
| if( bRLE4 ) |
| { |
| nCountByte = nRunByte >> 1UL; |
| |
| for( i = 0; i < nCountByte; i++ ) |
| { |
| cTmp = *pRLE++; |
| ImplSetPixel4( pDIB, nX++, cTmp >> 4 ); |
| ImplSetPixel4( pDIB, nX++, cTmp & 0x0f ); |
| } |
| |
| if( nRunByte & 1 ) |
| ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 ); |
| |
| if( ( ( nRunByte + 1 ) >> 1 ) & 1 ) |
| pRLE++; |
| } |
| else |
| { |
| memcpy( &pDIB[ nX ], pRLE, nRunByte ); |
| pRLE += nRunByte; |
| nX += nRunByte; |
| |
| if( nRunByte & 1 ) |
| pRLE++; |
| } |
| } |
| else if( !nRunByte ) |
| { |
| pDIB = ( pRow += nWidthAl ); |
| nX = 0UL; |
| } |
| else if( nRunByte == 1 ) |
| bEndDecoding = TRUE; |
| else |
| { |
| nX += *pRLE++; |
| pDIB = ( pRow += ( *pRLE++ ) * nWidthAl ); |
| } |
| } |
| else |
| { |
| cTmp = *pRLE++; |
| |
| if( bRLE4 ) |
| { |
| nRunByte = nCountByte >> 1; |
| |
| for( i = 0; i < nRunByte; i++ ) |
| { |
| ImplSetPixel4( pDIB, nX++, cTmp >> 4 ); |
| ImplSetPixel4( pDIB, nX++, cTmp & 0x0f ); |
| } |
| |
| if( nCountByte & 1 ) |
| ImplSetPixel4( pDIB, nX++, cTmp >> 4 ); |
| } |
| else |
| { |
| for( i = 0; i < nCountByte; i++ ) |
| pDIB[ nX++ ] = cTmp; |
| } |
| } |
| } |
| while( !bEndDecoding && ( pDIB <= pLast ) ); |
| } |
| } |
| |
| bool Os2SalBitmap::GetSystemData( BitmapSystemData& rData ) |
| { |
| bool bRet = false; |
| if( mhDIB || mhDDB ) |
| { |
| bRet = true; |
| rData.pDIB = (void*)mhDIB; |
| rData.pDDB = (void*)mhDDB; |
| } |
| return bRet; |
| } |