private void performDecode(DecodeTask currentDecodeTask) throws IOException {
    if (isTaskDead(currentDecodeTask)) {
      Log.d(DECODE_SERVICE, "Skipping decode task for page " + currentDecodeTask.pageNumber);
      return;
    }
    Log.d(DECODE_SERVICE, "Starting decode of page: " + currentDecodeTask.pageNumber);
    CodecPage vuPage = getPage(currentDecodeTask.pageNumber);
    preloadNextPage(currentDecodeTask.pageNumber);

    if (isTaskDead(currentDecodeTask)) {
      return;
    }
    Log.d(DECODE_SERVICE, "Start converting map to bitmap");
    float scale = calculateScale(vuPage) * currentDecodeTask.zoom;
    final Bitmap bitmap =
        vuPage.renderBitmap(
            getScaledWidth(currentDecodeTask, vuPage, scale),
            getScaledHeight(currentDecodeTask, vuPage, scale),
            currentDecodeTask.pageSliceBounds);
    Log.d(DECODE_SERVICE, "Converting map to bitmap finished");
    if (isTaskDead(currentDecodeTask)) {
      bitmap.recycle();
      return;
    }
    finishDecoding(currentDecodeTask, bitmap);
  }
 private CodecPage getPage(int pageIndex) {
   if (!pages.containsKey(pageIndex) || pages.get(pageIndex).get() == null) {
     pages.put(pageIndex, new SoftReference<CodecPage>(document.getPage(pageIndex)));
     pageEvictionQueue.remove(pageIndex);
     pageEvictionQueue.offer(pageIndex);
     if (pageEvictionQueue.size() > PAGE_POOL_SIZE) {
       Integer evictedPageIndex = pageEvictionQueue.poll();
       CodecPage evictedPage = pages.remove(evictedPageIndex).get();
       if (evictedPage != null) {
         evictedPage.recycle();
       }
     }
   }
   return pages.get(pageIndex).get();
 }
 private void waitForDecode(CodecPage vuPage) {
   vuPage.waitForDecode();
 }
 private float calculateScale(CodecPage codecPage) {
   return 1.0f * getTargetWidth() / codecPage.getWidth();
 }
 private int getScaledWidth(CodecPage vuPage, float scale) {
   return (int) (scale * vuPage.getWidth());
 }
 private int getScaledHeight(CodecPage vuPage, float scale) {
   return (int) (scale * vuPage.getHeight());
 }