Redirects searching and loading of engine files at runtime to a specified directory or memory buffer.
#include "ltocr.h"
L_LTOCR_API L_INT EXT_CALLBACK L_OcrEngine_SetRuntimeFileCallback(engine, callback, userData)
Handle to the OCR engine.
Callback that can be used to redirect searching and loading of engine files at runtime to a specified directory or memory buffer.
Optional user data to pass to the callback function.
Value | Meaning |
---|---|
SUCCESS | The function was successful. |
< 1 | An error occurred. Refer to Return Codes. |
Important Note 1: The LEAD Engine OCR Runtime file shipping with version 20 of LEADTOOLS does not support redirecting through memory buffer. Contact support@leadtools.com for instructions on how to obtain a copy of these files with streaming support.
The OCR engine by default performs the task of locating and obtaining the runtime files necessary for the engine to perform its operation by either passing the name of the directory where these files reside to L_OcrEngine_Startup as the engineDirectory parameter, or relying on the automatic discovery of the engine files in the special folders as outlined in L_OcrEngine_Startup
.
The above technique is suitable for desktop-based applications that install on a physical path on the machine. There are situations where the above is not desired or possible:
The application may choose to download or extract runtime files on demand from internal resources embedded in the app or even external ones.
Some environments, such as Android, do not support obtaining a physical path to resources embedded in the application.
L_OcrEngine_SetRuntimeFileCallback
can be used to redirect the search and loading of OCR runtime files to support these types of applications.
An OCR engine instance will try to load one or more engine runtime files during its lifetime as follows:
L_OcrEngine_Startup
will try to locate (but not load) all known engine files to build the feature support matrix (obtained through L_OcrLanguageManager_GetSupportedLanguages).L_OcrEngine_Startup
will load and cache the default language files (for instance, LEAD.en.bin).In other words, for any LEAD.xyz.bin runtime file, OCR engine may request a check if the file exist one or more times and may request loading it one or more times. The order and frequency of these operations is internal to the engine.
The runtime files reside on disk files by default. Therefore, a request to check if a file exists is a simple call to the operating system access
. If the file does exist, a request to load the file is made by calling fopen(fullPathToFile, "rb")
and then the content of the file is read. If the file does not exist, there will be no attempt to read it.
An application can use L_OcrEngine_SetRuntimeFileCallback
and install a callback to intercept such calls and redirect checking for file existence and loading to a custom path or routine as follows:
Set a L_OcrRuntimeFileCallback callback using L_OcrEngine_SetRuntimeFileCallback
before calling L_OcrEngine_Startup. The order is important because the engine checks for a redirect during Startup
:
// Create a LEAD OCR Engine instance
L_OcrEngine ocrEngine = NULL;
L_OcrEngineManager_CreateEngine(L_OcrEngineType_LEAD, &ocrEngine);
// Set a runtime file redirect callback
L_OcrEngine_SetRuntimeFileCallback(ocrEngine, MyOcrRuntimeFileCallback, /*if any*/ &userData);
// Now start up the engine without passing a directory name to the runtime files.
// The runtime file callback will be called as many times as necessary to locate and load the OCR
// runtime files required by the engine
L_OcrEngine_Startup(
ocrEngine,
NULL,
NULL, // NULL for 'const L_TCHAR* engineDirectory' parameter
);
Perform OCR operations as normal. The runtime file callback will be called as many times as necessary.
// OCR a TIF file and save it as PDF
// The runtime file callback can be called as many times as necessary to locate and load the OCR
// runtime files required by the engine for this operation
L_OcrAutoRecognizeManager ocrAutoRecognizeManager;
L_OcrEngine_GetAutoRecognizeManager(ocrEngine, &ocrAutoRecognizeManager);
L_OcrAutoRecognizeManager_Run(
ocrAutoRecognizeManager,
L_TEXT("C:\\LEADTOOLS23\\Resources\\Images\\ocr1.tif"),
L_TEXT("C:\\LEADTOOLS23\\Resources\\Images\\out.pdf"),
DOCUMENTFORMAT_PDF,
NULL);
Optionally, remove the runtime file callback. This must be done after shutting the engine down but before disposing it
// Shutdown
L_OcrEngine_Shutdown(ocrEngine);
// Remove the runtime callback
L_OcrEngine_SetRuntimeFileCallback(ocrEngine, NULL, NULL);
// Destroy the engine
L_OcrEngine_Destroy(ocrEngine);
The runtime file callback is called with an instance of L_OcrRuntimeFile that describes the runtime file and the operation requested as follows:
Member | Description |
---|---|
const L_TCHAR * FileName | Input only: The name of the OCR runtime file requested. |
L_OcrRuntimeFileMode Mode | Input only: Operation to perform on the file, such check for its existence, opening it for reading or closing it. |
L_TCHAR FullPath[MAX_PATH] |
Output: Full path to where the file exists, if available. |
Refer to the example below on how to use L_OcrEngine_SetRuntimeFileCallback
.
Win32, x64, Linux.
static L_INT EXT_CALLBACK MyRuntimeFileCallback(L_OcrEngine engine, L_OcrRuntimeFile* runtimeFile, L_VOID* userData);
static void OcrRuntimeFileCallbackExample()
{
// This example assumes that some or all of the OCR runtime files are copied into "C:\MyDir" folder
const L_TCHAR* myDir = L"C:\\MyDir";
// Create an OCR engine instance
L_OcrEngine ocrEngine = NULL;
L_OcrEngineManager_CreateEngine(L_OcrEngineType_LEAD, &ocrEngine);
// Install a OCR file runtime handler, passing our directory as the user data
L_OcrEngine_SetRuntimeFileCallback(ocrEngine, MyRuntimeFileCallback, (L_VOID*)myDir);
// Startup the engine
L_OcrEngine_Startup(ocrEngine,
NULL,
NULL // engineDirectory is NULL
);
// Perform OCR operation
L_OcrAutoRecognizeManager ocrAutoRecognizeManager;
L_OcrEngine_GetAutoRecognizeManager(ocrEngine, &ocrAutoRecognizeManager);
L_OcrAutoRecognizeManager_Run(
ocrAutoRecognizeManager,
L_TEXT("C:\\LEADTOOLS22\\Resources\\Images\\ocr1.tif"),
L_TEXT("C:\\LEADTOOLS22\\Resources\\Images\\out.pdf"),
DOCUMENTFORMAT_PDF,
NULL);
// Shutdown
L_OcrEngine_Shutdown(ocrEngine);
// Remove the runtime callback
L_OcrEngine_SetRuntimeFileCallback(ocrEngine, NULL, NULL);
// Destroy the engine
L_OcrEngine_Destroy(ocrEngine);
}
static L_INT EXT_CALLBACK MyRuntimeFileCallback(L_OcrEngine /*ocrEngine*/, L_OcrRuntimeFile* runtimeFile, L_VOID* userData)
{
// Called by the OCR engine for each runtime file operation
// Get the directory (our user data)
const L_TCHAR* myDir = reinterpret_cast<L_TCHAR*>(userData);
L_INT ret = SUCCESS;
// Check the operation:
switch(runtimeFile->Mode)
{
case L_OcrRuntimeFileMode_Exists:
wprintf(L_TEXT("MyRuntimeFileCallback does '%s' exist\n"), runtimeFile->FileName);
// The engine is checking if a certain file exists
L_TCHAR fullPath[MAX_PATH];
swprintf_s(fullPath, L_TEXT("%s\\%s"), myDir, runtimeFile->FileName);
if(_waccess_s(fullPath, 0) != 0)
ret = ERROR_FILENOTFOUND;
break;
case L_OcrRuntimeFileMode_Open:
wprintf(L_TEXT("MyRuntimeFileCallback open '%s'\n"), runtimeFile->FileName);
// The engine requested to open the file for reading
swprintf_s(fullPath, L_TEXT("%s\\%s"), myDir, runtimeFile->FileName);
break;
case L_OcrRuntimeFileMode_Close:
wprintf(L_TEXT("MyRuntimeFileCallback close '%s'\n"), runtimeFile->FileName);
// The engine requested to close the file after reading.
break;
}
return ret;
}