@DoNotStrip public static Bitmap hookDecodeResourceStream( Resources res, TypedValue value, InputStream is, Rect pad, BitmapFactory.Options opts) { if (opts == null) { opts = new BitmapFactory.Options(); } if (opts.inDensity == 0 && value != null) { final int density = value.density; if (density == TypedValue.DENSITY_DEFAULT) { opts.inDensity = DisplayMetrics.DENSITY_DEFAULT; } else if (density != TypedValue.DENSITY_NONE) { opts.inDensity = density; } } if (opts.inTargetDensity == 0 && res != null) { opts.inTargetDensity = res.getDisplayMetrics().densityDpi; } return hookDecodeStream(is, pad, opts); }
@DoNotStrip public static Bitmap hookDecodeResource( Resources res, int id, BitmapFactory.Options opts) { Bitmap bm = null; TypedValue value = new TypedValue(); try (InputStream is = res.openRawResource(id, value)) { bm = hookDecodeResourceStream(res, value, is, null, opts); } catch (Exception e) { // Keep resulting bitmap as null } if (IN_BITMAP_SUPPORTED && bm == null && opts != null && opts.inBitmap != null) { throw new IllegalArgumentException("Problem decoding into existing bitmap"); } return bm; }
@DoNotStrip private static float getScaleFromOptions(BitmapFactory.Options options) { float scale = 1.0f; if (options != null) { int sampleSize = options.inSampleSize; if (sampleSize > 1) { scale = 1.0f / (float) sampleSize; } if (options.inScaled) { int density = options.inDensity; int targetDensity = options.inTargetDensity; int screenDensity = options.inScreenDensity; if (density != 0 && targetDensity != 0 && density != screenDensity) { scale = targetDensity / (float) density; } } } return scale; }
@DoNotStrip public AnimatedFactoryV2Impl( PlatformBitmapFactory platformBitmapFactory, ExecutorSupplier executorSupplier, CountingMemoryCache<CacheKey, CloseableImage> backingCache) { mPlatformBitmapFactory = platformBitmapFactory; mExecutorSupplier = executorSupplier; mBackingCache = backingCache; }
@DoNotStrip public static Bitmap hookDecodeByteArray( byte[] array, int offset, int length, BitmapFactory.Options opts) { StaticWebpNativeLoader.ensure(); Bitmap bitmap; if (WebpSupportStatus.sIsWebpSupportRequired && isWebpHeader(array, offset, length)) { bitmap = nativeDecodeByteArray( array, offset, length, opts, getScaleFromOptions(opts), getInTempStorageFromOptions(opts)); // We notify that the direct decoding failed if (bitmap == null) { sendWebpErrorLog("webp_direct_decode_array"); } setWebpBitmapOptions(bitmap, opts); } else { bitmap = originalDecodeByteArray(array, offset, length, opts); if (bitmap == null) { sendWebpErrorLog("webp_direct_decode_array_failed_on_no_webp"); } } return bitmap; }
@DoNotStrip private static Bitmap originalDecodeByteArray( byte[] array, int offset, int length, BitmapFactory.Options opts) { return BitmapFactory.decodeByteArray(array, offset, length, opts); }
@DoNotStrip public static Bitmap hookDecodeByteArray( byte[] array, int offset, int length) { return hookDecodeByteArray(array, offset, length, null); }
@DoNotStrip private static Bitmap originalDecodeByteArray( byte[] array, int offset, int length) { return BitmapFactory.decodeByteArray(array, offset, length); }
@DoNotStrip public static Bitmap hookDecodeStream( InputStream inputStream, Rect outPadding, BitmapFactory.Options opts) { StaticWebpNativeLoader.ensure(); inputStream = wrapToMarkSupportedStream(inputStream); Bitmap bitmap; byte[] header = getWebpHeader(inputStream, opts); if (WebpSupportStatus.sIsWebpSupportRequired && isWebpHeader(header, 0, HEADER_SIZE)) { bitmap = nativeDecodeStream( inputStream, opts, getScaleFromOptions(opts), getInTempStorageFromOptions(opts)); // We notify that the direct decoder failed if (bitmap == null) { sendWebpErrorLog("webp_direct_decode_stream"); } setWebpBitmapOptions(bitmap, opts); setPaddingDefaultValues(outPadding); } else { bitmap = originalDecodeStream(inputStream, outPadding, opts); if (bitmap == null) { sendWebpErrorLog("webp_direct_decode_stream_failed_on_no_webp"); } } return bitmap; }
@DoNotStrip private static Bitmap originalDecodeStream( InputStream inputStream, Rect outPadding, BitmapFactory.Options opts) { return BitmapFactory.decodeStream(inputStream, outPadding, opts); }
@DoNotStrip public static Bitmap hookDecodeFile( String pathName, BitmapFactory.Options opts) { Bitmap bitmap = null; try (InputStream stream = new FileInputStream(pathName)) { bitmap = hookDecodeStream(stream, null, opts); } catch (Exception e) { // Ignore, will just return null } return bitmap; }
@DoNotStrip private static Bitmap originalDecodeResourceStream( Resources res, TypedValue value, InputStream is, Rect pad, BitmapFactory.Options opts) { return BitmapFactory.decodeResourceStream(res, value, is, pad, opts); }
@DoNotStrip private static Bitmap originalDecodeResource( Resources res, int id, BitmapFactory.Options opts) { return BitmapFactory.decodeResource(res, id, opts); }
@DoNotStrip private static boolean setOutDimensions( BitmapFactory.Options options, int imageWidth, int imageHeight) { if (options != null && options.inJustDecodeBounds) { options.outWidth = imageWidth; options.outHeight = imageHeight; return true; } return false; }
@DoNotStrip private static void setPaddingDefaultValues(@Nullable Rect padding) { if (padding != null) { padding.top = -1; padding.left = -1; padding.bottom = -1; padding.right = -1; } }
@DoNotStrip private static void setBitmapSize( @Nullable BitmapFactory.Options options, int width, int height) { if (options != null) { options.outWidth = width; options.outHeight = height; } }
@DoNotStrip private static Bitmap originalDecodeFileDescriptor( FileDescriptor fd, Rect outPadding, BitmapFactory.Options opts) { return BitmapFactory.decodeFileDescriptor(fd, outPadding, opts); }
@DoNotStrip @SuppressLint("NewApi") private static boolean shouldPremultiply(BitmapFactory.Options options) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && options != null) { return options.inPremultiplied; } return true; }
@DoNotStrip private static Bitmap createBitmap(int width, int height, BitmapFactory.Options options) { if (IN_BITMAP_SUPPORTED && options != null && options.inBitmap != null && options.inBitmap.isMutable()) { return options.inBitmap; } return mBitmapCreator.createNakedBitmap(width, height, Bitmap.Config.ARGB_8888); }
@DoNotStrip private static native Bitmap nativeDecodeByteArray( byte[] data, int offset, int length, BitmapFactory.Options opts, float scale, byte[] inTempStorage);
@DoNotStrip private static byte[] getInTempStorageFromOptions(@Nullable final BitmapFactory.Options options) { if (options != null && options.inTempStorage != null) { return options.inTempStorage; } else { return new byte[IN_TEMP_BUFFER_SIZE]; } }
/** * Copy count bytes pointed by mNativePtr to array, starting at position offset */ @DoNotStrip private static native void nativeCopyToByteArray( long address, byte[] array, int offset, int count);
/** * Copy count bytes from byte array to native memory pointed by mNativePtr. */ @DoNotStrip private static native void nativeCopyFromByteArray( long address, byte[] array, int offset, int count);
@DoNotStrip private static native void nativeCopyBitmap( Bitmap dest, int destStride, Bitmap src, int srcStride, int rows);
@DoNotStrip private static native void nativeTranscodeJpeg( InputStream inputStream, OutputStream outputStream, int rotationAngle, int scaleNominator, int quality) throws IOException;
@DoNotStrip private static native void nativeTranscodeJpegWithExifOrientation( InputStream inputStream, OutputStream outputStream, int exifOrientation, int scaleNominator, int quality) throws IOException;