package main

import (
	"image"
	"image/color"
	"image/png"
	"os"
)

// processImage takes input png image from stdin, processes it with f and outputs it to stdout.
func processImage(f func(image.Image) image.Image) error {
	img, err := png.Decode(os.Stdin)
	if err != nil {
		return err
	}
	err = png.Encode(os.Stdout, f(img))
	if err != nil {
		return err
	}
	return err
}

type convert struct {
	image.Image
	color.Model
}

func (c convert) ColorModel() color.Model { return c.Model }
func (c convert) Bounds() image.Rectangle { return c.Image.Bounds() }
func (c convert) At(x, y int) color.Color { return c.Model.Convert(c.Image.At(x, y)) }

func grayscale(img image.Image) image.Image {
	return convert{img, color.GrayModel}
}

func main() {
	err := processImage(grayscale)
	if err != nil {
		panic(err)
	}
}
