Leptonica 1.82.0
Image processing and image analysis suite
fmorphauto.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
27
99#ifdef HAVE_CONFIG_H
100#include <config_auto.h>
101#endif /* HAVE_CONFIG_H */
102
103#include <string.h>
104#include "allheaders.h"
105
106#define OUTROOT "fmorphgen"
107#define TEMPLATE1 "morphtemplate1.txt"
108#define TEMPLATE2 "morphtemplate2.txt"
109
110#define PROTOARGS "(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32);"
111
112#define L_BUF_SIZE 512
113
114static char * makeBarrelshiftString(l_int32 delx, l_int32 dely);
115static SARRAY * sarrayMakeInnerLoopDWACode(SEL *sel, l_int32 index);
116static SARRAY * sarrayMakeWplsCode(SEL *sel);
117
118static char wpldecls[][53] = {
119 "l_int32 wpls2;",
120 "l_int32 wpls2, wpls3;",
121 "l_int32 wpls2, wpls3, wpls4;",
122 "l_int32 wpls5;",
123 "l_int32 wpls5, wpls6;",
124 "l_int32 wpls5, wpls6, wpls7;",
125 "l_int32 wpls5, wpls6, wpls7, wpls8;",
126 "l_int32 wpls9;",
127 "l_int32 wpls9, wpls10;",
128 "l_int32 wpls9, wpls10, wpls11;",
129 "l_int32 wpls9, wpls10, wpls11, wpls12;",
130 "l_int32 wpls13;",
131 "l_int32 wpls13, wpls14;",
132 "l_int32 wpls13, wpls14, wpls15;",
133 "l_int32 wpls13, wpls14, wpls15, wpls16;",
134 "l_int32 wpls17;",
135 "l_int32 wpls17, wpls18;",
136 "l_int32 wpls17, wpls18, wpls19;",
137 "l_int32 wpls17, wpls18, wpls19, wpls20;",
138 "l_int32 wpls21;",
139 "l_int32 wpls21, wpls22;",
140 "l_int32 wpls21, wpls22, wpls23;",
141 "l_int32 wpls21, wpls22, wpls23, wpls24;",
142 "l_int32 wpls25;",
143 "l_int32 wpls25, wpls26;",
144 "l_int32 wpls25, wpls26, wpls27;",
145 "l_int32 wpls25, wpls26, wpls27, wpls28;",
146 "l_int32 wpls29;",
147 "l_int32 wpls29, wpls30;",
148 "l_int32 wpls29, wpls30, wpls31;"};
149
150static char wplgendecls[][30] = {
151 "l_int32 wpls2;",
152 "l_int32 wpls3;",
153 "l_int32 wpls4;",
154 "l_int32 wpls5;",
155 "l_int32 wpls6;",
156 "l_int32 wpls7;",
157 "l_int32 wpls8;",
158 "l_int32 wpls9;",
159 "l_int32 wpls10;",
160 "l_int32 wpls11;",
161 "l_int32 wpls12;",
162 "l_int32 wpls13;",
163 "l_int32 wpls14;",
164 "l_int32 wpls15;",
165 "l_int32 wpls16;",
166 "l_int32 wpls17;",
167 "l_int32 wpls18;",
168 "l_int32 wpls19;",
169 "l_int32 wpls20;",
170 "l_int32 wpls21;",
171 "l_int32 wpls22;",
172 "l_int32 wpls23;",
173 "l_int32 wpls24;",
174 "l_int32 wpls25;",
175 "l_int32 wpls26;",
176 "l_int32 wpls27;",
177 "l_int32 wpls28;",
178 "l_int32 wpls29;",
179 "l_int32 wpls30;",
180 "l_int32 wpls31;"};
181
182static char wpldefs[][25] = {
183 " wpls2 = 2 * wpls;",
184 " wpls3 = 3 * wpls;",
185 " wpls4 = 4 * wpls;",
186 " wpls5 = 5 * wpls;",
187 " wpls6 = 6 * wpls;",
188 " wpls7 = 7 * wpls;",
189 " wpls8 = 8 * wpls;",
190 " wpls9 = 9 * wpls;",
191 " wpls10 = 10 * wpls;",
192 " wpls11 = 11 * wpls;",
193 " wpls12 = 12 * wpls;",
194 " wpls13 = 13 * wpls;",
195 " wpls14 = 14 * wpls;",
196 " wpls15 = 15 * wpls;",
197 " wpls16 = 16 * wpls;",
198 " wpls17 = 17 * wpls;",
199 " wpls18 = 18 * wpls;",
200 " wpls19 = 19 * wpls;",
201 " wpls20 = 20 * wpls;",
202 " wpls21 = 21 * wpls;",
203 " wpls22 = 22 * wpls;",
204 " wpls23 = 23 * wpls;",
205 " wpls24 = 24 * wpls;",
206 " wpls25 = 25 * wpls;",
207 " wpls26 = 26 * wpls;",
208 " wpls27 = 27 * wpls;",
209 " wpls28 = 28 * wpls;",
210 " wpls29 = 29 * wpls;",
211 " wpls30 = 30 * wpls;",
212 " wpls31 = 31 * wpls;"};
213
214static char wplstrp[][10] = {"+ wpls", "+ wpls2", "+ wpls3", "+ wpls4",
215 "+ wpls5", "+ wpls6", "+ wpls7", "+ wpls8",
216 "+ wpls9", "+ wpls10", "+ wpls11", "+ wpls12",
217 "+ wpls13", "+ wpls14", "+ wpls15", "+ wpls16",
218 "+ wpls17", "+ wpls18", "+ wpls19", "+ wpls20",
219 "+ wpls21", "+ wpls22", "+ wpls23", "+ wpls24",
220 "+ wpls25", "+ wpls26", "+ wpls27", "+ wpls28",
221 "+ wpls29", "+ wpls30", "+ wpls31"};
222
223static char wplstrm[][10] = {"- wpls", "- wpls2", "- wpls3", "- wpls4",
224 "- wpls5", "- wpls6", "- wpls7", "- wpls8",
225 "- wpls9", "- wpls10", "- wpls11", "- wpls12",
226 "- wpls13", "- wpls14", "- wpls15", "- wpls16",
227 "- wpls17", "- wpls18", "- wpls19", "- wpls20",
228 "- wpls21", "- wpls22", "- wpls23", "- wpls24",
229 "- wpls25", "- wpls26", "- wpls27", "- wpls28",
230 "- wpls29", "- wpls30", "- wpls31"};
231
232
248l_ok
250 l_int32 fileindex,
251 const char *filename)
252{
253l_int32 ret1, ret2;
254
255 PROCNAME("fmorphautogen");
256
257 if (!sela)
258 return ERROR_INT("sela not defined", procName, 1);
259 ret1 = fmorphautogen1(sela, fileindex, filename);
260 ret2 = fmorphautogen2(sela, fileindex, filename);
261 if (ret1 || ret2)
262 return ERROR_INT("code generation problem", procName, 1);
263 return 0;
264}
265
266
288l_ok
290 l_int32 fileindex,
291 const char *filename)
292{
293char *filestr;
294char *str_proto1, *str_proto2, *str_proto3;
295char *str_doc1, *str_doc2, *str_doc3, *str_doc4;
296char *str_def1, *str_def2, *str_proc1, *str_proc2;
297char *str_dwa1, *str_low_dt, *str_low_ds, *str_low_ts;
298char *str_low_tsp1, *str_low_dtp1;
299char bigbuf[L_BUF_SIZE];
300l_int32 i, nsels, nbytes, actstart, end, newstart;
301size_t size;
302SARRAY *sa1, *sa2, *sa3;
303
304 PROCNAME("fmorphautogen1");
305
306 if (!sela)
307 return ERROR_INT("sela not defined", procName, 1);
308 if (fileindex < 0)
309 fileindex = 0;
310 if ((nsels = selaGetCount(sela)) == 0)
311 return ERROR_INT("no sels in sela", procName, 1);
312
313 /* Make array of textlines from morphtemplate1.txt */
314 if ((filestr = (char *)l_binaryRead(TEMPLATE1, &size)) == NULL)
315 return ERROR_INT("filestr not made", procName, 1);
316 sa2 = sarrayCreateLinesFromString(filestr, 1);
317 LEPT_FREE(filestr);
318 if (!sa2)
319 return ERROR_INT("sa2 not made", procName, 1);
320
321 /* Make array of sel names */
322 sa1 = selaGetSelnames(sela);
323
324 /* Make strings containing function call names */
325 sprintf(bigbuf, "PIX *pixMorphDwa_%d(PIX *pixd, PIX *pixs, "
326 "l_int32 operation, char *selname);", fileindex);
327 str_proto1 = stringNew(bigbuf);
328 sprintf(bigbuf, "PIX *pixFMorphopGen_%d(PIX *pixd, PIX *pixs, "
329 "l_int32 operation, char *selname);", fileindex);
330 str_proto2 = stringNew(bigbuf);
331 sprintf(bigbuf, "l_int32 fmorphopgen_low_%d(l_uint32 *datad, l_int32 w,\n"
332 " l_int32 h, l_int32 wpld,\n"
333 " l_uint32 *datas, l_int32 wpls,\n"
334 " l_int32 index);", fileindex);
335 str_proto3 = stringNew(bigbuf);
336 sprintf(bigbuf, " * PIX *pixMorphDwa_%d()", fileindex);
337 str_doc1 = stringNew(bigbuf);
338 sprintf(bigbuf, " * PIX *pixFMorphopGen_%d()", fileindex);
339 str_doc2 = stringNew(bigbuf);
340 sprintf(bigbuf, " * \\brief pixMorphDwa_%d()", fileindex);
341 str_doc3 = stringNew(bigbuf);
342 sprintf(bigbuf, " * \\brief pixFMorphopGen_%d()", fileindex);
343 str_doc4 = stringNew(bigbuf);
344 sprintf(bigbuf, "pixMorphDwa_%d(PIX *pixd,", fileindex);
345 str_def1 = stringNew(bigbuf);
346 sprintf(bigbuf, "pixFMorphopGen_%d(PIX *pixd,", fileindex);
347 str_def2 = stringNew(bigbuf);
348 sprintf(bigbuf, " PROCNAME(\"pixMorphDwa_%d\");", fileindex);
349 str_proc1 = stringNew(bigbuf);
350 sprintf(bigbuf, " PROCNAME(\"pixFMorphopGen_%d\");", fileindex);
351 str_proc2 = stringNew(bigbuf);
352 sprintf(bigbuf,
353 " pixt2 = pixFMorphopGen_%d(NULL, pixt1, operation, selname);",
354 fileindex);
355 str_dwa1 = stringNew(bigbuf);
356 sprintf(bigbuf,
357 " fmorphopgen_low_%d(datad, w, h, wpld, datat, wpls, index);",
358 fileindex);
359 str_low_dt = stringNew(bigbuf);
360 sprintf(bigbuf,
361 " fmorphopgen_low_%d(datad, w, h, wpld, datas, wpls, index);",
362 fileindex);
363 str_low_ds = stringNew(bigbuf);
364 sprintf(bigbuf,
365 " fmorphopgen_low_%d(datat, w, h, wpls, datas, wpls, index+1);",
366 fileindex);
367 str_low_tsp1 = stringNew(bigbuf);
368 sprintf(bigbuf,
369 " fmorphopgen_low_%d(datat, w, h, wpls, datas, wpls, index);",
370 fileindex);
371 str_low_ts = stringNew(bigbuf);
372 sprintf(bigbuf,
373 " fmorphopgen_low_%d(datad, w, h, wpld, datat, wpls, index+1);",
374 fileindex);
375 str_low_dtp1 = stringNew(bigbuf);
376
377 /* Make the output sa */
378 sa3 = sarrayCreate(0);
379
380 /* Copyright notice and info header */
381 sarrayParseRange(sa2, 0, &actstart, &end, &newstart, "--", 0);
382 sarrayAppendRange(sa3, sa2, actstart, end);
383
384 /* Insert function names as documentation */
385 sarrayAddString(sa3, str_doc1, L_INSERT);
386 sarrayAddString(sa3, str_doc2, L_INSERT);
387
388 /* Add '#include's */
389 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
390 sarrayAppendRange(sa3, sa2, actstart, end);
391
392 /* Insert function prototypes */
393 sarrayAddString(sa3, str_proto1, L_INSERT);
394 sarrayAddString(sa3, str_proto2, L_INSERT);
395 sarrayAddString(sa3, str_proto3, L_INSERT);
396
397 /* Add static globals */
398 sprintf(bigbuf, "\nstatic l_int32 NUM_SELS_GENERATED = %d;", nsels);
399 sarrayAddString(sa3, bigbuf, L_COPY);
400 sprintf(bigbuf, "static char SEL_NAMES[][80] = {");
401 sarrayAddString(sa3, bigbuf, L_COPY);
402 for (i = 0; i < nsels - 1; i++) {
403 sprintf(bigbuf, " \"%s\",",
404 sarrayGetString(sa1, i, L_NOCOPY));
405 sarrayAddString(sa3, bigbuf, L_COPY);
406 }
407 sprintf(bigbuf, " \"%s\"};",
408 sarrayGetString(sa1, i, L_NOCOPY));
409 sarrayAddString(sa3, bigbuf, L_COPY);
410
411 /* Start pixMorphDwa_*() function description */
412 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
413 sarrayAppendRange(sa3, sa2, actstart, end);
414 sarrayAddString(sa3, str_doc3, L_INSERT);
415 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
416 sarrayAppendRange(sa3, sa2, actstart, end);
417
418 /* Finish pixMorphDwa_*() function definition */
419 sarrayAddString(sa3, str_def1, L_INSERT);
420 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
421 sarrayAppendRange(sa3, sa2, actstart, end);
422 sarrayAddString(sa3, str_proc1, L_INSERT);
423 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
424 sarrayAppendRange(sa3, sa2, actstart, end);
425 sarrayAddString(sa3, str_dwa1, L_INSERT);
426 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
427 sarrayAppendRange(sa3, sa2, actstart, end);
428
429 /* Start pixFMorphopGen_*() function description */
430 sarrayAddString(sa3, str_doc4, L_INSERT);
431 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
432 sarrayAppendRange(sa3, sa2, actstart, end);
433
434 /* Finish pixFMorphopGen_*() function definition */
435 sarrayAddString(sa3, str_def2, L_INSERT);
436 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
437 sarrayAppendRange(sa3, sa2, actstart, end);
438 sarrayAddString(sa3, str_proc2, L_INSERT);
439 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
440 sarrayAppendRange(sa3, sa2, actstart, end);
441 sarrayAddString(sa3, str_low_dt, L_COPY);
442 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
443 sarrayAppendRange(sa3, sa2, actstart, end);
444 sarrayAddString(sa3, str_low_ds, L_INSERT);
445 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
446 sarrayAppendRange(sa3, sa2, actstart, end);
447 sarrayAddString(sa3, str_low_tsp1, L_INSERT);
448 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
449 sarrayAppendRange(sa3, sa2, actstart, end);
450 sarrayAddString(sa3, str_low_dt, L_INSERT);
451 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
452 sarrayAppendRange(sa3, sa2, actstart, end);
453 sarrayAddString(sa3, str_low_ts, L_INSERT);
454 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
455 sarrayAppendRange(sa3, sa2, actstart, end);
456 sarrayAddString(sa3, str_low_dtp1, L_INSERT);
457 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0);
458 sarrayAppendRange(sa3, sa2, actstart, end);
459
460 /* Output to file */
461 filestr = sarrayToString(sa3, 1);
462 nbytes = strlen(filestr);
463 if (filename)
464 snprintf(bigbuf, L_BUF_SIZE, "%s.%d.c", filename, fileindex);
465 else
466 sprintf(bigbuf, "%s.%d.c", OUTROOT, fileindex);
467 l_binaryWrite(bigbuf, "w", filestr, nbytes);
468 sarrayDestroy(&sa1);
469 sarrayDestroy(&sa2);
470 sarrayDestroy(&sa3);
471 LEPT_FREE(filestr);
472 return 0;
473}
474
475
476/*
477 * fmorphautogen2()
478 *
479 * Input: sela
480 * fileindex
481 * filename (<optional>; can be null)
482 * Return: 0 if OK; 1 on error
483 *
484 * Notes:
485 * (1) This function uses morphtemplate2.txt to create a
486 * low-level file that contains the low-level functions for
487 * implementing dilation and erosion for every sel
488 * in the input sela.
489 * (2) The fileindex parameter is inserted into the output
490 * filename, as described below.
491 * (3) If filename == NULL, the output file is fmorphgenlow.[n].c,
492 * where [n] is equal to the 'fileindex' parameter.
493 * (4) If filename != NULL, the output file is [filename]low.[n].c.
494 */
495l_int32
496fmorphautogen2(SELA *sela,
497 l_int32 fileindex,
498 const char *filename)
499{
500char *filestr, *linestr, *fname;
501char *str_doc1, *str_doc2, *str_doc3, *str_doc4, *str_def1;
502char bigbuf[L_BUF_SIZE];
503char breakstring[] = " break;";
504char staticstring[] = "static void";
505l_int32 i, nsels, nbytes, actstart, end, newstart;
506l_int32 argstart, argend, loopstart, loopend, finalstart, finalend;
507size_t size;
508SARRAY *sa1, *sa2, *sa3, *sa4, *sa5, *sa6;
509SEL *sel;
510
511 PROCNAME("fmorphautogen2");
512
513 if (!sela)
514 return ERROR_INT("sela not defined", procName, 1);
515 if (fileindex < 0)
516 fileindex = 0;
517 if ((nsels = selaGetCount(sela)) == 0)
518 return ERROR_INT("no sels in sela", procName, 1);
519
520 /* Make the array of textlines from morphtemplate2.txt */
521 if ((filestr = (char *)l_binaryRead(TEMPLATE2, &size)) == NULL)
522 return ERROR_INT("filestr not made", procName, 1);
523 sa1 = sarrayCreateLinesFromString(filestr, 1);
524 LEPT_FREE(filestr);
525 if (!sa1)
526 return ERROR_INT("sa1 not made", procName, 1);
527
528 /* Make the array of static function names */
529 if ((sa2 = sarrayCreate(2 * nsels)) == NULL) {
530 sarrayDestroy(&sa1);
531 return ERROR_INT("sa2 not made", procName, 1);
532 }
533 for (i = 0; i < nsels; i++) {
534 sprintf(bigbuf, "fdilate_%d_%d", fileindex, i);
535 sarrayAddString(sa2, bigbuf, L_COPY);
536 sprintf(bigbuf, "ferode_%d_%d", fileindex, i);
537 sarrayAddString(sa2, bigbuf, L_COPY);
538 }
539
540 /* Make the static prototype strings */
541 sa3 = sarrayCreate(2 * nsels); /* should be ok */
542 for (i = 0; i < 2 * nsels; i++) {
543 fname = sarrayGetString(sa2, i, L_NOCOPY);
544 sprintf(bigbuf, "static void %s%s", fname, PROTOARGS);
545 sarrayAddString(sa3, bigbuf, L_COPY);
546 }
547
548 /* Make strings containing function names */
549 sprintf(bigbuf, " * l_int32 fmorphopgen_low_%d()",
550 fileindex);
551 str_doc1 = stringNew(bigbuf);
552 sprintf(bigbuf, " * void fdilate_%d_*()", fileindex);
553 str_doc2 = stringNew(bigbuf);
554 sprintf(bigbuf, " * void ferode_%d_*()", fileindex);
555 str_doc3 = stringNew(bigbuf);
556
557 /* Output to this sa */
558 sa4 = sarrayCreate(0);
559
560 /* Copyright notice and info header */
561 sarrayParseRange(sa1, 0, &actstart, &end, &newstart, "--", 0);
562 sarrayAppendRange(sa4, sa1, actstart, end);
563
564 /* Insert function names as documentation */
565 sarrayAddString(sa4, str_doc1, L_INSERT);
566 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0);
567 sarrayAppendRange(sa4, sa1, actstart, end);
568 sarrayAddString(sa4, str_doc2, L_INSERT);
569 sarrayAddString(sa4, str_doc3, L_INSERT);
570 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0);
571 sarrayAppendRange(sa4, sa1, actstart, end);
572
573 /* Insert static protos */
574 for (i = 0; i < 2 * nsels; i++) {
575 if ((linestr = sarrayGetString(sa3, i, L_COPY)) == NULL) {
576 sarrayDestroy(&sa1);
577 sarrayDestroy(&sa2);
578 sarrayDestroy(&sa3);
579 sarrayDestroy(&sa4);
580 return ERROR_INT("linestr not retrieved", procName, 1);
581 }
582 sarrayAddString(sa4, linestr, L_INSERT);
583 }
584
585 /* More strings with function names */
586 sprintf(bigbuf, " * fmorphopgen_low_%d()", fileindex);
587 str_doc4 = stringNew(bigbuf);
588 sprintf(bigbuf, "fmorphopgen_low_%d(l_uint32 *datad,", fileindex);
589 str_def1 = stringNew(bigbuf);
590
591 /* Insert function header */
592 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0);
593 sarrayAppendRange(sa4, sa1, actstart, end);
594 sarrayAddString(sa4, str_doc4, L_INSERT);
595 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0);
596 sarrayAppendRange(sa4, sa1, actstart, end);
597 sarrayAddString(sa4, str_def1, L_INSERT);
598 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0);
599 sarrayAppendRange(sa4, sa1, actstart, end);
600
601 /* Generate and insert the dispatcher code */
602 for (i = 0; i < 2 * nsels; i++) {
603 sprintf(bigbuf, " case %d:", i);
604 sarrayAddString(sa4, bigbuf, L_COPY);
605 sprintf(bigbuf, " %s(datad, w, h, wpld, datas, wpls);",
606 sarrayGetString(sa2, i, L_NOCOPY));
607 sarrayAddString(sa4, bigbuf, L_COPY);
608 sarrayAddString(sa4, breakstring, L_COPY);
609 }
610
611 /* Finish the dispatcher and introduce the low-level code */
612 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0);
613 sarrayAppendRange(sa4, sa1, actstart, end);
614
615 /* Get the range for the args common to all functions */
616 sarrayParseRange(sa1, newstart, &argstart, &argend, &newstart, "--", 0);
617
618 /* Get the range for the loop code common to all functions */
619 sarrayParseRange(sa1, newstart, &loopstart, &loopend, &newstart, "--", 0);
620
621 /* Get the range for the ending code common to all functions */
622 sarrayParseRange(sa1, newstart, &finalstart, &finalend, &newstart, "--", 0);
623
624 /* Do all the static functions */
625 for (i = 0; i < 2 * nsels; i++) {
626 /* Generate the function header and add the common args */
627 sarrayAddString(sa4, staticstring, L_COPY);
628 fname = sarrayGetString(sa2, i, L_NOCOPY);
629 sprintf(bigbuf, "%s(l_uint32 *datad,", fname);
630 sarrayAddString(sa4, bigbuf, L_COPY);
631 sarrayAppendRange(sa4, sa1, argstart, argend);
632
633 /* Declare and define wplsN args, as necessary */
634 if ((sel = selaGetSel(sela, i/2)) == NULL) {
635 sarrayDestroy(&sa1);
636 sarrayDestroy(&sa2);
637 sarrayDestroy(&sa3);
638 sarrayDestroy(&sa4);
639 return ERROR_INT("sel not returned", procName, 1);
640 }
641 sa5 = sarrayMakeWplsCode(sel);
642 sarrayJoin(sa4, sa5);
643 sarrayDestroy(&sa5);
644
645 /* Add the function loop code */
646 sarrayAppendRange(sa4, sa1, loopstart, loopend);
647
648 /* Insert barrel-op code for *dptr */
649 sa6 = sarrayMakeInnerLoopDWACode(sel, i);
650 sarrayJoin(sa4, sa6);
651 sarrayDestroy(&sa6);
652
653 /* Finish the function code */
654 sarrayAppendRange(sa4, sa1, finalstart, finalend);
655 }
656
657 /* Output to file */
658 filestr = sarrayToString(sa4, 1);
659 nbytes = strlen(filestr);
660 if (filename)
661 snprintf(bigbuf, L_BUF_SIZE, "%slow.%d.c", filename, fileindex);
662 else
663 sprintf(bigbuf, "%slow.%d.c", OUTROOT, fileindex);
664 l_binaryWrite(bigbuf, "w", filestr, nbytes);
665 sarrayDestroy(&sa1);
666 sarrayDestroy(&sa2);
667 sarrayDestroy(&sa3);
668 sarrayDestroy(&sa4);
669 LEPT_FREE(filestr);
670 return 0;
671}
672
673
674/*--------------------------------------------------------------------------*
675 * Helper code for sel *
676 *--------------------------------------------------------------------------*/
680static SARRAY *
682{
683char emptystring[] = "";
684l_int32 i, j, ymax, dely, allvshifts;
685l_int32 vshift[32];
686SARRAY *sa;
687
688 PROCNAME("sarrayMakeWplsCode");
689
690 if (!sel)
691 return (SARRAY *)ERROR_PTR("sel not defined", procName, NULL);
692
693 for (i = 0; i < 32; i++)
694 vshift[i] = 0;
695 ymax = 0;
696 for (i = 0; i < sel->sy; i++) {
697 for (j = 0; j < sel->sx; j++) {
698 if (sel->data[i][j] == 1) {
699 dely = L_ABS(i - sel->cy);
700 if (dely < 32)
701 vshift[dely] = 1;
702 ymax = L_MAX(ymax, dely);
703 }
704 }
705 }
706 if (ymax > 31) {
707 L_WARNING("ymax > 31; truncating to 31\n", procName);
708 ymax = 31;
709 }
710
711 /* Test if this is a vertical brick */
712 allvshifts = TRUE;
713 for (i = 0; i < ymax; i++) {
714 if (vshift[i] == 0) {
715 allvshifts = FALSE;
716 break;
717 }
718 }
719
720 sa = sarrayCreate(0);
721
722 /* Add declarations */
723 if (allvshifts == TRUE) { /* packs them as well as possible */
724 if (ymax > 4)
725 sarrayAddString(sa, wpldecls[2], L_COPY);
726 if (ymax > 8)
727 sarrayAddString(sa, wpldecls[6], L_COPY);
728 if (ymax > 12)
729 sarrayAddString(sa, wpldecls[10], L_COPY);
730 if (ymax > 16)
731 sarrayAddString(sa, wpldecls[14], L_COPY);
732 if (ymax > 20)
733 sarrayAddString(sa, wpldecls[18], L_COPY);
734 if (ymax > 24)
735 sarrayAddString(sa, wpldecls[22], L_COPY);
736 if (ymax > 28)
737 sarrayAddString(sa, wpldecls[26], L_COPY);
738 if (ymax > 1)
739 sarrayAddString(sa, wpldecls[ymax - 2], L_COPY);
740 } else { /* puts them one/line */
741 for (i = 2; i <= ymax; i++) {
742 if (vshift[i])
743 sarrayAddString(sa, wplgendecls[i - 2], L_COPY);
744 }
745 }
746
747 sarrayAddString(sa, emptystring, L_COPY);
748
749 /* Add definitions */
750 for (i = 2; i <= ymax; i++) {
751 if (vshift[i])
752 sarrayAddString(sa, wpldefs[i - 2], L_COPY);
753 }
754
755 return sa;
756}
757
758
762static SARRAY *
764 l_int32 index)
765{
766char *tstr, *string;
767char logicalor[] = "|";
768char logicaland[] = "&";
769char bigbuf[L_BUF_SIZE];
770l_int32 i, j, optype, count, nfound, delx, dely;
771SARRAY *sa;
772
773 PROCNAME("sarrayMakeInnerLoopDWACode");
774
775 if (!sel)
776 return (SARRAY *)ERROR_PTR("sel not defined", procName, NULL);
777
778 if (index % 2 == 0) {
779 optype = L_MORPH_DILATE;
780 tstr = logicalor;
781 } else {
782 optype = L_MORPH_ERODE;
783 tstr = logicaland;
784 }
785
786 count = 0;
787 for (i = 0; i < sel->sy; i++) {
788 for (j = 0; j < sel->sx; j++) {
789 if (sel->data[i][j] == 1)
790 count++;
791 }
792 }
793
794 sa = sarrayCreate(0);
795 if (count == 0) {
796 L_WARNING("no hits in Sel %d\n", procName, index);
797 return sa; /* no code inside! */
798 }
799
800 nfound = 0;
801 for (i = 0; i < sel->sy; i++) {
802 for (j = 0; j < sel->sx; j++) {
803 if (sel->data[i][j] == 1) {
804 nfound++;
805 if (optype == L_MORPH_DILATE) {
806 dely = sel->cy - i;
807 delx = sel->cx - j;
808 } else { /* optype == L_MORPH_ERODE */
809 dely = i - sel->cy;
810 delx = j - sel->cx;
811 }
812 if ((string = makeBarrelshiftString(delx, dely)) == NULL) {
813 L_WARNING("barrel shift string not made\n", procName);
814 continue;
815 }
816 if (count == 1) /* just one item */
817 sprintf(bigbuf, " *dptr = %s;", string);
818 else if (nfound == 1)
819 sprintf(bigbuf, " *dptr = %s %s", string, tstr);
820 else if (nfound < count)
821 sprintf(bigbuf, " %s %s", string, tstr);
822 else /* nfound == count */
823 sprintf(bigbuf, " %s;", string);
824 sarrayAddString(sa, bigbuf, L_COPY);
825 LEPT_FREE(string);
826 }
827 }
828 }
829
830 return sa;
831}
832
833
837static char *
838makeBarrelshiftString(l_int32 delx, /* j - cx */
839 l_int32 dely) /* i - cy */
840{
841l_int32 absx, absy;
842char bigbuf[L_BUF_SIZE];
843
844 PROCNAME("makeBarrelshiftString");
845
846 if (delx < -31 || delx > 31)
847 return (char *)ERROR_PTR("delx out of bounds", procName, NULL);
848 if (dely < -31 || dely > 31)
849 return (char *)ERROR_PTR("dely out of bounds", procName, NULL);
850 absx = L_ABS(delx);
851 absy = L_ABS(dely);
852
853 if ((delx == 0) && (dely == 0))
854 sprintf(bigbuf, "(*sptr)");
855 else if ((delx == 0) && (dely < 0))
856 sprintf(bigbuf, "(*(sptr %s))", wplstrm[absy - 1]);
857 else if ((delx == 0) && (dely > 0))
858 sprintf(bigbuf, "(*(sptr %s))", wplstrp[absy - 1]);
859 else if ((delx < 0) && (dely == 0))
860 sprintf(bigbuf, "((*(sptr) >> %d) | (*(sptr - 1) << %d))",
861 absx, 32 - absx);
862 else if ((delx > 0) && (dely == 0))
863 sprintf(bigbuf, "((*(sptr) << %d) | (*(sptr + 1) >> %d))",
864 absx, 32 - absx);
865 else if ((delx < 0) && (dely < 0))
866 sprintf(bigbuf, "((*(sptr %s) >> %d) | (*(sptr %s - 1) << %d))",
867 wplstrm[absy - 1], absx, wplstrm[absy - 1], 32 - absx);
868 else if ((delx > 0) && (dely < 0))
869 sprintf(bigbuf, "((*(sptr %s) << %d) | (*(sptr %s + 1) >> %d))",
870 wplstrm[absy - 1], absx, wplstrm[absy - 1], 32 - absx);
871 else if ((delx < 0) && (dely > 0))
872 sprintf(bigbuf, "((*(sptr %s) >> %d) | (*(sptr %s - 1) << %d))",
873 wplstrp[absy - 1], absx, wplstrp[absy - 1], 32 - absx);
874 else /* ((delx > 0) && (dely > 0)) */
875 sprintf(bigbuf, "((*(sptr %s) << %d) | (*(sptr %s + 1) >> %d))",
876 wplstrp[absy - 1], absx, wplstrp[absy - 1], 32 - absx);
877
878 return stringNew(bigbuf);
879}
#define L_BUF_SIZE
Definition: classapp.c:59
static SARRAY * sarrayMakeInnerLoopDWACode(SEL *sel, l_int32 index)
sarrayMakeInnerLoopDWACode()
Definition: fmorphauto.c:763
l_ok fmorphautogen1(SELA *sela, l_int32 fileindex, const char *filename)
fmorphautogen1()
Definition: fmorphauto.c:289
static SARRAY * sarrayMakeWplsCode(SEL *sel)
sarrayMakeWplsCode()
Definition: fmorphauto.c:681
l_ok fmorphautogen(SELA *sela, l_int32 fileindex, const char *filename)
fmorphautogen()
Definition: fmorphauto.c:249
static char * makeBarrelshiftString(l_int32 delx, l_int32 dely)
makeBarrelshiftString()
Definition: fmorphauto.c:838
@ L_COPY
Definition: pix.h:712
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:170
l_ok sarrayJoin(SARRAY *sa1, SARRAY *sa2)
sarrayJoin()
Definition: sarray1.c:969
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
sarrayToString()
Definition: sarray1.c:785
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
Definition: sarray1.c:283
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:451
l_int32 sarrayParseRange(SARRAY *sa, l_int32 start, l_int32 *pactualstart, l_int32 *pend, l_int32 *pnewstart, const char *substr, l_int32 loc)
sarrayParseRange()
Definition: sarray1.c:1356
l_ok sarrayAppendRange(SARRAY *sa1, SARRAY *sa2, l_int32 start, l_int32 end)
sarrayAppendRange()
Definition: sarray1.c:1012
SEL * selaGetSel(SELA *sela, l_int32 i)
selaGetSel()
Definition: sel1.c:662
SARRAY * selaGetSelnames(SELA *sela)
selaGetSelnames()
Definition: sel1.c:1145
l_int32 selaGetCount(SELA *sela)
selaGetCount()
Definition: sel1.c:637
Definition: array.h:127
l_int32 sx
Definition: morph.h:64
l_int32 cy
Definition: morph.h:65
l_int32 cx
Definition: morph.h:66
l_int32 ** data
Definition: morph.h:67
l_int32 sy
Definition: morph.h:63
Definition: morph.h:74
l_uint8 * l_binaryRead(const char *filename, size_t *pnbytes)
l_binaryRead()
Definition: utils2.c:1352
l_ok l_binaryWrite(const char *filename, const char *operation, const void *data, size_t nbytes)
l_binaryWrite()
Definition: utils2.c:1569
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:223