content: package com.baidu.paddle.fastdeploy.app.ui;
  
  import android.content.Context;
  import android.content.res.Resources;
  import android.database.Cursor;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.hardware.Camera;
  import android.net.Uri;
  import android.opengl.GLES20;
  import android.os.Environment;
  import android.provider.MediaStore;
  import android.util.Log;
  import android.view.Surface;
  import android.view.WindowManager;
  
  import java.io.BufferedInputStream;
  import java.io.BufferedOutputStream;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.OutputStream;
  import java.util.ArrayList;
  import java.util.List;
  
  public class Utils {
      private static final String TAG = Utils.class.getSimpleName();
  
      public static void RecursiveCreateDirectories(String fileDir) {
          String[] fileDirs = fileDir.split("\\/");
          String topPath = "";
          for (int i = 0; i < fileDirs.length; i++) {
              topPath += "/" + fileDirs[i];
              File file = new File(topPath);
              if (file.exists()) {
                  continue;
              } else {
                  file.mkdir();
              }
          }
      }
  
      public static void copyFileFromAssets(Context appCtx, String srcPath, String dstPath) {
          if (srcPath.isEmpty() || dstPath.isEmpty()) {
              return;
          }
          String dstDir = dstPath.substring(0, dstPath.lastIndexOf('/'));
          if (dstDir.length() > 0) {
              RecursiveCreateDirectories(dstDir);
          }
          InputStream is = null;
          OutputStream os = null;
          try {
              is = new BufferedInputStream(appCtx.getAssets().open(srcPath));
              os = new BufferedOutputStream(new FileOutputStream(new File(dstPath)));
              byte[] buffer = new byte[1024];
              int length = 0;
              while ((length = is.read(buffer)) != -1) {
                  os.write(buffer, 0, length);
              }
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
              try {
                  os.close();
                  is.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  
      public static void copyDirectoryFromAssets(Context appCtx, String srcDir, String dstDir) {
          if (srcDir.isEmpty() || dstDir.isEmpty()) {
              return;
          }
          try {
              if (!new File(dstDir).exists()) {
                  new File(dstDir).mkdirs();
              }
              for (String fileName : appCtx.getAssets().list(srcDir)) {
                  String srcSubPath = srcDir + File.separator + fileName;
                  String dstSubPath = dstDir + File.separator + fileName;
                  if (new File(srcSubPath).isDirectory()) {
                      copyDirectoryFromAssets(appCtx, srcSubPath, dstSubPath);
                  } else {
                      copyFileFromAssets(appCtx, srcSubPath, dstSubPath);
                  }
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      public static float[] parseFloatsFromString(String string, String delimiter) {
          String[] pieces = string.trim().toLowerCase().split(delimiter);
          float[] floats = new float[pieces.length];
          for (int i = 0; i < pieces.length; i++) {
              floats[i] = Float.parseFloat(pieces[i].trim());
          }
          return floats;
      }
  
      public static long[] parseLongsFromString(String string, String delimiter) {
          String[] pieces = string.trim().toLowerCase().split(delimiter);
          long[] longs = new long[pieces.length];
          for (int i = 0; i < pieces.length; i++) {
              longs[i] = Long.parseLong(pieces[i].trim());
          }
          return longs;
      }
  
      public static String getSDCardDirectory() {
          return Environment.getExternalStorageDirectory().getAbsolutePath();
      }
  
      public static String getDCIMDirectory() {
          return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath();
      }
  
      public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
          final double ASPECT_TOLERANCE = 0.3;
          double targetRatio = (double) w / h;
          if (sizes == null) return null;
  
          Camera.Size optimalSize = null;
          double minDiff = Double.MAX_VALUE;
  
          int targetHeight = h;
  
          // Try to find an size match aspect ratio and size
          for (Camera.Size size : sizes) {
              double ratio = (double) size.width / size.height;
              if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
              if (Math.abs(size.height - targetHeight) < minDiff) {
                  optimalSize = size;
                  minDiff = Math.abs(size.height - targetHeight);
              }
          }
  
          // Cannot find the one match the aspect ratio, ignore the requirement
          if (optimalSize == null) {
              minDiff = Double.MAX_VALUE;
              for (Camera.Size size : sizes) {
                  if (Math.abs(size.height - targetHeight) < minDiff) {
                      optimalSize = size;
                      minDiff = Math.abs(size.height - targetHeight);
                  }
              }
          }
          return optimalSize;
      }
  
      public static int getScreenWidth() {
          return Resources.getSystem().getDisplayMetrics().widthPixels;
      }
  
      public static int getScreenHeight() {
          return Resources.getSystem().getDisplayMetrics().heightPixels;
      }
  
      public static int getCameraDisplayOrientation(Context context, int cameraId) {
          Camera.CameraInfo info = new Camera.CameraInfo();
          Camera.getCameraInfo(cameraId, info);
          WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
          int rotation = wm.getDefaultDisplay().getRotation();
          int degrees = 0;
          switch (rotation) {
              case Surface.ROTATION_0:
                  degrees = 0;
                  break;
              case Surface.ROTATION_90:
                  degrees = 90;
                  break;
              case Surface.ROTATION_180:
                  degrees = 180;
                  break;
              case Surface.ROTATION_270:
                  degrees = 270;
                  break;
          }
          int result;
          if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
              result = (info.orientation + degrees) % 360;
              result = (360 - result) % 360;   // compensate the mirror
          } else {
              // back-facing
              result = (info.orientation - degrees + 360) % 360;
          }
          return result;
      }
  
      public static int createShaderProgram(String vss, String fss) {
          int vshader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
          GLES20.glShaderSource(vshader, vss);
          GLES20.glCompileShader(vshader);
          int[] status = new int[1];
          GLES20.glGetShaderiv(vshader, GLES20.GL_COMPILE_STATUS, status, 0);
          if (status[0] == 0) {
              Log.e(TAG, GLES20.glGetShaderInfoLog(vshader));
              GLES20.glDeleteShader(vshader);
              vshader = 0;
              return 0;
          }
  
          int fshader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
          GLES20.glShaderSource(fshader, fss);
          GLES20.glCompileShader(fshader);
          GLES20.glGetShaderiv(fshader, GLES20.GL_COMPILE_STATUS, status, 0);
          if (status[0] == 0) {
              Log.e(TAG, GLES20.glGetShaderInfoLog(fshader));
              GLES20.glDeleteShader(vshader);
              GLES20.glDeleteShader(fshader);
              fshader = 0;
              return 0;
          }
  
          int program = GLES20.glCreateProgram();
          GLES20.glAttachShader(program, vshader);
          GLES20.glAttachShader(program, fshader);
          GLES20.glLinkProgram(program);
          GLES20.glDeleteShader(vshader);
          GLES20.glDeleteShader(fshader);
          GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0);
          if (status[0] == 0) {
              Log.e(TAG, GLES20.glGetProgramInfoLog(program));
              program = 0;
              return 0;
          }
          GLES20.glValidateProgram(program);
          GLES20.glGetProgramiv(program, GLES20.GL_VALIDATE_STATUS, status, 0);
          if (status[0] == 0) {
              Log.e(TAG, GLES20.glGetProgramInfoLog(program));
              GLES20.glDeleteProgram(program);
              program = 0;
              return 0;
          }
  
          return program;
      }
  
      public static boolean isSupportedNPU() {
          String hardware = android.os.Build.HARDWARE;
          return hardware.equalsIgnoreCase("kirin810") || hardware.equalsIgnoreCase("kirin990");
      }
  
      public static Bitmap decodeBitmap(String path, int displayWidth, int displayHeight) {
          BitmapFactory.Options op = new BitmapFactory.Options();
          op.inJustDecodeBounds = true;// Only the width and height information of Bitmap is read, not the pixels.
          Bitmap bmp = BitmapFactory.decodeFile(path, op); // Get size information.
          int wRatio = (int) Math.ceil(op.outWidth / (float) displayWidth);// Get Scale Size.
          int hRatio = (int) Math.ceil(op.outHeight / (float) displayHeight);
          // If the specified size is exceeded, reduce the corresponding scale.
          if (wRatio > 1 && hRatio > 1) {
              if (wRatio > hRatio) {
                  // If it is too wide, we will reduce the width to the required size. Note that the height will become smaller.
                  op.inSampleSize = wRatio;
              } else {
                  op.inSampleSize = hRatio;
              }
          }
          op.inJustDecodeBounds = false;
          bmp = BitmapFactory.decodeFile(path, op);
          // Create a Bitmap with a given width and height from the original Bitmap.
          return Bitmap.createScaledBitmap(bmp, displayWidth, displayHeight, true);
      }
  
      public static String getRealPathFromURI(Context context, Uri contentURI) {
          String result;
          Cursor cursor = null;
          try {
              cursor = context.getContentResolver().query(contentURI, null, null, null, null);
          } catch (Throwable e) {
              e.printStackTrace();
          }
          if (cursor == null) {
              result = contentURI.getPath();
          } else {
              cursor.moveToFirst();
              int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
              result = cursor.getString(idx);
              cursor.close();
          }
          return result;
      }
  
      public static List<String> readTxt(String txtPath) {
          File file = new File(txtPath);
          if (file.isFile() && file.exists()) {
              try {
                  FileInputStream fileInputStream = new FileInputStream(file);
                  InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
                  BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                  String text;
                  List<String> labels = new ArrayList<>();
                  while ((text = bufferedReader.readLine()) != null) {
                      labels.add(text);
                  }
                  return labels;
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
          return null;
      }
  }
  