The Source for Java Technology Collaboration
User: Password:



Start New Message Delete Post a Reply

Article: 
 Java Tech: Acquire Images with TWAIN and SANE, Part 2
Subject:  error in Virtual Machine
Date:  2006-10-11 00:01:27
From:  seboss


Hi,

I've a JTwain version that include the following function :

JNIEXPORT jobject JNICALL
Java_transpo_system_jtwain_JTwain_acquireCfg
(JNIEnv *env, jclass clazz)
{
// Verify that the data source manager has not been opened.

if (g_hLib != 0)
{
throwJTE (env, "Data source manager already open (_acquire)");

return (jobject) 0; // Return value never reaches Java, but is needed
// to satisfy the compiler.
}

// Attempt to load TWAIN DLL.

if (!loadTWAIN ())
{
throwJTE (env, "Unable to load TWAIN (_acquire)");

return (jobject) 0;
}

// Create a static window whose handle is passed to DSM_Entry() when we
// open the data source manager.

HWND hwnd = CreateWindow ("STATIC",
"",
WS_POPUPWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
0,
g_hinstDLL,
0);

// If window could not be created, throw exception. Because the exception
// is not actually thrown until execution returns to Java, we must return
// a value -- (jobject) 0 was chosen to represent Image null. This value
// will not be seen in the Java code because of the exception.

if (hwnd == 0)
{
unloadTWAIN ();

throwJTE (env, "Unable to create private window (_acquire)");

return (jobject) 0;
}

// Ensure that the default data source's dialog box does not disappear
// behind other windows, which can be very disconcerting to the user. We do
// that by making the hwnd -- created above and passed to DSM_Entry() below
// -- the handle of the topmost window.

SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);

TW_UINT16 rc;
jobject image = 0;
cout << "block begin 1";
BLOCK_BEGIN(1)

// Open the data source manager.

rc = (*g_pDSM_Entry) (&g_AppID,
0,
DG_CONTROL,
DAT_PARENT,
MSG_OPENDSM,
(TW_MEMREF) &hwnd);

// If data source manager could not be opened, throw exception. Because the
// exception is not actually thrown until execution returns to Java, we
// first exit current block to destroy previously-created window and return
// a value (which isn't seen in the Java code).

if (rc != TWRC_SUCCESS)
{
throwJTE (env, "Unable to open data source manager (_acquire)");
EXIT_CURRENT_BLOCK
}
cout << "block begin 2";
BLOCK_BEGIN(2)

// Get the default data source's name.

TW_IDENTITY srcID;

ZeroMemory (&srcID, sizeof(srcID));
rc = (*g_pDSM_Entry) (&g_AppID,
0,
DG_CONTROL,
DAT_IDENTITY,
MSG_GETDEFAULT,
&srcID);

// If failure occurred, prepare to throw an exception, which is only thrown
// after this function ends.

if (rc == TWRC_FAILURE)
{
throwJTE (env, "Unable to obtain default data source name (_acquire)");
EXIT_CURRENT_BLOCK
}

// Open the default data source.

rc = (*g_pDSM_Entry) (&g_AppID,
0,
DG_CONTROL,
DAT_IDENTITY,
MSG_OPENDS,
&srcID);

// If default data source could not be opened, throw exception. Because the
// exception is not actually thrown until execution returns to Java, we
// first exit current block to close data source manager and destroy the
// previously-created window.

if (rc != TWRC_SUCCESS)
{
throwJTE (env, "Unable to open default data source (_acquire)");
EXIT_CURRENT_BLOCK
}
cout << "block begin 3";
BLOCK_BEGIN(3)

// Prepare to enable the default data source. Make sure to show the data
// source's own user interface (dialog box).

TW_USERINTERFACE ui;
ui.ShowUI = TRUE;
ui.ModalUI = FALSE;
ui.hParent = hwnd;

// Enable the default data source.

rc = (*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_CONTROL,
DAT_USERINTERFACE,
MSG_ENABLEDS,
&ui);

// If default data source could not be enabled, throw exception. Because
// the exception is not actually thrown until execution returns to Java, we
// first exit current block to close data source, close data source
// manager and destroy the previously-created window.

if (rc != TWRC_SUCCESS)
{
throwJTE (env, "Unable to enable default data source (_acquire)");
EXIT_CURRENT_BLOCK
}

// Begin the event-handling loop. Data transfer takes place in this loop.

MSG msg;
TW_EVENT event;
TW_PENDINGXFERS pxfers;
cout << "while (getmessage) begin";
while (GetMessage ((LPMSG) &msg, 0, 0, 0))
{
// Each window message must be forwarded to the default data source.

event.pEvent = (TW_MEMREF) &msg;
event.TWMessage = MSG_NULL;

rc = (*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_CONTROL,
DAT_EVENT,
MSG_PROCESSEVENT,
(TW_MEMREF) &event);

// Safety check -- in case something went wrong.

if (g_rc == TWRC_FAILURE)
{
throwJTE (env, "Unable to retrieve next event (_acquire)");

break; // Break out of event-handling loop.
}

// If the message does not correspond to a data source event, we must
// dispatch it to the appropriate Windows window.

if (rc == TWRC_NOTDSEVENT)
{
TranslateMessage ((LPMSG) &msg);
DispatchMessage ((LPMSG) &msg);
continue;
}

// If the default data source is requesting that the data source's
// dialog box be closed (user pressed Cancel), we must break out of the
// message loop.

if (event.TWMessage == MSG_CLOSEDSREQ)
break;

// If the default data source is requesting that it is ready to begin
// the data transfer, we must perform that transfer.

if (event.TWMessage == MSG_XFERREADY)
{
// Obtain information about the first image to be transferred.

TW_IMAGEINFO ii;
rc = (*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_IMAGE,
DAT_IMAGEINFO,
MSG_GET,
(TW_MEMREF) &ii);

// If unable to obtain image information ...

if (rc == TWRC_FAILURE)
{
// Cancel all transfers.

(*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_CONTROL,
DAT_PENDINGXFERS,
MSG_RESET,
(TW_MEMREF) &pxfers);

// Throw exception upon return to Java and break out of event
// loop.

throwJTE (env, "Unable to obtain image information (_acquire)");
break;
}

// If image is compressed or is not 1-bit color and not 8-bit color
// and not 24-bit color ...

if (ii.Compression != TWCP_NONE ||
ii.BitsPerPixel != 1 &&
ii.BitsPerPixel != 8 &&
ii.BitsPerPixel != 24)
{
// Cancel all transfers.

(*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_CONTROL,
DAT_PENDINGXFERS,
MSG_RESET,
(TW_MEMREF) &pxfers);

// Throw exception upon return to Java and break out of event
// loop.

throwJTE (env, "Image compressed or not 1-bit/8-bit/24-bit "
"(_acquire)");
break;
}

// Perform the transfer.
TW_UINT32 handle;

rc = (*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_IMAGE,
DAT_IMAGENATIVEXFER,
MSG_GET,
(TW_MEMREF) &handle);

// If image not successfully transferred ...

if (rc != TWRC_XFERDONE)
{
// Cancel all remaining transfers.

(*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_CONTROL,
DAT_PENDINGXFERS,
MSG_RESET,
(TW_MEMREF) &pxfers);

// Throw exception upon return to Java and break out of event
// loop.

throwJTE (env, "User aborted transfer or failure (_acquire)");
break;
}

// Convert Windows-based DIB to a Java-based Image via a
// BufferedImage.

LPBITMAPINFOHEADER lpbmih;
lpbmih = (LPBITMAPINFOHEADER) GlobalLock ((HANDLE) handle);

image = xferDIBtoImage (lpbmih, env);

GlobalUnlock ((HANDLE) handle);
GlobalFree ((HANDLE) handle);

// Cancel all remaining transfers.

(*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_CONTROL,
DAT_PENDINGXFERS,
MSG_RESET,
(TW_MEMREF) &pxfers);

// Convert TWRC_XFERDONE to TWRC_SUCCESS so that appropriate value
// is returned.

rc = TWRC_SUCCESS;

break;
}
}
cout << "end while";

// Disable the data source.

(*g_pDSM_Entry) (&g_AppID,
&srcID,
DG_CONTROL,
DAT_USERINTERFACE,
MSG_DISABLEDS,
&ui);
cout << "block end 3";
BLOCK_END(3)

// Close the data source.

(*g_pDSM_Entry) (&g_AppID,
0,
DG_CONTROL,
DAT_IDENTITY,
MSG_CLOSEDS,
&srcID);
cout << "block end 2";
BLOCK_END(2)

// Close the data source manager.

(*g_pDSM_Entry) (&g_AppID,
0,
DG_CONTROL,
DAT_PARENT,
MSG_CLOSEDSM,
(TW_MEMREF) &hwnd);
cout << "block end 1";
BLOCK_END(1)

// Destroy window.

if (!DestroyWindow (hwnd))
cout << "destroy KO";
else
cout << "destroy OK";

// Unload TWAIN DLL from memory.

unloadTWAIN ();

return (rc == TWRC_SUCCESS) ? image : (jobject) 0;
}

this function, when using a HP scanner, crash the JVM with the error :

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7c9211e0, pid=528, tid=588
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_08-b03 mixed mode, sharing)
# Problematic frame:
# C [ntdll.dll+0x111e0]
#
# An error report file with more information is saved as hs_err_pid528.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#

but only after the scan. The system returns the image but the user interface of the scanner still visible and it's impossible to close it. (i need to go in windows process).

Is this problem can be link to the JTwain.cpp or to the scanner (it seems to run with a canon).

Thank for help.

 Feed java.net RSS Feeds