Imagedecoder do not support anon pipe, drop it and use memarea

This commit is contained in:
tarsin committed 2022-07-24 23:32:03 +08:00
1 parent 3a05649c71
commit 50c6111773
7 files changed
+87 -30

No files matched your search

@@ -53,7 +53,7 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
private final UriArchiveAccessor archiveAccessor;
private final Stack<Integer> requests = new Stack<>();
private final AtomicInteger extractingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX);
private final LinkedHashMap<Integer, FileDescriptor> streams = new LinkedHashMap<>();
private final LinkedHashMap<Integer, Long> streams = new LinkedHashMap<>();
private final AtomicInteger decodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX);
private Thread archiveThread;
private Thread decodeThread;
@@ -253,22 +253,14 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
continue;
}
Pipe pipe = new Pipe();
synchronized (streams) {
if (streams.get(index) != null) {
continue;
}
try {
streams.put(index, ((FileInputStream)pipe.getInputStream()).getFD());
} catch (IOException e) {
e.printStackTrace();
}
long addr = archiveAccessor.extracttoOutputStream(index);
streams.put(index, addr);
streams.notify();
}
archiveAccessor.extracttoOutputStream(index, pipe.getOutputFd());
pipe.closeOutputFd();
}
}
}
@@ -278,7 +270,7 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
int index;
FileDescriptor fd;
Long addr;
synchronized (streams) {
if (streams.isEmpty()) {
try {
@@ -290,16 +282,16 @@ public class ArchiveGalleryProvider extends GalleryProvider2 {
continue;
}
Iterator<Map.Entry<Integer, FileDescriptor>> iterator = streams.entrySet().iterator();
Map.Entry<Integer, FileDescriptor> entry = iterator.next();
Iterator<Map.Entry<Integer, Long>> iterator = streams.entrySet().iterator();
Map.Entry<Integer, Long> entry = iterator.next();
iterator.remove();
index = entry.getKey();
fd = entry.getValue();
addr = entry.getValue();
decodingIndex.lazySet(index);
}
try {
Image image = Image.decode(fd, true);
Image image = Image.decodeAddr(addr, true);
if (image != null) {
notifyPageSucceed(index, image);
} else {
@@ -47,7 +47,7 @@ public class UriArchiveAccessor {
private native int openArchive(long addr, long size);
public native void extracttoOutputStream(int index, int fd);
public native long extracttoOutputStream(int index);
public native boolean needPassword();
@@ -65,6 +65,14 @@ public final class Image {
return nativeDecodeFdInt(fd, partially);
}
/**
* Decode image from {@code InputStream}
*/
@Nullable
public static Image decodeAddr(Long addr, boolean partially) {
return nativeDecodeAddr(addr, partially);
}
/**
* Create a plain image from Bitmap
*/
@@ -85,6 +93,8 @@ public final class Image {
private static native Image nativeDecodeFdInt(int fd, boolean partially);
private static native Image nativeDecodeAddr(long addr, boolean partially);
private static native Image nativeCreate(Bitmap bitmap);
private static native int nativeGetByteCount(long nativePtr, int format);
+14 -12
View File
@@ -121,35 +121,37 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *_, jobject thiz, jlong add
return r;
}
JNIEXPORT void JNICALL
Java_com_hippo_UriArchiveAccessor_extracttoOutputStream(JNIEnv *_, jobject thiz, jint index,
jint fd) {
typedef struct Memarea {
void* buffer;
long size;
} Memarea;
JNIEXPORT jlong JNICALL
Java_com_hippo_UriArchiveAccessor_extracttoOutputStream(JNIEnv *_, jobject thiz, jint index) {
struct archive_entry *entry;
size_t size;
int ret;
la_int64_t offset;
const void *buff;
if (!arc || index < cur_index) {
archive_alloc();
cur_index = 0;
}
Memarea* memarea = malloc(sizeof(Memarea));
while (archive_read_next_header(arc, &entry) == ARCHIVE_OK) {
if (!filename_is_playable_file(archive_entry_pathname(entry)))
continue;
if (cur_index++ == index) {
memarea->size = archive_entry_size(entry);
memarea->buffer = malloc(memarea->size);
for (;;) {
ret = archive_read_data_block(arc, &buff, &size, &offset);
if (ret == ARCHIVE_EOF)
break;
if (ret != ARCHIVE_OK) {
ret = archive_read_data(arc, memarea->buffer, memarea->size);
if (ret < 0) {
LOGE("%s%s", "Archive read failed:", archive_error_string(arc));
break;
}
write(fd, buff, size);
break;
}
break;
}
}
return (jlong) memarea;
}
JNIEXPORT void JNICALL
+23 -1
View File
@@ -39,7 +39,7 @@ void* decode(JNIEnv* env, int fd, bool partially, int* format)
*format = AImageDecoder_isAnimated(decoder);
const AImageDecoderHeaderInfo *headerInfo = AImageDecoder_getHeaderInfo(decoder);
size_t stride = AImageDecoder_getMinimumStride(decoder);
IMAGE *image = malloc(sizeof(IMAGE));
IMAGE *image = calloc(1, sizeof(IMAGE));
image->height = AImageDecoderHeaderInfo_getHeight(headerInfo);
image->width = AImageDecoderHeaderInfo_getWidth(headerInfo);
image->decoder = decoder;
@@ -49,6 +49,27 @@ void* decode(JNIEnv* env, int fd, bool partially, int* format)
return image;
}
void* decodeAddr(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);
if (r)
return NULL;
*format = AImageDecoder_isAnimated(decoder);
const AImageDecoderHeaderInfo *headerInfo = AImageDecoder_getHeaderInfo(decoder);
size_t stride = AImageDecoder_getMinimumStride(decoder);
IMAGE *image = calloc(1, sizeof(IMAGE));
image->height = AImageDecoderHeaderInfo_getHeight(headerInfo);
image->width = AImageDecoderHeaderInfo_getWidth(headerInfo);
image->decoder = decoder;
image->bufferLen = image->height * stride;
image->buffer = malloc(image->bufferLen);
image->srcBuffer = addr;
AImageDecoder_decodeImage(decoder, image->buffer, stride, image->bufferLen);
return image;
}
void* create(int32_t width, int32_t height, const void* data)
{
return PLAIN_create(width, height, data);
@@ -149,5 +170,6 @@ void recycle(JNIEnv *env, IMAGE* image, int format)
free(image->buffer);
image->buffer = NULL;
AImageDecoder_delete(image->decoder);
free(image->srcBuffer);
free(image);
}
+2
View File
@@ -32,9 +32,11 @@ typedef struct
void* buffer;
int bufferLen;
AImageDecoder* decoder;
void* srcBuffer;
} IMAGE;
void* decode(JNIEnv* env, int fd, bool partially, int* format);
void* decodeAddr(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);
+29
View File
@@ -282,3 +282,32 @@ JNI_OnUnload(JavaVM *vm, void *reserved)
free(tile_buffer);
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;
Memarea *memarea = (Memarea*)addr;
image = decodeAddr(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;
}
}