View | Details | Raw Unified | Return to issue 121233
Collapse All | Expand All

(-)vcl/source/gdi/bitmap3.cxx (-4 / +176 lines)
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 )
(-)vcl/inc/vcl/bitmap.hxx (-2 / +103 lines)
Lines 42-49 Link Here
42
42
43
#define BMP_SCALE_NONE				0x00000000UL
43
#define BMP_SCALE_NONE				0x00000000UL
44
#define BMP_SCALE_FAST				0x00000001UL
44
#define BMP_SCALE_FAST				0x00000001UL
45
#define BMP_SCALE_INTERPOLATE		0x00000002UL
45
#define BMP_SCALE_INTERPOLATE			0x00000002UL
46
#define BMP_SCALE_LANCZOS				0x00000003UL
47
#define BMP_SCALE_BICUBIC           		0x00000004UL
48
#define BMP_SCALE_BILINEAR          		0x00000005UL
49
#define BMP_SCALE_BOX               		0x00000006UL
46
50
51
47
// -----------------------------------------------------------------------------
52
// -----------------------------------------------------------------------------
48
53
49
#define BMP_DITHER_NONE				0x00000000UL
54
#define BMP_DITHER_NONE				0x00000000UL
Lines 159-165 Link Here
159
	friend class Animation;
164
	friend class Animation;
160
165
161
private:
166
private:
162
	BmpFilter	meFilter;
167
	BmpFilter		meFilter;
163
	sal_uLong		mnProgressStart;
168
	sal_uLong		mnProgressStart;
164
	sal_uLong		mnProgressEnd;
169
	sal_uLong		mnProgressEnd;
165
170
Lines 214-219 Link Here
214
		}
219
		}
215
};
220
};
216
221
222
// --------------------
223
// Resample Kernels
224
// --------------------
225
226
class Kernel
227
{
228
229
public:
230
    Kernel () {}
231
    virtual ~Kernel() {}
232
233
    virtual double GetWidth() = 0;
234
    virtual double Calculate( double x ) = 0;
235
};
236
237
class Lanczos3Kernel : public Kernel
238
{
239
240
public:
241
    virtual double GetWidth() { return 3.0; }
242
    virtual double Calculate (double x)
243
    {
244
        return (-3.0 <= x && x < 3.0) ? SincFilter(x) * SincFilter( x / 3.0 ) : 0.0;
245
    }
246
247
    inline double SincFilter(double x)
248
    {
249
        if (x == 0.0)
250
        {
251
            return 1.0;
252
        }
253
        x = x * M_PI;
254
        return sin(x) / x;
255
    }
256
};
257
258
class BicubicKernel : public Kernel {
259
    virtual double GetWidth() { return 2.0; }
260
    virtual double Calculate (double x)
261
    {
262
        if (x < 0.0)
263
        {
264
            x = -x;
265
        }
266
267
        if (x <= 1.0)
268
        {
269
            return (1.5 * x - 2.5) * x * x + 1.0;
270
        }
271
        else if (x < 2.0)
272
        {
273
            return ((-0.5 * x + 2.5) * x - 4) * x + 2;
274
        }
275
        return 0.0;
276
    }
277
};
278
279
class BilinearKernel : public Kernel {
280
    virtual double GetWidth() { return 1.0; }
281
    virtual double Calculate (double x)
282
    {
283
        if (x < 0.0)
284
        {
285
            x = -x;
286
        }
287
        if (x < 1.0)
288
        {
289
            return 1.0-x;
290
        }
291
        return 0.0;
292
    }
293
};
294
295
class BoxKernel : public Kernel {
296
    virtual double GetWidth() { return 0.5; }
297
    virtual double Calculate (double x)
298
    {
299
        if (-0.5 <= x && x < 0.5)
300
            return 1.0;
301
        return 0.0;
302
    }
303
};
304
217
// ----------
305
// ----------
218
// - Bitmap -
306
// - Bitmap -
219
// ----------
307
// ----------
Lines 279-284 Link Here
279
367
280
    SAL_DLLPRIVATE sal_Bool                 ImplScaleFast( const double& rScaleX, const double& rScaleY );
368
    SAL_DLLPRIVATE sal_Bool                 ImplScaleFast( const double& rScaleX, const double& rScaleY );
281
    SAL_DLLPRIVATE sal_Bool                 ImplScaleInterpolate( const double& rScaleX, const double& rScaleY );
369
    SAL_DLLPRIVATE sal_Bool                 ImplScaleInterpolate( const double& rScaleX, const double& rScaleY );
370
    SAL_DLLPRIVATE bool                 ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel);
371
    SAL_DLLPRIVATE bool                 ImplTransformAveraging( const double& rScaleX, const double& rScaleY,
372
                                                const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor );
373
    SAL_DLLPRIVATE bool                 ImplTransformBilinearFiltering( const double& rScaleX, const double& rScaleY,
374
                                                const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor );
375
376
    SAL_DLLPRIVATE static void          ImplCalculateContributions( const int aSourceSize, const int aDestinationSize,
377
                                                int& aNumberOfContributions, double*& pWeights, int*& pPixels, int*& pCount,
378
                                                Kernel& aKernel );
379
380
    SAL_DLLPRIVATE bool                 ImplConvolutionPass( Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc,
381
                                                int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount );
382
282
    SAL_DLLPRIVATE sal_Bool                 ImplMakeMono( sal_uInt8 cThreshold );
383
    SAL_DLLPRIVATE sal_Bool                 ImplMakeMono( sal_uInt8 cThreshold );
283
    SAL_DLLPRIVATE sal_Bool                 ImplMakeMonoDither();
384
    SAL_DLLPRIVATE sal_Bool                 ImplMakeMonoDither();
284
    SAL_DLLPRIVATE sal_Bool                 ImplMakeGreyscales( sal_uInt16 nGreyscales );
385
    SAL_DLLPRIVATE sal_Bool                 ImplMakeGreyscales( sal_uInt16 nGreyscales );

Return to issue 121233