Rebol3 Code Examplex


Bilinear interpolation

Interpolate values across a 2D grid.

Rebol [
    title: "Rosetta code: Bilinear interpolation"
    file:  %Bilinear_interpolation.r3
    url:   https://rosettacode.org/wiki/Bilinear_interpolation
]

;; Use the native lerp if available (Rebol 3.21.8+),
;; otherwise fall back to a pure Rebol implementation
unless function? :lerp [
    lerp: func [s e t] [s + ((e - s) * t)]
]

bilinear-scale: function [
    "Bilinear image interpolation"
    image [image!] "Source image to scale"
    scale [pair! number!] "Scale factor"
][
    src-size: image/size
    output: make image! new-size: src-size * scale  ; Allocate destination image
    wide:     src-size/x                            ; Source dimensions
    high:     src-size/y
    new-wide: output/size/x                         ; Destination dimensions
    new-high: output/size/y

    w-1: wide - 1  ; Max valid source X index
    h-1: high - 1  ; Max valid source Y index

    for y 0 (new-high - 1) 1 [
        for x 0 (new-wide - 1) 1 [
            ; Map destination pixel to fractional source coordinate
            gx: (x / new-wide) * w-1
            gy: (y / new-high) * h-1
            ; Integer top-left neighbor
            gxi0: to integer! gx
            gyi0: to integer! gy
            ; Bottom-right neighbor, clamped to image edge
            gxi1: min (gxi0 + 1) w-1
            gyi1: min (gyi0 + 1) h-1
            ; Sample the 2x2 neighborhood
            c00: image/(1 + as-pair gxi0 gyi0)  ; Top-left
            c10: image/(1 + as-pair gxi1 gyi0)  ; Top-right
            c01: image/(1 + as-pair gxi0 gyi1)  ; Bottom-left
            c11: image/(1 + as-pair gxi1 gyi1)  ; Bottom-right
            ; Fractional offset within the 2x2 neighborhood
            tx: gx - gxi0
            ty: gy - gyi0
            ; Bilinear blend: interpolate horizontally then vertically
            clr: lerp (lerp c00 c10 tx) (lerp c01 c11 tx) ty

            output/(1 + as-pair x y): clr    
        ]
    ]
    output
]

; -- Demo --
unless exists? image-file: %Lenna100.jpg [
    write image-file
     read https://static.wikitide.net/rosettacodewiki/b/b6/Lenna100.jpg
]
img: load image-file
out: bilinear-scale img 160%
browse save %Lenna100-larger.png out