 ///
 /// To draw an image, use 2DContext.drawImage(:in:).
 open struct Image {
+
+    typealias Source = (data: Data, format: Format) -> CGImage?
+
+    static var formatFileExtensions: [String: Format] =  ["jpeg": .jpeg, "jpg": .jpeg, "png": .png]
+    static var formatSources: [Format: Source] = [.jpeg: imageFrom(_:format:), .png = imageFrom(_:format:)]
+
+    /// Default supported image formats.
+    enum Format: UInt8 {
+        case jpeg
+        case png
+    }
+    
+    enum Error: Swift.Error {
+        case unsupportedFormat
+    }
     
     private var image: CGImage
+    /// The image type.
+    ///
+    /// For formats supported by Tapestry, returns a Format enum raw value.
+    /// For other formats, must return a custom constant higher than 128.
+    let format: UInt8
     let size: Size {
         return Size(image.size.width, image.size.height)
     }

                 shouldInterpolate: true,
                            intent: .defaultIntent)
    }
}

    var bytesPerRow: UInt {
        return image.bytesPerRow
    }
    var colorSpace: ColorSpace {
        return ColorSpace(image.colorSpace)
    }
    var data: Data
    
    // MARK: - Initialization

    convenience init(url: URL) throws {
        guard let format = formatFileExtensions[url.pathExtension] else {
            throw Error.unsupportedImageFormat
        }
        return init(data: Data(url: url), format: format)
    }
    
    required init(data: Data, format: Format) throws {
        guard let image = formatSources[format](data, format: format) else {
            throw Error.unsupportedFormat
        }
        self.image = image
        self.data = data
        self.format = format
    }
    
    required init(size: Size) {
    
    }
    
    private required init(size: Size, bitsPerComponent: BitsPerComponent, bitsPerPixel: UIInt8, bytesPerRow: UIInt, info: CGBitmapInfo, provider: CGDataProvider) {
        self.data = data
        self.image = CGImage(width: size.width,
                            height: size.height,
