/*
 * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * This include file contains information on how to use a SurfaceData
 * object from native code.
 */

#ifndef _Included_SurfaceData
#define _Included_SurfaceData

#include <jni.h>
#include <limits.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * This structure is used to represent a rectangular bounding box
 * throughout various functions in the native SurfaceData API.
 *
 * All coordinates (x1 <= x < x2, y1 <= y < y2) are considered to
 * be inside these bounds.
 */
typedef struct {
    jint x1;
    jint y1;
    jint x2;
    jint y2;
} SurfaceDataBounds;

#define SD_RASINFO_PRIVATE_SIZE         64

#define UNSAFE_TO_ADD(a, b) \
    (((a >= 0) && (b >= 0) && (a > (INT_MAX - b))) || \
     ((a < 0) && (b < 0) && (a < (INT_MIN - b)))) \

#define UNSAFE_TO_SUB(a, b) \
    (((b >= 0) && (a < 0) && (a < (INT_MIN + b))) || \
     ((b < 0) && (a >= 0) && (a > (INT_MAX + b)))) \

/*
 * The SurfaceDataRasInfo structure is used to pass in and return various
 * pieces of information about the destination drawable.  In particular:
 *
 *      SurfaceDataBounds bounds;
 * [Needed for SD_LOCK_READ or SD_LOCK_WRITE]
 * The 2 dimensional bounds of the raster array that is needed.  Valid
 * memory locations are required at:
 *      *(pixeltype *) (((char *)rasBase) + y * scanStride + x * pixelStride)
 * for each x, y pair such that (bounds.x1 <= x < bounds.x2) and
 * (bounds.y1 <= y < bounds.y2).
 *
 *      void *rasBase;
 * [Requires SD_LOCK_READ or SD_LOCK_WRITE]
 * A pointer to the device space origin (0, 0) of the indicated raster
 * data.  This pointer may point to a location that is outside of the
 * allocated memory for the requested bounds and it may even point
 * outside of accessible memory.  Only the locations that fall within
 * the coordinates indicated by the requested bounds are guaranteed
 * to be accessible.
 *
 *      jint pixelBitOffset;
 * [Requires SD_LOCK_READ or SD_LOCK_WRITE]
 * The number of bits offset from the beginning of the first byte
 * of a scanline to the first bit of the first pixel on that scanline.
 * The bit offset must be less than 8 and it must be the same for each
 * scanline.  This field is only needed by image types which pack
 * multiple pixels into a byte, such as ByteBinary1Bit et al.  For
 * image types which use whole bytes (or shorts or ints) to store
 * their pixels, this field will always be 0.
 *
 *      jint pixelStride;
 * [Requires SD_LOCK_READ or SD_LOCK_WRITE]
 * The pixel stride is the distance in bytes from the data for one pixel
 * to the data for the pixel at the next x coordinate (x, y) => (x+1, y).
 * For data types that pack multiple pixels into a byte, such as
 * ByteBinary1Bit et al, this field will be 0 and the loops which
 * render to and from such data need to calculate their own offset
 * from the beginning of the scanline using the absolute x coordinate
 * combined with the pixelBitOffset field.
 * Bugfix 6220829 - this field used to be unsigned int, but some
 * primitives used negative pixel offsets and the corresponding
 * unsigned stride values caused the resulting pixel offset to
 * to always be a positive 32-bit quantity - causing problems on
 * 64-bit architectures.
 *
 *      jint scanStride;
 * [Requires SD_LOCK_READ or SD_LOCK_WRITE]
 * The scan stride is the distance in bytes from the data for one pixel
 * to the data for the pixel at the next y coordinate (x, y) => (x, y+1).
 * Bugfix 6220829 - this field used to be unsigned int, but some
 * primitives used negative pixel offsets and the corresponding
 * unsigned stride values caused the resulting pixel offset to
 * to always be a positive 32-bit quantity - causing problems on
 * 64-bit architectures.
 *
 *      unsigned int lutSize;
 * [Requires SD_LOCK_LUT]
 * The number of entries in the color lookup table.  The data beyond the
 * end of the map will be undefined.
 *
 *      jint *lutBase;
 * [Requires SD_LOCK_LUT]
 * A pointer to the beginning of the color lookup table for the colormap.
 * The color lookup table is formatted as an array of jint values each
 * representing the 32-bit ARGB color for the pixel representing by the
 * corresponding index.  The table is guaranteed to contain at least 256
 * valid memory locations even if the size of the map is smaller than 256.
 *
 *      unsigned char *invColorTable;
 * [Requires SD_LOCK_INVCOLOR]
 * A pointer to the beginning of the inverse color lookup table for the
 * colormap.  The inverse color lookup table is formatted as a 32x32x32
 * array of bytes indexed by RxGxB where each component is reduced to 5
 * bits of precision before indexing.
 *
 *      signed char *redErrTable;
 *      signed char *grnErrTable;
 *      signed char *bluErrTable;
 * [Requires SD_LOCK_INVCOLOR]
 * Pointers to the beginning of the ordered dither color error tables
 * for the colormap.  The error tables are formatted as an 8x8 array
 * of bytes indexed by coordinates using the formula [y & 7][x & 7].
 *
 *      int *invGrayTable;
 * [Requires SD_LOCK_INVGRAY]
 * A pointer to the beginning of the inverse gray lookup table for the
 * colormap.  The inverse color lookup table is formatted as an array
 * of 256 integers indexed by a byte gray level and storing an index
 * into the colormap of the closest matching gray pixel.
 *
 *      union priv {};
 * A buffer of private data for the SurfaceData implementation.
 * This field is a union of a data block of the desired default
 * size (SD_RASINFO_PRIVATE_SIZE) and a (void *) pointer that
 * ensures proper "strictest" alignment on all platforms.
 */
typedef struct {
    SurfaceDataBounds   bounds;                 /* bounds of raster array */
    void                *rasBase;               /* Pointer to (0, 0) pixel */
    jint                pixelBitOffset;         /* bit offset to (0, *) pixel */
    jint                pixelStride;            /* bytes to next X pixel */
    jint                scanStride;             /* bytes to next Y pixel */
    unsigned int        lutSize;                /* # colors in colormap */
    jint                *lutBase;               /* Pointer to colormap[0] */
    unsigned char       *invColorTable;         /* Inverse color table */
    signed char         *redErrTable;           /* Red ordered dither table */
    signed char         *grnErrTable;           /* Green ordered dither table */
    signed char         *bluErrTable;           /* Blue ordered dither table */
    int                 *invGrayTable;          /* Inverse gray table */
    int                 representsPrimaries;    /* whether cmap represents primary colors */
    union {
        void            *align;                 /* ensures strict alignment */
        char            data[SD_RASINFO_PRIVATE_SIZE];
    } priv;
} SurfaceDataRasInfo;

typedef struct _SurfaceDataOps SurfaceDataOps;

/*
 * This function is used to lock a particular region of a particular
 * destination.  Once this method is called, no changes of any of the
 * data returned by any of the other SurfaceData vectored functions
 * may change until a corresponding call to Release is made.
 *
 * The env parameter should be the JNIEnv of the surrounding JNI context.
 *
 * The ops parameter should be a pointer to the ops object upon which
 * this function is being invoked.
 *
 * The rasInfo parameter should be a pointer to a SurfaceDataRasInfo
 * structure in which the bounds have been initialized to the maximum
 * bounds of the raster data that will need to be accessed later.
 *
 * The lockflags parameter should indicate which information will be
 * needed by the caller.  The various flags which may be OR'd together
 * may consist of any of the following:
 *      SD_LOCK_READ            The caller needs to read pixels from the dest
 *      SD_LOCK_WRITE           The caller needs to write pixels to the dest
 *      SD_LOCK_RD_WR           A combination of (SD_LOCK_READ | SD_LOCK_WRITE)
 *      SD_LOCK_LUT             The caller needs the colormap (Lut)
 *      SD_LOCK_INVCOLOR        The caller needs the inverse color table
 *      SD_LOCK_INVGRAY         The caller needs the inverse gray table
 *      SD_LOCK_FASTEST         The caller only wants direct pixel access
 * Note that the SD_LOCK_LUT, SD_LOCK_INVCOLOR, and SD_LOCK_INVGRAY flags
 * are only valid for destinations with IndexColorModels.
 * Also note that SD_LOCK_FASTEST will only succeed if the access to the
 * pixels will occur just as fast regardless of the size of the bounds.
 * This flag is used by the Text rendering routines to determine if it
 * matters whether or not they have calculated a tight bounding box for
 * the pixels they will be touching.
 *
 * Return value:
 *
 * If this function succeeds, it will return SD_SUCCESS (0).
 *
 * If this function is unable to honor the SD_LOCK_FASTEST flag,
 * it will return SD_SLOWLOCK.  The bounds parameter of the
 * SurfaceDataRasInfo object should be intersected with a tighter
 * bounding rectangle before calling the GetRasInfo function so
 * as to minimize the amount pixel copying or conversion.  Note
 * that the Lock function may have already intersected the
 * bounds with a tighter rectangle as it tried to honor the
 * SD_SLOWLOCK flag and so the caller should only use intersection
 * operations to further restrict the bounds.
 *
 * If this function fails for any reason that is not recoverable,
 * it will throw an appropriate Java exception and return SD_FAILED.
 *
 * Operation:
 *
 * This function will intersect the bounds specified in the rasInfo
 * parameter with the available raster data in the destination drawable
 * and modify the contents of the bounds field to represent the maximum
 * available raster data.
 *
 * If the available raster data in the destination drawable consists of
 * a non-rectangular region of pixels, this method may throw an InvalidPipe
 * exception (optionally the object may decide to provide a copy of the
 * destination pixel data with undefined data in the inaccessible portions).
 *
 * Further processing by the caller may discover that a smaller region of
 * data is actually needed and the call to GetRasData can be made with a
 * still smaller bounds.
 *
 * Note to callers:
 *      This function may use JNI methods so it is important that the
 *      caller not have any outstanding GetPrimitiveArrayCritical or
 *      GetStringCritical locks which have not been released.
 *
 * Note to implementers:
 *      The caller may also continue to use JNI methods after this method
 *      is called so it is important that implementations of SurfaceData
 *      not return from this function with any outstanding JNI Critical
 *      locks that have not been released.
 */
typedef jint LockFunc(JNIEnv *env,
                      SurfaceDataOps *ops,
                      SurfaceDataRasInfo *rasInfo,
                      jint lockflags);

/*
 * This function returns information about the raster data for the drawable.
 * The function will fill in or modify the contents of the SurfaceDataRasInfo
 * structure that is passed in with various pieces of information depending
 * on what was requested in the lockflags parameter that was handed into
 * the LockFunc.  For more information on which pieces of information are
 * returned based upon the lock flags see the documentation for the
 * RasInfo structure above.
 *
 * The env parameter should be the JNIEnv of the surrounding JNI context.
 *
 * The ops parameter should be a pointer to the ops object upon which
 * this function is being invoked.
 *
 * The pRasInfo parameter should be a pointer to the same structure of type
 * SurfaceDataRasInfo.  The bounds member of that structure should be
 * initialized to the bounding box of the raster data that is actually
 * needed for reading or writing before calling this function.  These
 * bounds must be a subset of the raster bounds that were given to the
 * LockFunc or the results will be undefined.
 *
 * If the surface was locked with the flag SD_LOCK_FASTEST then this
 * function may reevaluate the bounds in the RasInfo structure and
 * return a subset of what was requested.  Callers that use that flag
 * should be prepared to reevaluate their clipping after GetRasInfo
 * returns.  If the SD_LOCK_FASTEST flag was not specified, then this
 * function will return a buffer containing all of the pixels in the
 * requested bounds without reevaluating them.
 *
 * Any information that was requested in the lockflags of the LockFunc
 * will be returned and NULL pointers will be returned for all other
 * information.
 *
 * Note to callers:
 *      This function may use JNI Critical methods so it is important
 *      that the caller not call any other JNI methods after this function
 *      returns until the Release function is called.
 */
typedef void GetRasInfoFunc(JNIEnv *env,
                            SurfaceDataOps *ops,
                            SurfaceDataRasInfo *pRasInfo);

/*
 * This function releases all of the Critical data for the specified
 * drawable.
 *
 * This function vector is allowed to be NULL if a given SurfaceData
 * implementation does not require the use of JNI Critical array locks.
 * Callers should use the "SurfaceData_InvokeRelease(env, ops)" macro
 * to handle the conditional invocation of this function.
 *
 * In particular, this function will release any outstanding JNI Critical
 * locks that the SurfaceData implementation may have used so that it
 * will be safe for the caller to start using arbitrary JNI calls or
 * return from its calling JNI function.
 *
 * The env parameter should be the JNIEnv of the surrounding JNI context.
 *
 * The ops parameter should be a pointer to the ops object upon which
 * this function is being invoked.
 *
 * The pRasInfo parameter should be a pointer to the same structure of
 * type SurfaceDataRasInfo that was passed to the GetRasInfo function.
 * The bounds should be unchanged since that call.
 *
 * Note to callers:
 *      This function will release any outstanding JNI Critical locks so
 *      it will once again be safe to use arbitrary JNI calls or return
 *      to the enclosing JNI native context.
 *
 * Note to implementers:
 *      This function may not use any JNI methods other than to release
 *      outstanding JNI Critical array locks since there may be other
 *      nested SurfacData objects holding locks with their own outstanding
 *      JNI Critical locks.  This restriction includes the use of the
 *      JNI monitor calls so that all MonitorExit invocations must be
 *      done in the Unlock function.
 */
typedef void ReleaseFunc(JNIEnv *env,
                         SurfaceDataOps *ops,
                         SurfaceDataRasInfo *pRasInfo);

/*
 * This function unlocks the specified drawable.
 *
 * This function vector is allowed to be NULL if a given SurfaceData
 * implementation does not require any unlocking of the destination.
 * Callers should use the "SurfaceData_InvokeUnlock(env, ops)" macro
 * to handle the conditional invocation of this function.
 *
 * The env parameter should be the JNIEnv of the surrounding JNI context.
 *
 * The ops parameter should be a pointer to the ops object upon which
 * this function is being invoked.
 *
 * The pRasInfo parameter should be a pointer to the same structure of
 * type SurfaceDataRasInfo that was passed to the GetRasInfo function.
 * The bounds should be unchanged since that call.
 *
 * Note to callers:
 *      This function may use JNI methods so it is important that the
 *      caller not have any outstanding GetPrimitiveArrayCritical or
 *      GetStringCritical locks which have not been released.
 *
 * Note to implementers:
 *      This function may be used to release any JNI monitors used to
 *      prevent the destination from being modified.  It may also be
 *      used to perform operations which may require blocking (such as
 *      executing X11 operations which may need to flush data).
 */
typedef void UnlockFunc(JNIEnv *env,
                        SurfaceDataOps *ops,
                        SurfaceDataRasInfo *pRasInfo);

/*
 * This function sets up the specified drawable.  Some surfaces may
 * need to perform certain operations during Setup that cannot be
 * done after later operations such as Lock.  For example, on
 * win9x systems, when any surface is locked we cannot make a call to
 * the message-handling thread.
 *
 * This function vector is allowed to be NULL if a given SurfaceData
 * implementation does not require any setup.
 *
 * The env parameter should be the JNIEnv of the surrounding JNI context.
 *
 * The ops parameter should be a pointer to the ops object upon which
 * this function is being invoked.
 *
 * Note to callers:
 *      This function may use JNI methods so it is important that the
 *      caller not have any outstanding GetPrimitiveArrayCritical or
 *      GetStringCritical locks which have not been released.
 */
typedef void SetupFunc(JNIEnv *env,
                       SurfaceDataOps *ops);

/*
 * This function disposes the specified SurfaceDataOps structure
 * and associated native resources.
 * The implementation is SurfaceData-type specific.
 */
typedef void DisposeFunc(JNIEnv *env,
                         SurfaceDataOps *ops);

/*
 * Constants used for return values.  Constants less than 0 are
 * unrecoverable failures and indicate that a Java exception has
 * already been thrown.  Constants greater than 0 are conditional
 * successes which warn the caller that various optional features
 * were not available so that workarounds can be used.
 */
#define SD_FAILURE              -1
#define SD_SUCCESS              0
#define SD_SLOWLOCK             1

/*
 * Constants for the flags used in the Lock function.
 */
#define SD_LOCK_READ            (1 << 0)
#define SD_LOCK_WRITE           (1 << 1)
#define SD_LOCK_RD_WR           (SD_LOCK_READ | SD_LOCK_WRITE)
#define SD_LOCK_LUT             (1 << 2)
#define SD_LOCK_INVCOLOR        (1 << 3)
#define SD_LOCK_INVGRAY         (1 << 4)
#define SD_LOCK_FASTEST         (1 << 5)
#define SD_LOCK_PARTIAL         (1 << 6)
#define SD_LOCK_PARTIAL_WRITE   (SD_LOCK_WRITE | SD_LOCK_PARTIAL)
#define SD_LOCK_NEED_PIXELS     (SD_LOCK_READ | SD_LOCK_PARTIAL)

/*
 * This structure provides the function vectors for manipulating
 * and retrieving information about the destination drawable.
 * There are also variables for the surface data object used by
 * native code to track the state of the surface.
 * The sdObject is a pointer to the Java SurfaceData object;
 * this is set in SurfaceData_InitOps() and used by any object
 * using the ops structure to refer to elements in the Java object
 * (such as fields that we need to set from native code).
 */
struct _SurfaceDataOps {
    LockFunc            *Lock;
    GetRasInfoFunc      *GetRasInfo;
    ReleaseFunc         *Release;
    UnlockFunc          *Unlock;
    SetupFunc           *Setup;
    DisposeFunc         *Dispose;
    jobject             sdObject;
};

#define _ClrReduce(c)   (((unsigned char) c) >> 3)

/*
 * This macro performs a lookup in an inverse color table given 3 8-bit
 * RGB primaries.  It automates the process of reducing the primaries
 * to 5-bits of precision and using them to index into the specified
 * inverse color lookup table.
 */
#define SurfaceData_InvColorMap(invcolortbl, r, g, b) \
    (invcolortbl)[(_ClrReduce(r)<<10) + (_ClrReduce(g)<<5) + _ClrReduce(b)]

/*
 * This macro invokes the SurfaceData Release function only if the
 * function vector is not NULL.
 */
#define SurfaceData_InvokeRelease(env, ops, pRI)        \
    do {                                                \
        if ((ops)->Release != NULL) {                   \
            (ops)->Release(env, ops, pRI);              \
        }                                               \
    } while(0)

/*
 * This macro invokes the SurfaceData Unlock function only if the
 * function vector is not NULL.
 */
#define SurfaceData_InvokeUnlock(env, ops, pRI)         \
    do {                                                \
        if ((ops)->Unlock != NULL) {                    \
            (ops)->Unlock(env, ops, pRI);               \
        }                                               \
    } while(0)

/*
 * This macro invokes both the SurfaceData Release and Unlock functions
 * only if the function vectors are not NULL.  It can be used in cases
 * where only one surface has been accessed and where no other JNI
 * Critical locks (which would need to be released after Release and
 * before Unlock) are held by the calling function.
 */
#define SurfaceData_InvokeReleaseUnlock(env, ops, pRI)  \
    do {                                                \
        if ((ops)->Release != NULL) {                   \
            (ops)->Release(env, ops, pRI);              \
        }                                               \
        if ((ops)->Unlock != NULL) {                    \
            (ops)->Unlock(env, ops, pRI);               \
        }                                               \
    } while(0)

/*
 * This macro invokes both the SurfaceData Release and Unlock functions
 * on two nested drawables only if the function vectors are not NULL.
 * It can be used in cases where two surfaces have been accessed and
 * where no other JNI Critical locks (which would need to be released
 * after Release and before Unlock) are held by the calling function.  The
 * two ops vectors should be specified in the same order that they were
 * locked.  Both surfaces will be released and then both unlocked.
 */
#define SurfaceData_InvokeReleaseUnlock2(env, ops1, pRI1, ops2, pRI2)   \
    do {                                                        \
        if ((ops2)->Release != NULL) {                          \
            (ops2)->Release(env, ops2, pRI2);                   \
        }                                                       \
        if ((ops1)->Release != NULL) {                          \
            (ops1)->Release(env, ops1, pRI1);                   \
        }                                                       \
        if ((ops2)->Unlock != NULL) {                           \
            (ops2)->Unlock(env, ops2, pRI2);                    \
        }                                                       \
        if ((ops1)->Unlock != NULL) {                           \
            (ops1)->Unlock(env, ops1, pRI1);                    \
        }                                                       \
    } while(0)

#define SurfaceData_InvokeDispose(env, ops)                     \
    do {                                                        \
        if ((ops)->Dispose != NULL) {                           \
            (ops)->Dispose(env, ops);                           \
        }                                                       \
    } while(0)

#define SurfaceData_InvokeSetup(env, ops)                       \
    do {                                                        \
        if ((ops)->Setup != NULL) {                             \
            (ops)->Setup(env, ops);                             \
        }                                                       \
    } while(0)

/*
 * This function returns a pointer to a native SurfaceDataOps
 * structure for accessing the indicated SurfaceData Java object.
 *
 * Note to callers:
 *      This function uses JNI methods so it is important that the
 *      caller not have any outstanding GetPrimitiveArrayCritical or
 *      GetStringCritical locks which have not been released.
 *
 *      The caller may continue to use JNI methods after this method
 *      is called since this function will not leave any outstanding
 *      JNI Critical locks unreleased.
 */
JNIEXPORT SurfaceDataOps * JNICALL
SurfaceData_GetOps(JNIEnv *env, jobject sData);

/*
 * Does the same as the above, but doesn't call Setup function
 * even if it's set.
 */
SurfaceDataOps *
SurfaceData_GetOpsNoSetup(JNIEnv *env, jobject sData);

/*
 * This function stores a pointer to a native SurfaceDataOps
 * structure into the indicated Java SurfaceData object.
 *
 * Note to callers:
 *      This function uses JNI methods so it is important that the
 *      caller not have any outstanding GetPrimitiveArrayCritical or
 *      GetStringCritical locks which have not been released.
 *
 *      The caller may continue to use JNI methods after this method
 *      is called since this function will not leave any outstanding
 *      JNI Critical locks unreleased.
 */
void
SurfaceData_SetOps(JNIEnv *env, jobject sData, SurfaceDataOps *ops);

/*
 * This function throws an InvalidPipeException which will cause the
 * calling SunGraphics2D object to revalidate its pipelines and call
 * again.  This utility method should be called from the SurfaceData
 * native Lock routine when some attribute of the surface has changed
 * that requires pipeline revalidation, including:
 *
 *      The bit depth or pixel format of the surface.
 *      The surface (window) has been disposed.
 *      The device clip of the surface has been changed (resize, visibility, etc.)
 *
 * Note to callers:
 *      This function uses JNI methods so it is important that the
 *      caller not have any outstanding GetPrimitiveArrayCritical or
 *      GetStringCritical locks which have not been released.
 *
 *      The caller may continue to use JNI methods after this method
 *      is called since this function will not leave any outstanding
 *      JNI Critical locks unreleased.
 */
JNIEXPORT void JNICALL
SurfaceData_ThrowInvalidPipeException(JNIEnv *env, const char *msg);

/*
 * This function intersects two bounds objects which exist in the same
 * coordinate space.  The contents of the first parameter (dst) are
 * modified to contain the intersection of the two bounds while the
 * contents of the second parameter (src) are untouched.
 */
JNIEXPORT void JNICALL
SurfaceData_IntersectBounds(SurfaceDataBounds *dst, SurfaceDataBounds *src);

/*
 * This function intersects a bounds object with a rectangle specified
 * in lox, loy, hix, hiy format in the same coordinate space.  The
 * contents of the first parameter (bounds) are modified to contain
 * the intersection of the two rectangular regions.
 */
JNIEXPORT void JNICALL
SurfaceData_IntersectBoundsXYXY(SurfaceDataBounds *bounds,
                                jint lox, jint loy, jint hix, jint hiy);

/*
 * This function intersects a bounds object with a rectangle specified
 * in XYWH format in the same coordinate space.  The contents of the
 * first parameter (bounds) are modified to contain the intersection
 * of the two rectangular regions.
 */
JNIEXPORT void JNICALL
SurfaceData_IntersectBoundsXYWH(SurfaceDataBounds *bounds,
                                jint x, jint y, jint w, jint h);

/*
 * This function intersects two bounds objects which exist in different
 * coordinate spaces.  The coordinate spaces of the two objects are
 * related such that a given coordinate in the space of the A bounds
 * is related to the analogous coordinate in the space of the B bounds
 * by the formula: (AX + BXminusAX, AY + BYminusAY) == (BX, BY).
 * The contents of both bounds objects are modified to represent their
 * mutual intersection.
 */
JNIEXPORT void JNICALL
SurfaceData_IntersectBlitBounds(SurfaceDataBounds *Abounds,
                                SurfaceDataBounds *Bbounds,
                                jint BXminusAX, jint BYminusAY);


/*
 * This function creates and initializes the ops structure.  The function
 * is called by "subclasses" of SurfaceData (e.g., BufImgSurfaceData)
 * which pass in the size of the structure to allocate (subclasses generally
 * need additional fields in the ops structure particular to their usage
 * of the structure).  The structure is allocated and initialized
 * and is stored in the SurfaceData java object for later retrieval.
 * Subclasses of SurfaceData should call this function instead of allocating
 * the memory directly.
 */
JNIEXPORT SurfaceDataOps * JNICALL
SurfaceData_InitOps(JNIEnv *env, jobject sData, int opsSize);

/*
 * This function invokes the ops-specific disposal function.
 * It is a part of the finalizers-free disposal mechanism.
 * (see Disposer and DefaultDisposerRecord classes for more information)
 * It also destroys the ops structure created in SurfaceData_InitOps.
 */
void SurfaceData_DisposeOps(JNIEnv *env, jlong ops);

#ifdef __cplusplus
}
#endif

#endif
