/*! * pixaGenerateFontFromFile() * * Input: dir (directory holding image of character set) * fontsize (4, 6, 8, ... , 20, in pts at 300 ppi) * &bl1 (<return> baseline of row 1) * &bl2 (<return> baseline of row 2) * &bl3 (<return> baseline of row 3) * Return: pixa of font bitmaps for 95 characters, or null on error * * These font generation functions use 9 sets, each with bitmaps * of 94 ascii characters, all in Palatino-Roman font. * Each input bitmap has 3 rows of characters. The range of * ascii values in each row is as follows: * row 0: 32-57 (32 is a space) * row 1: 58-91 (92, '\', is not represented in this font) * row 2: 93-126 * We LR flip the '/' char to generate a bitmap for the missing * '\' character, so that we have representations of all 95 * printable chars. * * Typically, use pixaGetFont() to generate the character bitmaps * in memory for a bmf. This will simply access the bitmap files * in a serialized pixa that were produced in prog/genfonts.c using * this function. */ PIXA * pixaGenerateFontFromFile(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2) { char *pathname; l_int32 fileno; PIX *pix; PIXA *pixa; PROCNAME("pixaGenerateFontFromFile"); if (!pbl0 || !pbl1 || !pbl2) return (PIXA *)ERROR_PTR("&bl not all defined", procName, NULL); *pbl0 = *pbl1 = *pbl2 = 0; if (!dir) return (PIXA *)ERROR_PTR("dir not defined", procName, NULL); fileno = (fontsize / 2) - 2; if (fileno < 0 || fileno > NUM_FONTS) return (PIXA *)ERROR_PTR("font size invalid", procName, NULL); pathname = genPathname(dir, inputfonts[fileno]); pix = pixRead(pathname); FREE(pathname); if (!pix) return (PIXA *)ERROR_PTR("pix not all defined", procName, NULL); pixa = pixaGenerateFont(pix, fontsize, pbl0, pbl1, pbl2); pixDestroy(&pix); return pixa; }
/*! * pixaGetFont() * * Input: dir (directory holding pixa of character set) * fontsize (4, 6, 8, ... , 20) * &bl1 (<return> baseline of row 1) * &bl2 (<return> baseline of row 2) * &bl3 (<return> baseline of row 3) * Return: pixa of font bitmaps for 95 characters, or null on error * * Notes: * (1) This reads a pre-computed pixa file with the 95 ascii chars. */ PIXA * pixaGetFont(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2) { char *pathname; l_int32 fileno; PIXA *pixa; PROCNAME("pixaGetFont"); fileno = (fontsize / 2) - 2; if (fileno < 0 || fileno > NUM_FONTS) return (PIXA *)ERROR_PTR("font size invalid", procName, NULL); if (!pbl0 || !pbl1 || !pbl2) return (PIXA *)ERROR_PTR("&bl not all defined", procName, NULL); *pbl0 = baselines[fileno][0]; *pbl1 = baselines[fileno][1]; *pbl2 = baselines[fileno][2]; pathname = genPathname(dir, outputfonts[fileno]); pixa = pixaRead(pathname); FREE(pathname); if (!pixa) L_WARNING("pixa of char bitmaps not found\n", procName); return pixa; }
void TestGenPathname(L_REGPARAMS *rp, const char *dir, const char *fname, const char *result) { char expect[256], localdir[256]; char *path = genPathname(dir, fname); if (!dir || dir[0] == '\0') { if (!getcwd(localdir, sizeof(localdir))) fprintf(stderr, "bad bad bad -- no local directory!\n"); snprintf(expect, sizeof(expect), "%s/%s", localdir, result); #ifdef _WIN32 convertSepCharsInPath(expect, UNIX_PATH_SEPCHAR); #endif /* _WIN32 */ regTestCompareStrings(rp, (l_uint8 *)expect, strlen(expect), (l_uint8 *)path, strlen(path)); } else { regTestCompareStrings(rp, (l_uint8 *)result, strlen(result), (l_uint8 *)path, strlen(path)); } if (rp->display) { char *newdir = NULL; if (dir && dir[0] == '\0') newdir = stringNew("\"\""); else if (dir) newdir = stringNew(dir); fprintf(stderr, "genPathname(%s, %s) --> %s\n", newdir, fname, path); lept_free(newdir); } lept_free(path); return; }
/*! * \brief gplotMakeOutput() * * \param[in] gplot * \return 0 if OK; 1 on error * * <pre> * Notes: * (1) This uses gplot and the new arrays to add a plot * to the output, by writing a new data file and appending * the appropriate plot commands to the command file. * (2) This is the only function in this file that requires the * gnuplot executable, to actually generate the plot. * (3) The command file name for unix is canonical (i.e., directory /tmp) * but the temp filename paths in the command file must be correct. * (4) The gnuplot program for windows is wgnuplot.exe. * </pre> */ l_int32 gplotMakeOutput(GPLOT *gplot) { char buf[L_BUF_SIZE]; char *cmdname; l_int32 ignore; PROCNAME("gplotMakeOutput"); if (!gplot) return ERROR_INT("gplot not defined", procName, 1); gplotGenCommandFile(gplot); gplotGenDataFiles(gplot); cmdname = genPathname(gplot->cmdname, NULL); #ifndef _WIN32 snprintf(buf, L_BUF_SIZE, "gnuplot %s", cmdname); #else snprintf(buf, L_BUF_SIZE, "wgnuplot %s", cmdname); #endif /* _WIN32 */ ignore = system(buf); /* gnuplot || wgnuplot */ LEPT_FREE(cmdname); return 0; }
/*! * pixDisplayMultiple() * * Input: filepattern * Return: 0 if OK; 1 on error * * Notes: * (1) This allows display of multiple images using gthumb on unix * and i_view32 on windows. The @filepattern is a regular * expression that is expanded by the shell. * (2) _fullpath automatically changes '/' to '\' if necessary. */ l_int32 pixDisplayMultiple(const char *filepattern) { char buffer[L_BUF_SIZE]; l_int32 ignore; #ifdef _WIN32 char *pathname; char *dir, *tail; char fullpath[_MAX_PATH]; #endif /* _WIN32 */ PROCNAME("pixDisplayMultiple"); if (!filepattern || strlen(filepattern) == 0) return ERROR_INT("filepattern not defined", procName, 1); #ifndef _WIN32 snprintf(buffer, L_BUF_SIZE, "gthumb %s &", filepattern); #else /* irFanView wants absolute path for directory */ pathname = genPathname(filepattern, NULL); splitPathAtDirectory(pathname, &dir, &tail); _fullpath(fullpath, dir, sizeof(fullpath)); snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /filepattern=\"%s\" /thumbs", fullpath, tail); FREE(pathname); FREE(dir); FREE(tail); #endif /* _WIN32 */ ignore = system(buffer); return 0; }
int main(int argc, char **argv) { char *filein, *tempfile, *printer; char buf[512]; l_int32 ignore; static char mainName[] = "printtiff"; if (argc != 2 && argc != 3) return ERROR_INT(" Syntax: printtiff filein [printer]", mainName, 1); filein = argv[1]; if (argc == 3) printer = argv[2]; lept_rm(NULL, TEMP_PS); tempfile = genPathname("/tmp", TEMP_PS); convertTiffMultipageToPS(filein, tempfile, NULL, FILL_FACTOR); if (argc == 3) { sprintf(buf, "lpr -P%s %s &", printer, tempfile); ignore = system(buf); } lept_free(tempfile); return 0; }
int main(int argc, char **argv) { l_int32 ret; char *filein, *tempfile, *printer; char buf[512]; static char mainName[] = "printtiff"; if (argc != 2 && argc != 3) return ERROR_INT(" Syntax: printtiff filein [printer]", mainName, 1); filein = argv[1]; if (argc == 3) printer = argv[2]; fprintf(stderr, "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" " Warning: this program should only be used for testing,\n" " and not in a production environment, because of a\n" " potential vulnerability with the 'system' call.\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"); setLeptDebugOK(1); (void)lept_rm(NULL, TEMP_PS); tempfile = genPathname("/tmp", TEMP_PS); convertTiffMultipageToPS(filein, tempfile, FILL_FACTOR); if (argc == 3) { snprintf(buf, sizeof(buf), "lpr -P%s %s &", printer, tempfile); ret = system(buf); } lept_free(tempfile); return 0; }
/*! * pixaSaveFont() * * Input: indir (directory holding image of character set) * outdir (directory into which the output pixa file * will be written) * size (in pts, at 300 ppi) * Return: 0 if OK, 1 on error * * Notes: * (1) This saves a font of a particular size. * (2) prog/genfonts calls this function for each of the * nine font sizes, to generate all the font pixa files. */ l_int32 pixaSaveFont(const char *indir, const char *outdir, l_int32 size) { char *pathname; l_int32 bl1, bl2, bl3; PIXA *pixa; PROCNAME("pixaSaveFont"); if (size < 4 || size > 20 || (size % 2)) return ERROR_INT("size must be in {4, 6, ..., 20}", procName, 1); if ((pixa = pixaGenerateFont(indir, size, &bl1, &bl2, &bl3)) == NULL) return ERROR_INT("pixa not made", procName, 1); pathname = genPathname(outdir, outputfonts[(size - 4) / 2]); pixaWrite(pathname, pixa); #if DEBUG_FONT_GEN fprintf(stderr, "Found %d chars in font size %d\n", pixaGetCount(pixa), size); fprintf(stderr, "Baselines are at: %d, %d, %d\n", bl1, bl2, bl3); #endif /* DEBUG_FONT_GEN */ FREE(pathname); pixaDestroy(&pixa); return 0; }
/*! * \brief regTestCleanup() * * \param[in] rp regression test parameters * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) This copies anything written to the temporary file to the * output file /tmp/lept/reg_results.txt. * </pre> */ l_int32 regTestCleanup(L_REGPARAMS *rp) { char result[512]; char *results_file; /* success/failure output in 'compare' mode */ char *text, *message; l_int32 retval; size_t nbytes; PROCNAME("regTestCleanup"); if (!rp) return ERROR_INT("rp not defined", procName, 1); fprintf(stderr, "Time: %7.3f sec\n", stopTimerNested(rp->tstart)); fprintf(stderr, "################################################\n"); /* If generating golden files or running in display mode, release rp */ if (!rp->fp) { LEPT_FREE(rp->testname); LEPT_FREE(rp->tempfile); LEPT_FREE(rp); return 0; } /* Compare mode: read back data from temp file */ fclose(rp->fp); text = (char *)l_binaryRead(rp->tempfile, &nbytes); LEPT_FREE(rp->tempfile); if (!text) { rp->success = FALSE; LEPT_FREE(rp->testname); LEPT_FREE(rp); return ERROR_INT("text not returned", procName, 1); } /* Prepare result message */ if (rp->success) snprintf(result, sizeof(result), "SUCCESS: %s_reg\n", rp->testname); else snprintf(result, sizeof(result), "FAILURE: %s_reg\n", rp->testname); message = stringJoin(text, result); LEPT_FREE(text); results_file = genPathname("/tmp/lept", "reg_results.txt"); fileAppendString(results_file, message); retval = (rp->success) ? 0 : 1; LEPT_FREE(results_file); LEPT_FREE(message); LEPT_FREE(rp->testname); LEPT_FREE(rp); return retval; }
int main(int argc, char **argv) { char *dirin, *dirout, *infile, *outfile, *tail; l_int32 i, nfiles, border, x, y, w, h, xb, yb, wb, hb; BOX *box1, *box2; BOXA *boxa1, *boxa2; PIX *pixs, *pixt1, *pixd; SARRAY *safiles; static char mainName[] = "croptext"; if (argc != 4) return ERROR_INT("Syntax: croptext dirin border dirout", mainName, 1); dirin = argv[1]; border = atoi(argv[2]); dirout = argv[3]; setLeptDebugOK(1); safiles = getSortedPathnamesInDirectory(dirin, NULL, 0, 0); nfiles = sarrayGetCount(safiles); for (i = 0; i < nfiles; i++) { infile = sarrayGetString(safiles, i, L_NOCOPY); splitPathAtDirectory(infile, NULL, &tail); outfile = genPathname(dirout, tail); pixs = pixRead(infile); pixt1 = pixMorphSequence(pixs, "r11 + c10.40 + o5.5 + x4", 0); boxa1 = pixConnComp(pixt1, NULL, 8); if (boxaGetCount(boxa1) == 0) { fprintf(stderr, "Warning: no components on page %s\n", tail); continue; } boxa2 = boxaSort(boxa1, L_SORT_BY_AREA, L_SORT_DECREASING, NULL); box1 = boxaGetBox(boxa2, 0, L_CLONE); boxGetGeometry(box1, &x, &y, &w, &h); xb = L_MAX(0, x - border); yb = L_MAX(0, y - border); wb = w + 2 * border; hb = h + 2 * border; box2 = boxCreate(xb, yb, wb, hb); pixd = pixClipRectangle(pixs, box2, NULL); pixWrite(outfile, pixd, IFF_TIFF_G4); pixDestroy(&pixs); pixDestroy(&pixt1); pixDestroy(&pixd); boxaDestroy(&boxa1); boxaDestroy(&boxa2); } return 0; }
/*! * gplotCreate() * * Input: rootname (root for all output files) * outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11, * GPLOT_LATEX) * title (<optional> overall title) * xlabel (<optional> x axis label) * ylabel (<optional> y axis label) * Return: gplot, or null on error * * Notes: * (1) This initializes the plot. * (2) The 'title', 'xlabel' and 'ylabel' strings can have spaces, * double quotes and backquotes, but not single quotes. */ GPLOT * gplotCreate(const char *rootname, l_int32 outformat, const char *title, const char *xlabel, const char *ylabel) { char *newroot; char buf[L_BUF_SIZE]; GPLOT *gplot; PROCNAME("gplotCreate"); if (!rootname) return (GPLOT *)ERROR_PTR("rootname not defined", procName, NULL); if (outformat != GPLOT_PNG && outformat != GPLOT_PS && outformat != GPLOT_EPS && outformat != GPLOT_X11 && outformat != GPLOT_LATEX) return (GPLOT *)ERROR_PTR("outformat invalid", procName, NULL); if ((gplot = (GPLOT *)CALLOC(1, sizeof(GPLOT))) == NULL) return (GPLOT *)ERROR_PTR("gplot not made", procName, NULL); gplot->cmddata = sarrayCreate(0); gplot->datanames = sarrayCreate(0); gplot->plotdata = sarrayCreate(0); gplot->plottitles = sarrayCreate(0); gplot->plotstyles = numaCreate(0); /* Save title, labels, rootname, outformat, cmdname, outname */ newroot = genPathname(rootname, NULL); gplot->rootname = newroot; gplot->outformat = outformat; snprintf(buf, L_BUF_SIZE, "%s.cmd", newroot); gplot->cmdname = stringNew(buf); if (outformat == GPLOT_PNG) snprintf(buf, L_BUF_SIZE, "%s.png", newroot); else if (outformat == GPLOT_PS) snprintf(buf, L_BUF_SIZE, "%s.ps", newroot); else if (outformat == GPLOT_EPS) snprintf(buf, L_BUF_SIZE, "%s.eps", newroot); else if (outformat == GPLOT_LATEX) snprintf(buf, L_BUF_SIZE, "%s.tex", newroot); else /* outformat == GPLOT_X11 */ buf[0] = '\0'; gplot->outname = stringNew(buf); if (title) gplot->title = stringNew(title); if (xlabel) gplot->xlabel = stringNew(xlabel); if (ylabel) gplot->ylabel = stringNew(ylabel); return gplot; }
/*! * getSortedPathnamesInDirectory() * * Input: directory name * substr (<optional> substring filter on filenames; can be NULL) * firstpage (0-based) * npages (use 0 for all to the end) * Return: sarray of sorted pathnames, or NULL on error * * Notes: * (1) If 'substr' is not NULL, only filenames that contain * the substring can be returned. If 'substr' is NULL, * none of the filenames are filtered out. * (2) The files in the directory, after optional filtering by * the substring, are lexically sorted in increasing order. * The full pathnames are returned for the requested sequence. * If no files are found after filtering, returns an empty sarray. */ SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 firstpage, l_int32 npages) { char *fname, *fullname; l_int32 i, nfiles, lastpage; SARRAY *sa, *safiles, *saout; PROCNAME("getSortedPathnamesInDirectory"); if (!dirname) return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL); if ((sa = getFilenamesInDirectory(dirname)) == NULL) return (SARRAY *)ERROR_PTR("sa not made", procName, NULL); safiles = sarraySelectBySubstring(sa, substr); sarrayDestroy(&sa); nfiles = sarrayGetCount(safiles); if (nfiles == 0) { L_WARNING("no files found", procName); return safiles; } sarraySort(safiles, safiles, L_SORT_INCREASING); firstpage = L_MIN(L_MAX(firstpage, 0), nfiles - 1); if (npages == 0) npages = nfiles - firstpage; lastpage = L_MIN(firstpage + npages - 1, nfiles - 1); saout = sarrayCreate(lastpage - firstpage + 1); for (i = firstpage; i <= lastpage; i++) { fname = sarrayGetString(safiles, i, L_NOCOPY); fullname = genPathname(dirname, fname); sarrayAddString(saout, fullname, L_INSERT); } sarrayDestroy(&safiles); return saout; }
/*! * pixaSaveFont() * * Input: indir (<optional> directory holding image of character set) * outdir (directory into which the output pixa file * will be written) * fontsize (in pts, at 300 ppi) * Return: 0 if OK, 1 on error * * Notes: * (1) This saves a font of a particular size. * (2) If @dir == null, this generates the font bitmaps from a * compiled string. * (3) prog/genfonts calls this function for each of the * nine font sizes, to generate all the font pixa files. */ l_int32 pixaSaveFont(const char *indir, const char *outdir, l_int32 fontsize) { char *pathname; l_int32 bl1, bl2, bl3; PIXA *pixa; PROCNAME("pixaSaveFont"); if (fontsize < 4 || fontsize > 20 || (fontsize % 2)) return ERROR_INT("fontsize must be in {4, 6, ..., 20}", procName, 1); if (!indir) { /* Generate from a string */ L_INFO("Generating pixa of bitmap fonts from string\n", procName); pixa = pixaGenerateFontFromString(fontsize, &bl1, &bl2, &bl3); } else { /* Generate from an image file */ L_INFO("Generating pixa of bitmap fonts from a file\n", procName); pixa = pixaGenerateFontFromFile(indir, fontsize, &bl1, &bl2, &bl3); } if (!pixa) return ERROR_INT("pixa not made", procName, 1); pathname = genPathname(outdir, outputfonts[(fontsize - 4) / 2]); pixaWrite(pathname, pixa); #if DEBUG_FONT_GEN L_INFO("Found %d chars in font size %d\n", procName, pixaGetCount(pixa), fontsize); L_INFO("Baselines are at: %d, %d, %d\n", procName, bl1, bl2, bl3); #endif /* DEBUG_FONT_GEN */ FREE(pathname); pixaDestroy(&pixa); return 0; }
/*! * pixDisplayWithTitle() * * Input: pix (1, 2, 4, 8, 16, 32 bpp) * x, y (location of display frame) * title (<optional> on frame; can be NULL); * dispflag (1 to write, else disabled) * Return: 0 if OK; 1 on error * * Notes: * (1) See notes for pixDisplay(). * (2) This displays the image if dispflag == 1. */ l_int32 pixDisplayWithTitle(PIX *pixs, l_int32 x, l_int32 y, const char *title, l_int32 dispflag) { char *tempname; char buffer[L_BUF_SIZE]; static l_int32 index = 0; /* caution: not .so or thread safe */ l_int32 w, h, d, spp, maxheight, opaque, threeviews, ignore; l_float32 ratw, rath, ratmin; PIX *pix0, *pix1, *pix2; PIXCMAP *cmap; #ifndef _WIN32 l_int32 wt, ht; #else char *pathname; char fullpath[_MAX_PATH]; #endif /* _WIN32 */ PROCNAME("pixDisplayWithTitle"); if (dispflag != 1) return 0; if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (var_DISPLAY_PROG != L_DISPLAY_WITH_XZGV && var_DISPLAY_PROG != L_DISPLAY_WITH_XLI && var_DISPLAY_PROG != L_DISPLAY_WITH_XV && var_DISPLAY_PROG != L_DISPLAY_WITH_IV && var_DISPLAY_PROG != L_DISPLAY_WITH_OPEN) { return ERROR_INT("no program chosen for display", procName, 1); } /* Display with three views if either spp = 4 or if colormapped * and the alpha component is not fully opaque */ opaque = TRUE; if ((cmap = pixGetColormap(pixs)) != NULL) pixcmapIsOpaque(cmap, &opaque); spp = pixGetSpp(pixs); threeviews = (spp == 4 || !opaque) ? TRUE : FALSE; /* If colormapped and not opaque, remove the colormap to RGBA */ if (!opaque) pix0 = pixRemoveColormap(pixs, REMOVE_CMAP_WITH_ALPHA); else pix0 = pixClone(pixs); /* Scale if necessary; this will also remove a colormap */ pixGetDimensions(pix0, &w, &h, &d); maxheight = (threeviews) ? MAX_DISPLAY_HEIGHT / 3 : MAX_DISPLAY_HEIGHT; if (w <= MAX_DISPLAY_WIDTH && h <= maxheight) { if (d == 16) /* take MSB */ pix1 = pixConvert16To8(pix0, 1); else pix1 = pixClone(pix0); } else { ratw = (l_float32)MAX_DISPLAY_WIDTH / (l_float32)w; rath = (l_float32)maxheight / (l_float32)h; ratmin = L_MIN(ratw, rath); if (ratmin < 0.125 && d == 1) pix1 = pixScaleToGray8(pix0); else if (ratmin < 0.25 && d == 1) pix1 = pixScaleToGray4(pix0); else if (ratmin < 0.33 && d == 1) pix1 = pixScaleToGray3(pix0); else if (ratmin < 0.5 && d == 1) pix1 = pixScaleToGray2(pix0); else pix1 = pixScale(pix0, ratmin, ratmin); } pixDestroy(&pix0); if (!pix1) return ERROR_INT("pix1 not made", procName, 1); /* Generate the three views if required */ if (threeviews) pix2 = pixDisplayLayersRGBA(pix1, 0xffffff00, 0); else pix2 = pixClone(pix1); if (index == 0) { lept_rmdir("disp"); lept_mkdir("disp"); } index++; if (pixGetDepth(pix2) < 8 || (w < MAX_SIZE_FOR_PNG && h < MAX_SIZE_FOR_PNG)) { snprintf(buffer, L_BUF_SIZE, "/tmp/disp/write.%03d.png", index); pixWrite(buffer, pix2, IFF_PNG); } else { snprintf(buffer, L_BUF_SIZE, "/tmp/disp/write.%03d.jpg", index); pixWrite(buffer, pix2, IFF_JFIF_JPEG); } tempname = stringNew(buffer); #ifndef _WIN32 /* Unix */ if (var_DISPLAY_PROG == L_DISPLAY_WITH_XZGV) { /* no way to display title */ pixGetDimensions(pix2, &wt, &ht, NULL); snprintf(buffer, L_BUF_SIZE, "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10, x, y, tempname); } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XLI) { if (title) { snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &", x, y, title, tempname); } else { snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &", x, y, tempname); } } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XV) { if (title) { snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d -name \"%s\" %s &", x, y, title, tempname); } else { snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d %s &", x, y, tempname); } } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_OPEN) { snprintf(buffer, L_BUF_SIZE, "open %s &", tempname); } ignore = system(buffer); #else /* _WIN32 */ /* Windows: L_DISPLAY_WITH_IV */ pathname = genPathname(tempname, NULL); _fullpath(fullpath, pathname, sizeof(fullpath)); if (title) { snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"", fullpath, x, y, title); } else { snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d)", fullpath, x, y); } ignore = system(buffer); FREE(pathname); #endif /* _WIN32 */ pixDestroy(&pix1); pixDestroy(&pix2); FREE(tempname); return 0; }
/*! * pixWrite() * * Input: filename * pix * format (defined in imageio.h) * Return: 0 if OK; 1 on error * * Notes: * (1) Open for write using binary mode (with the "b" flag) * to avoid having Windows automatically translate the NL * into CRLF, which corrupts image files. On non-windows * systems this flag should be ignored, per ISO C90. * Thanks to Dave Bryan for pointing this out. * (2) If the default image format is requested, we use the input format; * if the input format is unknown, a lossless format is assigned. * (3) There are two modes with respect to file naming. * (a) The default code writes to @filename. * (b) If WRITE_AS_NAMED is defined to 0, it's a bit fancier. * Then, if @filename does not have a file extension, one is * automatically appended, depending on the requested format. * The original intent for providing option (b) was to insure * that filenames on Windows have an extension that matches * the image compression. However, this is not the default. */ l_int32 pixWrite(const char *filename, PIX *pix, l_int32 format) { char *fname; FILE *fp; PROCNAME("pixWrite"); if (!pix) return ERROR_INT("pix not defined", procName, 1); if (!filename) return ERROR_INT("filename not defined", procName, 1); if (format == IFF_JP2) return ERROR_INT("jp2 not supported", procName, 1); fname = genPathname(filename, NULL); #if WRITE_AS_NAMED /* Default */ if ((fp = fopenWriteStream(fname, "wb+")) == NULL) { FREE(fname); return ERROR_INT("stream not opened", procName, 1); } #else /* Add an extension to the output name if none exists */ {l_int32 extlen; char *extension, *filebuf; splitPathAtExtension(fname, NULL, &extension); extlen = strlen(extension); FREE(extension); if (extlen == 0) { if (format == IFF_DEFAULT || format == IFF_UNKNOWN) format = pixChooseOutputFormat(pix); filebuf = (char *)CALLOC(strlen(fname) + 10, sizeof(char)); if (!filebuf) { return ERROR_INT("filebuf not made", procName, 1); FREE(fname); } strncpy(filebuf, fname, strlen(fname)); strcat(filebuf, "."); strcat(filebuf, ImageFileFormatExtensions[format]); } else { filebuf = (char *)fname; } fp = fopenWriteStream(filebuf, "wb+"); if (filebuf != fname) FREE(filebuf); if (fp == NULL) { FREE(fname); return ERROR_INT("stream not opened", procName, 1); } } #endif /* WRITE_AS_NAMED */ FREE(fname); if (pixWriteStream(fp, pix, format)) { fclose(fp); return ERROR_INT("pix not written to stream", procName, 1); } /* Close the stream except if GIF under windows, because * EGifCloseFile() closes the windows file stream! */ if (format != IFF_GIF) fclose(fp); #ifndef _WIN32 else /* gif file */ fclose(fp); #endif /* ! _WIN32 */ return 0; }
int main(int argc, char **argv) { char *fname, *filename; const char *str; char buffer[512]; l_int32 i, npages; size_t length; FILE *fp; NUMA *naflags, *nasizes; PIX *pix, *pix1, *pix2, *pixd; PIXA *pixa; PIXCMAP *cmap; SARRAY *savals, *satypes, *sa; static char mainName[] = "mtifftest"; if (argc != 1) return ERROR_INT(" Syntax: mtifftest", mainName, 1); lept_mkdir("tiff"); #if 1 /* ------------------ Test multipage I/O -------------------*/ /* This puts every image file in the directory with a string * match to "weasel" into a multipage tiff file. * Images with 1 bpp are coded as g4; the others as zip. * It then reads back into a pix and displays. */ writeMultipageTiff(".", "weasel8.", "/tmp/tiff/weasel8.tif"); pixa = pixaReadMultipageTiff("/tmp/tiff/weasel8.tif"); pixd = pixaDisplayTiledInRows(pixa, 1, 1200, 0.5, 0, 15, 4); pixDisplay(pixd, 100, 0); pixDestroy(&pixd); pixd = pixaDisplayTiledInRows(pixa, 8, 1200, 0.8, 0, 15, 4); pixDisplay(pixd, 100, 200); pixDestroy(&pixd); pixd = pixaDisplayTiledInRows(pixa, 32, 1200, 1.2, 0, 15, 4); pixDisplay(pixd, 100, 400); pixDestroy(&pixd); pixaDestroy(&pixa); #endif #if 1 /* ------------ Test single-to-multipage I/O -------------------*/ /* Read the files and generate a multipage tiff file of G4 images. * Then convert that to a G4 compressed and ascii85 encoded PS file. */ sa = getSortedPathnamesInDirectory(".", "weasel4.", 0, 4); sarrayWriteStream(stderr, sa); sarraySort(sa, sa, L_SORT_INCREASING); sarrayWriteStream(stderr, sa); npages = sarrayGetCount(sa); for (i = 0; i < npages; i++) { fname = sarrayGetString(sa, i, 0); filename = genPathname(".", fname); pix1 = pixRead(filename); if (!pix1) continue; pix2 = pixConvertTo1(pix1, 128); if (i == 0) pixWriteTiff("/tmp/tiff/weasel4", pix2, IFF_TIFF_G4, "w+"); else pixWriteTiff("/tmp/tiff/weasel4", pix2, IFF_TIFF_G4, "a"); pixDestroy(&pix1); pixDestroy(&pix2); lept_free(filename); } /* Write it out as a PS file */ convertTiffMultipageToPS("/tmp/tiff/weasel4", "/tmp/tiff/weasel4.ps", NULL, 0.95); sarrayDestroy(&sa); #endif #if 1 /* ------------------ Test multipage I/O -------------------*/ /* Read count of pages in tiff multipage file */ writeMultipageTiff(".", "weasel2", weasel_orig); fp = lept_fopen(weasel_orig, "rb"); if (fileFormatIsTiff(fp)) { tiffGetCount(fp, &npages); fprintf(stderr, " Tiff: %d page\n", npages); } else return ERROR_INT(" file not tiff", mainName, 1); lept_fclose(fp); /* Split into separate page files */ for (i = 0; i < npages + 1; i++) { /* read one beyond to catch error */ if (i == npages) L_INFO("Errors in next 2 lines are intentional!\n", mainName); pix = pixReadTiff(weasel_orig, i); if (!pix) continue; sprintf(buffer, "/tmp/tiff/%03d.tif", i); pixWrite(buffer, pix, IFF_TIFF_ZIP); pixDestroy(&pix); } /* Read separate page files and write reversed file */ for (i = npages - 1; i >= 0; i--) { sprintf(buffer, "/tmp/tiff/%03d.tif", i); pix = pixRead(buffer); if (!pix) continue; if (i == npages - 1) pixWriteTiff(weasel_rev, pix, IFF_TIFF_ZIP, "w+"); else pixWriteTiff(weasel_rev, pix, IFF_TIFF_ZIP, "a"); pixDestroy(&pix); } /* Read reversed file and reverse again */ pixa = pixaCreate(npages); for (i = 0; i < npages; i++) { pix = pixReadTiff(weasel_rev, i); pixaAddPix(pixa, pix, L_INSERT); } for (i = npages - 1; i >= 0; i--) { pix = pixaGetPix(pixa, i, L_CLONE); if (i == npages - 1) pixWriteTiff(weasel_rev_rev, pix, IFF_TIFF_ZIP, "w+"); else pixWriteTiff(weasel_rev_rev, pix, IFF_TIFF_ZIP, "a"); pixDestroy(&pix); } pixaDestroy(&pixa); #endif #if 0 /* ----- test adding custom public tags to a tiff header ----- */ pix = pixRead("feyn.tif"); naflags = numaCreate(10); savals = sarrayCreate(10); satypes = sarrayCreate(10); nasizes = numaCreate(10); /* numaAddNumber(naflags, TIFFTAG_XMLPACKET); */ /* XMP: 700 */ numaAddNumber(naflags, 700); str = "<xmp>This is a Fake XMP packet</xmp>\n<text>Guess what ...?</text>"; length = strlen(str); sarrayAddString(savals, (char *)str, L_COPY); sarrayAddString(satypes, (char *)"char*", L_COPY); numaAddNumber(nasizes, length); /* get it all */ numaAddNumber(naflags, 269); /* DOCUMENTNAME */ sarrayAddString(savals, (char *)"One silly title", L_COPY); sarrayAddString(satypes, (char *)"const char*", L_COPY); numaAddNumber(naflags, 270); /* IMAGEDESCRIPTION */ sarrayAddString(savals, (char *)"One page of text", L_COPY); sarrayAddString(satypes, (char *)"const char*", L_COPY); /* the max sample is used by rendering programs * to scale the dynamic range */ numaAddNumber(naflags, 281); /* MAXSAMPLEVALUE */ sarrayAddString(savals, (char *)"4", L_COPY); sarrayAddString(satypes, (char *)"l_uint16", L_COPY); /* note that date is required to be a 20 byte string */ numaAddNumber(naflags, 306); /* DATETIME */ sarrayAddString(savals, (char *)"2004:10:11 09:35:15", L_COPY); sarrayAddString(satypes, (char *)"const char*", L_COPY); /* note that page number requires 2 l_uint16 input */ numaAddNumber(naflags, 297); /* PAGENUMBER */ sarrayAddString(savals, (char *)"1-412", L_COPY); sarrayAddString(satypes, (char *)"l_uint16-l_uint16", L_COPY); pixWriteTiffCustom("/tmp/tiff/tags.tif", pix, IFF_TIFF_G4, "w", naflags, savals, satypes, nasizes); fprintTiffInfo(stderr, (char *)"/tmp/tiff/tags.tif"); fprintf(stderr, "num flags = %d\n", numaGetCount(naflags)); fprintf(stderr, "num sizes = %d\n", numaGetCount(nasizes)); fprintf(stderr, "num vals = %d\n", sarrayGetCount(savals)); fprintf(stderr, "num types = %d\n", sarrayGetCount(satypes)); numaDestroy(&naflags); numaDestroy(&nasizes); sarrayDestroy(&savals); sarrayDestroy(&satypes); pixDestroy(&pix); #endif return 0; }
int main(int argc, char **argv) { char *filein, *fileout, *fname; char buffer[512]; const char *psfile = "/tmp/junk_split_image.ps"; l_int32 nx, ny, i, w, h, d, ws, hs, n, res, ignore; l_float32 scale; PIX *pixs, *pixt, *pixr; PIXA *pixa; static char mainName[] = "splitimage2pdf"; if (argc != 5) return ERROR_INT(" Syntax: splitimage2pdf filein nx ny fileout", mainName, 1); filein = argv[1]; nx = atoi(argv[2]); ny = atoi(argv[3]); fileout = argv[4]; lept_rm(NULL, "junk_split_image.ps"); if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); d = pixGetDepth(pixs); if (d == 1 ) lept_rm(NULL, "junk_split_image.tif"); else if (d == 8 || d == 32) lept_rm(NULL, "junk_split_image.jpg"); else return ERROR_INT("d not in {1,8,32} bpp", mainName, 1); pixGetDimensions(pixs, &ws, &hs, NULL); if (ny * ws > nx * hs) pixr = pixRotate90(pixs, 1); else pixr = pixClone(pixs); pixa = pixaSplitPix(pixr, nx, ny, 0, 0); n = pixaGetCount(pixa); res = 300; for (i = 0; i < n; i++) { pixt = pixaGetPix(pixa, i, L_CLONE); pixGetDimensions(pixt, &w, &h, NULL); scale = L_MIN(FILL_FACTOR * 2550 / w, FILL_FACTOR * 3300 / h); fname = NULL; if (d == 1) { fname = genPathname("/tmp", "junk_split_image.tif"); pixWrite(fname, pixt, IFF_TIFF_G4); if (i == 0) { convertG4ToPS(fname, psfile, "w", 0, 0, 300, scale, 1, FALSE, TRUE); } else { convertG4ToPS(fname, psfile, "a", 0, 0, 300, scale, 1, FALSE, TRUE); } } else { fname = genPathname("/tmp", "junk_split_image.jpg"); pixWrite(fname, pixt, IFF_JFIF_JPEG); if (i == 0) { convertJpegToPS(fname, psfile, "w", 0, 0, 300, scale, 1, TRUE); } else { convertJpegToPS(fname, psfile, "a", 0, 0, 300, scale, 1, TRUE); } } lept_free(fname); pixDestroy(&pixt); } snprintf(buffer, sizeof(buffer), "ps2pdf %s %s", psfile, fileout); ignore = system(buffer); /* ps2pdf */ pixaDestroy(&pixa); pixDestroy(&pixr); pixDestroy(&pixs); return 0; }
/*! * dewarpDebug() * * Input: dew * subdir (a subdirectory of /tmp; e.g., "dew1") * index (to help label output images; e.g., the page number) * Return: 0 if OK, 1 on error * * Notes: * (1) Prints dewarp fields and generates disparity array contour images. * The contour images are written to file: * /tmp/[subdir]/pixv_[index].png */ l_int32 dewarpDebug(L_DEWARP *dew, const char *subdir, l_int32 index) { char outdir[256], fname[64]; char *pathname; l_int32 svd, shd; PIX *pixv, *pixh; PROCNAME("dewarpDebug"); if (!dew) return ERROR_INT("dew not defined", procName, 1); if (!subdir) return ERROR_INT("subdir not defined", procName, 1); fprintf(stderr, "pageno = %d, hasref = %d, refpage = %d\n", dew->pageno, dew->hasref, dew->refpage); fprintf(stderr, "sampling = %d, redfactor = %d, minlines = %d\n", dew->sampling, dew->redfactor, dew->minlines); svd = shd = 0; if (!dew->hasref) { if (dew->sampvdispar) svd = 1; if (dew->samphdispar) shd = 1; fprintf(stderr, "sampv = %d, samph = %d\n", svd, shd); fprintf(stderr, "w = %d, h = %d\n", dew->w, dew->h); fprintf(stderr, "nx = %d, ny = %d\n", dew->nx, dew->ny); fprintf(stderr, "nlines = %d\n", dew->nlines); if (svd) { fprintf(stderr, "(min,max,abs-diff) line curvature = (%d,%d,%d)\n", dew->mincurv, dew->maxcurv, dew->maxcurv - dew->mincurv); } if (shd) { fprintf(stderr, "(left edge slope = %d, right edge slope = %d\n", dew->leftslope, dew->rightslope); fprintf(stderr, "(left,right,abs-diff) edge curvature = " "(%d,%d,%d)\n", dew->leftcurv, dew->rightcurv, L_ABS(dew->leftcurv - dew->rightcurv)); } } if (!svd && !shd) { fprintf(stderr, "No disparity arrays\n"); return 0; } dewarpPopulateFullRes(dew, NULL, 0, 0); lept_mkdir(subdir); snprintf(outdir, sizeof(outdir), "/tmp/%s", subdir); if (svd) { pixv = fpixRenderContours(dew->fullvdispar, 3.0, 0.15); snprintf(fname, sizeof(fname), "pixv_%d.png", index); pathname = genPathname(outdir, fname); pixWrite(pathname, pixv, IFF_PNG); pixDestroy(&pixv); FREE(pathname); } if (shd) { pixh = fpixRenderContours(dew->fullhdispar, 3.0, 0.15); snprintf(fname, sizeof(fname), "pixh_%d.png", index); pathname = genPathname(outdir, fname); pixWrite(pathname, pixh, IFF_PNG); pixDestroy(&pixh); FREE(pathname); } return 0; }
int main(int argc, char **argv) { char buffer[512]; char *tempfile1, *tempfile2; l_uint8 *data; l_int32 i, j, w, h, seq, ret, same; size_t nbytes; const char *title; BOX *box; BOXA *boxa1, *boxa2; L_BYTEA *ba; L_PDF_DATA *lpd; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6; PIX *pixs, *pixt, *pixg, *pixgc, *pixc; static char mainName[] = "pdfiotest"; if (argc != 1) return ERROR_INT("syntax: pdfiotest", mainName, 1); l_pdfSetDateAndVersion(0); lept_mkdir("lept/pdf"); #if 1 /* --------------- Single image tests ------------------- */ fprintf(stderr, "\n*** Writing single images as pdf files\n"); convertToPdf("weasel2.4c.png", L_FLATE_ENCODE, 0, "/tmp/lept/pdf/file01.pdf", 0, 0, 72, "weasel2.4c.png", NULL, 0); convertToPdf("test24.jpg", L_JPEG_ENCODE, 0, "/tmp/lept/pdf/file02.pdf", 0, 0, 72, "test24.jpg", NULL, 0); convertToPdf("feyn.tif", L_G4_ENCODE, 0, "/tmp/lept/pdf/file03.pdf", 0, 0, 300, "feyn.tif", NULL, 0); pixs = pixRead("feyn.tif"); pixConvertToPdf(pixs, L_G4_ENCODE, 0, "/tmp/lept/pdf/file04.pdf", 0, 0, 300, "feyn.tif", NULL, 0); pixDestroy(&pixs); pixs = pixRead("test24.jpg"); pixConvertToPdf(pixs, L_JPEG_ENCODE, 5, "/tmp/lept/pdf/file05.pdf", 0, 0, 72, "test24.jpg", NULL, 0); pixDestroy(&pixs); pixs = pixRead("feyn.tif"); pixt = pixScaleToGray2(pixs); pixWrite("/tmp/lept/pdf/feyn8.png", pixt, IFF_PNG); convertToPdf("/tmp/lept/pdf/feyn8.png", L_JPEG_ENCODE, 0, "/tmp/lept/pdf/file06.pdf", 0, 0, 150, "feyn8.png", NULL, 0); pixDestroy(&pixs); pixDestroy(&pixt); convertToPdf("weasel4.16g.png", L_FLATE_ENCODE, 0, "/tmp/lept/pdf/file07.pdf", 0, 0, 30, "weasel4.16g.png", NULL, 0); pixs = pixRead("test24.jpg"); pixg = pixConvertTo8(pixs, 0); box = boxCreate(100, 100, 100, 100); pixc = pixClipRectangle(pixs, box, NULL); pixgc = pixClipRectangle(pixg, box, NULL); pixWrite("/tmp/lept/pdf/pix32.jpg", pixc, IFF_JFIF_JPEG); pixWrite("/tmp/lept/pdf/pix8.jpg", pixgc, IFF_JFIF_JPEG); convertToPdf("/tmp/lept/pdf/pix32.jpg", L_FLATE_ENCODE, 0, "/tmp/lept/pdf/file08.pdf", 0, 0, 72, "pix32.jpg", NULL, 0); convertToPdf("/tmp/lept/pdf/pix8.jpg", L_FLATE_ENCODE, 0, "/tmp/lept/pdf/file09.pdf", 0, 0, 72, "pix8.jpg", NULL, 0); pixDestroy(&pixs); pixDestroy(&pixg); pixDestroy(&pixc); pixDestroy(&pixgc); boxDestroy(&box); #endif #if 1 /* --------------- Multiple image tests ------------------- */ fprintf(stderr, "\n*** Writing multiple images as single page pdf files\n"); pix1 = pixRead("feyn-fract.tif"); pix2 = pixRead("weasel8.240c.png"); /* l_pdfSetDateAndVersion(0); */ /* First, write the 1 bpp image through the mask onto the weasels */ for (i = 0; i < 5; i++) { for (j = 0; j < 10; j++) { seq = (i == 0 && j == 0) ? L_FIRST_IMAGE : L_NEXT_IMAGE; title = (i == 0 && j == 0) ? "feyn-fract.tif" : NULL; pixConvertToPdf(pix2, L_FLATE_ENCODE, 0, NULL, 100 * j, 100 * i, 70, title, &lpd, seq); } } pixConvertToPdf(pix1, L_G4_ENCODE, 0, "/tmp/lept/pdf/file10.pdf", 0, 0, 80, NULL, &lpd, L_LAST_IMAGE); /* Now, write the 1 bpp image over the weasels */ l_pdfSetG4ImageMask(0); for (i = 0; i < 5; i++) { for (j = 0; j < 10; j++) { seq = (i == 0 && j == 0) ? L_FIRST_IMAGE : L_NEXT_IMAGE; title = (i == 0 && j == 0) ? "feyn-fract.tif" : NULL; pixConvertToPdf(pix2, L_FLATE_ENCODE, 0, NULL, 100 * j, 100 * i, 70, title, &lpd, seq); } } pixConvertToPdf(pix1, L_G4_ENCODE, 0, "/tmp/lept/pdf/file11.pdf", 0, 0, 80, NULL, &lpd, L_LAST_IMAGE); l_pdfSetG4ImageMask(1); pixDestroy(&pix1); pixDestroy(&pix2); #endif #if 1 /* -------- pdf convert segmented with no image regions -------- */ fprintf(stderr, "\n*** Writing segmented images without image regions\n"); pix1 = pixRead("rabi.png"); pix2 = pixScaleToGray2(pix1); pixWrite("/tmp/lept/pdf/rabi8.jpg", pix2, IFF_JFIF_JPEG); pix3 = pixThresholdTo4bpp(pix2, 16, 1); pixWrite("/tmp/lept/pdf/rabi4.png", pix3, IFF_PNG); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); /* 1 bpp input */ convertToPdfSegmented("rabi.png", 300, L_G4_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file12.pdf"); convertToPdfSegmented("rabi.png", 300, L_JPEG_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file13.pdf"); convertToPdfSegmented("rabi.png", 300, L_FLATE_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file14.pdf"); /* 8 bpp input, no cmap */ convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_G4_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file15.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_JPEG_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file16.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_FLATE_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file17.pdf"); /* 4 bpp input, cmap */ convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_G4_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file18.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file19.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128, NULL, 0, 0, NULL, "/tmp/lept/pdf/file20.pdf"); #endif #if 1 /* ---------- pdf convert segmented with image regions ---------- */ fprintf(stderr, "\n*** Writing segmented images with image regions\n"); /* Get the image region(s) for rabi.png. There are two * small bogus regions at the top, but we'll keep them for * the demonstration. */ pix1 = pixRead("rabi.png"); pixSetResolution(pix1, 300, 300); pixGetDimensions(pix1, &w, &h, NULL); pix2 = pixGenerateHalftoneMask(pix1, NULL, NULL, NULL); pix3 = pixMorphSequence(pix2, "c20.1 + c1.20", 0); boxa1 = pixConnComp(pix3, NULL, 8); boxa2 = boxaTransform(boxa1, 0, 0, 0.5, 0.5); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); /* 1 bpp input */ convertToPdfSegmented("rabi.png", 300, L_G4_ENCODE, 128, boxa1, 0, 0.25, NULL, "/tmp/lept/pdf/file21.pdf"); convertToPdfSegmented("rabi.png", 300, L_JPEG_ENCODE, 128, boxa1, 0, 0.25, NULL, "/tmp/lept/pdf/file22.pdf"); convertToPdfSegmented("rabi.png", 300, L_FLATE_ENCODE, 128, boxa1, 0, 0.25, NULL, "/tmp/lept/pdf/file23.pdf"); /* 8 bpp input, no cmap */ convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_G4_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file24.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_JPEG_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file25.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_FLATE_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file26.pdf"); /* 4 bpp input, cmap */ convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_G4_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file27.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file28.pdf"); convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file29.pdf"); /* 4 bpp input, cmap, data output */ data = NULL; convertToPdfDataSegmented("/tmp/lept/pdf/rabi4.png", 150, L_G4_ENCODE, 128, boxa2, 0, 0.5, NULL, &data, &nbytes); l_binaryWrite("/tmp/lept/pdf/file30.pdf", "w", data, nbytes); lept_free(data); convertToPdfDataSegmented("/tmp/lept/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128, boxa2, 0, 0.5, NULL, &data, &nbytes); l_binaryWrite("/tmp/lept/pdf/file31.pdf", "w", data, nbytes); lept_free(data); convertToPdfDataSegmented("/tmp/lept/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128, boxa2, 0, 0.5, NULL, &data, &nbytes); l_binaryWrite("/tmp/lept/pdf/file32.pdf", "w", data, nbytes); lept_free(data); boxaDestroy(&boxa1); boxaDestroy(&boxa2); #endif #if 1 /* -------- pdf convert segmented from color image -------- */ fprintf(stderr, "\n*** Writing color segmented images\n"); pix1 = pixRead("candelabrum.011.jpg"); pix2 = pixScale(pix1, 3.0, 3.0); pixWrite("/tmp/lept/pdf/candelabrum3.jpg", pix2, IFF_JFIF_JPEG); GetImageMask(pix2, 200, &boxa1, "/tmp/lept/pdf/seg1.jpg"); convertToPdfSegmented("/tmp/lept/pdf/candelabrum3.jpg", 200, L_G4_ENCODE, 100, boxa1, 0, 0.25, NULL, "/tmp/lept/pdf/file33.pdf"); convertToPdfSegmented("/tmp/lept/pdf/candelabrum3.jpg", 200, L_JPEG_ENCODE, 100, boxa1, 0, 0.25, NULL, "/tmp/lept/pdf/file34.pdf"); convertToPdfSegmented("/tmp/lept/pdf/candelabrum3.jpg", 200, L_FLATE_ENCODE, 100, boxa1, 0, 0.25, NULL, "/tmp/lept/pdf/file35.pdf"); pixDestroy(&pix1); pixDestroy(&pix2); boxaDestroy(&boxa1); pix1 = pixRead("lion-page.00016.jpg"); pix2 = pixScale(pix1, 3.0, 3.0); pixWrite("/tmp/lept/pdf/lion16.jpg", pix2, IFF_JFIF_JPEG); pix3 = pixRead("lion-mask.00016.tif"); boxa1 = pixConnComp(pix3, NULL, 8); boxa2 = boxaTransform(boxa1, 0, 0, 3.0, 3.0); convertToPdfSegmented("/tmp/lept/pdf/lion16.jpg", 200, L_G4_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file36.pdf"); convertToPdfSegmented("/tmp/lept/pdf/lion16.jpg", 200, L_JPEG_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file37.pdf"); convertToPdfSegmented("/tmp/lept/pdf/lion16.jpg", 200, L_FLATE_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file38.pdf"); /* Quantize the non-image part and flate encode. * This is useful because it results in a smaller file than * when you flate-encode the un-quantized non-image regions. */ pix4 = pixScale(pix3, 3.0, 3.0); /* higher res mask, for combining */ pix5 = QuantizeNonImageRegion(pix2, pix4, 12); pixWrite("/tmp/lept/pdf/lion16-quant.png", pix5, IFF_PNG); convertToPdfSegmented("/tmp/lept/pdf/lion16-quant.png", 200, L_FLATE_ENCODE, 190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file39.pdf"); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); boxaDestroy(&boxa1); boxaDestroy(&boxa2); #endif #if 1 /* ------------------ Test multipage pdf generation ----------------- */ fprintf(stderr, "\n*** Writing multipage pdfs from single page pdfs\n"); /* Generate a multi-page pdf from all these files */ startTimer(); concatenatePdf("/tmp/lept/pdf", "file", "/tmp/lept/pdf/cat_lept.pdf"); fprintf(stderr, "All files have been concatenated: /tmp/lept/pdf/cat_lept.pdf\n" "Concatenation time: %7.3f\n", stopTimer()); #endif #if 1 /* ----------- Test corruption recovery by concatenation ------------ */ /* Put two good pdf files in a directory */ lept_rmdir("lept/good"); lept_mkdir("lept/good"); lept_cp("testfile1.pdf", "lept/good", NULL, NULL); lept_cp("testfile2.pdf", "lept/good", NULL, NULL); concatenatePdf("/tmp/lept/good", "file", "/tmp/lept/pdf/good.pdf"); /* Make a bad version with the pdf id removed, so that it is not * recognized as a pdf */ lept_rmdir("lept/bad"); lept_mkdir("lept/bad"); ba = l_byteaInitFromFile("testfile2.pdf"); data = l_byteaGetData(ba, &nbytes); l_binaryWrite("/tmp/lept/bad/testfile0.notpdf.pdf", "w", data + 10, nbytes - 10); /* Make a version with a corrupted trailer */ if (data) data[2297] = '2'; /* munge trailer object 6: change 458 --> 428 */ l_binaryWrite("/tmp/lept/bad/testfile2.bad.pdf", "w", data, nbytes); l_byteaDestroy(&ba); /* Copy testfile1.pdf to the /tmp/lept/bad directory. Then * run concat on the bad files. The "not pdf" file should be * ignored, and the corrupted pdf file should be properly parsed, * so the resulting concatenated pdf files should be identical. */ fprintf(stderr, "\nWe attempt to build from the bad directory\n"); lept_cp("testfile1.pdf", "lept/bad", NULL, NULL); concatenatePdf("/tmp/lept/bad", "file", "/tmp/lept/pdf/bad.pdf"); filesAreIdentical("/tmp/lept/pdf/good.pdf", "/tmp/lept/pdf/bad.pdf", &same); if (same) fprintf(stderr, "Fixed: files are the same\n" "Attempt succeeded\n"); else fprintf(stderr, "Busted: files are different\n"); #endif #if 0 fprintf(stderr, "\n*** pdftk writes multipage pdfs from images\n"); tempfile1 = genPathname("/tmp/lept/pdf", "file*.pdf"); tempfile2 = genPathname("/tmp/lept/pdf", "cat_pdftk.pdf"); snprintf(buffer, sizeof(buffer), "pdftk %s output %s", tempfile1, tempfile2); ret = system(buffer); /* pdftk */ lept_free(tempfile1); lept_free(tempfile2); #endif #if 1 /* -- Test simple interface for generating multi-page pdf from images -- */ fprintf(stderr, "\n*** Writing multipage pdfs from images\n"); /* Put four image files in a directory. They will be encoded thus: * file1.png: flate (8 bpp, only 10 colors) * file2.jpg: dct (8 bpp, 256 colors because of the jpeg encoding) * file3.tif: g4 (1 bpp) * file4.jpg: dct (32 bpp) */ lept_mkdir("lept/image"); pix1 = pixRead("feyn.tif"); pix2 = pixRead("rabi.png"); pix3 = pixScaleToGray3(pix1); pix4 = pixScaleToGray3(pix2); pix5 = pixScale(pix1, 0.33, 0.33); pix6 = pixRead("test24.jpg"); pixWrite("/tmp/lept/image/file1.png", pix3, IFF_PNG); /* 10 colors */ pixWrite("/tmp/lept/image/file2.jpg", pix4, IFF_JFIF_JPEG); /* 256 colors */ pixWrite("/tmp/lept/image/file3.tif", pix5, IFF_TIFF_G4); pixWrite("/tmp/lept/image/file4.jpg", pix6, IFF_JFIF_JPEG); startTimer(); convertFilesToPdf("/tmp/lept/image", "file", 100, 0.8, 0, 75, "4 file test", "/tmp/lept/pdf/fourimages.pdf"); fprintf(stderr, "4-page pdf generated: /tmp/lept/pdf/fourimages.pdf\n" "Time: %7.3f\n", stopTimer()); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); #endif return 0; }
/*! * dewarpShowResults() * * Input: dewa * sarray (of indexed input images) * boxa (crop boxes for input images; can be null) * firstpage, lastpage * fontdir (for text bitmap fonts) * pdfout (filename) * Return: 0 if OK, 1 on error * * Notes: * (1) This generates a pdf of image pairs (before, after) for * the designated set of input pages. * (2) If the boxa exists, its elements are aligned with numbers * in the filenames in @sa. It is used to crop the input images. * It is assumed that the dewa was generated from the cropped * images. No undercropping is applied before rendering. */ l_int32 dewarpShowResults(L_DEWARPA *dewa, SARRAY *sa, BOXA *boxa, l_int32 firstpage, l_int32 lastpage, const char *fontdir, const char *pdfout) { char bufstr[256]; char *outpath; l_int32 i, modelpage; L_BMF *bmf; BOX *box; L_DEWARP *dew; PIX *pixs, *pixc, *pixd, *pixt1, *pixt2; PIXA *pixa; PROCNAME("dewarpShowResults"); if (!dewa) return ERROR_INT("dewa not defined", procName, 1); if (!sa) return ERROR_INT("sa not defined", procName, 1); if (!pdfout) return ERROR_INT("pdfout not defined", procName, 1); if (firstpage > lastpage) return ERROR_INT("invalid first/last page numbers", procName, 1); lept_rmdir("dewarp_pdfout"); lept_mkdir("dewarp_pdfout"); if ((bmf = bmfCreate(fontdir, 6)) == NULL) L_ERROR("bmf not made; page info not displayed", procName); fprintf(stderr, "Dewarping and generating s/by/s view\n"); for (i = firstpage; i <= lastpage; i++) { if (i && (i % 10 == 0)) fprintf(stderr, ".. %d ", i); pixs = pixReadIndexed(sa, i); if (boxa) { box = boxaGetBox(boxa, i, L_CLONE); pixc = pixClipRectangle(pixs, box, NULL); boxDestroy(&box); } else pixc = pixClone(pixs); dew = dewarpaGetDewarp(dewa, i); pixd = NULL; if (dew) { dewarpaApplyDisparity(dewa, dew->pageno, pixc, GRAYIN_VALUE, 0, 0, &pixd, NULL); dewarpMinimize(dew); } pixa = pixaCreate(2); pixaAddPix(pixa, pixc, L_INSERT); if (pixd) pixaAddPix(pixa, pixd, L_INSERT); pixt1 = pixaDisplayTiledAndScaled(pixa, 32, 500, 2, 0, 35, 2); if (dew) { modelpage = (dew->hasref) ? dew->refpage : dew->pageno; snprintf(bufstr, sizeof(bufstr), "Page %d; using %d\n", i, modelpage); } else snprintf(bufstr, sizeof(bufstr), "Page %d; no dewarp\n", i); pixt2 = pixAddSingleTextblock(pixt1, bmf, bufstr, 0x0000ff00, L_ADD_BELOW, 0); snprintf(bufstr, sizeof(bufstr), "/tmp/dewarp_pdfout/%05d", i); pixWrite(bufstr, pixt2, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixs); pixDestroy(&pixt1); pixDestroy(&pixt2); } fprintf(stderr, "\n"); fprintf(stderr, "Generating pdf of result\n"); convertFilesToPdf("/tmp/dewarp_pdfout", NULL, 100, 1.0, L_JPEG_ENCODE, 0, "Dewarp sequence", pdfout); outpath = genPathname(pdfout, NULL); fprintf(stderr, "Output written to: %s\n", outpath); FREE(outpath); bmfDestroy(&bmf); return 0; }
/*! * \brief pixWrite() * * \param[in] filename * \param[in] pix * \param[in] format defined in imageio.h * \return 0 if OK; 1 on error * * <pre> * Notes: * (1) Open for write using binary mode (with the "b" flag) * to avoid having Windows automatically translate the NL * into CRLF, which corrupts image files. On non-windows * systems this flag should be ignored, per ISO C90. * Thanks to Dave Bryan for pointing this out. * (2) If the default image format IFF_DEFAULT is requested: * use the input format if known; otherwise, use a lossless format. * (3) There are two modes with respect to file naming. * (a) The default code writes to %filename. * (b) If WRITE_AS_NAMED is defined to 0, it's a bit fancier. * Then, if %filename does not have a file extension, one is * automatically appended, depending on the requested format. * The original intent for providing option (b) was to insure * that filenames on Windows have an extension that matches * the image compression. However, this is not the default. * </pre> */ l_int32 pixWrite(const char *filename, PIX *pix, l_int32 format) { char *fname; FILE *fp; PROCNAME("pixWrite"); if (!pix) return ERROR_INT("pix not defined", procName, 1); if (!filename) return ERROR_INT("filename not defined", procName, 1); fname = genPathname(filename, NULL); #if WRITE_AS_NAMED /* Default */ if ((fp = fopenWriteStream(fname, "wb+")) == NULL) { LEPT_FREE(fname); return ERROR_INT("stream not opened", procName, 1); } #else /* Add an extension to the output name if none exists */ {l_int32 extlen; char *extension, *filebuf; splitPathAtExtension(fname, NULL, &extension); extlen = strlen(extension); LEPT_FREE(extension); if (extlen == 0) { if (format == IFF_DEFAULT || format == IFF_UNKNOWN) format = pixChooseOutputFormat(pix); filebuf = (char *)LEPT_CALLOC(strlen(fname) + 10, sizeof(char)); if (!filebuf) { return ERROR_INT("filebuf not made", procName, 1); LEPT_FREE(fname); } strncpy(filebuf, fname, strlen(fname)); strcat(filebuf, "."); strcat(filebuf, ImageFileFormatExtensions[format]); } else { filebuf = (char *)fname; } fp = fopenWriteStream(filebuf, "wb+"); if (filebuf != fname) LEPT_FREE(filebuf); if (fp == NULL) { LEPT_FREE(fname); return ERROR_INT("stream not opened", procName, 1); } } #endif /* WRITE_AS_NAMED */ LEPT_FREE(fname); if (pixWriteStream(fp, pix, format)) { fclose(fp); return ERROR_INT("pix not written to stream", procName, 1); } fclose(fp); return 0; }
/*! * \brief pixDisplayWriteFormat() * * \param[in] pix 1, 2, 4, 8, 16, 32 bpp * \param[in] reduction -1 to erase and reset; 0 to disable; * otherwise this is a reduction factor * \param[in] format IFF_DEFAULT or IFF_PNG * \return 0 if OK; 1 on error * * <pre> * Notes: * (1) This writes files with pathnames "/tmp/lept/display/file.*" * if reduction \> 0. These can be collected into a pdf using * pixDisplayMultiple(); * (2) Before writing a set of files, call * pixDisplayWrite(NULL, -1); * This erases any previously written files in that directory. * (3) If reduction \> 1 and depth == 1, this does a scale-to-gray * reduction. * (4) This function uses a static internal variable to number * output files written by a single process. Behavior * with a shared library may be unpredictable. * (5) Output file format is as follows: * format == IFF_DEFAULT: * png if d \< 8 or d == 16 or if the output pix * has a colormap. Otherwise, output is jpg. * format == IFF_PNG: * png (lossless) on all images. * (6) For 16 bpp, the choice of full dynamic range with log scale * is the best for displaying these images. Alternative outputs are * pix8 = pixMaxDynamicRange(pixt, L_LINEAR_SCALE); * pix8 = pixConvert16To8(pixt, 0); // low order byte * pix8 = pixConvert16To8(pixt, 1); // high order byte * </pre> */ l_int32 pixDisplayWriteFormat(PIX *pixs, l_int32 reduction, l_int32 format) { char buf[L_BUF_SIZE]; char *fname; l_float32 scale; PIX *pix1, *pix2; static l_int32 index = 0; /* caution: not .so or thread safe */ PROCNAME("pixDisplayWriteFormat"); if (reduction == 0) return 0; if (reduction < 0) { /* initialize */ lept_rmdir("lept/display"); index = 0; return 0; } if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (format != IFF_DEFAULT && format != IFF_PNG) { L_INFO("invalid format; using default\n", procName); format = IFF_DEFAULT; } if (index == 0) lept_mkdir("lept/display"); index++; if (reduction == 1) { pix1 = pixClone(pixs); } else { scale = 1. / (l_float32)reduction; if (pixGetDepth(pixs) == 1) pix1 = pixScaleToGray(pixs, scale); else pix1 = pixScale(pixs, scale, scale); } if (pixGetDepth(pix1) == 16) { pix2 = pixMaxDynamicRange(pix1, L_LOG_SCALE); snprintf(buf, L_BUF_SIZE, "file.%03d.png", index); fname = genPathname("/tmp/lept/display", buf); pixWrite(fname, pix2, IFF_PNG); pixDestroy(&pix2); } else if (pixGetDepth(pix1) < 8 || pixGetColormap(pix1) || format == IFF_PNG) { snprintf(buf, L_BUF_SIZE, "file.%03d.png", index); fname = genPathname("/tmp/lept/display", buf); pixWrite(fname, pix1, IFF_PNG); } else { snprintf(buf, L_BUF_SIZE, "file.%03d.jpg", index); fname = genPathname("/tmp/lept/display", buf); pixWrite(fname, pix1, format); } LEPT_FREE(fname); pixDestroy(&pix1); return 0; }
int main(int argc, char **argv) { char *filein, *fname, *argp, *argn; char buffer[512]; l_int32 i, w, h, ignore; l_float32 scale; FILE *fp; PIX *pixs, *pixt; static char mainName[] = "printimage"; if (argc < 2 || argc > 4) return ERROR_INT( " Syntax: printimage filein [-P<printer>] [-#<number>]", mainName, 1); /* parse args */ filein = argv[1]; argp = argn = NULL; if (argc > 2) { for (i = 2; i < argc; i++) { if (argv[i][1] == 'P') argp = argv[i]; else if (argv[i][1] == '#') argn = argv[i]; } } lept_rm(NULL, "print_image.ps"); if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); pixGetDimensions(pixs, &w, &h, NULL); if (w > h) { pixt = pixRotate90(pixs, 1); pixGetDimensions(pixt, &w, &h, NULL); } else { pixt = pixClone(pixs); } scale = L_MIN(FILL_FACTOR * 2550 / w, FILL_FACTOR * 3300 / h); fname = genPathname("/tmp", "print_image.ps"); fp = lept_fopen(fname, "wb+"); pixWriteStreamPS(fp, pixt, NULL, 300, scale); lept_fclose(fp); /* print it out */ if (argp && !argn) { sprintf(buffer, "lpr %s %s &", argp, fname); ignore = system(buffer); } else if (!argp && argn) { sprintf(buffer, "lpr %s %s &", argn, fname); ignore = system(buffer); } else if (argp && argn) { sprintf(buffer, "lpr %s %s %s &", argp, argn, fname); ignore = system(buffer); } lept_free(fname); pixDestroy(&pixs); pixDestroy(&pixt); return 0; }
/*! * regTestSetup() * * Input: argc (from invocation; can be either 1 or 2) * argv (to regtest: @argv[1] is one of these: * "generate", "compare", "display") * &rp (<return> all regression params) * Return: 0 if OK, 1 on error * * Notes: * (1) Call this function with the args to the reg test. * There are three cases: * Case 1: * There is either only one arg, or the second arg is "compare". * This is the mode in which you run a regression test * (or a set of them), looking for failures and logging * the results to a file. The output, which includes * logging of all reg test failures plus a SUCCESS or * FAILURE summary for each test, is appended to the file * "/tmp/reg_results.txt. For this case, as in Case 2, * the display field in rp is set to FALSE, preventing * image display. * Case 2: * The second arg is "generate". This will cause * generation of new golden files for the reg test. * The results of the reg test are not recorded, and * the display field in rp is set to FALSE. * Case 3: * The second arg is "display". The test will run and * files will be written. Comparisons with golden files * will not be carried out, so the only notion of success * or failure is with tests that do not involve golden files. * The display field in rp is TRUE, and this is used by * pixDisplayWithTitle(). * (2) See regutils.h for examples of usage. */ l_int32 regTestSetup(l_int32 argc, char **argv, L_REGPARAMS **prp) { char *testname, *vers; char errormsg[64]; L_REGPARAMS *rp; PROCNAME("regTestSetup"); if (argc != 1 && argc != 2) { snprintf(errormsg, sizeof(errormsg), "Syntax: %s [ [generate] | compare | display ]", argv[0]); return ERROR_INT(errormsg, procName, 1); } if ((testname = getRootNameFromArgv0(argv[0])) == NULL) return ERROR_INT("invalid root", procName, 1); if ((rp = (L_REGPARAMS *) CALLOC(1, sizeof(L_REGPARAMS))) == NULL) return ERROR_INT("rp not made", procName, 1); *prp = rp; rp->testname = testname; rp->index = -1; /* increment before each test */ /* Initialize to true. A failure in any test is registered * as a failure of the regression test. */ rp->success = TRUE; /* Make sure the regout subdirectory exists */ lept_mkdir("regout"); /* Only open a stream to a temp file for the 'compare' case */ if (argc == 1 || !strcmp(argv[1], "compare")) { rp->mode = L_REG_COMPARE; rp->tempfile = genPathname("/tmp/regout", "regtest_output.txt"); rp->fp = fopenWriteStream(rp->tempfile, "wb"); if (rp->fp == NULL) { rp->success = FALSE; return ERROR_INT("stream not opened for tempfile", procName, 1); } } else if (!strcmp(argv[1], "generate")) { rp->mode = L_REG_GENERATE; lept_mkdir("golden"); } else if (!strcmp(argv[1], "display")) { rp->mode = L_REG_DISPLAY; rp->display = TRUE; } else { FREE(rp); snprintf(errormsg, sizeof(errormsg), "Syntax: %s [ [generate] | compare | display ]", argv[0]); return ERROR_INT(errormsg, procName, 1); } /* Print out test name and both the leptonica and * image libarary versions */ fprintf(stderr, "\n################ %s_reg ###############\n", rp->testname); vers = getLeptonicaVersion(); fprintf(stderr, "%s\n", vers); FREE(vers); vers = getImagelibVersions(); fprintf(stderr, "%s\n", vers); FREE(vers); rp->tstart = startTimerNested(); return 0; }
/*! * pixDisplayWriteFormat() * * Input: pix (1, 2, 4, 8, 16, 32 bpp) * reduction (-1 to reset/erase; 0 to disable; * otherwise this is a reduction factor) * format (IFF_PNG or IFF_JFIF_JPEG) * Return: 0 if OK; 1 on error * * Notes: * (1) This writes files if reduction > 0. These can be displayed using * pixDisplayMultiple("/tmp/display/file*"); * (2) All previously written files can be erased by calling with * reduction < 0; the value of pixs is ignored. * (3) If reduction > 1 and depth == 1, this does a scale-to-gray * reduction. * (4) This function uses a static internal variable to number * output files written by a single process. Behavior * with a shared library may be unpredictable. * (5) Output file format is as follows: * format == IFF_JFIF_JPEG: * png if d < 8 or d == 16 or if the output pix * has a colormap. Otherwise, output is jpg. * format == IFF_PNG: * png (lossless) on all images. * (6) For 16 bpp, the choice of full dynamic range with log scale * is the best for displaying these images. Alternative outputs are * pix8 = pixMaxDynamicRange(pixt, L_LINEAR_SCALE); * pix8 = pixConvert16To8(pixt, 0); // low order byte * pix8 = pixConvert16To8(pixt, 1); // high order byte */ l_int32 pixDisplayWriteFormat(PIX *pixs, l_int32 reduction, l_int32 format) { char buf[L_BUF_SIZE]; char *fname; l_float32 scale; PIX *pixt, *pix8; static l_int32 index = 0; /* caution: not .so or thread safe */ PROCNAME("pixDisplayWriteFormat"); if (reduction == 0) return 0; if (reduction < 0) { index = 0; /* reset; this will cause erasure at next call to write */ return 0; } if (format != IFF_JFIF_JPEG && format != IFF_PNG) return ERROR_INT("invalid format", procName, 1); if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (index == 0) { lept_rmdir("display"); lept_mkdir("display"); } index++; if (reduction == 1) { pixt = pixClone(pixs); } else { scale = 1. / (l_float32)reduction; if (pixGetDepth(pixs) == 1) pixt = pixScaleToGray(pixs, scale); else pixt = pixScale(pixs, scale, scale); } if (pixGetDepth(pixt) == 16) { pix8 = pixMaxDynamicRange(pixt, L_LOG_SCALE); snprintf(buf, L_BUF_SIZE, "file.%03d.png", index); fname = genPathname("/tmp/display", buf); pixWrite(fname, pix8, IFF_PNG); pixDestroy(&pix8); } else if (pixGetDepth(pixt) < 8 || pixGetColormap(pixt) || format == IFF_PNG) { snprintf(buf, L_BUF_SIZE, "file.%03d.png", index); fname = genPathname("/tmp/display", buf); pixWrite(fname, pixt, IFF_PNG); } else { snprintf(buf, L_BUF_SIZE, "file.%03d.jpg", index); fname = genPathname("/tmp/display", buf); pixWrite(fname, pixt, format); } FREE(fname); pixDestroy(&pixt); return 0; }
/*! * dewarpaShowArrays() * * Input: dewa * scalefact (on contour images; typ. 0.5) * first (first page model to render) * last (last page model to render; use 0 to go to end) * fontdir (for text bitmap fonts) * Return: 0 if OK, 1 on error * * Notes: * (1) Generates a pdf of contour plots of the disparity arrays. * (2) This only shows actual models; not ref models */ l_int32 dewarpaShowArrays(L_DEWARPA *dewa, l_float32 scalefact, l_int32 first, l_int32 last, const char *fontdir) { char buf[256]; char *pathname; l_int32 i, svd, shd; L_BMF *bmf; L_DEWARP *dew; PIX *pixv, *pixvs, *pixh, *pixhs, *pixt, *pixd; PIXA *pixa; PROCNAME("dewarpaShowArrays"); if (!dewa) return ERROR_INT("dew not defined", procName, 1); if (first < 0 || first > dewa->maxpage) return ERROR_INT("first out of bounds", procName, 1); if (last <= 0 || last > dewa->maxpage) last = dewa->maxpage; if (last < first) return ERROR_INT("last < first", procName, 1); lept_rmdir("lept"); lept_mkdir("lept"); if ((bmf = bmfCreate(fontdir, 8)) == NULL) L_ERROR("bmf not made; page info not displayed", procName); fprintf(stderr, "Generating contour plots\n"); for (i = first; i <= last; i++) { if (i && ((i % 10) == 0)) fprintf(stderr, " .. %d", i); dew = dewarpaGetDewarp(dewa, i); if (!dew) continue; if (dew->hasref == 1) continue; svd = shd = 0; if (dew->sampvdispar) svd = 1; if (dew->samphdispar) shd = 1; if (!svd) { L_ERROR("sampvdispar not made for page %d!\n", procName, i); continue; } /* Generate contour plots at reduced resolution */ dewarpPopulateFullRes(dew, NULL, 0, 0); pixv = fpixRenderContours(dew->fullvdispar, 3.0, 0.15); pixvs = pixScaleBySampling(pixv, scalefact, scalefact); pixDestroy(&pixv); if (shd) { pixh = fpixRenderContours(dew->fullhdispar, 3.0, 0.15); pixhs = pixScaleBySampling(pixh, scalefact, scalefact); pixDestroy(&pixh); } dewarpMinimize(dew); /* Save side-by-side */ pixa = pixaCreate(2); pixaAddPix(pixa, pixvs, L_INSERT); if (shd) pixaAddPix(pixa, pixhs, L_INSERT); pixt = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2); snprintf(buf, sizeof(buf), "Page %d", i); pixd = pixAddSingleTextblock(pixt, bmf, buf, 0x0000ff00, L_ADD_BELOW, NULL); snprintf(buf, sizeof(buf), "arrays_%04d.png", i); pathname = genPathname("/tmp/lept", buf); pixWrite(pathname, pixd, IFF_PNG); pixaDestroy(&pixa); pixDestroy(&pixt); pixDestroy(&pixd); FREE(pathname); } bmfDestroy(&bmf); fprintf(stderr, "\n"); fprintf(stderr, "Generating pdf of contour plots\n"); convertFilesToPdf("/tmp/lept", "arrays_", 90, 1.0, L_FLATE_ENCODE, 0, "Disparity arrays", "/tmp/lept/disparity_arrays.pdf"); fprintf(stderr, "Output written to: /tmp/lept/disparity_arrays.pdf\n"); return 0; }
int main(int argc, char **argv) { char buf[512]; char *pathname, *datastr, *formstr; l_uint8 *data1, *data2; l_int32 i, bl1, bl2, bl3, sbytes, formbytes, fontsize, rbytes; size_t nbytes; PIX *pix1, *pix2, *pixd; PIXA *pixa; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ------------ Generate pixa char bitmap files from file ----------- */ lept_rmdir("filefonts"); lept_mkdir("filefonts"); for (i = 0; i < 9; i++) { pixaSaveFont("fonts", "/tmp/filefonts", sizes[i]); pathname = genPathname("/tmp/filefonts", outputfonts[i]); pixa = pixaRead(pathname); if (rp->display) { fprintf(stderr, "Found %d chars in font size %d\n", pixaGetCount(pixa), sizes[i]); } pixd = pixaDisplayTiled(pixa, 1500, 0, 15); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 0 - 8 */ if (i == 2) pixDisplayWithTitle(pixd, 100, 0, NULL, rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); lept_free(pathname); } lept_rmdir("filefonts"); /* ---------- Generate pixa char bitmap files from string --------- */ lept_rmdir("strfonts"); lept_mkdir("strfonts"); for (i = 0; i < 9; i++) { pixaSaveFont(NULL, "/tmp/strfonts", sizes[i]); pathname = genPathname("/tmp/strfonts", outputfonts[i]); pixa = pixaRead(pathname); if (rp->display) { fprintf(stderr, "Found %d chars in font size %d\n", pixaGetCount(pixa), sizes[i]); } pixd = pixaDisplayTiled(pixa, 1500, 0, 15); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 9 - 17 */ if (i == 2) pixDisplayWithTitle(pixd, 100, 150, NULL, rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); lept_free(pathname); } /* ----- Use pixaGetFont() and write the result out -----*/ lept_rmdir("pafonts"); lept_mkdir("pafonts"); for (i = 0; i < 9; i++) { pixa = pixaGetFont("/tmp/strfonts", sizes[i], &bl1, &bl2, &bl3); fprintf(stderr, "Baselines are at: %d, %d, %d\n", bl1, bl2, bl3); snprintf(buf, sizeof(buf), "/tmp/pafonts/chars-%d.pa", sizes[i]); pixaWrite(buf, pixa); if (i == 2) { pixd = pixaDisplayTiled(pixa, 1500, 0, 15); pixDisplayWithTitle(pixd, 100, 300, NULL, rp->display); pixDestroy(&pixd); } pixaDestroy(&pixa); } lept_rmdir("pafonts"); /* ------- Generate 4/3 encoded ascii strings from tiff files ------ */ lept_rmdir("fontencode"); lept_mkdir("fontencode"); for (i = 0; i < 9; i++) { fontsize = 2 * i + 4; pathname = genPathname("fonts", inputfonts[i]); data1 = l_binaryRead(pathname, &nbytes); datastr = encodeBase64(data1, nbytes, &sbytes); if (rp->display) fprintf(stderr, "nbytes = %lu, sbytes = %d\n", (unsigned long)nbytes, sbytes); formstr = reformatPacked64(datastr, sbytes, 4, 72, 1, &formbytes); snprintf(buf, sizeof(buf), "/tmp/fontencode/formstr_%d.txt", fontsize); l_binaryWrite(buf, "w", formstr, formbytes); regTestCheckFile(rp, buf); /* 18-26 */ if (i == 8) pix1 = pixReadMem(data1, nbytes); /* original */ FREE(data1); data2 = decodeBase64(datastr, sbytes, &rbytes); snprintf(buf, sizeof(buf), "/tmp/fontencode/image_%d.tif", fontsize); l_binaryWrite(buf, "w", data2, rbytes); if (i == 8) { pix2 = pixReadMem(data2, rbytes); /* encode/decode */ regTestComparePix(rp, pix1, pix2); /* 27 */ pixDestroy(&pix1); pixDestroy(&pix2); } FREE(data2); FREE(pathname); FREE(datastr); FREE(formstr); } /* ------------ Get timing for font generation ----------- */ startTimer(); for (i = 0; i < 100; i++) { pixa = pixaGenerateFontFromString(sizes[5], &bl1, &bl2, &bl3); pixaDestroy(&pixa); } fprintf(stderr, "Time for font gen = %7.4f sec\n", stopTimer() / 100.0); return regTestCleanup(rp); }
l_int32 main(int argc, char **argv) { char buf[256], rootname[256]; char *dir, *pattern, *psdir, *imagedir; char *fname, *tail, *filename; l_int32 i, n, ret; SARRAY *sa, *saps; static char mainName[] = "concatpdf"; if (argc != 2 && argc != 3) return ERROR_INT("Syntax: concatpdf dir [pattern]", mainName, 1); dir = argv[1]; pattern = (argc == 3) ? argv[2] : NULL; /* Get the names of the pdf files */ sa = getSortedPathnamesInDirectory(dir, pattern, 0, 0); sarrayWriteStream(stderr, sa); n = sarrayGetCount(sa); #if 1 /* Convert to ps */ psdir = genPathname("/tmp/ps", NULL); lept_rmdir("ps"); lept_mkdir("ps"); saps = sarrayCreate(n); for (i = 0; i < n; i++) { fname = sarrayGetString(sa, i, L_NOCOPY); splitPathAtDirectory(fname, NULL, &tail); splitPathAtExtension(tail, &filename, NULL); snprintf(buf, sizeof(buf), "acroread -toPostScript -annotsOff %s %s", fname, psdir); fprintf(stderr, "%s\n", buf); ret = system(buf); /* acroread -toPostScript -annotsOff */ snprintf(buf, sizeof(buf), "%s/%s.ps", psdir, filename); sarrayAddString(saps, buf, L_COPY); lept_free(tail); lept_free(filename); } sarrayDestroy(&sa); #endif #if 1 /* Rasterize */ imagedir = genPathname("/tmp/image", NULL); lept_rmdir("image"); lept_mkdir("image"); sarrayWriteStream(stderr, saps); n = sarrayGetCount(saps); for (i = 0; i < n; i++) { fname = sarrayGetString(saps, i, L_NOCOPY); snprintf(rootname, sizeof(rootname), "%s/r%d", imagedir, i); snprintf(buf, sizeof(buf), "ps2png-gray %s %s", fname, rootname); fprintf(stderr, "%s\n", buf); ret = system(buf); /* ps2png-gray */ } #endif #if 1 /* Generate the pdf */ convertFilesToPdf(imagedir, "png", RESOLUTION, 1.0, L_FLATE_ENCODE, 0, "", "/tmp/output.pdf"); #endif return 0; }
/*! * regTestCheckFile() * * Input: rp (regtest parameters) * localname (name of output file from reg test) * Return: 0 if OK, 1 on error (a failure in comparison is not an error) * * Notes: * (1) This function does one of three things, depending on the mode: * * "generate": makes a "golden" file as a copy @localname. * * "compare": compares @localname contents with the golden file * * "display": makes the @localname file but does no comparison * (2) The canonical format of the golden filenames is: * /tmp/golden/<root of main name>_golden.<index>.<ext of localname> * e.g., * /tmp/golden/maze_golden.0.png * It is important to add an extension to the local name, because * the extension is added to the name of the golden file. */ l_int32 regTestCheckFile(L_REGPARAMS *rp, const char *localname) { char *ext; char namebuf[256]; l_int32 ret, same, format; PIX *pix1, *pix2; PROCNAME("regTestCheckFile"); if (!rp) return ERROR_INT("rp not defined", procName, 1); if (!localname) { rp->success = FALSE; return ERROR_INT("local name not defined", procName, 1); } if (rp->mode != L_REG_GENERATE && rp->mode != L_REG_COMPARE && rp->mode != L_REG_DISPLAY) { rp->success = FALSE; return ERROR_INT("invalid mode", procName, 1); } rp->index++; /* If display mode, no generation and no testing */ if (rp->mode == L_REG_DISPLAY) return 0; /* Generate the golden file name; used in 'generate' and 'compare' */ splitPathAtExtension(localname, NULL, &ext); snprintf(namebuf, sizeof(namebuf), "/tmp/golden/%s_golden.%02d%s", rp->testname, rp->index, ext); FREE(ext); /* Generate mode. No testing. */ if (rp->mode == L_REG_GENERATE) { /* Save the file as a golden file */ ret = fileCopy(localname, namebuf); #if 0 /* Enable for details on writing of golden files */ if (!ret) { char *local = genPathname(localname, NULL); char *golden = genPathname(namebuf, NULL); L_INFO("Copy: %s to %s\n", procName, local, golden); FREE(local); FREE(golden); } #endif return ret; } /* Compare mode: test and record on failure. GIF compression * is lossless for images with up to 8 bpp (but not for RGB * because it must generate a 256 color palette). Although * the read/write cycle for GIF is idempotent in the image * pixels for bpp <= 8, it is not idempotent in the actual * file bytes. Tests comparing file bytes before and after * a GIF read/write cycle will fail. So for GIF we uncompress * the two images and compare the actual pixels. From my tests, * PNG, in addition to being lossless, is idempotent in file * bytes on read/write, so comparing the pixels is not necessary. * (It also increases the regression test time by an an average * of about 8%.) JPEG is lossy and not idempotent in the image * pixels, so no tests are constructed that would require it. */ findFileFormat(localname, &format); if (format == IFF_GIF) { same = 0; pix1 = pixRead(localname); pix2 = pixRead(namebuf); pixEqual(pix1, pix2, &same); pixDestroy(&pix1); pixDestroy(&pix2); } else { filesAreIdentical(localname, namebuf, &same); } if (!same) { fprintf(rp->fp, "Failure in %s_reg, index %d: comparing %s with %s\n", rp->testname, rp->index, localname, namebuf); fprintf(stderr, "Failure in %s_reg, index %d: comparing %s with %s\n", rp->testname, rp->index, localname, namebuf); rp->success = FALSE; } return 0; }
/*! * pixDisplayWithTitle() * * Input: pix (1, 2, 4, 8, 16, 32 bpp) * x, y (location of display frame) * title (<optional> on frame; can be NULL); * dispflag (1 to write, else disabled) * Return: 0 if OK; 1 on error * * Notes: * (1) See notes for pixDisplay(). * (2) This displays the image if dispflag == 1. */ l_int32 pixDisplayWithTitle(PIX *pixs, l_int32 x, l_int32 y, const char *title, l_int32 dispflag) { char *tempname; char buffer[L_BUF_SIZE]; static l_int32 index = 0; /* caution: not .so or thread safe */ l_int32 w, h, d, ignore; l_float32 ratw, rath, ratmin; PIX *pixt; #ifndef _WIN32 l_int32 wt, ht; #else char *pathname; char fullpath[_MAX_PATH]; #endif /* _WIN32 */ PROCNAME("pixDisplayWithTitle"); if (dispflag != 1) return 0; if (!pixs) return ERROR_INT("pixs not defined", procName, 1); if (var_DISPLAY_PROG != L_DISPLAY_WITH_XV && var_DISPLAY_PROG != L_DISPLAY_WITH_XLI && var_DISPLAY_PROG != L_DISPLAY_WITH_XZGV && var_DISPLAY_PROG != L_DISPLAY_WITH_IV) return ERROR_INT("no program chosen for display", procName, 1); pixGetDimensions(pixs, &w, &h, &d); if (w <= MAX_DISPLAY_WIDTH && h <= MAX_DISPLAY_HEIGHT) { if (d == 16) /* take MSB */ pixt = pixConvert16To8(pixs, 1); else pixt = pixClone(pixs); } else { ratw = (l_float32)MAX_DISPLAY_WIDTH / (l_float32)w; rath = (l_float32)MAX_DISPLAY_HEIGHT / (l_float32)h; ratmin = L_MIN(ratw, rath); if (ratmin < 0.125 && d == 1) pixt = pixScaleToGray8(pixs); else if (ratmin < 0.25 && d == 1) pixt = pixScaleToGray4(pixs); else if (ratmin < 0.33 && d == 1) pixt = pixScaleToGray3(pixs); else if (ratmin < 0.5 && d == 1) pixt = pixScaleToGray2(pixs); else pixt = pixScale(pixs, ratmin, ratmin); if (!pixt) return ERROR_INT("pixt not made", procName, 1); } if (index == 0) { lept_rmdir("display"); lept_mkdir("display"); } index++; if (pixGetDepth(pixt) < 8 || (w < MAX_SIZE_FOR_PNG && h < MAX_SIZE_FOR_PNG)) { snprintf(buffer, L_BUF_SIZE, "/tmp/display/write.%03d.png", index); pixWrite(buffer, pixt, IFF_PNG); } else { snprintf(buffer, L_BUF_SIZE, "/tmp/display/write.%03d.jpg", index); pixWrite(buffer, pixt, IFF_JFIF_JPEG); } tempname = stringNew(buffer); #ifndef _WIN32 /* Unix */ if (var_DISPLAY_PROG == L_DISPLAY_WITH_XV) { if (title) snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d -name \"%s\" %s &", x, y, title, tempname); else snprintf(buffer, L_BUF_SIZE, "xv -quit -geometry +%d+%d %s &", x, y, tempname); } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XLI) { if (title) snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &", x, y, title, tempname); else snprintf(buffer, L_BUF_SIZE, "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &", x, y, tempname); } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XZGV) { /* no way to display title */ pixGetDimensions(pixt, &wt, &ht, NULL); snprintf(buffer, L_BUF_SIZE, "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10, x, y, tempname); } ignore = system(buffer); #else /* _WIN32 */ /* Windows: L_DISPLAY_WITH_IV */ pathname = genPathname(tempname, NULL); _fullpath(fullpath, pathname, sizeof(fullpath)); if (title) snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"", fullpath, x, y, title); else snprintf(buffer, L_BUF_SIZE, "i_view32.exe \"%s\" /pos=(%d,%d)", fullpath, x, y); ignore = system(buffer); FREE(pathname); #endif /* _WIN32 */ pixDestroy(&pixt); FREE(tempname); return 0; }