RapidOCR Native DLL Adapter
HPDFRapidOCRRecognition exposes an in-process IHPDFOCREngine backed by HotPDFRapidOCR.dll, with the same public API in Delphi, C++Builder, and Windows FPC/Lazarus Win32 and Win64 builds
The DLL performs CPU ONNX inference directly on memory snapshots and keeps initialized models until the engine interface is released; runtime deployment consists of the matching native DLL and compatible local models and dictionary
The existing Python process adapter remains available with its original factory overloads
Factory and options
function HPDFCreateRapidOCRDLLOCREngine(const LibraryPath,
ModelDirectory: string): IHPDFOCREngine; overload;
function HPDFCreateRapidOCRDLLOCREngine(const LibraryPath,
ModelDirectory: string; const Options: THPDFRapidOCRDLLOptions): IHPDFOCREngine; overload;
THPDFRapidOCRDLLOptions = record
DetectionModel: string;
RecognitionModel: string;
ClassificationModel: string;
CharacterDictionary: string;
UseAngleClassifier: Boolean;
RightToLeft: Boolean;
Threads: Integer;
MaxPixels: Integer;
TimeoutMilliseconds: Cardinal;
class function Default: THPDFRapidOCRDLLOptions; static;
class function ForLanguage(const Language: string): THPDFRapidOCRDLLOptions; static;
end;
Initialize options with THPDFRapidOCRDLLOptions.Default; the defaults use the following local files
| Field | Default | Meaning |
|---|---|---|
DetectionModel | ch_PP-OCRv3_det_infer.onnx | DB detection model |
RecognitionModel | ch_PP-OCRv3_rec_infer.onnx | Compatible PP-OCRv3 or PP-OCRv4 CTC recognition model |
ClassificationModel | ch_ppocr_mobile_v2.0_cls_infer.onnx | Optional text orientation model |
CharacterDictionary | ppocr_keys_v1.txt | UTF-8 dictionary without a BOM, in the model's character order |
UseAngleClassifier | True | When disabled, no classification model is required or initialized |
RightToLeft | False | Order detected boxes from right to left within horizontal rows; enabled by the Arabic preset |
Threads | 1 | ONNX CPU thread count from 1 through 64, capped at the logical processor count |
MaxPixels | 16777216 | Input pixel limit, from 1 through 67,108,864 |
TimeoutMilliseconds | 60000 | Cooperative recognition deadline, from 1 through 3,600,000 milliseconds |
Relative filenames resolve against ModelDirectory; absolute paths may select separately provisioned files
The factory checks file availability, options, required exports, and ABI version before initializing models; invalid configuration raises EArgumentException, and model loading failures raise EInvalidOperation with a native diagnostic
Model initialization occurs in the factory and is outside the recognition deadline; dictionary class counts must match the recognition model, and identical class counts alone do not establish that character order or preprocessing is compatible
The supplied pipeline uses DB detection with a 1,024-pixel maximum detection side and 50 pixels of white padding; the recognizer accepts compatible NCHW models with a fixed input height of 32 or 48 and uses 48 for a dynamic height
Recognition preserves aspect ratio for dynamic-width models and normalizes padded inputs with a minimum width of 320; a fixed-width model caps the resized crop width, which can compress a long text line
Angle classification preserves crop aspect ratio within its model input width and fills unused pixels with normalized zeroes; a crop rotates 180 degrees only when the upside-down score exceeds 0.9, preventing weak direction predictions from flipping short text
The dictionary must match the model's character order and output class count; CRLF dictionary line endings are accepted, but a UTF-8 BOM is rejected
When the model embeds character metadata, the factory also verifies every dictionary entry and its order; dictionary size alone is insufficient
Chinese, Russian, and common languages
THPDFRapidOCRDLLOptions.ForLanguage selects a recognition model and matching dictionary below the local model directory while retaining the shared detector, classifier, thread, pixel, and timeout defaults
The method accepts case-insensitive language aliases, changes underscores to hyphens, and trims surrounding whitespace; an empty or unsupported tag raises EArgumentException before loading models
| Profile directory | Languages | Common accepted aliases |
|---|---|---|
ch | Simplified Chinese and English | zh, zh-CN, zh-Hans, chi_sim |
chinese_cht | Traditional Chinese | zh-TW, zh-HK, zh-Hant, chi_tra |
en | English | en, en-US, en-GB, eng |
latin | French, German, Spanish, Portuguese, Italian, Dutch, and Turkish | fr, de, es, pt-BR, it, nl, tr |
japan | Japanese | ja, ja-JP, jpn |
korean | Korean | ko, ko-KR, kor |
cyrillic | Russian, Ukrainian, Bulgarian, and Belarusian | ru, ru-RU, rus, uk, bg, be |
arabic | Arabic, Persian, and Urdu | ar, fa, ur, ara, fas, urd |
devanagari | Hindi, Marathi, and Nepali | hi, mr, ne, hin, mar, nep |
Every profile uses <profile>/recognition.onnx and <profile>/dictionary.txt; profile names are accepted directly, and recognized regional aliases are explicitly defined rather than inferred from an arbitrary prefix
Install the selected model sets before deployment with the SHA256-pinned provisioning helper
& tools/Install-RapidOCRModels.ps1 `
-Destination C:/OCR/models `
-Language ch,chinese_cht,en,latin,japan,korean,cyrillic,arabic,devanagari
-Language All installs all nine profiles; -SkipClassifier omits the optional classifier, in which case set UseAngleClassifier := False when creating an engine
The helper verifies pinned SHA256 hashes and installs a shared multilingual detector and classifier under the root filenames used by Default; recognition runs offline and never downloads missing models automatically
Choose the engine's language for each page or region; one engine does not automatically detect the language or combine separate recognizers for different scripts
The pinned packages use compatible PP-OCRv3 and PP-OCRv4 models; recognition accuracy depends on the model, font, resolution, and crop, and the Latin model can confuse accents such as ñ even on clean input
Newer PP-OCRv5 models can require a newer ONNX Runtime than the static libraries used to build the DLL; an unsupported model format fails initialization with a diagnostic
Detection models must accept a single float32 image tensor and produce a float32 probability map with shape [1, 1, H, W] at the resized input resolution; incompatible types, dimensions, non-finite values, or probabilities outside [0, 1] by more than four float32 machine epsilons fail with a diagnostic before detection results are used
Tiny sigmoid rounding errors within that tolerance are clamped to [0, 1] before thresholding and contour scoring so valid models can retain their normal detection behavior
Chinese example
uses SysUtils, HPDFDoc, HPDFRapidOCRRecognition;
procedure AddNativeRapidOCRText(PDF: THotPDF);
var
Engine: IHPDFOCREngine;
Models: THPDFRapidOCRDLLOptions;
Layer: THPDFOCRTextLayerOptions;
Info: THPDFOCRTextLayerInfo;
begin
Models := THPDFRapidOCRDLLOptions.ForLanguage('zh-CN');
Models.UseAngleClassifier := False;
Engine := HPDFCreateRapidOCRDLLOCREngine(
'C:\OCR\Win64\HotPDFRapidOCR.dll', 'C:\OCR\models', Models);
Layer := THPDFOCRTextLayerOptions.Default;
if not PDF.ApplyLoadedOCRTextLayer([0], Engine, Layer, Info) then
raise Exception.Create('Native RapidOCR text layer was not added');
end;
Retain the engine interface across requests to reuse its models; use a DLL matching the calling application's architecture and supply its dependencies beside it or in standard Windows loader directories
Russian example
procedure AddRussianRapidOCRText(PDF: THotPDF);
var
Engine: IHPDFOCREngine;
Models: THPDFRapidOCRDLLOptions;
Layer: THPDFOCRTextLayerOptions;
Info: THPDFOCRTextLayerInfo;
begin
Models := THPDFRapidOCRDLLOptions.ForLanguage('ru-RU');
Engine := HPDFCreateRapidOCRDLLOCREngine(
'C:\OCR\Win64\HotPDFRapidOCR.dll', 'C:\OCR\models', Models);
Layer := THPDFOCRTextLayerOptions.Default;
if not PDF.ApplyLoadedOCRTextLayer([0], Engine, Layer, Info) then
raise Exception.Create('Russian RapidOCR text layer was not added');
end;
ru, ru-RU, and rus select the same cyrillic recognition model and dictionary
Results and lifetime
The adapter copies the current bitmap into an independent top-down BGR snapshot; it checks dimensions and the pixel budget before allocation and does not modify the borrowed bitmap
The native pipeline emits one result per recognized text line, with original-image pixel bounds and the mean character confidence; each line consumes one MaxWords slot, and no native baseline is supplied
Detected boxes follow horizontal row reading order, from left to right by default and from right to left when RightToLeft is enabled; the Arabic preset enables this option
Angle classification corrects individual text crops; it does not determine whole-page orientation or reorder an upside-down page's separate detection boxes into logical reading order
Recognized text remains in the model's logical Unicode order; the adapter does not automatically reverse Arabic strings or apply bidirectional shaping
The adapter validates UTF-8, Unicode control characters, bounds, confidence, and the request's MaxTextCodeUnits limit, with a hard text ceiling of 1,048,576 UTF-16 units; supplementary characters consume two units
An empty page succeeds with an empty result array; a failure clears partial results, and searchable PDF publication retains the existing atomic page transaction behavior
Calls on the same engine are serialized; waiting for the engine lock checks cancellation and the recognition deadline every 25 milliseconds
Native callbacks check cancellation and deadlines before and after detection, classification, and each recognized line; an individual ONNX inference call cannot be forcibly interrupted, so cancellation may return after the current stage finishes
Input and text limits bound adapter allocations and accepted output, but they do not impose a hard cap on model, detection, crop, or inference memory
Building and ABI
Native/RapidOCR contains the C++ bridge, compatible model recognizer, versioned C header, export definition, and CMake project; provision compatible CPU network sources exposing DbNet, AngleNet, and OcrUtils, plus matching ONNX Runtime and OpenCV libraries
Use Windows MSVC with C++17, a Windows SDK, and CMake 3.20 or later; the default build uses the static release CRT, which must match the provisioned libraries
& tools/Build-HotPDFRapidOCR.ps1 `
-NativeSourceDirectory C:/OCR/native-sources `
-OnnxRuntimeDirectory C:/OCR/onnxruntime/windows-x64 `
-OpenCVDirectory C:/OCR/opencv/x64/vc16/staticlib `
-Platform Win64
OnnxRuntimeDirectory must contain OnnxRuntimeConfig.cmake, and OpenCVDirectory must point to the architecture-specific library configuration; select Win32 and matching x86 libraries for a 32-bit DLL
The build helper writes Lib/Native/RapidOCR/<Platform>/HotPDFRapidOCR.dll; -BuildDirectory, -OutputDirectory, and -Generator can override build placement and the Visual Studio generator
The bridge contains C++ exceptions and exposes ABI version 1 through HPDFRapidOCRAbiVersion, HPDFRapidOCRCreate, HPDFRapidOCRRecognize, and HPDFRapidOCRDestroy; all use cdecl, 32-bit status values, and explicit UTF-8 byte lengths
ABI version 1 also defines the optional HPDFRapidOCRSetReadingDirection export; the adapter requires it only when RightToLeft is enabled, so existing DLLs can still serve left-to-right requests
Callbacks borrow their text only for the duration of the call; the adapter copies validated text before returning, and the engine destructor destroys models before unloading the DLL
Validation
With the Python onnx package and a native BUILD_TESTING build, run python tools/test_rapidocr_detector.py <build>/Release/NativeDetectorTests.exe to check valid blank output, invalid tensor ranks, channels and types, mismatched spatial dimensions, and invalid probabilities through the DLL ABI; multiple runner paths can validate both architectures in one invocation
Add -RapidOCRLanguageModelDirectory and one or both native DLL library parameters to the Delphi or FPC adapter runner to validate all installed presets with Chinese, Russian, Japanese, Korean, common Latin languages, Arabic, and Hindi samples; Russian and Traditional Chinese also undergo searchable PDF save, reload, text extraction, and pixel comparison
The Delphi and FPC adapter runners test persistent model lifetime, BGR row layout, Unicode and supplementary characters, ABI checks, invalid results, budgets, cooperative cancellation, serialized lock waiting, and cleanup
Supply -RapidOCRNativeWin32Library, -RapidOCRNativeWin64Library, and -RapidOCRNativeModelDirectory to Tests/Delphi/Run-TesseractRecognitionTests.ps1 or Tests/Delphi/Run-TesseractFPCRecognitionTests.ps1 for real model validation, empty pages, damaged model handling, English and Chinese recognition, and searchable PDF round trips with unchanged rendered pixels
See Searchable OCR Text Layers for page rendering, Unicode PDF text mapping, optional-content grouping, and conformance constraints