private Bitmap tryLoadBitmap() throws TaskCancelledException {
    File imageFile = getImageFileInDiscCache();

    Bitmap bitmap = null;
    try {
      String cacheFileUri = Scheme.FILE.wrap(imageFile.getAbsolutePath());
      if (imageFile.exists()) {
        log(LOG_LOAD_IMAGE_FROM_DISC_CACHE);
        loadedFrom = LoadedFrom.DISC_CACHE;

        checkTaskNotActual();
        bitmap = decodeImage(cacheFileUri);
      }
      if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
        log(LOG_LOAD_IMAGE_FROM_NETWORK);
        loadedFrom = LoadedFrom.NETWORK;

        String imageUriForDecoding =
            options.isCacheOnDisc() && tryCacheImageOnDisc(imageFile) ? cacheFileUri : uri;

        checkTaskNotActual();
        bitmap = decodeImage(imageUriForDecoding);

        if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
          fireFailEvent(FailType.DECODING_ERROR, null);
        }
      }
    } catch (IllegalStateException e) {
      fireFailEvent(FailType.NETWORK_DENIED, null);
    } catch (TaskCancelledException e) {
      throw e;
    } catch (IOException e) {
      L.e(e);
      fireFailEvent(FailType.IO_ERROR, e);
      if (imageFile.exists()) {
        imageFile.delete();
      }
    } catch (OutOfMemoryError e) {
      L.e(e);
      fireFailEvent(FailType.OUT_OF_MEMORY, e);
    } catch (Throwable e) {
      L.e(e);
      fireFailEvent(FailType.UNKNOWN, e);
    }
    return bitmap;
  }
 /** @return <b>true</b> - if task should be interrupted; <b>false</b> - otherwise */
 private boolean delayIfNeed() {
   if (options.shouldDelayBeforeLoading()) {
     log(LOG_DELAY_BEFORE_LOADING, options.getDelayBeforeLoading(), memoryCacheKey);
     try {
       Thread.sleep(options.getDelayBeforeLoading());
     } catch (InterruptedException e) {
       L.e(LOG_TASK_INTERRUPTED, memoryCacheKey);
       return true;
     }
     return isTaskNotActual();
   }
   return false;
 }
 /** @return <b>true</b> - if task should be interrupted; <b>false</b> - otherwise */
 private boolean waitIfPaused() {
   AtomicBoolean pause = engine.getPause();
   if (pause.get()) {
     synchronized (engine.getPauseLock()) {
       if (pause.get()) {
         log(LOG_WAITING_FOR_RESUME);
         try {
           engine.getPauseLock().wait();
         } catch (InterruptedException e) {
           L.e(LOG_TASK_INTERRUPTED, memoryCacheKey);
           return true;
         }
         log(LOG_RESUME_AFTER_PAUSE);
       }
     }
   }
   return isTaskNotActual();
 }
 /** Decodes image file into Bitmap, resize it and save it back */
 private boolean resizeAndSaveImage(File targetFile, int maxWidth, int maxHeight)
     throws IOException {
   // Decode image file, compress and re-save it
   ImageSize targetImageSize = new ImageSize(maxWidth, maxHeight);
   DisplayImageOptions specialOptions =
       new DisplayImageOptions.Builder()
           .cloneFrom(options)
           .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
           .build();
   ImageDecodingInfo decodingInfo =
       new ImageDecodingInfo(
           memoryCacheKey,
           Scheme.FILE.wrap(targetFile.getAbsolutePath()),
           targetImageSize,
           ViewScaleType.FIT_INSIDE,
           getDownloader(),
           specialOptions);
   Bitmap bmp = decoder.decode(decodingInfo);
   if (bmp != null && configuration.processorForDiscCache != null) {
     log(LOG_PROCESS_IMAGE_BEFORE_CACHE_ON_DISC);
     bmp = configuration.processorForDiscCache.process(bmp);
     if (bmp == null) {
       L.e(ERROR_PROCESSOR_FOR_DISC_CACHE_NULL, memoryCacheKey);
     }
   }
   if (bmp != null) {
     OutputStream os = new BufferedOutputStream(new FileOutputStream(targetFile), BUFFER_SIZE);
     try {
       bmp.compress(
           configuration.imageCompressFormatForDiscCache,
           configuration.imageQualityForDiscCache,
           os);
     } finally {
       IoUtils.closeSilently(os);
     }
     bmp.recycle();
   }
   return true;
 }
  /** @return <b>true</b> - if image was downloaded successfully; <b>false</b> - otherwise */
  private boolean tryCacheImageOnDisc(File targetFile) throws TaskCancelledException {
    log(LOG_CACHE_IMAGE_ON_DISC);

    boolean loaded = false;
    try {
      loaded = downloadImage(targetFile);
      if (loaded) {
        int width = configuration.maxImageWidthForDiscCache;
        int height = configuration.maxImageHeightForDiscCache;
        if (width > 0 || height > 0) {
          log(LOG_RESIZE_CACHED_IMAGE_FILE);
          loaded = resizeAndSaveImage(targetFile, width, height); // TODO : process boolean result
        }

        configuration.discCache.put(uri, targetFile);
      }
    } catch (IOException e) {
      L.e(e);
      if (targetFile.exists()) {
        targetFile.delete();
      }
    }
    return loaded;
  }
 private void log(String message, Object... args) {
   if (writeLogs) L.d(message, args);
 }
 private void log(String message) {
   if (writeLogs) L.d(message, memoryCacheKey);
 }
  @Override
  public void run() {
    if (waitIfPaused()) return;
    if (delayIfNeed()) return;

    ReentrantLock loadFromUriLock = imageLoadingInfo.loadFromUriLock;
    log(LOG_START_DISPLAY_IMAGE_TASK);
    if (loadFromUriLock.isLocked()) {
      log(LOG_WAITING_FOR_IMAGE_LOADED);
    }

    loadFromUriLock.lock();
    Bitmap bmp;
    try {
      checkTaskNotActual();

      bmp = configuration.memoryCache.get(memoryCacheKey);
      if (bmp == null) {
        bmp = tryLoadBitmap();
        if (bmp == null) return; // listener callback already was fired

        checkTaskNotActual();
        checkTaskInterrupted();

        if (options.shouldPreProcess()) {
          log(LOG_PREPROCESS_IMAGE);
          bmp = options.getPreProcessor().process(bmp);
          if (bmp == null) {
            L.e(ERROR_PRE_PROCESSOR_NULL, memoryCacheKey);
          }
        }

        if (bmp != null && options.isCacheInMemory()) {
          log(LOG_CACHE_IMAGE_IN_MEMORY);
          configuration.memoryCache.put(memoryCacheKey, bmp);
        }
      } else {
        loadedFrom = LoadedFrom.MEMORY_CACHE;
        log(LOG_GET_IMAGE_FROM_MEMORY_CACHE_AFTER_WAITING);
      }

      if (bmp != null && options.shouldPostProcess()) {
        log(LOG_POSTPROCESS_IMAGE);
        bmp = options.getPostProcessor().process(bmp);
        if (bmp == null) {
          L.e(ERROR_POST_PROCESSOR_NULL, memoryCacheKey);
        }
      }
      checkTaskNotActual();
      checkTaskInterrupted();
    } catch (TaskCancelledException e) {
      fireCancelEvent();
      return;
    } finally {
      loadFromUriLock.unlock();
    }

    DisplayBitmapTask displayBitmapTask =
        new DisplayBitmapTask(bmp, imageLoadingInfo, engine, loadedFrom);
    displayBitmapTask.setLoggingEnabled(writeLogs);
    runTask(displayBitmapTask, options.isSyncLoading(), handler);
  }