src/share/native/sun/awt/image/jpeg/imageioJPEG.c
Print this page
*** 105,115 ****
*/
/******************** StreamBuffer definition ************************/
typedef struct streamBufferStruct {
! jobject stream; // ImageInputStream or ImageOutputStream
jbyteArray hstreamBuffer; // Handle to a Java buffer for the stream
JOCTET *buf; // Pinned buffer pointer */
int bufferOffset; // holds offset between unpin and the next pin
int bufferLength; // Allocated, nut just used
int suspendable; // Set to true to suspend input
--- 105,115 ----
*/
/******************** StreamBuffer definition ************************/
typedef struct streamBufferStruct {
! jweak ioRef; // weak reference to a provider of I/O routines
jbyteArray hstreamBuffer; // Handle to a Java buffer for the stream
JOCTET *buf; // Pinned buffer pointer */
int bufferOffset; // holds offset between unpin and the next pin
int bufferLength; // Allocated, nut just used
int suspendable; // Set to true to suspend input
*** 124,133 ****
--- 124,142 ----
* seems too big and 1K seems too small. If 4K was good enough for the
* IJG folks, it's good enough for me.
*/
#define STREAMBUF_SIZE 4096
+ #define GET_IO_REF(io_name) \
+ do { \
+ if ((*env)->IsSameObject(env, sb->ioRef, NULL) || \
+ ((io_name) = (*env)->NewLocalRef(env, sb->ioRef)) == NULL) \
+ { \
+ cinfo->err->error_exit((j_common_ptr) cinfo); \
+ } \
+ } while (0) \
+
/*
* Used to signal that no data need be restored from an unpin to a pin.
* I.e. the buffer is empty.
*/
#define NO_DATA -1
*** 158,168 ****
"Initializing Reader");
return NOT_OK;
}
! sb->stream = NULL;
sb->buf = NULL;
resetStreamBuffer(env, sb);
--- 167,177 ----
"Initializing Reader");
return NOT_OK;
}
! sb->ioRef = NULL;
sb->buf = NULL;
resetStreamBuffer(env, sb);
*** 190,202 ****
* The global reference to the stream is released, but the reference
* to the buffer is retained. The buffer is unpinned if it was pinned.
* All other state is reset.
*/
static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
! if (sb->stream != NULL) {
! (*env)->DeleteGlobalRef(env, sb->stream);
! sb->stream = NULL;
}
unpinStreamBuffer(env, sb, NULL);
sb->bufferOffset = NO_DATA;
sb->suspendable = FALSE;
sb->remaining_skip = 0;
--- 199,211 ----
* The global reference to the stream is released, but the reference
* to the buffer is retained. The buffer is unpinned if it was pinned.
* All other state is reset.
*/
static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
! if (sb->ioRef != NULL) {
! (*env)->DeleteWeakGlobalRef(env, sb->ioRef);
! sb->ioRef = NULL;
}
unpinStreamBuffer(env, sb, NULL);
sb->bufferOffset = NO_DATA;
sb->suspendable = FALSE;
sb->remaining_skip = 0;
*** 580,604 ****
/*************** Shared utility code ***********************/
static void imageio_set_stream(JNIEnv *env,
j_common_ptr cinfo,
imageIODataPtr data,
! jobject stream){
streamBufferPtr sb;
sun_jpeg_error_ptr jerr;
sb = &data->streamBuf;
resetStreamBuffer(env, sb); // Removes any old stream
! /* Now we need a new global reference for the stream */
! if (stream != NULL) { // Fix for 4411955
! sb->stream = (*env)->NewGlobalRef(env, stream);
! if (sb->stream == NULL) {
JNU_ThrowByName(env,
"java/lang/OutOfMemoryError",
! "Setting Stream");
return;
}
}
/* And finally reset state */
--- 589,613 ----
/*************** Shared utility code ***********************/
static void imageio_set_stream(JNIEnv *env,
j_common_ptr cinfo,
imageIODataPtr data,
! jobject io) {
streamBufferPtr sb;
sun_jpeg_error_ptr jerr;
sb = &data->streamBuf;
resetStreamBuffer(env, sb); // Removes any old stream
! /* Now we need a new weak global reference for the I/O provider */
! if (io != NULL) { // Fix for 4411955
! sb->ioRef = (*env)->NewWeakGlobalRef(env, io);
! if (sb->ioRef == NULL) {
JNU_ThrowByName(env,
"java/lang/OutOfMemoryError",
! "Setting I/O provider");
return;
}
}
/* And finally reset state */
*** 904,913 ****
--- 913,923 ----
struct jpeg_source_mgr *src = cinfo->src;
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
streamBufferPtr sb = &data->streamBuf;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
int ret;
+ jobject input = NULL;
/* This is where input suspends */
if (sb->suspendable) {
return FALSE;
}
*** 929,941 ****
/*
* Now fill a complete buffer, or as much of one as the stream
* will give us if we are near the end.
*/
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallIntMethod(env,
! sb->stream,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer, 0,
sb->bufferLength);
if ((*env)->ExceptionOccurred(env)
|| !GET_ARRAYS(env, data, &(src->next_input_byte))) {
--- 939,953 ----
/*
* Now fill a complete buffer, or as much of one as the stream
* will give us if we are near the end.
*/
+ GET_IO_REF(input);
+
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallIntMethod(env,
! input,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer, 0,
sb->bufferLength);
if ((*env)->ExceptionOccurred(env)
|| !GET_ARRAYS(env, data, &(src->next_input_byte))) {
*** 991,1000 ****
--- 1003,1013 ----
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
streamBufferPtr sb = &data->streamBuf;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jint ret;
int offset, buflen;
+ jobject input = NULL;
/*
* The original (jpegdecoder.c) had code here that called
* InputStream.available and just returned if the number of bytes
* available was less than any remaining skip. Presumably this was
*** 1012,1031 ****
/* Save the data currently in the buffer */
offset = src->bytes_in_buffer;
if (src->next_input_byte > sb->buf) {
memcpy(sb->buf, src->next_input_byte, offset);
}
RELEASE_ARRAYS(env, data, src->next_input_byte);
buflen = sb->bufferLength - offset;
if (buflen <= 0) {
if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
cinfo->err->error_exit((j_common_ptr) cinfo);
}
return;
}
! ret = (*env)->CallIntMethod(env, sb->stream,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer,
offset, buflen);
if ((*env)->ExceptionOccurred(env)
|| !GET_ARRAYS(env, data, &(src->next_input_byte))) {
--- 1025,1047 ----
/* Save the data currently in the buffer */
offset = src->bytes_in_buffer;
if (src->next_input_byte > sb->buf) {
memcpy(sb->buf, src->next_input_byte, offset);
}
+
+ GET_IO_REF(input);
+
RELEASE_ARRAYS(env, data, src->next_input_byte);
buflen = sb->bufferLength - offset;
if (buflen <= 0) {
if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
cinfo->err->error_exit((j_common_ptr) cinfo);
}
return;
}
! ret = (*env)->CallIntMethod(env, input,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer,
offset, buflen);
if ((*env)->ExceptionOccurred(env)
|| !GET_ARRAYS(env, data, &(src->next_input_byte))) {
*** 1084,1093 ****
--- 1100,1110 ----
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
streamBufferPtr sb = &data->streamBuf;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jlong ret;
jobject reader;
+ jobject input = NULL;
if (num_bytes < 0) {
return;
}
num_bytes += sb->remaining_skip;
*** 1113,1125 ****
if (sb->suspendable) {
sb->remaining_skip = num_bytes;
return;
}
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallLongMethod(env,
! sb->stream,
JPEGImageReader_skipInputBytesID,
(jlong) num_bytes);
if ((*env)->ExceptionOccurred(env)
|| !GET_ARRAYS(env, data, &(src->next_input_byte))) {
cinfo->err->error_exit((j_common_ptr) cinfo);
--- 1130,1144 ----
if (sb->suspendable) {
sb->remaining_skip = num_bytes;
return;
}
+ GET_IO_REF(input);
+
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallLongMethod(env,
! input,
JPEGImageReader_skipInputBytesID,
(jlong) num_bytes);
if ((*env)->ExceptionOccurred(env)
|| !GET_ARRAYS(env, data, &(src->next_input_byte))) {
cinfo->err->error_exit((j_common_ptr) cinfo);
*** 2291,2305 ****
{
struct jpeg_destination_mgr *dest = cinfo->dest;
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
streamBufferPtr sb = &data->streamBuf;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
(*env)->CallVoidMethod(env,
! sb->stream,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
sb->bufferLength);
if ((*env)->ExceptionOccurred(env)
--- 2310,2327 ----
{
struct jpeg_destination_mgr *dest = cinfo->dest;
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
streamBufferPtr sb = &data->streamBuf;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ jobject output = NULL;
+
+ GET_IO_REF(output);
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
(*env)->CallVoidMethod(env,
! output,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
sb->bufferLength);
if ((*env)->ExceptionOccurred(env)
*** 2329,2342 ****
/* find out how much needs to be written */
jint datacount = sb->bufferLength - dest->free_in_buffer;
if (datacount != 0) {
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
(*env)->CallVoidMethod(env,
! sb->stream,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
datacount);
--- 2351,2368 ----
/* find out how much needs to be written */
jint datacount = sb->bufferLength - dest->free_in_buffer;
if (datacount != 0) {
+ jobject output = NULL;
+
+ GET_IO_REF(output);
+
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
(*env)->CallVoidMethod(env,
! output,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
datacount);