     }
 }
 
+// MARK: - ImageLoaderDelegate
+
+public protocol ImageLoaderDelegate {
+    func imageLoader(loader: ImageLoader, shouldProcessImage image: Image) -> Bool
+    func imageLoader(loader: ImageLoader, decompressorForRequest request: ImageRequest) -> ImageProcessing?
+}
+
+extension ImageLoaderDelegate {
+    /** Returns true when image loader should process image. Processing includes both decompressing.
+    */
+    public func imageLoader(loader: ImageLoader, shouldProcessImage image: Image) -> Bool {
+        return true
+    }
+    
+    public func imageLoader(loader: ImageLoader, decompressorForRequest request: ImageRequest) -> ImageProcessing? {
+        #if !os(OSX)
+            if request.shouldDecompressImage {
+                return ImageDecompressor(targetSize: request.targetSize, contentMode: request.contentMode)
+            }
+        #endif
+        return nil
+    }
+}
+
+public class ImageLoaderDefaultDelegate: ImageLoaderDelegate {
+    public init() {}
+}
+
 // MARK: - ImageLoader
 
 /** Implements image loading using objects conforming to ImageDataLoading, ImageDecoding and ImageProcessing protocols. Reuses data tasks for multiple equivalent image tasks.

    }
    
    private func processImage(image: Image?, error: ErrorType?, forImageTask imageTask: ImageTask) {
        if let image = image, processor = self.processorForRequest(imageTask.request) {
            let operation = NSBlockOperation { [weak self] in
                self?.imageTask(imageTask, didCompleteWithImage: processor.processImage(image), error: error)
            }

    private func processorForRequest(request: ImageRequest) -> ImageProcessing? {
        var processors = [ImageProcessing]()
        #if !os(OSX)
        if request.shouldDecompressImage, let decompressor = self.delegate.imageLoader(self, decompressorForRequest: request) {
            processors.append(decompressor)
        }
        #endif
        if let processor = request.processor {
