517 lines
19 KiB
C++
517 lines
19 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#include <rtl/memory.h>
|
|
#include <vcl/bmpacc.hxx>
|
|
#include <vcl/salbtype.hxx>
|
|
#include <bmpfast.hxx>
|
|
|
|
// -----------
|
|
// - Defines -
|
|
// -----------
|
|
|
|
#define IMPL_CASE_GET_FORMAT( Format ) \
|
|
case( BMP_FORMAT##Format ): \
|
|
pFncGetPixel = BitmapReadAccess::GetPixelFor##Format; \
|
|
break
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
#define IMPL_CASE_SET_FORMAT( Format, BitCount ) \
|
|
case( BMP_FORMAT##Format ): \
|
|
{ \
|
|
pFncSetPixel = BitmapReadAccess::SetPixelFor##Format; \
|
|
pDstBuffer->mnBitCount = BitCount; \
|
|
} \
|
|
break
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
#define DOUBLE_SCANLINES() \
|
|
while( ( nActY < nHeight1 ) && ( pMapY[ nActY + 1 ] == nMapY ) ) \
|
|
{ \
|
|
memcpy( pDstScanMap[ nActY + 1L ], pDstScan, rDstBuffer.mnScanlineSize ); \
|
|
nActY++; \
|
|
}
|
|
|
|
// -----------
|
|
// - Inlines -
|
|
// -----------
|
|
|
|
#define TC_TO_PAL_COLORS 4096
|
|
|
|
static long ImplIndexFromColor( const BitmapColor& rCol )
|
|
{
|
|
#if TC_TO_PAL_COLORS == 4096
|
|
|
|
return( ( ( (long) rCol.GetBlue() >> 4L) << 8L ) |
|
|
( ( (long) rCol.GetGreen() >> 4L ) << 4L ) |
|
|
( (long) rCol.GetRed() >> 4L ) );
|
|
|
|
#elif TC_TO_PAL_COLORS == 32768
|
|
|
|
return( ( ( (long) rCol.GetBlue() >> 3L) << 10L ) |
|
|
( ( (long) rCol.GetGreen() >> 3L ) << 5L ) |
|
|
( (long) rCol.GetRed() >> 3L ) );
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
#define COLOR_TO_INDEX( _def_rCol )
|
|
|
|
// ------------------------
|
|
// - conversion functions -
|
|
// ------------------------
|
|
|
|
static void ImplPALToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
|
|
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
|
|
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
|
|
{
|
|
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
|
|
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
|
|
const ColorMask& rDstMask = rDstBuffer.maColorMask;
|
|
BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
|
|
BitmapColor* pColMapBuf = aColMap.ImplGetColorBuffer();
|
|
BitmapColor aIndex( 0 );
|
|
|
|
for( sal_uInt16 i = 0, nSrcCount = aColMap.GetEntryCount(), nDstCount = rDstBuffer.maPalette.GetEntryCount(); i < nSrcCount; i++ )
|
|
{
|
|
if( ( i < nDstCount ) && ( rSrcBuffer.maPalette[ i ] == rDstBuffer.maPalette[ i ] ) )
|
|
aIndex.SetIndex( sal::static_int_cast<sal_uInt8>(i) );
|
|
else
|
|
aIndex.SetIndex( sal::static_int_cast<sal_uInt8>(rDstBuffer.maPalette.GetBestIndex( rSrcBuffer.maPalette[ i ] )) );
|
|
|
|
pColMapBuf[ i ] = aIndex;
|
|
}
|
|
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
pFncSetPixel( pDstScan, nX, pColMapBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
|
|
|
|
DOUBLE_SCANLINES();
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
static void ImplPALToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
|
|
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
|
|
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
|
|
{
|
|
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
|
|
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
|
|
const ColorMask& rDstMask = rDstBuffer.maColorMask;
|
|
const BitmapColor* pColBuf = rSrcBuffer.maPalette.ImplGetColorBuffer();
|
|
|
|
if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_1BIT_MSB_PAL )
|
|
{
|
|
const BitmapColor aCol0( pColBuf[ 0 ] );
|
|
const BitmapColor aCol1( pColBuf[ 1 ] );
|
|
long nMapX;
|
|
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; )
|
|
{
|
|
nMapX = pMapX[ nX ];
|
|
pFncSetPixel( pDstScan, nX++,
|
|
pSrcScan[ nMapX >> 3 ] & ( 1 << ( 7 - ( nMapX & 7 ) ) ) ? aCol1 : aCol0,
|
|
rDstMask );
|
|
}
|
|
|
|
DOUBLE_SCANLINES();
|
|
}
|
|
}
|
|
else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_4BIT_MSN_PAL )
|
|
{
|
|
long nMapX;
|
|
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; )
|
|
{
|
|
nMapX = pMapX[ nX ];
|
|
pFncSetPixel( pDstScan, nX++,
|
|
pColBuf[ ( pSrcScan[ nMapX >> 1 ] >> ( nMapX & 1 ? 0 : 4 ) ) & 0x0f ],
|
|
rDstMask );
|
|
}
|
|
|
|
DOUBLE_SCANLINES();
|
|
}
|
|
}
|
|
else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_8BIT_PAL )
|
|
{
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
pFncSetPixel( pDstScan, nX, pColBuf[ pSrcScan[ pMapX[ nX ] ] ], rDstMask );
|
|
|
|
DOUBLE_SCANLINES();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
pFncSetPixel( pDstScan, nX, pColBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
|
|
|
|
DOUBLE_SCANLINES();
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
static void ImplTCToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
|
|
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
|
|
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
|
|
{
|
|
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
|
|
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
|
|
const ColorMask& rDstMask = rDstBuffer.maColorMask;
|
|
|
|
if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_24BIT_TC_BGR )
|
|
{
|
|
BitmapColor aCol;
|
|
sal_uInt8* pPixel = NULL;
|
|
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
{
|
|
aCol.SetBlue( *( pPixel = ( pSrcScan + pMapX[ nX ] * 3 ) )++ );
|
|
aCol.SetGreen( *pPixel++ );
|
|
aCol.SetRed( *pPixel );
|
|
pFncSetPixel( pDstScan, nX, aCol, rDstMask );
|
|
}
|
|
|
|
DOUBLE_SCANLINES()
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
pFncSetPixel( pDstScan, nX, pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ), rDstMask );
|
|
|
|
DOUBLE_SCANLINES();
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
static void ImplTCToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
|
|
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
|
|
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
|
|
{
|
|
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
|
|
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
|
|
const ColorMask& rDstMask = rDstBuffer.maColorMask;
|
|
BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
|
|
sal_uInt8* pColToPalMap = new sal_uInt8[ TC_TO_PAL_COLORS ];
|
|
BitmapColor aIndex( 0 );
|
|
|
|
for( long nR = 0; nR < 16; nR++ )
|
|
{
|
|
for( long nG = 0; nG < 16; nG++ )
|
|
{
|
|
for( long nB = 0; nB < 16; nB++ )
|
|
{
|
|
BitmapColor aCol( sal::static_int_cast<sal_uInt8>(nR << 4),
|
|
sal::static_int_cast<sal_uInt8>(nG << 4),
|
|
sal::static_int_cast<sal_uInt8>(nB << 4) );
|
|
pColToPalMap[ ImplIndexFromColor( aCol ) ] = (sal_uInt8) rDstBuffer.maPalette.GetBestIndex( aCol );
|
|
}
|
|
}
|
|
}
|
|
|
|
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
|
|
{
|
|
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
|
|
|
|
for( long nX = 0L; nX < nWidth; nX++ )
|
|
{
|
|
aIndex.SetIndex( pColToPalMap[ ImplIndexFromColor( pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ) ) ] );
|
|
pFncSetPixel( pDstScan, nX, aIndex, rDstMask );
|
|
}
|
|
|
|
DOUBLE_SCANLINES();
|
|
}
|
|
|
|
delete[] pColToPalMap;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// ---------------------
|
|
// - StretchAndConvert -
|
|
// ---------------------
|
|
|
|
BitmapBuffer* StretchAndConvert( const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect,
|
|
sal_uLong nDstBitmapFormat, BitmapPalette* pDstPal, ColorMask* pDstMask )
|
|
{
|
|
FncGetPixel pFncGetPixel;
|
|
FncSetPixel pFncSetPixel;
|
|
BitmapBuffer* pDstBuffer = new BitmapBuffer;
|
|
long i;
|
|
|
|
// set function for getting pixels
|
|
switch( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) )
|
|
{
|
|
IMPL_CASE_GET_FORMAT( _1BIT_MSB_PAL );
|
|
IMPL_CASE_GET_FORMAT( _1BIT_LSB_PAL );
|
|
IMPL_CASE_GET_FORMAT( _4BIT_MSN_PAL );
|
|
IMPL_CASE_GET_FORMAT( _4BIT_LSN_PAL );
|
|
IMPL_CASE_GET_FORMAT( _8BIT_PAL );
|
|
IMPL_CASE_GET_FORMAT( _8BIT_TC_MASK );
|
|
IMPL_CASE_GET_FORMAT( _16BIT_TC_MSB_MASK );
|
|
IMPL_CASE_GET_FORMAT( _16BIT_TC_LSB_MASK );
|
|
IMPL_CASE_GET_FORMAT( _24BIT_TC_BGR );
|
|
IMPL_CASE_GET_FORMAT( _24BIT_TC_RGB );
|
|
IMPL_CASE_GET_FORMAT( _24BIT_TC_MASK );
|
|
IMPL_CASE_GET_FORMAT( _32BIT_TC_ABGR );
|
|
IMPL_CASE_GET_FORMAT( _32BIT_TC_ARGB );
|
|
IMPL_CASE_GET_FORMAT( _32BIT_TC_BGRA );
|
|
IMPL_CASE_GET_FORMAT( _32BIT_TC_RGBA );
|
|
IMPL_CASE_GET_FORMAT( _32BIT_TC_MASK );
|
|
|
|
default:
|
|
// should never come here
|
|
// initialize pFncGetPixel to something valid that is
|
|
// least likely to crash
|
|
pFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL;
|
|
OSL_FAIL( "unknown read format" );
|
|
break;
|
|
}
|
|
|
|
// set function for setting pixels
|
|
const sal_uLong nDstScanlineFormat = BMP_SCANLINE_FORMAT( nDstBitmapFormat );
|
|
switch( nDstScanlineFormat )
|
|
{
|
|
IMPL_CASE_SET_FORMAT( _1BIT_MSB_PAL, 1 );
|
|
IMPL_CASE_SET_FORMAT( _1BIT_LSB_PAL, 1 );
|
|
IMPL_CASE_SET_FORMAT( _4BIT_MSN_PAL, 1 );
|
|
IMPL_CASE_SET_FORMAT( _4BIT_LSN_PAL, 4 );
|
|
IMPL_CASE_SET_FORMAT( _8BIT_PAL, 8 );
|
|
IMPL_CASE_SET_FORMAT( _8BIT_TC_MASK, 8 );
|
|
IMPL_CASE_SET_FORMAT( _16BIT_TC_MSB_MASK, 16 );
|
|
IMPL_CASE_SET_FORMAT( _16BIT_TC_LSB_MASK, 16 );
|
|
IMPL_CASE_SET_FORMAT( _24BIT_TC_BGR, 24 );
|
|
IMPL_CASE_SET_FORMAT( _24BIT_TC_RGB, 24 );
|
|
IMPL_CASE_SET_FORMAT( _24BIT_TC_MASK, 24 );
|
|
IMPL_CASE_SET_FORMAT( _32BIT_TC_ABGR, 32 );
|
|
IMPL_CASE_SET_FORMAT( _32BIT_TC_ARGB, 32 );
|
|
IMPL_CASE_SET_FORMAT( _32BIT_TC_BGRA, 32 );
|
|
IMPL_CASE_SET_FORMAT( _32BIT_TC_RGBA, 32 );
|
|
IMPL_CASE_SET_FORMAT( _32BIT_TC_MASK, 32 );
|
|
|
|
default:
|
|
// should never come here
|
|
// initialize pFncSetPixel to something valid that is
|
|
// least likely to crash
|
|
pFncSetPixel = BitmapReadAccess::SetPixelFor_1BIT_MSB_PAL;
|
|
pDstBuffer->mnBitCount = 1;
|
|
OSL_FAIL( "unknown write format" );
|
|
break;
|
|
}
|
|
|
|
// fill destination buffer
|
|
pDstBuffer->mnFormat = nDstBitmapFormat;
|
|
pDstBuffer->mnWidth = rTwoRect.mnDestWidth;
|
|
pDstBuffer->mnHeight = rTwoRect.mnDestHeight;
|
|
pDstBuffer->mnScanlineSize = AlignedWidth4Bytes( pDstBuffer->mnBitCount * pDstBuffer->mnWidth );
|
|
try
|
|
{
|
|
pDstBuffer->mpBits = new sal_uInt8[ pDstBuffer->mnScanlineSize * pDstBuffer->mnHeight ];
|
|
}
|
|
catch( const std::bad_alloc& )
|
|
{
|
|
// memory exception, clean up
|
|
pDstBuffer->mpBits = NULL;
|
|
delete pDstBuffer;
|
|
return NULL;
|
|
}
|
|
|
|
// do we need a destination palette or color mask?
|
|
if( ( nDstScanlineFormat == BMP_FORMAT_1BIT_MSB_PAL ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_1BIT_LSB_PAL ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_4BIT_MSN_PAL ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_4BIT_LSN_PAL ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_8BIT_PAL ) )
|
|
{
|
|
DBG_ASSERT( pDstPal, "destination buffer requires palette" );
|
|
pDstBuffer->maPalette = *pDstPal;
|
|
}
|
|
else if( ( nDstScanlineFormat == BMP_FORMAT_8BIT_TC_MASK ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_16BIT_TC_MSB_MASK ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_16BIT_TC_LSB_MASK ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_24BIT_TC_MASK ) ||
|
|
( nDstScanlineFormat == BMP_FORMAT_32BIT_TC_MASK ) )
|
|
{
|
|
DBG_ASSERT( pDstMask, "destination buffer requires color mask" );
|
|
pDstBuffer->maColorMask = *pDstMask;
|
|
}
|
|
|
|
// short circuit the most important conversions
|
|
bool bFastConvert = ImplFastBitmapConversion( *pDstBuffer, rSrcBuffer, rTwoRect );
|
|
if( bFastConvert )
|
|
return pDstBuffer;
|
|
|
|
const long nSrcX = rTwoRect.mnSrcX, nSrcY = rTwoRect.mnSrcY;
|
|
const long nSrcDX = rTwoRect.mnSrcWidth, nSrcDY = rTwoRect.mnSrcHeight;
|
|
const long nDstDX = rTwoRect.mnDestWidth, nDstDY = rTwoRect.mnDestHeight;
|
|
Scanline* pSrcScan = NULL;
|
|
Scanline* pDstScan = NULL;
|
|
long* pMapX = NULL;
|
|
long* pMapY = NULL;
|
|
long nTmp, nOffset;
|
|
|
|
try
|
|
{
|
|
pSrcScan = new Scanline[ rSrcBuffer.mnHeight ];
|
|
pDstScan = new Scanline[ nDstDY ];
|
|
pMapX = new long[ nDstDX ];
|
|
pMapY = new long[ nDstDY ];
|
|
}
|
|
catch( const std::bad_alloc& )
|
|
{
|
|
// memory exception, clean up
|
|
// remark: the buffer ptr causing the exception
|
|
// is still NULL here
|
|
delete[] pSrcScan;
|
|
delete[] pDstScan;
|
|
delete[] pMapX;
|
|
delete[] pMapY;
|
|
delete pDstBuffer;
|
|
return NULL;
|
|
}
|
|
|
|
// horizontal mapping table
|
|
if( nDstDX != nSrcDX )
|
|
{
|
|
const double fFactorX = ( nDstDX > 1 ) ? (double) ( nSrcDX - 1 ) / ( nDstDX - 1 ) : 0.0;
|
|
|
|
for( i = 0L; i < nDstDX; i++ )
|
|
pMapX[ i ] = nSrcX + FRound( i * fFactorX );
|
|
}
|
|
else
|
|
{
|
|
for( i = 0L, nTmp = nSrcX; i < nDstDX; i++ )
|
|
pMapX[ i ] = nTmp++;
|
|
}
|
|
|
|
// vertical mapping table
|
|
if( nDstDY != nSrcDY )
|
|
{
|
|
const double fFactorY = ( nDstDY > 1 ) ? (double) ( nSrcDY - 1 ) / ( nDstDY - 1 ) : 0.0;
|
|
|
|
for( i = 0L; i < nDstDY; i++ )
|
|
pMapY[ i ] = nSrcY + FRound( i * fFactorY );
|
|
}
|
|
else
|
|
{
|
|
for( i = 0L, nTmp = nSrcY; i < nDstDY; i++ )
|
|
pMapY[ i ] = nTmp++;
|
|
}
|
|
|
|
// source scanline buffer
|
|
Scanline pTmpScan;
|
|
if( BMP_SCANLINE_ADJUSTMENT( rSrcBuffer.mnFormat ) == BMP_FORMAT_TOP_DOWN )
|
|
pTmpScan = rSrcBuffer.mpBits, nOffset = rSrcBuffer.mnScanlineSize;
|
|
else
|
|
{
|
|
pTmpScan = rSrcBuffer.mpBits + ( rSrcBuffer.mnHeight - 1 ) * rSrcBuffer.mnScanlineSize;
|
|
nOffset = -rSrcBuffer.mnScanlineSize;
|
|
}
|
|
|
|
for( i = 0L; i < rSrcBuffer.mnHeight; i++, pTmpScan += nOffset )
|
|
pSrcScan[ i ] = pTmpScan;
|
|
|
|
// destination scanline buffer
|
|
if( BMP_SCANLINE_ADJUSTMENT( pDstBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
|
|
pTmpScan = pDstBuffer->mpBits, nOffset = pDstBuffer->mnScanlineSize;
|
|
else
|
|
{
|
|
pTmpScan = pDstBuffer->mpBits + ( nDstDY - 1 ) * pDstBuffer->mnScanlineSize;
|
|
nOffset = -pDstBuffer->mnScanlineSize;
|
|
}
|
|
|
|
for( i = 0L; i < nDstDY; i++, pTmpScan += nOffset )
|
|
pDstScan[ i ] = pTmpScan;
|
|
|
|
// do buffer scaling and conversion
|
|
if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount <= 8 )
|
|
{
|
|
ImplPALToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
|
|
pSrcScan, pDstScan, pMapX, pMapY );
|
|
}
|
|
else if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount > 8 )
|
|
{
|
|
ImplPALToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
|
|
pSrcScan, pDstScan, pMapX, pMapY );
|
|
}
|
|
else if( rSrcBuffer.mnBitCount > 8 && pDstBuffer->mnBitCount > 8 )
|
|
{
|
|
ImplTCToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
|
|
pSrcScan, pDstScan, pMapX, pMapY );
|
|
}
|
|
else
|
|
{
|
|
ImplTCToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
|
|
pSrcScan, pDstScan, pMapX, pMapY );
|
|
}
|
|
|
|
// cleanup
|
|
delete[] pSrcScan;
|
|
delete[] pDstScan;
|
|
delete[] pMapX;
|
|
delete[] pMapY;
|
|
|
|
return pDstBuffer;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|