Has anyone succeeded in creating a Borland dll?

291 views
Skip to first unread message

Daryl

unread,
Oct 4, 2008, 4:22:16 PM10/4/08
to tesseract-ocr
I'm using Borland C++ Builder 6.0, and would greatly like to integrate
Tesseract OCR into a couple of programs I am writing.

Has anyone succeeded in creating a Borland compatible dll?

If so, would you be willing to send it to me, or alternatively post it
so anyone could use it?

I will continue attempting to create one myself, but things are moving
slowly...

Thanks,
Daryl

Morgy

unread,
Oct 7, 2008, 11:00:47 AM10/7/08
to tesseract-ocr
i don't realy get it but any tessdll.dll is compatible with Borland,
but i'll sent the dll i use in my own bcb6 project, to your email.

Daryl

unread,
Oct 8, 2008, 5:56:52 PM10/8/08
to tesseract-ocr
Hi Morgoth,
Thanks for your reply. I received the tessdll.dll that you sent. I
still have some problems. If you have time, can you or someone here
give me some tips?

Here's what I did:
-- I used the tessdll.lib that I downloaded previously, and added it
to my project (Project/Add to Project)
-- I included tesdll.h (also downloaded previously) in the main header
file for my program (.h file)
-- I put tessdll.dll in the same folder as all the project files.

However, when I try to compile/link everything I get an error message
regarding this line in the tessdll.h file (almost the very first line
in the file):

int BeginPage(UINT32 xsize,UINT32 ysize,unsigned char *buf);
Error: ) expected.

Perhaps it is expecting another BeginPage function that uses fewer
parameters?

Am I doing something obviously wrong?

Thanks for any help you can give.

Daryl

Morgy

unread,
Oct 8, 2008, 7:28:57 PM10/8/08
to tesseract-ocr
You have to use a dll wrapper.

for example the one i made

cTessdll.h

#ifndef tess_dllH
#define tess_dllH
//---------------------------------------------------------------------------
#include <Windows.hpp> // Pascal unit
#include <SysInit.hpp> // Pascal unit
#include <System.hpp> // Pascal unit
//---------------------------------------------------------------------------

typedef struct
{
Word char_code;
short left;
short right;
short top;
short bottom;
short font_index;
Byte confidence;
Byte point_size;
Shortint blanks;
Byte formatting;
} TEANYCODE_CHAR;
//---------------------------------------------------------------------------

typedef struct
{
short count;
short progress;
Shortint more_to_come;
Shortint ocr_alive;
Shortint err_code;
void *cancel;
void *cancel_this;
int end_time;
::TEANYCODE_CHAR text[32000];
} TETEXT_DESC;


//---------------------------------------------------------------------------
// TESSDLL Class
//---------------------------------------------------------------------------
class TessDLL
{
private:
bool LoadDLL(void);
public:
TessDLL();
~TessDLL();

AnsiString ConvertText(TETEXT_DESC *EText_Desc);

int __cdecl (*TessDllBeginPage)(unsigned xsize, unsigned
ysize, void * buf);
int __cdecl (*TessDllBeginPageLang)(unsigned xsize, unsigned
ysize, void * buf, const char * lang);
int __cdecl (*TessDllBeginPageUpright)(unsigned xsize,
unsigned ysize, void * buf, const char * lang);
int __cdecl (*TessDllBeginPageBPP)(unsigned xsize, unsigned
ysize, void * buf, Byte bpp);
int __cdecl (*TessDllBeginPageLangBPP)(unsigned xsize,
unsigned ysize, void * buf, const char * lang, Byte bpp);
int __cdecl (*TessDllBeginPageUprightBPP)(unsigned xsize,
unsigned ysize, void * buf, const char * lang, Byte bpp);
int __cdecl (*TessDllEndPage)(void);
::TETEXT_DESC * __cdecl (*TessDllRecognize_a_Block)(unsigned
left, unsigned right, unsigned top, unsigned bottom);
::TETEXT_DESC * __cdecl (*TessDllRecognize_all_Words)(void);
int __cdecl (*TessDllRelease)(void);

HANDLE TessHandle;
bool TessDLLLoaded;
};
//---------------------------------------------------------------------------
#endif



cTessdll.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "cTessdll.h"
//---------------------------------------------------------------------------
TessDLL::TessDLL()
{
TessDLLLoaded = false;
TessDLLLoaded = LoadDLL();
}
//---------------------------------------------------------------------------
TessDLL::~TessDLL()
{
if (TessDLLLoaded){
TessDllRelease();
FreeLibrary(TessHandle);
}
}
//---------------------------------------------------------------------------

bool TessDLL::LoadDLL(void)
{
if (TessDLLLoaded)
return(true);

TessHandle = LoadLibrary("TESSDLL.DLL");
if(TessHandle != NULL) {
TessDllBeginPage = (int (*)(unsigned int,unsigned
int,void *))

GetProcAddress((HINSTANCE)TessHandle,"TessDllBeginPage");
TessDllBeginPageLang = (int (*)(unsigned int,unsigned
int,void *,const char *))

GetProcAddress((HINSTANCE)TessHandle,"TessDllBeginPageLang");
TessDllBeginPageUpright = (int (*)(unsigned
int,unsigned int,void *,const char *))

GetProcAddress((HINSTANCE)TessHandle,"TessDllBeginPageUpright");
TessDllBeginPageBPP = (int (*)(unsigned int,unsigned
int,void *,unsigned char))

GetProcAddress((HINSTANCE)TessHandle,"TessDllBeginPageBPP");
TessDllBeginPageLangBPP = (int (*)(unsigned
int,unsigned int,void *,const char *,unsigned char))

GetProcAddress((HINSTANCE)TessHandle,"TessDllBeginPageLangBPP");
TessDllBeginPageUprightBPP = (int (*)(unsigned
int,unsigned int,void *,const char *,unsigned char))

GetProcAddress((HINSTANCE)TessHandle,"TessDllBeginPageUprightBPP");
TessDllEndPage = (int (*)())

GetProcAddress((HINSTANCE)TessHandle,"TessDllEndPage");
TessDllRecognize_a_Block = (TETEXT_DESC * (*)(unsigned
int,unsigned int,unsigned int,unsigned int))

GetProcAddress((HINSTANCE)TessHandle,"TessDllRecognize_a_Block");
TessDllRecognize_all_Words = (TETEXT_DESC * (*)())

GetProcAddress((HINSTANCE)TessHandle,"TessDllRecognize_all_Words");
TessDllRelease = (int (*)())

GetProcAddress((HINSTANCE)TessHandle,"TessDllRelease");

if(TessDllBeginPage && TessDllBeginPageLang &&
TessDllBeginPageUpright && TessDllBeginPageBPP
&&
TessDllBeginPageLangBPP &&
TessDllBeginPageUprightBPP &&
TessDllEndPage && TessDllRecognize_a_Block &&
TessDllRecognize_all_Words && TessDllRelease){
return(true); //Succeeded
} else {
FreeLibrary(TessHandle);
return(false);
}
} else {
return(false);
}
}
//---------------------------------------------------------------------------

AnsiString TessDLL::ConvertText(::TETEXT_DESC *EText_Desc)
{
TEANYCODE_CHAR ch;
AnsiString Result = "";

for (int i = 0; i < EText_Desc->count; i++){
ch = EText_Desc->text[i];
for (int b = 0; b < ch.blanks; ++b)
Result = Result + " ";
Result = Result + char(ch.char_code);
if (ch.formatting & 64)
Result = Result + "\r\n";
if (ch.formatting & 128)
Result = Result + "\r\n";
}

return Result;
}
//---------------------------------------------------------------------------

then you can use it in a program like

TessDLL *Tesseract = new TessDLL();


AnsiString result;

if (Tesseract->TessDLLLoaded){
Graphics::TBitmap *bmOCR = new Graphics::TBitmap();
bmOCR->LoadFromFile("test.bmp");

int BytesPerLine = int(bmOCR->ScanLine[0])-
int(bmOCR->ScanLine[1]);
int bpp, VirtualWidth;
bmOCR->HandleType = bmDIB;
switch (bmOCR->PixelFormat) {
case pfDevice :
bmOCR->PixelFormat = pf24bit;
bpp = 24;
break;
case pf1bit :
bpp = 1;
break;
case pf4bit :
bmOCR->PixelFormat = pf8bit;
bpp = 8;
break;
case pf8bit :
bpp = 8;
break;
case pf15bit :
bmOCR->PixelFormat = pf24bit;
bpp = 24;
break;
case pf16bit :
bmOCR->PixelFormat = pf24bit;
bpp = 24;
break;
case pf24bit :
bpp = 24;
break;
case pf32bit :
bmOCR->PixelFormat = pf24bit;
bpp = 24;
break;
}

switch (bpp) {
case 1 :
VirtualWidth = BytesPerLine * 8;
break;
case 8 :
VirtualWidth = BytesPerLine;
break;
case 24 :
bmOCR->Width = 4*((bmOCR->Width+3) /
4);
VirtualWidth = bmOCR->Width;
break;
}

try {
try {
Tesseract-
>TessDllBeginPageLangBPP(VirtualWidth,
bmOCR->Height,
bmOCR->ScanLine[bmOCR-
>Height-1],
NULL,
bpp);

TETEXT_DESC *RecognizedText;


RecognizedText = Tesseract-
>TessDllRecognize_all_Words();
result = Tesseract-
>ConvertText(RecognizedText);
}
__finally {
Tesseract->TessDllEndPage();
}
}
__except (true) {
result = ".ERROR.";
}

delete bmOCR;
}

delete Tesseract;

etc.....

Daryl

unread,
Oct 10, 2008, 2:57:01 AM10/10/08
to tesseract-ocr
Hi Morgy,
Summary:
It compiles and links. It crashes the first time I try to access a
function from the dll, with no error message.

Details:
I have it working partly. I added your wrapper (cTessdll.cpp and
cTessdll.h), and then used your sample code below, from "TessDLL
*Tesseract = new TessDLL();" all the way to the end ("delete
Tesseract;")..

It compiles and links fine.

When I run it, the program crashes at the line:
Tesseract->TessDllBeginPageLangBPP(VirtualWidth, bmOCR->Height,bmOCR-
>ScanLine[bmOCR->Height-1], NULL,bpp);

The "try" doesn't catch it -- it just simply exits with no error
message. If I step through the program up to that point, I can see
that all the variables are initialized. My .bmp image is opened, and
the program comes up with valid VirtualWidth, etc. I even added a
separate "try" for this line only, with no changes.

I notice that this is the first line that actually makes any calls to
tessdll.dll, I think, so I assume it somehow isn't linked in
correctly, though the line "TessHandle = LoadLibrary("tessdll.dll");"
in cTessdll.cpp comes up with a valid TessHandle.

I tried it without adding a Tess library to the project, then also
both the original library, and then a new one by running IMPLIB on
tessdll.dll. It always immediately stopped at that point.

What am I doing wrong?

Thanks, I feel like I am getting very close. If I can get over this
hump I think I'm good to go.

Daryl

Morgy

unread,
Oct 10, 2008, 9:52:09 AM10/10/08
to tesseract-ocr
exiting without a error message means normaly that you don't have the
english language file, to be sure look for the tesseract.log

but your project directory should look like

project.exe
tessdll.dll
tessdata --------- eng.DangAmbigs
|- eng.freq-dawg
|- eng.inttemp
|- eng.normproto
|- eng.pffmtable
|- eng.unicharset
|- eng.user-words
- eng.word-dawg

Daryl

unread,
Oct 10, 2008, 1:28:01 PM10/10/08
to tesseract-ocr
Wonderful! That did it. And I apologize -- you did tell me earlier
that I needed those files. I didn't know about the tessdata.log file,
though. That will be useful.

I'm getting garbage results, but I'm glad to work that on my own -- I
can search the forums for others having similar problems in the past.
At least the program runs.
Thanks again.
Daryl
Reply all
Reply to author
Forward
0 new messages