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