1 /* 2 * Copyright (C) 2016 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 /** 18 * @addtogroup Media 19 * @{ 20 */ 21 22 /** 23 * @file NdkImageReader.h 24 */ 25 26 /* 27 * This file defines an NDK API. 28 * Do not remove methods. 29 * Do not change method signatures. 30 * Do not change the value of constants. 31 * Do not change the size of any of the classes defined in here. 32 * Do not reference types that are not part of the NDK. 33 * Do not #include files that aren't part of the NDK. 34 */ 35 36 #ifndef _NDK_IMAGE_READER_H 37 #define _NDK_IMAGE_READER_H 38 39 #include <sys/cdefs.h> 40 #ifdef __ANDROID_VNDK__ 41 #include <cutils/native_handle.h> 42 #endif 43 44 #include <android/native_window.h> 45 #include "NdkMediaError.h" 46 #include "NdkImage.h" 47 48 __BEGIN_DECLS 49 50 /** 51 * AImage is an opaque type that allows direct application access to image data rendered into a 52 * {@link ANativeWindow}. 53 */ 54 typedef struct AImageReader AImageReader; 55 56 /** 57 * Create a new reader for images of the desired size and format. 58 * 59 * <p> 60 * The maxImages parameter determines the maximum number of {@link AImage} objects that can be 61 * acquired from the {@link AImageReader} simultaneously. Requesting more buffers will use up 62 * more memory, so it is important to use only the minimum number necessary for the use case. 63 * </p> 64 * <p> 65 * The valid sizes and formats depend on the source of the image data. 66 * </p> 67 * 68 * Available since API level 24. 69 * 70 * @param width The default width in pixels of the Images that this reader will produce. 71 * @param height The default height in pixels of the Images that this reader will produce. 72 * @param format The format of the Image that this reader will produce. This must be one of the 73 * AIMAGE_FORMAT_* enum value defined in {@link AIMAGE_FORMATS}. Note that not all 74 * formats are supported. One example is {@link AIMAGE_FORMAT_PRIVATE}, as it is not 75 * intended to be read by applications directly. That format is supported by 76 * {@link AImageReader_newWithUsage} introduced in API 26. 77 * @param maxImages The maximum number of images the user will want to access simultaneously. This 78 * should be as small as possible to limit memory use. Once maxImages Images are obtained 79 * by the user, one of them has to be released before a new {@link AImage} will become 80 * available for access through {@link AImageReader_acquireLatestImage} or 81 * {@link AImageReader_acquireNextImage}. Must be greater than 0. 82 * @param reader The created image reader will be filled here if the method call succeeeds. 83 * 84 * @return <ul> 85 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 86 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL, or one or more of width, 87 * height, format, maxImages arguments is not supported.</li> 88 * <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul> 89 * 90 * @see AImage 91 */ 92 media_status_t AImageReader_new( 93 int32_t width, int32_t height, int32_t format, int32_t maxImages, 94 /*out*/AImageReader** reader) __INTRODUCED_IN(24); 95 96 /** 97 * Delete an {@link AImageReader} and return all images generated by this reader to system. 98 * 99 * <p>This method will return all {@link AImage} objects acquired by this reader (via 100 * {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}) to system, 101 * making any of data pointers obtained from {@link AImage_getPlaneData} invalid. Do NOT access 102 * the reader object or any of those data pointers after this method returns.</p> 103 * 104 * Available since API level 24. 105 * 106 * @param reader The image reader to be deleted. 107 */ 108 void AImageReader_delete(AImageReader* reader) __INTRODUCED_IN(24); 109 110 /** 111 * Get a {@link ANativeWindow} that can be used to produce {@link AImage} for this image reader. 112 * 113 * Available since API level 24. 114 * 115 * @param reader The image reader of interest. 116 * @param window The output {@link ANativeWindow} will be filled here if the method call succeeds. 117 * The {@link ANativeWindow} is managed by this image reader. Do NOT call 118 * {@link ANativeWindow_release} on it. Instead, use {@link AImageReader_delete}. 119 * 120 * @return <ul> 121 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 122 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or window is NULL.</li></ul> 123 */ 124 media_status_t AImageReader_getWindow(AImageReader* reader, /*out*/ANativeWindow** window) __INTRODUCED_IN(24); 125 126 /** 127 * Query the default width of the {@link AImage} generated by this reader, in pixels. 128 * 129 * <p>The width may be overridden by the producer sending buffers to this reader's 130 * {@link ANativeWindow}. If so, the actual width of the images can be found using 131 * {@link AImage_getWidth}.</p> 132 * 133 * Available since API level 24. 134 * 135 * @param reader The image reader of interest. 136 * @param width the default width of the reader will be filled here if the method call succeeeds. 137 * 138 * @return <ul> 139 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 140 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or width is NULL.</li></ul> 141 */ 142 media_status_t AImageReader_getWidth(const AImageReader* reader, /*out*/int32_t* width) __INTRODUCED_IN(24); 143 144 /** 145 * Query the default height of the {@link AImage} generated by this reader, in pixels. 146 * 147 * <p>The height may be overridden by the producer sending buffers to this reader's 148 * {@link ANativeWindow}. If so, the actual height of the images can be found using 149 * {@link AImage_getHeight}.</p> 150 * 151 * Available since API level 24. 152 * 153 * @param reader The image reader of interest. 154 * @param height the default height of the reader will be filled here if the method call succeeeds. 155 * 156 * @return <ul> 157 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 158 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or height is NULL.</li></ul> 159 */ 160 media_status_t AImageReader_getHeight(const AImageReader* reader, /*out*/int32_t* height) __INTRODUCED_IN(24); 161 162 /** 163 * Query the format of the {@link AImage} generated by this reader. 164 * 165 * Available since API level 24. 166 * 167 * @param reader The image reader of interest. 168 * @param format the fromat of the reader will be filled here if the method call succeeeds. The 169 * value will be one of the AIMAGE_FORMAT_* enum value defiend in {@link NdkImage.h}. 170 * 171 * @return <ul> 172 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 173 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or format is NULL.</li></ul> 174 */ 175 media_status_t AImageReader_getFormat(const AImageReader* reader, /*out*/int32_t* format) __INTRODUCED_IN(24); 176 177 /** 178 * Query the maximum number of concurrently acquired {@link AImage}s of this reader. 179 * 180 * Available since API level 24. 181 * 182 * @param reader The image reader of interest. 183 * @param maxImages the maximum number of concurrently acquired images of the reader will be filled 184 * here if the method call succeeeds. 185 * 186 * @return <ul> 187 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 188 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or maxImages is NULL.</li></ul> 189 */ 190 media_status_t AImageReader_getMaxImages(const AImageReader* reader, /*out*/int32_t* maxImages) __INTRODUCED_IN(24); 191 192 /** 193 * Acquire the next {@link AImage} from the image reader's queue. 194 * 195 * <p>Warning: Consider using {@link AImageReader_acquireLatestImage} instead, as it will 196 * automatically release older images, and allow slower-running processing routines to catch 197 * up to the newest frame. Usage of {@link AImageReader_acquireNextImage} is recommended for 198 * batch/background processing. Incorrectly using this method can cause images to appear 199 * with an ever-increasing delay, followed by a complete stall where no new images seem to appear. 200 * </p> 201 * 202 * <p> 203 * This method will fail if {@link AImageReader_getMaxImages maxImages} have been acquired with 204 * {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}. In particular 205 * a sequence of {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage} 206 * calls greater than {@link AImageReader_getMaxImages maxImages} without calling 207 * {@link AImage_delete} in-between will exhaust the underlying queue. At such a time, 208 * {@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} will be returned until more images are released with 209 * {@link AImage_delete}. 210 * </p> 211 * 212 * Available since API level 24. 213 * 214 * @param reader The image reader of interest. 215 * @param image the acquired {@link AImage} will be filled here if the method call succeeeds. 216 * 217 * @return <ul> 218 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 219 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or image is NULL.</li> 220 * <li>{@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} if the number of concurrently acquired 221 * images has reached the limit.</li> 222 * <li>{@link AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE} if there is no buffers currently 223 * available in the reader queue.</li> 224 * <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul> 225 * 226 * @see AImageReader_acquireLatestImage 227 */ 228 media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image) __INTRODUCED_IN(24); 229 230 /** 231 * Acquire the latest {@link AImage} from the image reader's queue, dropping older images. 232 * 233 * <p> 234 * This operation will acquire all the images possible from the image reader, but 235 * {@link AImage_delete} all images that aren't the latest. This function is recommended to use over 236 * {@link AImageReader_acquireNextImage} for most use-cases, as it's more suited for real-time 237 * processing. 238 * </p> 239 * <p> 240 * Note that {@link AImageReader_getMaxImages maxImages} should be at least 2 for 241 * {@link AImageReader_acquireLatestImage} to be any different than 242 * {@link AImageReader_acquireNextImage} - discarding all-but-the-newest {@link AImage} requires 243 * temporarily acquiring two {@link AImage}s at once. Or more generally, calling 244 * {@link AImageReader_acquireLatestImage} with less than two images of margin, that is 245 * (maxImages - currentAcquiredImages < 2) will not discard as expected. 246 * </p> 247 * <p> 248 * This method will fail if {@link AImageReader_getMaxImages maxImages} have been acquired with 249 * {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage}. In particular 250 * a sequence of {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage} 251 * calls greater than {@link AImageReader_getMaxImages maxImages} without calling 252 * {@link AImage_delete} in-between will exhaust the underlying queue. At such a time, 253 * {@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} will be returned until more images are released with 254 * {@link AImage_delete}. 255 * </p> 256 * 257 * Available since API level 24. 258 * 259 * @param reader The image reader of interest. 260 * @param image the acquired {@link AImage} will be filled here if the method call succeeeds. 261 * 262 * @return <ul> 263 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 264 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader or image is NULL.</li> 265 * <li>{@link AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED} if the number of concurrently acquired 266 * images has reached the limit.</li> 267 * <li>{@link AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE} if there is no buffers currently 268 * available in the reader queue.</li> 269 * <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul> 270 * 271 * @see AImageReader_acquireNextImage 272 */ 273 media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image) __INTRODUCED_IN(24); 274 275 276 /** 277 * Signature of the callback which is called when a new image is available from {@link AImageReader}. 278 * 279 * @param context The optional application context provided by user in 280 * {@link AImageReader_setImageListener}. 281 * @param session The camera capture session whose state is changing. 282 */ 283 typedef void (*AImageReader_ImageCallback)(void* context, AImageReader* reader); 284 285 typedef struct AImageReader_ImageListener { 286 /// Optional application context passed as the first parameter of the callback. 287 void* context; 288 289 /** 290 * This callback is called when there is a new image available in the image reader's queue. 291 * 292 * <p>The callback happens on one dedicated thread per {@link AImageReader} instance. It is okay 293 * to use AImageReader_* and AImage_* methods within the callback. Note that it is possible that 294 * calling {@link AImageReader_acquireNextImage} or {@link AImageReader_acquireLatestImage} 295 * returns {@link AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE} within this callback. For example, when 296 * there are multiple images and callbacks queued, if application called 297 * {@link AImageReader_acquireLatestImage}, some images will be returned to system before their 298 * corresponding callback is executed.</p> 299 */ 300 AImageReader_ImageCallback onImageAvailable; 301 } AImageReader_ImageListener; 302 303 /** 304 * Set the onImageAvailable listener of this image reader. 305 * 306 * Calling this method will replace previously registered listeners. 307 * 308 * Available since API level 24. 309 * 310 * @param reader The image reader of interest. 311 * @param listener The {@link AImageReader_ImageListener} to be registered. Set this to NULL if 312 * the application no longer needs to listen to new images. 313 * 314 * @return <ul> 315 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 316 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL.</li></ul> 317 */ 318 media_status_t AImageReader_setImageListener( 319 AImageReader* reader, AImageReader_ImageListener* listener) __INTRODUCED_IN(24); 320 321 /** 322 * AImageReader constructor similar to {@link AImageReader_new} that takes an additional parameter 323 * for the consumer usage. All other parameters and the return values are identical to those passed 324 * to {@link AImageReader_new}. 325 * 326 * <p>If the \c format is {@link AIMAGE_FORMAT_PRIVATE}, the created {@link AImageReader} 327 * will produce images whose contents are not directly accessible by the application. The application can 328 * still acquire images from this {@link AImageReader} and access {@link AHardwareBuffer} via 329 * {@link AImage_getHardwareBuffer()}. The {@link AHardwareBuffer} gained this way can then 330 * be passed back to hardware (such as GPU or hardware encoder if supported) for future processing. 331 * For example, you can obtain an EGLClientBuffer from the {@link AHardwareBuffer} by using 332 * eglGetNativeClientBufferANDROID extension and pass that EGLClientBuffer to 333 * eglCreateImageKHR to create an EGLImage resource type, which may then be bound to a 334 * texture via glEGLImageTargetTexture2DOES on supported devices. This can be useful for 335 * transporting textures that may be shared cross-process.</p> 336 * <p>In general, when software access to image data is not necessary, an {@link AImageReader} 337 * created with {@link AIMAGE_FORMAT_PRIVATE} format is more efficient, compared with {@link 338 * AImageReader}s using other format such as {@link AIMAGE_FORMAT_YUV_420_888}.</p> 339 * 340 * <p>Note that not all format and usage flag combination is supported by the {@link AImageReader}, 341 * especially if \c format is {@link AIMAGE_FORMAT_PRIVATE}, \c usage must not include either 342 * {@link AHARDWAREBUFFER_USAGE_CPU_READ_RARELY} or {@link AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN}</p> 343 * 344 * @param width The default width in pixels of the Images that this reader will produce. 345 * @param height The default height in pixels of the Images that this reader will produce. 346 * @param format The format of the Image that this reader will produce. This must be one of the 347 * AIMAGE_FORMAT_* enum value defined in {@link AIMAGE_FORMATS}. 348 * @param usage specifies how the consumer will access the AImage, using combination of the 349 * AHARDWAREBUFFER_USAGE flags described in {@link hardware_buffer.h}. 350 * Passing {@link AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN} is equivalent to calling 351 * {@link AImageReader_new} with the same parameters. 352 * 353 * Note that not all format and usage flag combination is supported by the {@link AImageReader}. 354 * Below are the combinations supported by the {@link AImageReader}. 355 * <table> 356 * <tr> 357 * <th>Format</th> 358 * <th>Compatible usage flags</th> 359 * </tr> 360 * <tr> 361 * <td>non-{@link AIMAGE_FORMAT_PRIVATE} formats defined in {@link NdkImage.h} 362 * </td> 363 * <td>{@link AHARDWAREBUFFER_USAGE_CPU_READ_RARELY} or 364 * {@link AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN}</td> 365 * </tr> 366 * <tr> 367 * <td>{@link AIMAGE_FORMAT_RGBA_8888}</td> 368 * <td>{@link AHARDWAREBUFFER_USAGE_VIDEO_ENCODE} or 369 * {@link AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE}, or combined</td> 370 * </tr> 371 * </table> 372 * 373 * Available since API level 26. 374 * 375 * @return <ul> 376 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 377 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL, or one or more of width, 378 * height, format, maxImages, or usage arguments is not supported.</li> 379 * <li>{@link AMEDIA_ERROR_UNKNOWN} if the method fails for some other reasons.</li></ul> 380 * 381 * @see AImage 382 * @see AImageReader_new 383 * @see AHardwareBuffer 384 */ 385 media_status_t AImageReader_newWithUsage( 386 int32_t width, int32_t height, int32_t format, uint64_t usage, int32_t maxImages, 387 /*out*/ AImageReader** reader) __INTRODUCED_IN(26); 388 389 /** 390 * Acquire the next {@link AImage} from the image reader's queue asynchronously. 391 * 392 * <p>AImageReader acquire method similar to {@link AImageReader_acquireNextImage} that takes an 393 * additional parameter for the sync fence. All other parameters and the return values are 394 * identical to those passed to {@link AImageReader_acquireNextImage}.</p> 395 * 396 * Available since API level 26. 397 * 398 * @param acquireFenceFd A sync fence fd defined in {@link sync.h}, which is used to signal when the 399 * buffer is ready to consume. When synchronization fence is not needed, fence will be set 400 * to -1 and the {@link AImage} returned is ready for use immediately. Otherwise, user shall 401 * use syscalls such as \c poll(), \c epoll(), \c select() to wait for the 402 * fence fd to change status before attempting to access the {@link AImage} returned. 403 * 404 * @see sync.h 405 * @see sync_get_fence_info 406 */ 407 media_status_t AImageReader_acquireNextImageAsync( 408 AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd) __INTRODUCED_IN(26); 409 410 /** 411 * Acquire the latest {@link AImage} from the image reader's queue asynchronously, dropping older 412 * images. 413 * 414 * <p>AImageReader acquire method similar to {@link AImageReader_acquireLatestImage} that takes an 415 * additional parameter for the sync fence. All other parameters and the return values are 416 * identical to those passed to {@link AImageReader_acquireLatestImage}.</p> 417 * 418 * Available since API level 26. 419 * 420 * @param acquireFenceFd A sync fence fd defined in {@link sync.h}, which is used to signal when the 421 * buffer is ready to consume. When synchronization fence is not needed, fence will be set 422 * to -1 and the {@link AImage} returned is ready for use immediately. Otherwise, user shall 423 * use syscalls such as \c poll(), \c epoll(), \c select() to wait for the 424 * fence fd to change status before attempting to access the {@link AImage} returned. 425 * 426 * @see sync.h 427 * @see sync_get_fence_info 428 */ 429 media_status_t AImageReader_acquireLatestImageAsync( 430 AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd) __INTRODUCED_IN(26); 431 432 /** 433 * Signature of the callback which is called when {@link AImageReader} is about to remove a buffer. 434 * 435 * @param context The optional application context provided by user in 436 * {@link AImageReader_setBufferRemovedListener}. 437 * @param reader The {@link AImageReader} of interest. 438 * @param buffer The {@link AHardwareBuffer} that is being removed from this image reader. 439 */ 440 typedef void (*AImageReader_BufferRemovedCallback)(void* context, 441 AImageReader* reader, 442 AHardwareBuffer* buffer); 443 444 /** 445 * A listener to the AHardwareBuffer removal event, use 446 * {@link AImageReader_setBufferRemovedListener} to register the listener object to AImageReader. 447 */ 448 typedef struct AImageReader_BufferRemovedListener { 449 /// Optional application context passed as the first parameter of the callback. 450 void* context; 451 452 /** 453 * This callback is called when an old {@link AHardwareBuffer} is about to be removed from the 454 * image reader. 455 * 456 * <p>Note that registering this callback is optional unless the user holds on extra reference 457 * to {@link AHardwareBuffer} returned from {@link AImage_getHardwareBuffer} by calling {@link 458 * AHardwareBuffer_acquire} or creating external graphic objects, such as EglImage, from it.</p> 459 * 460 * <p>If the callback is registered, the {@link AImageReader} will hold on the last of its 461 * references to the {@link AHardwareBuffer} until this callback returns. User can use the 462 * callback to get notified that it becomes the last owner of the buffer. It is up to the user 463 * to decide to either 1) immediately release all of its references to the buffer; or 2) keep 464 * using the buffer and release it in future. Note that, if option 2 if used, user of this API 465 * is responsible to deallocate the buffer properly by calling {@link AHardwareBuffer_release}. 466 * </p> 467 * 468 * @see AHardwareBuffer_release 469 * @see AImage_getHardwareBuffer 470 */ 471 AImageReader_BufferRemovedCallback onBufferRemoved; 472 } AImageReader_BufferRemovedListener; 473 474 /** 475 * Set the onBufferRemoved listener of this image reader. 476 * 477 * <p>Note that calling this method will replace previously registered listeners.</p> 478 * 479 * Available since API level 26. 480 * 481 * @param reader The image reader of interest. 482 * @param listener the {@link AImageReader_BufferRemovedListener} to be registered. Set this to 483 * NULL if application no longer needs to listen to buffer removed events. 484 * 485 * @return <ul> 486 * <li>{@link AMEDIA_OK} if the method call succeeds.</li> 487 * <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if reader is NULL.</li></ul> 488 * 489 * @see AImage_getHardwareBuffer 490 */ 491 media_status_t AImageReader_setBufferRemovedListener( 492 AImageReader* reader, AImageReader_BufferRemovedListener* listener) __INTRODUCED_IN(26); 493 494 #ifdef __ANDROID_VNDK__ 495 /* 496 * Get the native_handle_t corresponding to the ANativeWindow owned by the 497 * AImageReader provided. 498 * 499 * @param reader The image reader of interest. 500 * @param handle The output native_handle_t. This native handle is owned by 501 * this image reader. 502 * 503 * @return AMEDIA_OK if the method call succeeds. 504 * AMEDIA_ERROR_INVALID_PARAMETER if reader or handle are NULL. 505 * AMEDIA_ERROR_UNKNOWN if some other error is encountered. 506 */ 507 media_status_t AImageReader_getWindowNativeHandle( 508 AImageReader *reader, /* out */native_handle_t **handle); 509 #endif 510 511 __END_DECLS 512 513 #endif //_NDK_IMAGE_READER_H 514 515 /** @} */ 516