-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from oupson/31-library-load-images-from-inputs…
…tream-instead-of-byte-array Library - Load images from inputstream instead of byte array
- Loading branch information
Showing
7 changed files
with
322 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// | ||
// Created by oupso on 04/01/2024. | ||
// | ||
|
||
#ifndef JXLVIEWER_FILEDESCRIPTORINPUTSOURCE_H | ||
#define JXLVIEWER_FILEDESCRIPTORINPUTSOURCE_H | ||
|
||
#include "InputSource.h" | ||
#include <unistd.h> | ||
|
||
inline int32_t readWithErrorHandling(JNIEnv *env, int fd, uint8_t *buffer, size_t size); | ||
|
||
class FileDescriptorInputSource : public InputSource { | ||
public: | ||
FileDescriptorInputSource(JNIEnv *env, int fd) : env(env), fd(fd) { | ||
|
||
} | ||
|
||
virtual int32_t read(uint8_t *buffer, size_t size) { | ||
return readWithErrorHandling(this->env, this->fd, buffer, size); | ||
} | ||
|
||
private: | ||
JNIEnv *env; | ||
int fd; | ||
}; | ||
|
||
inline int32_t readWithErrorHandling(JNIEnv *env, int fd, uint8_t *buffer, size_t size) { | ||
auto n = read(fd, buffer, size); | ||
if (n > 0) { | ||
return n; | ||
} else if (n == 0) { | ||
return -1; | ||
} else { | ||
auto error = strerror(errno); | ||
jxlviewer::throwNewError(env, "java/io/IOException", error); | ||
return INT32_MIN; | ||
} | ||
} | ||
|
||
#endif //JXLVIEWER_FILEDESCRIPTORINPUTSOURCE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// Created by oupso on 04/01/2024. | ||
// | ||
|
||
#ifndef JXLVIEWER_INPUTSOURCE_H | ||
#define JXLVIEWER_INPUTSOURCE_H | ||
|
||
/** | ||
* @class InputSource | ||
* @brief Abstraction over an input source. | ||
* | ||
* This represent an abstraction over a source, for example an Java InputStream or a file descriptor. | ||
*/ | ||
class InputSource { | ||
public: | ||
/** | ||
* @brief Reads data from the source into the provided buffer. | ||
* @param buffer The buffer to read data into. | ||
* @param size The number of bytes to read. | ||
* @return The total number of bytes read, -1 if EOF or INT32_MIN if error with JNI error set correctly. | ||
* | ||
* This method reads data from the source into the specified buffer. | ||
*/ | ||
virtual int32_t read(uint8_t *buffer, size_t size) = 0; | ||
}; | ||
|
||
#endif //JXLVIEWER_INPUTSOURCE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// | ||
// Created by oupso on 04/01/2024. | ||
// | ||
|
||
#ifndef JXLVIEWER_JNIINPUTSTREAM_H | ||
#define JXLVIEWER_JNIINPUTSTREAM_H | ||
|
||
#include "InputSource.h" | ||
#include <jni.h> | ||
|
||
#define BUFFER_SIZE (4096) | ||
|
||
/** | ||
* @class JniInputStream | ||
* @brief An implementation of InputSource using Java Native Interface (JNI) to read from a Java InputStream. | ||
* | ||
* This class extends the InputSource class and provides functionality to read data from a Java InputStream | ||
* using the Java Native Interface (JNI). It overrides the read method to efficiently read data from the | ||
* underlying Java InputStream into a provided buffer. | ||
*/ | ||
class JniInputStream : public InputSource { | ||
public: | ||
/** | ||
* @brief Constructor for JniInputStream. | ||
* @param env The JNI environment pointer. | ||
* @param inputStream The Java InputStream object. | ||
* | ||
* This constructor initializes the JniInputStream with the JNI environment pointer and the Java InputStream object. | ||
* It also sets up the JNI method ID for the read method and allocates a Java byte array for buffering. | ||
*/ | ||
JniInputStream(JNIEnv *env, jobject inputStream) : env(env), inputStream(inputStream), | ||
sizeRead(0) { | ||
jclass inputStream_Clazz = env->FindClass("java/io/InputStream"); | ||
this->readMethodId = env->GetMethodID(inputStream_Clazz, "read", "([BII)I"); | ||
this->javaByteArray = env->NewByteArray(BUFFER_SIZE); | ||
} | ||
|
||
/** | ||
* @brief Destructor for JniInputStream. | ||
* | ||
* Cleans up resources, including deleting the allocated Java byte array. | ||
*/ | ||
~JniInputStream() { | ||
env->DeleteLocalRef(this->javaByteArray); | ||
} | ||
|
||
/** | ||
* @brief Reads data from the Java InputStream into the provided buffer. | ||
* @param buffer The buffer to read data into. | ||
* @param size The number of bytes to read. | ||
* @return The total number of bytes read, -1 if EOF or INT32_MIN if error with JNI error set correctly. | ||
* | ||
* This method reads data from the Java InputStream into the specified buffer. | ||
* It efficiently manages the reading process, handling buffering and JNI calls. | ||
*/ | ||
int32_t read(uint8_t *buffer, size_t size) override { | ||
ssize_t totalRead = (this->sizeRead > 0) ? readFromBuffer(buffer, size) : this->sizeRead; | ||
|
||
while (totalRead < size) { | ||
this->sizeRead = env->CallIntMethod(this->inputStream, this->readMethodId, | ||
javaByteArray, 0, BUFFER_SIZE); | ||
if (env->ExceptionCheck()) { | ||
return INT32_MIN; | ||
} else { | ||
this->offset = 0; | ||
if (this->sizeRead >= 0) { | ||
totalRead += readFromBuffer(buffer + totalRead, size - totalRead); | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return totalRead; | ||
} | ||
|
||
private: | ||
JNIEnv *env; | ||
jobject inputStream; | ||
jmethodID readMethodId; | ||
jbyteArray javaByteArray; | ||
size_t sizeRead; | ||
size_t offset; | ||
|
||
size_t readFromBuffer(const uint8_t *buffer, size_t size) { | ||
auto res = std::min(size, sizeRead - offset); | ||
env->GetByteArrayRegion(javaByteArray, offset, | ||
res, | ||
(jbyte *) buffer); | ||
if (res + offset == sizeRead) { | ||
sizeRead = 0; | ||
offset = 0; | ||
} else { | ||
offset += res; | ||
} | ||
return res; | ||
} | ||
}; | ||
|
||
#endif //JXLVIEWER_JNIINPUTSTREAM_H |
Oops, something went wrong.