Image support

@jakebolewski this is your image branch rebased against current master. 
What would be needed in your opinion to push this forward. The functionality worked great when I tested it some time ago.
A more julian way to write functions like these is:
```
nchannels(::Type{Red}) = 1
nchannels(::Type{Alpha}) = 1
nchannels(::Type{RG}) = 2
...
```
The advantage of this formulation is that the compiler can do the evaluation more easily during type inference. For example:
```
julia> @code_llvm nchannels(BGRA)

define i64 @julia_nchannels_64752(%jl_value_t*) {
top:
  %1 = alloca [4 x %jl_value_t*], align 8
  %.sub = getelementptr inbounds [4 x %jl_value_t*]* %1, i64 0, i64 0
  store %jl_value_t* inttoptr (i64 4 to %jl_value_t*), %jl_value_t** %.sub, align 8
  %2 = getelementptr [4 x %jl_value_t*]* %1, i64 0, i64 1, !dbg !541
  %3 = load %jl_value_t*** @jl_pgcstack, align 8, !dbg !541
  %.c = bitcast %jl_value_t** %3 to %jl_value_t*, !dbg !541
  store %jl_value_t* %.c, %jl_value_t** %2, align 8, !dbg !541
  store %jl_value_t** %.sub, %jl_value_t*** @jl_pgcstack, align 8, !dbg !541
  %4 = getelementptr [4 x %jl_value_t*]* %1, i64 0, i64 2
  store %jl_value_t* null, %jl_value_t** %4, align 8
  %5 = getelementptr [4 x %jl_value_t*]* %1, i64 0, i64 3
  store %jl_value_t* null, %jl_value_t** %5, align 8
  %6 = load %jl_value_t** %2, align 8, !dbg !542
  %7 = getelementptr inbounds %jl_value_t* %6, i64 0, i32 0, !dbg !542
  store %jl_value_t** %7, %jl_value_t*** @jl_pgcstack, align 8, !dbg !542
  ret i64 4, !dbg !542
}

julia> mynchannels(::Type{BGRA}) = 4
mynchannels (generic function with 1 method)

julia> mynchannels(BGRA)
4

julia> @code_llvm mynchannels(BGRA)

define i64 @julia_mynchannels_64758(%jl_value_t*) {
top:
  ret i64 4, !dbg !559
}
```