Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b221bf8e52 | ||
|
|
ab9a89685c | ||
|
|
41ccb16227 | ||
|
|
f6bf7b1ba6 | ||
|
|
09e7113df1 | ||
|
|
62a7e283a4 |
No files matched your search
@@ -54,12 +54,8 @@ Here is the libraries
|
||||
- [material-components-android](https://github.com/material-components/material-components-android)
|
||||
- [material-design-icons](https://github.com/google/material-design-icons)
|
||||
- [Apache Commons Lang](https://commons.apache.org/proper/commons-lang/)
|
||||
- [apng](http://apng.sourceforge.net/)
|
||||
- [giflib](http://giflib.sourceforge.net)
|
||||
- [greenDAO](https://github.com/greenrobot/greenDAO)
|
||||
- [jsoup](https://github.com/jhy/jsoup)
|
||||
- [libjpeg-turbo](https://libjpeg-turbo.org/)
|
||||
- [libpng](http://www.libpng.org/pub/png/libpng.html)
|
||||
- [okhttp](https://github.com/square/okhttp)
|
||||
- [roaster](https://github.com/forge/roaster)
|
||||
- [TapTargetView](https://github.com/KeepSafe/TapTargetView)
|
||||
|
||||
+2
-2
@@ -34,8 +34,8 @@ android {
|
||||
applicationId "moe.tarsin.ehviewer"
|
||||
minSdkVersion 31
|
||||
targetSdkVersion 33
|
||||
versionCode 180000
|
||||
versionName "1.8.0.0"
|
||||
versionCode 180001
|
||||
versionName "1.8.0.1"
|
||||
resConfigs 'zh', 'zh-rCN', 'zh-rHK', 'zh-rTW', 'es', 'ja', 'ko', 'fr', 'de', 'th'
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,7 @@ import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@@ -54,7 +52,7 @@ public final class Image {
|
||||
*/
|
||||
@Nullable
|
||||
public static Image decode(FileDescriptor fd, boolean partially) {
|
||||
return nativeDecode(fd, partially);
|
||||
return nativeDecode(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +60,7 @@ public final class Image {
|
||||
*/
|
||||
@Nullable
|
||||
public static Image decode(Integer fd, boolean partially) {
|
||||
return nativeDecodeFdInt(fd, partially);
|
||||
return nativeDecodeFdInt(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +68,7 @@ public final class Image {
|
||||
*/
|
||||
@Nullable
|
||||
public static Image decodeAddr(Long addr, boolean partially) {
|
||||
return nativeDecodeAddr(addr, partially);
|
||||
return nativeDecodeAddr(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,34 +87,27 @@ public final class Image {
|
||||
return sImageCount.get();
|
||||
}
|
||||
|
||||
private static native Image nativeDecode(FileDescriptor fd, boolean partially);
|
||||
private static native Image nativeDecode(FileDescriptor fd);
|
||||
|
||||
private static native Image nativeDecodeFdInt(int fd, boolean partially);
|
||||
private static native Image nativeDecodeFdInt(int fd);
|
||||
|
||||
private static native Image nativeDecodeAddr(long addr, boolean partially);
|
||||
private static native Image nativeDecodeAddr(long addr);
|
||||
|
||||
private static native Image nativeCreate(Bitmap bitmap);
|
||||
|
||||
private static native int nativeGetByteCount(long nativePtr, int format);
|
||||
|
||||
private static native void nativeRender(long nativePtr, int format,
|
||||
private static native void nativeRender(long nativePtr,
|
||||
int srcX, int srcY, Bitmap dst, int dstX, int dstY,
|
||||
int width, int height, boolean fillBlank, int defaultColor);
|
||||
int width, int height);
|
||||
|
||||
private static native void nativeTexImage(long nativePtr, int format,
|
||||
boolean init, int offsetX, int offsetY, int width, int height);
|
||||
private static native void nativeTexImage(long nativePtr, boolean init, int offsetX, int offsetY, int width, int height);
|
||||
|
||||
private static native void nativeAdvance(long nativePtr, int format);
|
||||
private static native void nativeAdvance(long nativePtr);
|
||||
|
||||
private static native int nativeGetDelay(long nativePtr, int format);
|
||||
private static native int nativeGetDelay(long nativePtr);
|
||||
|
||||
private static native boolean nativeIsOpaque(long nativePtr, int format);
|
||||
private static native boolean nativeIsOpaque(long nativePtr);
|
||||
|
||||
private static native boolean nativeIsGray(long nativePtr, int format, int error);
|
||||
|
||||
private static native void nativeClahe(long nativePtr, int format, boolean toGray);
|
||||
|
||||
private static native void nativeRecycle(long nativePtr, int format);
|
||||
private static native void nativeRecycle(long nativePtr);
|
||||
|
||||
/**
|
||||
* Return the format of the image
|
||||
@@ -139,14 +130,6 @@ public final class Image {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum number of bytes that can be used to store this image's pixels.
|
||||
*/
|
||||
public int getByteCount() {
|
||||
checkRecycled();
|
||||
return nativeGetByteCount(mNativePtr, mFormat);
|
||||
}
|
||||
|
||||
private void checkRecycled() {
|
||||
if (mNativePtr == 0) {
|
||||
if (mRecycleTracker != null) {
|
||||
@@ -163,8 +146,7 @@ public final class Image {
|
||||
public void render(int srcX, int srcY, Bitmap dst, int dstX, int dstY,
|
||||
int width, int height, boolean fillBlank, int defaultColor) {
|
||||
checkRecycled();
|
||||
nativeRender(mNativePtr, mFormat, srcX, srcY, dst, dstX, dstY,
|
||||
width, height, fillBlank, defaultColor);
|
||||
nativeRender(mNativePtr, srcX, srcY, dst, dstX, dstY, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +156,7 @@ public final class Image {
|
||||
*/
|
||||
public void texImage(boolean init, int offsetX, int offsetY, int width, int height) {
|
||||
checkRecycled();
|
||||
nativeTexImage(mNativePtr, mFormat, init, offsetX, offsetY, width, height);
|
||||
nativeTexImage(mNativePtr, init, offsetX, offsetY, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +164,7 @@ public final class Image {
|
||||
*/
|
||||
public void advance() {
|
||||
checkRecycled();
|
||||
nativeAdvance(mNativePtr, mFormat);
|
||||
nativeAdvance(mNativePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,7 +172,7 @@ public final class Image {
|
||||
*/
|
||||
public int getDelay() {
|
||||
checkRecycled();
|
||||
int delay = nativeGetDelay(mNativePtr, mFormat);
|
||||
int delay = nativeGetDelay(mNativePtr);
|
||||
return delay <= 10 ? 100 : delay;
|
||||
}
|
||||
|
||||
@@ -199,23 +181,7 @@ public final class Image {
|
||||
*/
|
||||
public boolean isOpaque() {
|
||||
checkRecycled();
|
||||
return nativeIsOpaque(mNativePtr, mFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the image is gray.
|
||||
*/
|
||||
public boolean isGray(int error) {
|
||||
checkRecycled();
|
||||
return nativeIsGray(mNativePtr, mFormat, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Improves contrast in this image with CLAHE.
|
||||
*/
|
||||
public void clahe(boolean toGray) {
|
||||
checkRecycled();
|
||||
nativeClahe(mNativePtr, mFormat, toGray);
|
||||
return nativeIsOpaque(mNativePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +191,7 @@ public final class Image {
|
||||
*/
|
||||
public void recycle() {
|
||||
if (mNativePtr != 0) {
|
||||
nativeRecycle(mNativePtr, mFormat);
|
||||
nativeRecycle(mNativePtr);
|
||||
mNativePtr = 0;
|
||||
|
||||
sImageCount.getAndDecrement();
|
||||
|
||||
@@ -45,7 +45,6 @@ public final class ImageBitmap implements Animatable, Runnable {
|
||||
private final Bitmap mBitmap;
|
||||
private final int mFormat;
|
||||
private final boolean mIsOpaque;
|
||||
private final int mByteCount;
|
||||
private final Set<WeakReference<Callback>> mCallbackSet = new LinkedHashSet<>();
|
||||
@Nullable
|
||||
private Image mImage;
|
||||
@@ -60,7 +59,6 @@ public final class ImageBitmap implements Animatable, Runnable {
|
||||
image.render(0, 0, mBitmap, 0, 0, width, height, false, 0);
|
||||
mFormat = image.getFormat();
|
||||
mIsOpaque = image.isOpaque();
|
||||
mByteCount = image.getByteCount();
|
||||
|
||||
if (mFormat == 1) {
|
||||
// For animated image, save image object
|
||||
@@ -75,7 +73,6 @@ public final class ImageBitmap implements Animatable, Runnable {
|
||||
mFormat = Image.FORMAT_NORMAL;
|
||||
mBitmap = bitmap;
|
||||
mIsOpaque = !bitmap.hasAlpha();
|
||||
mByteCount = bitmap.getRowBytes() * bitmap.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,13 +218,6 @@ public final class ImageBitmap implements Animatable, Runnable {
|
||||
return mIsOpaque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return byte count of image
|
||||
*/
|
||||
public int getByteCount() {
|
||||
return mByteCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return image is animated
|
||||
*/
|
||||
|
||||
@@ -43,21 +43,27 @@ static char *passwd = NULL;
|
||||
static void *archiveAddr = NULL;
|
||||
static jlong archiveSize = 0;
|
||||
|
||||
const char supportExt[9][6] = {
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"png",
|
||||
"gif",
|
||||
"webp",
|
||||
"bmp",
|
||||
"ico",
|
||||
"wbmp",
|
||||
"heif"
|
||||
};
|
||||
|
||||
static int filename_is_playable_file(const char *name) {
|
||||
const char *dotptr = strrchr(name, '.');
|
||||
if (dotptr++) {
|
||||
switch (*dotptr) {
|
||||
case 'j':
|
||||
return (strcmp(dotptr, "jpg") == 0) || (strcmp(dotptr, "jpeg") == 0);
|
||||
case 'p':
|
||||
return strcmp(dotptr, "png") == 0;
|
||||
case 'g':
|
||||
return strcmp(dotptr, "gif") == 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if (!dotptr++)
|
||||
return false;
|
||||
int i;
|
||||
for (i=0; i<9; i++)
|
||||
if (strcmp(dotptr, supportExt[i]) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static long archive_list_all_entries() {
|
||||
|
||||
@@ -18,8 +18,6 @@ project(image C)
|
||||
set(IMAGE_SOURCES
|
||||
image.c
|
||||
image_utils.c
|
||||
filter/clahe.c
|
||||
filter/gray.c
|
||||
java_wrapper.c
|
||||
)
|
||||
set(IMAGE_INCLUDES
|
||||
|
||||
@@ -1,186 +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.
|
||||
*/
|
||||
|
||||
#include "clahe.h"
|
||||
#include "pixel.h"
|
||||
#include "../utils.h"
|
||||
#include "../log.h"
|
||||
|
||||
#define TILE_BLOCK 8
|
||||
#define LIMIT_MULTIPLE 4
|
||||
#define CL_MAX_LOOP_NUMBER 4
|
||||
|
||||
static BYTE clamp(int 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);
|
||||
}
|
||||
} 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};
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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_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)));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +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.
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_CLAHE_H
|
||||
#define IMAGE_CLAHE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void IMAGE_clahe(void *data, int width, int height, bool to_gray);
|
||||
|
||||
#endif //IMAGE_CLAHE_H
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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 "gray.h"
|
||||
#include "pixel.h"
|
||||
|
||||
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;
|
||||
|
||||
if (e1 > error || e1 < -error
|
||||
|| e2 > error || e2 < -error
|
||||
|| e3 > error || e3 < -error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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 IMAGE_GRAY_H
|
||||
#define IMAGE_GRAY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool IMAGE_is_gray(void *data, int width, int height, int error);
|
||||
|
||||
#endif //IMAGE_GRAY_H
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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 IMAGE_PIXEL_H
|
||||
#define IMAGE_PIXEL_H
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
typedef struct {
|
||||
BYTE c1;
|
||||
BYTE c2;
|
||||
BYTE c3;
|
||||
BYTE c4;
|
||||
} PIXEL;
|
||||
|
||||
#endif //IMAGE_PIXEL_H
|
||||
@@ -14,23 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by Hippo on 12/27/2015.
|
||||
//
|
||||
|
||||
#include <android/data_space.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "image.h"
|
||||
#include "image_utils.h"
|
||||
#include "filter/clahe.h"
|
||||
#include "filter/gray.h"
|
||||
#include "log.h"
|
||||
|
||||
void decodeCommon(IMAGE *image) {
|
||||
AImageDecoder *decoder = image->decoder;
|
||||
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);
|
||||
@@ -38,155 +32,80 @@ void decodeCommon(IMAGE *image) {
|
||||
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;
|
||||
src->stride = AImageDecoder_getMinimumStride(decoder);
|
||||
image->bufferLen = image->height * src->stride;
|
||||
image->buffer = malloc(image->bufferLen);
|
||||
if (image->isAnimated) {
|
||||
AImageDecoder_setInternallyHandleDisposePrevious(decoder, false);
|
||||
image->frameInfo = AImageDecoderFrameInfo_create();
|
||||
AImageDecoder_getFrameInfo(decoder, image->frameInfo);
|
||||
src->frameInfo = AImageDecoderFrameInfo_create();
|
||||
AImageDecoder_getFrameInfo(decoder, src->frameInfo);
|
||||
}
|
||||
AImageDecoder_decodeImage(decoder, image->buffer, src->stride, image->bufferLen);
|
||||
if (!image->isAnimated) {
|
||||
recycleSource(image->src);
|
||||
image->src = NULL;
|
||||
}
|
||||
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) {
|
||||
AImageDecoder *decoder;
|
||||
int r = AImageDecoder_createFromFd(fd, &decoder);
|
||||
LOGD("%s%d", "Create ImageDecoder with ret ", r);
|
||||
if (r)
|
||||
return NULL;
|
||||
AImageDecoder_createFromFd(fd, &decoder);
|
||||
IMAGE *image = calloc(1, sizeof(IMAGE));
|
||||
image->isAnimated = *format = AImageDecoder_isAnimated(decoder);
|
||||
image->decoder = decoder;
|
||||
decodeCommon(image);
|
||||
SOURCE *src = calloc(1, sizeof(SOURCE));
|
||||
src->decoder = decoder;
|
||||
src->fd = fd;
|
||||
decodeCommon(image, src);
|
||||
return image;
|
||||
}
|
||||
|
||||
IMAGE *createFromAddr(JNIEnv *env, void *addr, long size, bool partially, int *format) {
|
||||
IMAGE *createFromAddr(JNIEnv *env, void *addr, long size) {
|
||||
AImageDecoder *decoder;
|
||||
int r = AImageDecoder_createFromBuffer((const void *) addr, size, &decoder);
|
||||
LOGD("%s%d", "Create ImageDecoder with ret ", r);
|
||||
if (r)
|
||||
return NULL;
|
||||
AImageDecoder_createFromBuffer((const void *) addr, size, &decoder);
|
||||
IMAGE *image = calloc(1, sizeof(IMAGE));
|
||||
image->isAnimated = *format = AImageDecoder_isAnimated(decoder);
|
||||
image->decoder = decoder;
|
||||
image->srcBuffer = addr;
|
||||
decodeCommon(image);
|
||||
SOURCE *src = calloc(1, sizeof(SOURCE));
|
||||
src->decoder = decoder;
|
||||
src->srcBuffer = addr;
|
||||
decodeCommon(image, src);
|
||||
return image;
|
||||
}
|
||||
|
||||
void *create(int32_t width, int32_t height, const void *data) {
|
||||
IMAGE *plain = NULL;
|
||||
IMAGE *create(int32_t width, int32_t height, const void *data) {
|
||||
IMAGE *plain = calloc(1, sizeof(IMAGE));
|
||||
void *buffer = NULL;
|
||||
size_t length;
|
||||
|
||||
plain = malloc(sizeof(IMAGE));
|
||||
if (plain == NULL) {
|
||||
WTF_OM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
length = (size_t) (width * height * 4);
|
||||
size_t length = 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;
|
||||
}
|
||||
|
||||
int get_width(IMAGE *image, int format) {
|
||||
return image->width;
|
||||
}
|
||||
|
||||
int get_height(IMAGE *image, int format) {
|
||||
return image->height;
|
||||
}
|
||||
|
||||
int get_byte_count(IMAGE *image, int format) {
|
||||
return image->bufferLen;
|
||||
}
|
||||
|
||||
void render(IMAGE *image, int format, int src_x, int src_y,
|
||||
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, bool fill_blank, int default_color) {
|
||||
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, fill_blank, default_color);
|
||||
dst_y, width, height);
|
||||
}
|
||||
|
||||
void advance(IMAGE *image, int format) {
|
||||
if (format) {
|
||||
AImageDecoder_advanceFrame(image->decoder);
|
||||
if (AImageDecoder_decodeImage(image->decoder, image->buffer, image->stride,
|
||||
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->decoder);
|
||||
AImageDecoder_decodeImage(image->decoder, image->buffer, image->stride,
|
||||
AImageDecoder_rewind(image->src->decoder);
|
||||
AImageDecoder_decodeImage(image->src->decoder, image->buffer, image->src->stride,
|
||||
image->bufferLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int get_delay(IMAGE *image, int format) {
|
||||
if (format)
|
||||
return AImageDecoderFrameInfo_getDuration(image->frameInfo) / 1000000;
|
||||
int get_delay(IMAGE *image) {
|
||||
if (image->isAnimated)
|
||||
return (int) AImageDecoderFrameInfo_getDuration(image->src->frameInfo) / 1000000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (pixel == NULL || width == 0 || height == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
get_image_data(image, format, &pixel, &width, &height);
|
||||
|
||||
if (pixel == NULL || width == 0 || height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
IMAGE_clahe(pixel, width, height, to_gray);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -14,10 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by Hippo on 12/27/2015.
|
||||
//
|
||||
|
||||
#ifndef IMAGE_IMAGE_H
|
||||
#define IMAGE_IMAGE_H
|
||||
|
||||
@@ -25,45 +21,55 @@
|
||||
#include <stdbool.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
typedef struct {
|
||||
AImageDecoder *decoder;
|
||||
void *srcBuffer;
|
||||
size_t stride;
|
||||
AImageDecoderFrameInfo *frameInfo;
|
||||
int fd;
|
||||
} SOURCE;
|
||||
|
||||
typedef struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
void *buffer;
|
||||
int bufferLen;
|
||||
AImageDecoder *decoder;
|
||||
void *srcBuffer;
|
||||
size_t stride;
|
||||
bool isAnimated;
|
||||
AImageDecoderFrameInfo *frameInfo;
|
||||
bool alpha;
|
||||
SOURCE *src;
|
||||
} IMAGE;
|
||||
|
||||
IMAGE *createFromFd(JNIEnv *env, int fd, bool partially, int *format);
|
||||
static void recycleSource(SOURCE *src) {
|
||||
if (!src)
|
||||
return;
|
||||
AImageDecoderFrameInfo_delete(src->frameInfo);
|
||||
AImageDecoder_delete(src->decoder);
|
||||
free(src->srcBuffer);
|
||||
free(src);
|
||||
}
|
||||
|
||||
IMAGE *createFromAddr(JNIEnv *env, void *addr, long size, bool partially, int *format);
|
||||
static void recycle(IMAGE *image) {
|
||||
if (!image)
|
||||
return;
|
||||
recycleSource(image->src);
|
||||
free(image->buffer);
|
||||
free(image);
|
||||
}
|
||||
|
||||
void *create(int32_t width, int32_t height, const void *data);
|
||||
IMAGE *createFromFd(JNIEnv *env, int fd);
|
||||
|
||||
int get_width(IMAGE *image, int format);
|
||||
IMAGE *createFromAddr(JNIEnv *env, void *addr, long size);
|
||||
|
||||
int get_height(IMAGE *image, int format);
|
||||
IMAGE *create(int32_t width, int32_t height, const void *data);
|
||||
|
||||
int get_byte_count(IMAGE *image, int format);
|
||||
|
||||
void render(IMAGE *image, int format, int src_x, int src_y,
|
||||
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, bool fill_blank, int default_color);
|
||||
int width, int height);
|
||||
|
||||
void advance(IMAGE *image, int format);
|
||||
void advance(IMAGE *image);
|
||||
|
||||
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);
|
||||
int get_delay(IMAGE *image);
|
||||
|
||||
#endif //IMAGE_IMAGE_H
|
||||
@@ -14,64 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by Hippo on 12/27/2015.
|
||||
//
|
||||
|
||||
#include "image_utils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LITTLE_ENDIAN 0x00
|
||||
#define BIG_ENDIAN 0x01
|
||||
|
||||
static unsigned int endian = ~0U;
|
||||
|
||||
static unsigned int get_endian() {
|
||||
unsigned int x = 1;
|
||||
|
||||
if (endian == ~0U) {
|
||||
if (1 == ((char *) &x)[0]) {
|
||||
endian = LITTLE_ENDIAN;
|
||||
} else {
|
||||
endian = BIG_ENDIAN;
|
||||
}
|
||||
}
|
||||
|
||||
return endian;
|
||||
}
|
||||
|
||||
static int convert_color(int origin) {
|
||||
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) {
|
||||
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;
|
||||
@@ -137,10 +87,6 @@ bool copy_pixels_internal(const void *src, int src_w, int src_h, int src_x, int
|
||||
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;
|
||||
@@ -151,33 +97,11 @@ bool copy_pixels_internal(const void *src, int src_w, int src_h, int src_x, int
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -17,17 +17,19 @@
|
||||
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by Hippo on 12/27/2015.
|
||||
//
|
||||
|
||||
#ifndef IMAGE_IMAGE_UTILS_H
|
||||
#define IMAGE_IMAGE_UTILS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void copy_pixels(const void *src, int src_w, int src_h, int src_x, int src_y,
|
||||
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, bool fill_blank, int default_color);
|
||||
int width, int height);
|
||||
|
||||
#define STRINGIZE(L) #L
|
||||
#define MAKESTRING(M, L) M(L)
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#endif //IMAGE_IMAGE_UTILS_H
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "java_wrapper.h"
|
||||
#include "image.h"
|
||||
#include "image_utils.h"
|
||||
#include "log.h"
|
||||
|
||||
static JavaVM *jvm;
|
||||
@@ -80,42 +81,28 @@ jobject create_image_object(JNIEnv *env, void *ptr, int format, int width, int h
|
||||
}
|
||||
|
||||
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) {
|
||||
IMAGE *image;
|
||||
|
||||
image = createFromFd(env, fd, partially, &format);
|
||||
image = createFromFd(env, fd);
|
||||
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;
|
||||
}
|
||||
return create_image_object(env, image, image->isAnimated, image->width, image->height);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_hippo_image_Image_nativeDecode(JNIEnv *env,
|
||||
jclass clazz, jobject fd, jboolean partially) {
|
||||
Java_com_hippo_image_Image_nativeDecode(JNIEnv *env, jclass clazz, jobject fd) {
|
||||
return Java_com_hippo_image_Image_nativeDecodeFdInt(env, clazz,
|
||||
jniGetFDFromFileDescriptor(env, fd),
|
||||
partially);
|
||||
jniGetFDFromFileDescriptor(env, fd));
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_hippo_image_Image_nativeCreate(JNIEnv *env,
|
||||
jclass clazz, jobject bitmap) {
|
||||
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);
|
||||
@@ -125,35 +112,14 @@ Java_com_hippo_image_Image_nativeCreate(JNIEnv *env,
|
||||
}
|
||||
|
||||
image = create(info.width, info.height, pixels);
|
||||
|
||||
AndroidBitmap_unlockPixels(env, bitmap);
|
||||
|
||||
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 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);
|
||||
return create_image_object(env, image, 0, info.width, info.height);
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
|
||||
@@ -164,82 +130,52 @@ Java_com_hippo_image_Image_nativeRender(JNIEnv *env,
|
||||
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);
|
||||
render((IMAGE *) ptr, src_x, src_y, pixels, info.width, info.height, dst_x, dst_y, width,
|
||||
height);
|
||||
|
||||
AndroidBitmap_unlockPixels(env, dst);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_image_Image_nativeTexImage(JNIEnv *env,
|
||||
jclass clazz, jlong ptr, jint format, jboolean init,
|
||||
Java_com_hippo_image_Image_nativeTexImage(JNIEnv *env, jclass clazz, jlong ptr, jboolean init,
|
||||
jint src_x, jint src_y, jint width, jint height) {
|
||||
// Check tile_buffer NULL
|
||||
if (NULL == tile_buffer) {
|
||||
if (width * height > IMAGE_TILE_MAX_SIZE)
|
||||
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((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);
|
||||
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);
|
||||
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) {
|
||||
advance((IMAGE *) ptr);
|
||||
}
|
||||
|
||||
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) {
|
||||
return get_delay((IMAGE *) ptr);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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_nativeIsOpaque(JNIEnv *env, jclass clazz, jlong ptr) {
|
||||
return ((IMAGE *) ptr)->alpha;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
recycle((IMAGE *) ptr);
|
||||
}
|
||||
|
||||
bool image_onLoad(JavaVM *vm) {
|
||||
jvm = vm;
|
||||
|
||||
tile_buffer = malloc(IMAGE_TILE_MAX_SIZE * 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -249,31 +185,10 @@ JNI_OnUnload(JavaVM *vm, void *reserved) {
|
||||
tile_buffer = NULL;
|
||||
}
|
||||
|
||||
typedef struct Memarea {
|
||||
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;
|
||||
|
||||
Java_com_hippo_image_Image_nativeDecodeAddr(JNIEnv *env, jclass clazz, jlong addr) {
|
||||
Memarea *memarea = (Memarea *) addr;
|
||||
image = createFromAddr(env, memarea->buffer, memarea->size, partially, &format);
|
||||
IMAGE *image = createFromAddr(env, memarea->buffer, memarea->size);
|
||||
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;
|
||||
}
|
||||
}
|
||||
return create_image_object(env, image, image->isAnimated, image->width, image->height);
|
||||
}
|
||||
@@ -17,10 +17,6 @@
|
||||
* EhViewer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by Hippo on 12/28/2015.
|
||||
//
|
||||
|
||||
#ifndef IMAGE_JAVA_WRAPPER_H
|
||||
#define IMAGE_JAVA_WRAPPER_H
|
||||
|
||||
@@ -29,6 +25,11 @@
|
||||
|
||||
#define IMAGE_TILE_MAX_SIZE (512 * 512)
|
||||
|
||||
typedef struct Memarea {
|
||||
void *buffer;
|
||||
long size;
|
||||
} Memarea;
|
||||
|
||||
bool image_onLoad(JavaVM *vm);
|
||||
|
||||
JNIEnv *obtain_env(bool *attach);
|
||||
|
||||
@@ -14,18 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by Hippo on 10/19/2015.
|
||||
//
|
||||
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define TAG "Image"
|
||||
#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__)
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
//
|
||||
// Created by Hippo on 12/29/2015.
|
||||
//
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#define STRINGIZE(L) #L
|
||||
#define MAKESTRING(M, L) M(L)
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#endif // UTILS_H
|
||||
Reference in new issue
Block a user