If ENGINE_THREADPOOL_SIZE > 0, this will schedule the image operations
        into a threadpool.  If not, it just executes them synchronously, and
        calls self.done_callback when it's finished.

        The actual work happens in self.img_operation_worker

def do_image_operations(self):
        """
        If ENGINE_THREADPOOL_SIZE > 0, this will schedule the image operations
        into a threadpool.  If not, it just executes them synchronously, and
        calls self.done_callback when it's finished.

        The actual work happens in self.img_operation_worker
        """
        def inner(future):
            self.done_callback()

        self.context.thread_pool.queue(
            operation=self.img_operation_worker,
            callback=inner
        )