X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=android%2Fxscreensaver%2Fsrc%2Forg%2Fjwz%2Fxscreensaver%2Fjwxyz.java;fp=android%2Fxscreensaver%2Fsrc%2Forg%2Fjwz%2Fxscreensaver%2Fjwxyz.java;h=8ca6af40588b0fcbb8e8affa8d826f48aa0036d8;hp=9ad2c1705c88fc4ab64e2fb2e6d169221167e54e;hb=78add6e627ee5f10e1fa6f3852602ea5066eee5a;hpb=39809ded547bdbb08207d3e514950425215b4410 diff --git a/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java b/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java index 9ad2c170..8ca6af40 100644 --- a/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java +++ b/android/xscreensaver/src/org/jwz/xscreensaver/jwxyz.java @@ -1,5 +1,5 @@ /* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * xscreensaver, Copyright (c) 2016-2017 Jamie Zawinski + * xscreensaver, Copyright (c) 2016-2018 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -33,6 +33,7 @@ import android.graphics.Rect; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; @@ -57,7 +58,6 @@ import org.jwz.xscreensaver.TTFAnalyzer; import android.util.Log; import android.view.Surface; - public class jwxyz implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { @@ -552,16 +552,17 @@ public class jwxyz } - private ByteBuffer convertBitmap (String name, Bitmap bitmap, - int target_width, int target_height, - ExifInterface exif, - boolean rotate_p) { + // Returns [ Bitmap bitmap, String name ] + private Object[] convertBitmap (String name, Bitmap bitmap, + int target_width, int target_height, + ExifInterface exif, boolean rotate_p) { if (bitmap == null) return null; - try { + { int width = bitmap.getWidth(); int height = bitmap.getHeight(); + Matrix matrix = new Matrix(); LOG ("read image %s: %d x %d", name, width, height); @@ -577,28 +578,26 @@ public class jwxyz } if (deg != 0) { LOG ("%s: EXIF rotate %d", name, deg); - Matrix matrix = new Matrix(); matrix.preRotate (deg); - bitmap = Bitmap.createBitmap (bitmap, 0, 0, width, height, - matrix, true); - width = bitmap.getWidth(); - height = bitmap.getHeight(); + if (deg == 90 || deg == 270) { + int temp = width; + width = height; + height = temp; + } } } // If the caller requested that we rotate the image to best fit the - // screen, rotate it again. (Could combine this with the above and - // avoid copying the image again, but I'm lazy.) + // screen, rotate it again. if (rotate_p && (width > height) != (target_width > target_height)) { LOG ("%s: rotated to fit screen", name); - Matrix matrix = new Matrix(); matrix.preRotate (90); - bitmap = Bitmap.createBitmap (bitmap, 0, 0, width, height, - matrix, true); - width = bitmap.getWidth(); - height = bitmap.getHeight(); + + int temp = width; + width = height; + height = temp; } // Resize the image to be not larger than the screen, potentially @@ -612,42 +611,24 @@ public class jwxyz float r = (r1 > r2 ? r2 : r1); LOG ("%s: resize %.1f: %d x %d => %d x %d", name, r, width, height, (int) (width * r), (int) (height * r)); - width = (int) (width * r); - height = (int) (height * r); - bitmap = Bitmap.createScaledBitmap (bitmap, width, height, true); - width = bitmap.getWidth(); - height = bitmap.getHeight(); + matrix.preScale (r, r); } - // Now convert it to a ByteBuffer in the form expected by the C caller. - - byte[] nameb = name.getBytes("UTF-8"); - int size = bitmap.getByteCount() + 4 + nameb.length + 1; - - ByteBuffer bits = ByteBuffer.allocateDirect (size); - - bits.put ((byte) ((width >> 8) & 0xFF)); - bits.put ((byte) ( width & 0xFF)); - bits.put ((byte) ((height >> 8) & 0xFF)); - bits.put ((byte) ( height & 0xFF)); - bits.put (nameb); - bits.put ((byte) 0); + bitmap = Bitmap.createBitmap (bitmap, 0, 0, + bitmap.getWidth(), bitmap.getHeight(), + matrix, true); - // The fourth of five copies. Good thing these are supercomputers. - bitmap.copyPixelsToBuffer (bits); + if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) + bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false); - return bits; + return new Object[] { bitmap, name }; - } catch (Exception e) { - LOG ("image %s unreadable: %s", name, e.toString()); } - - return null; } - public ByteBuffer loadRandomImage (int target_width, int target_height, - boolean rotate_p) { + public Object[] loadRandomImage (int target_width, int target_height, + boolean rotate_p) { int min_size = 480; int max_size = 0x7FFF; @@ -665,6 +646,8 @@ public class jwxyz for (int i = 0; i < uris.length; i++) { Cursor cursor = cr.query (uris[i], cols, null, null, null); + if (cursor == null) + continue; int j = 0; int path_col = cursor.getColumnIndexOrThrow (cols[j++]); int type_col = cursor.getColumnIndexOrThrow (cols[j++]); @@ -673,12 +656,17 @@ public class jwxyz while (cursor.moveToNext()) { String path = cursor.getString(path_col); String type = cursor.getString(type_col); - int w = Integer.parseInt (cursor.getString(width_col)); - int h = Integer.parseInt (cursor.getString(height_col)); - if (type.startsWith("image/") && - w > min_size && h > min_size && - w < max_size && h < max_size) { - imgs.add (path); + if (path != null && type != null && type.startsWith("image/")) { + String wc = cursor.getString(width_col); + String hc = cursor.getString(height_col); + if (wc != null && hc != null) { + int w = Integer.parseInt (wc); + int h = Integer.parseInt (hc); + if (w > min_size && h > min_size && + w < max_size && h < max_size) { + imgs.add (path); + } + } } } cursor.close(); @@ -702,33 +690,42 @@ public class jwxyz ExifInterface exif = null; try { - bitmap = MediaStore.Images.Media.getBitmap (cr, uri); - } catch (Exception e) { - LOG ("image %s unloadable: %s", which, e.toString()); - return null; - } + try { + bitmap = MediaStore.Images.Media.getBitmap (cr, uri); + } catch (Exception e) { + LOG ("image %s unloadable: %s", which, e.toString()); + return null; + } - try { - exif = new ExifInterface (uri.getPath()); // If it fails, who cares - } catch (Exception e) { - } + try { + exif = new ExifInterface (uri.getPath()); // If it fails, who cares + } catch (Exception e) { + } - ByteBuffer bits = convertBitmap (name, bitmap, - target_width, target_height, - exif, rotate_p); - bitmap.recycle(); - return bits; + return convertBitmap (name, bitmap, target_width, target_height, + exif, rotate_p); + } catch (java.lang.OutOfMemoryError e) { + LOG ("image %s got OutOfMemoryError: %s", which, e.toString()); + return null; + } } - public ByteBuffer getScreenshot (int target_width, int target_height, - boolean rotate_p) { + public Object[] getScreenshot (int target_width, int target_height, + boolean rotate_p) { return convertBitmap ("Screenshot", screenshot, target_width, target_height, null, rotate_p); } + public Bitmap decodePNG (byte[] data) { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inPreferredConfig = Bitmap.Config.ARGB_8888; + return BitmapFactory.decodeByteArray (data, 0, data.length, opts); + } + + // Sadly duplicated from jwxyz.h (and thence X.h and keysymdef.h) // private static final int ShiftMask = (1<<0);