diff --git a/app/src/main/java/com/hippo/glview/image/ImageTexture.java b/app/src/main/java/com/hippo/glview/image/ImageTexture.java index d98d459c9..3096ffd3e 100644 --- a/app/src/main/java/com/hippo/glview/image/ImageTexture.java +++ b/app/src/main/java/com/hippo/glview/image/ImageTexture.java @@ -153,12 +153,6 @@ public class ImageTexture implements Texture, Animatable { } mTiles = list.toArray(new Tile[list.size()]); - - if (!mImage.isCompleted()) { - Runnable runnable = new AnimateRunnable(); - mAnimateRunnable = runnable; - sThreadExecutor.execute(runnable); - } } private static Tile obtainSmallTile() { @@ -239,7 +233,7 @@ public class ImageTexture implements Texture, Animatable { } boolean end = mReleased.get() || mImage.isImageRecycled() || mNeedRelease.get() || - (mImage.isCompleted() && mImage.getFormat() == 0) || mRunning.get(); + (mImage.getFormat() == 0) || mRunning.get(); synchronized (mImage) { mImageBusy = false; @@ -597,18 +591,6 @@ public class ImageTexture implements Texture, Animatable { mImageBusy = true; } - if (!mImage.isCompleted()) { - try { - sPVLock.p(); - } catch (InterruptedException e) { - // Ignore - } - if (!mNeedRelease.get()) { - mImage.complete(); - } - sPVLock.v(); - } - synchronized (mImage) { // Release image mImageBusy = false; diff --git a/app/src/main/java/com/hippo/glview/image/ImageWrapper.java b/app/src/main/java/com/hippo/glview/image/ImageWrapper.java index e16498ddc..7a4e1f8e7 100644 --- a/app/src/main/java/com/hippo/glview/image/ImageWrapper.java +++ b/app/src/main/java/com/hippo/glview/image/ImageWrapper.java @@ -122,22 +122,6 @@ public class ImageWrapper { return mCut.height(); } - /** - * @see Image#complete() - */ - public boolean complete() { - synchronized (mImage) { - return mImage.complete(); - } - } - - /** - * @see Image#isCompleted() - */ - public boolean isCompleted() { - return mImage.isCompleted(); - } - /** * @see Image#render(int, int, Bitmap, int, int, int, int, boolean, int) */ diff --git a/native/src/main/java/com/hippo/image/Image.java b/native/src/main/java/com/hippo/image/Image.java index 0ead00b8d..71bb13c6a 100644 --- a/native/src/main/java/com/hippo/image/Image.java +++ b/native/src/main/java/com/hippo/image/Image.java @@ -99,10 +99,6 @@ public final class Image { private static native int nativeGetByteCount(long nativePtr, int format); - private static native boolean nativeComplete(long nativePtr, int format); - - private static native boolean nativeIsCompleted(long nativePtr, int format); - private static native void nativeRender(long nativePtr, int format, int srcX, int srcY, Bitmap dst, int dstX, int dstY, int width, int height, boolean fillBlank, int defaultColor); @@ -114,8 +110,6 @@ public final class Image { private static native int nativeGetDelay(long nativePtr, int format); - private static native int nativeFrameCount(long nativePtr, int format); - private static native boolean nativeIsOpaque(long nativePtr, int format); private static native boolean nativeIsGray(long nativePtr, int format, int error); @@ -163,22 +157,6 @@ public final class Image { } } - /** - * Complete the image decoding - */ - public boolean complete() { - checkRecycled(); - return nativeComplete(mNativePtr, mFormat); - } - - /** - * Is the image decoding completed - */ - public boolean isCompleted() { - checkRecycled(); - return nativeIsCompleted(mNativePtr, mFormat); - } - /** * Render the image to {@code Bitmap} */ diff --git a/native/src/main/jni/image/CMakeLists.txt b/native/src/main/jni/image/CMakeLists.txt index 1a6bb0d7d..28dba95e4 100644 --- a/native/src/main/jni/image/CMakeLists.txt +++ b/native/src/main/jni/image/CMakeLists.txt @@ -18,7 +18,6 @@ project(image C) set(IMAGE_SOURCES image.c image_utils.c - image_plain.c filter/clahe.c filter/gray.c java_wrapper.c diff --git a/native/src/main/jni/image/filter/clahe.c b/native/src/main/jni/image/filter/clahe.c index 708ff31d4..c1733199b 100644 --- a/native/src/main/jni/image/filter/clahe.c +++ b/native/src/main/jni/image/filter/clahe.c @@ -24,161 +24,163 @@ #define CL_MAX_LOOP_NUMBER 4 static BYTE clamp(int t) { - t = t > 255 ? 255 : t; - t = t < 0 ? 0 : t; - return (BYTE) t; + t = t > 255 ? 255 : t; + t = t < 0 ? 0 : t; + return (BYTE) t; } -void IMAGE_clahe(void* data, int width, int height, bool to_gray) { - if (width < TILE_BLOCK || height < TILE_BLOCK) { - return; - } - - PIXEL* pixels = data; - - if (to_gray) { - for (int i = 0; i < width * height; ++i) { - PIXEL* p = pixels + i; - int t1 = (int) (p->c1 * 0.299f + p->c2 * 0.587f + p->c3 * 0.114f); - p->c1 = clamp(t1); +void IMAGE_clahe(void *data, int width, int height, bool to_gray) { + if (width < TILE_BLOCK || height < TILE_BLOCK) { + return; } - } else { - // RGBA to YUVA - for (int i = 0; i < width * height; ++i) { - PIXEL* p = pixels + i; - int t1 = (int) (p->c1 * 0.299f + p->c2 * 0.587f + p->c3 * 0.114f); - int t2 = (int) (p->c1 * -0.169f + p->c2 * -0.331f + p->c3 * 0.5f + 128); - int t3 = (int) (p->c1 * 0.5f + p->c2 * -0.419f + p->c3 * -0.081f + 128); - p->c1 = clamp(t1); - p->c2 = clamp(t2); - p->c3 = clamp(t3); + + PIXEL *pixels = data; + + if (to_gray) { + for (int i = 0; i < width * height; ++i) { + PIXEL *p = pixels + i; + int t1 = (int) (p->c1 * 0.299f + p->c2 * 0.587f + p->c3 * 0.114f); + p->c1 = clamp(t1); + } + } else { + // RGBA to YUVA + for (int i = 0; i < width * height; ++i) { + PIXEL *p = pixels + i; + int t1 = (int) (p->c1 * 0.299f + p->c2 * 0.587f + p->c3 * 0.114f); + int t2 = (int) (p->c1 * -0.169f + p->c2 * -0.331f + p->c3 * 0.5f + 128); + int t3 = (int) (p->c1 * 0.5f + p->c2 * -0.419f + p->c3 * -0.081f + 128); + p->c1 = clamp(t1); + p->c2 = clamp(t2); + p->c3 = clamp(t3); + } } - } - int tile_width = width / TILE_BLOCK; - int tile_height = height / TILE_BLOCK; - int histogram[TILE_BLOCK * TILE_BLOCK][256] = {0}; - float accumulation[TILE_BLOCK * TILE_BLOCK][256] = {0.0f}; + int tile_width = width / TILE_BLOCK; + int tile_height = height / TILE_BLOCK; + int histogram[TILE_BLOCK * TILE_BLOCK][256] = {0}; + float accumulation[TILE_BLOCK * TILE_BLOCK][256] = {0.0f}; - // Build histogram and accumulation - for (int i = 0; i < TILE_BLOCK; i++) { - for (int j = 0; j < TILE_BLOCK; j++) { - int x_start = tile_width * i; - int x_end = i == TILE_BLOCK - 1 ? width : x_start + tile_width; - int y_start = tile_height * j; - int y_end = j == TILE_BLOCK - 1 ? height : y_start + tile_height; - int tile_size = (x_end - x_start) * (y_end - y_start); - int tile_index = i + TILE_BLOCK * j; + // Build histogram and accumulation + for (int i = 0; i < TILE_BLOCK; i++) { + for (int j = 0; j < TILE_BLOCK; j++) { + int x_start = tile_width * i; + int x_end = i == TILE_BLOCK - 1 ? width : x_start + tile_width; + int y_start = tile_height * j; + int y_end = j == TILE_BLOCK - 1 ? height : y_start + tile_height; + int tile_size = (x_end - x_start) * (y_end - y_start); + int tile_index = i + TILE_BLOCK * j; - // Count - for(int x = x_start; x < x_end; x++) { - for(int y = y_start; y < y_end ; y++) { - PIXEL* p = pixels + x + y * width; - histogram[tile_index][p->c1] += 1; - } - } + // Count + for (int x = x_start; x < x_end; x++) { + for (int y = y_start; y < y_end; y++) { + PIXEL *p = pixels + x + y * width; + histogram[tile_index][p->c1] += 1; + } + } - // CL - int limit = tile_size * LIMIT_MULTIPLE / 256; - for (int m = 0; m < CL_MAX_LOOP_NUMBER; m++) { - int steal = 0; - for (int n = 0; n < 256; n++) { - if (histogram[tile_index][n] > limit) { - steal += histogram[tile_index][n] - limit; - histogram[tile_index][n] = limit; - } - } - int bonus = steal / 256; - if (bonus == 0 && steal != 0 && m == 0) { - bonus = 1; - } - if (bonus == 0) { - break; - } - for (int n = 0; n < 256; n++) { - histogram[tile_index][n] += bonus; - } - } + // CL + int limit = tile_size * LIMIT_MULTIPLE / 256; + for (int m = 0; m < CL_MAX_LOOP_NUMBER; m++) { + int steal = 0; + for (int n = 0; n < 256; n++) { + if (histogram[tile_index][n] > limit) { + steal += histogram[tile_index][n] - limit; + histogram[tile_index][n] = limit; + } + } + int bonus = steal / 256; + if (bonus == 0 && steal != 0 && m == 0) { + bonus = 1; + } + if (bonus == 0) { + break; + } + for (int n = 0; n < 256; n++) { + histogram[tile_index][n] += bonus; + } + } - // accumulation - for (int n = 0; n < 256; n++) { - accumulation[tile_index][n] = (float) histogram[tile_index][n] / tile_size; - if (n != 0) { - accumulation[tile_index][n] += accumulation[tile_index][n - 1]; + // accumulation + for (int n = 0; n < 256; n++) { + accumulation[tile_index][n] = (float) histogram[tile_index][n] / tile_size; + if (n != 0) { + accumulation[tile_index][n] += accumulation[tile_index][n - 1]; + } + } } - } } - } - // Interpolation - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - PIXEL* p = pixels + x + y * width; - // top-left corner - if (x <= tile_width / 2 && y <= tile_height / 2) { - p->c1 = clamp((int) (accumulation[0][p->c1] * 255)); - continue; - } - // top-right corner - if (x > width - tile_width / 2 && y <= tile_height / 2) { - p->c1 = clamp((int) (accumulation[TILE_BLOCK - 1][p->c1] * 255)); - continue; - } - // bottom-left corner - if (x <= tile_width / 2 && y > height - tile_height / 2) { - p->c1 = clamp((int) (accumulation[TILE_BLOCK * (TILE_BLOCK - 1)][p->c1] * 255)); - continue; - } - // bottom-right corner - if (x > width - tile_width / 2 && y > height - tile_height / 2) { - p->c1 = clamp((int) (accumulation[TILE_BLOCK * TILE_BLOCK - 1][p->c1] * 255)); - continue; - } + // Interpolation + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + PIXEL *p = pixels + x + y * width; + // top-left corner + if (x <= tile_width / 2 && y <= tile_height / 2) { + p->c1 = clamp((int) (accumulation[0][p->c1] * 255)); + continue; + } + // top-right corner + if (x > width - tile_width / 2 && y <= tile_height / 2) { + p->c1 = clamp((int) (accumulation[TILE_BLOCK - 1][p->c1] * 255)); + continue; + } + // bottom-left corner + if (x <= tile_width / 2 && y > height - tile_height / 2) { + p->c1 = clamp((int) (accumulation[TILE_BLOCK * (TILE_BLOCK - 1)][p->c1] * 255)); + continue; + } + // bottom-right corner + if (x > width - tile_width / 2 && y > height - tile_height / 2) { + p->c1 = clamp((int) (accumulation[TILE_BLOCK * TILE_BLOCK - 1][p->c1] * 255)); + continue; + } - int tile_x_index = (x - tile_width / 2) / tile_width; - int tile_y_index = (y - tile_height / 2) / tile_height; - int tile_index1 = tile_x_index + TILE_BLOCK * tile_y_index; - int tile_index2 = tile_index1 + 1; - float u = (float) (x - (tile_x_index * tile_width + tile_width / 2)) / tile_width; - // top side and bottom side - if (y <= tile_height / 2 || y > height - tile_height / 2) { - p->c1 = clamp((int) (255 * (accumulation[tile_index1][p->c1] * (1 - u) + accumulation[tile_index2][p->c1] * u))); - continue; - } + int tile_x_index = (x - tile_width / 2) / tile_width; + int tile_y_index = (y - tile_height / 2) / tile_height; + int tile_index1 = tile_x_index + TILE_BLOCK * tile_y_index; + int tile_index2 = tile_index1 + 1; + float u = (float) (x - (tile_x_index * tile_width + tile_width / 2)) / tile_width; + // top side and bottom side + if (y <= tile_height / 2 || y > height - tile_height / 2) { + p->c1 = clamp((int) (255 * (accumulation[tile_index1][p->c1] * (1 - u) + + accumulation[tile_index2][p->c1] * u))); + continue; + } - int tile_index3 = tile_index1 + TILE_BLOCK; - float v = (float) (y - (tile_y_index * tile_height + tile_height / 2)) / tile_height; - // left side and right side - if (x <= tile_width / 2 || x > width - tile_width / 2) { - p->c1 = clamp((int) (255 * (accumulation[tile_index1][p->c1] * (1 - v) + accumulation[tile_index3][p->c1] * v))); - continue; - } + int tile_index3 = tile_index1 + TILE_BLOCK; + float v = (float) (y - (tile_y_index * tile_height + tile_height / 2)) / tile_height; + // left side and right side + if (x <= tile_width / 2 || x > width - tile_width / 2) { + p->c1 = clamp((int) (255 * (accumulation[tile_index1][p->c1] * (1 - v) + + accumulation[tile_index3][p->c1] * v))); + continue; + } - int tile_index4 = tile_index2 + TILE_BLOCK; - p->c1 = clamp((int) (255 * ( - accumulation[tile_index1][p->c1] * (1 - u) * (1 - v) - + accumulation[tile_index2][p->c1] * u * (1 - v) - + accumulation[tile_index3][p->c1] * (1 - u) * v - + accumulation[tile_index4][p->c1] * u * v))); + int tile_index4 = tile_index2 + TILE_BLOCK; + p->c1 = clamp((int) (255 * ( + accumulation[tile_index1][p->c1] * (1 - u) * (1 - v) + + accumulation[tile_index2][p->c1] * u * (1 - v) + + accumulation[tile_index3][p->c1] * (1 - u) * v + + accumulation[tile_index4][p->c1] * u * v))); + } } - } - if (to_gray) { - for (int i = 0; i < width * height; ++i) { - PIXEL* p = pixels + i; - p->c2 = p->c1; - p->c3 = p->c1; + if (to_gray) { + for (int i = 0; i < width * height; ++i) { + PIXEL *p = pixels + i; + p->c2 = p->c1; + p->c3 = p->c1; + } + } else { + // YUVA to RGBA + for (int i = 0; i < width * height; ++i) { + PIXEL *p = pixels + i; + int t1 = (int) (p->c1 + (p->c2 - 128) * -0.00093f + (p->c3 - 128) * 1.401687f); + int t2 = (int) (p->c1 + (p->c2 - 128) * -0.3437f + (p->c3 - 128) * -0.71417f); + int t3 = (int) (p->c1 + (p->c2 - 128) * 1.77216f + (p->c3 - 128) * 0.00099f); + p->c1 = clamp(t1); + p->c2 = clamp(t2); + p->c3 = clamp(t3); + } } - } else { - // YUVA to RGBA - for (int i = 0; i < width * height; ++i) { - PIXEL* p = pixels + i; - int t1 = (int) (p->c1 + (p->c2 - 128) * -0.00093f + (p->c3 - 128) * 1.401687f); - int t2 = (int) (p->c1 + (p->c2 - 128) * -0.3437f + (p->c3 - 128) * -0.71417f); - int t3 = (int) (p->c1 + (p->c2 - 128) * 1.77216f + (p->c3 - 128) * 0.00099f); - p->c1 = clamp(t1); - p->c2 = clamp(t2); - p->c3 = clamp(t3); - } - } } diff --git a/native/src/main/jni/image/filter/clahe.h b/native/src/main/jni/image/filter/clahe.h index bacf5bbe4..83e965923 100644 --- a/native/src/main/jni/image/filter/clahe.h +++ b/native/src/main/jni/image/filter/clahe.h @@ -19,6 +19,6 @@ #include -void IMAGE_clahe(void* data, int width, int height, bool to_gray); +void IMAGE_clahe(void *data, int width, int height, bool to_gray); #endif //IMAGE_CLAHE_H diff --git a/native/src/main/jni/image/filter/gray.c b/native/src/main/jni/image/filter/gray.c index a5f0ae123..95ec08b0f 100644 --- a/native/src/main/jni/image/filter/gray.c +++ b/native/src/main/jni/image/filter/gray.c @@ -17,20 +17,20 @@ #include "gray.h" #include "pixel.h" -bool IMAGE_is_gray(void* data, int width, int height, int error) { - PIXEL* p = data; +bool IMAGE_is_gray(void *data, int width, int height, int error) { + PIXEL *p = data; - for (int i = 0, n = width * height; i < n; i++, p++) { - int e1 = p->c1 - p->c2; - int e2 = p->c1 - p->c3; - int e3 = p->c2 - p->c3; + for (int i = 0, n = width * height; i < n; i++, p++) { + int e1 = p->c1 - p->c2; + int e2 = p->c1 - p->c3; + int e3 = p->c2 - p->c3; - if (e1 > error || e1 < -error - || e2 > error || e2 < -error - || e3 > error || e3 < -error) { - return false; + if (e1 > error || e1 < -error + || e2 > error || e2 < -error + || e3 > error || e3 < -error) { + return false; + } } - } - return true; + return true; } diff --git a/native/src/main/jni/image/filter/gray.h b/native/src/main/jni/image/filter/gray.h index c31e6c797..408dbb041 100644 --- a/native/src/main/jni/image/filter/gray.h +++ b/native/src/main/jni/image/filter/gray.h @@ -19,6 +19,6 @@ #include -bool IMAGE_is_gray(void* data, int width, int height, int error); +bool IMAGE_is_gray(void *data, int width, int height, int error); #endif //IMAGE_GRAY_H diff --git a/native/src/main/jni/image/filter/pixel.h b/native/src/main/jni/image/filter/pixel.h index 95154afea..adadcd70c 100644 --- a/native/src/main/jni/image/filter/pixel.h +++ b/native/src/main/jni/image/filter/pixel.h @@ -19,12 +19,11 @@ typedef unsigned char BYTE; -typedef struct -{ - BYTE c1; - BYTE c2; - BYTE c3; - BYTE c4; +typedef struct { + BYTE c1; + BYTE c2; + BYTE c3; + BYTE c4; } PIXEL; #endif //IMAGE_PIXEL_H diff --git a/native/src/main/jni/image/image.c b/native/src/main/jni/image/image.c index fa80396e7..ac6ec1491 100644 --- a/native/src/main/jni/image/image.c +++ b/native/src/main/jni/image/image.c @@ -18,37 +18,38 @@ // Created by Hippo on 12/27/2015. // -#include #include #include +#include #include #include "image.h" -#include "image_plain.h" #include "image_utils.h" #include "filter/clahe.h" #include "filter/gray.h" #include "log.h" -void decodeCommon(IMAGE * image) -{ +void decodeCommon(IMAGE *image) { AImageDecoder *decoder = image->decoder; AImageDecoder_setDataSpace(decoder, ADATASPACE_SRGB); AImageDecoder_setAndroidBitmapFormat(decoder, ANDROID_BITMAP_FORMAT_RGBA_8888); const AImageDecoderHeaderInfo *headerInfo = AImageDecoder_getHeaderInfo(decoder); image->height = AImageDecoderHeaderInfo_getHeight(headerInfo); image->width = AImageDecoderHeaderInfo_getWidth(headerInfo); + image->alpha = + AImageDecoderHeaderInfo_getAlphaFlags(headerInfo) == ANDROID_BITMAP_FLAGS_ALPHA_PREMUL; image->stride = AImageDecoder_getMinimumStride(decoder); image->bufferLen = image->height * image->stride; image->buffer = malloc(image->bufferLen); if (image->isAnimated) { + AImageDecoder_setInternallyHandleDisposePrevious(decoder, false); image->frameInfo = AImageDecoderFrameInfo_create(); AImageDecoder_getFrameInfo(decoder, image->frameInfo); } AImageDecoder_decodeImage(decoder, image->buffer, image->stride, image->bufferLen); } -IMAGE * createFromFd(JNIEnv* env, int fd, bool partially, int* format) { +IMAGE *createFromFd(JNIEnv *env, int fd, bool partially, int *format) { AImageDecoder *decoder; int r = AImageDecoder_createFromFd(fd, &decoder); LOGD("%s%d", "Create ImageDecoder with ret ", r); @@ -61,7 +62,7 @@ IMAGE * createFromFd(JNIEnv* env, int fd, bool partially, int* format) { return image; } -IMAGE * createFromAddr(JNIEnv* env, void* addr, long size, bool partially, int* format) { +IMAGE *createFromAddr(JNIEnv *env, void *addr, long size, bool partially, int *format) { AImageDecoder *decoder; int r = AImageDecoder_createFromBuffer((const void *) addr, size, &decoder); LOGD("%s%d", "Create ImageDecoder with ret ", r); @@ -75,104 +76,116 @@ IMAGE * createFromAddr(JNIEnv* env, void* addr, long size, bool partially, int* return image; } -void* create(int32_t width, int32_t height, const void* data) -{ - return PLAIN_create(width, height, data); +void *create(int32_t width, int32_t height, const void *data) { + IMAGE *plain = NULL; + void *buffer = NULL; + size_t length; + + plain = malloc(sizeof(IMAGE)); + if (plain == NULL) { + WTF_OM; + return NULL; + } + + length = (size_t) (width * height * 4); + + buffer = malloc(length); + if (buffer == NULL) { + WTF_OM; + free(plain); + return NULL; + } + + memcpy(buffer, data, length); + + plain->width = width; + plain->height = height; + plain->buffer = buffer; + plain->bufferLen = length; + plain->decoder = NULL; + + return plain; } -bool complete(JNIEnv* env, IMAGE * image, int format) -{ - return true; -} - -bool is_completed(IMAGE * image, int format) -{ - return true; -} - -int get_width(IMAGE * image, int format) -{ +int get_width(IMAGE *image, int format) { return image->width; } -int get_height(IMAGE * image, int format) -{ +int get_height(IMAGE *image, int format) { return image->height; } -int get_byte_count(IMAGE * image, int format) -{ +int get_byte_count(IMAGE *image, int format) { return image->bufferLen; } -void render(IMAGE * image, int format, int src_x, int src_y, - void* dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height, bool fill_blank, int default_color) -{ - copy_pixels(image->buffer, image->width, image->height, src_x, src_y, dst, dst_w, dst_h, dst_x, dst_y, width, height, fill_blank, default_color); +void render(IMAGE *image, int format, int src_x, int src_y, + void *dst, int dst_w, int dst_h, int dst_x, int dst_y, + int width, int height, bool fill_blank, int default_color) { + copy_pixels(image->buffer, image->width, image->height, src_x, src_y, dst, dst_w, dst_h, dst_x, + dst_y, width, height, fill_blank, default_color); } -void advance(IMAGE * image, int format) -{ +void advance(IMAGE *image, int format) { if (format) { AImageDecoder_advanceFrame(image->decoder); - if (AImageDecoder_decodeImage(image->decoder, image->buffer, image->stride, image->bufferLen) == ANDROID_IMAGE_DECODER_FINISHED) { + if (AImageDecoder_decodeImage(image->decoder, image->buffer, image->stride, + image->bufferLen) == ANDROID_IMAGE_DECODER_FINISHED) { AImageDecoder_rewind(image->decoder); - AImageDecoder_decodeImage(image->decoder, image->buffer, image->stride, image->bufferLen); + AImageDecoder_decodeImage(image->decoder, image->buffer, image->stride, + image->bufferLen); } } } -int get_delay(IMAGE * image, int format) -{ +int get_delay(IMAGE *image, int format) { + if (format) + return AImageDecoderFrameInfo_getDuration(image->frameInfo) / 1000000; return 0; } -bool is_opaque(IMAGE * image, int format) -{ - return false; +bool is_opaque(IMAGE *image, int format) { + return image->alpha; } -static void get_image_data(IMAGE * image, int format, void** pixel, int* width, int* height) { - *pixel = image->buffer; - *width = image->width; - *height = image->height; +static void get_image_data(IMAGE *image, int format, void **pixel, int *width, int *height) { + *pixel = image->buffer; + *width = image->width; + *height = image->height; } -bool is_gray(IMAGE * image, int format, int error) -{ - void* pixel = NULL; - int width = 0; - int height = 0; +bool is_gray(IMAGE *image, int format, int error) { + void *pixel = NULL; + int width = 0; + int height = 0; - get_image_data(image, format, &pixel, &width, &height); + get_image_data(image, format, &pixel, &width, &height); - if (pixel == NULL || width == 0 || height == 0) { - return false; - } + if (pixel == NULL || width == 0 || height == 0) { + return false; + } - return IMAGE_is_gray(pixel, width, height, error); + return IMAGE_is_gray(pixel, width, height, error); } -void clahe(IMAGE * image, int format, bool to_gray) -{ - void* pixel = NULL; - int width = 0; - int height = 0; +void clahe(IMAGE *image, int format, bool to_gray) { + void *pixel = NULL; + int width = 0; + int height = 0; - get_image_data(image, format, &pixel, &width, &height); + get_image_data(image, format, &pixel, &width, &height); - if (pixel == NULL || width == 0 || height == 0) { - return; - } + if (pixel == NULL || width == 0 || height == 0) { + return; + } - IMAGE_clahe(pixel, width, height, to_gray); + IMAGE_clahe(pixel, width, height, to_gray); } -void recycle(JNIEnv *env, IMAGE* image, int format) -{ +void recycle(JNIEnv *env, IMAGE *image, int format) { free(image->buffer); image->buffer = NULL; + AImageDecoderFrameInfo_delete(image->frameInfo); AImageDecoder_delete(image->decoder); free(image->srcBuffer); free(image); diff --git a/native/src/main/jni/image/image.h b/native/src/main/jni/image/image.h index 53cf7ec1c..f21a68195 100644 --- a/native/src/main/jni/image/image.h +++ b/native/src/main/jni/image/image.h @@ -25,35 +25,45 @@ #include #include -typedef struct -{ +typedef struct { int32_t width; int32_t height; - void* buffer; + void *buffer; int bufferLen; - AImageDecoder* decoder; - void* srcBuffer; + AImageDecoder *decoder; + void *srcBuffer; size_t stride; bool isAnimated; AImageDecoderFrameInfo *frameInfo; + bool alpha; } IMAGE; -IMAGE * createFromFd(JNIEnv* env, int fd, bool partially, int* format); -IMAGE * createFromAddr(JNIEnv* env, void* addr, long size, bool partially, int* format); -void* create(int32_t width, int32_t height, const void* data); -bool complete(JNIEnv* env, IMAGE * image, int format); -bool is_completed(IMAGE * image, int format); -int get_width(IMAGE * image, int format); -int get_height(IMAGE * image, int format); -int get_byte_count(IMAGE * image, int format); -void render(IMAGE * image, int format, int src_x, int src_y, - void* dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height, bool fill_blank, int default_color); -void advance(IMAGE * image, int format); -int get_delay(IMAGE * image, int format); -bool is_opaque(IMAGE * image, int format); -bool is_gray(IMAGE * image, int format, int error); -void clahe(IMAGE * image, int format, bool to_gray); -void recycle(JNIEnv *env, IMAGE * image, int format); +IMAGE *createFromFd(JNIEnv *env, int fd, bool partially, int *format); + +IMAGE *createFromAddr(JNIEnv *env, void *addr, long size, bool partially, int *format); + +void *create(int32_t width, int32_t height, const void *data); + +int get_width(IMAGE *image, int format); + +int get_height(IMAGE *image, int format); + +int get_byte_count(IMAGE *image, int format); + +void render(IMAGE *image, int format, int src_x, int src_y, + void *dst, int dst_w, int dst_h, int dst_x, int dst_y, + int width, int height, bool fill_blank, int default_color); + +void advance(IMAGE *image, int format); + +int get_delay(IMAGE *image, int format); + +bool is_opaque(IMAGE *image, int format); + +bool is_gray(IMAGE *image, int format, int error); + +void clahe(IMAGE *image, int format, bool to_gray); + +void recycle(JNIEnv *env, IMAGE *image, int format); #endif //IMAGE_IMAGE_H diff --git a/native/src/main/jni/image/image_plain.c b/native/src/main/jni/image/image_plain.c deleted file mode 100644 index cea9c7e29..000000000 --- a/native/src/main/jni/image/image_plain.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2016 Hippo Seven - * - * 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 -#include - -#include "image_plain.h" -#include "image_utils.h" -#include "log.h" - -void* PLAIN_create(int32_t width, int32_t height, const void* data) -{ - IMAGE * plain = NULL; - void* buffer = NULL; - size_t length; - - plain = malloc(sizeof(IMAGE)); - if (plain == NULL) { - WTF_OM; - return NULL; - } - - length = (size_t) (width * height * 4); - - buffer = malloc(length); - if (buffer == NULL) { - WTF_OM; - free(plain); - return NULL; - } - - memcpy(buffer, data, length); - - plain->width = width; - plain->height = height; - plain->buffer = buffer; - plain->bufferLen = length; - plain->decoder = NULL; - - return plain; -} diff --git a/native/src/main/jni/image/image_plain.h b/native/src/main/jni/image/image_plain.h deleted file mode 100644 index 665ef0f84..000000000 --- a/native/src/main/jni/image/image_plain.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016 Hippo Seven - * - * 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. - */ - -// -// Created by Hippo on 5/3/2016. -// - -#ifndef IMAGE_IMAGE_PLAIN_H -#define IMAGE_IMAGE_PLAIN_H - -#include - -#include "image.h" - -void* PLAIN_create(int32_t width, int32_t height, const void* data); - -#endif // IMAGE_IMAGE_PLAIN_H diff --git a/native/src/main/jni/image/image_utils.c b/native/src/main/jni/image/image_utils.c index e88bee1a2..55ca4502c 100644 --- a/native/src/main/jni/image/image_utils.c +++ b/native/src/main/jni/image/image_utils.c @@ -29,157 +29,155 @@ static unsigned int endian = ~0U; static unsigned int get_endian() { - unsigned int x = 1; + unsigned int x = 1; - if (endian == ~0U) { - if (1 == ((char *)&x)[0]) { - endian = LITTLE_ENDIAN; - } else { - endian = BIG_ENDIAN; + if (endian == ~0U) { + if (1 == ((char *) &x)[0]) { + endian = LITTLE_ENDIAN; + } else { + endian = BIG_ENDIAN; + } } - } - return endian; + return endian; } static int convert_color(int origin) { - int result; - unsigned char* orPtr = (unsigned char *) &origin; - unsigned char* rePtr = (unsigned char *) &result; + int result; + unsigned char *orPtr = (unsigned char *) &origin; + unsigned char *rePtr = (unsigned char *) &result; - if (get_endian() == BIG_ENDIAN) { - rePtr[0] = orPtr[1]; - rePtr[1] = orPtr[2]; - rePtr[2] = orPtr[3]; - rePtr[3] = orPtr[0]; - } else { - rePtr[0] = orPtr[2]; - rePtr[1] = orPtr[1]; - rePtr[2] = orPtr[0]; - rePtr[3] = orPtr[3]; - } - - return result; -} - -static void memset_int(int* dst, int val, size_t size) { - int* maxPtr = dst + size; - int* ptr = dst; - while(ptr < maxPtr) - *ptr++ = val; -} - -bool copy_pixels_internal(const void* src, int src_w, int src_h, int src_x, int src_y, - void* dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height, bool fill_blank, int color) -{ - int left; - int line; - size_t line_stride; - int src_stride; - int src_pos; - int dst_pos; - size_t dst_blank_length; - - // Sanitize - if (src_x < 0) { - width -= src_x; - dst_x -= src_x; - src_x = 0; - } - if (dst_x < 0) { - width -= dst_x; - src_x -= dst_x; - dst_x = 0; - } - if (width <= 0) { - return false; - } - if (src_y < 0) { - height -= src_y; - dst_y -= src_y; - src_y = 0; - } - if (dst_y < 0) { - height -= dst_y; - src_y -= dst_y; - dst_y = 0; - } - if (height <= 0) { - return false; - } - left = src_x + width - src_w; - if (left > 0) { - width -= left; - } - left = dst_x + width - dst_w; - if (left > 0) { - width -= left; - } - if (width <= 0) { - return false; - } - left = src_y + height - src_h; - if (left > 0) { - height -= left; - } - left = dst_y + height - dst_h; - if (left > 0) { - height -= left; - } - if (height <= 0) { - return false; - } - - // Init - line_stride = (size_t) (width * 4); - src_stride = src_w * 4; - src_pos = src_y * src_stride + src_x * 4; - dst_pos = 0; - - dst_blank_length = (size_t) (dst_y * dst_w + dst_x) * 4; - // Fill start blank if necessary - if (fill_blank) { - memset_int((int *) (dst + dst_pos), color, dst_blank_length / 4); - } - - // First line - dst_pos += dst_blank_length; - memcpy(dst + dst_pos, src + src_pos, line_stride); - dst_pos += line_stride; - src_pos += src_stride; - - // Other lines - dst_blank_length = (size_t) ((dst_w - width) * 4); - for (line = 1; line < height; line++) { - if (fill_blank) { - memset_int((int *) (dst + dst_pos), color, dst_blank_length / 4); + if (get_endian() == BIG_ENDIAN) { + rePtr[0] = orPtr[1]; + rePtr[1] = orPtr[2]; + rePtr[2] = orPtr[3]; + rePtr[3] = orPtr[0]; + } else { + rePtr[0] = orPtr[2]; + rePtr[1] = orPtr[1]; + rePtr[2] = orPtr[0]; + rePtr[3] = orPtr[3]; } + + return result; +} + +static void memset_int(int *dst, int val, size_t size) { + int *maxPtr = dst + size; + int *ptr = dst; + while (ptr < maxPtr) + *ptr++ = val; +} + +bool copy_pixels_internal(const void *src, int src_w, int src_h, int src_x, int src_y, + void *dst, int dst_w, int dst_h, int dst_x, int dst_y, + int width, int height, bool fill_blank, int color) { + int left; + int line; + size_t line_stride; + int src_stride; + int src_pos; + int dst_pos; + size_t dst_blank_length; + + // Sanitize + if (src_x < 0) { + width -= src_x; + dst_x -= src_x; + src_x = 0; + } + if (dst_x < 0) { + width -= dst_x; + src_x -= dst_x; + dst_x = 0; + } + if (width <= 0) { + return false; + } + if (src_y < 0) { + height -= src_y; + dst_y -= src_y; + src_y = 0; + } + if (dst_y < 0) { + height -= dst_y; + src_y -= dst_y; + dst_y = 0; + } + if (height <= 0) { + return false; + } + left = src_x + width - src_w; + if (left > 0) { + width -= left; + } + left = dst_x + width - dst_w; + if (left > 0) { + width -= left; + } + if (width <= 0) { + return false; + } + left = src_y + height - src_h; + if (left > 0) { + height -= left; + } + left = dst_y + height - dst_h; + if (left > 0) { + height -= left; + } + if (height <= 0) { + return false; + } + + // Init + line_stride = (size_t) (width * 4); + src_stride = src_w * 4; + src_pos = src_y * src_stride + src_x * 4; + dst_pos = 0; + + dst_blank_length = (size_t) (dst_y * dst_w + dst_x) * 4; + // Fill start blank if necessary + if (fill_blank) { + memset_int((int *) (dst + dst_pos), color, dst_blank_length / 4); + } + + // First line dst_pos += dst_blank_length; memcpy(dst + dst_pos, src + src_pos, line_stride); dst_pos += line_stride; src_pos += src_stride; - } - // Fill left blank if necessary - if (fill_blank) { - memset_int((int *) (dst + dst_pos), color, (size_t) (dst_w * dst_h * 4 - dst_pos) / 4); - } + // Other lines + dst_blank_length = (size_t) ((dst_w - width) * 4); + for (line = 1; line < height; line++) { + if (fill_blank) { + memset_int((int *) (dst + dst_pos), color, dst_blank_length / 4); + } + dst_pos += dst_blank_length; + memcpy(dst + dst_pos, src + src_pos, line_stride); + dst_pos += line_stride; + src_pos += src_stride; + } - return true; + // Fill left blank if necessary + if (fill_blank) { + memset_int((int *) (dst + dst_pos), color, (size_t) (dst_w * dst_h * 4 - dst_pos) / 4); + } + + return true; } -void copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, - void* dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height, bool fill_blank, int default_color) -{ - int color = 0; - if (fill_blank) { - color = convert_color(default_color); - } +void copy_pixels(const void *src, int src_w, int src_h, int src_x, int src_y, + void *dst, int dst_w, int dst_h, int dst_x, int dst_y, + int width, int height, bool fill_blank, int default_color) { + int color = 0; + if (fill_blank) { + color = convert_color(default_color); + } - if (!copy_pixels_internal(src, src_w, src_h, src_x, src_y, dst, dst_w, dst_h, dst_x, - dst_y, width, height, fill_blank, color) && fill_blank) { - memset_int(dst, color, (size_t) (dst_w * dst_h)); - } + if (!copy_pixels_internal(src, src_w, src_h, src_x, src_y, dst, dst_w, dst_h, dst_x, + dst_y, width, height, fill_blank, color) && fill_blank) { + memset_int(dst, color, (size_t) (dst_w * dst_h)); + } } diff --git a/native/src/main/jni/image/image_utils.h b/native/src/main/jni/image/image_utils.h index 46a814f5a..e99369f64 100644 --- a/native/src/main/jni/image/image_utils.h +++ b/native/src/main/jni/image/image_utils.h @@ -26,8 +26,8 @@ #include -void copy_pixels(const void* src, int src_w, int src_h, int src_x, int src_y, - void* dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height, bool fill_blank, int default_color); +void copy_pixels(const void *src, int src_w, int src_h, int src_x, int src_y, + void *dst, int dst_w, int dst_h, int dst_x, int dst_y, + int width, int height, bool fill_blank, int default_color); #endif //IMAGE_IMAGE_UTILS_H diff --git a/native/src/main/jni/image/java_wrapper.c b/native/src/main/jni/image/java_wrapper.c index 4c4859c2d..3acc55d52 100644 --- a/native/src/main/jni/image/java_wrapper.c +++ b/native/src/main/jni/image/java_wrapper.c @@ -22,285 +22,258 @@ #include "image.h" #include "log.h" -static JavaVM* jvm; +static JavaVM *jvm; -static void* tile_buffer; +static void *tile_buffer; -static int jniGetFDFromFileDescriptor(JNIEnv * env, jobject fileDescriptor) { - jint fd = -1; - jclass fdClass = (*env)->FindClass(env, "java/io/FileDescriptor"); +static int jniGetFDFromFileDescriptor(JNIEnv *env, jobject fileDescriptor) { + jint fd = -1; + jclass fdClass = (*env)->FindClass(env, "java/io/FileDescriptor"); - if (fdClass != NULL) { - jfieldID fdClassDescriptorFieldID = (*env)->GetFieldID(env, fdClass, "descriptor", "I"); - if (fdClassDescriptorFieldID != NULL && fileDescriptor != NULL) { - fd = (*env)->GetIntField(env, fileDescriptor, fdClassDescriptorFieldID); + if (fdClass != NULL) { + jfieldID fdClassDescriptorFieldID = (*env)->GetFieldID(env, fdClass, "descriptor", "I"); + if (fdClassDescriptorFieldID != NULL && fileDescriptor != NULL) { + fd = (*env)->GetIntField(env, fileDescriptor, fdClassDescriptorFieldID); + } } - } - return fd; + return fd; } -JNIEnv *obtain_env(bool *attach) -{ - JNIEnv *env; - switch ((*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6)) { - case JNI_EDETACHED: - if ((*jvm)->AttachCurrentThread(jvm, &env, NULL) == JNI_OK) { - *attach = true; - return env; - } else { +JNIEnv *obtain_env(bool *attach) { + JNIEnv *env; + switch ((*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_6)) { + case JNI_EDETACHED: + if ((*jvm)->AttachCurrentThread(jvm, &env, NULL) == JNI_OK) { + *attach = true; + return env; + } else { + return NULL; + } + case JNI_OK: + *attach = false; + return env; + default: + case JNI_EVERSION: + return NULL; + } +} + +void release_env() { + (*jvm)->DetachCurrentThread(jvm); +} + +jobject create_image_object(JNIEnv *env, void *ptr, int format, int width, int height) { + jclass image_clazz; + jmethodID constructor; + + image_clazz = (*env)->FindClass(env, "com/hippo/image/Image"); + constructor = (*env)->GetMethodID(env, image_clazz, "", "(JIII)V"); + if (constructor == 0) { + LOGE(MSG("Can't find Image object constructor")); return NULL; - } - case JNI_OK: - *attach = false; - return env; - default: - case JNI_EVERSION: - return NULL; - } -} - -void release_env() -{ - (*jvm)->DetachCurrentThread(jvm); -} - -jobject create_image_object(JNIEnv* env, void* ptr, int format, int width, int height) -{ - jclass image_clazz; - jmethodID constructor; - - image_clazz = (*env)->FindClass(env, "com/hippo/image/Image"); - constructor = (*env)->GetMethodID(env, image_clazz, "", "(JIII)V"); - if (constructor == 0) { - LOGE(MSG("Can't find Image object constructor")); - return NULL; - } else { - return (*env)->NewObject(env, image_clazz, constructor, - (jlong) (uintptr_t) ptr, (jint) format, (jint) width, (jint) height); - } + } else { + return (*env)->NewObject(env, image_clazz, constructor, + (jlong) (uintptr_t) ptr, (jint) format, (jint) width, + (jint) height); + } } JNIEXPORT jobject JNICALL -Java_com_hippo_image_Image_nativeDecodeFdInt(JNIEnv* env, - jclass clazz, jint fd, jboolean partially) -{ - int format; - void* image; - jobject image_object; +Java_com_hippo_image_Image_nativeDecodeFdInt(JNIEnv *env, + jclass clazz, jint fd, jboolean partially) { + int format; + void *image; + jobject image_object; - image = createFromFd(env, fd, partially, &format); - if (image == NULL) { - return NULL; - } + image = createFromFd(env, fd, partially, &format); + if (image == NULL) { + return NULL; + } - image_object = create_image_object(env, image, format, - get_width(image, format), get_height(image, format)); - if (image_object == NULL) { - recycle(env, image, format); - return NULL; - } else { - return image_object; - } + image_object = create_image_object(env, image, format, + get_width(image, format), get_height(image, format)); + if (image_object == NULL) { + recycle(env, image, format); + return NULL; + } else { + return image_object; + } } JNIEXPORT jobject JNICALL -Java_com_hippo_image_Image_nativeDecode(JNIEnv* env, - jclass clazz, jobject fd, jboolean partially) -{ - return Java_com_hippo_image_Image_nativeDecodeFdInt(env, clazz, jniGetFDFromFileDescriptor(env, fd), partially); +Java_com_hippo_image_Image_nativeDecode(JNIEnv *env, + jclass clazz, jobject fd, jboolean partially) { + return Java_com_hippo_image_Image_nativeDecodeFdInt(env, clazz, + jniGetFDFromFileDescriptor(env, fd), + partially); } JNIEXPORT jobject JNICALL -Java_com_hippo_image_Image_nativeCreate(JNIEnv* env, - jclass clazz, jobject bitmap) -{ - AndroidBitmapInfo info; - void *pixels = NULL; - void* image = NULL; - jobject image_object; +Java_com_hippo_image_Image_nativeCreate(JNIEnv *env, + jclass clazz, jobject bitmap) { + AndroidBitmapInfo info; + void *pixels = NULL; + void *image = NULL; + jobject image_object; - AndroidBitmap_getInfo(env, bitmap, &info); - AndroidBitmap_lockPixels(env, bitmap, &pixels); - if (pixels == NULL) { - LOGE(MSG("Can't lock bitmap pixels")); - return NULL; - } + AndroidBitmap_getInfo(env, bitmap, &info); + AndroidBitmap_lockPixels(env, bitmap, &pixels); + if (pixels == NULL) { + LOGE(MSG("Can't lock bitmap pixels")); + return NULL; + } - image = create(info.width, info.height, pixels); + image = create(info.width, info.height, pixels); - AndroidBitmap_unlockPixels(env, bitmap); + AndroidBitmap_unlockPixels(env, bitmap); - if (image == NULL) { - return NULL; - } + if (image == NULL) { + return NULL; + } - image_object = create_image_object(env, image, 0, - info.width, info.height); - if (image_object == NULL) { - recycle(env, image, 0); - return NULL; - } else { - return image_object; - } -} - -JNIEXPORT jboolean JNICALL -Java_com_hippo_image_Image_nativeComplete(JNIEnv* env, - jclass clazz, jlong ptr, jint format) -{ - return (jboolean) complete(env, (void*) (intptr_t) ptr, format); -} - -JNIEXPORT jboolean JNICALL -Java_com_hippo_image_Image_nativeIsCompleted(JNIEnv* env, - jclass clazz, jlong ptr, jint format) -{ - return (jboolean) is_completed((void*) (intptr_t) ptr, format); + image_object = create_image_object(env, image, 0, + info.width, info.height); + if (image_object == NULL) { + recycle(env, image, 0); + return NULL; + } else { + return image_object; + } } JNIEXPORT jint JNICALL -Java_com_hippo_image_Image_nativeGetByteCount(JNIEnv* env, - jclass clazz, jlong ptr, jint format) -{ - return (jint) get_byte_count((void*) (intptr_t) ptr, format); +Java_com_hippo_image_Image_nativeGetByteCount(JNIEnv *env, + jclass clazz, jlong ptr, jint format) { + return (jint) get_byte_count((void *) (intptr_t) ptr, format); } JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeRender(JNIEnv* env, - jclass clazz, jlong ptr, jint format, - jint src_x, jint src_y, jobject dst, jint dst_x, jint dst_y, - jint width, jint height, jboolean fill_blank, jint default_color) -{ - AndroidBitmapInfo info; - void *pixels = NULL; +Java_com_hippo_image_Image_nativeRender(JNIEnv *env, + jclass clazz, jlong ptr, jint format, + jint src_x, jint src_y, jobject dst, jint dst_x, jint dst_y, + jint width, jint height, jboolean fill_blank, + jint default_color) { + AndroidBitmapInfo info; + void *pixels = NULL; + + AndroidBitmap_getInfo(env, dst, &info); + AndroidBitmap_lockPixels(env, dst, &pixels); + if (pixels == NULL) { + LOGE(MSG("Can't lock bitmap pixels")); + return; + } + + render((void *) (intptr_t) ptr, format, src_x, src_y, + pixels, info.width, info.height, dst_x, dst_y, + width, height, fill_blank, default_color); + + AndroidBitmap_unlockPixels(env, dst); - AndroidBitmap_getInfo(env, dst, &info); - AndroidBitmap_lockPixels(env, dst, &pixels); - if (pixels == NULL) { - LOGE(MSG("Can't lock bitmap pixels")); return; - } - - render((void*) (intptr_t) ptr, format, src_x, src_y, - pixels, info.width, info.height, dst_x, dst_y, - width, height, fill_blank, default_color); - - AndroidBitmap_unlockPixels(env, dst); - - return; } JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeTexImage(JNIEnv* env, - jclass clazz, jlong ptr, jint format, jboolean init, - jint src_x, jint src_y, jint width, jint height) -{ - // Check tile_buffer NULL - if (NULL == tile_buffer) { - return; - } - // Check render size - if (width * height > IMAGE_TILE_MAX_SIZE) { - return; - } +Java_com_hippo_image_Image_nativeTexImage(JNIEnv *env, + jclass clazz, jlong ptr, jint format, jboolean init, + jint src_x, jint src_y, jint width, jint height) { + // Check tile_buffer NULL + if (NULL == tile_buffer) { + return; + } + // Check render size + if (width * height > IMAGE_TILE_MAX_SIZE) { + return; + } - render((void*) (intptr_t) ptr, format, src_x, src_y, - tile_buffer, width, height, 0, 0, - width, height, false, 0); + render((void *) (intptr_t) ptr, format, src_x, src_y, + tile_buffer, width, height, 0, 0, + width, height, false, 0); - if (init) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, tile_buffer); - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_RGBA, GL_UNSIGNED_BYTE, tile_buffer); - } + if (init) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, tile_buffer); + } else { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, tile_buffer); + } } JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeAdvance(JNIEnv* env, - jclass clazz, jlong ptr, jint format) -{ - advance((void*) (intptr_t) ptr, format); +Java_com_hippo_image_Image_nativeAdvance(JNIEnv *env, + jclass clazz, jlong ptr, jint format) { + advance((void *) (intptr_t) ptr, format); } JNIEXPORT jint JNICALL -Java_com_hippo_image_Image_nativeGetDelay(JNIEnv* env, - jclass clazz, jlong ptr, jint format) -{ - return (jint) get_delay((void*) (intptr_t) ptr, format); +Java_com_hippo_image_Image_nativeGetDelay(JNIEnv *env, + jclass clazz, jlong ptr, jint format) { + return (jint) get_delay((void *) (intptr_t) ptr, format); } JNIEXPORT jboolean JNICALL -Java_com_hippo_image_Image_nativeIsOpaque(JNIEnv* env, - jclass clazz, jlong ptr, jint format) -{ - return (jboolean) is_opaque((void*) (intptr_t) ptr, format); +Java_com_hippo_image_Image_nativeIsOpaque(JNIEnv *env, + jclass clazz, jlong ptr, jint format) { + return (jboolean) is_opaque((void *) (intptr_t) ptr, format); } JNIEXPORT jboolean JNICALL -Java_com_hippo_image_Image_nativeIsGray(JNIEnv* env, - jclass clazz, jlong ptr, jint format, jint error) -{ - return (jboolean) is_gray((void*) (intptr_t) ptr, format, error); +Java_com_hippo_image_Image_nativeIsGray(JNIEnv *env, + jclass clazz, jlong ptr, jint format, jint error) { + return (jboolean) is_gray((void *) (intptr_t) ptr, format, error); } JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeClahe(JNIEnv* env, - jclass clazz, jlong ptr, jint format, jboolean to_gray) -{ - clahe((void*) (intptr_t) ptr, format, to_gray); +Java_com_hippo_image_Image_nativeClahe(JNIEnv *env, + jclass clazz, jlong ptr, jint format, jboolean to_gray) { + clahe((void *) (intptr_t) ptr, format, to_gray); } JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeRecycle(JNIEnv* env, - jclass clazz, jlong ptr, jint format) -{ - recycle(env, (void*) (intptr_t) ptr, format); +Java_com_hippo_image_Image_nativeRecycle(JNIEnv *env, + jclass clazz, jlong ptr, jint format) { + recycle(env, (void *) (intptr_t) ptr, format); } -bool image_onLoad(JavaVM *vm) -{ - jvm = vm; +bool image_onLoad(JavaVM *vm) { + jvm = vm; - tile_buffer = malloc(IMAGE_TILE_MAX_SIZE * 4); + tile_buffer = malloc(IMAGE_TILE_MAX_SIZE * 4); - return true; + return true; } JNIEXPORT void JNICALL -JNI_OnUnload(JavaVM *vm, void *reserved) -{ - free(tile_buffer); - tile_buffer = NULL; +JNI_OnUnload(JavaVM *vm, void *reserved) { + free(tile_buffer); + tile_buffer = NULL; } typedef struct Memarea { - void* buffer; + void *buffer; long size; } Memarea; JNIEXPORT jobject JNICALL Java_com_hippo_image_Image_nativeDecodeAddr(JNIEnv *env, jclass clazz, jlong addr, jboolean partially) { - int format; - void* image; - jobject image_object; + int format; + void *image; + jobject image_object; - Memarea *memarea = (Memarea*)addr; - image = createFromAddr(env, memarea->buffer, memarea->size, partially, &format); - free(memarea); - if (image == NULL) { - return NULL; - } + Memarea *memarea = (Memarea *) addr; + image = createFromAddr(env, memarea->buffer, memarea->size, partially, &format); + free(memarea); + if (image == NULL) { + return NULL; + } - image_object = create_image_object(env, image, format, - get_width(image, format), get_height(image, format)); - if (image_object == NULL) { - recycle(env, image, format); - return NULL; - } else { - return image_object; - } + image_object = create_image_object(env, image, format, + get_width(image, format), get_height(image, format)); + if (image_object == NULL) { + recycle(env, image, format); + return NULL; + } else { + return image_object; + } } \ No newline at end of file