/**
 ** Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

#include "jni.h"
#include "JNIHelp.h"
#include "GraphicsJNI.h"

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <dlfcn.h>

#include <GLES/gl.h>
#include <ETC1/etc1.h>

#include <SkBitmap.h>

#include "core_jni_helpers.h"

#undef LOG_TAG
#define LOG_TAG "OpenGLUtil"
#include <utils/Log.h>
#include "utils/misc.h"

#include "poly.h"

namespace android {

static inline
void mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) {
    pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w;
    pDest[1] = pM[1 + 4 * 0] * x + pM[1 + 4 * 1] * y + pM[1 + 4 * 2] * z + pM[1 + 4 * 3] * w;
    pDest[2] = pM[2 + 4 * 0] * x + pM[2 + 4 * 1] * y + pM[2 + 4 * 2] * z + pM[2 + 4 * 3] * w;
    pDest[3] = pM[3 + 4 * 0] * x + pM[3 + 4 * 1] * y + pM[3 + 4 * 2] * z + pM[3 + 4 * 3] * w;
}

class MallocHelper {
public:
    MallocHelper() {
        mData = 0;
    }

    ~MallocHelper() {
        if (mData != 0) {
            free(mData);
        }
    }

    void* alloc(size_t size) {
        mData = malloc(size);
        return mData;
    }

private:
    void* mData;
};

#if 0
static
void
print_poly(const char* label, Poly* pPoly) {
    ALOGI("%s: %d verts", label, pPoly->n);
    for(int i = 0; i < pPoly->n; i++) {
        Poly_vert* pV = & pPoly->vert[i];
        ALOGI("[%d] %g, %g, %g %g", i, pV->sx, pV->sy, pV->sz, pV->sw);
    }
}
#endif

static
int visibilityTest(float* pWS, float* pPositions, int positionsLength,
        unsigned short* pIndices, int indexCount) {
    MallocHelper mallocHelper;
    int result = POLY_CLIP_OUT;
    float* pTransformed = 0;
    int transformedIndexCount = 0;

    if ( indexCount < 3 ) {
        return POLY_CLIP_OUT;
    }

    // Find out how many vertices we need to transform
    // We transform every vertex between the min and max indices, inclusive.
    // This is OK for the data sets we expect to use with this function, but
    // for other loads it might be better to use a more sophisticated vertex
    // cache of some sort.

    int minIndex = 65536;
    int maxIndex = -1;
    for(int i = 0; i < indexCount; i++) {
        int index = pIndices[i];
        if ( index < minIndex ) {
            minIndex = index;
        }
        if ( index > maxIndex ) {
            maxIndex = index;
        }
    }

    if ( maxIndex * 3 > positionsLength) {
        return -1;
    }

    transformedIndexCount = maxIndex - minIndex + 1;
    pTransformed = (float*) mallocHelper.alloc(transformedIndexCount * 4 * sizeof(float));

    if (pTransformed == 0 ) {
        return -2;
    }

    // Transform the vertices
    {
        const float* pSrc = pPositions + 3 * minIndex;
        float* pDst = pTransformed;
        for (int i = 0; i < transformedIndexCount; i++, pSrc += 3, pDst += 4) {
            mx4transform(pSrc[0], pSrc[1], pSrc[2], 1.0f, pWS,  pDst);
        }
    }

    // Clip the triangles

    Poly poly;
    float* pDest = & poly.vert[0].sx;
    for (int i = 0; i < indexCount; i += 3) {
        poly.n = 3;
        memcpy(pDest    , pTransformed + 4 * (pIndices[i    ] - minIndex), 4 * sizeof(float));
        memcpy(pDest + 4, pTransformed + 4 * (pIndices[i + 1] - minIndex), 4 * sizeof(float));
        memcpy(pDest + 8, pTransformed + 4 * (pIndices[i + 2] - minIndex), 4 * sizeof(float));
        result = poly_clip_to_frustum(&poly);
        if ( result != POLY_CLIP_OUT) {
            return result;
        }
    }

    return result;
}

template<class JArray, class T>
class ArrayHelper {
public:
    ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) {
        mEnv = env;
        mRef = ref;
        mOffset = offset;
        mMinSize = minSize;
        mBase = 0;
        mReleaseParam = JNI_ABORT;
    }

    ~ArrayHelper() {
        if (mBase) {
            mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam);
        }
    }

    // We seperate the bounds check from the initialization because we want to
    // be able to bounds-check multiple arrays, and we can't throw an exception
    // after we've called GetPrimitiveArrayCritical.

    // Return true if the bounds check succeeded
    // Else instruct the runtime to throw an exception

    bool check() {
        if ( ! mRef) {
            doThrowIAE(mEnv, "array == null");
            return false;
        }
        if ( mOffset < 0) {
            doThrowIAE(mEnv, "offset < 0");
            return false;
        }
        mLength = mEnv->GetArrayLength(mRef) - mOffset;
        if (mLength < mMinSize ) {
            doThrowIAE(mEnv, "length - offset < n");
            return false;
        }
        return true;
    }

    // Bind the array.

    void bind() {
        mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0);
        mData = mBase + mOffset;
    }

    void commitChanges() {
        mReleaseParam = 0;
    }

    T* mData;
    int mLength;

private:
    T* mBase;
    JNIEnv* mEnv;
    JArray mRef;
    jint mOffset;
    jint mMinSize;
    int mReleaseParam;
};

typedef ArrayHelper<jfloatArray, float> FloatArrayHelper;
typedef ArrayHelper<jcharArray, unsigned short> UnsignedShortArrayHelper;
typedef ArrayHelper<jintArray, int> IntArrayHelper;
typedef ArrayHelper<jbyteArray, unsigned char> ByteArrayHelper;

inline float distance2(float x, float y, float z) {
    return x * x + y * y + z * z;
}

inline float distance(float x, float y, float z) {
    return sqrtf(distance2(x, y, z));
}

static
void util_computeBoundingSphere(JNIEnv *env, jclass clazz,
        jfloatArray positions_ref, jint positionsOffset, jint positionsCount,
        jfloatArray sphere_ref, jint sphereOffset) {
    FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
    FloatArrayHelper sphere(env, sphere_ref, sphereOffset, 4);

    bool checkOK = positions.check() && sphere.check();
        if (! checkOK) {
        return;
    }

    positions.bind();
    sphere.bind();

    if ( positionsCount < 1 ) {
        doThrowIAE(env, "positionsCount < 1");
        return;
    }

    const float* pSrc = positions.mData;

    // find bounding box
    float x0 = *pSrc++;
    float x1 = x0;
    float y0 = *pSrc++;
    float y1 = y0;
    float z0 = *pSrc++;
    float z1 = z0;

    for(int i = 1; i < positionsCount; i++) {
        {
            float x = *pSrc++;
            if (x < x0) {
                x0 = x;
            }
            else if (x > x1) {
                x1 = x;
            }
        }
        {
            float y = *pSrc++;
            if (y < y0) {
                y0 = y;
            }
            else if (y > y1) {
                y1 = y;
            }
        }
        {
            float z = *pSrc++;
            if (z < z0) {
                z0 = z;
            }
            else if (z > z1) {
                z1 = z;
            }
        }
    }

    // Because we know our input meshes fit pretty well into bounding boxes,
    // just take the diagonal of the box as defining our sphere.
    float* pSphere = sphere.mData;
    float dx = x1 - x0;
    float dy = y1 - y0;
    float dz = z1 - z0;
    *pSphere++ = x0 + dx * 0.5f;
    *pSphere++ = y0 + dy * 0.5f;
    *pSphere++ = z0 + dz * 0.5f;
    *pSphere++ = distance(dx, dy, dz) * 0.5f;

    sphere.commitChanges();
}

static void normalizePlane(float* p) {
    float rdist = 1.0f / distance(p[0], p[1], p[2]);
    for(int i = 0; i < 4; i++) {
        p[i] *= rdist;
    }
}

static inline float dot3(float x0, float y0, float z0, float x1, float y1, float z1) {
    return x0 * x1 + y0 * y1 + z0 * z1;
}

static inline float signedDistance(const float* pPlane, float x, float y, float z) {
    return dot3(pPlane[0], pPlane[1], pPlane[2], x, y, z) + pPlane[3];
}

// Return true if the sphere intersects or is inside the frustum

static bool sphereHitsFrustum(const float* pFrustum, const float* pSphere) {
    float x = pSphere[0];
    float y = pSphere[1];
    float z = pSphere[2];
    float negRadius = -pSphere[3];
    for (int i = 0; i < 6; i++, pFrustum += 4) {
        if (signedDistance(pFrustum, x, y, z) <= negRadius) {
            return false;
        }
    }
    return true;
}

static void computeFrustum(const float* m, float* f) {
    float m3 = m[3];
    float m7 = m[7];
    float m11 = m[11];
    float m15 = m[15];
    // right
    f[0] = m3  - m[0];
    f[1] = m7  - m[4];
    f[2] = m11 - m[8];
    f[3] = m15 - m[12];
    normalizePlane(f);
    f+= 4;

    // left
    f[0] = m3  + m[0];
    f[1] = m7  + m[4];
    f[2] = m11 + m[8];
    f[3] = m15 + m[12];
    normalizePlane(f);
    f+= 4;

    // top
    f[0] = m3  - m[1];
    f[1] = m7  - m[5];
    f[2] = m11 - m[9];
    f[3] = m15 - m[13];
    normalizePlane(f);
    f+= 4;

    // bottom
    f[0] = m3  + m[1];
    f[1] = m7  + m[5];
    f[2] = m11 + m[9];
    f[3] = m15 + m[13];
    normalizePlane(f);
    f+= 4;

    // far
    f[0] = m3  - m[2];
    f[1] = m7  - m[6];
    f[2] = m11 - m[10];
    f[3] = m15 - m[14];
    normalizePlane(f);
    f+= 4;

    // near
    f[0] = m3  + m[2];
    f[1] = m7  + m[6];
    f[2] = m11 + m[10];
    f[3] = m15 + m[14];
    normalizePlane(f);
}

static
jint util_frustumCullSpheres(JNIEnv *env, jclass clazz,
        jfloatArray mvp_ref, jint mvpOffset,
        jfloatArray spheres_ref, jint spheresOffset, jint spheresCount,
        jintArray results_ref, jint resultsOffset, jint resultsCapacity) {
    float frustum[6*4];
    int outputCount;
    int* pResults;
    float* pSphere;
    FloatArrayHelper mvp(env, mvp_ref, mvpOffset, 16);
    FloatArrayHelper spheres(env, spheres_ref, spheresOffset, spheresCount * 4);
    IntArrayHelper results(env, results_ref, resultsOffset, resultsCapacity);

    bool initializedOK = mvp.check() && spheres.check() && results.check();
        if (! initializedOK) {
        return -1;
    }

    mvp.bind();
    spheres.bind();
    results.bind();

    computeFrustum(mvp.mData, frustum);

    // Cull the spheres

    pSphere = spheres.mData;
    pResults = results.mData;
    outputCount = 0;
    for(int i = 0; i < spheresCount; i++, pSphere += 4) {
        if (sphereHitsFrustum(frustum, pSphere)) {
            if (outputCount < resultsCapacity) {
                *pResults++ = i;
            }
            outputCount++;
        }
    }
    results.commitChanges();
    return outputCount;
}

/*
 public native int visibilityTest(float[] ws, int wsOffset,
 float[] positions, int positionsOffset,
 char[] indices, int indicesOffset, int indexCount);
 */

static
jint util_visibilityTest(JNIEnv *env, jclass clazz,
        jfloatArray ws_ref, jint wsOffset,
        jfloatArray positions_ref, jint positionsOffset,
        jcharArray indices_ref, jint indicesOffset, jint indexCount) {

    FloatArrayHelper ws(env, ws_ref, wsOffset, 16);
    FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
    UnsignedShortArrayHelper indices(env, indices_ref, indicesOffset, 0);

    bool checkOK = ws.check() && positions.check() && indices.check();
    if (! checkOK) {
        // Return value will be ignored, because an exception has been thrown.
        return -1;
    }

    if (indices.mLength < indexCount) {
        doThrowIAE(env, "length < offset + indexCount");
        return -1;
    }

    ws.bind();
    positions.bind();
    indices.bind();

    return visibilityTest(ws.mData,
            positions.mData, positions.mLength,
            indices.mData, indexCount);
}

#define I(_i, _j) ((_j)+ 4*(_i))

static
void multiplyMM(float* r, const float* lhs, const float* rhs)
{
    for (int i=0 ; i<4 ; i++) {
        const float rhs_i0 = rhs[ I(i,0) ];
        float ri0 = lhs[ I(0,0) ] * rhs_i0;
        float ri1 = lhs[ I(0,1) ] * rhs_i0;
        float ri2 = lhs[ I(0,2) ] * rhs_i0;
        float ri3 = lhs[ I(0,3) ] * rhs_i0;
        for (int j=1 ; j<4 ; j++) {
            const float rhs_ij = rhs[ I(i,j) ];
            ri0 += lhs[ I(j,0) ] * rhs_ij;
            ri1 += lhs[ I(j,1) ] * rhs_ij;
            ri2 += lhs[ I(j,2) ] * rhs_ij;
            ri3 += lhs[ I(j,3) ] * rhs_ij;
        }
        r[ I(i,0) ] = ri0;
        r[ I(i,1) ] = ri1;
        r[ I(i,2) ] = ri2;
        r[ I(i,3) ] = ri3;
    }
}

static
void util_multiplyMM(JNIEnv *env, jclass clazz,
    jfloatArray result_ref, jint resultOffset,
    jfloatArray lhs_ref, jint lhsOffset,
    jfloatArray rhs_ref, jint rhsOffset) {

    FloatArrayHelper resultMat(env, result_ref, resultOffset, 16);
    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16);

    bool checkOK = resultMat.check() && lhs.check() && rhs.check();

    if ( !checkOK ) {
        return;
    }

    resultMat.bind();
    lhs.bind();
    rhs.bind();

    multiplyMM(resultMat.mData, lhs.mData, rhs.mData);

    resultMat.commitChanges();
}

static
void multiplyMV(float* r, const float* lhs, const float* rhs)
{
    mx4transform(rhs[0], rhs[1], rhs[2], rhs[3], lhs, r);
}

static
void util_multiplyMV(JNIEnv *env, jclass clazz,
    jfloatArray result_ref, jint resultOffset,
    jfloatArray lhs_ref, jint lhsOffset,
    jfloatArray rhs_ref, jint rhsOffset) {

    FloatArrayHelper resultV(env, result_ref, resultOffset, 4);
    FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
    FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4);

    bool checkOK = resultV.check() && lhs.check() && rhs.check();

    if ( !checkOK ) {
        return;
    }

    resultV.bind();
    lhs.bind();
    rhs.bind();

    multiplyMV(resultV.mData, lhs.mData, rhs.mData);

    resultV.commitChanges();
}

// ---------------------------------------------------------------------------

extern void setGLDebugLevel(int level);
void setTracingLevel(JNIEnv *env, jclass clazz, jint level)
{
    setGLDebugLevel(level);
}

static int checkFormat(SkColorType colorType, int format, int type)
{
    switch(colorType) {
        case kIndex_8_SkColorType:
            if (format == GL_PALETTE8_RGBA8_OES)
                return 0;
        case kN32_SkColorType:
        case kAlpha_8_SkColorType:
            if (type == GL_UNSIGNED_BYTE)
                return 0;
        case kARGB_4444_SkColorType:
        case kRGB_565_SkColorType:
            switch (type) {
                case GL_UNSIGNED_SHORT_4_4_4_4:
                case GL_UNSIGNED_SHORT_5_6_5:
                case GL_UNSIGNED_SHORT_5_5_5_1:
                    return 0;
                case GL_UNSIGNED_BYTE:
                    if (format == GL_LUMINANCE_ALPHA)
                        return 0;
            }
            break;
        default:
            break;
    }
    return -1;
}

static int getInternalFormat(SkColorType colorType)
{
    switch(colorType) {
        case kAlpha_8_SkColorType:
            return GL_ALPHA;
        case kARGB_4444_SkColorType:
            return GL_RGBA;
        case kN32_SkColorType:
            return GL_RGBA;
        case kIndex_8_SkColorType:
            return GL_PALETTE8_RGBA8_OES;
        case kRGB_565_SkColorType:
            return GL_RGB;
        default:
            return -1;
    }
}

static int getType(SkColorType colorType)
{
    switch(colorType) {
        case kAlpha_8_SkColorType:
            return GL_UNSIGNED_BYTE;
        case kARGB_4444_SkColorType:
            return GL_UNSIGNED_SHORT_4_4_4_4;
        case kN32_SkColorType:
            return GL_UNSIGNED_BYTE;
        case kIndex_8_SkColorType:
            return -1; // No type for compressed data.
        case kRGB_565_SkColorType:
            return GL_UNSIGNED_SHORT_5_6_5;
        default:
            return -1;
    }
}

static jint util_getInternalFormat(JNIEnv *env, jclass clazz,
        jobject jbitmap)
{
    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
    return getInternalFormat(nativeBitmap->colorType());
}

static jint util_getType(JNIEnv *env, jclass clazz,
        jobject jbitmap)
{
    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
    return getType(nativeBitmap->colorType());
}

static jint util_texImage2D(JNIEnv *env, jclass clazz,
        jint target, jint level, jint internalformat,
        jobject jbitmap, jint type, jint border)
{
    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
    const SkBitmap& bitmap(*nativeBitmap);
    SkColorType colorType = bitmap.colorType();
    if (internalformat < 0) {
        internalformat = getInternalFormat(colorType);
    }
    if (type < 0) {
        type = getType(colorType);
    }
    int err = checkFormat(colorType, internalformat, type);
    if (err)
        return err;
    bitmap.lockPixels();
    const int w = bitmap.width();
    const int h = bitmap.height();
    const void* p = bitmap.getPixels();
    if (internalformat == GL_PALETTE8_RGBA8_OES) {
        if (sizeof(SkPMColor) != sizeof(uint32_t)) {
            err = -1;
            goto error;
        }
        const size_t size = bitmap.getSize();
        const size_t palette_size = 256*sizeof(SkPMColor);
        const size_t imageSize = size + palette_size;
        void* const data = malloc(imageSize);
        if (data) {
            void* const pixels = (char*)data + palette_size;
            SkColorTable* ctable = bitmap.getColorTable();
            memcpy(data, ctable->readColors(), ctable->count() * sizeof(SkPMColor));
            memcpy(pixels, p, size);
            glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
            free(data);
        } else {
            err = -1;
        }
    } else {
        glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p);
    }
error:
    bitmap.unlockPixels();
    return err;
}

static jint util_texSubImage2D(JNIEnv *env, jclass clazz,
        jint target, jint level, jint xoffset, jint yoffset,
        jobject jbitmap, jint format, jint type)
{
    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
    const SkBitmap& bitmap(*nativeBitmap);
    SkColorType colorType = bitmap.colorType();
    if (format < 0) {
        format = getInternalFormat(colorType);
        if (format == GL_PALETTE8_RGBA8_OES)
            return -1; // glCompressedTexSubImage2D() not supported
    }
    int err = checkFormat(colorType, format, type);
    if (err)
        return err;
    bitmap.lockPixels();
    const int w = bitmap.width();
    const int h = bitmap.height();
    const void* p = bitmap.getPixels();
    glTexSubImage2D(target, level, xoffset, yoffset, w, h, format, type, p);
    bitmap.unlockPixels();
    return 0;
}

/*
 * ETC1 methods.
 */

static jclass nioAccessClass;
static jclass bufferClass;
static jmethodID getBasePointerID;
static jmethodID getBaseArrayID;
static jmethodID getBaseArrayOffsetID;
static jfieldID positionID;
static jfieldID limitID;
static jfieldID elementSizeShiftID;

/* Cache method IDs each time the class is loaded. */

static void
nativeClassInitBuffer(JNIEnv *env)
{
    jclass nioAccessClassLocal = FindClassOrDie(env, "java/nio/NIOAccess");
    nioAccessClass = MakeGlobalRefOrDie(env, nioAccessClassLocal);
    getBasePointerID = GetStaticMethodIDOrDie(env, nioAccessClass,
            "getBasePointer", "(Ljava/nio/Buffer;)J");
    getBaseArrayID = GetStaticMethodIDOrDie(env, nioAccessClass,
            "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
    getBaseArrayOffsetID = GetStaticMethodIDOrDie(env, nioAccessClass,
            "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");

    jclass bufferClassLocal = FindClassOrDie(env, "java/nio/Buffer");
    bufferClass = MakeGlobalRefOrDie(env, bufferClassLocal);
    positionID = GetFieldIDOrDie(env, bufferClass, "position", "I");
    limitID = GetFieldIDOrDie(env, bufferClass, "limit", "I");
    elementSizeShiftID = GetFieldIDOrDie(env, bufferClass, "_elementSizeShift", "I");
}

static void *
getPointer(JNIEnv *_env, jobject buffer, jint *remaining)
{
    jint position;
    jint limit;
    jint elementSizeShift;
    jlong pointer;

    position = _env->GetIntField(buffer, positionID);
    limit = _env->GetIntField(buffer, limitID);
    elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
    *remaining = (limit - position) << elementSizeShift;
    pointer = _env->CallStaticLongMethod(nioAccessClass,
            getBasePointerID, buffer);
    if (pointer != 0L) {
        return reinterpret_cast<void *>(pointer);
    }
    return NULL;
}

class BufferHelper {
public:
    BufferHelper(JNIEnv *env, jobject buffer) {
        mEnv = env;
        mBuffer = buffer;
        mData = NULL;
        mRemaining = 0;
    }

    bool checkPointer(const char* errorMessage) {
        if (mBuffer) {
            mData = getPointer(mEnv, mBuffer, &mRemaining);
            if (mData == NULL) {
                doThrowIAE(mEnv, errorMessage);
            }
            return mData != NULL;
        } else {
            doThrowIAE(mEnv, errorMessage);
            return false;
        }
    }

    inline void* getData() {
        return mData;
    }

    inline jint remaining() {
        return mRemaining;
    }

private:
    JNIEnv* mEnv;
    jobject mBuffer;
    void* mData;
    jint mRemaining;
};

/**
 * Encode a block of pixels.
 *
 * @param in a pointer to a ETC1_DECODED_BLOCK_SIZE array of bytes that represent a
 * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
 * value of pixel (x, y).
 *
 * @param validPixelMask is a 16-bit mask where bit (1 << (x + y * 4)) indicates whether
 * the corresponding (x,y) pixel is valid. Invalid pixel color values are ignored when compressing.
 *
 * @param out an ETC1 compressed version of the data.
 *
 */
static void etc1_encodeBlock(JNIEnv *env, jclass clazz,
        jobject in, jint validPixelMask, jobject out) {
    if (validPixelMask < 0 || validPixelMask > 15) {
        doThrowIAE(env, "validPixelMask");
        return;
    }
    BufferHelper inB(env, in);
    BufferHelper outB(env, out);
    if (inB.checkPointer("in") && outB.checkPointer("out")) {
        if (inB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
            doThrowIAE(env, "in's remaining data < DECODED_BLOCK_SIZE");
        } else if (outB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
            doThrowIAE(env, "out's remaining data < ENCODED_BLOCK_SIZE");
        } else {
            etc1_encode_block((etc1_byte*) inB.getData(), validPixelMask,
                    (etc1_byte*) outB.getData());
        }
    }
}

/**
 * Decode a block of pixels.
 *
 * @param in an ETC1 compressed version of the data.
 *
 * @param out a pointer to a ETC_DECODED_BLOCK_SIZE array of bytes that represent a
 * 4 x 4 square of 3-byte pixels in form R, G, B. Byte (3 * (x + 4 * y) is the R
 * value of pixel (x, y).
 */
static void etc1_decodeBlock(JNIEnv *env, jclass clazz,
        jobject in, jobject out){
    BufferHelper inB(env, in);
    BufferHelper outB(env, out);
    if (inB.checkPointer("in") && outB.checkPointer("out")) {
        if (inB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
            doThrowIAE(env, "in's remaining data < ENCODED_BLOCK_SIZE");
        } else if (outB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
            doThrowIAE(env, "out's remaining data < DECODED_BLOCK_SIZE");
        } else {
            etc1_decode_block((etc1_byte*) inB.getData(),
                    (etc1_byte*) outB.getData());
        }
    }
}

/**
 * Return the size of the encoded image data (does not include size of PKM header).
 */
static jint etc1_getEncodedDataSize(JNIEnv *env, jclass clazz,
        jint width, jint height) {
    return etc1_get_encoded_data_size(width, height);
}

/**
 * Encode an entire image.
 * @param in pointer to the image data. Formatted such that
 *           pixel (x,y) is at pIn + pixelSize * x + stride * y + redOffset;
 * @param out pointer to encoded data. Must be large enough to store entire encoded image.
 */
static void etc1_encodeImage(JNIEnv *env, jclass clazz,
        jobject in, jint width, jint height,
        jint pixelSize, jint stride, jobject out) {
    if (pixelSize < 2 || pixelSize > 3) {
        doThrowIAE(env, "pixelSize must be 2 or 3");
        return;
    }
    BufferHelper inB(env, in);
    BufferHelper outB(env, out);
    if (inB.checkPointer("in") && outB.checkPointer("out")) {
        jint imageSize = stride * height;
        jint encodedImageSize = etc1_get_encoded_data_size(width, height);
        if (inB.remaining() < imageSize) {
            doThrowIAE(env, "in's remaining data < image size");
        } else if (outB.remaining() < encodedImageSize) {
            doThrowIAE(env, "out's remaining data < encoded image size");
        } else {
            etc1_encode_image((etc1_byte*) inB.getData(), width, height, pixelSize, stride,
                              (etc1_byte*) outB.getData());
        }
    }
}

/**
 * Decode an entire image.
 * @param in the encoded data.
 * @param out pointer to the image data. Will be written such that
 *            pixel (x,y) is at pIn + pixelSize * x + stride * y. Must be
 *            large enough to store entire image.
 */
static void etc1_decodeImage(JNIEnv *env, jclass clazz,
        jobject  in, jobject out,
        jint width, jint height,
        jint pixelSize, jint stride) {
    if (pixelSize < 2 || pixelSize > 3) {
        doThrowIAE(env, "pixelSize must be 2 or 3");
        return;
    }
    BufferHelper inB(env, in);
    BufferHelper outB(env, out);
    if (inB.checkPointer("in") && outB.checkPointer("out")) {
        jint imageSize = stride * height;
        jint encodedImageSize = etc1_get_encoded_data_size(width, height);
        if (inB.remaining() < encodedImageSize) {
            doThrowIAE(env, "in's remaining data < encoded image size");
        } else if (outB.remaining() < imageSize) {
            doThrowIAE(env, "out's remaining data < image size");
        } else {
            etc1_decode_image((etc1_byte*) inB.getData(), (etc1_byte*) outB.getData(),
                              width, height, pixelSize, stride);
        }
    }
}

/**
 * Format a PKM header
 */
static void etc1_formatHeader(JNIEnv *env, jclass clazz,
        jobject header, jint width, jint height) {
    BufferHelper headerB(env, header);
    if (headerB.checkPointer("header") ){
        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
        } else {
            etc1_pkm_format_header((etc1_byte*) headerB.getData(), width, height);
        }
    }
}

/**
 * Check if a PKM header is correctly formatted.
 */
static jboolean etc1_isValid(JNIEnv *env, jclass clazz,
        jobject header) {
    jboolean result = false;
    BufferHelper headerB(env, header);
    if (headerB.checkPointer("header") ){
        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
        } else {
            result = etc1_pkm_is_valid((etc1_byte*) headerB.getData());
        }
    }
    return result ? JNI_TRUE : JNI_FALSE;
}

/**
 * Read the image width from a PKM header
 */
static jint etc1_getWidth(JNIEnv *env, jclass clazz,
        jobject header) {
    jint result = 0;
    BufferHelper headerB(env, header);
    if (headerB.checkPointer("header") ){
        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
        } else {
            result = etc1_pkm_get_width((etc1_byte*) headerB.getData());
        }
    }
    return result;
}

/**
 * Read the image height from a PKM header
 */
static jint etc1_getHeight(JNIEnv *env, jclass clazz,
        jobject header) {
    jint result = 0;
    BufferHelper headerB(env, header);
    if (headerB.checkPointer("header") ){
        if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
        } else {
            result = etc1_pkm_get_height((etc1_byte*) headerB.getData());
        }
    }
    return result;
}

/*
 * JNI registration
 */

static JNINativeMethod gMatrixMethods[] = {
    { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
    { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
};

static JNINativeMethod gVisibilityMethods[] = {
    { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
    { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
    { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest },
};

static JNINativeMethod gUtilsMethods[] = {
    { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat },
    { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType },
    { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D },
    { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D },
    { "setTracingLevel", "(I)V",                        (void*)setTracingLevel },
};

static JNINativeMethod gEtc1Methods[] = {
    { "encodeBlock", "(Ljava/nio/Buffer;ILjava/nio/Buffer;)V", (void*) etc1_encodeBlock },
    { "decodeBlock", "(Ljava/nio/Buffer;Ljava/nio/Buffer;)V", (void*) etc1_decodeBlock },
    { "getEncodedDataSize", "(II)I", (void*) etc1_getEncodedDataSize },
    { "encodeImage", "(Ljava/nio/Buffer;IIIILjava/nio/Buffer;)V", (void*) etc1_encodeImage },
    { "decodeImage", "(Ljava/nio/Buffer;Ljava/nio/Buffer;IIII)V", (void*) etc1_decodeImage },
    { "formatHeader", "(Ljava/nio/Buffer;II)V", (void*) etc1_formatHeader },
    { "isValid", "(Ljava/nio/Buffer;)Z", (void*) etc1_isValid },
    { "getWidth", "(Ljava/nio/Buffer;)I", (void*) etc1_getWidth },
    { "getHeight", "(Ljava/nio/Buffer;)I", (void*) etc1_getHeight },
};

typedef struct _ClassRegistrationInfo {
    const char* classPath;
    JNINativeMethod* methods;
    size_t methodCount;
} ClassRegistrationInfo;

static ClassRegistrationInfo gClasses[] = {
    {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
    {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
    {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
    {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
};

int register_android_opengl_classes(JNIEnv* env)
{
    nativeClassInitBuffer(env);
    int result = 0;
    for (int i = 0; i < NELEM(gClasses); i++) {
        ClassRegistrationInfo* cri = &gClasses[i];
        result = RegisterMethodsOrDie(env, cri->classPath, cri->methods, cri->methodCount);
    }
    return result;
}

} // namespace android
