function image_distance_pixel($xo, $yo, $x0, $y0)
{
    include_spip('filtres/images_lib');
    return _image_distance_pixel($xo, $yo, $x0, $y0);
}
function image_RotateBicubic($src_img, $angle, $bicubic = 0)
{
    include_spip('filtres/images_lib');
    if (round($angle / 90) * 90 == $angle) {
        $droit = true;
        if (round($angle / 180) * 180 == $angle) {
            $rot = 180;
        } else {
            $rot = 90;
        }
    } else {
        $droit = false;
    }
    // convert degrees to radians
    $angle = $angle + 180;
    $angle = deg2rad($angle);
    $src_x = imagesx($src_img);
    $src_y = imagesy($src_img);
    $center_x = floor(($src_x - 1) / 2);
    $center_y = floor(($src_y - 1) / 2);
    $cosangle = cos($angle);
    $sinangle = sin($angle);
    // calculer dimensions en simplifiant angles droits, ce qui evite "floutage"
    // des rotations a angle droit
    if (!$droit) {
        $corners = array(array(0, 0), array($src_x, 0), array($src_x, $src_y), array(0, $src_y));
        foreach ($corners as $key => $value) {
            $value[0] -= $center_x;
            //Translate coords to center for rotation
            $value[1] -= $center_y;
            $temp = array();
            $temp[0] = $value[0] * $cosangle + $value[1] * $sinangle;
            $temp[1] = $value[1] * $cosangle - $value[0] * $sinangle;
            $corners[$key] = $temp;
        }
        $min_x = 1000000000000000;
        $max_x = -1000000000000000;
        $min_y = 1000000000000000;
        $max_y = -1000000000000000;
        foreach ($corners as $key => $value) {
            if ($value[0] < $min_x) {
                $min_x = $value[0];
            }
            if ($value[0] > $max_x) {
                $max_x = $value[0];
            }
            if ($value[1] < $min_y) {
                $min_y = $value[1];
            }
            if ($value[1] > $max_y) {
                $max_y = $value[1];
            }
        }
        $rotate_width = ceil($max_x - $min_x);
        $rotate_height = ceil($max_y - $min_y);
    } else {
        if ($rot == 180) {
            $rotate_height = $src_y;
            $rotate_width = $src_x;
        } else {
            $rotate_height = $src_x;
            $rotate_width = $src_y;
        }
        $bicubic = false;
    }
    $rotate = imagecreatetruecolor($rotate_width, $rotate_height);
    imagealphablending($rotate, false);
    imagesavealpha($rotate, true);
    $cosangle = cos($angle);
    $sinangle = sin($angle);
    // arrondir pour rotations angle droit (car cos et sin dans {-1,0,1})
    if ($droit) {
        $cosangle = round($cosangle);
        $sinangle = round($sinangle);
    }
    $newcenter_x = ($rotate_width - 1) / 2;
    $newcenter_y = ($rotate_height - 1) / 2;
    for ($y = 0; $y < $rotate_height; $y++) {
        for ($x = 0; $x < $rotate_width; $x++) {
            // rotate...
            $old_x = ($newcenter_x - $x) * $cosangle + ($newcenter_y - $y) * $sinangle + $center_x;
            $old_y = ($newcenter_y - $y) * $cosangle - ($newcenter_x - $x) * $sinangle + $center_y;
            $old_x = ceil($old_x);
            $old_y = ceil($old_y);
            if ($old_x >= 0 && $old_x < $src_x && $old_y >= 0 && $old_y < $src_y) {
                if ($bicubic == true) {
                    $xo = $old_x;
                    $x0 = floor($xo);
                    $x1 = ceil($xo);
                    $yo = $old_y;
                    $y0 = floor($yo);
                    $y1 = ceil($yo);
                    // on prend chaque point, mais on pondere en fonction de la distance
                    $rgb = ImageColorAt($src_img, $x0, $y0);
                    $a1 = $rgb >> 24 & 0xff;
                    $r1 = $rgb >> 16 & 0xff;
                    $g1 = $rgb >> 8 & 0xff;
                    $b1 = $rgb & 0xff;
                    $d1 = _image_distance_pixel($xo, $yo, $x0, $y0);
                    $rgb = ImageColorAt($src_img, $x1, $y0);
                    $a2 = $rgb >> 24 & 0xff;
                    $r2 = $rgb >> 16 & 0xff;
                    $g2 = $rgb >> 8 & 0xff;
                    $b2 = $rgb & 0xff;
                    $d2 = _image_distance_pixel($xo, $yo, $x1, $y0);
                    $rgb = ImageColorAt($src_img, $x0, $y1);
                    $a3 = $rgb >> 24 & 0xff;
                    $r3 = $rgb >> 16 & 0xff;
                    $g3 = $rgb >> 8 & 0xff;
                    $b3 = $rgb & 0xff;
                    $d3 = _image_distance_pixel($xo, $yo, $x0, $y1);
                    $rgb = ImageColorAt($src_img, $x1, $y1);
                    $a4 = $rgb >> 24 & 0xff;
                    $r4 = $rgb >> 16 & 0xff;
                    $g4 = $rgb >> 8 & 0xff;
                    $b4 = $rgb & 0xff;
                    $d4 = _image_distance_pixel($xo, $yo, $x1, $y1);
                    $ac1 = (127 - $a1) / 127;
                    $ac2 = (127 - $a2) / 127;
                    $ac3 = (127 - $a3) / 127;
                    $ac4 = (127 - $a4) / 127;
                    // limiter impact des couleurs transparentes,
                    // mais attention tout transp: division par 0
                    if ($ac1 * $d1 + $ac2 * $d2 + $ac3 + $d3 + $ac4 + $d4 > 0) {
                        if ($ac1 > 0) {
                            $d1 = $d1 * $ac1;
                        }
                        if ($ac2 > 0) {
                            $d2 = $d2 * $ac2;
                        }
                        if ($ac3 > 0) {
                            $d3 = $d3 * $ac3;
                        }
                        if ($ac4 > 0) {
                            $d4 = $d4 * $ac4;
                        }
                    }
                    $tot = $d1 + $d2 + $d3 + $d4;
                    $r = round(($d1 * $r1 + $d2 * $r2 + $d3 * $r3 + $d4 * $r4) / $tot);
                    $g = round(($d1 * $g1 + $d2 * $g2 + $d3 * $g3 + $d4 * $g4) / $tot);
                    $b = round(($d1 * $b1 + $d2 * $b2 + $d3 * $b3 + $d4 * $b4) / $tot);
                    $a = round(($d1 * $a1 + $d2 * $a2 + $d3 * $a3 + $d4 * $a4) / $tot);
                    $color = imagecolorallocatealpha($src_img, $r, $g, $b, $a);
                } else {
                    $color = imagecolorat($src_img, round($old_x), round($old_y));
                }
            } else {
                // this line sets the background colour
                $color = imagecolorallocatealpha($src_img, 255, 255, 255, 127);
            }
            @imagesetpixel($rotate, $x, $y, $color);
        }
    }
    return $rotate;
}