flow = "image-analysis"
docs = "DESCRIPTION.md"
# Image analysis and enhancement — ALL algorithm logic in flowstdlib.
# ZERO WASM for algorithms. Only context functions for I/O.
#
# Demonstrates fan-out parallelism: pixel stream feeds min, max, avg,
# bin_count, AND contrast stretch — all simultaneously.
# Read input and output filenames from args
[[process]]
source = "context://args/get"
# Read input image as grayscale pixels (null-terminated stream)
[[process]]
source = "context://image/image_read"
[[connection]]
from = "get/string/1"
to = "image_read/filename"
########################################################################
# Statistics — all from pixel stream in PARALLEL (fan-out)
########################################################################
# Minimum pixel value
[[process]]
alias = "find_min"
source = "lib://flowstdlib/data/min"
input.partial = { once = 255 }
[[connection]]
from = "image_read/pixels_eof"
to = "find_min/value"
[[connection]]
from = "find_min/partial"
to = "find_min/partial"
# Maximum pixel value
[[process]]
alias = "find_max"
source = "lib://flowstdlib/data/max"
input.partial = { once = 0 }
[[connection]]
from = "image_read/pixels_eof"
to = "find_max/value"
[[connection]]
from = "find_max/partial"
to = "find_max/partial"
# Average pixel value
[[process]]
alias = "find_avg"
source = "lib://flowstdlib/data/avg"
input.partial_sum = { once = 0 }
input.partial_count = { once = 0 }
[[connection]]
from = "image_read/pixels_eof"
to = "find_avg/value"
[[connection]]
from = "find_avg/partial_sum"
to = "find_avg/partial_sum"
[[connection]]
from = "find_avg/partial_count"
to = "find_avg/partial_count"
# Histogram bins (256 bins for grayscale 0-255)
[[process]]
alias = "histogram"
source = "lib://flowstdlib/data/bin_count"
input.partial = { once = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] }
[[connection]]
from = "image_read/pixels_eof"
to = "histogram/value"
[[connection]]
from = "histogram/partial"
to = "histogram/partial"
# Output statistics to stdout (accepts numbers directly)
[[process]]
source = "context://stdio/stdout"
[[connection]]
from = "find_min/result"
to = "stdout"
[[connection]]
from = "find_max/result"
to = "stdout"
[[connection]]
from = "find_avg/result"
to = "stdout"
[[connection]]
from = "find_avg/count"
to = "stdout"
########################################################################
# Contrast stretch — (pixel - min) * 255 / (max - min)
########################################################################
[[process]]
alias = "offset"
source = "lib://flowstdlib/math/subtract"
[[connection]]
from = "image_read/pixels"
to = "offset/i1"
[[connection]]
from = "find_min/result"
to = "offset/i2"
[[connection]]
from = "offset/i2"
to = "offset/i2"
[[process]]
alias = "scale"
source = "lib://flowstdlib/math/multiply"
input.i2 = { always = 255 }
[[connection]]
from = "offset"
to = "scale/i1"
[[process]]
alias = "range_calc"
source = "lib://flowstdlib/math/subtract"
[[connection]]
from = "find_max/result"
to = "range_calc/i1"
[[connection]]
from = "find_min/result"
to = "range_calc/i2"
[[process]]
alias = "stretch"
source = "lib://flowstdlib/math/divide"
[[connection]]
from = "scale"
to = "stretch/dividend"
[[connection]]
from = "range_calc"
to = "stretch/divisor"
[[connection]]
from = "stretch/divisor"
to = "stretch/divisor"
# Accumulate stretched pixels
[[process]]
alias = "collect"
source = "lib://flowstdlib/data/accumulate"
input.partial = { once = [] }
[[process]]
alias = "pixel_count"
source = "lib://flowstdlib/math/multiply"
[[connection]]
from = "image_read/width"
to = "pixel_count/i1"
[[connection]]
from = "image_read/height"
to = "pixel_count/i2"
[[connection]]
from = "pixel_count"
to = "collect/chunk_size"
[[connection]]
from = "stretch/result"
to = "collect/values"
[[connection]]
from = "collect/chunk_size"
to = "collect/chunk_size"
[[connection]]
from = "collect/partial"
to = "collect/partial"
# Write enhanced image
[[process]]
source = "context://image/image_write"
[[connection]]
from = "collect/chunk"
to = "image_write/grid"
[[connection]]
from = "image_read/width"
to = "image_write/width"
[[connection]]
from = "get/string/2"
to = "image_write/filename"
########################################################################
# Histogram visualization
########################################################################
[[process]]
alias = "chart"
source = "lib://flowstdlib/charts/histogram"
[[connection]]
from = "histogram/bins"
to = "chart/bins"
[[process]]
source = "write_histogram"
[[connection]]
from = "chart/grid"
to = "write_histogram/grid"
[[connection]]
from = "get/string/3"
to = "write_histogram/filename"