Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
dewarp1.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
412#ifdef HAVE_CONFIG_H
413#include <config_auto.h>
414#endif /* HAVE_CONFIG_H */
415
416#include <math.h>
417#include "allheaders.h"
418
419static l_int32 dewarpaExtendArraysToSize(L_DEWARPA *dewa, l_int32 size);
420
421 /* Parameter values used in dewarpaCreate() */
422static const l_int32 InitialPtrArraySize = 20; /* n'import quoi */
423static const l_int32 MaxPtrArraySize = 10000;
424static const l_int32 DefaultArraySampling = 30;
425static const l_int32 MinArraySampling = 8;
426static const l_int32 DefaultMinLines = 15;
427static const l_int32 MinMinLines = 4;
428static const l_int32 DefaultMaxRefDist = 16;
429static const l_int32 DefaultUseBoth = TRUE;
430static const l_int32 DefaultCheckColumns = TRUE;
431
432 /* Parameter values used in dewarpaSetCurvatures() */
433static const l_int32 DefaultMaxLineCurv = 150;
434static const l_int32 DefaultMinDiffLineCurv = 0;
435static const l_int32 DefaultMaxDiffLineCurv = 170;
436static const l_int32 DefaultMaxEdgeCurv = 50;
437static const l_int32 DefaultMaxDiffEdgeCurv = 40;
438static const l_int32 DefaultMaxEdgeSlope = 80;
439
440/*----------------------------------------------------------------------*
441 * Create/destroy Dewarp *
442 *----------------------------------------------------------------------*/
458L_DEWARP *
460 l_int32 pageno)
461{
462L_DEWARP *dew;
463
464 if (!pixs)
465 return (L_DEWARP *)ERROR_PTR("pixs not defined", __func__, NULL);
466 if (pixGetDepth(pixs) != 1)
467 return (L_DEWARP *)ERROR_PTR("pixs not 1 bpp", __func__, NULL);
468
469 dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
470 dew->pixs = pixClone(pixs);
471 dew->pageno = pageno;
472 dew->w = pixGetWidth(pixs);
473 dew->h = pixGetHeight(pixs);
474 return dew;
475}
476
477
495L_DEWARP *
496dewarpCreateRef(l_int32 pageno,
497 l_int32 refpage)
498{
499L_DEWARP *dew;
500
501 dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
502 dew->pageno = pageno;
503 dew->hasref = 1;
504 dew->refpage = refpage;
505 return dew;
506}
507
508
515void
517{
518L_DEWARP *dew;
519
520 if (pdew == NULL) {
521 L_WARNING("ptr address is null!\n", __func__);
522 return;
523 }
524 if ((dew = *pdew) == NULL)
525 return;
526
527 pixDestroy(&dew->pixs);
528 fpixDestroy(&dew->sampvdispar);
529 fpixDestroy(&dew->samphdispar);
530 fpixDestroy(&dew->sampydispar);
531 fpixDestroy(&dew->fullvdispar);
532 fpixDestroy(&dew->fullhdispar);
533 fpixDestroy(&dew->fullydispar);
534 numaDestroy(&dew->namidys);
535 numaDestroy(&dew->nacurves);
536 LEPT_FREE(dew);
537 *pdew = NULL;
538}
539
540
541/*----------------------------------------------------------------------*
542 * Create/destroy Dewarpa *
543 *----------------------------------------------------------------------*/
575L_DEWARPA *
576dewarpaCreate(l_int32 nptrs,
577 l_int32 sampling,
578 l_int32 redfactor,
579 l_int32 minlines,
580 l_int32 maxdist)
581{
582L_DEWARPA *dewa;
583
584 if (nptrs <= 0)
585 nptrs = InitialPtrArraySize;
586 if (nptrs > MaxPtrArraySize)
587 return (L_DEWARPA *)ERROR_PTR("too many pages", __func__, NULL);
588 if (redfactor != 1 && redfactor != 2)
589 return (L_DEWARPA *)ERROR_PTR("redfactor not in {1,2}",
590 __func__, NULL);
591 if (sampling == 0) {
592 sampling = DefaultArraySampling;
593 } else if (sampling < MinArraySampling) {
594 L_WARNING("sampling too small; setting to %d\n", __func__,
595 MinArraySampling);
596 sampling = MinArraySampling;
597 }
598 if (minlines == 0) {
599 minlines = DefaultMinLines;
600 } else if (minlines < MinMinLines) {
601 L_WARNING("minlines too small; setting to %d\n", __func__,
602 MinMinLines);
603 minlines = DefaultMinLines;
604 }
605 if (maxdist < 0)
606 maxdist = DefaultMaxRefDist;
607
608 dewa = (L_DEWARPA *)LEPT_CALLOC(1, sizeof(L_DEWARPA));
609 dewa->dewarp = (L_DEWARP **)LEPT_CALLOC(nptrs, sizeof(L_DEWARPA *));
610 dewa->dewarpcache = (L_DEWARP **)LEPT_CALLOC(nptrs, sizeof(L_DEWARPA *));
611 if (!dewa->dewarp || !dewa->dewarpcache) {
612 dewarpaDestroy(&dewa);
613 return (L_DEWARPA *)ERROR_PTR("dewarp ptrs not made", __func__, NULL);
614 }
615 dewa->nalloc = nptrs;
616 dewa->sampling = sampling;
617 dewa->redfactor = redfactor;
618 dewa->minlines = minlines;
619 dewa->maxdist = maxdist;
620 dewa->max_linecurv = DefaultMaxLineCurv;
621 dewa->min_diff_linecurv = DefaultMinDiffLineCurv;
622 dewa->max_diff_linecurv = DefaultMaxDiffLineCurv;
623 dewa->max_edgeslope = DefaultMaxEdgeSlope;
624 dewa->max_edgecurv = DefaultMaxEdgeCurv;
625 dewa->max_diff_edgecurv = DefaultMaxDiffEdgeCurv;
626 dewa->check_columns = DefaultCheckColumns;
627 dewa->useboth = DefaultUseBoth;
628 return dewa;
629}
630
631
662L_DEWARPA *
664 l_int32 useboth,
665 l_int32 sampling,
666 l_int32 minlines,
667 l_int32 maxdist)
668{
669l_int32 i, nptrs, pageno;
670L_DEWARP *dew;
671L_DEWARPA *dewa;
672PIX *pixt;
673
674 if (!pixac)
675 return (L_DEWARPA *)ERROR_PTR("pixac not defined", __func__, NULL);
676
677 nptrs = pixacompGetCount(pixac);
678 if ((dewa = dewarpaCreate(pixacompGetOffset(pixac) + nptrs,
679 sampling, 1, minlines, maxdist)) == NULL)
680 return (L_DEWARPA *)ERROR_PTR("dewa not made", __func__, NULL);
681 dewarpaUseBothArrays(dewa, useboth);
682
683 for (i = 0; i < nptrs; i++) {
684 pageno = pixacompGetOffset(pixac) + i; /* index into pixacomp */
685 pixt = pixacompGetPix(pixac, pageno);
686 if (pixt && (pixGetWidth(pixt) > 1)) {
687 dew = dewarpCreate(pixt, pageno);
688 pixDestroy(&pixt);
689 if (!dew) {
690 ERROR_INT("unable to make dew!", __func__, 1);
691 continue;
692 }
693
694 /* Insert into dewa for this page */
695 dewarpaInsertDewarp(dewa, dew);
696
697 /* Build disparity arrays for this page */
698 dewarpBuildPageModel(dew, NULL);
699 if (!dew->vsuccess) { /* will need to use model from nearby page */
700 dewarpaDestroyDewarp(dewa, pageno);
701 L_ERROR("unable to build model for page %d\n", __func__, i);
702 continue;
703 }
704 /* Remove all extraneous data */
705 dewarpMinimize(dew);
706 }
707 pixDestroy(&pixt);
708 }
709 dewarpaInsertRefModels(dewa, 0, 0);
710
711 return dewa;
712}
713
714
721void
723{
724l_int32 i;
725L_DEWARP *dew;
726L_DEWARPA *dewa;
727
728 if (pdewa == NULL) {
729 L_WARNING("ptr address is null!\n", __func__);
730 return;
731 }
732 if ((dewa = *pdewa) == NULL)
733 return;
734
735 for (i = 0; i < dewa->nalloc; i++) {
736 if ((dew = dewa->dewarp[i]) != NULL)
737 dewarpDestroy(&dew);
738 if ((dew = dewa->dewarpcache[i]) != NULL)
739 dewarpDestroy(&dew);
740 }
741 numaDestroy(&dewa->namodels);
742 numaDestroy(&dewa->napages);
743
744 LEPT_FREE(dewa->dewarp);
745 LEPT_FREE(dewa->dewarpcache);
746 LEPT_FREE(dewa);
747 *pdewa = NULL;
748}
749
750
758l_ok
760 l_int32 pageno)
761{
762L_DEWARP *dew;
763
764 if (!dewa)
765 return ERROR_INT("dewa or dew not defined", __func__, 1);
766 if (pageno < 0 || pageno > dewa->maxpage)
767 return ERROR_INT("page out of bounds", __func__, 1);
768 if ((dew = dewa->dewarp[pageno]) == NULL)
769 return ERROR_INT("dew not defined", __func__, 1);
770
771 dewarpDestroy(&dew);
772 dewa->dewarp[pageno] = NULL;
773 return 0;
774}
775
776
777/*----------------------------------------------------------------------*
778 * Dewarpa insertion/extraction *
779 *----------------------------------------------------------------------*/
799l_ok
801 L_DEWARP *dew)
802{
803l_int32 pageno, n, newsize;
804L_DEWARP *prevdew;
805
806 if (!dewa)
807 return ERROR_INT("dewa not defined", __func__, 1);
808 if (!dew)
809 return ERROR_INT("dew not defined", __func__, 1);
810
811 dew->dewa = dewa;
812 pageno = dew->pageno;
813 if (pageno > MaxPtrArraySize)
814 return ERROR_INT("too many pages", __func__, 1);
815 if (pageno > dewa->maxpage)
816 dewa->maxpage = pageno;
817 dewa->modelsready = 0; /* force re-evaluation at application time */
818
819 /* Extend ptr array if necessary */
820 n = dewa->nalloc;
821 newsize = n;
822 if (pageno >= 2 * n)
823 newsize = 2 * pageno;
824 else if (pageno >= n)
825 newsize = 2 * n;
826 if (newsize > n) {
827 if (dewarpaExtendArraysToSize(dewa, newsize))
828 return ERROR_INT("extension failed", __func__, 1);
829 }
830
831 if ((prevdew = dewarpaGetDewarp(dewa, pageno)) != NULL)
832 dewarpDestroy(&prevdew);
833 dewa->dewarp[pageno] = dew;
834
835 dew->sampling = dewa->sampling;
836 dew->redfactor = dewa->redfactor;
837 dew->minlines = dewa->minlines;
838
839 /* Get the dimensions of the sampled array. This will be
840 * stored in an fpix, and the input resolution version is
841 * guaranteed to be larger than pixs. However, if you
842 * want to apply the disparity to an image with a width
843 * w > nx * s - 2 * s + 2
844 * you will need to extend the input res fpix.
845 * And similarly for h. */
846 dew->nx = (dew->w + 2 * dew->sampling - 2) / dew->sampling;
847 dew->ny = (dew->h + 2 * dew->sampling - 2) / dew->sampling;
848 return 0;
849}
850
851
864static l_int32
866 l_int32 size)
867{
868 if (!dewa)
869 return ERROR_INT("dewa not defined", __func__, 1);
870
871 if (size > dewa->nalloc) {
872 if ((dewa->dewarp = (L_DEWARP **)reallocNew((void **)&dewa->dewarp,
873 sizeof(L_DEWARP *) * dewa->nalloc,
874 size * sizeof(L_DEWARP *))) == NULL)
875 return ERROR_INT("new ptr array not returned", __func__, 1);
876 if ((dewa->dewarpcache =
877 (L_DEWARP **)reallocNew((void **)&dewa->dewarpcache,
878 sizeof(L_DEWARP *) * dewa->nalloc,
879 size * sizeof(L_DEWARP *))) == NULL)
880 return ERROR_INT("new ptr cache array not returned", __func__, 1);
881 dewa->nalloc = size;
882 }
883 return 0;
884}
885
886
894L_DEWARP *
896 l_int32 index)
897{
898 if (!dewa)
899 return (L_DEWARP *)ERROR_PTR("dewa not defined", __func__, NULL);
900 if (index < 0 || index > dewa->maxpage) {
901 L_ERROR("index = %d is invalid; max index = %d\n",
902 __func__, index, dewa->maxpage);
903 return NULL;
904 }
905
906 return dewa->dewarp[index];
907}
908
909
910/*----------------------------------------------------------------------*
911 * Setting parameters to control rendering from the model *
912 *----------------------------------------------------------------------*/
961l_ok
963 l_int32 max_linecurv,
964 l_int32 min_diff_linecurv,
965 l_int32 max_diff_linecurv,
966 l_int32 max_edgecurv,
967 l_int32 max_diff_edgecurv,
968 l_int32 max_edgeslope)
969{
970 if (!dewa)
971 return ERROR_INT("dewa not defined", __func__, 1);
972
973 if (max_linecurv == -1)
974 dewa->max_linecurv = DefaultMaxLineCurv;
975 else
976 dewa->max_linecurv = L_ABS(max_linecurv);
977
978 if (min_diff_linecurv == -1)
979 dewa->min_diff_linecurv = DefaultMinDiffLineCurv;
980 else
981 dewa->min_diff_linecurv = L_ABS(min_diff_linecurv);
982
983 if (max_diff_linecurv == -1)
984 dewa->max_diff_linecurv = DefaultMaxDiffLineCurv;
985 else
986 dewa->max_diff_linecurv = L_ABS(max_diff_linecurv);
987
988 if (max_edgecurv == -1)
989 dewa->max_edgecurv = DefaultMaxEdgeCurv;
990 else
991 dewa->max_edgecurv = L_ABS(max_edgecurv);
992
993 if (max_diff_edgecurv == -1)
994 dewa->max_diff_edgecurv = DefaultMaxDiffEdgeCurv;
995 else
996 dewa->max_diff_edgecurv = L_ABS(max_diff_edgecurv);
997
998 if (max_edgeslope == -1)
999 dewa->max_edgeslope = DefaultMaxEdgeSlope;
1000 else
1001 dewa->max_edgeslope = L_ABS(max_edgeslope);
1002
1003 dewa->modelsready = 0; /* force validation */
1004 return 0;
1005}
1006
1007
1023l_ok
1025 l_int32 useboth)
1026{
1027 if (!dewa)
1028 return ERROR_INT("dewa not defined", __func__, 1);
1029
1030 dewa->useboth = useboth;
1031 dewa->modelsready = 0; /* force validation */
1032 return 0;
1033}
1034
1035
1060l_ok
1062 l_int32 check_columns)
1063{
1064 if (!dewa)
1065 return ERROR_INT("dewa not defined", __func__, 1);
1066
1067 dewa->check_columns = check_columns;
1068 return 0;
1069}
1070
1071
1084l_ok
1086 l_int32 maxdist)
1087{
1088 if (!dewa)
1089 return ERROR_INT("dewa not defined", __func__, 1);
1090
1091 dewa->maxdist = maxdist;
1092 dewa->modelsready = 0; /* force validation */
1093 return 0;
1094}
1095
1096
1097/*----------------------------------------------------------------------*
1098 * Dewarp serialized I/O *
1099 *----------------------------------------------------------------------*/
1106L_DEWARP *
1107dewarpRead(const char *filename)
1108{
1109FILE *fp;
1110L_DEWARP *dew;
1111
1112 if (!filename)
1113 return (L_DEWARP *)ERROR_PTR("filename not defined", __func__, NULL);
1114 if ((fp = fopenReadStream(filename)) == NULL)
1115 return (L_DEWARP *)ERROR_PTR_1("stream not opened",
1116 filename, __func__, NULL);
1117
1118 if ((dew = dewarpReadStream(fp)) == NULL) {
1119 fclose(fp);
1120 return (L_DEWARP *)ERROR_PTR_1("dew not read",
1121 filename, __func__, NULL);
1122 }
1123
1124 fclose(fp);
1125 return dew;
1126}
1127
1128
1146L_DEWARP *
1148{
1149l_int32 version, sampling, redfactor, minlines, pageno, hasref, refpage;
1150l_int32 w, h, nx, ny, vdispar, hdispar, nlines;
1151l_int32 mincurv, maxcurv, leftslope, rightslope, leftcurv, rightcurv;
1152L_DEWARP *dew;
1153FPIX *fpixv = NULL, *fpixh = NULL;
1154
1155 if (!fp)
1156 return (L_DEWARP *)ERROR_PTR("stream not defined", __func__, NULL);
1157
1158 if (fscanf(fp, "\nDewarp Version %d\n", &version) != 1)
1159 return (L_DEWARP *)ERROR_PTR("not a dewarp file", __func__, NULL);
1160 if (version != DEWARP_VERSION_NUMBER)
1161 return (L_DEWARP *)ERROR_PTR("invalid dewarp version", __func__, NULL);
1162 if (fscanf(fp, "pageno = %d\n", &pageno) != 1)
1163 return (L_DEWARP *)ERROR_PTR("read fail for pageno", __func__, NULL);
1164 if (fscanf(fp, "hasref = %d, refpage = %d\n", &hasref, &refpage) != 2)
1165 return (L_DEWARP *)ERROR_PTR("read fail for hasref, refpage",
1166 __func__, NULL);
1167 if (fscanf(fp, "sampling = %d, redfactor = %d\n", &sampling, &redfactor)
1168 != 2)
1169 return (L_DEWARP *)ERROR_PTR("read fail for sampling/redfactor",
1170 __func__, NULL);
1171 if (fscanf(fp, "nlines = %d, minlines = %d\n", &nlines, &minlines) != 2)
1172 return (L_DEWARP *)ERROR_PTR("read fail for nlines/minlines",
1173 __func__, NULL);
1174 if (fscanf(fp, "w = %d, h = %d\n", &w, &h) != 2)
1175 return (L_DEWARP *)ERROR_PTR("read fail for w, h", __func__, NULL);
1176 if (fscanf(fp, "nx = %d, ny = %d\n", &nx, &ny) != 2)
1177 return (L_DEWARP *)ERROR_PTR("read fail for nx, ny", __func__, NULL);
1178 if (fscanf(fp, "vert_dispar = %d, horiz_dispar = %d\n", &vdispar, &hdispar)
1179 != 2)
1180 return (L_DEWARP *)ERROR_PTR("read fail for flags", __func__, NULL);
1181 if (vdispar) {
1182 if (fscanf(fp, "min line curvature = %d, max line curvature = %d\n",
1183 &mincurv, &maxcurv) != 2)
1184 return (L_DEWARP *)ERROR_PTR("read fail for mincurv & maxcurv",
1185 __func__, NULL);
1186 }
1187 if (hdispar) {
1188 if (fscanf(fp, "left edge slope = %d, right edge slope = %d\n",
1189 &leftslope, &rightslope) != 2)
1190 return (L_DEWARP *)ERROR_PTR("read fail for leftslope & rightslope",
1191 __func__, NULL);
1192 if (fscanf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1193 &leftcurv, &rightcurv) != 2)
1194 return (L_DEWARP *)ERROR_PTR("read fail for leftcurv & rightcurv",
1195 __func__, NULL);
1196 }
1197 if (vdispar) {
1198 if ((fpixv = fpixReadStream(fp)) == NULL)
1199 return (L_DEWARP *)ERROR_PTR("read fail for vdispar",
1200 __func__, NULL);
1201 }
1202 if (hdispar) {
1203 if ((fpixh = fpixReadStream(fp)) == NULL)
1204 return (L_DEWARP *)ERROR_PTR("read fail for hdispar",
1205 __func__, NULL);
1206 }
1207 getc(fp);
1208
1209 dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
1210 dew->w = w;
1211 dew->h = h;
1212 dew->pageno = pageno;
1213 dew->sampling = sampling;
1214 dew->redfactor = redfactor;
1215 dew->minlines = minlines;
1216 dew->nlines = nlines;
1217 dew->hasref = hasref;
1218 dew->refpage = refpage;
1219 if (hasref == 0) /* any dew without a ref has an actual model */
1220 dew->vsuccess = 1;
1221 dew->nx = nx;
1222 dew->ny = ny;
1223 if (vdispar) {
1224 dew->mincurv = mincurv;
1225 dew->maxcurv = maxcurv;
1226 dew->vsuccess = 1;
1227 dew->sampvdispar = fpixv;
1228 }
1229 if (hdispar) {
1230 dew->leftslope = leftslope;
1231 dew->rightslope = rightslope;
1232 dew->leftcurv = leftcurv;
1233 dew->rightcurv = rightcurv;
1234 dew->hsuccess = 1;
1235 dew->samphdispar = fpixh;
1236 }
1237
1238 return dew;
1239}
1240
1241
1249L_DEWARP *
1250dewarpReadMem(const l_uint8 *data,
1251 size_t size)
1252{
1253FILE *fp;
1254L_DEWARP *dew;
1255
1256 if (!data)
1257 return (L_DEWARP *)ERROR_PTR("data not defined", __func__, NULL);
1258 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1259 return (L_DEWARP *)ERROR_PTR("stream not opened", __func__, NULL);
1260
1261 dew = dewarpReadStream(fp);
1262 fclose(fp);
1263 if (!dew) L_ERROR("dew not read\n", __func__);
1264 return dew;
1265}
1266
1267
1275l_ok
1276dewarpWrite(const char *filename,
1277 L_DEWARP *dew)
1278{
1279l_int32 ret;
1280FILE *fp;
1281
1282 if (!filename)
1283 return ERROR_INT("filename not defined", __func__, 1);
1284 if (!dew)
1285 return ERROR_INT("dew not defined", __func__, 1);
1286
1287 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1288 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1289 ret = dewarpWriteStream(fp, dew);
1290 fclose(fp);
1291 if (ret)
1292 return ERROR_INT_1("dew not written to stream", filename, __func__, 1);
1293 return 0;
1294}
1295
1296
1311l_ok
1313 L_DEWARP *dew)
1314{
1315l_int32 vdispar, hdispar;
1316
1317 if (!fp)
1318 return ERROR_INT("stream not defined", __func__, 1);
1319 if (!dew)
1320 return ERROR_INT("dew not defined", __func__, 1);
1321
1322 fprintf(fp, "\nDewarp Version %d\n", DEWARP_VERSION_NUMBER);
1323 fprintf(fp, "pageno = %d\n", dew->pageno);
1324 fprintf(fp, "hasref = %d, refpage = %d\n", dew->hasref, dew->refpage);
1325 fprintf(fp, "sampling = %d, redfactor = %d\n",
1326 dew->sampling, dew->redfactor);
1327 fprintf(fp, "nlines = %d, minlines = %d\n", dew->nlines, dew->minlines);
1328 fprintf(fp, "w = %d, h = %d\n", dew->w, dew->h);
1329 fprintf(fp, "nx = %d, ny = %d\n", dew->nx, dew->ny);
1330 vdispar = (dew->sampvdispar) ? 1 : 0;
1331 hdispar = (dew->samphdispar) ? 1 : 0;
1332 fprintf(fp, "vert_dispar = %d, horiz_dispar = %d\n", vdispar, hdispar);
1333 if (vdispar)
1334 fprintf(fp, "min line curvature = %d, max line curvature = %d\n",
1335 dew->mincurv, dew->maxcurv);
1336 if (hdispar) {
1337 fprintf(fp, "left edge slope = %d, right edge slope = %d\n",
1338 dew->leftslope, dew->rightslope);
1339 fprintf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1340 dew->leftcurv, dew->rightcurv);
1341 }
1342 if (vdispar) fpixWriteStream(fp, dew->sampvdispar);
1343 if (hdispar) fpixWriteStream(fp, dew->samphdispar);
1344 fprintf(fp, "\n");
1345
1346 if (!vdispar)
1347 L_WARNING("no disparity arrays!\n", __func__);
1348 return 0;
1349}
1350
1351
1365l_ok
1366dewarpWriteMem(l_uint8 **pdata,
1367 size_t *psize,
1368 L_DEWARP *dew)
1369{
1370l_int32 ret;
1371FILE *fp;
1372
1373 if (pdata) *pdata = NULL;
1374 if (psize) *psize = 0;
1375 if (!pdata)
1376 return ERROR_INT("&data not defined", __func__, 1);
1377 if (!psize)
1378 return ERROR_INT("&size not defined", __func__, 1);
1379 if (!dew)
1380 return ERROR_INT("dew not defined", __func__, 1);
1381
1382#if HAVE_FMEMOPEN
1383 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1384 return ERROR_INT("stream not opened", __func__, 1);
1385 ret = dewarpWriteStream(fp, dew);
1386 fputc('\0', fp);
1387 fclose(fp);
1388 if (*psize > 0) *psize = *psize - 1;
1389#else
1390 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1391 #ifdef _WIN32
1392 if ((fp = fopenWriteWinTempfile()) == NULL)
1393 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1394 #else
1395 if ((fp = tmpfile()) == NULL)
1396 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1397 #endif /* _WIN32 */
1398 ret = dewarpWriteStream(fp, dew);
1399 rewind(fp);
1400 *pdata = l_binaryReadStream(fp, psize);
1401 fclose(fp);
1402#endif /* HAVE_FMEMOPEN */
1403 return ret;
1404}
1405
1406
1407/*----------------------------------------------------------------------*
1408 * Dewarpa serialized I/O *
1409 *----------------------------------------------------------------------*/
1416L_DEWARPA *
1417dewarpaRead(const char *filename)
1418{
1419FILE *fp;
1420L_DEWARPA *dewa;
1421
1422 if (!filename)
1423 return (L_DEWARPA *)ERROR_PTR("filename not defined", __func__, NULL);
1424 if ((fp = fopenReadStream(filename)) == NULL)
1425 return (L_DEWARPA *)ERROR_PTR_1("stream not opened",
1426 filename, __func__, NULL);
1427
1428 if ((dewa = dewarpaReadStream(fp)) == NULL) {
1429 fclose(fp);
1430 return (L_DEWARPA *)ERROR_PTR_1("dewa not read",
1431 filename, __func__, NULL);
1432 }
1433
1434 fclose(fp);
1435 return dewa;
1436}
1437
1438
1453L_DEWARPA *
1455{
1456l_int32 i, version, ndewarp, maxpage;
1457l_int32 sampling, redfactor, minlines, maxdist, useboth;
1458l_int32 max_linecurv, min_diff_linecurv, max_diff_linecurv;
1459l_int32 max_edgeslope, max_edgecurv, max_diff_edgecurv;
1460L_DEWARP *dew;
1461L_DEWARPA *dewa;
1462NUMA *namodels;
1463
1464 if (!fp)
1465 return (L_DEWARPA *)ERROR_PTR("stream not defined", __func__, NULL);
1466
1467 if (fscanf(fp, "\nDewarpa Version %d\n", &version) != 1)
1468 return (L_DEWARPA *)ERROR_PTR("not a dewarpa file", __func__, NULL);
1469 if (version != DEWARP_VERSION_NUMBER)
1470 return (L_DEWARPA *)ERROR_PTR("invalid dewarp version", __func__, NULL);
1471
1472 if (fscanf(fp, "ndewarp = %d, maxpage = %d\n", &ndewarp, &maxpage) != 2)
1473 return (L_DEWARPA *)ERROR_PTR("read fail for maxpage+", __func__, NULL);
1474 if (ndewarp < 1)
1475 return (L_DEWARPA *)ERROR_PTR("pages not >= 1", __func__, NULL);
1476 if (ndewarp > MaxPtrArraySize)
1477 return (L_DEWARPA *)ERROR_PTR("too many pages", __func__, NULL);
1478 if (fscanf(fp,
1479 "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1480 &sampling, &redfactor, &minlines, &maxdist) != 4)
1481 return (L_DEWARPA *)ERROR_PTR("read fail for 4 params", __func__, NULL);
1482 if (fscanf(fp,
1483 "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1484 &max_linecurv, &min_diff_linecurv, &max_diff_linecurv) != 3)
1485 return (L_DEWARPA *)ERROR_PTR("read fail for linecurv", __func__, NULL);
1486 if (fscanf(fp,
1487 "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1488 &max_edgeslope, &max_edgecurv, &max_diff_edgecurv) != 3)
1489 return (L_DEWARPA *)ERROR_PTR("read fail for edgecurv", __func__, NULL);
1490 if (fscanf(fp, "fullmodel = %d\n", &useboth) != 1)
1491 return (L_DEWARPA *)ERROR_PTR("read fail for useboth", __func__, NULL);
1492
1493 dewa = dewarpaCreate(maxpage + 1, sampling, redfactor, minlines, maxdist);
1494 dewa->maxpage = maxpage;
1495 dewa->max_linecurv = max_linecurv;
1496 dewa->min_diff_linecurv = min_diff_linecurv;
1497 dewa->max_diff_linecurv = max_diff_linecurv;
1498 dewa->max_edgeslope = max_edgeslope;
1499 dewa->max_edgecurv = max_edgecurv;
1500 dewa->max_diff_edgecurv = max_diff_edgecurv;
1501 dewa->useboth = useboth;
1502 namodels = numaCreate(ndewarp);
1503 dewa->namodels = namodels;
1504 for (i = 0; i < ndewarp; i++) {
1505 if ((dew = dewarpReadStream(fp)) == NULL) {
1506 L_ERROR("read fail for dew[%d]\n", __func__, i);
1507 dewarpaDestroy(&dewa);
1508 return NULL;
1509 }
1510 dewarpaInsertDewarp(dewa, dew);
1511 numaAddNumber(namodels, dew->pageno);
1512 }
1513
1514 /* Validate the models and insert reference models */
1515 dewarpaInsertRefModels(dewa, 0, 0);
1516 return dewa;
1517}
1518
1519
1527L_DEWARPA *
1528dewarpaReadMem(const l_uint8 *data,
1529 size_t size)
1530{
1531FILE *fp;
1532L_DEWARPA *dewa;
1533
1534 if (!data)
1535 return (L_DEWARPA *)ERROR_PTR("data not defined", __func__, NULL);
1536 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1537 return (L_DEWARPA *)ERROR_PTR("stream not opened", __func__, NULL);
1538
1539 dewa = dewarpaReadStream(fp);
1540 fclose(fp);
1541 if (!dewa) L_ERROR("dewa not read\n", __func__);
1542 return dewa;
1543}
1544
1545
1553l_ok
1554dewarpaWrite(const char *filename,
1555 L_DEWARPA *dewa)
1556{
1557l_int32 ret;
1558FILE *fp;
1559
1560 if (!filename)
1561 return ERROR_INT("filename not defined", __func__, 1);
1562 if (!dewa)
1563 return ERROR_INT("dewa not defined", __func__, 1);
1564
1565 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1566 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1567 ret = dewarpaWriteStream(fp, dewa);
1568 fclose(fp);
1569 if (ret)
1570 return ERROR_INT_1("dewa not written to stream", filename, __func__, 1);
1571 return 0;
1572}
1573
1574
1582l_ok
1584 L_DEWARPA *dewa)
1585{
1586l_int32 ndewarp, i, pageno;
1587
1588 if (!fp)
1589 return ERROR_INT("stream not defined", __func__, 1);
1590 if (!dewa)
1591 return ERROR_INT("dewa not defined", __func__, 1);
1592
1593 /* Generate the list of page numbers for which a model exists.
1594 * Note that no attempt is made to determine if the model is
1595 * valid, because that determination is associated with
1596 * using the model to remove the warping, which typically
1597 * can happen later, after all the models have been built. */
1598 dewarpaListPages(dewa);
1599 if (!dewa->namodels)
1600 return ERROR_INT("dewa->namodels not made", __func__, 1);
1601 ndewarp = numaGetCount(dewa->namodels); /* with actual page models */
1602
1603 fprintf(fp, "\nDewarpa Version %d\n", DEWARP_VERSION_NUMBER);
1604 fprintf(fp, "ndewarp = %d, maxpage = %d\n", ndewarp, dewa->maxpage);
1605 fprintf(fp, "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1606 dewa->sampling, dewa->redfactor, dewa->minlines, dewa->maxdist);
1607 fprintf(fp,
1608 "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1610 fprintf(fp,
1611 "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1612 dewa->max_edgeslope, dewa->max_edgecurv, dewa->max_diff_edgecurv);
1613 fprintf(fp, "fullmodel = %d\n", dewa->useboth);
1614 for (i = 0; i < ndewarp; i++) {
1615 numaGetIValue(dewa->namodels, i, &pageno);
1616 dewarpWriteStream(fp, dewarpaGetDewarp(dewa, pageno));
1617 }
1618
1619 return 0;
1620}
1621
1622
1636l_ok
1637dewarpaWriteMem(l_uint8 **pdata,
1638 size_t *psize,
1639 L_DEWARPA *dewa)
1640{
1641l_int32 ret;
1642FILE *fp;
1643
1644 if (pdata) *pdata = NULL;
1645 if (psize) *psize = 0;
1646 if (!pdata)
1647 return ERROR_INT("&data not defined", __func__, 1);
1648 if (!psize)
1649 return ERROR_INT("&size not defined", __func__, 1);
1650 if (!dewa)
1651 return ERROR_INT("dewa not defined", __func__, 1);
1652
1653#if HAVE_FMEMOPEN
1654 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1655 return ERROR_INT("stream not opened", __func__, 1);
1656 ret = dewarpaWriteStream(fp, dewa);
1657 fputc('\0', fp);
1658 fclose(fp);
1659 if (*psize > 0) *psize = *psize - 1;
1660#else
1661 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1662 #ifdef _WIN32
1663 if ((fp = fopenWriteWinTempfile()) == NULL)
1664 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1665 #else
1666 if ((fp = tmpfile()) == NULL)
1667 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1668 #endif /* _WIN32 */
1669 ret = dewarpaWriteStream(fp, dewa);
1670 rewind(fp);
1671 *pdata = l_binaryReadStream(fp, psize);
1672 fclose(fp);
1673#endif /* HAVE_FMEMOPEN */
1674 return ret;
1675}
L_DEWARP * dewarpaGetDewarp(L_DEWARPA *dewa, l_int32 index)
dewarpaGetDewarp()
Definition dewarp1.c:895
l_ok dewarpaUseBothArrays(L_DEWARPA *dewa, l_int32 useboth)
dewarpaUseBothArrays()
Definition dewarp1.c:1024
L_DEWARP * dewarpRead(const char *filename)
dewarpRead()
Definition dewarp1.c:1107
l_ok dewarpaSetMaxDistance(L_DEWARPA *dewa, l_int32 maxdist)
dewarpaSetMaxDistance()
Definition dewarp1.c:1085
L_DEWARP * dewarpReadStream(FILE *fp)
dewarpReadStream()
Definition dewarp1.c:1147
L_DEWARP * dewarpCreateRef(l_int32 pageno, l_int32 refpage)
dewarpCreateRef()
Definition dewarp1.c:496
void dewarpaDestroy(L_DEWARPA **pdewa)
dewarpaDestroy()
Definition dewarp1.c:722
static l_int32 dewarpaExtendArraysToSize(L_DEWARPA *dewa, l_int32 size)
dewarpaExtendArraysToSize()
Definition dewarp1.c:865
l_ok dewarpWriteStream(FILE *fp, L_DEWARP *dew)
dewarpWriteStream()
Definition dewarp1.c:1312
l_ok dewarpaDestroyDewarp(L_DEWARPA *dewa, l_int32 pageno)
dewarpaDestroyDewarp()
Definition dewarp1.c:759
L_DEWARPA * dewarpaReadMem(const l_uint8 *data, size_t size)
dewarpaReadMem()
Definition dewarp1.c:1528
l_ok dewarpaInsertDewarp(L_DEWARPA *dewa, L_DEWARP *dew)
dewarpaInsertDewarp()
Definition dewarp1.c:800
L_DEWARP * dewarpCreate(PIX *pixs, l_int32 pageno)
dewarpCreate()
Definition dewarp1.c:459
L_DEWARPA * dewarpaCreateFromPixacomp(PIXAC *pixac, l_int32 useboth, l_int32 sampling, l_int32 minlines, l_int32 maxdist)
dewarpaCreateFromPixacomp()
Definition dewarp1.c:663
void dewarpDestroy(L_DEWARP **pdew)
dewarpDestroy()
Definition dewarp1.c:516
l_ok dewarpWrite(const char *filename, L_DEWARP *dew)
dewarpWrite()
Definition dewarp1.c:1276
l_ok dewarpaSetCheckColumns(L_DEWARPA *dewa, l_int32 check_columns)
dewarpaSetCheckColumns()
Definition dewarp1.c:1061
l_ok dewarpaWriteStream(FILE *fp, L_DEWARPA *dewa)
dewarpaWriteStream()
Definition dewarp1.c:1583
l_ok dewarpWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARP *dew)
dewarpWriteMem()
Definition dewarp1.c:1366
L_DEWARPA * dewarpaRead(const char *filename)
dewarpaRead()
Definition dewarp1.c:1417
l_ok dewarpaWrite(const char *filename, L_DEWARPA *dewa)
dewarpaWrite()
Definition dewarp1.c:1554
L_DEWARP * dewarpReadMem(const l_uint8 *data, size_t size)
dewarpReadMem()
Definition dewarp1.c:1250
l_ok dewarpaWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARPA *dewa)
dewarpaWriteMem()
Definition dewarp1.c:1637
l_ok dewarpaSetCurvatures(L_DEWARPA *dewa, l_int32 max_linecurv, l_int32 min_diff_linecurv, l_int32 max_diff_linecurv, l_int32 max_edgecurv, l_int32 max_diff_edgecurv, l_int32 max_edgeslope)
dewarpaSetCurvatures()
Definition dewarp1.c:962
L_DEWARPA * dewarpaCreate(l_int32 nptrs, l_int32 sampling, l_int32 redfactor, l_int32 minlines, l_int32 maxdist)
dewarpaCreate()
Definition dewarp1.c:576
L_DEWARPA * dewarpaReadStream(FILE *fp)
dewarpaReadStream()
Definition dewarp1.c:1454
#define DEWARP_VERSION_NUMBER
Definition dewarp.h:110
l_int32 minlines
Definition dewarp.h:168
struct FPix * fullvdispar
Definition dewarp.h:158
l_int32 mincurv
Definition dewarp.h:170
l_int32 pageno
Definition dewarp.h:165
l_int32 vsuccess
Definition dewarp.h:180
struct L_Dewarpa * dewa
Definition dewarp.h:153
l_int32 hasref
Definition dewarp.h:178
l_int32 h
Definition dewarp.h:164
l_int32 sampling
Definition dewarp.h:166
l_int32 hsuccess
Definition dewarp.h:181
l_int32 leftcurv
Definition dewarp.h:174
l_int32 w
Definition dewarp.h:163
struct FPix * fullydispar
Definition dewarp.h:160
l_int32 redfactor
Definition dewarp.h:167
struct Pix * pixs
Definition dewarp.h:154
l_int32 nx
Definition dewarp.h:176
l_int32 nlines
Definition dewarp.h:169
l_int32 maxcurv
Definition dewarp.h:171
l_int32 refpage
Definition dewarp.h:179
struct FPix * fullhdispar
Definition dewarp.h:159
struct FPix * sampydispar
Definition dewarp.h:157
struct FPix * sampvdispar
Definition dewarp.h:155
struct Numa * nacurves
Definition dewarp.h:162
l_int32 ny
Definition dewarp.h:177
struct Numa * namidys
Definition dewarp.h:161
struct FPix * samphdispar
Definition dewarp.h:156
l_int32 rightcurv
Definition dewarp.h:175
l_int32 leftslope
Definition dewarp.h:172
l_int32 rightslope
Definition dewarp.h:173
l_int32 min_diff_linecurv
Definition dewarp.h:129
l_int32 maxdist
Definition dewarp.h:126
struct L_Dewarp ** dewarp
Definition dewarp.h:117
l_int32 max_diff_linecurv
Definition dewarp.h:131
l_int32 sampling
Definition dewarp.h:124
l_int32 max_edgeslope
Definition dewarp.h:133
l_int32 maxpage
Definition dewarp.h:116
l_int32 max_edgecurv
Definition dewarp.h:135
struct L_Dewarp ** dewarpcache
Definition dewarp.h:118
l_int32 minlines
Definition dewarp.h:125
l_int32 nalloc
Definition dewarp.h:115
struct Numa * namodels
Definition dewarp.h:119
l_int32 max_diff_edgecurv
Definition dewarp.h:137
l_int32 max_linecurv
Definition dewarp.h:127
l_int32 check_columns
Definition dewarp.h:141
struct Numa * napages
Definition dewarp.h:121
l_int32 redfactor
Definition dewarp.h:123
l_int32 modelsready
Definition dewarp.h:144
l_int32 useboth
Definition dewarp.h:139