func (self *SizeSpec) ToRect(rect image.Rectangle) image.Rectangle {
	if self.full || self.Width() == -1 || self.Height() == -1 {
		return rect
	}
	if self.square {
		if rectIsSquare(rect) {
			return rect
		}
		if rectIsLandscape(rect) {
			trim := (rect.Dx() - rect.Dy()) / 2
			return image.Rect(trim, 0, rect.Dx()-trim, rect.Dy())
		} else {
			trim := (rect.Dy() - rect.Dx()) / 2
			return image.Rect(0, trim, rect.Dx(), rect.Dy()-trim)
		}
	}
	if self.width == self.height {
		return rect
	}
	if self.IsLandscape() {
		if rectIsSquare(rect) {
			ratio := float64(self.Height()) / float64(self.Width())
			targetHeight := int(ratio * float64(rect.Dx()))
			trim := targetHeight / 2
			return image.Rect(0, trim, rect.Dx(), rect.Dy()-trim)
		} else {
			if rectIsLandscape(rect) {
				ratio := float64(rect.Dy()) / float64(rect.Dx())
				outRatio := float64(self.Height()) / float64(self.Width())
				if ratio == outRatio {
					return rect
				}
				if outRatio > ratio {
				} else {
				}
				rHeight := int(float64(rect.Dy()) * ratio)
				trim := (rect.Dy() - rHeight) / 2
				return image.Rect(0, trim, rect.Dx(), rect.Dy()-trim)
			} else {
				ratio := float64(rect.Dx()) / float64(self.Width())
				rHeight := ratio * float64(self.Height())
				trim := int((float64(rect.Dy()) - rHeight) / 2)
				return image.Rect(0, trim, rect.Dx(), rect.Dy()-trim)
			}
		}
	} else {
		if rectIsSquare(rect) {
			ratio := float64(self.Width()) / float64(self.Height())
			targetWidth := int(ratio * float64(rect.Dy()))
			trim := (rect.Dx() - targetWidth) / 2
			return image.Rect(trim, 0, rect.Dx()-trim, rect.Dx())
		} else {
			if rectIsLandscape(rect) {
				ratio := float64(self.Width()) / float64(self.Height())
				targetWidth := int(ratio * float64(rect.Dy()))
				trim := (rect.Dx() - targetWidth) / 2
				return image.Rect(trim, 0, rect.Dx()-trim, rect.Dy())
			} else {
				ratio := float64(rect.Dx()) / float64(self.Width())
				rHeight := ratio * float64(self.Height())
				trim := int((float64(rect.Dy()) - rHeight) / 2)
				return image.Rect(0, trim, rect.Dx(), rect.Dy()-trim)
			}
		}
	}
	return rect
}
given an image size (as image.Rect), we match it up
to the SizeSpec and return a new image.Rect which is
essentially, the dimensions to crop the image to before scaling
package resize
import (
	"fmt"
	"image"
	"image/color"
	"regexp"
	"strconv"
)
type SizeSpec struct {
	width  int
	height int
	square bool
	full   bool
}
func MakeSizeSpec(str string) *SizeSpec {
	s := SizeSpec{}
	if str == "full" {
		s.full = true
		s.width = -1
		s.height = -1
		return &s
	}
	r, _ := regexp.Compile("\\d+s")
	if m := r.FindString(str); m != "" {
		w, _ := strconv.Atoi(m[:len(m)-1])
		s.width = w
		s.height = w
		s.square = true
		return &s
	}
	s.square = false
	s.full = false
	r, _ = regexp.Compile("\\d+w")
	if m := r.FindString(str); m != "" {
		w, _ := strconv.Atoi(m[:len(m)-1])
		s.width = w
	} else {
		s.width = -1
	}
	r, _ = regexp.Compile("\\d+h")
	if m := r.FindString(str); m != "" {
		h, _ := strconv.Atoi(m[:len(m)-1])
		s.height = h
	} else {
		s.height = -1
	}
	return &s
}
func (self SizeSpec) IsSquare() bool {
	return self.square
}
func (self SizeSpec) IsPortrait() bool {
	return self.height > self.width
}
func (self SizeSpec) IsLandscape() bool {
	return self.width > self.height
}
func (self SizeSpec) ToImageMagickSpec() string {
	if self.IsSquare() {
		return fmt.Sprintf("%dx%d^", self.width, self.width)
	}
	if self.width == -1 {
		return fmt.Sprintf("x%d", self.height)
	}
	if self.height == -1 {
		return fmt.Sprintf("%d", self.width)
	}
	return fmt.Sprintf("%dx%d", self.width, self.height)
}
func (self SizeSpec) String() string {
	if self.IsFull() {
		return "full"
	}
	if self.IsSquare() {
		return fmt.Sprintf("%ds", self.width)
	}
	if self.width == -1 {
		return fmt.Sprintf("%dh", self.height)
	}
	if self.height == -1 {
		return fmt.Sprintf("%dw", self.width)
	}
	return fmt.Sprintf("%dw%dh", self.width, self.height)
}
func (self SizeSpec) IsFull() bool {
	return self.full
}
func (self SizeSpec) Width() int {
	return self.width
}
func (self SizeSpec) Height() int {
	return self.height
}
func (self SizeSpec) MaxDimension() int {
	if self.width > self.height {
		return self.width
	}
	return self.height
}
func (self SizeSpec) MinDimension() int {
	if self.width < self.height {
		return self.width
	}
	return self.height
}
func rectMaxDimension(r image.Rectangle) int {
	if r.Dx() > r.Dy() {
		return r.Dx()
	}
	return r.Dy()
}
func rectMinDimension(r image.Rectangle) int {
	if r.Dx() < r.Dy() {
		return r.Dx()
	}
	return r.Dy()
}
func rectIsPortrait(r image.Rectangle) bool {
	return r.Dy() > r.Dx()
}
func rectIsLandscape(r image.Rectangle) bool {
	return r.Dx() > r.Dy()
}
func rectIsSquare(r image.Rectangle) bool {
	return r.Dx() == r.Dy()
}