Lines 34-39
Link Here
|
34 |
#include <impoct.hxx> |
34 |
#include <impoct.hxx> |
35 |
#include <impvect.hxx> |
35 |
#include <impvect.hxx> |
36 |
|
36 |
|
|
|
37 |
#include <math.h> |
38 |
|
37 |
// ----------- |
39 |
// ----------- |
38 |
// - Defines - |
40 |
// - Defines - |
39 |
// ----------- |
41 |
// ----------- |
Lines 907-916
Link Here
|
907 |
|
909 |
|
908 |
if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) ) |
910 |
if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) ) |
909 |
{ |
911 |
{ |
910 |
if( BMP_SCALE_FAST == nScaleFlag ) |
912 |
if( BMP_SCALE_FAST == nScaleFlag ) |
911 |
bRet = ImplScaleFast( rScaleX, rScaleY ); |
913 |
bRet = ImplScaleFast( rScaleX, rScaleY ); |
912 |
else if( BMP_SCALE_INTERPOLATE == nScaleFlag ) |
914 |
else if( BMP_SCALE_INTERPOLATE == nScaleFlag ) |
913 |
bRet = ImplScaleInterpolate( rScaleX, rScaleY ); |
915 |
bRet = ImplScaleInterpolate( rScaleX, rScaleY ); |
|
|
916 |
else if( BMP_SCALE_LANCZOS == nScaleFlag ) |
917 |
{ |
918 |
Lanczos3Kernel kernel; |
919 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel); |
920 |
} |
921 |
else if( BMP_SCALE_BICUBIC == nScaleFlag ) |
922 |
{ |
923 |
BicubicKernel kernel; |
924 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel ); |
925 |
} |
926 |
else if( BMP_SCALE_BILINEAR == nScaleFlag ) |
927 |
{ |
928 |
BilinearKernel kernel; |
929 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel ); |
930 |
} |
931 |
else if( BMP_SCALE_BOX == nScaleFlag ) |
932 |
{ |
933 |
BoxKernel kernel; |
934 |
bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel ); |
935 |
} |
914 |
else |
936 |
else |
915 |
bRet = sal_False; |
937 |
bRet = sal_False; |
916 |
} |
938 |
} |
Lines 1246-1251
Link Here
|
1246 |
return bRet; |
1268 |
return bRet; |
1247 |
} |
1269 |
} |
1248 |
|
1270 |
|
|
|
1271 |
//----------------------------------------------------------------------------------- |
1272 |
bool Bitmap::ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel ) |
1273 |
{ |
1274 |
const long nWidth = GetSizePixel().Width(); |
1275 |
const long nHeight = GetSizePixel().Height(); |
1276 |
const long nNewWidth = FRound( nWidth * rScaleX ); |
1277 |
const long nNewHeight = FRound( nHeight * rScaleY ); |
1278 |
|
1279 |
bool bResult; |
1280 |
BitmapReadAccess* pReadAcc; |
1281 |
Bitmap aNewBitmap; |
1282 |
|
1283 |
int aNumberOfContributions; |
1284 |
double* pWeights; |
1285 |
int* pPixels; |
1286 |
int* pCount; |
1287 |
|
1288 |
// Do horizontal filtering |
1289 |
ImplCalculateContributions( nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel ); |
1290 |
pReadAcc = AcquireReadAccess(); |
1291 |
aNewBitmap = Bitmap( Size( nHeight, nNewWidth ), 24); |
1292 |
bResult = ImplConvolutionPass( aNewBitmap, nNewWidth, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount ); |
1293 |
|
1294 |
ReleaseAccess( pReadAcc ); |
1295 |
delete[] pWeights; |
1296 |
delete[] pCount; |
1297 |
delete[] pPixels; |
1298 |
|
1299 |
if ( !bResult ) |
1300 |
return bResult; |
1301 |
|
1302 |
// Swap Bitmaps |
1303 |
ImplAssignWithSize( aNewBitmap ); |
1304 |
|
1305 |
// Do vertical filtering |
1306 |
ImplCalculateContributions( nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel ); |
1307 |
pReadAcc = AcquireReadAccess(); |
1308 |
aNewBitmap = Bitmap( Size( nNewWidth, nNewHeight ), 24); |
1309 |
bResult = ImplConvolutionPass( aNewBitmap, nNewHeight, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount ); |
1310 |
|
1311 |
ReleaseAccess( pReadAcc ); |
1312 |
delete[] pWeights; |
1313 |
delete[] pCount; |
1314 |
delete[] pPixels; |
1315 |
|
1316 |
if ( !bResult ) |
1317 |
return bResult; |
1318 |
|
1319 |
ImplAssignWithSize( aNewBitmap ); |
1320 |
|
1321 |
return true; |
1322 |
} |
1323 |
|
1324 |
|
1325 |
void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDestinationSize, int& aNumberOfContributions, |
1326 |
double*& pWeights, int*& pPixels, int*& pCount, Kernel& aKernel) |
1327 |
{ |
1328 |
const double aSamplingRadius = aKernel.GetWidth(); |
1329 |
const double aScale = aDestinationSize / (double) aSourceSize; |
1330 |
const double aScaledRadius = (aScale < 1.0) ? aSamplingRadius / aScale : aSamplingRadius; |
1331 |
const double aFilterFactor = (aScale < 1.0) ? aScale : 1.0; |
1332 |
|
1333 |
aNumberOfContributions = (int) ( 2 * ceil(aScaledRadius) + 1 ); |
1334 |
|
1335 |
pWeights = new double[ aDestinationSize*aNumberOfContributions ]; |
1336 |
pPixels = new int[ aDestinationSize*aNumberOfContributions ]; |
1337 |
pCount = new int[ aDestinationSize ]; |
1338 |
|
1339 |
double aWeight, aCenter; |
1340 |
int aIndex, aLeft, aRight; |
1341 |
int aPixelIndex, aCurrentCount; |
1342 |
|
1343 |
for ( int i = 0; i < aDestinationSize; i++ ) |
1344 |
{ |
1345 |
aIndex = i * aNumberOfContributions; |
1346 |
aCurrentCount = 0; |
1347 |
aCenter = i / aScale; |
1348 |
|
1349 |
aLeft = (int) floor(aCenter - aScaledRadius); |
1350 |
aRight = (int) ceil (aCenter + aScaledRadius); |
1351 |
|
1352 |
for ( int j = aLeft; j <= aRight; j++ ) |
1353 |
{ |
1354 |
aWeight = aKernel.Calculate( aFilterFactor * ( aCenter - (double) j ) ); |
1355 |
|
1356 |
// Reduce calculations with ignoring weights of 0.0 |
1357 |
if (fabs(aWeight) < 0.0001) |
1358 |
continue; |
1359 |
|
1360 |
// Handling on edges |
1361 |
aPixelIndex = MinMax( j, 0, aSourceSize - 1); |
1362 |
|
1363 |
pWeights[ aIndex + aCurrentCount ] = aWeight; |
1364 |
pPixels[ aIndex + aCurrentCount ] = aPixelIndex; |
1365 |
|
1366 |
aCurrentCount++; |
1367 |
} |
1368 |
pCount[ i ] = aCurrentCount; |
1369 |
} |
1370 |
} |
1371 |
|
1372 |
bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount) |
1373 |
{ |
1374 |
BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess(); |
1375 |
|
1376 |
if (!pReadAcc || !pWriteAcc) |
1377 |
return false; |
1378 |
|
1379 |
const int nHeight = GetSizePixel().Height(); |
1380 |
|
1381 |
BitmapColor aColor; |
1382 |
double aValueRed, aValueGreen, aValueBlue; |
1383 |
double aSum, aWeight; |
1384 |
int aBaseIndex, aIndex; |
1385 |
|
1386 |
for ( int y = 0; y < nHeight; y++ ) |
1387 |
{ |
1388 |
for ( int x = 0; x < nNewSize; x++ ) |
1389 |
{ |
1390 |
aBaseIndex = x * aNumberOfContributions; |
1391 |
aSum = aValueRed = aValueGreen = aValueBlue = 0.0; |
1392 |
|
1393 |
for ( int j=0; j < pCount[x]; j++ ) |
1394 |
{ |
1395 |
aIndex = aBaseIndex + j; |
1396 |
aSum += aWeight = pWeights[ aIndex ]; |
1397 |
|
1398 |
aColor = pReadAcc->GetPixel( y, pPixels[ aIndex ] ); |
1399 |
if( pReadAcc->HasPalette() ) |
1400 |
aColor = pReadAcc->GetPaletteColor( aColor ); |
1401 |
|
1402 |
aValueRed += aWeight * aColor.GetRed(); |
1403 |
aValueGreen += aWeight * aColor.GetGreen(); |
1404 |
aValueBlue += aWeight * aColor.GetBlue(); |
1405 |
} |
1406 |
|
1407 |
BitmapColor aResultColor( |
1408 |
(sal_uInt8) MinMax( aValueRed / aSum, 0, 255 ), |
1409 |
(sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ), |
1410 |
(sal_uInt8) MinMax( aValueBlue / aSum, 0, 255 ) ); |
1411 |
pWriteAcc->SetPixel( x, y, aResultColor ); |
1412 |
} |
1413 |
} |
1414 |
aNewBitmap.ReleaseAccess( pWriteAcc ); |
1415 |
return true; |
1416 |
} |
1417 |
|
1418 |
|
1419 |
|
1420 |
|
1249 |
// ------------------------------------------------------------------------ |
1421 |
// ------------------------------------------------------------------------ |
1250 |
|
1422 |
|
1251 |
sal_Bool Bitmap::Dither( sal_uLong nDitherFlags ) |
1423 |
sal_Bool Bitmap::Dither( sal_uLong nDitherFlags ) |