19c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall/* 29c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * Copyright (C) 2014 The Android Open Source Project 39c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * 49c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * Licensed under the Apache License, Version 2.0 (the "License"); 59c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * you may not use this file except in compliance with the License. 69c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * You may obtain a copy of the License at 79c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * 89c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * http://www.apache.org/licenses/LICENSE-2.0 99c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * 109c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * Unless required by applicable law or agreed to in writing, software 119c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * distributed under the License is distributed on an "AS IS" BASIS, 129c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * See the License for the specific language governing permissions and 149c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * limitations under the License. 159c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 169c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 179c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lallpackage com.android.camera.one.v2.camera2proxy; 189c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 199c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lallimport android.graphics.Rect; 206e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Linimport android.media.Image; 216e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin 22b8397360d318edf3093b20b2b102207d76730e1bPuneet Lallimport com.google.common.base.Objects; 23d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lallimport com.google.common.collect.ImmutableList; 24b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall 256e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Linimport java.nio.ByteBuffer; 266e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Linimport java.util.ArrayList; 276e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Linimport java.util.List; 289c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 291738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lallimport javax.annotation.concurrent.GuardedBy; 301738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lallimport javax.annotation.concurrent.ThreadSafe; 311738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall 329c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall/** 339c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * An {@link ImageProxy} backed by an {@link android.media.Image}. 349c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 351738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall@ThreadSafe 369c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lallpublic class AndroidImageProxy implements ImageProxy { 376e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin 386e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin /** 396e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin * An {@link ImageProxy.Plane} backed by an 406e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin * {@link android.media.Image.Plane}. 416e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin */ 426e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin public class Plane implements ImageProxy.Plane { 43d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final int mPixelStride; 44d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final int mRowStride; 45d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final ByteBuffer mBuffer; 466e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin 476e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin public Plane(Image.Plane imagePlane) { 48d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // Copying out the contents of the Image.Plane means that this Plane 49d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // implementation can be thread-safe (without requiring any locking) 50d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // and can have getters which do not throw a RuntimeException if 51d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // the underlying Image is closed. 52d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mPixelStride = imagePlane.getPixelStride(); 53d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mRowStride = imagePlane.getRowStride(); 54d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mBuffer = imagePlane.getBuffer(); 556e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin } 566e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin 576e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin /** 586e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin * @see {@link android.media.Image.Plane#getRowStride} 596e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin */ 606e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin @Override 616e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin public int getRowStride() { 62d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mRowStride; 636e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin } 646e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin 656e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin /** 666e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin * @see {@link android.media.Image.Plane#getPixelStride} 676e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin */ 686e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin @Override 696e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin public int getPixelStride() { 70d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mPixelStride; 716e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin } 726e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin 736e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin /** 746e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin * @see {@link android.media.Image.Plane#getBuffer} 756e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin */ 766e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin @Override 776e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin public ByteBuffer getBuffer() { 78d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mBuffer; 796e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin } 806e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin } 816e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin 821738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall private final Object mLock; 831738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall /** 841738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall * {@link android.media.Image} is not thread-safe, so all interactions must 851738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall * be guarded by {@link #mLock}. 861738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall */ 871738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall @GuardedBy("mLock") 889c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall private final android.media.Image mImage; 89d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final int mFormat; 90d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final int mWidth; 91d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final int mHeight; 92d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final long mTimestamp; 93d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private final ImmutableList<ImageProxy.Plane> mPlanes; 94d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall @GuardedBy("mLock") 95d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall private Rect mCropRect; 969c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 979c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public AndroidImageProxy(android.media.Image image) { 981738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall mLock = new Object(); 99d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall 1009c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall mImage = image; 101d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // Copying out the contents of the Image means that this Image 102d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // implementation can be thread-safe (without requiring any locking) 103d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // and can have getters which do not throw a RuntimeException if 104d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // the underlying Image is closed. 105d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mFormat = mImage.getFormat(); 106d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mWidth = mImage.getWidth(); 107d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mHeight = mImage.getHeight(); 108d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mTimestamp = mImage.getTimestamp(); 109d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall 110d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall Image.Plane[] planes; 111d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall planes = mImage.getPlanes(); 112d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall if (planes == null) { 113d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mPlanes = ImmutableList.of(); 114d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } else { 115d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall List<ImageProxy.Plane> wrappedPlanes = new ArrayList<>(planes.length); 116d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall for (int i = 0; i < planes.length; i++) { 117d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall wrappedPlanes.add(new Plane(planes[i])); 118d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } 119d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mPlanes = ImmutableList.copyOf(wrappedPlanes); 120d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } 1219c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1229c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1239c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1249c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#getCropRect} 1259c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1269c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1279c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public Rect getCropRect() { 1281738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall synchronized (mLock) { 129d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall try { 130d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mCropRect = mImage.getCropRect(); 131d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } catch (IllegalStateException imageClosedException) { 132d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // If the image is closed, then just return the cached CropRect. 133d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mCropRect; 134d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } 135d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mCropRect; 1361738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall } 1379c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1389c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1399c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1409c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#setCropRect} 1419c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1429c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1439c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public void setCropRect(Rect cropRect) { 1441738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall synchronized (mLock) { 145d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mCropRect = cropRect; 146d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall try { 147d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall mImage.setCropRect(cropRect); 148d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } catch (IllegalStateException imageClosedException) { 149d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall // Ignore. 150d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } 1511738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall } 1529c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1539c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1549c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1559c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#getFormat} 1569c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1579c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1589c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public int getFormat() { 159d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mFormat; 1609c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1619c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1629c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1639c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#getHeight} 1649c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1659c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1669c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public int getHeight() { 167d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mHeight; 1689c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1699c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1709c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1719c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#getPlanes} 1729c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1739c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1746e981cafa9cc57ebc7100cb84f68fb74dbd163daI-Jong Lin public List<ImageProxy.Plane> getPlanes() { 175d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mPlanes; 1769c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1779c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1789c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1799c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#getTimestamp} 1809c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1819c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1829c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public long getTimestamp() { 183d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mTimestamp; 1849c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1859c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1869c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1879c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#getWidth} 1889c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1899c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1909c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public int getWidth() { 191d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return mWidth; 1929c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 1939c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall 1949c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall /** 1959c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall * @see {@link android.media.Image#close} 1969c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall */ 1979c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall @Override 1989c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall public void close() { 1991738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall synchronized (mLock) { 2001738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall mImage.close(); 2011738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall } 2029c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall } 203b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall 204b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall @Override 205b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall public String toString() { 206d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return Objects.toStringHelper(this) 207d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall .add("format", getFormat()) 208d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall .add("timestamp", getTimestamp()) 209d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall .add("width", getWidth()) 210d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall .add("height", getHeight()) 211d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall .toString(); 212d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } 2131738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall 214d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall @Override 215d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall public boolean equals(Object other) { 216d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall if (other == null) { 217d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return false; 2181738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall } 219d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall if (!(other instanceof ImageProxy)) { 220d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return false; 221d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } 222d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall ImageProxy otherImage = (ImageProxy) other; 223d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return otherImage.getFormat() == getFormat() && 224d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall otherImage.getWidth() == getWidth() && 225d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall otherImage.getHeight() == getHeight() && 226d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall otherImage.getTimestamp() == getTimestamp(); 227d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall } 228d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall 229d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall @Override 230d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall public int hashCode() { 231d0316626dd2c2f4bd37ac7a198dbfe9e0ce2277fPuneet Lall return Objects.hashCode(getFormat(), getWidth(), getHeight(), getTimestamp()); 232b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall } 2339c94ab32a69a1ad3642a0f1e38e68bcfd97d3511Puneet Lall} 234