1 /***************************************************************************
2                           Q_SRT.cpp  -  description
3                              -------------------
4 
5     Handle the QT specific part of the fontsize & position dialog box
6     copyright            : (C) 2002/2007 by mean
7     email                : fixounet@free.fr
8  ***************************************************************************/
9 
10 /***************************************************************************
11  *                                                                         *
12  *   This program is free software; you can redistribute it and/or modify  *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  ***************************************************************************/
18 
19 #include "Q_ocr.h"
20 #include "ADM_toolkitQt.h"
21 
22 //*********************************************
23 
setGlyph(admGlyph * glyph,admGlyph * head,char * decodedString)24 void Ui_ocrWindow::setGlyph(admGlyph *glyph,admGlyph *head,char *decodedString)
25 {
26 	_glyph=glyph;
27 	_head=head;
28 	_decodedString=decodedString;
29 }
30 
dialogReturn(ReplyType r)31 void Ui_ocrWindow::dialogReturn(ReplyType r)
32 {
33 	_reply=r;
34 	accept();
35 }
36 
resizeSmall(uint32_t w,uint32_t h,uint8_t * smallData)37 void Ui_ocrWindow::resizeSmall(uint32_t w,uint32_t h,uint8_t *smallData)
38 {
39 	smallCanvas->changeSize(w*2,h*2);
40 	smallCanvas->dataBuffer=smallData;
41 	QGraphicsView *graphicsView=ui.smallView;
42 
43 	graphicsView->resize(w*2, h*2);
44 	smallCanvas->setMinimumSize(w*2,h*2);
45 	smallCanvas->resize(w*2, h*2);
46 }
47 
Ui_ocrWindow(QWidget * parent)48 Ui_ocrWindow::Ui_ocrWindow(QWidget *parent) : QDialog(parent)
49 {
50 	ui.setupUi(this);
51 	ui.textEdit->setReadOnly(TRUE);
52 	data=NULL;
53 	_w=_h=100;
54 	canvas=new ADM_QCanvas(ui.bigView,_w,_h);
55 	smallCanvas= new ADM_QCanvas(ui.smallView,_w,_h);
56 #define BUTTON(x)   connect(ui.x,SIGNAL(clicked(bool)),this,SLOT(x(bool)))
57 	BUTTON(pushButtonCalibrate);
58 	BUTTON(pushButtonSkipAll);
59 	BUTTON(pushButtonSkip);
60 	BUTTON(pushButtonIgnore);
61 	BUTTON(pushButtonOk);
62 	BUTTON(pushButtonClose);
63 	_glyph=_head=NULL;
64 	_decodedString=NULL;
65 }
66 //***********************************************
67 
pushButtonSkip(bool i)68 void  Ui_ocrWindow::pushButtonSkip(bool i)
69   {
70 	  	dialogReturn(ReplySkip);
71   }
pushButtonSkipAll(bool i)72 void    Ui_ocrWindow::pushButtonSkipAll(bool i)
73   {
74 	  	dialogReturn(ReplySkipAll);
75   }
pushButtonIgnore(bool i)76 void  Ui_ocrWindow::pushButtonIgnore(bool i)
77   {
78 	  	ADM_assert(_glyph);
79 	  	ADM_assert(_head);
80 	  	_glyph->code=NULL;
81 	  	insertInGlyphTree(_head,_glyph);
82 	  	dialogReturn(ReplyOk);
83   }
pushButtonClose(bool i)84 void    Ui_ocrWindow::pushButtonClose(bool i)
85   {
86 	  	dialogReturn(ReplyClose);
87   }
pushButtonCalibrate(bool i)88 void    Ui_ocrWindow::pushButtonCalibrate(bool i)
89   {
90 	  	dialogReturn(ReplyCalibrate);
91   }
pushButtonOk(bool i)92 void    Ui_ocrWindow::pushButtonOk(bool i)
93   {
94 		// Retrieve content typed
95 	 		char *data=(ui.lineEdit->text()).toAscii().data(); // Memleak ??
96 	 		if(data&& strlen(data))
97 	                     {
98 	                         _glyph->code=ADM_strdup(data);
99 	                         insertInGlyphTree(_head,_glyph);
100 	                         strcat(_decodedString,_glyph->code);
101 	                     }
102 	  	dialogReturn(ReplyOk);
103   }
104 //***********************************************
~Ui_ocrWindow()105 Ui_ocrWindow::~Ui_ocrWindow()
106 {
107 	delete canvas;
108 	canvas=NULL;
109 
110 	delete smallCanvas;
111 	smallCanvas=NULL;
112 
113 	if(data) delete [] data;
114 	data=NULL;
115 }
116 
117 Ui_ocrWindow *gDialog=NULL;
118 /**
119  * 	\fn ADM_ocrUpdateNbLines
120  *  \brief Update the number of lines ocr'ed
121  */
ADM_ocrUpdateNbLines(void * ui,uint32_t cur,uint32_t total)122 uint8_t ADM_ocrUpdateNbLines(void *ui,uint32_t cur,uint32_t total)
123 {
124 	return 1;
125 }
126 /**
127  * 	\fn ADM_ocrUpdateNbGlyphs
128  *  \brief Update the number of glyphs learnt (not used ATM)
129  */
130 
ADM_ocrUpdateNbGlyphs(void * ui,uint32_t nbGlyphs)131 uint8_t ADM_ocrUpdateNbGlyphs(void *ui,uint32_t nbGlyphs)
132 {
133 	return 1;
134 }
135 /**
136  * 	\fn ADM_ocrUpdateTextAndTime
137  *  \brief Update the currently ocr'ed text from the current image
138  */
139 
ADM_ocrUpdateTextAndTime(void * ui,char * decodedString,char * timeCode)140 uint8_t ADM_ocrUpdateTextAndTime(void *ui,char *decodedString,char *timeCode)
141 {
142 	Ui_ocrWindow *dialog=( Ui_ocrWindow *)ui;
143 	 ADM_assert(dialog==gDialog);
144 	 if(timeCode)
145 	 {
146 		 QLabel *labelTimecode=dialog->ui.labelTimecode;
147 		 labelTimecode->setText(timeCode);
148 	 }
149 	 if(decodedString)
150 	 {
151 		 QTextEdit *textedit=dialog->ui.textEdit;
152 		 textedit->clear();
153 		 textedit->textCursor().insertText(decodedString);
154 	 }
155 	 UI_purge();
156 	return 1;
157 }
158 
convertBWtoRGB32(uint32_t w,uint32_t h,uint8_t * in,uint8_t * out)159 static void convertBWtoRGB32(uint32_t w,uint32_t h,uint8_t *in,uint8_t *out)
160 {
161 	for(int y=0;y<h;y++)
162 		for(int x=0;x<w;x++)
163 		{
164 			uint8_t a=*in++;
165 			*(out+0)=a;
166 			*(out+1)=a;
167 			*(out+2)=a;
168 			*(out+3)=255; // alpha
169 			out+=4;
170 		}
171 }
convertBWtoRGB32Zoom(uint32_t w,uint32_t h,uint32_t strideW,uint32_t strideH,uint8_t * in,uint8_t * out)172 static void convertBWtoRGB32Zoom(uint32_t w,uint32_t h,uint32_t strideW,uint32_t strideH,uint8_t *in,uint8_t *out)
173 {
174 	ADM_assert(strideW>=w);
175 	memset(out,0,strideW*strideH*4*4);
176 	for(int y=0;y<h;y++)
177 	{
178 		for(int x=0;x<w;x++)
179 		{
180 			uint8_t a=*in++;
181 			*(out+0)=a;
182 			*(out+1)=a;
183 			*(out+2)=a;
184 			*(out+3)=255; // alpha
185 			*(out+4)=a;
186 			*(out+5)=a;
187 			*(out+6)=a;
188 			*(out+7)=255; // alpha
189 			out+=8;
190 		}
191 		out+=(strideW-w)*8;
192 		memcpy(out,out-8*strideW,8*w);
193 		out+=8*strideW;
194 
195 	}
196 }
197 /**
198  * 	\fn ADM_ocrDrawFull
199  *  \brief Redraw the full image
200  *  @param data : uin8_t image to redraw (1 byte per pixel)
201  */
202 
ADM_ocrDrawFull(void * d,uint8_t * data)203 uint8_t ADM_ocrDrawFull(void *d,uint8_t *data)
204 {
205 	Ui_ocrWindow *dialog=( Ui_ocrWindow *)d;
206 	ADM_assert(dialog==gDialog);
207 	uint8_t *out=dialog->data;
208 	uint8_t *in=data;
209 	uint32_t w=dialog->_w,h=dialog->_h;
210 
211 	convertBWtoRGB32(w,h,in,out);
212 
213 	// Paint!
214 
215 	dialog->canvas->dataBuffer=dialog->data;
216 
217 
218 	QGraphicsView *graphicsView=dialog->ui.bigView;
219 
220 	graphicsView->resize(w, h);
221 	dialog->canvas->setMinimumSize(w,h);
222 	dialog->canvas->resize(w, h);
223 
224 
225 
226 	dialog->canvas->repaint();
227 	return 1;
228 }
229 /**
230  * 	\fn ADM_ocrSetRedrawSize
231  *  \brief Set the new image dimensions. Redraw is disabled until ocrDrawFull is called with new datas
232  *  @param w New image width
233  *  @param h New image height
234  */
235 
ADM_ocrSetRedrawSize(void * d,uint32_t w,uint32_t h)236 uint8_t ADM_ocrSetRedrawSize(void *d,uint32_t w,uint32_t h)
237 {
238 	Ui_ocrWindow *dialog=( Ui_ocrWindow *)d;
239 	ADM_assert(dialog==gDialog);
240 	dialog->_w=w;
241 	dialog->_h=h;
242 
243 	dialog->canvas->changeSize(w,h);
244 
245 	if(dialog->data) delete [] dialog->data;
246 	dialog->data=NULL;
247 	dialog->data=new uint8_t[w*h*4];
248 
249 
250 	return 1;
251 }
252 /**
253  * 	\fn ADM_ocrUiEnd
254  *  \brief Destroy the UI for OCR
255  */
256 
257 
ADM_ocrUiEnd(void * d)258 uint8_t ADM_ocrUiEnd(void *d)
259 {
260 	   Ui_ocrWindow *dialog=( Ui_ocrWindow *)d;
261 	   ADM_assert(dialog==gDialog);
262 
263 	   qtUnregisterDialog(dialog);
264 
265 	   gDialog=NULL;
266 	   delete dialog;
267 	   return 1;
268 }
269 /**
270  * 	\fn ADM_ocrUiSetup
271  *  \brief Create OCR UI
272  */
273 
ADM_ocrUiSetup(void)274 void 	*ADM_ocrUiSetup(void)
275 {
276 	   Ui_ocrWindow *dialog=new Ui_ocrWindow(qtLastRegisteredDialog());
277 	   qtRegisterDialog(dialog);
278 	   dialog->setModal(TRUE);
279 	   dialog->show();
280 	   gDialog=dialog;
281 	   return dialog;
282 }
283 /**
284  * 	\fn glyphToText
285  *  \brief OCR one gluph
286  *  @param glyph : Glyph to OCR
287  *  @param head  : Pointer to the head of known glyph
288  *  @param decodedString : String containing the current ocred text so far
289  *  FIXME : Add ui as parameter!!
290  */
291 #define MAX_W 32
292 #define MAX_H 32
293 
glyphToText(admGlyph * glyph,admGlyph * head,char * decodedString)294 ReplyType glyphToText(admGlyph *glyph,admGlyph *head,char *decodedString)
295 {
296 	// First draw small glyph
297 	uint32_t w,h,clipW,clipH;
298 	w=glyph->width;
299 	h=glyph->height;
300 
301 	// Known glyph ?
302 	  if(glyph->width<2 && glyph->height<2)
303 	  {
304 	         // ????delete glyph;
305 	         return ReplyOk;
306 	   }
307 	  admGlyph *cand=NULL;
308 	  cand=searchGlyph(head,glyph);
309 	  if(cand) // New glyph?
310 	  {
311 		   if(cand->code)
312 			   		strcat(decodedString,cand->code);
313 		   	delete glyph;
314 		   	return ReplyOk;
315 	  }
316 	  // Yes, it is a new one
317 	//
318 #ifndef MAX
319         #define MAX(a,b) a>b?a:b
320 #endif
321 	 clipW=MAX(MAX_W,w);
322 	 clipH=MAX(MAX_H,h);
323 	// Set datas too
324 	uint8_t smallData[clipW*clipH*4*4];
325 	// upscale & convert to RGB32 for display
326 	convertBWtoRGB32Zoom(w,h,clipW,clipH,glyph->data,smallData);
327 	//
328 	gDialog->resizeSmall(clipW,clipH,smallData);
329 	//
330 	gDialog->setGlyph(glyph,head,decodedString);
331 	//
332 	gDialog->ui.lineEdit->clear();
333 	gDialog->ui.lineEdit->setFocus(Qt::OtherFocusReason);
334 	ADM_ocrUpdateTextAndTime(gDialog,decodedString,NULL); // put ocred text so far
335 	//
336     gDialog->exec();
337 
338     gDialog->smallCanvas->dataBuffer=NULL;
339     // ???delete glyph;
340 	return gDialog->_reply;
341 }
342 
343 //____________________________________
344 // EOF
345