SkBitmapScaler.h revision f3b1eb4ea262e48c93db8f0975e16341596cd8ec
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright 2013 Google Inc.
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * found in the LICENSE file.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef SkBitmapScaler_DEFINED
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define SkBitmapScaler_DEFINED
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "SkBitmap.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "SkConvolver.h"
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** \class SkBitmapScaler
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    Provides the interface for high quality image resampling.
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SK_API SkBitmapScaler {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public:
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    enum ResizeMethod {
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // Quality Methods
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        //
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // Those enumeration values express a desired quality/speed tradeoff.
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // They are translated into an algorithm-specific method that depends
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // on the capabilities (CPU, GPU) of the underlying platform.
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // It is possible for all three methods to be mapped to the same
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // algorithm on a given platform.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Good quality resizing. Fastest resizing with acceptable visual quality.
31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        // This is typically intended for use during interactive layouts
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // where slower platforms may want to trade image quality for large
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // increase in resizing performance.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        //
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // For example the resizing implementation may devolve to linear
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // filtering if this enables GPU acceleration to be used.
37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        //
38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        // Note that the underlying resizing method may be determined
39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        // on the fly based on the parameters for a given resize call.
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // For example an implementation using a GPU-based linear filter
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // in the common case may still use a higher-quality software-based
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // filter in cases where using the GPU would actually be slower - due
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        // to too much latency - or impossible - due to image format or size
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        // constraints.
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        RESIZE_GOOD,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Medium quality resizing. Close to high quality resizing (better
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // than linear interpolation) with potentially some quality being
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // traded-off for additional speed compared to RESIZE_BEST.
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        //
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // This is intended, for example, for generation of large thumbnails
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // (hundreds of pixels in each dimension) from large sources, where
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // a linear filter would produce too many artifacts but where
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // a RESIZE_HIGH might be too costly time-wise.
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_BETTER,
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // High quality resizing. The algorithm is picked to favor image quality.
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_BEST,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        //
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Algorithm-specific enumerations
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        //
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // Box filter. This is a weighted average of all of the pixels touching
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // the destination pixel. For enlargement, this is nearest neighbor.
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        //
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // You probably don't want this, it is here for testing since it is easy to
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // compute. Use RESIZE_LANCZOS3 instead.
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_BOX,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_TRIANGLE,
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_LANCZOS3,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_HAMMING,
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_MITCHELL,
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        // enum aliases for first and last methods by algorithm or by quality.
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_FIRST_QUALITY_METHOD = RESIZE_GOOD,
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_LAST_QUALITY_METHOD = RESIZE_BEST,
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_FIRST_ALGORITHM_METHOD = RESIZE_BOX,
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        RESIZE_LAST_ALGORITHM_METHOD = RESIZE_MITCHELL,
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    };
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Resizes the given source bitmap using the specified resize method, so that
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // the entire image is (dest_size) big. The dest_subset is the rectangle in
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // this destination image that should actually be returned.
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    //
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // The output image will be (dest_subset.width(), dest_subset.height()). This
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // will save work if you do not need the entire bitmap.
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    //
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The destination subset must be smaller than the destination image.
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    static bool Resize(SkBitmap* result,
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const SkBitmap& source,
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       ResizeMethod method,
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       int dest_width, int dest_height,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const SkIRect& dest_subset,
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const SkConvolutionProcs&,
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       SkBitmap::Allocator* allocator = NULL);
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Alternate version for resizing and returning the entire bitmap rather than
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // a subset.
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    static bool Resize(SkBitmap* result,
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const SkBitmap& source,
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       ResizeMethod method,
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       int dest_width, int dest_height,
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       const SkConvolutionProcs&,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       SkBitmap::Allocator* allocator = NULL);
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)