Leptonica 1.82.0
Image processing and image analysis suite
regutils.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
27
68#ifdef HAVE_CONFIG_H
69#include <config_auto.h>
70#endif /* HAVE_CONFIG_H */
71
72#include <string.h>
73#include "allheaders.h"
74
75extern l_int32 NumImageFileFormatExtensions;
76extern const char *ImageFileFormatExtensions[];
77
78static char *getRootNameFromArgv0(const char *argv0);
79
80
81/*--------------------------------------------------------------------*
82 * Regression test utilities *
83 *--------------------------------------------------------------------*/
122l_ok
123regTestSetup(l_int32 argc,
124 char **argv,
125 L_REGPARAMS **prp)
126{
127char *testname, *vers;
128char errormsg[64];
129L_REGPARAMS *rp;
130
131 PROCNAME("regTestSetup");
132
133 if (argc != 1 && argc != 2) {
134 snprintf(errormsg, sizeof(errormsg),
135 "Syntax: %s [ [compare] | generate | display ]", argv[0]);
136 return ERROR_INT(errormsg, procName, 1);
137 }
138
139 if ((testname = getRootNameFromArgv0(argv[0])) == NULL)
140 return ERROR_INT("invalid root", procName, 1);
141
142 setLeptDebugOK(1); /* required for testing */
143
144 rp = (L_REGPARAMS *)LEPT_CALLOC(1, sizeof(L_REGPARAMS));
145 *prp = rp;
146 rp->testname = testname;
147 rp->index = -1; /* increment before each test */
148
149 /* Initialize to true. A failure in any test is registered
150 * as a failure of the regression test. */
151 rp->success = TRUE;
152
153 /* Make sure the lept/regout subdirectory exists */
154 lept_mkdir("lept/regout");
155
156 /* Only open a stream to a temp file for the 'compare' case */
157 if (argc == 1 || !strcmp(argv[1], "compare")) {
158 rp->mode = L_REG_COMPARE;
159 rp->tempfile = stringNew("/tmp/lept/regout/regtest_output.txt");
160 rp->fp = fopenWriteStream(rp->tempfile, "wb");
161 if (rp->fp == NULL) {
162 rp->success = FALSE;
163 return ERROR_INT("stream not opened for tempfile", procName, 1);
164 }
165 } else if (!strcmp(argv[1], "generate")) {
166 rp->mode = L_REG_GENERATE;
167 lept_mkdir("lept/golden");
168 } else if (!strcmp(argv[1], "display")) {
169 rp->mode = L_REG_DISPLAY;
170 rp->display = TRUE;
171 } else {
172 LEPT_FREE(rp);
173 snprintf(errormsg, sizeof(errormsg),
174 "Syntax: %s [ [generate] | compare | display ]", argv[0]);
175 return ERROR_INT(errormsg, procName, 1);
176 }
177
178 /* Print out test name and both the leptonica and
179 * image library versions */
180 lept_stderr("\n////////////////////////////////////////////////\n"
181 "//////////////// %s_reg ///////////////\n"
182 "////////////////////////////////////////////////\n",
183 rp->testname);
184 vers = getLeptonicaVersion();
185 lept_stderr("%s : ", vers);
186 LEPT_FREE(vers);
187 vers = getImagelibVersions();
188 lept_stderr("%s\n", vers);
189 LEPT_FREE(vers);
190
191 rp->tstart = startTimerNested();
192 return 0;
193}
194
195
208l_ok
210{
211char result[512];
212char *results_file; /* success/failure output in 'compare' mode */
213char *text, *message;
214l_int32 retval;
215size_t nbytes;
216
217 PROCNAME("regTestCleanup");
218
219 if (!rp)
220 return ERROR_INT("rp not defined", procName, 1);
221
222 lept_stderr("Time: %7.3f sec\n", stopTimerNested(rp->tstart));
223
224 /* If generating golden files or running in display mode, release rp */
225 if (!rp->fp) {
226 LEPT_FREE(rp->testname);
227 LEPT_FREE(rp->tempfile);
228 LEPT_FREE(rp);
229 return 0;
230 }
231
232 /* Compare mode: read back data from temp file */
233 fclose(rp->fp);
234 text = (char *)l_binaryRead(rp->tempfile, &nbytes);
235 LEPT_FREE(rp->tempfile);
236 if (!text) {
237 rp->success = FALSE;
238 LEPT_FREE(rp->testname);
239 LEPT_FREE(rp);
240 return ERROR_INT("text not returned", procName, 1);
241 }
242
243 /* Prepare result message */
244 if (rp->success)
245 snprintf(result, sizeof(result), "SUCCESS: %s_reg\n", rp->testname);
246 else
247 snprintf(result, sizeof(result), "FAILURE: %s_reg\n", rp->testname);
248 message = stringJoin(text, result);
249 LEPT_FREE(text);
250 results_file = stringNew("/tmp/lept/reg_results.txt");
251 fileAppendString(results_file, message);
252 retval = (rp->success) ? 0 : 1;
253 LEPT_FREE(results_file);
254 LEPT_FREE(message);
255
256 LEPT_FREE(rp->testname);
257 LEPT_FREE(rp);
258 return retval;
259}
260
261
272l_ok
274 l_float32 val1,
275 l_float32 val2,
276 l_float32 delta)
277{
278l_float32 diff;
279
280 PROCNAME("regTestCompareValues");
281
282 if (!rp)
283 return ERROR_INT("rp not defined", procName, 1);
284
285 rp->index++;
286 diff = L_ABS(val2 - val1);
287
288 /* Record on failure */
289 if (diff > delta) {
290 if (rp->fp) {
291 fprintf(rp->fp,
292 "Failure in %s_reg: value comparison for index %d\n"
293 "difference = %f but allowed delta = %f\n",
294 rp->testname, rp->index, diff, delta);
295 }
296 lept_stderr("Failure in %s_reg: value comparison for index %d\n"
297 "difference = %f but allowed delta = %f\n",
298 rp->testname, rp->index, diff, delta);
299 rp->success = FALSE;
300 }
301 return 0;
302}
303
304
316l_ok
318 l_uint8 *string1,
319 size_t bytes1,
320 l_uint8 *string2,
321 size_t bytes2)
322{
323l_int32 same;
324char buf[256];
325
326 PROCNAME("regTestCompareStrings");
327
328 if (!rp)
329 return ERROR_INT("rp not defined", procName, 1);
330
331 rp->index++;
332 l_binaryCompare(string1, bytes1, string2, bytes2, &same);
333
334 /* Output on failure */
335 if (!same) {
336 /* Write the two strings to file */
337 snprintf(buf, sizeof(buf), "/tmp/lept/regout/string1_%d_%zu",
338 rp->index, bytes1);
339 l_binaryWrite(buf, "w", string1, bytes1);
340 snprintf(buf, sizeof(buf), "/tmp/lept/regout/string2_%d_%zu",
341 rp->index, bytes2);
342 l_binaryWrite(buf, "w", string2, bytes2);
343
344 /* Report comparison failure */
345 snprintf(buf, sizeof(buf), "/tmp/lept/regout/string*_%d_*", rp->index);
346 if (rp->fp) {
347 fprintf(rp->fp,
348 "Failure in %s_reg: string comp for index %d; "
349 "written to %s\n", rp->testname, rp->index, buf);
350 }
351 lept_stderr("Failure in %s_reg: string comp for index %d; "
352 "written to %s\n", rp->testname, rp->index, buf);
353 rp->success = FALSE;
354 }
355 return 0;
356}
357
358
373l_ok
375 PIX *pix1,
376 PIX *pix2)
377{
378l_int32 same;
379
380 PROCNAME("regTestComparePix");
381
382 if (!rp)
383 return ERROR_INT("rp not defined", procName, 1);
384 if (!pix1 || !pix2) {
385 rp->success = FALSE;
386 return ERROR_INT("pix1 and pix2 not both defined", procName, 1);
387 }
388
389 rp->index++;
390 pixEqual(pix1, pix2, &same);
391
392 /* Record on failure */
393 if (!same) {
394 if (rp->fp) {
395 fprintf(rp->fp, "Failure in %s_reg: pix comparison for index %d\n",
396 rp->testname, rp->index);
397 }
398 lept_stderr("Failure in %s_reg: pix comparison for index %d\n",
399 rp->testname, rp->index);
400 rp->success = FALSE;
401 }
402 return 0;
403}
404
405
433l_ok
435 PIX *pix1,
436 PIX *pix2,
437 l_int32 mindiff,
438 l_float32 maxfract,
439 l_int32 printstats)
440{
441l_int32 w, h, factor, similar;
442
443 PROCNAME("regTestCompareSimilarPix");
444
445 if (!rp)
446 return ERROR_INT("rp not defined", procName, 1);
447 if (!pix1 || !pix2) {
448 rp->success = FALSE;
449 return ERROR_INT("pix1 and pix2 not both defined", procName, 1);
450 }
451
452 rp->index++;
453 pixGetDimensions(pix1, &w, &h, NULL);
454 factor = L_MAX(w, h) / 400;
455 factor = L_MAX(1, L_MIN(factor, 4)); /* between 1 and 4 */
456 pixTestForSimilarity(pix1, pix2, factor, mindiff, maxfract, 0.0,
457 &similar, printstats);
458
459 /* Record on failure */
460 if (!similar) {
461 if (rp->fp) {
462 fprintf(rp->fp,
463 "Failure in %s_reg: pix similarity comp for index %d\n",
464 rp->testname, rp->index);
465 }
466 lept_stderr("Failure in %s_reg: pix similarity comp for index %d\n",
467 rp->testname, rp->index);
468 rp->success = FALSE;
469 }
470 return 0;
471}
472
473
500l_ok
502 const char *localname)
503{
504char *ext;
505char namebuf[256];
506l_int32 ret, same, format;
507PIX *pix1, *pix2;
508
509 PROCNAME("regTestCheckFile");
510
511 if (!rp)
512 return ERROR_INT("rp not defined", procName, 1);
513 if (!localname) {
514 rp->success = FALSE;
515 return ERROR_INT("local name not defined", procName, 1);
516 }
517 if (rp->mode != L_REG_GENERATE && rp->mode != L_REG_COMPARE &&
518 rp->mode != L_REG_DISPLAY) {
519 rp->success = FALSE;
520 return ERROR_INT("invalid mode", procName, 1);
521 }
522 rp->index++;
523
524 /* If display mode, no generation and no testing */
525 if (rp->mode == L_REG_DISPLAY) return 0;
526
527 /* Generate the golden file name; used in 'generate' and 'compare' */
528 splitPathAtExtension(localname, NULL, &ext);
529 snprintf(namebuf, sizeof(namebuf), "/tmp/lept/golden/%s_golden.%02d%s",
530 rp->testname, rp->index, ext);
531 LEPT_FREE(ext);
532
533 /* Generate mode. No testing. */
534 if (rp->mode == L_REG_GENERATE) {
535 /* Save the file as a golden file */
536 ret = fileCopy(localname, namebuf);
537#if 0 /* Enable for details on writing of golden files */
538 if (!ret) {
539 char *local = genPathname(localname, NULL);
540 char *golden = genPathname(namebuf, NULL);
541 L_INFO("Copy: %s to %s\n", procName, local, golden);
542 LEPT_FREE(local);
543 LEPT_FREE(golden);
544 }
545#endif
546 return ret;
547 }
548
549 /* Compare mode: test and record on failure. This can be used
550 * for all image formats, as well as for all files of serialized
551 * data, such as boxa, pta, etc. In all cases except for
552 * GIF compressed images, we compare the files to see if they
553 * are identical. GIF doesn't support RGB images; to write
554 * a 32 bpp RGB image in GIF, we do a lossy quantization to
555 * 256 colors, so the cycle read-RGB/write-GIF is not idempotent.
556 * And although the read/write cycle for GIF images with bpp <= 8
557 * is idempotent in the image pixels, it is not idempotent in the
558 * actual file bytes; tests comparing file bytes before and after
559 * a GIF read/write cycle will fail. So for GIF we uncompress
560 * the two images and compare the actual pixels. PNG is both
561 * lossless and idempotent in file bytes on read/write, so it is
562 * not necessary to compare pixels. (Comparing pixels requires
563 * decompression, and thus would increase the regression test
564 * time. JPEG is lossy and not idempotent in the image pixels,
565 * so no tests are constructed that would require it. */
566 findFileFormat(localname, &format);
567 if (format == IFF_GIF) {
568 same = 0;
569 pix1 = pixRead(localname);
570 pix2 = pixRead(namebuf);
571 pixEqual(pix1, pix2, &same);
572 pixDestroy(&pix1);
573 pixDestroy(&pix2);
574 } else {
575 filesAreIdentical(localname, namebuf, &same);
576 }
577 if (!same) {
578 fprintf(rp->fp, "Failure in %s_reg, index %d: comparing %s with %s\n",
579 rp->testname, rp->index, localname, namebuf);
580 lept_stderr("Failure in %s_reg, index %d: comparing %s with %s\n",
581 rp->testname, rp->index, localname, namebuf);
582 rp->success = FALSE;
583 }
584
585 return 0;
586}
587
588
608l_ok
610 l_int32 index1,
611 l_int32 index2)
612{
613char *name1, *name2;
614char namebuf[256];
615l_int32 same;
616SARRAY *sa;
617
618 PROCNAME("regTestCompareFiles");
619
620 if (!rp)
621 return ERROR_INT("rp not defined", procName, 1);
622 if (index1 < 0 || index2 < 0) {
623 rp->success = FALSE;
624 return ERROR_INT("index1 and/or index2 is negative", procName, 1);
625 }
626 if (index1 == index2) {
627 rp->success = FALSE;
628 return ERROR_INT("index1 must differ from index2", procName, 1);
629 }
630
631 rp->index++;
632 if (rp->mode != L_REG_COMPARE) return 0;
633
634 /* Generate the golden file names */
635 snprintf(namebuf, sizeof(namebuf), "%s_golden.%02d", rp->testname, index1);
636 sa = getSortedPathnamesInDirectory("/tmp/lept/golden", namebuf, 0, 0);
637 if (sarrayGetCount(sa) != 1) {
638 sarrayDestroy(&sa);
639 rp->success = FALSE;
640 L_ERROR("golden file %s not found\n", procName, namebuf);
641 return 1;
642 }
643 name1 = sarrayGetString(sa, 0, L_COPY);
644 sarrayDestroy(&sa);
645
646 snprintf(namebuf, sizeof(namebuf), "%s_golden.%02d", rp->testname, index2);
647 sa = getSortedPathnamesInDirectory("/tmp/lept/golden", namebuf, 0, 0);
648 if (sarrayGetCount(sa) != 1) {
649 sarrayDestroy(&sa);
650 rp->success = FALSE;
651 LEPT_FREE(name1);
652 L_ERROR("golden file %s not found\n", procName, namebuf);
653 return 1;
654 }
655 name2 = sarrayGetString(sa, 0, L_COPY);
656 sarrayDestroy(&sa);
657
658 /* Test and record on failure */
659 filesAreIdentical(name1, name2, &same);
660 if (!same) {
661 fprintf(rp->fp,
662 "Failure in %s_reg, index %d: comparing %s with %s\n",
663 rp->testname, rp->index, name1, name2);
664 lept_stderr("Failure in %s_reg, index %d: comparing %s with %s\n",
665 rp->testname, rp->index, name1, name2);
666 rp->success = FALSE;
667 }
668
669 LEPT_FREE(name1);
670 LEPT_FREE(name2);
671 return 0;
672}
673
674
701l_ok
703 PIX *pix,
704 l_int32 format)
705{
706char namebuf[256];
707
708 PROCNAME("regTestWritePixAndCheck");
709
710 if (!rp)
711 return ERROR_INT("rp not defined", procName, 1);
712 if (!pix) {
713 rp->success = FALSE;
714 return ERROR_INT("pix not defined", procName, 1);
715 }
716 if (format < 0 || format >= NumImageFileFormatExtensions) {
717 rp->success = FALSE;
718 return ERROR_INT("invalid format", procName, 1);
719 }
720
721 /* Use bmp format for testing if library for requested
722 * format for jpeg, png or tiff is not available */
723 changeFormatForMissingLib(&format);
724
725 /* Generate the local file name */
726 snprintf(namebuf, sizeof(namebuf), "/tmp/lept/regout/%s.%02d.%s",
727 rp->testname, rp->index + 1, ImageFileFormatExtensions[format]);
728
729 /* Write the local file */
730 if (pixGetDepth(pix) < 8)
731 pixSetPadBits(pix, 0);
732 pixWrite(namebuf, pix, format);
733
734 /* Either write the golden file ("generate") or check the
735 local file against an existing golden file ("compare") */
736 regTestCheckFile(rp, namebuf);
737
738 return 0;
739}
740
741
772l_ok
774 void *data,
775 size_t nbytes,
776 const char *ext)
777{
778char namebuf[256];
779
780 PROCNAME("regTestWriteDataAndCheck");
781
782 if (!rp)
783 return ERROR_INT("rp not defined", procName, 1);
784 if (!data || nbytes == 0) {
785 rp->success = FALSE;
786 return ERROR_INT("data not defined or size == 0", procName, 1);
787 }
788
789 /* Generate the local file name */
790 snprintf(namebuf, sizeof(namebuf), "/tmp/lept/regout/%s.%02d.%s",
791 rp->testname, rp->index + 1, ext);
792
793 /* Write the local file */
794 l_binaryWrite(namebuf, "w", data, nbytes);
795
796 /* Either write the golden file ("generate") or check the
797 local file against an existing golden file ("compare") */
798 regTestCheckFile(rp, namebuf);
799 return 0;
800}
801
802
823char *
825 l_int32 index,
826 l_int32 format)
827{
828char buf[64];
829l_int32 ind;
830
831 PROCNAME("regTestGenLocalFilename");
832
833 if (!rp)
834 return (char *)ERROR_PTR("rp not defined", procName, NULL);
835
836 ind = (index >= 0) ? index : rp->index;
837 snprintf(buf, sizeof(buf), "/tmp/lept/regout/%s.%02d.%s",
838 rp->testname, ind, ImageFileFormatExtensions[format]);
839 return stringNew(buf);
840}
841
842
859static char *
860getRootNameFromArgv0(const char *argv0)
861{
862l_int32 len;
863char *root;
864
865 PROCNAME("getRootNameFromArgv0");
866
867 splitPathAtDirectory(argv0, NULL, &root);
868 if ((len = strlen(root)) <= 4) {
869 LEPT_FREE(root);
870 return (char *)ERROR_PTR("invalid argv0; too small", procName, NULL);
871 }
872
873#ifndef _WIN32
874 {
875 char *newroot;
876 l_int32 loc;
877 if (stringFindSubstr(root, "-", &loc)) {
878 newroot = stringNew(root + loc + 1); /* strip out "lt-" */
879 LEPT_FREE(root);
880 root = newroot;
881 len = strlen(root);
882 }
883 len -= 4; /* remove the "_reg" suffix */
884 }
885#else
886 if (strstr(root, ".exe") != NULL)
887 len -= 4;
888 if (strstr(root, "_reg") == root + len - 4)
889 len -= 4;
890#endif /* ! _WIN32 */
891
892 root[len] = '\0'; /* terminate */
893 return root;
894}
l_ok pixEqual(PIX *pix1, PIX *pix2, l_int32 *psame)
pixEqual()
Definition: compare.c:156
l_ok pixTestForSimilarity(PIX *pix1, PIX *pix2, l_int32 factor, l_int32 mindiff, l_float32 maxfract, l_float32 maxave, l_int32 *psimilar, l_int32 details)
pixTestForSimilarity()
Definition: compare.c:1326
char * getImagelibVersions(void)
getImagelibVersions()
Definition: libversions.c:102
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1382
@ L_COPY
Definition: pix.h:712
PIX * pixRead(const char *filename)
pixRead()
Definition: readfile.c:193
l_ok findFileFormat(const char *filename, l_int32 *pformat)
findFileFormat()
Definition: readfile.c:584
l_ok regTestSetup(l_int32 argc, char **argv, L_REGPARAMS **prp)
regTestSetup()
Definition: regutils.c:123
l_ok regTestCompareSimilarPix(L_REGPARAMS *rp, PIX *pix1, PIX *pix2, l_int32 mindiff, l_float32 maxfract, l_int32 printstats)
regTestCompareSimilarPix()
Definition: regutils.c:434
l_ok regTestCompareFiles(L_REGPARAMS *rp, l_int32 index1, l_int32 index2)
regTestCompareFiles()
Definition: regutils.c:609
l_ok regTestCompareStrings(L_REGPARAMS *rp, l_uint8 *string1, size_t bytes1, l_uint8 *string2, size_t bytes2)
regTestCompareStrings()
Definition: regutils.c:317
l_ok regTestWritePixAndCheck(L_REGPARAMS *rp, PIX *pix, l_int32 format)
regTestWritePixAndCheck()
Definition: regutils.c:702
static char * getRootNameFromArgv0(const char *argv0)
getRootNameFromArgv0()
Definition: regutils.c:860
l_ok regTestCheckFile(L_REGPARAMS *rp, const char *localname)
regTestCheckFile()
Definition: regutils.c:501
l_ok regTestComparePix(L_REGPARAMS *rp, PIX *pix1, PIX *pix2)
regTestComparePix()
Definition: regutils.c:374
l_ok regTestCompareValues(L_REGPARAMS *rp, l_float32 val1, l_float32 val2, l_float32 delta)
regTestCompareValues()
Definition: regutils.c:273
l_ok regTestCleanup(L_REGPARAMS *rp)
regTestCleanup()
Definition: regutils.c:209
l_ok regTestWriteDataAndCheck(L_REGPARAMS *rp, void *data, size_t nbytes, const char *ext)
regTestWriteDataAndCheck()
Definition: regutils.c:773
char * regTestGenLocalFilename(L_REGPARAMS *rp, l_int32 index, l_int32 format)
regTestGenLocalFilename()
Definition: regutils.c:824
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
char * testname
Definition: regutils.h:120
l_int32 success
Definition: regutils.h:124
char * tempfile
Definition: regutils.h:121
l_int32 display
Definition: regutils.h:125
l_int32 index
Definition: regutils.h:123
l_int32 mode
Definition: regutils.h:122
L_TIMER tstart
Definition: regutils.h:126
FILE * fp
Definition: regutils.h:119
Definition: pix.h:139
Definition: array.h:127
l_ok filesAreIdentical(const char *fname1, const char *fname2, l_int32 *psame)
filesAreIdentical()
Definition: utils1.c:333
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
char * getLeptonicaVersion(void)
getLeptonicaVersion()
Definition: utils1.c:982
L_TIMER startTimerNested(void)
startTimerNested(), stopTimerNested()
Definition: utils1.c:1073
l_ok fileAppendString(const char *filename, const char *str)
fileAppendString()
Definition: utils2.c:1805
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
l_ok splitPathAtExtension(const char *pathname, char **pbasename, char **pextension)
splitPathAtExtension()
Definition: utils2.c:2894
char * genPathname(const char *dir, const char *fname)
genPathname()
Definition: utils2.c:3173
l_ok l_binaryCompare(const l_uint8 *data1, size_t size1, const l_uint8 *data2, size_t size2, l_int32 *psame)
l_binaryCompare()
Definition: utils2.c:1711
l_ok splitPathAtDirectory(const char *pathname, char **pdir, char **ptail)
splitPathAtDirectory()
Definition: utils2.c:2824
l_uint8 * l_binaryRead(const char *filename, size_t *pnbytes)
l_binaryRead()
Definition: utils2.c:1352
l_int32 stringFindSubstr(const char *src, const char *sub, l_int32 *ploc)
stringFindSubstr()
Definition: utils2.c:1027
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:518
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218
l_ok l_binaryWrite(const char *filename, const char *operation, const void *data, size_t nbytes)
l_binaryWrite()
Definition: utils2.c:1569
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:223
l_ok fileCopy(const char *srcfile, const char *newfile)
fileCopy()
Definition: utils2.c:1747