From d94b96a8ebd642b69639f6ca9fb40450dd320487 Mon Sep 17 00:00:00 2001 From: tarsin Date: Thu, 4 Aug 2022 13:05:47 +0800 Subject: [PATCH] Clean up --- app/src/main/cpp/CMakeLists.txt | 9 +- app/src/main/cpp/image.c | 380 ++++++++++++++++++ .../cpp/{image/java_wrapper.h => image.h} | 13 +- app/src/main/cpp/image/CMakeLists.txt | 34 -- app/src/main/cpp/image/image.c | 112 ------ app/src/main/cpp/image/image.h | 72 ---- app/src/main/cpp/image/image_utils.c | 107 ----- app/src/main/cpp/image/image_utils.h | 29 -- app/src/main/cpp/image/java_wrapper.c | 152 ------- app/src/main/cpp/image/log.h | 30 -- app/src/main/cpp/main.c | 2 +- 11 files changed, 387 insertions(+), 553 deletions(-) create mode 100644 app/src/main/cpp/image.c rename app/src/main/cpp/{image/java_wrapper.h => image.h} (79%) delete mode 100644 app/src/main/cpp/image/CMakeLists.txt delete mode 100644 app/src/main/cpp/image/image.c delete mode 100644 app/src/main/cpp/image/image.h delete mode 100644 app/src/main/cpp/image/image_utils.c delete mode 100644 app/src/main/cpp/image/image_utils.h delete mode 100644 app/src/main/cpp/image/java_wrapper.c delete mode 100644 app/src/main/cpp/image/log.h diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index 19612537a..4f24abfd8 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -44,10 +44,7 @@ SET(LIBARCHIVE_CUSTOM_LIBS "liblzma" "nettle") # Build libarchive add_subdirectory(libarchive) -# Build hippo's image lib -add_subdirectory(image) - # Build and link our app's native lib -add_library(${PROJECT_NAME} SHARED main.c archive.c) -target_include_directories(${PROJECT_NAME} PUBLIC image/image libarchive/libarchive) -target_link_libraries(${PROJECT_NAME} image archive_static -Wl,--gc-sections) +add_library(${PROJECT_NAME} SHARED main.c archive.c image.c) +target_include_directories(${PROJECT_NAME} PUBLIC libarchive/libarchive) +target_link_libraries(${PROJECT_NAME} archive_static log jnigraphics GLESv2 -Wl,--gc-sections) diff --git a/app/src/main/cpp/image.c b/app/src/main/cpp/image.c new file mode 100644 index 000000000..71a6aae72 --- /dev/null +++ b/app/src/main/cpp/image.c @@ -0,0 +1,380 @@ +/* + * Copyright 2022 Tarsin Norbin + * + * This file is part of EhViewer + * + * EhViewer is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * EhViewer 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 for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * EhViewer. If not, see . + */ + +#include +#include + +#include +#include +#include + +#include + +#include "image.h" + +#define TAG "ImageDecoder_wrapper" +#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG ,__VA_ARGS__) +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG ,__VA_ARGS__) +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG ,__VA_ARGS__) +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG ,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG ,__VA_ARGS__) +#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, TAG ,__VA_ARGS__) + +#define IMAGE_TILE_MAX_SIZE (512 * 512) + +static void *tile_buffer = NULL; + +bool image_onLoad() { + tile_buffer = malloc(IMAGE_TILE_MAX_SIZE * 4); + return tile_buffer != NULL; +} + +void image_onUnload() { + free(tile_buffer); + tile_buffer = NULL; +} + +typedef struct { + AImageDecoder *decoder; + void *srcBuffer; + size_t stride; + int fd; +} SOURCE; + +typedef struct { + int32_t width; + int32_t height; + void *buffer; + int bufferLen; + bool isAnimated; + bool alpha; + int delay; + SOURCE *src; +} IMAGE; + +static void recycleSource(SOURCE *src) { + if (!src) + return; + AImageDecoder_delete(src->decoder); + free(src->srcBuffer); + free(src); +} + +static void recycle(IMAGE *image) { + if (!image) + return; + recycleSource(image->src); + free(image->buffer); + free(image); +} + +typedef struct Memarea { + void *buffer; + long size; +} Memarea; + +bool 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) { + 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; + + // First line + dst_pos += (int)dst_blank_length; + memcpy(dst + dst_pos, src + src_pos, line_stride); + dst_pos += (int)line_stride; + src_pos += src_stride; + + // Other lines + dst_blank_length = (size_t) ((dst_w - width) * 4); + for (line = 1; line < height; line++) { + dst_pos += (int)dst_blank_length; + memcpy(dst + dst_pos, src + src_pos, line_stride); + dst_pos += (int)line_stride; + src_pos += src_stride; + } + + return true; +} + +void decodeCommon(IMAGE *image, SOURCE *src) { + image->src = src; + AImageDecoder *decoder = src->decoder; + image->isAnimated = AImageDecoder_isAnimated(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; + src->stride = AImageDecoder_getMinimumStride(decoder); + image->bufferLen = (int) (image->height * src->stride); + image->buffer = malloc(image->bufferLen); + if (image->isAnimated) { + AImageDecoder_setInternallyHandleDisposePrevious(decoder, false); + AImageDecoderFrameInfo *frameInfo = AImageDecoderFrameInfo_create(); + AImageDecoder_getFrameInfo(decoder, frameInfo); + image->delay = (int) AImageDecoderFrameInfo_getDuration(frameInfo) / 1000000; + AImageDecoderFrameInfo_delete(frameInfo); + } + AImageDecoder_decodeImage(decoder, image->buffer, src->stride, image->bufferLen); + if (!image->isAnimated) { + recycleSource(image->src); + image->src = NULL; + } +} + +IMAGE *createFromFd(int fd) { + AImageDecoder *decoder = NULL; + if (AImageDecoder_createFromFd(fd, &decoder) != ANDROID_IMAGE_DECODER_SUCCESS) + return NULL; + IMAGE *image = calloc(1, sizeof(IMAGE)); + SOURCE *src = calloc(1, sizeof(SOURCE)); + src->decoder = decoder; + src->fd = fd; + decodeCommon(image, src); + return image; +} + +IMAGE *createFromAddr(void *addr, long size) { + AImageDecoder *decoder; + AImageDecoder_createFromBuffer((const void *) addr, size, &decoder); + IMAGE *image = calloc(1, sizeof(IMAGE)); + SOURCE *src = calloc(1, sizeof(SOURCE)); + src->decoder = decoder; + src->srcBuffer = addr; + decodeCommon(image, src); + return image; +} + +IMAGE *create(int32_t width, int32_t height, const void *data) { + IMAGE *plain = calloc(1, sizeof(IMAGE)); + void *buffer = NULL; + size_t length = width * height * 4; + + buffer = malloc(length); + memcpy(buffer, data, length); + + // plain->isAnimated = false; this is unnecessary since we use calloc + plain->width = width; + plain->height = height; + plain->buffer = buffer; + plain->bufferLen = (int) length; + + return plain; +} + +void render(IMAGE *image, int src_x, int src_y, + void *dst, int dst_w, int dst_h, int dst_x, int dst_y, + int width, int height) { + copy_pixels(image->buffer, image->width, image->height, src_x, src_y, dst, dst_w, dst_h, dst_x, + dst_y, width, height); +} + +void advance(IMAGE *image) { + if (image->isAnimated) { + AImageDecoder_advanceFrame(image->src->decoder); + if (AImageDecoder_decodeImage(image->src->decoder, image->buffer, image->src->stride, + image->bufferLen) == ANDROID_IMAGE_DECODER_FINISHED) { + AImageDecoder_rewind(image->src->decoder); + AImageDecoder_decodeImage(image->src->decoder, image->buffer, image->src->stride, + image->bufferLen); + } + } +} + +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); + } + } + + return fd; +} + +JNIEXPORT jlong JNICALL +Java_com_hippo_image_Image_nativeDecodeFdInt(JNIEnv *env, jclass clazz, jint fd) { + IMAGE *image = createFromFd(fd); + return (jlong) image; +} + +JNIEXPORT jlong JNICALL +Java_com_hippo_image_Image_nativeDecode(JNIEnv *env, jclass clazz, jobject fd) { + return Java_com_hippo_image_Image_nativeDecodeFdInt(env, clazz, + jniGetFDFromFileDescriptor(env, fd)); +} + +JNIEXPORT jlong JNICALL +Java_com_hippo_image_Image_nativeCreate(JNIEnv *env, jclass clazz, jobject bitmap) { + AndroidBitmapInfo info; + void *pixels = NULL; + void *image = NULL; + + AndroidBitmap_getInfo(env, bitmap, &info); + AndroidBitmap_lockPixels(env, bitmap, &pixels); + + image = create((int)info.width, (int)info.height, pixels); + AndroidBitmap_unlockPixels(env, bitmap); + return (jlong) image; +} + +JNIEXPORT void JNICALL +Java_com_hippo_image_Image_nativeRender(JNIEnv *env, jclass clazz, jlong ptr, jint src_x, + jint src_y, jobject dst, jint dst_x, jint dst_y, jint width, + jint height) { + AndroidBitmapInfo info; + void *pixels = NULL; + + AndroidBitmap_getInfo(env, dst, &info); + AndroidBitmap_lockPixels(env, dst, &pixels); + + render((IMAGE *) ptr, src_x, src_y, pixels, (int)info.width, (int)info.height, dst_x, dst_y, width, + height); + + AndroidBitmap_unlockPixels(env, dst); +} + +JNIEXPORT void JNICALL +Java_com_hippo_image_Image_nativeTexImage(JNIEnv *env, jclass clazz, jlong ptr, jboolean init, + jint src_x, jint src_y, jint width, jint height) { + if (width * height > IMAGE_TILE_MAX_SIZE) + return; + + render((IMAGE *) ptr, src_x, src_y, tile_buffer, width, height, 0, 0, width, height); + + 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) { + advance((IMAGE *) ptr); +} + +JNIEXPORT jint JNICALL +Java_com_hippo_image_Image_nativeGetDelay(JNIEnv *env, jclass clazz, jlong ptr) { + return ((IMAGE *) ptr)->delay; +} + +JNIEXPORT jboolean JNICALL +Java_com_hippo_image_Image_nativeIsOpaque(JNIEnv *env, jclass clazz, jlong ptr) { + return ((IMAGE *) ptr)->alpha; +} + +JNIEXPORT void JNICALL +Java_com_hippo_image_Image_nativeRecycle(JNIEnv *env, jclass clazz, jlong ptr) { + recycle((IMAGE *) ptr); +} + +JNIEXPORT jlong JNICALL +Java_com_hippo_image_Image_nativeDecodeAddr(JNIEnv *env, jclass clazz, jlong addr) { + Memarea *memarea = (Memarea *) addr; + IMAGE *image = createFromAddr(memarea->buffer, memarea->size); + free(memarea); + return (jlong) image; +} + +JNIEXPORT jint JNICALL +Java_com_hippo_image_Image_nativeGetFormat(JNIEnv *env, jclass clazz, jlong native_ptr) { + return ((IMAGE *) native_ptr)->isAnimated; +} + +JNIEXPORT jint JNICALL +Java_com_hippo_image_Image_nativeGetWidth(JNIEnv *env, jclass clazz, jlong native_ptr) { + return ((IMAGE *) native_ptr)->width; +} + +JNIEXPORT jint JNICALL +Java_com_hippo_image_Image_nativeGetHeight(JNIEnv *env, jclass clazz, jlong native_ptr) { + return ((IMAGE *) native_ptr)->height; +} diff --git a/app/src/main/cpp/image/java_wrapper.h b/app/src/main/cpp/image.h similarity index 79% rename from app/src/main/cpp/image/java_wrapper.h rename to app/src/main/cpp/image.h index a8b7a267f..fe5dcc63a 100644 --- a/app/src/main/cpp/image/java_wrapper.h +++ b/app/src/main/cpp/image.h @@ -17,20 +17,13 @@ * EhViewer. If not, see . */ -#ifndef IMAGE_JAVA_WRAPPER_H -#define IMAGE_JAVA_WRAPPER_H +#ifndef IMAGE_IMAGE_H +#define IMAGE_IMAGE_H #include -#define IMAGE_TILE_MAX_SIZE (512 * 512) - -typedef struct Memarea { - void *buffer; - long size; -} Memarea; - bool image_onLoad(); void image_onUnload(); -#endif /* IMAGE_JAVA_WRAPPER_H */ +#endif /* IMAGE_IMAGE_H */ diff --git a/app/src/main/cpp/image/CMakeLists.txt b/app/src/main/cpp/image/CMakeLists.txt deleted file mode 100644 index 4adce6dc6..000000000 --- a/app/src/main/cpp/image/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2018 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. - -cmake_minimum_required(VERSION 3.4.1) -project(image C) - -set(IMAGE_SOURCES - image.c - image_utils.c - java_wrapper.c - ) -set(IMAGE_INCLUDES - ${CMAKE_CURRENT_SOURCE_DIR} - ) -set(IMAGE_LIBRARIES - log - jnigraphics - GLESv2 - ) - -add_library(image STATIC ${IMAGE_SOURCES}) -target_include_directories(image PRIVATE ${IMAGE_INCLUDES}) -target_link_libraries(image PRIVATE ${IMAGE_LIBRARIES}) \ No newline at end of file diff --git a/app/src/main/cpp/image/image.c b/app/src/main/cpp/image/image.c deleted file mode 100644 index 219560b46..000000000 --- a/app/src/main/cpp/image/image.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2022 Tarsin Norbin - * - * This file is part of EhViewer - * - * EhViewer is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * EhViewer 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 for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * EhViewer. If not, see . - */ - -#include -#include -#include - -#include "image.h" -#include "image_utils.h" - -void decodeCommon(IMAGE *image, SOURCE *src) { - image->src = src; - AImageDecoder *decoder = src->decoder; - image->isAnimated = AImageDecoder_isAnimated(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; - src->stride = AImageDecoder_getMinimumStride(decoder); - image->bufferLen = (int) (image->height * src->stride); - image->buffer = malloc(image->bufferLen); - if (image->isAnimated) { - AImageDecoder_setInternallyHandleDisposePrevious(decoder, false); - AImageDecoderFrameInfo *frameInfo = AImageDecoderFrameInfo_create(); - AImageDecoder_getFrameInfo(decoder, frameInfo); - image->delay = (int) AImageDecoderFrameInfo_getDuration(frameInfo) / 1000000; - AImageDecoderFrameInfo_delete(frameInfo); - } - AImageDecoder_decodeImage(decoder, image->buffer, src->stride, image->bufferLen); - if (!image->isAnimated) { - recycleSource(image->src); - image->src = NULL; - } -} - -IMAGE *createFromFd(int fd) { - AImageDecoder *decoder = NULL; - if (AImageDecoder_createFromFd(fd, &decoder) != ANDROID_IMAGE_DECODER_SUCCESS) - return NULL; - IMAGE *image = calloc(1, sizeof(IMAGE)); - SOURCE *src = calloc(1, sizeof(SOURCE)); - src->decoder = decoder; - src->fd = fd; - decodeCommon(image, src); - return image; -} - -IMAGE *createFromAddr(void *addr, long size) { - AImageDecoder *decoder; - AImageDecoder_createFromBuffer((const void *) addr, size, &decoder); - IMAGE *image = calloc(1, sizeof(IMAGE)); - SOURCE *src = calloc(1, sizeof(SOURCE)); - src->decoder = decoder; - src->srcBuffer = addr; - decodeCommon(image, src); - return image; -} - -IMAGE *create(int32_t width, int32_t height, const void *data) { - IMAGE *plain = calloc(1, sizeof(IMAGE)); - void *buffer = NULL; - size_t length = width * height * 4; - - buffer = malloc(length); - memcpy(buffer, data, length); - - // plain->isAnimated = false; this is unnecessary since we use calloc - plain->width = width; - plain->height = height; - plain->buffer = buffer; - plain->bufferLen = (int) length; - - return plain; -} - -void render(IMAGE *image, int src_x, int src_y, - void *dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height) { - copy_pixels(image->buffer, image->width, image->height, src_x, src_y, dst, dst_w, dst_h, dst_x, - dst_y, width, height); -} - -void advance(IMAGE *image) { - if (image->isAnimated) { - AImageDecoder_advanceFrame(image->src->decoder); - if (AImageDecoder_decodeImage(image->src->decoder, image->buffer, image->src->stride, - image->bufferLen) == ANDROID_IMAGE_DECODER_FINISHED) { - AImageDecoder_rewind(image->src->decoder); - AImageDecoder_decodeImage(image->src->decoder, image->buffer, image->src->stride, - image->bufferLen); - } - } -} diff --git a/app/src/main/cpp/image/image.h b/app/src/main/cpp/image/image.h deleted file mode 100644 index 17258e360..000000000 --- a/app/src/main/cpp/image/image.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2022 Tarsin Norbin - * - * This file is part of EhViewer - * - * EhViewer is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * EhViewer 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 for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * EhViewer. If not, see . - */ - -#ifndef IMAGE_IMAGE_H -#define IMAGE_IMAGE_H - -#include -#include - -typedef struct { - AImageDecoder *decoder; - void *srcBuffer; - size_t stride; - int fd; -} SOURCE; - -typedef struct { - int32_t width; - int32_t height; - void *buffer; - int bufferLen; - bool isAnimated; - bool alpha; - int delay; - SOURCE *src; -} IMAGE; - -static void recycleSource(SOURCE *src) { - if (!src) - return; - AImageDecoder_delete(src->decoder); - free(src->srcBuffer); - free(src); -} - -static void recycle(IMAGE *image) { - if (!image) - return; - recycleSource(image->src); - free(image->buffer); - free(image); -} - -IMAGE *createFromFd(int fd); - -IMAGE *createFromAddr(void *addr, long size); - -IMAGE *create(int32_t width, int32_t height, const void *data); - -void render(IMAGE *image, int src_x, int src_y, - void *dst, int dst_w, int dst_h, int dst_x, int dst_y, - int width, int height); - -void advance(IMAGE *image); - -#endif /* IMAGE_IMAGE_H */ diff --git a/app/src/main/cpp/image/image_utils.c b/app/src/main/cpp/image/image_utils.c deleted file mode 100644 index 7b39308be..000000000 --- a/app/src/main/cpp/image/image_utils.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2015 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 "image_utils.h" - -#include -#include - -bool 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) { - 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; - - // 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++) { - dst_pos += dst_blank_length; - memcpy(dst + dst_pos, src + src_pos, line_stride); - dst_pos += line_stride; - src_pos += src_stride; - } - - return true; -} diff --git a/app/src/main/cpp/image/image_utils.h b/app/src/main/cpp/image/image_utils.h deleted file mode 100644 index fe4f6df76..000000000 --- a/app/src/main/cpp/image/image_utils.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2022 Tarsin Norbin - * - * This file is part of EhViewer - * - * EhViewer is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * EhViewer 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 for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * EhViewer. If not, see . - */ - -#ifndef IMAGE_IMAGE_UTILS_H -#define IMAGE_IMAGE_UTILS_H - -#include - -bool 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); - -#endif /* IMAGE_IMAGE_UTILS_H */ diff --git a/app/src/main/cpp/image/java_wrapper.c b/app/src/main/cpp/image/java_wrapper.c deleted file mode 100644 index 61010dce6..000000000 --- a/app/src/main/cpp/image/java_wrapper.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2015 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 -#include - -#include "java_wrapper.h" -#include "image.h" -#include "log.h" - -static void *tile_buffer = NULL; - -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); - } - } - - return fd; -} - -JNIEXPORT jlong JNICALL -Java_com_hippo_image_Image_nativeDecodeFdInt(JNIEnv *env, jclass clazz, jint fd) { - IMAGE *image = createFromFd(fd); - return (jlong) image; -} - -JNIEXPORT jlong JNICALL -Java_com_hippo_image_Image_nativeDecode(JNIEnv *env, jclass clazz, jobject fd) { - return Java_com_hippo_image_Image_nativeDecodeFdInt(env, clazz, - jniGetFDFromFileDescriptor(env, fd)); -} - -JNIEXPORT jlong JNICALL -Java_com_hippo_image_Image_nativeCreate(JNIEnv *env, jclass clazz, jobject bitmap) { - AndroidBitmapInfo info; - void *pixels = NULL; - void *image = NULL; - - AndroidBitmap_getInfo(env, bitmap, &info); - AndroidBitmap_lockPixels(env, bitmap, &pixels); - - image = create(info.width, info.height, pixels); - AndroidBitmap_unlockPixels(env, bitmap); - return (jlong) image; -} - -JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeRender(JNIEnv *env, jclass clazz, jlong ptr, jint src_x, - jint src_y, jobject dst, jint dst_x, jint dst_y, jint width, - jint height) { - AndroidBitmapInfo info; - void *pixels = NULL; - - AndroidBitmap_getInfo(env, dst, &info); - AndroidBitmap_lockPixels(env, dst, &pixels); - - render((IMAGE *) ptr, src_x, src_y, pixels, info.width, info.height, dst_x, dst_y, width, - height); - - AndroidBitmap_unlockPixels(env, dst); -} - -JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeTexImage(JNIEnv *env, jclass clazz, jlong ptr, jboolean init, - jint src_x, jint src_y, jint width, jint height) { - if (width * height > IMAGE_TILE_MAX_SIZE) - return; - - render((IMAGE *) ptr, src_x, src_y, tile_buffer, width, height, 0, 0, width, height); - - 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) { - advance((IMAGE *) ptr); -} - -JNIEXPORT jint JNICALL -Java_com_hippo_image_Image_nativeGetDelay(JNIEnv *env, jclass clazz, jlong ptr) { - return ((IMAGE *) ptr)->delay; -} - -JNIEXPORT jboolean JNICALL -Java_com_hippo_image_Image_nativeIsOpaque(JNIEnv *env, jclass clazz, jlong ptr) { - return ((IMAGE *) ptr)->alpha; -} - -JNIEXPORT void JNICALL -Java_com_hippo_image_Image_nativeRecycle(JNIEnv *env, jclass clazz, jlong ptr) { - recycle((IMAGE *) ptr); -} - -bool image_onLoad() { - tile_buffer = malloc(IMAGE_TILE_MAX_SIZE * 4); - return tile_buffer != NULL; -} - -void image_onUnload() { - free(tile_buffer); - tile_buffer = NULL; -} - -JNIEXPORT jlong JNICALL -Java_com_hippo_image_Image_nativeDecodeAddr(JNIEnv *env, jclass clazz, jlong addr) { - Memarea *memarea = (Memarea *) addr; - IMAGE *image = createFromAddr(memarea->buffer, memarea->size); - free(memarea); - return (jlong) image; -} - -JNIEXPORT jint JNICALL -Java_com_hippo_image_Image_nativeGetFormat(JNIEnv *env, jclass clazz, jlong native_ptr) { - return ((IMAGE *) native_ptr)->isAnimated; -} - -JNIEXPORT jint JNICALL -Java_com_hippo_image_Image_nativeGetWidth(JNIEnv *env, jclass clazz, jlong native_ptr) { - return ((IMAGE *) native_ptr)->width; -} - -JNIEXPORT jint JNICALL -Java_com_hippo_image_Image_nativeGetHeight(JNIEnv *env, jclass clazz, jlong native_ptr) { - return ((IMAGE *) native_ptr)->height; -} diff --git a/app/src/main/cpp/image/log.h b/app/src/main/cpp/image/log.h deleted file mode 100644 index 0f52e28bb..000000000 --- a/app/src/main/cpp/image/log.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2015 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. - */ - -#ifndef LOG_H -#define LOG_H - -#include - -#define TAG "ImageDecoder_wrapper" -#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG ,__VA_ARGS__) -#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG ,__VA_ARGS__) -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG ,__VA_ARGS__) -#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG ,__VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG ,__VA_ARGS__) -#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, TAG ,__VA_ARGS__) - -#endif /* LOG_H */ diff --git a/app/src/main/cpp/main.c b/app/src/main/cpp/main.c index b8124f906..cc540335a 100644 --- a/app/src/main/cpp/main.c +++ b/app/src/main/cpp/main.c @@ -23,7 +23,7 @@ #include #include -#include "image/java_wrapper.h" +#include "image.h" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env;