1 /* 2 * Copyright 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.media.cts; 18 19 import android.graphics.Bitmap; 20 import android.graphics.Color; 21 import android.graphics.Rect; 22 import android.media.cts.CodecImage; 23 import android.media.Image; 24 import android.media.MediaCodec.BufferInfo; 25 import android.os.Environment; 26 import android.util.Log; 27 28 import java.io.File; 29 import java.io.FileDescriptor; 30 import java.io.FileOutputStream; 31 import java.io.InputStream; 32 import java.io.OutputStream; 33 import java.nio.ByteBuffer; 34 35 public class CodecUtils { 36 private static final String TAG = "CodecUtils"; 37 38 /** Load jni on initialization */ 39 static { Log.i(TAG, "before loadlibrary")40 Log.i(TAG, "before loadlibrary"); 41 System.loadLibrary("ctscodecutils_jni"); Log.i(TAG, "after loadlibrary")42 Log.i(TAG, "after loadlibrary"); 43 } 44 45 private static class ImageWrapper extends CodecImage { 46 private final Image mImage; 47 private final Plane[] mPlanes; 48 ImageWrapper(Image image)49 private ImageWrapper(Image image) { 50 mImage = image; 51 Image.Plane[] planes = mImage.getPlanes(); 52 53 mPlanes = new Plane[planes.length]; 54 for (int i = 0; i < planes.length; i++) { 55 mPlanes[i] = new PlaneWrapper(planes[i]); 56 } 57 } 58 createFromImage(Image image)59 public static ImageWrapper createFromImage(Image image) { 60 return new ImageWrapper(image); 61 } 62 63 @Override getFormat()64 public int getFormat() { 65 return mImage.getFormat(); 66 } 67 68 @Override getWidth()69 public int getWidth() { 70 return mImage.getWidth(); 71 } 72 73 @Override getHeight()74 public int getHeight() { 75 return mImage.getHeight(); 76 } 77 78 @Override getTimestamp()79 public long getTimestamp() { 80 return mImage.getTimestamp(); 81 } 82 83 @Override getPlanes()84 public Plane[] getPlanes() { 85 return mPlanes; 86 } 87 88 @Override close()89 public void close() { 90 mImage.close(); 91 } 92 93 private static class PlaneWrapper extends CodecImage.Plane { 94 private final Image.Plane mPlane; 95 PlaneWrapper(Image.Plane plane)96 PlaneWrapper(Image.Plane plane) { 97 mPlane = plane; 98 } 99 100 @Override getRowStride()101 public int getRowStride() { 102 return mPlane.getRowStride(); 103 } 104 105 @Override getPixelStride()106 public int getPixelStride() { 107 return mPlane.getPixelStride(); 108 } 109 110 @Override getBuffer()111 public ByteBuffer getBuffer() { 112 return mPlane.getBuffer(); 113 } 114 } 115 } 116 117 /* two native image checksum functions */ getImageChecksumAdler32(CodecImage image)118 public native static int getImageChecksumAdler32(CodecImage image); getImageChecksumMD5(CodecImage image)119 public native static String getImageChecksumMD5(CodecImage image); 120 copyFlexYUVImage(CodecImage target, CodecImage source)121 public native static void copyFlexYUVImage(CodecImage target, CodecImage source); 122 copyFlexYUVImage(Image target, CodecImage source)123 public static void copyFlexYUVImage(Image target, CodecImage source) { 124 copyFlexYUVImage(ImageWrapper.createFromImage(target), source); 125 } copyFlexYUVImage(Image target, Image source)126 public static void copyFlexYUVImage(Image target, Image source) { 127 copyFlexYUVImage( 128 ImageWrapper.createFromImage(target), 129 ImageWrapper.createFromImage(source)); 130 } 131 fillImageRectWithYUV( CodecImage image, Rect area, int y, int u, int v)132 public native static void fillImageRectWithYUV( 133 CodecImage image, Rect area, int y, int u, int v); 134 fillImageRectWithYUV(Image image, Rect area, int y, int u, int v)135 public static void fillImageRectWithYUV(Image image, Rect area, int y, int u, int v) { 136 fillImageRectWithYUV(ImageWrapper.createFromImage(image), area, y, u, v); 137 } 138 getRawStats(CodecImage image, Rect area)139 public native static long[] getRawStats(CodecImage image, Rect area); 140 getRawStats(Image image, Rect area)141 public static long[] getRawStats(Image image, Rect area) { 142 return getRawStats(ImageWrapper.createFromImage(image), area); 143 } 144 getYUVStats(CodecImage image, Rect area)145 public native static float[] getYUVStats(CodecImage image, Rect area); 146 getYUVStats(Image image, Rect area)147 public static float[] getYUVStats(Image image, Rect area) { 148 return getYUVStats(ImageWrapper.createFromImage(image), area); 149 } 150 Raw2YUVStats(long[] rawStats)151 public native static float[] Raw2YUVStats(long[] rawStats); 152 153 /** 154 * This method reads the binarybar code on the top row of a bitmap. Each 16x16 155 * block is one digit, with black=0 and white=1. LSB is on the left. 156 */ readBinaryCounterFromBitmap(Bitmap bitmap)157 public static int readBinaryCounterFromBitmap(Bitmap bitmap) { 158 int numDigits = bitmap.getWidth() / 16; 159 int counter = 0; 160 for (int i = 0; i < numDigits; i++) { 161 int rgb = bitmap.getPixel(i * 16 + 8, 8); 162 if (Color.red(rgb) > 128) { 163 counter |= (1 << i); 164 } 165 } 166 return counter; 167 } 168 saveBitmapToFile(Bitmap bitmap, String filename)169 public static void saveBitmapToFile(Bitmap bitmap, String filename) { 170 try { 171 File outputFile = new File(Environment.getExternalStorageDirectory(), filename); 172 173 Log.d(TAG, "Saving bitmap to: " + outputFile); 174 FileOutputStream outputStream = new FileOutputStream(outputFile); 175 bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream); 176 outputStream.flush(); 177 outputStream.close(); 178 } catch(Exception e) { 179 Log.e(TAG, "Failed to save to file: " + e); 180 } 181 } 182 } 183 184