22
22
import android .graphics .Matrix ;
23
23
import android .graphics .Bitmap ;
24
24
import android .graphics .BitmapFactory ;
25
- import android .media .ExifInterface ;
25
+ import android .support . media .ExifInterface ;
26
26
import android .os .Build ;
27
27
import android .util .Log ;
28
28
import android .util .TypedValue ;
32
32
import java .io .ByteArrayInputStream ;
33
33
import java .io .ByteArrayOutputStream ;
34
34
import java .io .File ;
35
- import java .io .FileDescriptor ;
36
35
import java .io .FileInputStream ;
37
36
import java .io .IOException ;
38
37
import java .io .InputStream ;
@@ -165,9 +164,10 @@ protected void closeCacheInternal() {
165
164
*/
166
165
private Bitmap processHttp (String data , int decodeWidth , int decodeHeight , boolean keepAspectRatio ) {
167
166
final String key = Cache .hashKeyForDisk (data );
168
- FileDescriptor fileDescriptor = null ;
169
167
FileInputStream fileInputStream = null ;
170
168
DiskLruCache .Snapshot snapshot ;
169
+ Bitmap bitmap = null ;
170
+
171
171
synchronized (mHttpDiskCacheLock ) {
172
172
// Wait for disk cache to initialize
173
173
while (mHttpDiskCacheStarting ) {
@@ -196,14 +196,15 @@ private Bitmap processHttp(String data, int decodeWidth, int decodeHeight, boole
196
196
}
197
197
if (snapshot != null ) {
198
198
fileInputStream = (FileInputStream ) snapshot .getInputStream (DISK_CACHE_INDEX );
199
- fileDescriptor = fileInputStream .getFD ();
199
+ bitmap = decodeSampledBitmapFromByteArray (readAllBytes (fileInputStream ), decodeWidth , decodeHeight ,
200
+ keepAspectRatio , getCache ());
200
201
}
201
202
} catch (IOException e ) {
202
203
Log .e (TAG , "processHttp - " + e );
203
204
} catch (IllegalStateException e ) {
204
205
Log .e (TAG , "processHttp - " + e );
205
206
} finally {
206
- if (fileDescriptor == null && fileInputStream != null ) {
207
+ if (fileInputStream != null ) {
207
208
try {
208
209
fileInputStream .close ();
209
210
} catch (IOException e ) {
@@ -213,12 +214,16 @@ private Bitmap processHttp(String data, int decodeWidth, int decodeHeight, boole
213
214
}
214
215
}
215
216
216
- Bitmap bitmap = null ;
217
- if (fileDescriptor != null ) {
218
- bitmap = decodeSampledBitmapFromDescriptor (fileDescriptor , decodeWidth , decodeHeight , keepAspectRatio ,
219
- getCache ());
220
- }
217
+
221
218
if (fileInputStream != null ) {
219
+ if (bitmap == null ) {
220
+ try {
221
+ bitmap = decodeSampledBitmapFromByteArray (readAllBytes (fileInputStream ), decodeWidth , decodeHeight ,
222
+ keepAspectRatio , getCache ());
223
+ } catch (IOException e ) {
224
+ Log .e (TAG , "processHttp - " + e );
225
+ }
226
+ }
222
227
try {
223
228
fileInputStream .close ();
224
229
} catch (IOException e ) {
@@ -227,6 +232,32 @@ private Bitmap processHttp(String data, int decodeWidth, int decodeHeight, boole
227
232
return bitmap ;
228
233
}
229
234
235
+ public static byte [] readAllBytes (InputStream inputStream ) throws IOException {
236
+ final int bufLen = 4 * 0x400 ; // 4KB
237
+ byte [] buf = new byte [bufLen ];
238
+ int readLen ;
239
+ IOException exception = null ;
240
+
241
+ try {
242
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream ()) {
243
+ while ((readLen = inputStream .read (buf , 0 , bufLen )) != -1 )
244
+ outputStream .write (buf , 0 , readLen );
245
+
246
+ return outputStream .toByteArray ();
247
+ }
248
+ } catch (IOException e ) {
249
+ exception = e ;
250
+ throw e ;
251
+ } finally {
252
+ if (exception == null ) inputStream .close ();
253
+ else try {
254
+ inputStream .close ();
255
+ } catch (IOException e ) {
256
+ exception .addSuppressed (e );
257
+ }
258
+ }
259
+ }
260
+
230
261
private Bitmap processHttpNoCache (String data , int decodeWidth , int decodeHeight , boolean keepAspectRatio ) {
231
262
ByteArrayOutputStreamInternal outputStream = null ;
232
263
Bitmap bitmap = null ;
@@ -415,20 +446,6 @@ private static ExifInterface getExifInterface(InputStream is) {
415
446
return ei ;
416
447
}
417
448
418
- @ TargetApi (Build .VERSION_CODES .N )
419
- private static ExifInterface getExifInterface (FileDescriptor fd ) {
420
- ExifInterface ei = null ;
421
- try {
422
- if (Utils .hasN ()) {
423
- ei = new ExifInterface (fd );
424
- }
425
- } catch (final Exception e ) {
426
- Log .e (TAG , "Error in reading bitmap - " + e );
427
- }
428
-
429
- return ei ;
430
- }
431
-
432
449
private static ExifInterface getExifInterface (String fileName ) {
433
450
ExifInterface ei = null ;
434
451
try {
@@ -531,50 +548,6 @@ private static int calculateRotationAngle(ExifInterface ei) {
531
548
return rotationAngle ;
532
549
}
533
550
534
- /**
535
- * Decode and sample down a bitmap from a file input stream to the requested width and height.
536
- *
537
- * @param fileDescriptor The file descriptor to read from
538
- * @param reqWidth The requested width of the resulting bitmap
539
- * @param reqHeight The requested height of the resulting bitmap
540
- * @param cache The Cache used to find candidate bitmaps for use with inBitmap
541
- * @return A bitmap sampled down from the original with the same aspect ratio and dimensions
542
- * that are equal to or greater than the requested width and height
543
- */
544
- public static Bitmap decodeSampledBitmapFromDescriptor (FileDescriptor fileDescriptor , int reqWidth , int reqHeight ,
545
- boolean keepAspectRatio , Cache cache ) {
546
-
547
- // First decode with inJustDecodeBounds=true to check dimensions
548
- final BitmapFactory .Options options = new BitmapFactory .Options ();
549
- options .inJustDecodeBounds = true ;
550
- BitmapFactory .decodeFileDescriptor (fileDescriptor , null , options );
551
-
552
- options .inSampleSize = calculateInSampleSize (options .outWidth , options .outHeight , reqWidth , reqHeight );
553
-
554
- // Decode bitmap with inSampleSize set
555
- options .inJustDecodeBounds = false ;
556
-
557
- // If we're running on Honeycomb or newer, try to use inBitmap
558
- if (Utils .hasHoneycomb ()) {
559
- addInBitmapOptions (options , cache );
560
- }
561
-
562
- Bitmap results = null ;
563
- try {
564
- // This can throw an error on a corrupted image when using an inBitmap
565
- results = BitmapFactory .decodeFileDescriptor (fileDescriptor , null , options );
566
- } catch (Exception e ) {
567
- // clear the inBitmap and try again
568
- options .inBitmap = null ;
569
- results = BitmapFactory .decodeFileDescriptor (fileDescriptor , null , options );
570
- // If image is broken, rather than an issue with the inBitmap, we will get a NULL out in this case...
571
- }
572
-
573
- ExifInterface ei = getExifInterface (fileDescriptor );
574
-
575
- return scaleAndRotateBitmap (results , ei , reqWidth , reqHeight , keepAspectRatio );
576
- }
577
-
578
551
public static Bitmap decodeSampledBitmapFromByteArray (byte [] buffer , int reqWidth , int reqHeight ,
579
552
boolean keepAspectRatio , Cache cache ) {
580
553
0 commit comments