Hello,
I have an optimized JPEG decoder written in C++, I have a JNI bridge to that codebase with this method:
Java-side:
public static native byte[] readJPEG(String name);
C++ side:
JNIEXPORT const jbyteArray JNICALL Java_IPPJPEGDecoder_readJPEG(JNIEnv *, jclass, jstring);
I have this call in Java layer:
long start = System.currentTimeMillis();
byte[] data = IPPJPEGDecoder.readJPEG("C:\\D-102_red_ink_1.JPG");
long end = System.currentTimeMillis();
System.out.println("total time = " + (end - start));
This is my method in C++ (rough/ugly code, don't judge me :) )
JNIEXPORT const jbyteArray JNICALL Java_IPPJPEGDecoder_readJPEG (JNIEnv * env, jclass jobj, jstring jpeg_filename)
{
//cout << "INVOKED IPPJPEGDecoder.readJPEG() SUCCESSFULL" << endl;
//cout << "Started"<<endl;
CIppImage m_image;
CIppImage grayscale_image;
CIppImage monochrome_image;
CTimer timer;
timer.Start();
CStdFileInput in;
const IppLibraryVersion* libver = ippGetLibVersion();
cout << "LibraryVersion = (" << libver->Name <<": " << libver->Version << ")"<<endl;
UIC::BaseStream::TStatus status;
jboolean iscopy;
const char * filename = env->GetStringUTFChars(jpeg_filename,&iscopy);
status = in.Open(filename);
GetImageFromJPEGJNI(in, m_image, timer);
cout<<"m_image: (Precision: " << m_image.Precision() << ", NumChannels: " <<m_image.NChannels()<<", Width: " << m_image.Width() << ", Height: " << m_image.Height()<< ", Color: " << m_image.Color() <<", step: " << m_image.Step()<<endl;
timer.Start();
cout << "data array size of image : " <<(m_image.Step()*m_image.Height())<<endl;
jbyteArray jb = env->NewByteArray(m_image.Step()*m_image.Height());
env->SetByteArrayRegion(jb,0, m_image.Step()*m_image.Height(),(const jbyte*)m_image.DataPtr());
timer.Stop();
double mytime = timer.GetTime();
cout << "JNI occurred in " << mytime << " ms"<<endl;
return jb;
//return NULL;
}
When I call this code, the C++ codeblock reports as running in 92.7793 ms
My java code reports back: 572 ms
is the Call to the JNI method THAT INSANELY slow !?!?! I MUST be doing something wrong... this is in Windows XP and I'm linking against my own dll that I compiled in Microsoft Visual C++ 2008.
The jbyteArray that I'm passing back has a length of 33583500
... maybe it's the conversion from jbyteArray to Java's byte[] that is causing all the overhead.... are there any ways around that?
Thanks!!
Alessandro Ferrucci