1f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He/* 2f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * Copyright 2015 The Android Open Source Project 3f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * 4f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * Licensed under the Apache License, Version 2.0 (the "License"); 5f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * you may not use this file except in compliance with the License. 6f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * You may obtain a copy of the License at 7f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * 8f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * http://www.apache.org/licenses/LICENSE-2.0 9f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * 10f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * Unless required by applicable law or agreed to in writing, software 11f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * distributed under the License is distributed on an "AS IS" BASIS, 12f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * See the License for the specific language governing permissions and 14f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * limitations under the License. 15f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He */ 16f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 17f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun Hepackage android.media; 18f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 19f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun Heimport android.graphics.ImageFormat; 20f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun Heimport android.graphics.PixelFormat; 21f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun Heimport android.media.Image.Plane; 22f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun Heimport android.util.Size; 23f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 24bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun Heimport libcore.io.Memory; 25bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He 26f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun Heimport java.nio.ByteBuffer; 27f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 28f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He/** 29f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * Package private utility class for hosting commonly used Image related methods. 30f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He */ 31f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun Heclass ImageUtils { 32f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 33f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He /** 34f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * Only a subset of the formats defined in 35f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * {@link android.graphics.ImageFormat ImageFormat} and 36f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * {@link android.graphics.PixelFormat PixelFormat} are supported by 37f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * ImageReader. When reading RGB data from a surface, the formats defined in 38f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * {@link android.graphics.PixelFormat PixelFormat} can be used; when 39f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * reading YUV, JPEG or raw sensor data (for example, from the camera or video 40f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * decoder), formats from {@link android.graphics.ImageFormat ImageFormat} 41f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * are used. 42f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He */ 43f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He public static int getNumPlanesForFormat(int format) { 44f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He switch (format) { 45f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.YV12: 46f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.YUV_420_888: 47f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.NV21: 48f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He return 3; 49f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.NV16: 50f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He return 2; 51f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case PixelFormat.RGB_565: 52f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case PixelFormat.RGBA_8888: 53f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case PixelFormat.RGBX_8888: 54f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case PixelFormat.RGB_888: 55f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.JPEG: 56f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.YUY2: 57f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.Y8: 58f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.Y16: 59f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.RAW_SENSOR: 6044581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh case ImageFormat.RAW_PRIVATE: 61f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He case ImageFormat.RAW10: 62dc6bb24a3c2c830c909523e8d7d999fb556fb77dZhijun He case ImageFormat.RAW12: 63dc6bb24a3c2c830c909523e8d7d999fb556fb77dZhijun He case ImageFormat.DEPTH16: 64dc6bb24a3c2c830c909523e8d7d999fb556fb77dZhijun He case ImageFormat.DEPTH_POINT_CLOUD: 65f7fec7397e37657d08ec6a8c1c214c1f90a77bfdEmilian Peev case ImageFormat.RAW_DEPTH: 66f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He return 1; 67d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He case ImageFormat.PRIVATE: 68f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He return 0; 69f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He default: 70f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He throw new UnsupportedOperationException( 71f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He String.format("Invalid format specified %d", format)); 72f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 73f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 74f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 75f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He /** 76f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * <p> 77f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * Copy source image data to destination Image. 78f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * </p> 79f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * <p> 80d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He * Only support the copy between two non-{@link ImageFormat#PRIVATE PRIVATE} format 81d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He * images with same properties (format, size, etc.). The data from the 82d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He * source image will be copied to the byteBuffers from the destination Image 83d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He * starting from position zero, and the destination image will be rewound to 84d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He * zero after copy is done. 85f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * </p> 86f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * 87f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * @param src The source image to be copied from. 88f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * @param dst The destination image to be copied to. 89f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * @throws IllegalArgumentException If the source and destination images 90f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He * have different format, or one of the images is not copyable. 91f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He */ 92f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He public static void imageCopy(Image src, Image dst) { 93f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (src == null || dst == null) { 94f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He throw new IllegalArgumentException("Images should be non-null"); 95f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 96f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (src.getFormat() != dst.getFormat()) { 97f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He throw new IllegalArgumentException("Src and dst images should have the same format"); 98f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 99d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He if (src.getFormat() == ImageFormat.PRIVATE || 100d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He dst.getFormat() == ImageFormat.PRIVATE) { 101d99dc329b9baefe3d722ccafc0c92461cfef42b1Zhijun He throw new IllegalArgumentException("PRIVATE format images are not copyable"); 102f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 10344581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh if (src.getFormat() == ImageFormat.RAW_PRIVATE) { 10444581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh throw new IllegalArgumentException( 10544581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh "Copy of RAW_OPAQUE format has not been implemented"); 10644581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh } 107f7fec7397e37657d08ec6a8c1c214c1f90a77bfdEmilian Peev if (src.getFormat() == ImageFormat.RAW_DEPTH) { 108f7fec7397e37657d08ec6a8c1c214c1f90a77bfdEmilian Peev throw new IllegalArgumentException( 109f7fec7397e37657d08ec6a8c1c214c1f90a77bfdEmilian Peev "Copy of RAW_DEPTH format has not been implemented"); 110f7fec7397e37657d08ec6a8c1c214c1f90a77bfdEmilian Peev } 111f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (!(dst.getOwner() instanceof ImageWriter)) { 112f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He throw new IllegalArgumentException("Destination image is not from ImageWriter. Only" 113f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He + " the images from ImageWriter are writable"); 114f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 115f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He Size srcSize = new Size(src.getWidth(), src.getHeight()); 116f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He Size dstSize = new Size(dst.getWidth(), dst.getHeight()); 117f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He if (!srcSize.equals(dstSize)) { 118f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He throw new IllegalArgumentException("source image size " + srcSize + " is different" 119f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He + " with " + "destination image size " + dstSize); 120f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 121f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He 122f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He Plane[] srcPlanes = src.getPlanes(); 123f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He Plane[] dstPlanes = dst.getPlanes(); 124f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He ByteBuffer srcBuffer = null; 125f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He ByteBuffer dstBuffer = null; 126f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He for (int i = 0; i < srcPlanes.length; i++) { 127bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He int srcRowStride = srcPlanes[i].getRowStride(); 128bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He int dstRowStride = dstPlanes[i].getRowStride(); 129f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He srcBuffer = srcPlanes[i].getBuffer(); 130bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He dstBuffer = dstPlanes[i].getBuffer(); 131bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He if (!(srcBuffer.isDirect() && dstBuffer.isDirect())) { 132bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He throw new IllegalArgumentException("Source and destination ByteBuffers must be" 133bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He + " direct byteBuffer!"); 134bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 135bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He if (srcPlanes[i].getPixelStride() != dstPlanes[i].getPixelStride()) { 136bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He throw new IllegalArgumentException("Source plane image pixel stride " + 137bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He srcPlanes[i].getPixelStride() + 138bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He " must be same as destination image pixel stride " + 139bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He dstPlanes[i].getPixelStride()); 140bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 141bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He 142f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He int srcPos = srcBuffer.position(); 143f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He srcBuffer.rewind(); 144f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He dstBuffer.rewind(); 145bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He if (srcRowStride == dstRowStride) { 146bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He // Fast path, just copy the content if the byteBuffer all together. 147bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He dstBuffer.put(srcBuffer); 148bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } else { 149bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He // Source and destination images may have different alignment requirements, 150bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He // therefore may have different strides. Copy row by row for such case. 151bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He int srcOffset = srcBuffer.position(); 152bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He int dstOffset = dstBuffer.position(); 153bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He Size effectivePlaneSize = getEffectivePlaneSizeForImage(src, i); 154bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He int srcByteCount = effectivePlaneSize.getWidth() * srcPlanes[i].getPixelStride(); 155bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He for (int row = 0; row < effectivePlaneSize.getHeight(); row++) { 156bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He if (row == effectivePlaneSize.getHeight() - 1) { 157bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He // Special case for NV21 backed YUV420_888: need handle the last row 158bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He // carefully to avoid memory corruption. Check if we have enough bytes to 159bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He // copy. 160bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He int remainingBytes = srcBuffer.remaining() - srcOffset; 161bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He if (srcByteCount > remainingBytes) { 162bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He srcByteCount = remainingBytes; 163bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 164bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 165bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He directByteBufferCopy(srcBuffer, srcOffset, dstBuffer, dstOffset, srcByteCount); 166bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He srcOffset += srcRowStride; 167bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He dstOffset += dstRowStride; 168bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 169bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 170bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He 171f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He srcBuffer.position(srcPos); 172f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He dstBuffer.rewind(); 173f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 174f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He } 17511c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen 17611c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen /** 17711c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * Return the estimated native allocation size in bytes based on width, height, format, 17811c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * and number of images. 17911c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * 18011c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * <p>This is a very rough estimation and should only be used for native allocation 18111c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * registration in VM so it can be accounted for during GC.</p> 18211c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * 18311c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * @param width The width of the images. 18411c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * @param height The height of the images. 18511c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * @param format The format of the images. 18611c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen * @param numImages The number of the images. 18711c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen */ 18811c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen public static int getEstimatedNativeAllocBytes(int width, int height, int format, 18911c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen int numImages) { 19011c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen double estimatedBytePerPixel; 19111c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen switch (format) { 19211c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen // 10x compression from RGB_888 19311c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.JPEG: 19411c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.DEPTH_POINT_CLOUD: 19511c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen estimatedBytePerPixel = 0.3; 19611c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen break; 19711c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.Y8: 19811c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen estimatedBytePerPixel = 1.0; 19911c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen break; 20011c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.RAW10: 20111c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen estimatedBytePerPixel = 1.25; 20211c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen break; 20311c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.YV12: 20411c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.YUV_420_888: 20511c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.NV21: 20644581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh case ImageFormat.RAW12: 20744581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh case ImageFormat.PRIVATE: // A rough estimate because the real size is unknown. 20811c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen estimatedBytePerPixel = 1.5; 20911c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen break; 21011c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.NV16: 21111c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case PixelFormat.RGB_565: 21211c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.YUY2: 21311c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.Y16: 214f7fec7397e37657d08ec6a8c1c214c1f90a77bfdEmilian Peev case ImageFormat.RAW_DEPTH: 21511c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.RAW_SENSOR: 21644581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown 21711c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case ImageFormat.DEPTH16: 21811c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen estimatedBytePerPixel = 2.0; 21911c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen break; 22011c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case PixelFormat.RGB_888: 22111c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen estimatedBytePerPixel = 3.0; 22211c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen break; 22311c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case PixelFormat.RGBA_8888: 22411c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen case PixelFormat.RGBX_8888: 22511c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen estimatedBytePerPixel = 4.0; 22611c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen break; 22711c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen default: 22811c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen throw new UnsupportedOperationException( 22911c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen String.format("Invalid format specified %d", format)); 23011c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen } 23111c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen 23211c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen return (int)(width * height * estimatedBytePerPixel * numImages); 23311c5d0dd01cccc500796febf63aab404e8ae058bChien-Yu Chen } 234bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He 235bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He private static Size getEffectivePlaneSizeForImage(Image image, int planeIdx) { 236bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He switch (image.getFormat()) { 237bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.YV12: 238bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.YUV_420_888: 239bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.NV21: 240bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He if (planeIdx == 0) { 241bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He return new Size(image.getWidth(), image.getHeight()); 242bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } else { 243bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He return new Size(image.getWidth() / 2, image.getHeight() / 2); 244bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 245bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.NV16: 246bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He if (planeIdx == 0) { 247bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He return new Size(image.getWidth(), image.getHeight()); 248bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } else { 249bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He return new Size(image.getWidth(), image.getHeight() / 2); 250bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 251bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case PixelFormat.RGB_565: 252bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case PixelFormat.RGBA_8888: 253bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case PixelFormat.RGBX_8888: 254bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case PixelFormat.RGB_888: 255bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.JPEG: 256bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.YUY2: 257bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.Y8: 258bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.Y16: 259bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.RAW_SENSOR: 260bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.RAW10: 26144581ff4db54bbaa30365ed210e67a0369576100Yin-Chia Yeh case ImageFormat.RAW12: 262f7fec7397e37657d08ec6a8c1c214c1f90a77bfdEmilian Peev case ImageFormat.RAW_DEPTH: 263bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He return new Size(image.getWidth(), image.getHeight()); 264bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He case ImageFormat.PRIVATE: 265bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He return new Size(0, 0); 266bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He default: 267bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He throw new UnsupportedOperationException( 268bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He String.format("Invalid image format %d", image.getFormat())); 269bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 270bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 271bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He 272bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He private static void directByteBufferCopy(ByteBuffer srcBuffer, int srcOffset, 273bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He ByteBuffer dstBuffer, int dstOffset, int srcByteCount) { 274bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He Memory.memmove(dstBuffer, dstOffset, srcBuffer, srcOffset, srcByteCount); 275bc0b63667960896929fdfcc0d95491ff8f1ef00aZhijun He } 276f6a09e510649ae4701bb5ad4c40d102d59a5608cZhijun He} 277