コード例 #1
0
  /**
   * Creates a bitmap from encoded JPEG bytes. Supports a partial JPEG image.
   *
   * @param encodedImage the encoded image with reference to the encoded bytes
   * @param bitmapConfig the {@link android.graphics.Bitmap.Config} used to create the decoded
   *     Bitmap
   * @param length the number of encoded bytes in the buffer
   * @return the bitmap
   * @exception java.lang.OutOfMemoryError if the Bitmap cannot be allocated
   */
  @Override
  public CloseableReference<Bitmap> decodeJPEGFromEncodedImage(
      EncodedImage encodedImage, Bitmap.Config bitmapConfig, int length) {
    boolean isJpegComplete = encodedImage.isCompleteAt(length);
    final BitmapFactory.Options options = getDecodeOptionsForStream(encodedImage, bitmapConfig);

    InputStream jpegDataStream = encodedImage.getInputStream();
    // At this point the InputStream from the encoded image should not be null since in the
    // pipeline,this comes from a call stack where this was checked before. Also this method needs
    // the InputStream to decode the image so this can't be null.
    Preconditions.checkNotNull(jpegDataStream);
    if (encodedImage.getSize() > length) {
      jpegDataStream = new LimitedInputStream(jpegDataStream, length);
    }
    if (!isJpegComplete) {
      jpegDataStream = new TailAppendingInputStream(jpegDataStream, EOI_TAIL);
    }
    boolean retryOnFail = options.inPreferredConfig != Bitmap.Config.ARGB_8888;
    try {
      return decodeStaticImageFromStream(jpegDataStream, options);
    } catch (RuntimeException re) {
      if (retryOnFail) {
        return decodeFromEncodedImage(encodedImage, Bitmap.Config.ARGB_8888);
      }
      throw re;
    }
  }
コード例 #2
0
    /** Performs the decode synchronously. */
    private void doDecode(EncodedImage encodedImage, boolean isLast) {
      if (isFinished() || !EncodedImage.isValid(encodedImage)) {
        return;
      }

      try {
        long queueTime = mJobScheduler.getQueuedTime();
        int length = isLast ? encodedImage.getSize() : getIntermediateImageEndOffset(encodedImage);
        QualityInfo quality = isLast ? ImmutableQualityInfo.FULL_QUALITY : getQualityInfo();

        mProducerListener.onProducerStart(mProducerContext.getId(), PRODUCER_NAME);
        CloseableImage image = null;
        try {
          image = mImageDecoder.decodeImage(encodedImage, length, quality, mImageDecodeOptions);
        } catch (Exception e) {
          Map<String, String> extraMap = getExtraMap(image, queueTime, quality, isLast);
          mProducerListener.onProducerFinishWithFailure(
              mProducerContext.getId(), PRODUCER_NAME, e, extraMap);
          handleError(e);
          return;
        }
        Map<String, String> extraMap = getExtraMap(image, queueTime, quality, isLast);
        mProducerListener.onProducerFinishWithSuccess(
            mProducerContext.getId(), PRODUCER_NAME, extraMap);
        handleResult(image, isLast);
      } finally {
        EncodedImage.closeSafely(encodedImage);
      }
    }
コード例 #3
0
 private boolean isResultGoodEnough(EncodedImage encodedimage, ImageRequest imagerequest) {
   while (encodedimage == null
       || encodedimage.getWidth() < imagerequest.getPreferredWidth()
       || encodedimage.getHeight() < imagerequest.getPreferredHeight()) {
     return false;
   }
   return true;
 }
コード例 #4
0
 @Test
 public void testEncodedMemoryCacheGetSuccessful() {
   setupEncodedMemoryCacheGetSuccess();
   when(mProducerContext.getLowestPermittedRequestLevel())
       .thenReturn(ImageRequest.RequestLevel.ENCODED_MEMORY_CACHE);
   mEncodedMemoryCacheProducer.produceResults(mConsumer, mProducerContext);
   ArgumentCaptor<EncodedImage> argumentCaptor = ArgumentCaptor.forClass(EncodedImage.class);
   verify(mConsumer).onNewResult(argumentCaptor.capture(), eq(true));
   EncodedImage encodedImage = argumentCaptor.getValue();
   Assert.assertSame(
       mFinalEncodedImage.getUnderlyingReferenceTestOnly(),
       encodedImage.getUnderlyingReferenceTestOnly());
   verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME);
   Map<String, String> extraMap = ImmutableMap.of(EncodedMemoryCacheProducer.VALUE_FOUND, "true");
   verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap);
   Assert.assertFalse(mFinalImageReference.isValid());
 }
コード例 #5
0
  /**
   * Options returned by this method are configured with mDecodeBuffer which is GuardedBy("this")
   */
  private static BitmapFactory.Options getDecodeOptionsForStream(
      EncodedImage encodedImage, Bitmap.Config bitmapConfig) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    // Sample size should ONLY be different than 1 when downsampling is enabled in the pipeline
    options.inSampleSize = encodedImage.getSampleSize();
    options.inJustDecodeBounds = true;
    // fill outWidth and outHeight
    BitmapFactory.decodeStream(encodedImage.getInputStream(), null, options);
    if (options.outWidth == -1 || options.outHeight == -1) {
      throw new IllegalArgumentException();
    }

    options.inJustDecodeBounds = false;
    options.inDither = true;
    options.inPreferredConfig = bitmapConfig;
    options.inMutable = true;

    return options;
  }
コード例 #6
0
 @Override
 public void onNewResultImpl(EncodedImage newResult, boolean isLast) {
   if (isLast && !EncodedImage.isValid(newResult)) {
     handleError(new NullPointerException("Encoded image is not valid."));
     return;
   }
   if (!updateDecodeJob(newResult, isLast)) {
     return;
   }
   if (isLast || mProducerContext.isIntermediateResultExpected()) {
     mJobScheduler.scheduleJob();
   }
 }
コード例 #7
0
 /**
  * Creates a bitmap from encoded bytes.
  *
  * @param encodedImage the encoded image with a reference to the encoded bytes
  * @param bitmapConfig the {@link android.graphics.Bitmap.Config} used to create the decoded
  *     Bitmap
  * @return the bitmap
  * @exception java.lang.OutOfMemoryError if the Bitmap cannot be allocated
  */
 @Override
 public CloseableReference<Bitmap> decodeFromEncodedImage(
     EncodedImage encodedImage, Bitmap.Config bitmapConfig) {
   final BitmapFactory.Options options = getDecodeOptionsForStream(encodedImage, bitmapConfig);
   boolean retryOnFail = options.inPreferredConfig != Bitmap.Config.ARGB_8888;
   try {
     return decodeStaticImageFromStream(encodedImage.getInputStream(), options);
   } catch (RuntimeException re) {
     if (retryOnFail) {
       return decodeFromEncodedImage(encodedImage, Bitmap.Config.ARGB_8888);
     }
     throw re;
   }
 }
コード例 #8
0
 @Override
 protected synchronized boolean updateDecodeJob(EncodedImage encodedImage, boolean isLast) {
   boolean ret = super.updateDecodeJob(encodedImage, isLast);
   if (!isLast && EncodedImage.isValid(encodedImage)) {
     if (!mProgressiveJpegParser.parseMoreData(encodedImage)) {
       return false;
     }
     int scanNum = mProgressiveJpegParser.getBestScanNumber();
     if (scanNum <= mLastScheduledScanNumber
         || scanNum
             < mProgressiveJpegConfig.getNextScanNumberToDecode(mLastScheduledScanNumber)) {
       return false;
     }
     mLastScheduledScanNumber = scanNum;
   }
   return ret;
 }
コード例 #9
0
 @Test
 public void testEncodedMemoryCacheGetNotFoundNextProducerSuccess() {
   setupEncodedMemoryCacheGetNotFound();
   setupNextProducerStreamingSuccess();
   mEncodedMemoryCacheProducer.produceResults(mConsumer, mProducerContext);
   verify(mMemoryCache, never()).cache(mCacheKey, mIntermediateImageReference);
   ArgumentCaptor<CloseableReference> argumentCaptor =
       ArgumentCaptor.forClass(CloseableReference.class);
   verify(mMemoryCache).cache(eq(mCacheKey), argumentCaptor.capture());
   CloseableReference<PooledByteBuffer> capturedRef =
       (CloseableReference<PooledByteBuffer>) argumentCaptor.getValue();
   Assert.assertSame(
       mFinalImageReference.getUnderlyingReferenceTestOnly(),
       capturedRef.getUnderlyingReferenceTestOnly());
   verify(mConsumer).onNewResult(mIntermediateEncodedImage, false);
   verify(mConsumer).onNewResult(mFinalEncodedImage, true);
   Assert.assertTrue(EncodedImage.isValid(mFinalEncodedImageClone));
   verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME);
   Map<String, String> extraMap = ImmutableMap.of(EncodedMemoryCacheProducer.VALUE_FOUND, "false");
   verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap);
 }
コード例 #10
0
 @Override
 protected int getIntermediateImageEndOffset(EncodedImage encodedImage) {
   return encodedImage.getSize();
 }