#
# interpolatedOps.test --
#
#    Unit tests for interpolatedOps.c
#
# Copyright (c) 2016-2017 by Simon Bachmann <simonbachmann@bluewin.ch>
# All rights reserved.
#
# Permission is hereby granted, without written agreement and without
# license or royalty fees, to use, copy, modify, and distribute this
# software and its documentation for any purpose, provided that the
# above copyright notice and the following two paragraphs appear in
# all copies of this software.
# 

package require tcltest 2.3

eval ::tcltest::configure $argv

namespace eval ::imgtools::test::imgtools {
    namespace import ::tcltest::*
    namespace import ::imgtools::test::*
    variable setup {
        set smiley [file join [file normalize [workingDirectory]] smiley.png]
        set scaled120W [file join [file normalize [workingDirectory]] smileyScaledW.png]
        set scaled120H [file join [file normalize [workingDirectory]] smileyScaledH.png]
        set scaled120WH [file join [file normalize [workingDirectory]] smileyScaledWH.png]
        set scaled1Pixel [file join [file normalize [workingDirectory]] scaled1Pixel.png]
        set pixel [file join [file normalize [workingDirectory]] pixel.png]
        set blue [file join [file normalize [workingDirectory]] blue.png]
        set red [file join [file normalize [workingDirectory]] red.png]
        set rot0 [file join [file normalize [workingDirectory]] drawing.png]
        set rot90 [file join [file normalize [workingDirectory]] drawingRot90.png]
        set rot180 [file join [file normalize [workingDirectory]] drawingRot180.png]
        set rot270 [file join [file normalize [workingDirectory]] drawingRot270.png]
        set rot67 [file join [file normalize [workingDirectory]] drawingRot67.png]
        set photo [file join [file normalize [workingDirectory]] photo.png]
        image create photo smiley -file $smiley
        image create photo emptyImg
        image create photo emptyImg2
        image create photo emptyImg3
        image create photo destImg
        image create photo scaled120W -file $scaled120W
        image create photo scaled120H -file $scaled120H
        image create photo scaled120WH -file $scaled120WH
        image create photo scaled1Pixel -file $scaled1Pixel
        image create photo pixel -file $pixel
        image create photo blueImg -file $blue
        image create photo redImg -file $red
        image create photo rotated0 -file $rot0
        image create photo rotated90 -file $rot90
        image create photo rotated180 -file $rot180
        image create photo rotated270 -file $rot270
        image create photo rotated67 -file $rot67
        image create photo photo -file $photo
    }
    variable cleanup {
        image delete smiley
        image delete destImg
        image delete emptyImg emptyImg2 emptyImg3
        image delete scaled120W scaled120H scaled120WH
        image delete scaled1Pixel pixel
        image delete blueImg redImg
        image delete rotated0 rotated90 rotated180 rotated270
        image delete rotated67
        image delete photo
    }
    
    #
    # ### Imgtools_Scale ###
    #
    
    #
    # Options and arguments
    #
    set allowedOpts "-compositingrule, -shrink, -interpolation, -from*-to*"
    test scale-1.1 {Too few arguments} -setup {} -body {
        ::imgtools::scale a b
    } -cleanup {} -match glob -returnCodes error -result {wrong # args: should be*} 
    
    test scale-1.2 {Source image not found} -setup {} -body {
        ::imgtools::scale a b c
    } -cleanup {} -returnCodes error -result {image "a" not found}
    
    test scale-1.3 {Destination image not found} -setup $setup -body {
        ::imgtools::scale smiley b c
    } -cleanup $cleanup -returnCodes error -result {image "c" not found}
    
    test scale-1.4 {Invalid sizespec} -setup $setup -body {
        ::imgtools::scale smiley invalid destImg
    } -cleanup $cleanup -returnCodes error -match glob -result {expected integer but got "invalid"}
    
    # this one is obsolete, but should still suceed
    test scale-1.5 {Option not allowed for command} -setup $setup -body {
        ::imgtools::scale smiley 100% -alpha 0 destImg
    } -cleanup $cleanup -returnCodes error -match glob -result {*}
    
    test scale-1.6 {Unknown option, (not part of the common opts)} -setup $setup -body {
        ::imgtools::scale smiley 100% -invalid destImg
    } -cleanup $cleanup -returnCodes error -match glob -result "bad option \"-invalid\": must be $allowedOpts"
    
    test scale-1.7 {allowed options} -setup $setup -body {
        ::imgtools::scale smiley 100% -compositingrule set -shrink -interpolation nearest -from 0 -to 1 destImg
    } -cleanup $cleanup -returnCodes ok -result {destImg}
    
    test scale-1.8 {existing options, not allowed for scale: -alpha} -setup $setup -body {
        ::imgtools::scale smiley 100% -alpha 0 destImg
    } -cleanup $cleanup -returnCodes error -match glob -result "bad option \"-alpha\": must be $allowedOpts"
    
    test scale-1.9 {existing options, not allowed for scale: -background} -setup $setup -body {
        ::imgtools::scale smiley 100% -background blue destImg
    } -cleanup $cleanup -returnCodes error -match glob -result "bad option \"-background\": must be $allowedOpts"
    
    #obsolete / out of place
    test scale-1.10 {existing options, allowed for scale: -to} -setup $setup -body {
        ::imgtools::scale smiley 100% -to 1 2 3 4 destImg
    } -cleanup $cleanup -returnCodes ok -result {destImg}
    
    test scale-1.11 {existing options, not allowed for scale: -orient} -setup $setup -body {
        ::imgtools::scale smiley 100% -orient horizontal destImg
    } -cleanup $cleanup -returnCodes error -match glob -result "bad option \"-orient\": must be $allowedOpts"
    
    #obsolete / out of place
    test scale-1.12 {existing options, allowed for scale: -from} -setup $setup -body {
        ::imgtools::scale rotated0 12x34 -from 9 8 7 6 destImg
    } -cleanup $cleanup -returnCodes ok -result {destImg}
    
    test scale-1.13 {existing ioptions, not allowed for scaling: -clipping} -setup $setup -body {
        ::imgtools::scale smiley 11% -clipping none destImg
    } -cleanup $cleanup -returnCodes error -match glob -result "bad option \"-clipping\": must be $allowedOpts"
    
    test scale-1.14 {-from option / applySubregion } -setup $setup -body {
        emptyImg copy rotated0 -from 5 6 6 7
        ::imgtools::scale emptyImg 500% emptyImg2
        ::imgtools::scale rotated0 500% -from 5 6 6 7 destImg
        compareImages destImg emptyImg2
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-1.15 {-from option with only 2 coords -> size} -setup $setup -body {
        ::imgtools::scale smiley 200% -from 5 10 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {20 10}
    
    #
    # functionality: scaling images
    # 
    test scale-2.1 {Empty source image (size is 0)} -setup $setup -body {
        ::imgtools::scale emptyImg 100x100 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {0 0}
    
    test scale-2.2 {Target width and height different from source} -setup $setup -body {
        ::imgtools::scale smiley 119.99% destImg
        compareImages destImg scaled120WH
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.3 {Target width and height are equal to source sizes} -setup $setup -body {
        ::imgtools::scale smiley 100% destImg
        compareImages smiley destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.4 {Target width is equal to source, height differs} -setup $setup -body {
        ::imgtools::scale smiley 100%x120.01 destImg
        compareImages destImg scaled120H
    } -cleanup $cleanup -returnCodes ok -result {1}
        
    test scale-2.5 {Target width different from source, width is equal} -setup $setup -body {
        ::imgtools::scale smiley 120%x100 destImg
        compareImages destImg scaled120W
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.6 {Destination width is 0} -setup $setup -body {
        ::imgtools::scale smiley 0x2 destImg
        expr {[image width destImg] == 0 && [image height destImg] == 0}
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.7 {Destination height is 0} -setup $setup -body {
        ::imgtools::scale smiley 122x0 destImg
        expr {[image width destImg] == 0 && [image height destImg] == 0}
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.8 {Destination with and height are 0} -setup $setup -body {
        ::imgtools::scale smiley 0x0 destImg
        expr {[image width destImg] == 0 && [image height destImg] == 0}
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.9 {Donwsizing an image to a single pixel} -setup $setup -body {
        ::imgtools::scale smiley 1x1 destImg
        compareImages destImg scaled1Pixel
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.10 {Enlarging a single-pixel image} -setup $setup -body {
        set w 4
        set h 11
        ::imgtools::scale pixel ${w}x$h destImg
        set equal 1
        set srcPixel [getPixel pixel 0 0]
        for {set x 0} {$x < $w} {incr x} {
            for {set y 0} {$y < $h} {incr y} {
                if {[getPixel destImg $x $y] ne $srcPixel} {
                    set equal 0
                    set x $w
                    break
                }
            }
        }
        set equal
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.11 {Check that the source image is not affected} -setup $setup -body {
        emptyImg copy smiley
        ::imgtools::scale smiley 44x46 -compositingrule set destImg
        compareImages emptyImg smiley
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    #
    # the next 2 tests fail - actually, they are not supposed to succed
    # turning them off.
    test scale-2.12 {Scaling up by integer ratio and back, catrom} -setup $setup \
    -constraints {knownBug} -body {
        ::imgtools::scale rotated0 400% -compositingrule set -shrink -interpolation catrom destImg
        ::imgtools::scale destImg 39x22 -compositingrule set -shrink -interpolation catrom destImg
        compareImages rotated0 destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.13 {Scaling up by integer ratio and back, linear} -setup $setup \
    -constraints {knownBug} -body {
        ::imgtools::scale rotated0 400% -compositingrule set -shrink -interpolation linear destImg
        ::imgtools::scale destImg 39x22 -compositingrule set -shrink -interpolation linear destImg
        compareImages rotated0 destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-2.14 {Scaling up by integer ratio and back, nearest} -setup $setup -body {
        ::imgtools::scale rotated0 400% -compositingrule set -shrink -interpolation nearest destImg
        ::imgtools::scale destImg 39x22 -compositingrule set -shrink -interpolation nearest destImg
        compareImages rotated0 destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    #
    # writing image data / -to option
    #
    test scale-3.1 {-to option} -setup $setup -body {
        ::imgtools::scale smiley 20x10 emptyImg
        ::imgtools::scale smiley 20x10 -to 11 12 2 1 destImg
        emptyImg2 copy emptyImg -to 11 12 2 1
        compareImages destImg emptyImg2
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test scale-3.2 {size with only 2 coords for -to} -setup $setup -body {
        ::imgtools::scale rotated0 23x45 -to 10 1 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {33 46}
    
    test scale-3.3 {result} -setup $setup -body {
        ::imgtools::scale smiley 21 rotated0
    } -cleanup $cleanup -returnCodes ok -result {rotated0}
    
    #
    # ### Imgtools_ResizeImage, Imgtools_CalcScaleCache and Imgtools_FreeScaleCache ###
    #
    
    #
    # normal interpolation, up and downscaling, all interpolation methods
    #
    test resize-1.0 {Enlarging both directions, catrom filter} -setup $setup -body {
        ::imgtools::scale rotated0 47x29 destImg
        getPixel destImg 30 13
    } -cleanup $cleanup -returnCodes ok -result {18 15 31 223}
    
    test resize-1.1 {Enlarging x, shrinking y, catrom filter} -setup $setup -body {
        ::imgtools::scale rotated0 82x12 destImg
        getPixel destImg 52 5
    } -cleanup $cleanup -returnCodes ok -result {28 33 79 185}
    
    test resize-1.2 {Shrinking x, enlarging y, catrom filter} -setup $setup -body {
        ::imgtools::scale rotated0 24x34 destImg
        getPixel destImg 15 15
    } -cleanup $cleanup -returnCodes ok -result {37 30 73 195}
    
    test resize-1.3 {shrinking both, catrom filter} -setup $setup -body {
        ::imgtools::scale rotated0 38x21 destImg
        getPixel destImg 24 9
    } -cleanup $cleanup -returnCodes ok -result {46 39 84 183}
    
    test resize-1.4 {Enlarging both directions, linear filter} -setup $setup -body {
        ::imgtools::scale rotated0 54x53 -interpolation linear destImg
        getPixel destImg 8 29
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 255}
    
    test resize-1.5 {Enlarging x, shrinking y, linear filter} -setup $setup -body {
        ::imgtools::scale rotated0 78x11 -interpolation linear destImg
        getPixel destImg 17 7
    } -cleanup $cleanup -returnCodes ok -result {111 2 2 255}
    
    test resize-1.6 {Shrinking x, enlarging y, linear filter} -setup $setup -body {
        ::imgtools::scale rotated0 16x25 -interpolation linear destImg
        getPixel destImg 6 23
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 255}
    
    test resize-1.7 {shrinking both, linear filter} -setup $setup -body {
        ::imgtools::scale rotated0 10x20 -interpolation linear destImg
        getPixel destImg 5 10
    } -cleanup $cleanup -returnCodes ok -result {14 12 26 40}
    
    test resize-1.8 {Enlarging both directions, nearest filter} -setup $setup -body {
        ::imgtools::scale rotated0 45x45 -interpolation nearest destImg
        getPixel destImg 8 41
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 255}
    
    test resize-1.9 {Enlarging x, shrinking y, nearest filter} -setup $setup -body {
        ::imgtools::scale rotated0 45x20 -interpolation nearest destImg
        getPixel destImg 10 15
    } -cleanup $cleanup -returnCodes ok -result {111 2 2 255}
    
    test resize-1.10 {Shrinking x, enlarging y, nearest filter} -setup $setup -body {
        ::imgtools::scale rotated0 10x45 -interpolation nearest destImg
        getPixel destImg 17 21
    } -cleanup $cleanup -returnCodes ok -result {60 50 113 166}
    
    test resize-1.11 {shrinking both, nearest filter} -setup $setup -body {
        ::imgtools::scale rotated0 23x15 -interpolation nearest destImg
        getPixel destImg 21 12
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test resize-1.12 {lanczos filters} -setup $setup -body {
        set testcases [list \
            {{shrinking both, lanczos2} photo lanczos2 58x58 30 46 {139 122 95 255}} \
            {{shrinking x, enlarging y, lanczos2} photo lanczos2 42x90 25 47 {48 40 38 255}} \
            {{enlarging x, shrinking y, lanczos2} photo lanczos2 155x39 111 26 {89 90 108 255}} \
            {{enlarging both, lanczos2} photo lanczos2 160x121 79 49 {124 29 49 255}} \
            {{shrinking both, lanczos3} photo lanczos3 83x62 11 60 {169 153 125 255}} \
            {{shrinking x, enlarging y, lanczos3} photo lanczos3 76x100 12 40 {50 50 56 255}} \
            {{enlarging x, shrinking y, lanczos3} photo lanczos3 191x43 173 23 {41 37 39 255}} \
            {{enlarging both, lanczos3} photo lanczos3 200x145 122 72 {66 55 48 255}} \
        ]
        set results {}
        foreach case $testcases {
            lassign $case descr img interpolation sizespec x y shouldRes
            ::imgtools::scale $img $sizespec -interpolation $interpolation -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {}
    
    
    #
    # edges, corners
    #
    test resize-2.1 {top left corner, catrom} -setup $setup -body {
        ::imgtools::scale rotated0 30x15 -interpolation catrom destImg
        getPixel destImg 0 0
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 0}
    
    test resize-2.2 {top right corner, catrom} -setup $setup -body {
        ::imgtools::scale rotated0 16x9 -interpolation catrom destImg
        getPixel destImg 15 0
    } -cleanup $cleanup -returnCodes ok -result {232 0 31 0}
    
    test resize-2.3 {bottom left corner, linear} -setup $setup -body {
        ::imgtools::scale rotated0 50x30 -interpolation linear destImg
        getPixel destImg 0 29 
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 255}
    
    test resize-2.4 {bottom right corner, nearest} -setup $setup -body {
        ::imgtools::scale rotated0 17x40 -interpolation nearest destImg
        getPixel destImg 16 39
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 255}
    
    test resize-2.5 {top edge, nearest} -setup $setup -body {
        ::imgtools::scale rotated0 100x100 -interpolation nearest destImg
        getPixel destImg 48 0
    } -cleanup $cleanup -returnCodes ok -result {255 255 0 199}
    
    test resize-2.6 {bottom edge, linear} -setup $setup -body {
        ::imgtools::scale rotated0 200x10 -interpolation linear destImg
        getPixel destImg 43 9
    } -cleanup $cleanup -returnCodes ok -result {28 96 0 255}
    
    test resize-2.7 {left edge, lanczos2} -setup $setup -body {
        ::imgtools::scale rotated0 19x29 -interpolation lanczos2 destImg
        getPixel destImg 0 7
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 255}
    
    test resize-2.8 {right edge, lanczos3} -setup $setup -body {
        ::imgtools::scale rotated0 24x14 -interpolation lanczos3 destImg
        getPixel destImg 23 4
    } -cleanup $cleanup -returnCodes ok -result {237 1 33 0}
    
    #
    # single-color image: no rounding errors
    # matematically, in a single-color image the result
    # will always be _exactly_ equal to source values.
    # we shouldn't even get close to rounding errors...
    # just check a few random pixels
    #
    test resize-3.1 {single-color, catrom, ++} -setup $setup -body {
        ::imgtools::scale blueImg 22x39 -interpolation catrom destImg
        getPixel destImg 17 13
    } -cleanup $cleanup -returnCodes ok -result {0 0 255 255} 
    
    test resize-3.2 {single-color, catrom, --} -setup $setup -body {
        ::imgtools::scale redImg 4x13 -interpolation catrom destImg
        getPixel destImg 2 8
    } -cleanup $cleanup -returnCodes ok -result {255 0 0 255} 
    
    test resize-3.3 {single-color, catrom, scale up then down again} -setup $setup -body {
        ::imgtools::scale redImg 321% -interpolation catrom destImg
        ::imgtools::scale destImg 15x15 -compositingrule set -shrink destImg
        compareImages destImg redImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test resize-3.4 {single-color, linear, +-} -setup $setup -body {
        ::imgtools::scale blueImg 200x10 -interpolation linear destImg
        getPixel destImg 187 6
    } -cleanup $cleanup -returnCodes ok -result {0 0 255 255} 
    
    test resize-3.5 {single-color, linear, ++} -setup $setup -body {
        ::imgtools::scale redImg 23x30 -interpolation linear destImg
        getPixel destImg 22 19
    } -cleanup $cleanup -returnCodes ok -result {255 0 0 255} 
    
    test resize-3.6 {single color, linear, scale down then up} -setup $setup -body {
        ::imgtools::scale blueImg 2x3 -interpolation linear destImg
        ::imgtools::scale destImg 15x15 -interpolation linear -compositingrule set -shrink destImg
        compareImages destImg blueImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test resize-3.7 {single-color, nearest, -+} -setup $setup -body {
        ::imgtools::scale blueImg 2x16 -interpolation nearest destImg
        getPixel destImg 1 7
    } -cleanup $cleanup -returnCodes ok -result {0 0 255 255} 
    
    test resize-3.8 {single-color, nearest, -+} -setup $setup -body {
        ::imgtools::scale redImg 14x16 -interpolation nearest destImg
        getPixel destImg 12 7
    } -cleanup $cleanup -returnCodes ok -result {255 0 0 255} 
    
    test resize-3.9 {single color, nearest, scale down then up} -setup $setup -body {
        ::imgtools::scale blueImg 14 -interpolation nearest destImg
        ::imgtools::scale destImg 15x15 -interpolation nearest -compositingrule set -shrink destImg
        compareImages destImg blueImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test resize-3.10 {single color, all interpol methods} -setup $setup -body {
        ::imgtools::scale redImg 7x20 -interpolation catrom -compositingrule set -shrink destImg
        ::imgtools::scale destImg 50x3 -interpolation linear -compositingrule set -shrink destImg
        ::imgtools::scale destImg 54x8 -interpolation nearest -compositingrule set -shrink destImg
        ::imgtools::scale destImg 21x99 -interpolation lanczos2 -compositingrule set -shrink destImg
        ::imgtools::scale destImg 15x15 -interpolation lanczos3 -compositingrule set -shrink destImg
        compareImages destImg redImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test resize-3.11 {single-color, lanczos2, -+} -setup $setup -body {
        ::imgtools::scale blueImg 5x17 -interpolation lanczos2 destImg
        getPixel destImg 3 13
    } -cleanup $cleanup -returnCodes ok -result {0 0 255 255} 
    
    test resize-3.12 {single-color, lanczos2, +-} -setup $setup -body {
        ::imgtools::scale redImg 22x2 -interpolation lanczos2 destImg
        getPixel destImg 9 1
    } -cleanup $cleanup -returnCodes ok -result {255 0 0 255} 
    
    test resize-3.13 {single color, lanczos2, scale down then up} -setup $setup -body {
        ::imgtools::scale blueImg 13 -interpolation lanczos2 destImg
        ::imgtools::scale destImg 15x15 -interpolation lanczos2 -compositingrule set -shrink destImg
        compareImages destImg blueImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test resize-3.14 {single-color, lanczos3, --} -setup $setup -body {
        ::imgtools::scale blueImg 2x14 -interpolation lanczos3 destImg
        getPixel destImg 1 11
    } -cleanup $cleanup -returnCodes ok -result {0 0 255 255} 
    
    test resize-3.15 {single-color, lanczos3, ++} -setup $setup -body {
        ::imgtools::scale redImg 17x31 -interpolation lanczos3 destImg
        getPixel destImg 5 29
    } -cleanup $cleanup -returnCodes ok -result {255 0 0 255} 
    
    test resize-3.16 {single color, lanczos3, scale down then up} -setup $setup -body {
        ::imgtools::scale blueImg 1 -interpolation lanczos3 destImg
        ::imgtools::scale destImg 15x15 -interpolation lanczos3 -compositingrule set -shrink destImg
        compareImages destImg blueImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    #
    # rounding errors: test some pixels with a result that's close to x.5
    #
    test resize-4.1 {result close to middle (x.5), catrom} -setup $setup -body {
        ::imgtools::scale smiley 24x14 -interpolation catrom destImg
        getPixel destImg 8 3
    } -cleanup $cleanup -returnCodes ok -result {141 141 0 220}
    
    test resize-4.2 {result close to middle (x.5), catrom} -setup $setup -body {
        ::imgtools::scale smiley 16x23 -interpolation catrom destImg
        getPixel destImg 8 1
    } -cleanup $cleanup -returnCodes ok -result {95 95 95 175}
    
    test resize-4.3 {result close to middle (x.5), catrom} -setup $setup -body {
        ::imgtools::scale rotated0 123x32 -interpolation catrom destImg
        getPixel destImg 78 22
    } -cleanup $cleanup -returnCodes ok -result {30 31 69 192}
    
    test resize-4.4 {result close to middle (x.5), catrom} -setup $setup -body {
        ::imgtools::scale smiley 11x12 -interpolation catrom destImg
        getPixel destImg 8 0
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 112}
    
    test resize-4.5 {result close to middle (x.5), linear} -setup $setup -body {
        ::imgtools::scale smiley 21x32 -interpolation linear destImg
        getPixel destImg 13 23
    } -cleanup $cleanup -returnCodes ok -result {164 164 0 215}
    
    test resize-4.6 {result close to middle (x.5), linear} -setup $setup -body {
        ::imgtools::scale smiley 25x10 -interpolation linear destImg
        getPixel destImg 20 6
    } -cleanup $cleanup -returnCodes ok -result {16 16 0 251}
    
    test resize-4.7 {result close to middle (x.5), lanczos} -setup $setup \
        -constraints {knownBug} -body {
        #
        # NOTE: 
        #
        # Testcase #2 fails for green (off by one). Real difference is 0.0002 - acceptable!
        # Testcase #3 fails for green (off by one). Real difference is 0.001 - acceptable!
        set testcases [list \
            {{rounding #2, lanczos2} photo lanczos2 122x92 0 90 {158 143 115 255}} \
            {{rounding #3, lanczos3} photo lanczos3 88x66 1 50 {134 118 101 255}} \
        ]
        set results {}
        foreach case $testcases {
            lassign $case descr img interpolation sizespec x y shouldRes
            ::imgtools::scale $img $sizespec -interpolation $interpolation -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {}
    
    test resize-4.8 {result close to middle (x.5), lanczos} -setup $setup -body {
        set testcases [list \
            {{rounding #1, lanczos2} photo lanczos2 144x 78 17 {66 67 73 255}} \
            {{rounding #4, lanczos3} photo lanczos3 111x 20 63 {158 142 116 255}} \
        ]
        set results {}
        foreach case $testcases {
            lassign $case descr img interpolation sizespec x y shouldRes
            ::imgtools::scale $img $sizespec -interpolation $interpolation -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {}
    
    # 
    # Sum of weighted alpha == 0
    #
    test resize-5.1 {sum of weighted alpha == 0, catrom} -setup $setup -body {
        ::imgtools::scale rotated0 50x30 -interpolation catrom destImg
        getPixel destImg 22 23
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test resize-5.2 {sum of weighted alpha == 0, linear} -setup $setup -body {
        ::imgtools::scale rotated0 50x30 -interpolation linear destImg
        getPixel destImg 22 23
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test resize-5.3 {sum of weighted alpha == 0, lanczos2} -setup $setup -body {
        ::imgtools::scale rotated0 34x19 -interpolation lanczos2 destImg
        getPixel destImg 32 2
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test resize-5.4 {sum of weighted alpha == 0, lanczos3} -setup $setup -body {
        ::imgtools::scale rotated0 48x27 -interpolation lanczos3 destImg
        getPixel destImg 1 20
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    # 
    # Getting a sum of weights of zero:
    # not possible with linear and nearest interpolation
    # not possible with catrom and lanczos either. 
    # ergo - no way to test it!
    #
    
    #   
    # clipping (both directions)
    # with linear and nearest filters, we won't get any results that need clipping
    #
    # rounding (simply test that results get rounded correctly, 
    # dont test for rounding errors here)
    # no rounding with nearest filter
    #
    
    test resize-7.1 {clipping, catrom} -setup $setup -body {
        ::imgtools::scale smiley x16 -interpolation catrom destImg
        getPixel destImg 8 2
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 255}
    
    test resize-7.2 {clipping, catrom} -setup $setup -body {
        ::imgtools::scale rotated0 37x15 -interpolation catrom destImg
        getPixel destImg 35 10
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test resize-7.3 {clipping, catrom} -setup $setup -body {
        ::imgtools::scale rotated0 37x15 -interpolation catrom destImg
        getPixel destImg 0 3
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 255}
    
    test resize-8.1 {rounding, catrom} -setup $setup -body {
        ::imgtools::scale rotated0 40x21 -interpolation catrom destImg
        getPixel destImg 8 12
    } -cleanup $cleanup -returnCodes ok -result {119 0 2 255}
    
    test resize-8.2 {rounding, linear} -setup $setup -body {
        ::imgtools::scale smiley 66x33 -interpolation linear destImg
        getPixel destImg 22 11
    } -cleanup $cleanup -returnCodes ok -result {118 118 0 224}
    
    test resize-8.3 {rounding, linear} -setup $setup -body {
        ::imgtools::scale smiley 66x33 -interpolation linear destImg
        getPixel destImg 22 10
    } -cleanup $cleanup -returnCodes ok -result {182 182 0 211}   
    
    test resize-8.4 {rounding and clipping, lanczos} -setup $setup -body {
        set testcases [list \
            {{rounding up, lanczos2}        photo   lanczos2 187x26  22 23   {56 56 64 255}} \
            {{rounding down, lanczos2}      photo   lanczos2 108x142 13 56   {106 94 85 255}} \
            {{rounding up, lanczos3}        photo   lanczos3 96x120  66 2    {120 119 109 255}} \
            {{rounding down, lanczos3}      photo   lanczos3 43x54   22 36   {69 44 31 255}} \
            {{clipping bottom, lanczos2}    smiley  lanczos2 16x11   6 8     {126 126 0 224}} \
            {{clipping top, lanczos2}       smiley  lanczos2 24x16   6 8     {255 255 0 196}} \
            {{clipping top, lanczos3}       smiley  lanczos3 9x27    2 13    {255 255 2 192}} \
            {{clipping bottom, lanczos3}    smiley  lanczos3 28x18   14 2    {0 0 0 255}} \
        ]
        set results {}
        foreach case $testcases {
            lassign $case descr img interpolation sizespec x y shouldRes
            ::imgtools::scale $img $sizespec -interpolation $interpolation -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {}
    
    #
    # ### Imgtools_Rotate ###
    #
    #
    # Arguments and options
    #
    set allowedOpts "-compositingrule, -shrink, -interpolation, -background, -alpha, -from, -to*-clipping*"
    
    test rotate-1.0 {too few arguments} -setup $setup -body {
        ::imgtools::rotate smiley destImg
    } -cleanup $cleanup -returnCodes error -match glob -result {wrong # args: should be "* sourceImg angle ?options? destImg"}
    
    test rotate-1.1 {Source image does not exist} -setup $setup -body {
        ::imgtools::rotate invalid 33 invalid
    } -cleanup $cleanup -returnCodes error -result {image "invalid" not found}
    
    test rotate-1.2 {Dest image does not exist} -setup $setup -body {
        ::imgtools::rotate smiley 33 invalid
    } -cleanup $cleanup -returnCodes error -result {image "invalid" not found}
    
    test rotate-1.3 {Angle not a valid value} -setup $setup -body {
        ::imgtools::rotate smiley invalid destImg
    } -cleanup $cleanup -returnCodes error -result {expected floating-point number but got "invalid"}
    
    test rotate-1.4 {Valid options} -setup $setup -body {
        ::imgtools::rotate rotated0 33 -alpha .5 -compositingrule set -shrink -interpolation linear -background blue -from 1 -to 2 -clipping keepsize destImg
    } -cleanup $cleanup -returnCodes ok -result {destImg}
    
    test rotate-1.5 {Nonexisting option} -setup $setup -body {
        ::imgtools::rotate rotated0 33 -invalid opt destImg
    } -cleanup $cleanup -returnCodes error -match glob -result "bad option \"-invalid\": must be $allowedOpts"
    
    # obsolete / out of place
    test rotate-1.6 {Option allowed for command: -to} -setup $setup -body {
        ::imgtools::rotate rotated0 -12 -shrink -to 3 4 5 -alpha 1 destImg
    } -cleanup $cleanup -returnCodes ok -result {destImg}
    
    test rotate-1.7 {Option not allowed for command: -orient} -setup $setup -body {
        ::imgtools::rotate rotated0 -12 -shrink -orient vertical -alpha 1 destImg
    } -cleanup $cleanup -returnCodes error -match glob -result "bad option \"-orient\": must be $allowedOpts"
    
    #obsolete / out of place
    test rotate-1.8 {Option allowed for command: -from} -setup $setup -body {
        ::imgtools::rotate smiley 55 -from 4 5 6 8 destImg
    } -cleanup $cleanup -returnCodes ok -result {destImg}
    
    test rotate-1.9 {-from option / applySubregion} -setup $setup -body {
        emptyImg copy rotated0 -from 10 22 39 5
        ::imgtools::rotate rotated0 90° -from 10 22 39 5 emptyImg2
        ::imgtools::rotate emptyImg2 -90° destImg
        compareImages destImg emptyImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate-1.10 {-from with only two coords, size} -setup $setup -body {
        ::imgtools::rotate photo 90° -from 10 20 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {55 90}
    
    #
    # Functionality
    # 
    test rotate-2.0 {Empty source image} -setup $setup -body {
        ::imgtools::rotate emptyImg 123 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {0 0}
    
    test rotate-2.1 {Single pixel image} -setup $setup -body {
        ::imgtools::rotate pixel 45 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {1 1}
    
    test rotate-2.2 {Check that sourceImage is not affected} -setup $setup -body {
        emptyImg copy rotated0
        ::imgtools::rotate rotated0 34 destImg
        compareImages rotated0 emptyImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate-2.3 {Basic rotate} -setup $setup -body {
        ::imgtools::rotate rotated0 67 destImg
        compareImages destImg rotated67
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate-2.4 {Angle larger than 360} -setup $setup -body {
        ::imgtools::rotate rotated0 3667 destImg
        compareImages destImg rotated67
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate-2.5 {Angle smaller than 0} -setup $setup -body {
        ::imgtools::rotate rotated0 -36293 destImg
        compareImages destImg rotated67
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate-2.6 {Angle equals maxint} -setup $setup -body {
        ::imgtools::rotate rotated0 [getIntMax] destImg
    } -cleanup $cleanup -returnCodes ok -result destImg
    
    test rotate-2.7 {Angle equals minint} -setup $setup -body {
        ::imgtools::rotate rotated0 [getIntMin] destImg
    } -cleanup $cleanup -returnCodes ok -result {destImg}
    
    test rotate-2.8 {Angle larger than maxint} -setup $setup -body {
        set angle [expr {[getIntMax]+1}]
        ::imgtools::rotate rotated0 $angle destImg
    } -cleanup $cleanup -returnCodes error -result {value for angle is too big}
    
    test rotate-2.9 {Angle smaller than minint} -setup $setup -body {
        set angle [expr {[getIntMin]-1}]
        ::imgtools::rotate rotated0 $angle destImg
    } -cleanup $cleanup -returnCodes error -result {value for angle is too small}
    
    #
    # in conclusion....
    #
    test rotate-3.1 {-to option} -setup $setup -body {
        ::imgtools::rotate smiley 22° -to 0 0 10 11 destImg
        ::imgtools::rotate smiley 22° emptyImg
        emptyImg2 copy emptyImg -from 0 0 10 11
        compareImages emptyImg2 destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate-3.2 {result} -setup $setup -body {
        image create photo blablabla
        ::imgtools::rotate smiley -112233° blablabla
    } -cleanup $cleanup -returnCodes ok -result {blablabla}
    
    test rotate-3.3 {size with only 2 coords to -to} -setup $setup -body {
        ::imgtools::rotate smiley 32° -clipping keepsize -to 5 15 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {20 30}
    
    #
    # ### Imgtools_RotateImage ###
    #    
    
    #
    # Size of dest Image
    #
    test rotateimage-1.1 {size of destImage, -clipping none (default)} -setup $setup -body {
        ::imgtools::rotate rotated0 -160 destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {44 34}
    
    test rotateimage-1.2 {size of destImage -clipping keepsize} -setup $setup -body {
        ::imgtools::rotate smiley 23 -clipping keepsize destImg
        list [image width destImg] [image height destImg]
    } -cleanup $cleanup -returnCodes ok -result {15 15}
    
    test rotateimage-1.3 {size of destImage -clipping noblanks} -setup $setup -body {
        set result {}
        ::imgtools::rotate rotated0 -7 -clipping noblanks destImg
        lappend result [list [image width destImg] [image height destImg]]
        
        ::imgtools::rotate rotated0 137 -clipping noblanks emptyImg
        lappend result [list [image width emptyImg] [image height emptyImg]]
        
        ::imgtools::rotate rotated0 -90 emptyImg2
        ::imgtools::rotate emptyImg2 137 -clipping noblanks emptyImg3
        lappend result [list [image width emptyImg3] [image height emptyImg3]]
    } -cleanup $cleanup -returnCodes ok -result {{37 18} {16 15} {15 16}}
    
        
    #
    # Outside pixels with no itnerpolation
    #
    test rotateimage-2.1 {outsidePixel with no interpolation} -setup $setup -body {
        ::imgtools::rotate rotated0 37 -background #686a88 -alpha 28.63% destImg
        getPixel destImg 3 4
    } -cleanup $cleanup -returnCodes ok -result {104 106 136 73}
    
    test rotateimage-2.2 {outsidePixel with no interpolation} -setup $setup -body {
        ::imgtools::rotate rotated0 224 -background #6caec5 -alpha 4.31% destImg
        getPixel destImg 40 40
    } -cleanup $cleanup -returnCodes ok -result {108 174 197 11}
    
    #
    # edges and corners of destImage
    #
    test rotateimage-3.1 {top edge of destImg / interpolated outsidePixel} -setup $setup -body {
        ::imgtools::rotate smiley 288 -interpolation catrom -background #4819c8 -alpha 16.47% destImg
        getPixel destImg 7 0
    } -cleanup $cleanup -returnCodes ok -result {98 57 208 46}
    
    test rotateimage-3.2 {bottom edge of destImg / interpolated outsidePixel} -setup $setup -body {
        ::imgtools::rotate smiley 272 -interpolation lanczos2 -background #4819c8 -alpha 0.1647 destImg
        getPixel destImg 7 15
    } -cleanup $cleanup -returnCodes ok -result {168 140 243 55}
    
    test rotateimage-3.3 {left edge of destImg / interpolated outsidePixel} -setup $setup -body {
        ::imgtools::rotate rotated0 132 -interpolation lanczos3 -background #13a785 -alpha .9333 destImg
        getPixel destImg 0 29
    } -cleanup $cleanup -returnCodes ok -result {14 142 65 252}
    
    test rotateimage-3.4 {right edge of destImg / interpolated outsidePixel} -setup $setup -body {
        ::imgtools::rotate rotated0 135 -interpolation linear -background #0c4636 -alpha 54.51% destImg
        getPixel destImg 42 14
    } -cleanup $cleanup -returnCodes ok -result {12 70 54 111}
    
    test rotateimage-3.5 {NW corner of destimg / outside pixel} -setup $setup -body {
        ::imgtools::rotate smiley 235 -interpolation nearest -background #b08127 -alpha 12.94% destImg
        getPixel destImg 0 0
    } -cleanup $cleanup -returnCodes ok -result {176 129 39 33}
    
    test rotateimage-3.6 {NE corner of destimg / outside pixel} -setup $setup -body {
        ::imgtools::rotate smiley -346 -interpolation catrom -background #beb591 -alpha .9647 destImg
        getPixel destImg 17 0
    } -cleanup $cleanup -returnCodes ok -result {190 181 145 246}
    
    test rotateimage-3.7 {SW corner of destimg / outside pixel} -setup $setup -body {
        ::imgtools::rotate rotated0 -25 -interpolation lanczos2 -background #ed5593 -alpha 1.96% destImg
        getPixel destImg 0 35
    } -cleanup $cleanup -returnCodes ok -result {237 85 147 5}
    
    test rotateimage-3.8 {SE corner of destimg / outside pixel} -setup $setup -body {
        ::imgtools::rotate rotated0 143 -interpolation lanczos3 -background #122e4e -alpha 9.41% destImg
        getPixel destImg 43 40
    } -cleanup $cleanup -returnCodes ok -result {18 46 78 24}
    
    #
    # ### Imgtools_RotateImage90 ### 
    #
    test rotateimage90-1.1 {sizes of destImg with all clipping methods} -setup $setup -body {
        set cases [list \
            {#1   0°  none      100 75} \
            {#2   0°  keepsize  100 75} \
            {#3   0°  noblanks  100 75} \
            {#4  90°  none      75 100} \
            {#5  90°  keepsize  100 75} \
            {#6  90°  noblanks  75 100} \
            {#7 180°  none      100 75} \
            {#8 180°  keepsize  100 75} \
            {#9 180°  noblanks  100 75} \
            {#10 270° none      75 100} \
            {#11 270° keepsize  100 75} \
            {#12 270° noblanks  75 100} ]
        
        set result {ok}
        foreach case $cases {
            lassign $case nr angle clipping expW expH
            image create photo tmp
            ::imgtools::rotate photo $angle -clipping $clipping tmp
            set haveW [image width tmp]
            set haveH [image height tmp]
            if {$expW != $haveW || $expH != $haveH } {
                lappend result "$nr failed: got $haveW, $haveH"
            }
            image delete tmp
        }
        set result
    } -cleanup $cleanup -returnCodes ok -result {ok}
    
    #
    # For testing correct rotation, these tests
    # concieved for the now replaced rotate90 function will do
    #
    
    test rotate90-1.0 {Basic test of 90° rotation, angle larger than 360} -setup $setup -body {
        ::imgtools::rotate rotated0 2250 destImg
        compareImages destImg rotated90
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate90-1.1 {Basic test of 180° rotation, angle between 0 and 360} -setup $setup -body {
        ::imgtools::rotate rotated0 180 destImg
        compareImages destImg rotated180
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate90-1.2 {Basic test of 270° rotation, smaller than -360} -setup $setup -body {
        ::imgtools::rotate rotated0 -450 destImg
        compareImages destImg rotated270
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate90-1.3 {Angle of 0°} -setup $setup -body {
        ::imgtools::rotate rotated0 -360 destImg
        compareImages destImg rotated0
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate90-1.4 {Check that the source image is not affected} -setup $setup -body {
        emptyImg copy rotated0
        ::imgtools::rotate rotated0 90 -compositingrule set destImg
        compareImages emptyImg rotated0
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    # 
    # Functionality
    #
    test rotate90-2.1 {rotate by 360° in steps of 90, catrom} -setup $setup -body {
        ::imgtools::rotate rotated0 90 -compositingrule set -shrink -interpolation catrom destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation catrom destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation catrom destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation catrom destImg
        compareImages rotated0 destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate90-2.2 {rotate by 360° in steps of 90, linear} -setup $setup -body {
        ::imgtools::rotate rotated0 90 -compositingrule set -shrink -interpolation linear destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation linear destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation linear destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation linear destImg
        compareImages rotated0 destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    test rotate90-2.3 {rotate by 360° in steps of 90, nearest neigbor} -setup $setup -body {
        ::imgtools::rotate rotated0 90 -compositingrule set -shrink -interpolation nearest destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation nearest destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation nearest destImg
        ::imgtools::rotate destImg 90 -compositingrule set -shrink -interpolation nearest destImg
        compareImages rotated0 destImg
    } -cleanup $cleanup -returnCodes ok -result {1}
    
    #
    # ### Imgtools_Interpol ###
    # This section has gotten a little "bloated" - 
    # we're testing things here that actually happen in other 
    # functions.
    #
    
    #
    # Normal interpolation (test some random pixels), 
    # edges and corners of srcImage (includes test for interpolation
    # with outside pixel)
    #
    test interpol-1.1 {normal interpolation, check values} -setup $setup -body {
        ::imgtools::rotate smiley 77 destImg
        getPixel destImg 13 7
    } -cleanup $cleanup -returnCodes ok -result {45 45 0 243}
    
    test interpol-1.2 {normal interpolation, check values} -setup $setup -body {
        ::imgtools::rotate rotated0 157 destImg
        getPixel destImg 9 17
    } -cleanup $cleanup -returnCodes ok -result {6 4 23 230}
    
    test interpol-1.3 {top edge of srcImg} -setup $setup -body {
        ::imgtools::rotate rotated0 200 destImg
        getPixel destImg 20 29
    } -cleanup $cleanup -returnCodes ok -result {255 255 0 0}
    
    test interpol-1.4 {bottom edge of srcImg} -setup $setup -body {
        ::imgtools::rotate rotated0 291 destImg
        getPixel destImg 31 15
    } -cleanup $cleanup -returnCodes ok -result {9 118 0 155}
    
    test interpol-1.5 {left edge of srcImg} -setup $setup -body {
        ::imgtools::rotate smiley 223 destImg
        getPixel destImg 17 15
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 0}
    
    test interpol-1.6 {right edge of srcImg} -setup $setup -body {
        ::imgtools::rotate smiley 92 destImg
        getPixel destImg 8 15
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 24}
    
    test interpol-1.7 {NW corner of srcImg} -setup $setup -body {
        ::imgtools::rotate rotated0 327 destImg
        getPixel destImg 0 19
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test interpol-1.8 {NE corner of srcImg} -setup $setup -body {
        ::imgtools::rotate rotated0 -20 destImg
        getPixel destImg 36 0
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test interpol-1.9 {SW corner of srcImg} -setup $setup -body {
        ::imgtools::rotate smiley 271 destImg
        getPixel destImg 14 14
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 124}
    
    test interpol-1.10 {SE corner of srcImg} -setup $setup -body {
        ::imgtools::rotate smiley 111 destImg
        getPixel destImg 0 14
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 20}
    
    #due to a change in implementation, we test the above again, 
    #this time with all filters
    test interpol-1.11 {random pixels, edges and corners of srcImg} -setup $setup -body {
        set testcases [list \
            {{random pixel, linear}     photo       linear      189     80 58   #e387c6 0.7765 {97 103 113 255} {227 135 198 198}} \
            {{random pixel, catrom}     photo       catrom      570     97 110  #dc733d 0.2902 {220 115 61 74} {220 115 61 74}} \
            {{random pixel, lanczos2}   photo       lanczos2    262     8 14    #7b8fbd 0.4314 {27 22 23 255} {123 143 189 110}} \
            {{random pixel, lanczos3}   photo       lanczos3    274     71 22   #8ae374 0.9725 {157 140 114 255} {138 227 116 248}} \
            {{NW corner, linear}        smiley      linear      -135    10 20   #ee1c30 0.8039 {253 228 230 121} {238 28 48 205}} \
            {{NE corner, catrom}        smiley      catrom      -45     10 0    #a089f8 0.2510 {243 240 254 104} {160 137 248 64}} \
            {{SW corner, lanczos2}      rotated0    lanczos2    -225    27 0    #d5fd1e 0.8196 {48 143 6 245} {213 253 30 209}} \
            {{SE corner, lanczos3}      rotated0    lanczos3    -315    28 42   #dc4653 0.6157 {132 90 48 193} {220 70 83 157}} \
            {{top edge, lanczos3}       smiley      lanczos3    135     16 15   #e7eb71 0.8745 {255 255 167 174} {231 235 113 223}} \
            {{right edge, lanczos2}     rotated0    lanczos2    232     6 8     #f06340 0.5529 {240 97 63 68} {240 99 64 141}} \
            {{bottom edge, catrom}      rotated0    catrom      297     32 20   #74b083 0.3490 {114 175 129 90} {116 176 131 89}} \
            {{left edge, linear}        smiley      linear      351     1 10    #564999 0.7294 {187 182 214 136} {86 73 153 186}} \
        ]
        
        set results {}
        foreach case $testcases {
            lassign $case descr img filter angle x y bg alpha shouldRes bgAlpha
            ::imgtools::rotate $img $angle -interpolation $filter -background $bg -alpha $alpha -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {} 
    
    #
    # interpolation that uses outside pixel:
    # these tests are obsolete - covered by previous section.
    # keep them anyway - they won't hurt :-)
    #
    test interpol-2.1 {interpolation with outsidePixel} -setup $setup -body {
        ::imgtools::rotate smiley 1 -background #000000 -alpha 0 destImg
        getPixel destImg 0 0
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 91}
    
    test interpol-2.2 {interpolation with outsidePixel} -setup $setup -body {
        ::imgtools::rotate smiley 32 -background #6090c0 -alpha 98.04% destImg
        getPixel destImg 15 3
    } -cleanup $cleanup -returnCodes ok -result {92 141 190 255}
    
    test interpol-2.3 {interpolation with outsidePixel} -setup $setup -body {
        ::imgtools::rotate smiley 5 -background #6090c0 -alpha 98.04% destImg
        getPixel destImg 15 7
    } -cleanup $cleanup -returnCodes ok -result {213 235 255 140}
       
    #
    # outsidePixel == NULL: cannot test case, as currently it is not used
    # by any function
    #
    
    #
    # weighted sum alpha == 0
    #
    test interpol-4.1 {sum of weighted alphas is 0} -setup $setup -body {
        ::imgtools::rotate rotated0 169 destImg
        getPixel destImg 20 7
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    test interpol-4.2 {sum of weighted alphas is 0} -setup $setup -body {
        ::imgtools::rotate rotated0 288 destImg
        getPixel destImg 21 25
    } -cleanup $cleanup -returnCodes ok -result {0 0 0 0}
    
    #
    # weightsSum == 0: shouldn't be possible - no tests
    #
    
    #
    # clipping and rounding
    #
    test interpol-6.1 {clipping down (val > 255)} -setup $setup -body {
        ::imgtools::rotate smiley 2 destImg
        getPixel destImg 12 13
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 112}
    
    test interpol-6.2 {clipping up (val < 0)} -setup $setup -body {
        ::imgtools::rotate smiley 55 destImg
        getPixel destImg 11 5
    } -cleanup $cleanup -returnCodes ok -result {9 9 0 255}
    
    test interpol-6.3 {rounding up} -setup $setup -body {
        ::imgtools::rotate rotated0 198 destImg
        getPixel destImg 11 5
    } -cleanup $cleanup -returnCodes ok -result {70 58 132 157}
    
    test interpol-6.4 {rounding down} -setup $setup -body {
        ::imgtools::rotate rotated0 228 destImg
        getPixel destImg 20 11
    } -cleanup $cleanup -returnCodes ok -result {0 4 10 243}
        
    #
    # single-color image: make sure there are no rounding errors.
    # matematically, in a single-color image the result
    # will always be _exactly_ equal to source values.
    # we shouldn't even get close to rounding errors.
    # just check a few random pixels
    #
    test interpol-7.1 {random pixel 1} -setup $setup -body {
        ::imgtools::rotate blueImg -301 -interpolation linear destImg
        getPixel destImg 12 6
    } -cleanup $cleanup -returnCodes ok -result {0 0 255 255}
    
    test interpol-7.2 {random pixel 2} -setup $setup -body {
        ::imgtools::rotate redImg -338 -interpolation catrom destImg
        getPixel destImg 10 14
    } -cleanup $cleanup -returnCodes ok -result {255 0 0 255}
    
    test interpol-7.3 {random pixel 3} -setup $setup -body {
        ::imgtools::rotate blueImg 113 -interpolation lanczos2 destImg
        getPixel destImg 14 5
    } -cleanup $cleanup -returnCodes ok -result {0 0 255 255}
    
    test interpol-7.4 {random pixel 4} -setup $setup -body {
        ::imgtools::rotate redImg 350 -interpolation lanczos3 destImg
        getPixel destImg 6 13
    } -cleanup $cleanup -returnCodes ok -result {255 0 0 255}
    
    
    #
    # check for rounding errors
    #
    test interpol-8.1 {rounding errors - result close to x.5, catrom} -setup $setup -body {
        ::imgtools::rotate smiley 33 destImg
        getPixel destImg 7 2
    } -cleanup $cleanup -returnCodes ok -result {255 255 255 123}
    
    test interpol-8.2 {rounding errors - result close to x.5, catrom} -setup $setup -body {
        ::imgtools::rotate smiley 197 destImg
        getPixel destImg 11 17
    } -cleanup $cleanup -returnCodes ok -result {254 254 254 102}
    
    test interpol-8.3 {rounding errors - result close to x.5, catrom} -setup $setup -body {
        ::imgtools::rotate rotated0 -179 destImg
        getPixel destImg 20 21
    } -cleanup $cleanup -returnCodes ok -result {255 255 0 232}
    
    test interpol-8.4 {rounding errors - result close to x.5, catrom} -setup $setup -body {
        ::imgtools::rotate rotated0 52 destImg
        getPixel destImg 20 34
    } -cleanup $cleanup -returnCodes ok -result {46 34 87 181}
    
    test interpol-8.5 {rounding errors - result close to x.5, lanczos and linear} -setup $setup -body {
        set testcases [list \
            {{rounding errors, linear}      photo   linear      -292    10 31 {17 17 19 255}} \
            {{rounding errors, lanczos2}    photo   lanczos2    -225    84 14 {96 82 69 255}} \
            {{rounding errors, lanczos3}    photo   lanczos3    325     70 46 {70 45 41 255}} \
        ]
        
        set results {}
        foreach case $testcases {
            lassign $case descr img filter angle x y shouldRes
            ::imgtools::rotate $img $angle -interpolation $filter -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {} 
    
    #
    # ### Imgtools_LinearInterpol ###
    #
    # This function is no longer used. 
    # The tests still make sense, though
    test linearinterpol-1.1 {The One Big Linear Test} -setup $setup -body {
        set testcases [list \
            {{random pixel #1} rotated0 189 20 23 #000000 0 {255 255 0 251}} \
            {{random pixel #2} rotated0 41 20 27 #000000 0 {0 0 0 31}} \
            {{random pixel #3} smiley 239 16 14 #000000 0 {230 230 230 122}} \
            {{random pixel #4} smiley -246 13 4 #000000 0 {72 72 72 190}} \
            {{top edge of src} smiley 104 16 8 #3d7df3 67.45% {242 246 254 118}} \
            {{right edge of src} smiley -282 9 16 #ead5ec .1451 {249 243 249 71}} \
            {{bottom edge of src} rotated0 -6 15 24 #d49dbb .7961 {85 133 70 233}} \
            {{left edge of src} rotated0 -117 20 43 #36de4f .1373 {54 222 79 23} } \
            {{NE corner of src} rotated0 193 38 29 #6ccc2b .3882 {108 204 43 82}} \
            {{NW corner of src} smiley 238 0 7 #19567a .9216 {79 126 153 189} } \
            {{SE corner of src} smiley 127 8 0 #d27a19 .7725 {222 157 86 166}} \
            {{SW corner of src} smiley 66 7 19 #dbd516 .3922 {227 223 76 103}} \
            {{weightedSums == 0, #1} rotated0 279 10 21 #000000 0 {0 0 0 0}} \
            {{weightedSums == 0, #2} smiley 199 7 18 #000000 0 {0 0 0 0}} \
            {{rounding errors #1} smiley 286 4 9 #000000 0 {68 68 0 237}} \
            {{rounding errors #2} smiley -189 5 3 #000000 0 {28 28 28 225}} \
            {{rounding errors #3} rotated0 290 31 9 #000000 0 {9 113 0 218} } \
            {{rounding errors #4} rotated0 311 30 20 #000000 0 {83 1 1 255} } \
        ]
        
        set results {}
        
        foreach case $testcases {
            lassign $case descr img angle x y bg alpha shouldRes
            ::imgtools::rotate $img $angle -interpolation linear -background $bg -alpha $alpha -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {} 
    
    #
    # ### Imgtools_NearestInterpol ###
    #
    # test some random pixels
    # left pixel, right pixel, same for above / below
    # interpolation with outside pixel (edges and corners)
    
    test nearestinterpol-1.1 {test for correct results} -setup $setup -body {
        set testcases [list \
            {{random pixel #1} rotated0 -44 29 13 #000000 0 {60 50 113 166}} \
            {{random pixel #2} rotated0 -290 11 9 #000000 0 {9 118 0 255}} \
            {{random pixel #3} smiley -187 7 5 #000000 0 {0 0 0 255}} \
            {{random pixel #4} smiley 25 12 14 #000000 0 {0 0 0 255}} \
            {{left pixels} rotated0 -126 13 9 #000000 0 {0 0 0 255}} \
            {{right pixels} rotated0 -5 25 17 #000000 0 {60 50 113 166}} \
            {{above pixels} smiley -229 5 8 #000000 0 {0 0 0 255}} \
            {{below pixels} smiley -104 12 10 #000000 0 {255 255 0 197}} \
            {{top edge, 142 250 182 231} smiley 158 16 15 #8efab6 .9059 {142 250 182 231}} \
            {{right edge, 30 66 98 129} smiley 55 16 15 #1e4262 .5059 {30 66 98 129}} \
            {{bottom edge, 94 195 23 78} rotated0 -158 35 10 #5ec317 .3059 {94 195 23 78}} \
            {{right edge, 209 158 21 16} rotated0 -27 2 22 #d19e15 .0627 {9 118 0 255}}\
            {{NW corner, 132 114 95 200} rotated0 -33 0 21 #84725f .7843 {0 0 0 0}} \
            {{NE corner, 181 189 150 6} rotated0 122 18 44 #b5bd96 .0235 {0 0 0 0}} \
            {{SW corner, 245 8 242 58} smiley -315 0 10 #f508f2 .2275 {255 255 255 115}} \
            {{SE corner, 185 22 66 90} smiley 135 0 10 #b91642 35.29% {255 255 255 115}} \
        ]
        
       set results {}
        
        foreach case $testcases {
            lassign $case descr img angle x y bg alpha shouldRes
            ::imgtools::rotate $img $angle -interpolation nearest -background $bg -alpha $alpha -compositingrule set -shrink destImg
            set calcRes [getPixel destImg $x $y]
            if {$calcRes ne $shouldRes} {
                append results "$descr: result was $calcRes, expected $shouldRes \n"
            }
        }
        set results
    } -cleanup $cleanup -returnCodes ok -result {} 
     
    #
    # ### Imgtools_*Filter functions ###
    #
    # tested through the interpolation tests
    
    
    cleanupTests
}
namespace delete ::imgtools::test::imgtools
    
