--- filter/source/graphicfilter/itiff/itiff.cxx 2010-10-06 11:12:42.000000000 +0100 +++ filter/source/graphicfilter/itiff/itiff.cxx 2010-10-06 13:21:08.000000000 +0100 @@ -61,6 +61,8 @@ SvStream* pTIFF; // Die einzulesende TIFF-Datei Bitmap aBitmap; BitmapWriteAccess* pAcc; + AlphaMask* pAlphaMask; + BitmapWriteAccess* pMaskAcc; USHORT nDstBitsPerPixel; ULONG nOrigPos; // Anfaengliche Position in pTIFF @@ -129,10 +131,14 @@ BOOL ConvertScanline( ULONG nY ); // Konvertiert eine Scanline in das Windows-BMP-Format + bool HasAlphaChannel() const; public: - TIFFReader() {} - ~TIFFReader() {} + TIFFReader() : pAlphaMask(0), pMaskAcc(0) {} + ~TIFFReader() + { + delete pAlphaMask; + } BOOL ReadTIFF( SvStream & rTIFF, Graphic & rGraphic ); }; @@ -744,12 +750,18 @@ BYTE nLRed = 0; BYTE nLGreen = 0; BYTE nLBlue = 0; + BYTE nLAlpha = 0; for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel ) { nLRed = nLRed + pt[ 0 ]; nLGreen = nLGreen + pt[ 1 ]; nLBlue = nLBlue + pt[ 2 ]; pAcc->SetPixel( nY, nx, Color( nLRed, nLGreen, nLBlue ) ); + if (nSamplesPerPixel >= 4 && pMaskAcc) + { + nLAlpha = nLAlpha + pt[ 3 ]; + pMaskAcc->SetPixel( nY, nx, ~nLAlpha ); + } } } else @@ -757,6 +769,11 @@ for ( nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel ) { pAcc->SetPixel( nY, nx, Color( pt[0], pt[1], pt[2] ) ); + if (nSamplesPerPixel >= 4 && pMaskAcc) + { + BYTE nAlpha = pt[3]; + pMaskAcc->SetPixel( nY, nx, ~nAlpha ); + } } } } @@ -1077,6 +1094,18 @@ bStatus = FALSE; } +bool TIFFReader::HasAlphaChannel() const +{ + /*There are undoubtedly more variants we could support, but keep it simple for now*/ + return ( + nDstBitsPerPixel == 24 && + nBitsPerSample == 8 && + nSamplesPerPixel >= 4 && + nPlanes == 1 && + nPhotometricInterpretation == 2 + ); +} + // --------------------------------------------------------------------------------- BOOL TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic ) @@ -1219,7 +1248,8 @@ else nDstBitsPerPixel = 8; - aBitmap = Bitmap( Size( nImageWidth, nImageLength ), nDstBitsPerPixel ); + Size aTargetSize( nImageWidth, nImageLength ); + aBitmap = Bitmap( aTargetSize, nDstBitsPerPixel ); pAcc = aBitmap.AcquireWriteAccess(); if ( pAcc ) { @@ -1240,7 +1270,7 @@ { pMap[ j ] = new BYTE[ nBytesPerRow ]; } - catch (std::bad_alloc) + catch (std::bad_alloc) { pMap[ j ] = NULL; bStatus = FALSE; @@ -1248,6 +1278,12 @@ } } + if (HasAlphaChannel()) + { + pAlphaMask = new AlphaMask( aTargetSize ); + pMaskAcc = pAlphaMask->AcquireWriteAccess(); + } + if ( bStatus && ReadMap( 10, 60 ) ) { nMaxPos = Max( pTIFF->Tell(), nMaxPos ); @@ -1260,9 +1296,24 @@ if( pAcc ) { aBitmap.ReleaseAccess( pAcc ); + + if ( pMaskAcc ) + { + if ( pAlphaMask ) + pAlphaMask->ReleaseAccess( pMaskAcc ); + pMaskAcc = NULL; + } + if ( bStatus ) { - AnimationBitmap aAnimationBitmap( aBitmap, Point( 0, 0 ), aBitmap.GetSizePixel(), + BitmapEx aImage; + + if (pAlphaMask) + aImage = BitmapEx( aBitmap, *pAlphaMask ); + else + aImage = aBitmap; + + AnimationBitmap aAnimationBitmap( aImage, Point( 0, 0 ), aBitmap.GetSizePixel(), ANIMATION_TIMEOUT_ON_CLICK, DISPOSE_BACK ); aAnimation.Insert( aAnimationBitmap );