Path: blob/master/src/java.desktop/share/native/libawt/java2d/SurfaceData.h
41152 views
/*1* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/**26* This include file contains information on how to use a SurfaceData27* object from native code.28*/2930#ifndef _Included_SurfaceData31#define _Included_SurfaceData3233#include <jni.h>3435#ifdef __cplusplus36extern "C" {37#endif3839/*40* This structure is used to represent a rectangular bounding box41* throughout various functions in the native SurfaceData API.42*43* All coordinates (x1 <= x < x2, y1 <= y < y2) are considered to44* be inside these bounds.45*/46typedef struct {47jint x1;48jint y1;49jint x2;50jint y2;51} SurfaceDataBounds;5253#define SD_RASINFO_PRIVATE_SIZE 645455/*56* The SurfaceDataRasInfo structure is used to pass in and return various57* pieces of information about the destination drawable. In particular:58*59* SurfaceDataBounds bounds;60* [Needed for SD_LOCK_READ or SD_LOCK_WRITE]61* The 2 dimensional bounds of the raster array that is needed. Valid62* memory locations are required at:63* *(pixeltype *) (((char *)rasBase) + y * scanStride + x * pixelStride)64* for each x, y pair such that (bounds.x1 <= x < bounds.x2) and65* (bounds.y1 <= y < bounds.y2).66*67* void *rasBase;68* [Requires SD_LOCK_READ or SD_LOCK_WRITE]69* A pointer to the device space origin (0, 0) of the indicated raster70* data. This pointer may point to a location that is outside of the71* allocated memory for the requested bounds and it may even point72* outside of accessible memory. Only the locations that fall within73* the coordinates indicated by the requested bounds are guaranteed74* to be accessible.75*76* jint pixelBitOffset;77* [Requires SD_LOCK_READ or SD_LOCK_WRITE]78* The number of bits offset from the beginning of the first byte79* of a scanline to the first bit of the first pixel on that scanline.80* The bit offset must be less than 8 and it must be the same for each81* scanline. This field is only needed by image types which pack82* multiple pixels into a byte, such as ByteBinary1Bit et al. For83* image types which use whole bytes (or shorts or ints) to store84* their pixels, this field will always be 0.85*86* jint pixelStride;87* [Requires SD_LOCK_READ or SD_LOCK_WRITE]88* The pixel stride is the distance in bytes from the data for one pixel89* to the data for the pixel at the next x coordinate (x, y) => (x+1, y).90* For data types that pack multiple pixels into a byte, such as91* ByteBinary1Bit et al, this field will be 0 and the loops which92* render to and from such data need to calculate their own offset93* from the beginning of the scanline using the absolute x coordinate94* combined with the pixelBitOffset field.95* Bugfix 6220829 - this field used to be unsigned int, but some96* primitives used negative pixel offsets and the corresponding97* unsigned stride values caused the resulting pixel offset to98* to always be a positive 32-bit quantity - causing problems on99* 64-bit architectures.100*101* jint scanStride;102* [Requires SD_LOCK_READ or SD_LOCK_WRITE]103* The scan stride is the distance in bytes from the data for one pixel104* to the data for the pixel at the next y coordinate (x, y) => (x, y+1).105* Bugfix 6220829 - this field used to be unsigned int, but some106* primitives used negative pixel offsets and the corresponding107* unsigned stride values caused the resulting pixel offset to108* to always be a positive 32-bit quantity - causing problems on109* 64-bit architectures.110*111* unsigned int lutSize;112* [Requires SD_LOCK_LUT]113* The number of entries in the color lookup table. The data beyond the114* end of the map will be undefined.115*116* jint *lutBase;117* [Requires SD_LOCK_LUT]118* A pointer to the beginning of the color lookup table for the colormap.119* The color lookup table is formatted as an array of jint values each120* representing the 32-bit ARGB color for the pixel representing by the121* corresponding index. The table is guaranteed to contain at least 256122* valid memory locations even if the size of the map is smaller than 256.123*124* unsigned char *invColorTable;125* [Requires SD_LOCK_INVCOLOR]126* A pointer to the beginning of the inverse color lookup table for the127* colormap. The inverse color lookup table is formatted as a 32x32x32128* array of bytes indexed by RxGxB where each component is reduced to 5129* bits of precision before indexing.130*131* char *redErrTable;132* char *grnErrTable;133* char *bluErrTable;134* [Requires SD_LOCK_INVCOLOR]135* Pointers to the beginning of the ordered dither color error tables136* for the colormap. The error tables are formatted as an 8x8 array137* of bytes indexed by coordinates using the formula [y & 7][x & 7].138*139* int *invGrayTable;140* [Requires SD_LOCK_INVGRAY]141* A pointer to the beginning of the inverse gray lookup table for the142* colormap. The inverse color lookup table is formatted as an array143* of 256 integers indexed by a byte gray level and storing an index144* into the colormap of the closest matching gray pixel.145*146* union priv {};147* A buffer of private data for the SurfaceData implementation.148* This field is a union of a data block of the desired default149* size (SD_RASINFO_PRIVATE_SIZE) and a (void *) pointer that150* ensures proper "strictest" alignment on all platforms.151*/152typedef struct {153SurfaceDataBounds bounds; /* bounds of raster array */154void *rasBase; /* Pointer to (0, 0) pixel */155jint pixelBitOffset; /* bit offset to (0, *) pixel */156jint pixelStride; /* bytes to next X pixel */157jint scanStride; /* bytes to next Y pixel */158unsigned int lutSize; /* # colors in colormap */159jint *lutBase; /* Pointer to colormap[0] */160unsigned char *invColorTable; /* Inverse color table */161char *redErrTable; /* Red ordered dither table */162char *grnErrTable; /* Green ordered dither table */163char *bluErrTable; /* Blue ordered dither table */164int *invGrayTable; /* Inverse gray table */165int representsPrimaries; /* whether cmap represents primary colors */166union {167void *align; /* ensures strict alignment */168char data[SD_RASINFO_PRIVATE_SIZE];169} priv;170} SurfaceDataRasInfo;171172typedef struct _SurfaceDataOps SurfaceDataOps;173174/*175* This function is used to lock a particular region of a particular176* destination. Once this method is called, no changes of any of the177* data returned by any of the other SurfaceData vectored functions178* may change until a corresponding call to Release is made.179*180* The env parameter should be the JNIEnv of the surrounding JNI context.181*182* The ops parameter should be a pointer to the ops object upon which183* this function is being invoked.184*185* The rasInfo parameter should be a pointer to a SurfaceDataRasInfo186* structure in which the bounds have been initialized to the maximum187* bounds of the raster data that will need to be accessed later.188*189* The lockflags parameter should indicate which information will be190* needed by the caller. The various flags which may be OR'd together191* may consist of any of the following:192* SD_LOCK_READ The caller needs to read pixels from the dest193* SD_LOCK_WRITE The caller needs to write pixels to the dest194* SD_LOCK_RD_WR A combination of (SD_LOCK_READ | SD_LOCK_WRITE)195* SD_LOCK_LUT The caller needs the colormap (Lut)196* SD_LOCK_INVCOLOR The caller needs the inverse color table197* SD_LOCK_INVGRAY The caller needs the inverse gray table198* SD_LOCK_FASTEST The caller only wants direct pixel access199* Note that the SD_LOCK_LUT, SD_LOCK_INVCOLOR, and SD_LOCK_INVGRAY flags200* are only valid for destinations with IndexColorModels.201* Also note that SD_LOCK_FASTEST will only succeed if the access to the202* pixels will occur just as fast regardless of the size of the bounds.203* This flag is used by the Text rendering routines to determine if it204* matters whether or not they have calculated a tight bounding box for205* the pixels they will be touching.206*207* Return value:208*209* If this function succeeds, it will return SD_SUCCESS (0).210*211* If this function is unable to honor the SD_LOCK_FASTEST flag,212* it will return SD_SLOWLOCK. The bounds parameter of the213* SurfaceDataRasInfo object should be intersected with a tighter214* bounding rectangle before calling the GetRasInfo function so215* as to minimize the amount pixel copying or conversion. Note216* that the Lock function may have already intersected the217* bounds with a tighter rectangle as it tried to honor the218* SD_SLOWLOCK flag and so the caller should only use intersection219* operations to further restrict the bounds.220*221* If this function fails for any reason that is not recoverable,222* it will throw an appropriate Java exception and return SD_FAILED.223*224* Operation:225*226* This function will intersect the bounds specified in the rasInfo227* parameter with the available raster data in the destination drawable228* and modify the contents of the bounds field to represent the maximum229* available raster data.230*231* If the available raster data in the destination drawable consists of232* a non-rectangular region of pixels, this method may throw an InvalidPipe233* exception (optionally the object may decide to provide a copy of the234* destination pixel data with undefined data in the inaccessible portions).235*236* Further processing by the caller may discover that a smaller region of237* data is actually needed and the call to GetRasData can be made with a238* still smaller bounds.239*240* Note to callers:241* This function may use JNI methods so it is important that the242* caller not have any outstanding GetPrimitiveArrayCritical or243* GetStringCritical locks which have not been released.244*245* Note to implementers:246* The caller may also continue to use JNI methods after this method247* is called so it is important that implementations of SurfaceData248* not return from this function with any outstanding JNI Critical249* locks that have not been released.250*/251typedef jint LockFunc(JNIEnv *env,252SurfaceDataOps *ops,253SurfaceDataRasInfo *rasInfo,254jint lockflags);255256/*257* This function returns information about the raster data for the drawable.258* The function will fill in or modify the contents of the SurfaceDataRasInfo259* structure that is passed in with various pieces of information depending260* on what was requested in the lockflags parameter that was handed into261* the LockFunc. For more information on which pieces of information are262* returned based upon the lock flags see the documentation for the263* RasInfo structure above.264*265* The env parameter should be the JNIEnv of the surrounding JNI context.266*267* The ops parameter should be a pointer to the ops object upon which268* this function is being invoked.269*270* The pRasInfo parameter should be a pointer to the same structure of type271* SurfaceDataRasInfo. The bounds member of that structure should be272* initialized to the bounding box of the raster data that is actually273* needed for reading or writing before calling this function. These274* bounds must be a subset of the raster bounds that were given to the275* LockFunc or the results will be undefined.276*277* If the surface was locked with the flag SD_LOCK_FASTEST then this278* function may reevaluate the bounds in the RasInfo structure and279* return a subset of what was requested. Callers that use that flag280* should be prepared to reevaluate their clipping after GetRasInfo281* returns. If the SD_LOCK_FASTEST flag was not specified, then this282* function will return a buffer containing all of the pixels in the283* requested bounds without reevaluating them.284*285* Any information that was requested in the lockflags of the LockFunc286* will be returned and NULL pointers will be returned for all other287* information.288*289* Note to callers:290* This function may use JNI Critical methods so it is important291* that the caller not call any other JNI methods after this function292* returns until the Release function is called.293*/294typedef void GetRasInfoFunc(JNIEnv *env,295SurfaceDataOps *ops,296SurfaceDataRasInfo *pRasInfo);297298/*299* This function releases all of the Critical data for the specified300* drawable.301*302* This function vector is allowed to be NULL if a given SurfaceData303* implementation does not require the use of JNI Critical array locks.304* Callers should use the "SurfaceData_InvokeRelease(env, ops)" macro305* to handle the conditional invocation of this function.306*307* In particular, this function will release any outstanding JNI Critical308* locks that the SurfaceData implementation may have used so that it309* will be safe for the caller to start using arbitrary JNI calls or310* return from its calling JNI function.311*312* The env parameter should be the JNIEnv of the surrounding JNI context.313*314* The ops parameter should be a pointer to the ops object upon which315* this function is being invoked.316*317* The pRasInfo parameter should be a pointer to the same structure of318* type SurfaceDataRasInfo that was passed to the GetRasInfo function.319* The bounds should be unchanged since that call.320*321* Note to callers:322* This function will release any outstanding JNI Critical locks so323* it will once again be safe to use arbitrary JNI calls or return324* to the enclosing JNI native context.325*326* Note to implementers:327* This function may not use any JNI methods other than to release328* outstanding JNI Critical array locks since there may be other329* nested SurfacData objects holding locks with their own outstanding330* JNI Critical locks. This restriction includes the use of the331* JNI monitor calls so that all MonitorExit invocations must be332* done in the Unlock function.333*/334typedef void ReleaseFunc(JNIEnv *env,335SurfaceDataOps *ops,336SurfaceDataRasInfo *pRasInfo);337338/*339* This function unlocks the specified drawable.340*341* This function vector is allowed to be NULL if a given SurfaceData342* implementation does not require any unlocking of the destination.343* Callers should use the "SurfaceData_InvokeUnlock(env, ops)" macro344* to handle the conditional invocation of this function.345*346* The env parameter should be the JNIEnv of the surrounding JNI context.347*348* The ops parameter should be a pointer to the ops object upon which349* this function is being invoked.350*351* The pRasInfo parameter should be a pointer to the same structure of352* type SurfaceDataRasInfo that was passed to the GetRasInfo function.353* The bounds should be unchanged since that call.354*355* Note to callers:356* This function may use JNI methods so it is important that the357* caller not have any outstanding GetPrimitiveArrayCritical or358* GetStringCritical locks which have not been released.359*360* Note to implementers:361* This function may be used to release any JNI monitors used to362* prevent the destination from being modified. It may also be363* used to perform operations which may require blocking (such as364* executing X11 operations which may need to flush data).365*/366typedef void UnlockFunc(JNIEnv *env,367SurfaceDataOps *ops,368SurfaceDataRasInfo *pRasInfo);369370/*371* This function sets up the specified drawable. Some surfaces may372* need to perform certain operations during Setup that cannot be373* done after later operations such as Lock. For example, on374* win9x systems, when any surface is locked we cannot make a call to375* the message-handling thread.376*377* This function vector is allowed to be NULL if a given SurfaceData378* implementation does not require any setup.379*380* The env parameter should be the JNIEnv of the surrounding JNI context.381*382* The ops parameter should be a pointer to the ops object upon which383* this function is being invoked.384*385* Note to callers:386* This function may use JNI methods so it is important that the387* caller not have any outstanding GetPrimitiveArrayCritical or388* GetStringCritical locks which have not been released.389*/390typedef void SetupFunc(JNIEnv *env,391SurfaceDataOps *ops);392393/*394* This function disposes the specified SurfaceDataOps structure395* and associated native resources.396* The implementation is SurfaceData-type specific.397*/398typedef void DisposeFunc(JNIEnv *env,399SurfaceDataOps *ops);400401/*402* Constants used for return values. Constants less than 0 are403* unrecoverable failures and indicate that a Java exception has404* already been thrown. Constants greater than 0 are conditional405* successes which warn the caller that various optional features406* were not available so that workarounds can be used.407*/408#define SD_FAILURE -1409#define SD_SUCCESS 0410#define SD_SLOWLOCK 1411412/*413* Constants for the flags used in the Lock function.414*/415#define SD_LOCK_READ (1 << 0)416#define SD_LOCK_WRITE (1 << 1)417#define SD_LOCK_RD_WR (SD_LOCK_READ | SD_LOCK_WRITE)418#define SD_LOCK_LUT (1 << 2)419#define SD_LOCK_INVCOLOR (1 << 3)420#define SD_LOCK_INVGRAY (1 << 4)421#define SD_LOCK_FASTEST (1 << 5)422#define SD_LOCK_PARTIAL (1 << 6)423#define SD_LOCK_PARTIAL_WRITE (SD_LOCK_WRITE | SD_LOCK_PARTIAL)424#define SD_LOCK_NEED_PIXELS (SD_LOCK_READ | SD_LOCK_PARTIAL)425426/*427* This structure provides the function vectors for manipulating428* and retrieving information about the destination drawable.429* There are also variables for the surface data object used by430* native code to track the state of the surface.431* The sdObject is a pointer to the Java SurfaceData object;432* this is set in SurfaceData_InitOps() and used by any object433* using the ops structure to refer to elements in the Java object434* (such as fields that we need to set from native code).435*/436struct _SurfaceDataOps {437LockFunc *Lock;438GetRasInfoFunc *GetRasInfo;439ReleaseFunc *Release;440UnlockFunc *Unlock;441SetupFunc *Setup;442DisposeFunc *Dispose;443jobject sdObject;444};445446#define _ClrReduce(c) (((unsigned char) c) >> 3)447448/*449* This macro performs a lookup in an inverse color table given 3 8-bit450* RGB primaries. It automates the process of reducing the primaries451* to 5-bits of precision and using them to index into the specified452* inverse color lookup table.453*/454#define SurfaceData_InvColorMap(invcolortbl, r, g, b) \455(invcolortbl)[(_ClrReduce(r)<<10) + (_ClrReduce(g)<<5) + _ClrReduce(b)]456457/*458* This macro invokes the SurfaceData Release function only if the459* function vector is not NULL.460*/461#define SurfaceData_InvokeRelease(env, ops, pRI) \462do { \463if ((ops)->Release != NULL) { \464(ops)->Release(env, ops, pRI); \465} \466} while(0)467468/*469* This macro invokes the SurfaceData Unlock function only if the470* function vector is not NULL.471*/472#define SurfaceData_InvokeUnlock(env, ops, pRI) \473do { \474if ((ops)->Unlock != NULL) { \475(ops)->Unlock(env, ops, pRI); \476} \477} while(0)478479/*480* This macro invokes both the SurfaceData Release and Unlock functions481* only if the function vectors are not NULL. It can be used in cases482* where only one surface has been accessed and where no other JNI483* Critical locks (which would need to be released after Release and484* before Unlock) are held by the calling function.485*/486#define SurfaceData_InvokeReleaseUnlock(env, ops, pRI) \487do { \488if ((ops)->Release != NULL) { \489(ops)->Release(env, ops, pRI); \490} \491if ((ops)->Unlock != NULL) { \492(ops)->Unlock(env, ops, pRI); \493} \494} while(0)495496/*497* This macro invokes both the SurfaceData Release and Unlock functions498* on two nested drawables only if the function vectors are not NULL.499* It can be used in cases where two surfaces have been accessed and500* where no other JNI Critical locks (which would need to be released501* after Release and before Unlock) are held by the calling function. The502* two ops vectors should be specified in the same order that they were503* locked. Both surfaces will be released and then both unlocked.504*/505#define SurfaceData_InvokeReleaseUnlock2(env, ops1, pRI1, ops2, pRI2) \506do { \507if ((ops2)->Release != NULL) { \508(ops2)->Release(env, ops2, pRI2); \509} \510if ((ops1)->Release != NULL) { \511(ops1)->Release(env, ops1, pRI1); \512} \513if ((ops2)->Unlock != NULL) { \514(ops2)->Unlock(env, ops2, pRI2); \515} \516if ((ops1)->Unlock != NULL) { \517(ops1)->Unlock(env, ops1, pRI1); \518} \519} while(0)520521#define SurfaceData_InvokeDispose(env, ops) \522do { \523if ((ops)->Dispose != NULL) { \524(ops)->Dispose(env, ops); \525} \526} while(0)527528#define SurfaceData_InvokeSetup(env, ops) \529do { \530if ((ops)->Setup != NULL) { \531(ops)->Setup(env, ops); \532} \533} while(0)534535/*536* This function returns a pointer to a native SurfaceDataOps537* structure for accessing the indicated SurfaceData Java object.538*539* Note to callers:540* This function uses JNI methods so it is important that the541* caller not have any outstanding GetPrimitiveArrayCritical or542* GetStringCritical locks which have not been released.543*544* The caller may continue to use JNI methods after this method545* is called since this function will not leave any outstanding546* JNI Critical locks unreleased.547*/548JNIEXPORT SurfaceDataOps * JNICALL549SurfaceData_GetOps(JNIEnv *env, jobject sData);550551/*552* Does the same as the above, but doesn't call Setup function553* even if it's set.554*/555JNIEXPORT SurfaceDataOps * JNICALL556SurfaceData_GetOpsNoSetup(JNIEnv *env, jobject sData);557558/*559* This function stores a pointer to a native SurfaceDataOps560* structure into the indicated Java SurfaceData object.561*562* Note to callers:563* This function uses JNI methods so it is important that the564* caller not have any outstanding GetPrimitiveArrayCritical or565* GetStringCritical locks which have not been released.566*567* The caller may continue to use JNI methods after this method568* is called since this function will not leave any outstanding569* JNI Critical locks unreleased.570*/571JNIEXPORT void JNICALL572SurfaceData_SetOps(JNIEnv *env, jobject sData, SurfaceDataOps *ops);573574/*575* This function throws an InvalidPipeException which will cause the576* calling SunGraphics2D object to revalidate its pipelines and call577* again. This utility method should be called from the SurfaceData578* native Lock routine when some attribute of the surface has changed579* that requires pipeline revalidation, including:580*581* The bit depth or pixel format of the surface.582* The surface (window) has been disposed.583* The device clip of the surface has been changed (resize, visibility, etc.)584*585* Note to callers:586* This function uses JNI methods so it is important that the587* caller not have any outstanding GetPrimitiveArrayCritical or588* GetStringCritical locks which have not been released.589*590* The caller may continue to use JNI methods after this method591* is called since this function will not leave any outstanding592* JNI Critical locks unreleased.593*/594JNIEXPORT void JNICALL595SurfaceData_ThrowInvalidPipeException(JNIEnv *env, const char *msg);596597/*598* This function intersects two bounds objects which exist in the same599* coordinate space. The contents of the first parameter (dst) are600* modified to contain the intersection of the two bounds while the601* contents of the second parameter (src) are untouched.602*/603JNIEXPORT void JNICALL604SurfaceData_IntersectBounds(SurfaceDataBounds *dst, SurfaceDataBounds *src);605606/*607* This function intersects a bounds object with a rectangle specified608* in lox, loy, hix, hiy format in the same coordinate space. The609* contents of the first parameter (bounds) are modified to contain610* the intersection of the two rectangular regions.611*/612JNIEXPORT void JNICALL613SurfaceData_IntersectBoundsXYXY(SurfaceDataBounds *bounds,614jint lox, jint loy, jint hix, jint hiy);615616/*617* This function intersects a bounds object with a rectangle specified618* in XYWH format in the same coordinate space. The contents of the619* first parameter (bounds) are modified to contain the intersection620* of the two rectangular regions.621*/622JNIEXPORT void JNICALL623SurfaceData_IntersectBoundsXYWH(SurfaceDataBounds *bounds,624jint x, jint y, jint w, jint h);625626/*627* This function intersects two bounds objects which exist in different628* coordinate spaces. The coordinate spaces of the two objects are629* related such that a given coordinate in the space of the A bounds630* is related to the analogous coordinate in the space of the B bounds631* by the formula: (AX + BXminusAX, AY + BYminusAY) == (BX, BY).632* The contents of both bounds objects are modified to represent their633* mutual intersection.634*/635JNIEXPORT void JNICALL636SurfaceData_IntersectBlitBounds(SurfaceDataBounds *Abounds,637SurfaceDataBounds *Bbounds,638jint BXminusAX, jint BYminusAY);639640641/*642* This function creates and initializes the ops structure. The function643* is called by "subclasses" of SurfaceData (e.g., BufImgSurfaceData)644* which pass in the size of the structure to allocate (subclasses generally645* need additional fields in the ops structure particular to their usage646* of the structure). The structure is allocated and initialized647* and is stored in the SurfaceData java object for later retrieval.648* Subclasses of SurfaceData should call this function instead of allocating649* the memory directly.650*/651JNIEXPORT SurfaceDataOps * JNICALL652SurfaceData_InitOps(JNIEnv *env, jobject sData, int opsSize);653654/*655* This function invokes the ops-specific disposal function.656* It is a part of the finalizers-free disposal mechanism.657* (see Disposer and DefaultDisposerRecord classes for more information)658* It also destroys the ops structure created in SurfaceData_InitOps.659*/660void SurfaceData_DisposeOps(JNIEnv *env, jlong ops);661662#ifdef __cplusplus663};664#endif665666#endif667668669