    // Copyright (C) 2007  Davis E. King (davis@dlib.net)
    // License: Boost Software License   See LICENSE.txt for the full license.
    #undef DLIB_ASSIGN_IMAGe_ABSTRACT
    #ifdef DLIB_ASSIGN_IMAGe_ABSTRACT

    #include "../pixel.h"

    namespace dlib
    {

    // ----------------------------------------------------------------------------------------

        template <
            typename dest_image_type,
            typename src_image_type
            >
        void assign_image (
            dest_image_type& dest_img,
            const src_image_type& src_img
        );
        /*!
            requires
                - src_image_type == is an implementation of array2d/array2d_kernel_abstract.h or
                  a dlib::matrix or something convertible to a matrix via mat()
                - dest_image_type == is an implementation of array2d/array2d_kernel_abstract.h or
                  is a dlib::matrix.
                - pixel_traits<typename src_image_type::type> is defined
                - pixel_traits<typename dest_image_type::type> is defined
            ensures
                - #dest_img.nc() == src_img.nc()
                - #dest_img.nr() == src_img.nr()
                - for all valid r and c:
                    - performs assign_pixel(#dest_img[r][c],src_img[r][c])
                      (i.e. copies the src image to dest image)
        !*/

    // ----------------------------------------------------------------------------------------

        template <
            typename dest_image_type,
            typename src_image_type
            >
        void assign_image_scaled (
            dest_image_type& dest_img,
            const src_image_type& src_img,
            const double thresh = 4
        );
        /*!
            requires
                - src_image_type == is an implementation of array2d/array2d_kernel_abstract.h or
                  a dlib::matrix or something convertible to a matrix via mat()
                - dest_image_type == is an implementation of array2d/array2d_kernel_abstract.h or
                  is a dlib::matrix.
                - pixel_traits<typename src_image_type::type> is defined
                - pixel_traits<typename dest_image_type::type> is defined
                - thresh > 0
            ensures
                - #dest_img.nc() == src_img.nc()
                - #dest_img.nr() == src_img.nr()
                - if (dest_img's pixels have a wide enough dynamic range to contain all the
                  pixels in src_img.  (Note that dynamic range is determined by the min() and
                  max() pixel_traits properties)) then
                    - performs: assign_image(dest_img, src_img)
                      (i.e. in this case, no scaling is performed.  Just a normal color space
                      conversion and copy )
                - else
                    - #dest_img will be converted to a grayscale image
                    - scales the contents of src_img into the dynamic range of dest_img and then
                      assigns the result into dest_img.  The thresh parameter is used to filter
                      source pixel values which are outliers.  These outliers will saturate
                      at the edge of the destination image's dynamic range.
                    - Specifically, for all valid r and c:
                        - scales get_pixel_intensity(src_img[r][c]) into the dynamic range
                          of the dest_img.  This is done by computing the mean and standard
                          deviation of src_img. Call the mean M and the standard deviation
                          D.  Then the scaling from src_img to dest_img is performed using
                          the following mapping:
                            let SRC_UPPER  = min(M + thresh*D, max(mat(src_img)))
                            let SRC_LOWER  = max(M - thresh*D, min(mat(src_img)))
                            let DEST_UPPER = pixel_traits<dest_image_type::type>::max()
                            let DEST_LOWER = pixel_traits<dest_image_type::type>::min()

                            MAPPING: [SRC_LOWER, SRC_UPPER] -> [DEST_LOWER, DEST_UPPER]

                          Where this mapping is a linear mapping of values from the left range
                          into the right range of values.  Source pixel values outside the left
                          range are modified to be at the appropriate end of the range.

                          The scaled pixel is then stored in dest_img[r][c].
        !*/

    // ----------------------------------------------------------------------------------------

        template <
            typename dest_image_type,
            typename src_pixel_type
            >
        void assign_all_pixels (
            dest_image_type& dest_img,
            const src_pixel_type& src_pixel
        );
        /*!
            requires
                - dest_image_type == is an implementation of array2d/array2d_kernel_abstract.h
                - pixel_traits<typename dest_image_type::type> is defined
                - pixel_traits<src_pixel_type> is defined
            ensures
                - #dest_img.nc() == dest_img.nc()
                - #dest_img.nr() == dest_img.nr()
                  (i.e. the size of dest_img isn't changed by this function)
                - for all valid r and c:
                    - performs assign_pixel(#dest_img[r][c],src_pixel)
                      (i.e. assigns the src pixel to every pixel in the dest image)
        !*/

    // ----------------------------------------------------------------------------------------

        template <
            typename image_type
            >
        void assign_border_pixels (
            image_type& img,
            long x_border_size,
            long y_border_size,
            const typename image_type::type& p
        );
        /*!
            requires
                - image_type == is an implementation of array2d/array2d_kernel_abstract.h
                - x_border_size >= 0
                - y_border_size >= 0
            ensures
                - #img.nc() == img.nc()
                - #img.nr() == img.nr()
                  (i.e. the size of img isn't changed by this function)
                - for all valid r such that r+y_border_size or r-y_border_size gives an invalid row
                    - for all valid c such that c+x_border_size or c-x_border_size gives an invalid column
                        - performs assign_pixel(#img[r][c],p)
                          (i.e. assigns the given pixel to every pixel in the border of img)
        !*/

    // ----------------------------------------------------------------------------------------

        template <
            typename image_type
            >
        void zero_border_pixels (
            image_type& img,
            long x_border_size,
            long y_border_size
        );
        /*!
            requires
                - image_type == is an implementation of array2d/array2d_kernel_abstract.h
                - x_border_size >= 0
                - y_border_size >= 0
                - pixel_traits<typename image_type::type> is defined
            ensures
                - #img.nc() == img.nc()
                - #img.nr() == img.nr()
                  (i.e. the size of img isn't changed by this function)
                - for all valid r such that r+y_border_size or r-y_border_size gives an invalid row
                    - for all valid c such that c+x_border_size or c-x_border_size gives an invalid column
                        - performs assign_pixel(#img[r][c], 0 )
                          (i.e. assigns 0 to every pixel in the border of img)
        !*/

    // ----------------------------------------------------------------------------------------

        template <
            typename image_type
            >
        void zero_border_pixels (
            image_type& img,
            rectangle inside
        );
        /*!
            requires
                - image_type == is an implementation of array2d/array2d_kernel_abstract.h
                - pixel_traits<typename image_type::type> is defined
            ensures
                - #img.nc() == img.nc()
                - #img.nr() == img.nr()
                  (i.e. the size of img isn't changed by this function)
                - All the pixels in img that are not contained inside the inside rectangle
                  given to this function are set to 0.  That is, anything not "inside" is on
                  the border and set to 0.
        !*/

    // ----------------------------------------------------------------------------------------

    }

    #endif // DLIB_ASSIGN_IMAGe_ABSTRACT