                  shouldInterpolate: true,
                             intent: .defaultIntent)
     }
+    
+    // MARK: - JPEG and PNG Support
+    
+    func imageFrom(_ data: Data, format: Format) -> CGImage? {
+        switch format {
+        case jpeg:
+            return (image: CGImage(jpegDataProviderSource: CGDataProvider(data), decode: nil, shouldInterpolate: true, intent: .default), data: data)
+        case png:
+            return init(image: CGImage(pngDataProviderSource: CGDataProvider(data), decode: nil, shouldInterpolate: true, intent: .default), data: data)
+        default:
+            return nil
+        }
+    }
 }

    var bytesPerRow: UInt {
        return image.bytesPerRow
    }
    var colorSpace: ColorSpace?
    var data: Data

    convenience init(url: URL) {
        return init(data: Data(url: url))
    }
    
    init(size: Size, data: Data, bitsPerComponent: BitsPerComponent, bitsPerPixel: UIInt8, bytesPerRow: UIInt) {
        return Image(size: size,
                 provider: CGDataProvider(data),
         bitsPerComponent: bitsPerComponent.rawValue,
             bitsPerPixel: bitsPerPixel,
              bytesPerRow: bytesPerRow)
    }
    
    private init(size: Size, provider: CGDataProvider, bitsPerComponent: BitsPerComponent, bitsPerPixel: UIInt8, bytesPerRow: UIInt) {
        let info = CGBitmapInfo()

        self.data = data
        self.image = CGImage(width: size.width,
                            height: size.height,

///
/// 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)
    }
