1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/log.hxx>
21 #include <tools/helpers.hxx>
23 #include <vcl/bitmapex.hxx>
24 #include <vcl/BitmapWriteAccess.hxx>
26 #include <bitmap/BitmapFastScaleFilter.hxx>
28 BitmapEx
BitmapFastScaleFilter::execute(BitmapEx
const& rBitmapEx
) const
30 SAL_INFO("vcl.gdi", "BitmapFastScaleFilter::execute()");
32 Bitmap
aBitmap(rBitmapEx
.GetBitmap());
34 const Size
aSizePix(aBitmap
.GetSizePixel());
35 const sal_Int32 nNewWidth
= basegfx::fround(aSizePix
.Width() * mfScaleX
);
36 const sal_Int32 nNewHeight
= basegfx::fround(aSizePix
.Height() * mfScaleY
);
39 SAL_INFO("vcl.gdi", "New width: " << nNewWidth
<< "\nNew height: " << nNewHeight
);
41 if (nNewWidth
> 0 && nNewHeight
> 0)
43 BitmapScopedReadAccess
pReadAcc(aBitmap
);
47 Bitmap
aNewBmp(Size(nNewWidth
, nNewHeight
), aBitmap
.getPixelFormat(),
48 &pReadAcc
->GetPalette());
49 BitmapScopedWriteAccess
pWriteAcc(aNewBmp
);
53 const sal_Int32 nScanlineSize
= pWriteAcc
->GetScanlineSize();
54 const sal_Int32 nNewHeight1
= nNewHeight
- 1;
56 if (nNewWidth
&& nNewHeight
)
58 const double nWidth
= pReadAcc
->Width();
59 const double nHeight
= pReadAcc
->Height();
60 std::unique_ptr
<sal_Int32
[]> pLutX(new sal_Int32
[nNewWidth
]);
61 std::unique_ptr
<sal_Int32
[]> pLutY(new sal_Int32
[nNewHeight
]);
63 for (sal_Int32 nX
= 0; nX
< nNewWidth
; nX
++)
65 pLutX
[nX
] = sal_Int32(nX
* nWidth
/ nNewWidth
);
68 for (sal_Int32 nY
= 0; nY
< nNewHeight
; nY
++)
70 pLutY
[nY
] = sal_Int32(nY
* nHeight
/ nNewHeight
);
74 while (nActY
< nNewHeight
)
76 sal_Int32 nMapY
= pLutY
[nActY
];
77 Scanline pScanline
= pWriteAcc
->GetScanline(nActY
);
78 Scanline pScanlineRead
= pReadAcc
->GetScanline(nMapY
);
80 for (sal_Int32 nX
= 0; nX
< nNewWidth
; nX
++)
82 pWriteAcc
->SetPixelOnData(
84 pReadAcc
->GetPixelFromData(pScanlineRead
, pLutX
[nX
]));
87 while ((nActY
< nNewHeight1
) && (pLutY
[nActY
+ 1] == nMapY
))
89 memcpy(pWriteAcc
->GetScanline(nActY
+ 1), pWriteAcc
->GetScanline(nActY
),
105 aBitmap
.ReassignWithSize(aNewBmp
);
106 SAL_INFO("vcl.gdi", "Bitmap size: " << aBitmap
.GetSizePixel());
110 SAL_WARN("vcl.gdi", "no resize");
115 AlphaMask
aMask(rBitmapEx
.GetAlphaMask());
117 if (bRet
&& !aMask
.IsEmpty())
118 bRet
= aMask
.Scale(Size(nNewWidth
, nNewHeight
), BmpScaleFlag::Fast
);
120 SAL_WARN_IF(!aMask
.IsEmpty() && aBitmap
.GetSizePixel() != aMask
.GetSizePixel(), "vcl",
121 "BitmapEx::Scale(): size mismatch for bitmap and alpha mask.");
124 return BitmapEx(aBitmap
, aMask
);
129 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */