/* * fmorphautogen2() * * Input: sela * fileindex * filename (<optional>; can be null) * Return: 0 if OK; 1 on error * * Notes: * (1) This function uses morphtemplate2.txt to create a * low-level file that contains the low-level functions for * implementing dilation and erosion for every sel * in the input sela. * (2) The fileindex parameter is inserted into the output * filename, as described below. * (3) If filename == NULL, the output file is fmorphgenlow.<n>.c, * where <n> is equal to the 'fileindex' parameter. * (4) If filename != NULL, the output file is <filename>low.<n>.c. */ l_int32 fmorphautogen2(SELA *sela, l_int32 fileindex, const char *filename) { char *filestr, *linestr, *fname; char *str_doc1, *str_doc2, *str_doc3, *str_doc4, *str_def1; char bigbuf[L_BUF_SIZE]; char breakstring[] = " break;"; char staticstring[] = "static void"; l_int32 i, nsels, nbytes, actstart, end, newstart; l_int32 argstart, argend, loopstart, loopend, finalstart, finalend; size_t size; SARRAY *sa1, *sa2, *sa3, *sa4, *sa5, *sa6; SEL *sel; PROCNAME("fmorphautogen2"); if (!sela) return ERROR_INT("sela not defined", procName, 1); if (fileindex < 0) fileindex = 0; if ((nsels = selaGetCount(sela)) == 0) return ERROR_INT("no sels in sela", procName, 1); /* Make the array of textlines from morphtemplate2.txt */ if ((filestr = (char *)l_binaryRead(TEMPLATE2, &size)) == NULL) return ERROR_INT("filestr not made", procName, 1); if ((sa1 = sarrayCreateLinesFromString(filestr, 1)) == NULL) return ERROR_INT("sa1 not made", procName, 1); FREE(filestr); /* Make the array of static function names */ if ((sa2 = sarrayCreate(2 * nsels)) == NULL) return ERROR_INT("sa2 not made", procName, 1); for (i = 0; i < nsels; i++) { sprintf(bigbuf, "fdilate_%d_%d", fileindex, i); sarrayAddString(sa2, bigbuf, 1); sprintf(bigbuf, "ferode_%d_%d", fileindex, i); sarrayAddString(sa2, bigbuf, 1); } /* Make the static prototype strings */ if ((sa3 = sarrayCreate(2 * nsels)) == NULL) return ERROR_INT("sa3 not made", procName, 1); for (i = 0; i < 2 * nsels; i++) { fname = sarrayGetString(sa2, i, 0); sprintf(bigbuf, "static void %s%s", fname, PROTOARGS); sarrayAddString(sa3, bigbuf, 1); } /* Make strings containing function names */ sprintf(bigbuf, " * l_int32 fmorphopgen_low_%d()", fileindex); str_doc1 = stringNew(bigbuf); sprintf(bigbuf, " * void fdilate_%d_*()", fileindex); str_doc2 = stringNew(bigbuf); sprintf(bigbuf, " * void ferode_%d_*()", fileindex); str_doc3 = stringNew(bigbuf); sprintf(bigbuf, " * fmorphopgen_low_%d()", fileindex); str_doc4 = stringNew(bigbuf); sprintf(bigbuf, "fmorphopgen_low_%d(l_uint32 *datad,", fileindex); str_def1 = stringNew(bigbuf); /* Output to this sa */ if ((sa4 = sarrayCreate(0)) == NULL) return ERROR_INT("sa4 not made", procName, 1); /* Copyright notice and info header */ sarrayParseRange(sa1, 0, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Insert function names as documentation */ sarrayAddString(sa4, str_doc1, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); sarrayAddString(sa4, str_doc2, L_INSERT); sarrayAddString(sa4, str_doc3, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Insert static protos */ for (i = 0; i < 2 * nsels; i++) { if ((linestr = sarrayGetString(sa3, i, L_COPY)) == NULL) return ERROR_INT("linestr not retrieved", procName, 1); sarrayAddString(sa4, linestr, L_INSERT); } /* Insert function header */ sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); sarrayAddString(sa4, str_doc4, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); sarrayAddString(sa4, str_def1, L_INSERT); sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Generate and insert the dispatcher code */ for (i = 0; i < 2 * nsels; i++) { sprintf(bigbuf, " case %d:", i); sarrayAddString(sa4, bigbuf, L_COPY); sprintf(bigbuf, " %s(datad, w, h, wpld, datas, wpls);", sarrayGetString(sa2, i, L_NOCOPY)); sarrayAddString(sa4, bigbuf, L_COPY); sarrayAddString(sa4, breakstring, L_COPY); } /* Finish the dispatcher and introduce the low-level code */ sarrayParseRange(sa1, newstart, &actstart, &end, &newstart, "--", 0); sarrayAppendRange(sa4, sa1, actstart, end); /* Get the range for the args common to all functions */ sarrayParseRange(sa1, newstart, &argstart, &argend, &newstart, "--", 0); /* Get the range for the loop code common to all functions */ sarrayParseRange(sa1, newstart, &loopstart, &loopend, &newstart, "--", 0); /* Get the range for the ending code common to all functions */ sarrayParseRange(sa1, newstart, &finalstart, &finalend, &newstart, "--", 0); /* Do all the static functions */ for (i = 0; i < 2 * nsels; i++) { /* Generate the function header and add the common args */ sarrayAddString(sa4, staticstring, L_COPY); fname = sarrayGetString(sa2, i, L_NOCOPY); sprintf(bigbuf, "%s(l_uint32 *datad,", fname); sarrayAddString(sa4, bigbuf, L_COPY); sarrayAppendRange(sa4, sa1, argstart, argend); /* Declare and define wplsN args, as necessary */ if ((sel = selaGetSel(sela, i/2)) == NULL) return ERROR_INT("sel not returned", procName, 1); if ((sa5 = sarrayMakeWplsCode(sel)) == NULL) return ERROR_INT("sa5 not made", procName, 1); sarrayConcatenate(sa4, sa5); sarrayDestroy(&sa5); /* Add the function loop code */ sarrayAppendRange(sa4, sa1, loopstart, loopend); /* Insert barrel-op code for *dptr */ if ((sa6 = sarrayMakeInnerLoopDWACode(sel, i)) == NULL) return ERROR_INT("sa6 not made", procName, 1); sarrayConcatenate(sa4, sa6); sarrayDestroy(&sa6); /* Finish the function code */ sarrayAppendRange(sa4, sa1, finalstart, finalend); } /* Output to file */ if ((filestr = sarrayToString(sa4, 1)) == NULL) return ERROR_INT("filestr from sa4 not made", procName, 1); nbytes = strlen(filestr); if (filename) sprintf(bigbuf, "%slow.%d.c", filename, fileindex); else sprintf(bigbuf, "%slow.%d.c", OUTROOT, fileindex); l_binaryWrite(bigbuf, "w", filestr, nbytes); sarrayDestroy(&sa1); sarrayDestroy(&sa2); sarrayDestroy(&sa3); sarrayDestroy(&sa4); FREE(filestr); return 0; }
int main(int argc, char **argv) { const char *name; l_int32 i, n; BOX *box; PIX *pix0, *pix1, *pixd; PIXA *pixa; SARRAY *sa1, *sa2, *sa3, *sa4; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ---------------- Find all the jpg and tif images --------------- */ sa1 = getSortedPathnamesInDirectory(".", ".jpg", 0, 0); sa2 = getSortedPathnamesInDirectory(".", ".tif", 0, 0); sa3 = sarraySelectByRange(sa1, 0, 9); sa4 = sarraySelectByRange(sa2, 0, 9); sarrayConcatenate(sa3, sa4); n = sarrayGetCount(sa3); sarrayDestroy(&sa1); sarrayDestroy(&sa2); sarrayDestroy(&sa4); /* ---------------- Use replace to fill up a pixa -------------------*/ pixa = pixaCreate(1); pixaExtendArrayToSize(pixa, n); if ((pix0 = pixRead("marge.jpg")) == NULL) rp->success = FALSE; pix1 = pixScaleToSize(pix0, 144, 108); /* scale 0.25 */ pixDestroy(&pix0); pixaInitFull(pixa, pix1, NULL); /* fill it up */ pixd = pixaDisplayTiledInRows(pixa, 32, 1000, 1.0, 0, 25, 2); pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display); pixWrite("/tmp/regout/pix1.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pix1); pixDestroy(&pixd); /* ---------------- And again with jpgs and tifs -------------------*/ for (i = 0; i < n; i++) { name = sarrayGetString(sa3, i, L_NOCOPY); if ((pix0 = pixRead(name)) == NULL) rp->success = FALSE; pix1 = pixScaleToSize(pix0, 144, 108); pixaReplacePix(pixa, i, pix1, NULL); pixDestroy(&pix0); } pixd = pixaDisplayTiledInRows(pixa, 32, 1000, 1.0, 0, 25, 2); pixDisplayWithTitle(pixd, 400, 100, NULL, rp->display); pixWrite("/tmp/regout/pix2.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); /* ---------------- And again, reversing the order ------------------*/ box = boxCreate(0, 0, 0, 0); pixaInitFull(pixa, NULL, box); boxDestroy(&box); for (i = 0; i < n; i++) { name = sarrayGetString(sa3, i, L_NOCOPY); if ((pix0 = pixRead(name)) == NULL) rp->success = FALSE; pix1 = pixScaleToSize(pix0, 144, 108); pixaReplacePix(pixa, n - 1 - i, pix1, NULL); pixDestroy(&pix0); } pixd = pixaDisplayTiledInRows(pixa, 32, 1000, 1.0, 0, 25, 2); pixDisplayWithTitle(pixd, 700, 100, NULL, rp->display); pixWrite("/tmp/regout/pix3.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); sarrayDestroy(&sa3); pixaDestroy(&pixa); return regTestCleanup(rp); }