canvas/source/vcl/canvasbitmaphelper.cxx                       |    2 
 canvas/source/vcl/canvashelper.cxx                             |    2 
 cui/source/dialogs/cuigrfflt.cxx                               |    2 
 filter/source/graphicfilter/eps/eps.cxx                        |    2 
 framework/source/fwe/classes/addonsoptions.cxx                 |    6 -
 framework/source/uielement/imagebuttontoolbarcontroller.cxx    |    2 
 sd/source/ui/dlg/dlgass.cxx                                    |    2 
 sd/source/ui/presenter/SlideRenderer.cxx                       |    2 
 sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx            |    2 
 sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx |    2 
 sd/source/ui/tools/PreviewRenderer.cxx                         |    2 
 sfx2/source/toolbox/tbxitem.cxx                                |    2 
 svx/source/gallery2/galobj.cxx                                 |    2 
 toolkit/source/awt/vclxmenu.cxx                                |    2 
 vcl/inc/vcl/bitmap.hxx                                         |    4 
 vcl/inc/vcl/bitmapex.hxx                                       |    4 
 vcl/source/gdi/bitmap3.cxx                                     |   60 
+++++++---
 vcl/source/gdi/bitmapex.cxx                                    |    2 
 vcl/source/gdi/pdfwriter_impl2.cxx                             |    2 
 vcl/source/helper/canvasbitmap.cxx                             |    2 
 20 files changed, 65 insertions(+), 41 deletions(-)

New commits:
commit 94f87ad9b1e50bb4458eb0b3e87dd053b636094f
Author: Jan Holesovsky <ke...@suse.cz>
Date:   Mon Jun 4 15:02:45 2012 +0200

    Let's be bold, and default to the nice method when scaling.
    
    [ie. use BMP_SCALE_FAST only where explicitly asked for.]
    
    Change-Id: Ia5eccc786262216a803b989b073ffd9c1ed78377

diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index 14aae27..8b11318 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -538,7 +538,7 @@ public:
         @return sal_True, if the operation was completed successfully.
      */
     sal_Bool                    Scale( const Size& rNewSize,
-                                   sal_uLong nScaleFlag = BMP_SCALE_FAST );
+                                   sal_uLong nScaleFlag = BMP_SCALE_LANCZOS );
 
     /** Scale the bitmap
 
@@ -551,7 +551,7 @@ public:
         @return sal_True, if the operation was completed successfully.
      */
     sal_Bool                    Scale( const double& rScaleX, const double& 
rScaleY,
-                                   sal_uLong nScaleFlag = BMP_SCALE_FAST );
+                                   sal_uLong nScaleFlag = BMP_SCALE_LANCZOS );
 
     /** Rotate bitmap by the specified angle
 
diff --git a/vcl/inc/vcl/bitmapex.hxx b/vcl/inc/vcl/bitmapex.hxx
index c9e4627..f1f46d3 100644
--- a/vcl/inc/vcl/bitmapex.hxx
+++ b/vcl/inc/vcl/bitmapex.hxx
@@ -254,7 +254,7 @@ public:
 
         @return sal_True, if the operation was completed successfully.
      */
-    sal_Bool                Scale( const Size& rNewSize, sal_uLong nScaleFlag 
= BMP_SCALE_FAST );
+    sal_Bool                Scale( const Size& rNewSize, sal_uLong nScaleFlag 
= BMP_SCALE_LANCZOS );
 
     /** Scale the bitmap
 
@@ -266,7 +266,7 @@ public:
 
         @return sal_True, if the operation was completed successfully.
      */
-    sal_Bool                Scale( const double& rScaleX, const double& 
rScaleY, sal_uLong nScaleFlag = BMP_SCALE_FAST );
+    sal_Bool                Scale( const double& rScaleX, const double& 
rScaleY, sal_uLong nScaleFlag = BMP_SCALE_LANCZOS );
 
     /** Rotate bitmap by the specified angle
 
commit 9afb6e1e38c362a768e8e981f7b03cf8bcaf22cf
Author: Jan Holesovsky <ke...@suse.cz>
Date:   Mon Jun 4 14:47:18 2012 +0200

    Use BMP_SCALE_LANCZOS instead of BMP_SCALE_INTERPOLATE.
    
    Where we explicitly ask for better quality, use BMP_SCALE_LANCZOS, instead 
of
    BMP_SCALE_INTERPOLATE.
    
    Change-Id: I28ddf3290204532a8660e09ee9ab0949b6ce1c73

diff --git a/canvas/source/vcl/canvasbitmaphelper.cxx 
b/canvas/source/vcl/canvasbitmaphelper.cxx
index 3032c18..cceaf7b 100644
--- a/canvas/source/vcl/canvasbitmaphelper.cxx
+++ b/canvas/source/vcl/canvasbitmaphelper.cxx
@@ -129,7 +129,7 @@ namespace vclcanvas
         BitmapEx aRes( mpBackBuffer->getBitmapReference() );
 
         aRes.Scale( ::vcl::unotools::sizeFromRealSize2D(newSize),
-                     beFast ? BMP_SCALE_FAST : BMP_SCALE_INTERPOLATE );
+                     beFast ? BMP_SCALE_FAST : BMP_SCALE_LANCZOS );
 
         return uno::Reference< rendering::XBitmap >(
             new CanvasBitmap( aRes, *mpDevice, mpOutDevReference ) );
diff --git a/canvas/source/vcl/canvashelper.cxx 
b/canvas/source/vcl/canvashelper.cxx
index 83f3ccf..ba36f40 100644
--- a/canvas/source/vcl/canvashelper.cxx
+++ b/canvas/source/vcl/canvashelper.cxx
@@ -927,7 +927,7 @@ namespace vclcanvas
         Bitmap aBitmap( rOutDev.GetBitmap(aEmptyPoint, aBmpSize) );
 
         aBitmap.Scale( ::vcl::unotools::sizeFromRealSize2D(newSize),
-                       beFast ? BMP_SCALE_FAST : BMP_SCALE_INTERPOLATE );
+                       beFast ? BMP_SCALE_FAST : BMP_SCALE_LANCZOS );
 
         return uno::Reference< rendering::XBitmap >(
             new CanvasBitmap( aBitmap, *mpDevice, mpOutDev ) );
diff --git a/cui/source/dialogs/cuigrfflt.cxx b/cui/source/dialogs/cuigrfflt.cxx
index 21ccf63..c1b3ad4 100644
--- a/cui/source/dialogs/cuigrfflt.cxx
+++ b/cui/source/dialogs/cuigrfflt.cxx
@@ -126,7 +126,7 @@ GraphicFilterDialog::GraphicFilterDialog( Window* pParent, 
const ResId& rResId,
         {
             BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
 
-            if( aBmpEx.Scale( aGrfSize, BMP_SCALE_INTERPOLATE ) )
+            if( aBmpEx.Scale( aGrfSize, BMP_SCALE_LANCZOS ) )
                 maGraphic = aBmpEx;
         }
     }
diff --git a/filter/source/graphicfilter/eps/eps.cxx 
b/filter/source/graphicfilter/eps/eps.cxx
index 8a1410f..9350687 100644
--- a/filter/source/graphicfilter/eps/eps.cxx
+++ b/filter/source/graphicfilter/eps/eps.cxx
@@ -499,7 +499,7 @@ void PSWriter::ImplWriteProlog( const Graphic* pPreview )
     {
         Size aSizeBitmap( ( aSizePoint.Width() + 7 ) & ~7, aSizePoint.Height() 
);
         Bitmap aTmpBitmap( pPreview->GetBitmap() );
-        aTmpBitmap.Scale( aSizeBitmap, BMP_SCALE_INTERPOLATE );
+        aTmpBitmap.Scale( aSizeBitmap, BMP_SCALE_LANCZOS );
         aTmpBitmap.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
         BitmapReadAccess* pAcc = aTmpBitmap.AcquireReadAccess();
         if ( pAcc )
diff --git a/framework/source/fwe/classes/addonsoptions.cxx 
b/framework/source/fwe/classes/addonsoptions.cxx
index d1e488f..844f109 100644
--- a/framework/source/fwe/classes/addonsoptions.cxx
+++ b/framework/source/fwe/classes/addonsoptions.cxx
@@ -1358,13 +1358,13 @@ void AddonsOptions_Impl::ReadImageFromURL( ImageSize 
nImageSize, const ::rtl::OU
             if ( aBmpSize != aNoScaleSize )
             {
                 BitmapEx aNoScaleBmp( aBitmapEx );
-                aNoScaleBmp.Scale( aNoScaleSize, BMP_SCALE_INTERPOLATE );
+                aNoScaleBmp.Scale( aNoScaleSize, BMP_SCALE_LANCZOS );
             }
             else
                 aImageNoScale = Image( aBitmapEx );
 
             if ( aBmpSize != aSize )
-                aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
+                aBitmapEx.Scale( aSize, BMP_SCALE_LANCZOS );
 
             aImage = Image( aBitmapEx );
         }
@@ -1512,7 +1512,7 @@ sal_Bool AddonsOptions_Impl::CreateImageFromSequence( 
Image& rImage, sal_Bool bB
 
         // Scale bitmap to fit the correct size for the menu/toolbar. Use best 
quality
         if ( aBitmapEx.GetSizePixel() != aSize )
-            aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
+            aBitmapEx.Scale( aSize, BMP_SCALE_LANCZOS );
 
         if( !aBitmapEx.IsTransparent() )
         {
diff --git a/framework/source/uielement/imagebuttontoolbarcontroller.cxx 
b/framework/source/uielement/imagebuttontoolbarcontroller.cxx
index 55f82dc..a1a494a 100644
--- a/framework/source/uielement/imagebuttontoolbarcontroller.cxx
+++ b/framework/source/uielement/imagebuttontoolbarcontroller.cxx
@@ -214,7 +214,7 @@ sal_Bool ImageButtonToolbarController::ReadImageFromURL( 
sal_Bool bBigImage, con
         {
             ::Size aNoScaleSize( aBmpSize.Width(), aSize.Height() );
             if ( aBmpSize != aNoScaleSize )
-                aBitmapEx.Scale( aNoScaleSize, BMP_SCALE_INTERPOLATE );
+                aBitmapEx.Scale( aNoScaleSize, BMP_SCALE_LANCZOS );
             aImage = Image( aBitmapEx );
             return sal_True;
         }
diff --git a/sd/source/ui/dlg/dlgass.cxx b/sd/source/ui/dlg/dlgass.cxx
index cd61216..8d0009c 100644
--- a/sd/source/ui/dlg/dlgass.cxx
+++ b/sd/source/ui/dlg/dlgass.cxx
@@ -92,7 +92,7 @@ void InterpolateFixedBitmap( FixedBitmap * pBitmap )
 {
     Bitmap aBmp( pBitmap->GetBitmap() );
     Size aSize = pBitmap->GetSizePixel();
-    aBmp.Scale( aSize, BMP_SCALE_INTERPOLATE );
+    aBmp.Scale( aSize, BMP_SCALE_LANCZOS );
     pBitmap->SetBitmap( aBmp );
 }
 
diff --git a/sd/source/ui/presenter/SlideRenderer.cxx 
b/sd/source/ui/presenter/SlideRenderer.cxx
index b7ce080..5c3b4ba 100644
--- a/sd/source/ui/presenter/SlideRenderer.cxx
+++ b/sd/source/ui/presenter/SlideRenderer.cxx
@@ -233,7 +233,7 @@ BitmapEx SlideRenderer::CreatePreview (
         BitmapEx aScaledPreview = aPreview.GetBitmapEx();
         aScaledPreview.Scale(
             Size(aPreviewSize.Width,aPreviewSize.Height),
-            BMP_SCALE_INTERPOLATE);
+            BMP_SCALE_LANCZOS);
         return aScaledPreview;
     }
 }
diff --git a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx 
b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx
index 871713c..503498c 100644
--- a/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx
+++ b/sd/source/ui/slidesorter/cache/SlsBitmapFactory.cxx
@@ -87,7 +87,7 @@ Bitmap BitmapFactory::CreateBitmap (
         false).GetBitmapEx().GetBitmap());
     if (bDoSuperSampling && gbAllowSuperSampling)
     {
-        aPreview.Scale(rPixelSize, BMP_SCALE_INTERPOLATE);
+        aPreview.Scale(rPixelSize, BMP_SCALE_LANCZOS);
     }
 
     return aPreview;
diff --git a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx 
b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx
index 6bde044..464f5cd 100644
--- a/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx
+++ b/sd/source/ui/slidesorter/view/SlsInsertionIndicatorOverlay.cxx
@@ -216,7 +216,7 @@ Point InsertionIndicatorOverlay::PaintRepresentatives (
         const Size aSuperSampleSize(
             aPreviewSize.Width()*gnSuperScaleFactor,
             aPreviewSize.Height()*gnSuperScaleFactor);
-        aPreview.Scale(aPreviewSize, BMP_SCALE_INTERPOLATE);
+        aPreview.Scale(aPreviewSize, BMP_SCALE_LANCZOS);
         rContent.DrawBitmapEx(aPageOffset, aPreview);
 
         // When the page is marked as excluded from the slide show then
diff --git a/sd/source/ui/tools/PreviewRenderer.cxx 
b/sd/source/ui/tools/PreviewRenderer.cxx
index fb81193..4b831c2 100644
--- a/sd/source/ui/tools/PreviewRenderer.cxx
+++ b/sd/source/ui/tools/PreviewRenderer.cxx
@@ -512,7 +512,7 @@ Image PreviewRenderer::ScaleBitmap (
 
         // Paint the bitmap scaled to the desired width.
         BitmapEx aScaledBitmap (rBitmapEx.GetBitmap());
-        aScaledBitmap.Scale (aPreviewSize, BMP_SCALE_INTERPOLATE);
+        aScaledBitmap.Scale (aPreviewSize, BMP_SCALE_LANCZOS);
         mpPreviewDevice->DrawBitmap (
             Point(1,1),
             aPreviewSize,
diff --git a/sfx2/source/toolbox/tbxitem.cxx b/sfx2/source/toolbox/tbxitem.cxx
index d288eef..d220e71 100644
--- a/sfx2/source/toolbox/tbxitem.cxx
+++ b/sfx2/source/toolbox/tbxitem.cxx
@@ -1550,7 +1550,7 @@ void SfxAppToolBoxControl_Impl::SetImage( const String 
&rURL )
     if ( bBig && aImage.GetSizePixel() != aBigSize )
     {
         BitmapEx aScaleBmpEx( aImage.GetBitmapEx() );
-        aScaleBmpEx.Scale( aBigSize, BMP_SCALE_INTERPOLATE );
+        aScaleBmpEx.Scale( aBigSize, BMP_SCALE_LANCZOS );
         GetToolBox().SetItemImage( GetId(), Image( aScaleBmpEx ) );
     }
     else
diff --git a/svx/source/gallery2/galobj.cxx b/svx/source/gallery2/galobj.cxx
index b2ca476..a05616f 100644
--- a/svx/source/gallery2/galobj.cxx
+++ b/svx/source/gallery2/galobj.cxx
@@ -111,7 +111,7 @@ sal_Bool SgaObject::CreateThumb( const Graphic& rGraphic )
                                       Max( (long) (fFactor < 1. ? S_THUMB : 
S_THUMB / fFactor), 8L ) );
 
                 if( aThumbBmp.Scale( (double) aNewSize.Width() / 
aBmpSize.Width(),
-                                     (double) aNewSize.Height() / 
aBmpSize.Height(), BMP_SCALE_INTERPOLATE ) )
+                                     (double) aNewSize.Height() / 
aBmpSize.Height(), BMP_SCALE_LANCZOS ) )
                 {
                     aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
                     bRet = sal_True;
diff --git a/toolkit/source/awt/vclxmenu.cxx b/toolkit/source/awt/vclxmenu.cxx
index d45d5dc..c629d67 100644
--- a/toolkit/source/awt/vclxmenu.cxx
+++ b/toolkit/source/awt/vclxmenu.cxx
@@ -680,7 +680,7 @@ namespace
 
                 sal_Bool bModified( sal_False );
                 BitmapEx aBitmapEx = aImage.GetBitmapEx();
-                bModified = aBitmapEx.Scale( aNewSize, BMP_SCALE_INTERPOLATE );
+                bModified = aBitmapEx.Scale( aNewSize, BMP_SCALE_LANCZOS );
 
                 if ( bModified )
                     aImage = Image( aBitmapEx );
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index f4e8e5b..72c91e4 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -754,7 +754,7 @@ BitmapEx BitmapEx:: AutoScaleBitmap(BitmapEx & aBitmap, 
const long aStandardSize
         }
 
         aScaledSize = Size( imgNewWidth, imgNewHeight );
-        aRet.Scale( aScaledSize, BMP_SCALE_INTERPOLATE );
+        aRet.Scale( aScaledSize, BMP_SCALE_LANCZOS );
     }
     else
     {
diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx 
b/vcl/source/gdi/pdfwriter_impl2.cxx
index d94281b..3fc7fac 100644
--- a/vcl/source/gdi/pdfwriter_impl2.cxx
+++ b/vcl/source/gdi/pdfwriter_impl2.cxx
@@ -139,7 +139,7 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& 
i_rPoint, const Size& i_rSiz
                     aNewBmpSize.Height() = FRound( fMaxPixelX / fBmpWH);
                 }
                 if( aNewBmpSize.Width() && aNewBmpSize.Height() )
-                    aBitmapEx.Scale( aNewBmpSize, BMP_SCALE_INTERPOLATE );
+                    aBitmapEx.Scale( aNewBmpSize, BMP_SCALE_LANCZOS );
                 else
                     aBitmapEx.SetEmpty();
             }
diff --git a/vcl/source/helper/canvasbitmap.cxx 
b/vcl/source/helper/canvasbitmap.cxx
index a7aebc2..854dea4 100644
--- a/vcl/source/helper/canvasbitmap.cxx
+++ b/vcl/source/helper/canvasbitmap.cxx
@@ -460,7 +460,7 @@ uno::Reference< rendering::XBitmap > SAL_CALL 
VclCanvasBitmap::getScaledBitmap(
     SolarMutexGuard aGuard;
 
     BitmapEx aNewBmp( m_aBitmap );
-    aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BMP_SCALE_FAST : 
BMP_SCALE_INTERPOLATE );
+    aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BMP_SCALE_FAST : 
BMP_SCALE_LANCZOS );
     return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) 
);
 }
 
commit 6428bef05a24f22705c96f84321c1df0066c6ecb
Author: Tomaž Vajngerl <qui...@gmail.com>
Date:   Tue Jun 5 07:17:08 2012 +0200

    Lanczos resampling - mirror image on edges and fix image upscaling
    
    When upscaling the bitmap at edges use the mirror of the image to
    calculate contributions. Fix calculation of contributions when
    upscaling a bitmap.
    
    Change-Id: I9d3aedaed95aaab60ee5ea9cdd65e4dd8624428f

diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 2d35c6a..094dcd3 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -2221,7 +2221,8 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, 
const double& rScaleY )
 
     // Do horizontal filtering
     double aScale = nNewWidth / (double) nWidth;
-    double aScaledRadius = aSupport / aScale;
+    double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
+
     int aNumberOfContributions  = (int) ( 2 * aScaledRadius + 1 );
 
     double* pWeights = new double[ nNewWidth*aNumberOfContributions ];
@@ -2248,7 +2249,8 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, 
const double& rScaleY )
 
     // Do vertical filtering
     aScale = nNewHeight / (double) nHeight;
-    aScaledRadius = aSupport / aScale;
+    aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
+
     aNumberOfContributions  = (int) ( 2 * aScaledRadius + 1 );
 
     pWeights = new double[ nNewHeight*aNumberOfContributions ];
@@ -2281,35 +2283,57 @@ void Bitmap::ImplCalculateContributions( const int 
aSourceSize, const int aDesti
                                          int* pCount )
 {
     const double aScale = aDestinationSize / (double) aSourceSize;
-    const double aScaledRadius = aSupport / aScale;
-    const double aFilterFactor = aScale;
+    const double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : 
aSupport;
+    const double aFilterFactor = (aScale <= 1.0) ? aScale : 1.0;
 
     double aWeight, aCenter;
     int aIndex, aLeft, aRight;
+    int aPixelIndex, aCurrentCount;
 
-    for ( int i = 0; i < aDestinationSize; i++ ) {
+    for ( int i = 0; i < aDestinationSize; i++ )
+    {
         aIndex = i * aNumberOfContributions;
-        pCount[i] = 0;
-        aCenter = ((double)i) / aScale;
+        aCurrentCount = 0;
+        aCenter = i / aScale;
 
-        aLeft = (int)((aCenter + 0.5) - aScaledRadius);
-        aRight = (int)(aLeft + 2 * aScaledRadius);
+        aLeft = (int) ((aCenter + 0.5) - aScaledRadius );
+        aRight = (int) ( aLeft + 2 * aScaledRadius );
+
+        for ( int j = aLeft; j <= aRight; j++ )
+        {
+            aWeight = ImplLanczosKernel( (aCenter - j) * aFilterFactor, 
aSupport );
 
-        for ( int j = aLeft; j<= aRight; j++ ) {
-            if ( j < 0 || j >= aSourceSize ) {
+            if (aWeight == 0.0)
+            {
                 continue;
             }
 
-            aWeight = ImplLanczosKernel( (aCenter - j) * aFilterFactor, 
aSupport );
-            if (aWeight == 0.0) {
-                continue;
+            // Mirror edges
+            if (j < 0)
+            {
+                aPixelIndex = -j;
             }
+            else if ( j >= aSourceSize )
+            {
+                aPixelIndex = (aSourceSize - j) + aSourceSize - 1;
+            }
+            else
+            {
+                aPixelIndex = j;
+            }
+
+            // Edge case for small bitmaps
+            if ( aPixelIndex < 0 || aPixelIndex >= aSourceSize )
+            {
+                aWeight = 0.0;
+            }
+
+            pWeights[ aIndex + aCurrentCount ] = aWeight;
+            pPixels[ aIndex + aCurrentCount ] = aPixelIndex;
 
-            int currentCount = pCount[ i ];
-            pWeights[ aIndex + currentCount ] = aWeight;
-            pPixels[ aIndex + currentCount ] = j;
-            pCount[ i ]++;
+            aCurrentCount++;
         }
+        pCount[ i ] = aCurrentCount;
     }
 }
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to