Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 00017 /* 00018 * fhmtauto.c 00019 * 00020 * Main function calls: 00021 * l_int32 fhmtautogen() 00022 * l_int32 fhmtautogen1() 00023 * l_int32 fhmtautogen2() 00024 * 00025 * Static helpers: 00026 * static SARRAY *sarrayMakeWplsCode() 00027 * static SARRAY *sarrayMakeInnerLoopDWACode() 00028 * static char *makeBarrelshiftString() 00029 * 00030 * This automatically generates dwa code for the hit-miss transform. 00031 * Here's a road map for how it all works. 00032 * 00033 * (1) You generate an array (a SELA) of hit-miss transform SELs. 00034 * This can be done in several ways, including 00035 * (a) calling the function selaAddHitMiss() for 00036 * pre-compiled SELs 00037 * (b) generating the SELA in code in line 00038 * (c) reading in a SELA from file, using selaRead() 00039 * or various other formats. 00040 * 00041 * (2) You call fhmtautogen1() and fhmtautogen2() on this SELA. 00042 * This uses the text files hmttemplate1.txt and 00043 * hmttemplate2.txt for building up the source code. See the file 00044 * prog/fhmtautogen.c for an example of how this is done. 00045 * The output is written to files named fhmtgen.*.c 00046 * and fhmtgenlow.*.c, where "*" is an integer that you 00047 * input to this function. That integer labels both 00048 * the output files, as well as all the functions that 00049 * are generated. That way, using different integers, 00050 * you can invoke fhmtautogen() any number of times 00051 * to get functions that all have different names so that 00052 * they can be linked into one program. 00053 * 00054 * (3) You copy the generated source code back to your src 00055 * directory for compilation. Put their names in the 00056 * Makefile, regnerate the prototypes, and recompile 00057 * the libraries. Look at the Makefile to see how I've 00058 * included fhmtgen.1.c and fhmtgenlow.1.c. These files 00059 * provide the high-level interfaces for the hmt, and 00060 * the low-level interfaces to do the actual work. 00061 * 00062 * (4) In an application, you now use this interface. Again 00063 * for the example files generated, using integer "1": 00064 * 00065 * PIX *pixHMTDwa_1(PIX *pixd, PIX *pixs, char *selname); 00066 * 00067 * or 00068 * 00069 * PIX *pixFHMTGen_1(PIX *pixd, PIX *pixs, char *selname); 00070 * 00071 * where the selname is one of the set that were defined 00072 * as the name field of sels. This set is listed at the 00073 * beginning of the file fhmtgen.1.c. 00074 * As an example, see the file prog/fmtauto_reg.c, which 00075 * verifies the correctness of the implementation by 00076 * comparing the dwa result with that of full-image 00077 * rasterops. 00078 */ 00079 00080 #include <string.h> 00081 #include "allheaders.h" 00082 00083 #define OUTROOT "fhmtgen" 00084 #define TEMPLATE1 "hmttemplate1.txt" 00085 #define TEMPLATE2 "hmttemplate2.txt" 00086 00087 #define BUFFER_SIZE 512 00088 00089 #define PROTOARGS "(l_uint32 *, l_int32, l_int32, l_int32, l_uint32 *, l_int32);" 00090 00091 static char * makeBarrelshiftString(l_int32 delx, l_int32 dely, l_int32 type); 00092 static SARRAY * sarrayMakeInnerLoopDWACode(SEL *sel, l_int32 nhits, l_int32 nmisses); 00093 static SARRAY * sarrayMakeWplsCode(SEL *sel); 00094 00095 static char wpldecls[][60] = { 00096 "l_int32 wpls2;", 00097 "l_int32 wpls2, wpls3;", 00098 "l_int32 wpls2, wpls3, wpls4;", 00099 "l_int32 wpls5;", 00100 "l_int32 wpls5, wpls6;", 00101 "l_int32 wpls5, wpls6, wpls7;", 00102 "l_int32 wpls5, wpls6, wpls7, wpls8;", 00103 "l_int32 wpls9;", 00104 "l_int32 wpls9, wpls10;", 00105 "l_int32 wpls9, wpls10, wpls11;", 00106 "l_int32 wpls9, wpls10, wpls11, wpls12;", 00107 "l_int32 wpls13;", 00108 "l_int32 wpls13, wpls14;", 00109 "l_int32 wpls13, wpls14, wpls15;", 00110 "l_int32 wpls13, wpls14, wpls15, wpls16;", 00111 "l_int32 wpls17;", 00112 "l_int32 wpls17, wpls18;", 00113 "l_int32 wpls17, wpls18, wpls19;", 00114 "l_int32 wpls17, wpls18, wpls19, wpls20;", 00115 "l_int32 wpls21;", 00116 "l_int32 wpls21, wpls22;", 00117 "l_int32 wpls21, wpls22, wpls23;", 00118 "l_int32 wpls21, wpls22, wpls23, wpls24;", 00119 "l_int32 wpls25;", 00120 "l_int32 wpls25, wpls26;", 00121 "l_int32 wpls25, wpls26, wpls27;", 00122 "l_int32 wpls25, wpls26, wpls27, wpls28;", 00123 "l_int32 wpls29;", 00124 "l_int32 wpls29, wpls30;", 00125 "l_int32 wpls29, wpls30, wpls31;"}; 00126 00127 static char wpldefs[][24] = { 00128 " wpls2 = 2 * wpls;", 00129 " wpls3 = 3 * wpls;", 00130 " wpls4 = 4 * wpls;", 00131 " wpls5 = 5 * wpls;", 00132 " wpls6 = 6 * wpls;", 00133 " wpls7 = 7 * wpls;", 00134 " wpls8 = 8 * wpls;", 00135 " wpls9 = 9 * wpls;", 00136 " wpls10 = 10 * wpls;", 00137 " wpls11 = 11 * wpls;", 00138 " wpls12 = 12 * wpls;", 00139 " wpls13 = 13 * wpls;", 00140 " wpls14 = 14 * wpls;", 00141 " wpls15 = 15 * wpls;", 00142 " wpls16 = 16 * wpls;", 00143 " wpls17 = 17 * wpls;", 00144 " wpls18 = 18 * wpls;", 00145 " wpls19 = 19 * wpls;", 00146 " wpls20 = 20 * wpls;", 00147 " wpls21 = 21 * wpls;", 00148 " wpls22 = 22 * wpls;", 00149 " wpls23 = 23 * wpls;", 00150 " wpls24 = 24 * wpls;", 00151 " wpls25 = 25 * wpls;", 00152 " wpls26 = 26 * wpls;", 00153 " wpls27 = 27 * wpls;", 00154 " wpls28 = 28 * wpls;", 00155 " wpls29 = 29 * wpls;", 00156 " wpls30 = 30 * wpls;", 00157 " wpls31 = 31 * wpls;"}; 00158 00159 static char wplstrp[][10] = {"+ wpls", "+ wpls2", "+ wpls3", "+ wpls4", 00160 "+ wpls5", "+ wpls6", "+ wpls7", "+ wpls8", 00161 "+ wpls9", "+ wpls10", "+ wpls11", "+ wpls12", 00162 "+ wpls13", "+ wpls14", "+ wpls15", "+ wpls16", 00163 "+ wpls17", "+ wpls18", "+ wpls19", "+ wpls20", 00164 "+ wpls21", "+ wpls22", "+ wpls23", "+ wpls24", 00165 "+ wpls25", "+ wpls26", "+ wpls27", "+ wpls28", 00166 "+ wpls29", "+ wpls30", "+ wpls31"}; 00167 00168 static char wplstrm[][10] = {"- wpls", "- wpls2", "- wpls3", "- wpls4", 00169 "- wpls5", "- wpls6", "- wpls7", "- wpls8", 00170 "- wpls9", "- wpls10", "- wpls11", "- wpls12", 00171 "- wpls13", "- wpls14", "- wpls15", "- wpls16", 00172 "- wpls17", "- wpls18", "- wpls19", "- wpls20", 00173 "- wpls21", "- wpls22", "- wpls23", "- wpls24", 00174 "- wpls25", "- wpls26", "- wpls27", "- wpls28", 00175 "- wpls29", "- wpls30", "- wpls31"}; 00176 00177 00178 /*! 00179 * fhmtautogen() 00180 * 00181 * Input: sela 00182 * fileindex 00183 * filename (<optional>; can be null) 00184 * Return: 0 if OK; 1 on error 00185 * 00186 * Notes: 00187 * (1) This function generates all the code for implementing 00188 * dwa morphological operations using all the sels in the sela. 00189 * (2) See fhmtautogen1() and fhmtautogen2() for details. 00190 */ 00191 l_int32 00192 fhmtautogen(SELA *sela, 00193 l_int32 fileindex, 00194 const char *filename) 00195 { 00196 l_int32 ret1, ret2; 00197 00198 PROCNAME("fhmtautogen"); 00199 00200 if (!sela) 00201 return ERROR_INT("sela not defined", procName, 1); 00202 ret1 = fhmtautogen1(sela, fileindex, filename); 00203 ret2 = fhmtautogen2(sela, fileindex, filename); 00204 if (ret1 || ret2) 00205 return ERROR_INT("code generation problem", procName, 1); 00206 return 0; 00207 } 00208 00209 00210 /*! 00211 * fhmtautogen1() 00212 * 00213 * Input: sel array 00214 * fileindex 00215 * filename (<optional>; can be null) 00216 * Return: 0 if OK; 1 on error 00217 * 00218 * Notes: 00219 * (1) This function uses hmttemplate1.txt to create a 00220 * top-level file that contains two functions that carry 00221 * out the hit-miss transform for any of the sels in 00222 * the input sela. 00223 * (2) The fileindex parameter is inserted into the output 00224 * filename, as described below. 00225 * (3) If filename == NULL, the output file is fhmtgen.<n>.c, 00226 * where <n> is equal to the 'fileindex' parameter. 00227 * (4) If filename != NULL, the output file is <filename>.<n>.c. 00228 * (5) Each sel must have at least one hit. A sel with only misses 00229 * generates code that will abort the operation if it is called. 00230 */ 00231 l_int32 00232 fhmtautogen1(SELA *sela, 00233 l_int32 fileindex, 00234 const char *filename) 00235 { 00236 char *filestr; 00237 char *str_proto1, *str_proto2, *str_proto3; 00238 char *str_doc1, *str_doc2, *str_doc3, *str_doc4; 00239 char *str_def1, *str_def2, *str_proc1, *str_proc2; 00240 char *str_dwa1, *str_low_dt, *str_low_ds; 00241 char bigbuf[BUFFER_SIZE]; 00242 l_int32 i, nsels, nbytes, actstart, end, newstart; 00243 size_t size; 00244 SARRAY *sa1, *sa2, *sa3; 00245 00246 PROCNAME("fhmtautogen1"); 00247 00248 if (!sela) 00249 return ERROR_INT("sela not defined", procName, 1); 00250 if (fileindex < 0) 00251 fileindex = 0; 00252 if ((nsels = selaGetCount(sela)) == 0) 00253 return ERROR_INT("no sels in sela", procName, 1); 00254 00255 /* Make array of sel names */ 00256 sa1 = selaGetSelnames(sela); 00257 00258 /* Make array of textlines from from hmttemplate1.txt */ 00259 if ((filestr = (char *)l_binaryRead(TEMPLATE1, &size)) == NULL) 00260 return ERROR_INT("filestr not made", procName, 1); 00261 if ((sa2 = sarrayCreateLinesFromString(filestr, 1)) == NULL) 00262 return ERROR_INT("sa2 not made", procName, 1); 00263 FREE(filestr); 00264 00265 /* Make strings containing function call names */ 00266 sprintf(bigbuf, "PIX *pixHMTDwa_%d(PIX *pixd, PIX *pixs, " 00267 "char *selname);", fileindex); 00268 str_proto1 = stringNew(bigbuf); 00269 sprintf(bigbuf, "PIX *pixFHMTGen_%d(PIX *pixd, PIX *pixs, " 00270 "char *selname);", fileindex); 00271 str_proto2 = stringNew(bigbuf); 00272 sprintf(bigbuf, "l_int32 fhmtgen_low_%d(l_uint32 *datad, l_int32 w,\n" 00273 " l_int32 h, l_int32 wpld,\n" 00274 " l_uint32 *datas, l_int32 wpls,\n" 00275 " l_int32 index);", fileindex); 00276 str_proto3 = stringNew(bigbuf); 00277 sprintf(bigbuf, " * PIX *pixHMTDwa_%d()", fileindex); 00278 str_doc1 = stringNew(bigbuf); 00279 sprintf(bigbuf, " * PIX *pixFHMTGen_%d()", fileindex); 00280 str_doc2 = stringNew(bigbuf); 00281 sprintf(bigbuf, " * pixHMTDwa_%d()", fileindex); 00282 str_doc3 = stringNew(bigbuf); 00283 sprintf(bigbuf, " * pixFHMTGen_%d()", fileindex); 00284 str_doc4 = stringNew(bigbuf); 00285 sprintf(bigbuf, "pixHMTDwa_%d(PIX *pixd,", fileindex); 00286 str_def1 = stringNew(bigbuf); 00287 sprintf(bigbuf, "pixFHMTGen_%d(PIX *pixd,", fileindex); 00288 str_def2 = stringNew(bigbuf); 00289 sprintf(bigbuf, " PROCNAME(\"pixHMTDwa_%d\");", fileindex); 00290 str_proc1 = stringNew(bigbuf); 00291 sprintf(bigbuf, " PROCNAME(\"pixFHMTGen_%d\");", fileindex); 00292 str_proc2 = stringNew(bigbuf); 00293 sprintf(bigbuf, " pixt2 = pixFHMTGen_%d(NULL, pixt1, selname);", 00294 fileindex); 00295 str_dwa1 = stringNew(bigbuf); 00296 sprintf(bigbuf, 00297 " fhmtgen_low_%d(datad, w, h, wpld, datat, wpls, index);", 00298 fileindex); 00299 str_low_dt = stringNew(bigbuf); 00300 sprintf(bigbuf, 00301 " fhmtgen_low_%d(datad, w, h, wpld, datas, wpls, index);", 00302 fileindex); 00303 str_low_ds = stringNew(bigbuf); 00304 00305 /* Make the output sa */ 00306 if ((sa3 = sarrayCreate(0)) == NULL) 00307 return ERROR_INT("sa3 not made", procName, 1); 00308 00309 /* Copyright notice and info header */ 00310 sarrayParseRange(sa2, 0, &actstart, &end, &newstart, "--", 0); 00311 sarrayAppendRange(sa3, sa2, actstart, end); 00312 00313 /* Insert function names as documentation */ 00314 sarrayAddString(sa3, str_doc1, L_INSERT); 00315 sarrayAddString(sa3, str_doc2, L_INSERT); 00316 00317 /* Add '#include's */ 00318 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00319 sarrayAppendRange(sa3, sa2, actstart, end); 00320 00321 /* Insert function prototypes */ 00322 sarrayAddString(sa3, str_proto1, L_INSERT); 00323 sarrayAddString(sa3, str_proto2, L_INSERT); 00324 sarrayAddString(sa3, str_proto3, L_INSERT); 00325 00326 /* Add static globals */ 00327 sprintf(bigbuf, "\nstatic l_int32 NUM_SELS_GENERATED = %d;", nsels); 00328 sarrayAddString(sa3, bigbuf, L_COPY); 00329 sprintf(bigbuf, "static char SEL_NAMES[][80] = {"); 00330 sarrayAddString(sa3, bigbuf, L_COPY); 00331 for (i = 0; i < nsels - 1; i++) { 00332 sprintf(bigbuf, 00333 " \"%s\",", sarrayGetString(sa1, i, 0)); 00334 sarrayAddString(sa3, bigbuf, L_COPY); 00335 } 00336 sprintf(bigbuf, 00337 " \"%s\"};", sarrayGetString(sa1, i, 0)); 00338 sarrayAddString(sa3, bigbuf, L_COPY); 00339 00340 /* Start pixHMTDwa_*() function description */ 00341 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00342 sarrayAppendRange(sa3, sa2, actstart, end); 00343 sarrayAddString(sa3, str_doc3, L_INSERT); 00344 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00345 sarrayAppendRange(sa3, sa2, actstart, end); 00346 00347 /* Finish pixMorphDwa_*() function definition */ 00348 sarrayAddString(sa3, str_def1, L_INSERT); 00349 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00350 sarrayAppendRange(sa3, sa2, actstart, end); 00351 sarrayAddString(sa3, str_proc1, L_INSERT); 00352 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00353 sarrayAppendRange(sa3, sa2, actstart, end); 00354 sarrayAddString(sa3, str_dwa1, L_INSERT); 00355 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00356 sarrayAppendRange(sa3, sa2, actstart, end); 00357 00358 /* Start pixFHMTGen_*() function description */ 00359 sarrayAddString(sa3, str_doc4, L_INSERT); 00360 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00361 sarrayAppendRange(sa3, sa2, actstart, end); 00362 00363 /* Finish pixFHMTGen_*() function description */ 00364 sarrayAddString(sa3, str_def2, L_INSERT); 00365 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00366 sarrayAppendRange(sa3, sa2, actstart, end); 00367 sarrayAddString(sa3, str_proc2, L_INSERT); 00368 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00369 sarrayAppendRange(sa3, sa2, actstart, end); 00370 sarrayAddString(sa3, str_low_dt, L_INSERT); 00371 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00372 sarrayAppendRange(sa3, sa2, actstart, end); 00373 sarrayAddString(sa3, str_low_ds, L_INSERT); 00374 sarrayParseRange(sa2, newstart, &actstart, &end, &newstart, "--", 0); 00375 sarrayAppendRange(sa3, sa2, actstart, end); 00376 00377 if ((filestr = sarrayToString(sa3, 1)) == NULL) 00378 return ERROR_INT("filestr from sa3 not made", procName, 1); 00379 nbytes = strlen(filestr); 00380 if (filename) 00381 sprintf(bigbuf, "%s.%d.c", filename, fileindex); 00382 else 00383 sprintf(bigbuf, "%s.%d.c", OUTROOT, fileindex); 00384 l_binaryWrite(bigbuf, "w", filestr, nbytes); 00385 sarrayDestroy(&sa1); 00386 sarrayDestroy(&sa2); 00387 sarrayDestroy(&sa3); 00388 FREE(filestr); 00389 return 0; 00390 } 00391 00392 00393 /*! 00394 * fhmtautogen2() 00395 * 00396 * Input: sel array 00397 * fileindex 00398 * filename (<optional>; can be null) 00399 * Return: 0 if OK; 1 on error 00400 * 00401 * Notes: 00402 * (1) This function uses hmttemplate2.txt to create a 00403 * low-level file that contains the low-level functions for 00404 * implementing the hit-miss transform for every sel 00405 * in the input sela. 00406 * (2) The fileindex parameter is inserted into the output 00407 * filename, as described below. 00408 * (3) If filename == NULL, the output file is fhmtgenlow.<n>.c, 00409 * where <n> is equal to the 'fileindex' parameter. 00410 * (4) If filename != NULL, the output file is <filename>low.<n>.c. 00411 */ 00412 l_int32 00413 fhmtautogen2(SELA *sela, 00414 l_int32 fileindex, 00415 const char *filename) 00416 { 00417 char *filestr, *fname, *linestr; 00418 char *str_doc1, *str_doc2, *str_doc3, *str_def1; 00419 char bigbuf[BUFFER_SIZE]; 00420 char breakstring[] = " break;"; 00421 char staticstring[] = "static void"; 00422 l_int32 i, k, l, nsels, nbytes, nhits, nmisses; 00423 l_int32 actstart, end, newstart; 00424 l_int32 argstart, argend, loopstart, loopend, finalstart, finalend; 00425 size_t size; 00426 SARRAY *sa1, *sa2, *sa3, *sa4, *sa5, *sa6; 00427 SEL *sel; 00428 00429 PROCNAME("fhmtautogen2"); 00430 00431 if (!sela) 00432 return ERROR_INT("sela not defined", procName, 1); 00433 if (fileindex < 0) 00434 fileindex = 0; 00435 if ((nsels = selaGetCount(sela)) == 0) 00436 return ERROR_INT("no sels in sela", procName, 1); 00437 00438 /* Make the array of textlines from hmttemplate2.txt */ 00439 if ((filestr = (char *)l_binaryRead(TEMPLATE2, &size)) == NULL) 00440 return ERROR_INT("filestr not made", procName, 1); 00441 if ((sa1 = sarrayCreateLinesFromString(filestr, 1)) == NULL) 00442 return ERROR_INT("sa1 not made", procName, 1); 00443 FREE(filestr); 00444 00445 /* Make the array of static function names */ 00446 if ((sa2 = sarrayCreate(nsels)) == NULL) 00447 return ERROR_INT("sa2 not made", procName, 1); 00448 for (i = 0; i < nsels; i++) { 00449 sprintf(bigbuf, "fhmt_%d_%d", fileindex, i); 00450 sarrayAddString(sa2, bigbuf, 1); 00451 } 00452 00453 /* Make the static prototype strings */ 00454 if ((sa3 = sarrayCreate(2 * nsels)) == NULL) 00455 return ERROR_INT("sa3 not made", procName, 1); 00456 for (i = 0; i < nsels; i++) { 00457 fname = sarrayGetString(sa2, i, 0); 00458 sprintf(bigbuf, "static void %s%s", fname, PROTOARGS); 00459 sarrayAddString(sa3, bigbuf, 1); 00460 } 00461 00462 /* Make strings containing function names */ 00463 sprintf(bigbuf, " * l_int32 fhmtgen_low_%d()", 00464 fileindex); 00465 str_doc1 = stringNew(bigbuf); 00466 sprintf(bigbuf, " * void fhmt_%d_*()", fileindex); 00467 str_doc2 = stringNew(bigbuf); 00468 sprintf(bigbuf, " * fhmtgen_low_%d()", fileindex); 00469 str_doc3 = stringNew(bigbuf); 00470 sprintf(bigbuf, "fhmtgen_low_%d(l_uint32 *datad,", fileindex); 00471 str_def1 = stringNew(bigbuf); 00472 00473 /* Output to this sa */ 00474 if ((sa4 = sarrayCreate(0)) == NULL) 00475 return ERROR_INT("sa4 not made", procName, 1); 00476 00477 /* Copyright notice and info header */ 00478 sarrayParseRange(sa1, 0, &actstart, &end, &newstart, "--", 0); 00479 sarrayAppendRange(sa4, sa1, actstart, end); 00480 00481 /* Insert function names as documentation */ 00482 sarrayAddString(sa4, str_doc1, L_INSERT); 00483 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); 00484 sarrayAppendRange(sa4, sa1, actstart, end); 00485 sarrayAddString(sa4, str_doc2, L_INSERT); 00486 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); 00487 sarrayAppendRange(sa4, sa1, actstart, end); 00488 00489 /* Insert static protos */ 00490 for (i = 0; i < nsels; i++) { 00491 if ((linestr = sarrayGetString(sa3, i, L_COPY)) == NULL) 00492 return ERROR_INT("linestr not retrieved", procName, 1); 00493 sarrayAddString(sa4, linestr, L_INSERT); 00494 } 00495 00496 /* Insert function header */ 00497 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); 00498 sarrayAppendRange(sa4, sa1, actstart, end); 00499 sarrayAddString(sa4, str_doc3, L_INSERT); 00500 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); 00501 sarrayAppendRange(sa4, sa1, actstart, end); 00502 sarrayAddString(sa4, str_def1, L_INSERT); 00503 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); 00504 sarrayAppendRange(sa4, sa1, actstart, end); 00505 00506 /* Generate and insert the dispatcher code */ 00507 for (i = 0; i < nsels; i++) { 00508 sprintf(bigbuf, " case %d:", i); 00509 sarrayAddString(sa4, bigbuf, L_COPY); 00510 sprintf(bigbuf, " %s(datad, w, h, wpld, datas, wpls);", 00511 sarrayGetString(sa2, i, L_NOCOPY)); 00512 sarrayAddString(sa4, bigbuf, L_COPY); 00513 sarrayAddString(sa4, breakstring, L_COPY); 00514 } 00515 00516 /* Finish the dispatcher and introduce the low-level code */ 00517 sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); 00518 sarrayAppendRange(sa4, sa1, actstart, end); 00519 00520 /* Get the range for the args common to all functions */ 00521 sarrayParseRange(sa1, newstart, &argstart, &argend, &newstart, "--", 0); 00522 00523 /* Get the range for the loop code common to all functions */ 00524 sarrayParseRange(sa1, newstart, &loopstart, &loopend, &newstart, "--", 0); 00525 00526 /* Get the range for the ending code common to all functions */ 00527 sarrayParseRange(sa1, newstart, &finalstart, &finalend, &newstart, "--", 0); 00528 00529 /* Do all the static functions */ 00530 for (i = 0; i < nsels; i++) { 00531 /* Generate the function header and add the common args */ 00532 sarrayAddString(sa4, staticstring, L_COPY); 00533 fname = sarrayGetString(sa2, i, L_NOCOPY); 00534 sprintf(bigbuf, "%s(l_uint32 *datad,", fname); 00535 sarrayAddString(sa4, bigbuf, L_COPY); 00536 sarrayAppendRange(sa4, sa1, argstart, argend); 00537 00538 /* Declare and define wplsN args, as necessary */ 00539 if ((sel = selaGetSel(sela, i)) == NULL) 00540 return ERROR_INT("sel not returned", procName, 1); 00541 if ((sa5 = sarrayMakeWplsCode(sel)) == NULL) 00542 return ERROR_INT("sa5 not made", procName, 1); 00543 sarrayConcatenate(sa4, sa5); 00544 sarrayDestroy(&sa5); 00545 00546 /* Make sure sel has at least one hit */ 00547 nhits = 0; 00548 nmisses = 0; 00549 for (k = 0; k < sel->sy; k++) { 00550 for (l = 0; l < sel->sx; l++) { 00551 if (sel->data[k][l] == 1) 00552 nhits++; 00553 else if (sel->data[k][l] == 2) 00554 nmisses++; 00555 } 00556 } 00557 if (nhits == 0) { 00558 linestr = stringNew(" fprintf(stderr, \"Error in HMT: no hits in sel!\\n\");\n}\n\n"); 00559 sarrayAddString(sa4, linestr, L_INSERT); 00560 continue; 00561 } 00562 00563 /* Add the function loop code */ 00564 sarrayAppendRange(sa4, sa1, loopstart, loopend); 00565 00566 /* Insert barrel-op code for *dptr */ 00567 if ((sa6 = sarrayMakeInnerLoopDWACode(sel, nhits, nmisses)) == NULL) 00568 return ERROR_INT("sa6 not made", procName, 1); 00569 sarrayConcatenate(sa4, sa6); 00570 sarrayDestroy(&sa6); 00571 00572 /* Finish the function code */ 00573 sarrayAppendRange(sa4, sa1, finalstart, finalend); 00574 } 00575 00576 /* Output to file */ 00577 if ((filestr = sarrayToString(sa4, 1)) == NULL) 00578 return ERROR_INT("filestr from sa4 not made", procName, 1); 00579 nbytes = strlen(filestr); 00580 if (filename) 00581 sprintf(bigbuf, "%slow.%d.c", filename, fileindex); 00582 else 00583 sprintf(bigbuf, "%slow.%d.c", OUTROOT, fileindex); 00584 l_binaryWrite(bigbuf, "w", filestr, nbytes); 00585 sarrayDestroy(&sa1); 00586 sarrayDestroy(&sa2); 00587 sarrayDestroy(&sa3); 00588 sarrayDestroy(&sa4); 00589 FREE(filestr); 00590 00591 return 0; 00592 } 00593 00594 00595 00596 /*--------------------------------------------------------------------------* 00597 * Helper code for sel * 00598 *--------------------------------------------------------------------------*/ 00599 /*! 00600 * sarrayMakeWplsCode() 00601 */ 00602 static SARRAY * 00603 sarrayMakeWplsCode(SEL *sel) 00604 { 00605 char spacestring[] = " "; 00606 l_int32 i, j, ymax, dely; 00607 SARRAY *sa; 00608 00609 PROCNAME("sarrayMakeWplsCode"); 00610 00611 if (!sel) 00612 return (SARRAY *)ERROR_PTR("sel not defined", procName, NULL); 00613 00614 ymax = 0; 00615 for (i = 0; i < sel->sy; i++) { 00616 for (j = 0; j < sel->sx; j++) { 00617 if (sel->data[i][j] == 1) { 00618 dely = L_ABS(i - sel->cy); 00619 ymax = L_MAX(ymax, dely); 00620 } 00621 } 00622 } 00623 if (ymax > 31) { 00624 L_WARNING("ymax > 31; truncating to 31", procName); 00625 ymax = 31; 00626 } 00627 00628 if ((sa = sarrayCreate(0)) == NULL) 00629 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL); 00630 00631 /* Declarations */ 00632 if (ymax > 4) 00633 sarrayAddString(sa, wpldecls[2], 1); 00634 if (ymax > 8) 00635 sarrayAddString(sa, wpldecls[6], 1); 00636 if (ymax > 12) 00637 sarrayAddString(sa, wpldecls[10], 1); 00638 if (ymax > 16) 00639 sarrayAddString(sa, wpldecls[14], 1); 00640 if (ymax > 20) 00641 sarrayAddString(sa, wpldecls[18], 1); 00642 if (ymax > 24) 00643 sarrayAddString(sa, wpldecls[22], 1); 00644 if (ymax > 28) 00645 sarrayAddString(sa, wpldecls[26], 1); 00646 if (ymax > 1) 00647 sarrayAddString(sa, wpldecls[ymax - 2], 1); 00648 00649 sarrayAddString(sa, spacestring, 1); 00650 00651 /* Definitions */ 00652 for (i = 2; i <= ymax; i++) 00653 sarrayAddString(sa, wpldefs[i - 2], 1); 00654 00655 return sa; 00656 } 00657 00658 00659 /*! 00660 * sarrayMakeInnerLoopDWACode() 00661 */ 00662 static SARRAY * 00663 sarrayMakeInnerLoopDWACode(SEL *sel, 00664 l_int32 nhits, 00665 l_int32 nmisses) 00666 { 00667 char *string; 00668 char land[] = "&"; 00669 char bigbuf[BUFFER_SIZE]; 00670 l_int32 i, j, ntot, nfound, type, delx, dely; 00671 SARRAY *sa; 00672 00673 PROCNAME("sarrayMakeInnerLoopDWACode"); 00674 00675 if (!sel) 00676 return (SARRAY *)ERROR_PTR("sel not defined", procName, NULL); 00677 00678 if ((sa = sarrayCreate(0)) == NULL) 00679 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL); 00680 00681 ntot = nhits + nmisses; 00682 nfound = 0; 00683 for (i = 0; i < sel->sy; i++) { 00684 for (j = 0; j < sel->sx; j++) { 00685 type = sel->data[i][j]; 00686 if (type == SEL_HIT || type == SEL_MISS) { 00687 nfound++; 00688 dely = i - sel->cy; 00689 delx = j - sel->cx; 00690 if ((string = makeBarrelshiftString(delx, dely, type)) 00691 == NULL) { 00692 L_WARNING("barrel shift string not made", procName); 00693 continue; 00694 } 00695 if (ntot == 1) /* just one item */ 00696 sprintf(bigbuf, " *dptr = %s;", string); 00697 else if (nfound == 1) 00698 sprintf(bigbuf, " *dptr = %s %s", string, land); 00699 else if (nfound < ntot) 00700 sprintf(bigbuf, " %s %s", string, land); 00701 else /* nfound == ntot */ 00702 sprintf(bigbuf, " %s;", string); 00703 sarrayAddString(sa, bigbuf, 1); 00704 FREE(string); 00705 } 00706 } 00707 } 00708 00709 return sa; 00710 } 00711 00712 00713 /*! 00714 * makeBarrelshiftString() 00715 */ 00716 static char * 00717 makeBarrelshiftString(l_int32 delx, /* j - cx */ 00718 l_int32 dely, /* i - cy */ 00719 l_int32 type) /* SEL_HIT or SEL_MISS */ 00720 { 00721 l_int32 absx, absy; 00722 char bigbuf[BUFFER_SIZE]; 00723 00724 PROCNAME("makeBarrelshiftString"); 00725 00726 if (delx < -31 || delx > 31) 00727 return (char *)ERROR_PTR("delx out of bounds", procName, NULL); 00728 if (dely < -31 || dely > 31) 00729 return (char *)ERROR_PTR("dely out of bounds", procName, NULL); 00730 absx = L_ABS(delx); 00731 absy = L_ABS(dely); 00732 00733 if (type == SEL_HIT) { 00734 if ((delx == 0) && (dely == 0)) 00735 sprintf(bigbuf, "(*sptr)"); 00736 else if ((delx == 0) && (dely < 0)) 00737 sprintf(bigbuf, "(*(sptr %s))", wplstrm[absy - 1]); 00738 else if ((delx == 0) && (dely > 0)) 00739 sprintf(bigbuf, "(*(sptr %s))", wplstrp[absy - 1]); 00740 else if ((delx < 0) && (dely == 0)) 00741 sprintf(bigbuf, "((*(sptr) >> %d) | (*(sptr - 1) << %d))", 00742 absx, 32 - absx); 00743 else if ((delx > 0) && (dely == 0)) 00744 sprintf(bigbuf, "((*(sptr) << %d) | (*(sptr + 1) >> %d))", 00745 absx, 32 - absx); 00746 else if ((delx < 0) && (dely < 0)) 00747 sprintf(bigbuf, "((*(sptr %s) >> %d) | (*(sptr %s - 1) << %d))", 00748 wplstrm[absy - 1], absx, wplstrm[absy - 1], 32 - absx); 00749 else if ((delx > 0) && (dely < 0)) 00750 sprintf(bigbuf, "((*(sptr %s) << %d) | (*(sptr %s + 1) >> %d))", 00751 wplstrm[absy - 1], absx, wplstrm[absy - 1], 32 - absx); 00752 else if ((delx < 0) && (dely > 0)) 00753 sprintf(bigbuf, "((*(sptr %s) >> %d) | (*(sptr %s - 1) << %d))", 00754 wplstrp[absy - 1], absx, wplstrp[absy - 1], 32 - absx); 00755 else /* ((delx > 0) && (dely > 0)) */ 00756 sprintf(bigbuf, "((*(sptr %s) << %d) | (*(sptr %s + 1) >> %d))", 00757 wplstrp[absy - 1], absx, wplstrp[absy - 1], 32 - absx); 00758 } 00759 else { /* type == SEL_MISS */ 00760 if ((delx == 0) && (dely == 0)) 00761 sprintf(bigbuf, "(~*sptr)"); 00762 else if ((delx == 0) && (dely < 0)) 00763 sprintf(bigbuf, "(~*(sptr %s))", wplstrm[absy - 1]); 00764 else if ((delx == 0) && (dely > 0)) 00765 sprintf(bigbuf, "(~*(sptr %s))", wplstrp[absy - 1]); 00766 else if ((delx < 0) && (dely == 0)) 00767 sprintf(bigbuf, "((~*(sptr) >> %d) | (~*(sptr - 1) << %d))", 00768 absx, 32 - absx); 00769 else if ((delx > 0) && (dely == 0)) 00770 sprintf(bigbuf, "((~*(sptr) << %d) | (~*(sptr + 1) >> %d))", 00771 absx, 32 - absx); 00772 else if ((delx < 0) && (dely < 0)) 00773 sprintf(bigbuf, "((~*(sptr %s) >> %d) | (~*(sptr %s - 1) << %d))", 00774 wplstrm[absy - 1], absx, wplstrm[absy - 1], 32 - absx); 00775 else if ((delx > 0) && (dely < 0)) 00776 sprintf(bigbuf, "((~*(sptr %s) << %d) | (~*(sptr %s + 1) >> %d))", 00777 wplstrm[absy - 1], absx, wplstrm[absy - 1], 32 - absx); 00778 else if ((delx < 0) && (dely > 0)) 00779 sprintf(bigbuf, "((~*(sptr %s) >> %d) | (~*(sptr %s - 1) << %d))", 00780 wplstrp[absy - 1], absx, wplstrp[absy - 1], 32 - absx); 00781 else /* ((delx > 0) && (dely > 0)) */ 00782 sprintf(bigbuf, "((~*(sptr %s) << %d) | (~*(sptr %s + 1) >> %d))", 00783 wplstrp[absy - 1], absx, wplstrp[absy - 1], 32 - absx); 00784 } 00785 00786 return stringNew(bigbuf); 00787 } 00788