Imagedecoder do not support anon pipe, drop it and use memarea
This commit is contained in:
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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user