Leptonica 1.82.0
Image processing and image analysis suite
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 PROCNAME("dewarpCreate");
465
466 if (!pixs)
467 return (L_DEWARP *)ERROR_PTR("pixs not defined", procName, NULL);
468 if (pixGetDepth(pixs) != 1)
469 return (L_DEWARP *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
470
471 dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
472 dew->pixs = pixClone(pixs);
473 dew->pageno = pageno;
474 dew->w = pixGetWidth(pixs);
475 dew->h = pixGetHeight(pixs);
476 return dew;
477}
478
479
497L_DEWARP *
498dewarpCreateRef(l_int32 pageno,
499 l_int32 refpage)
500{
501L_DEWARP *dew;
502
503 dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
504 dew->pageno = pageno;
505 dew->hasref = 1;
506 dew->refpage = refpage;
507 return dew;
508}
509
510
517void
519{
520L_DEWARP *dew;
521
522 PROCNAME("dewarpDestroy");
523
524 if (pdew == NULL) {
525 L_WARNING("ptr address is null!\n", procName);
526 return;
527 }
528 if ((dew = *pdew) == NULL)
529 return;
530
531 pixDestroy(&dew->pixs);
538 numaDestroy(&dew->namidys);
539 numaDestroy(&dew->nacurves);
540 LEPT_FREE(dew);
541 *pdew = NULL;
542}
543
544
545/*----------------------------------------------------------------------*
546 * Create/destroy Dewarpa *
547 *----------------------------------------------------------------------*/
579L_DEWARPA *
580dewarpaCreate(l_int32 nptrs,
581 l_int32 sampling,
582 l_int32 redfactor,
583 l_int32 minlines,
584 l_int32 maxdist)
585{
586L_DEWARPA *dewa;
587
588 PROCNAME("dewarpaCreate");
589
590 if (nptrs <= 0)
591 nptrs = InitialPtrArraySize;
592 if (nptrs > MaxPtrArraySize)
593 return (L_DEWARPA *)ERROR_PTR("too many pages", procName, NULL);
594 if (redfactor != 1 && redfactor != 2)
595 return (L_DEWARPA *)ERROR_PTR("redfactor not in {1,2}",
596 procName, NULL);
597 if (sampling == 0) {
598 sampling = DefaultArraySampling;
599 } else if (sampling < MinArraySampling) {
600 L_WARNING("sampling too small; setting to %d\n", procName,
601 MinArraySampling);
602 sampling = MinArraySampling;
603 }
604 if (minlines == 0) {
605 minlines = DefaultMinLines;
606 } else if (minlines < MinMinLines) {
607 L_WARNING("minlines too small; setting to %d\n", procName,
608 MinMinLines);
609 minlines = DefaultMinLines;
610 }
611 if (maxdist < 0)
612 maxdist = DefaultMaxRefDist;
613
614 dewa = (L_DEWARPA *)LEPT_CALLOC(1, sizeof(L_DEWARPA));
615 dewa->dewarp = (L_DEWARP **)LEPT_CALLOC(nptrs, sizeof(L_DEWARPA *));
616 dewa->dewarpcache = (L_DEWARP **)LEPT_CALLOC(nptrs, sizeof(L_DEWARPA *));
617 if (!dewa->dewarp || !dewa->dewarpcache) {
618 dewarpaDestroy(&dewa);
619 return (L_DEWARPA *)ERROR_PTR("dewarp ptrs not made", procName, NULL);
620 }
621 dewa->nalloc = nptrs;
622 dewa->sampling = sampling;
623 dewa->redfactor = redfactor;
624 dewa->minlines = minlines;
625 dewa->maxdist = maxdist;
626 dewa->max_linecurv = DefaultMaxLineCurv;
627 dewa->min_diff_linecurv = DefaultMinDiffLineCurv;
628 dewa->max_diff_linecurv = DefaultMaxDiffLineCurv;
629 dewa->max_edgeslope = DefaultMaxEdgeSlope;
630 dewa->max_edgecurv = DefaultMaxEdgeCurv;
631 dewa->max_diff_edgecurv = DefaultMaxDiffEdgeCurv;
632 dewa->check_columns = DefaultCheckColumns;
633 dewa->useboth = DefaultUseBoth;
634 return dewa;
635}
636
637
668L_DEWARPA *
670 l_int32 useboth,
671 l_int32 sampling,
672 l_int32 minlines,
673 l_int32 maxdist)
674{
675l_int32 i, nptrs, pageno;
676L_DEWARP *dew;
677L_DEWARPA *dewa;
678PIX *pixt;
679
680 PROCNAME("dewarpaCreateFromPixacomp");
681
682 if (!pixac)
683 return (L_DEWARPA *)ERROR_PTR("pixac not defined", procName, NULL);
684
685 nptrs = pixacompGetCount(pixac);
686 if ((dewa = dewarpaCreate(pixacompGetOffset(pixac) + nptrs,
687 sampling, 1, minlines, maxdist)) == NULL)
688 return (L_DEWARPA *)ERROR_PTR("dewa not made", procName, NULL);
689 dewarpaUseBothArrays(dewa, useboth);
690
691 for (i = 0; i < nptrs; i++) {
692 pageno = pixacompGetOffset(pixac) + i; /* index into pixacomp */
693 pixt = pixacompGetPix(pixac, pageno);
694 if (pixt && (pixGetWidth(pixt) > 1)) {
695 dew = dewarpCreate(pixt, pageno);
696 pixDestroy(&pixt);
697 if (!dew) {
698 ERROR_INT("unable to make dew!", procName, 1);
699 continue;
700 }
701
702 /* Insert into dewa for this page */
703 dewarpaInsertDewarp(dewa, dew);
704
705 /* Build disparity arrays for this page */
706 dewarpBuildPageModel(dew, NULL);
707 if (!dew->vsuccess) { /* will need to use model from nearby page */
708 dewarpaDestroyDewarp(dewa, pageno);
709 L_ERROR("unable to build model for page %d\n", procName, i);
710 continue;
711 }
712 /* Remove all extraneous data */
713 dewarpMinimize(dew);
714 }
715 pixDestroy(&pixt);
716 }
717 dewarpaInsertRefModels(dewa, 0, 0);
718
719 return dewa;
720}
721
722
729void
731{
732l_int32 i;
733L_DEWARP *dew;
734L_DEWARPA *dewa;
735
736 PROCNAME("dewarpaDestroy");
737
738 if (pdewa == NULL) {
739 L_WARNING("ptr address is null!\n", procName);
740 return;
741 }
742 if ((dewa = *pdewa) == NULL)
743 return;
744
745 for (i = 0; i < dewa->nalloc; i++) {
746 if ((dew = dewa->dewarp[i]) != NULL)
747 dewarpDestroy(&dew);
748 if ((dew = dewa->dewarpcache[i]) != NULL)
749 dewarpDestroy(&dew);
750 }
751 numaDestroy(&dewa->namodels);
752 numaDestroy(&dewa->napages);
753
754 LEPT_FREE(dewa->dewarp);
755 LEPT_FREE(dewa->dewarpcache);
756 LEPT_FREE(dewa);
757 *pdewa = NULL;
758}
759
760
768l_ok
770 l_int32 pageno)
771{
772L_DEWARP *dew;
773
774 PROCNAME("dewarpaDestroyDewarp");
775
776 if (!dewa)
777 return ERROR_INT("dewa or dew not defined", procName, 1);
778 if (pageno < 0 || pageno > dewa->maxpage)
779 return ERROR_INT("page out of bounds", procName, 1);
780 if ((dew = dewa->dewarp[pageno]) == NULL)
781 return ERROR_INT("dew not defined", procName, 1);
782
783 dewarpDestroy(&dew);
784 dewa->dewarp[pageno] = NULL;
785 return 0;
786}
787
788
789/*----------------------------------------------------------------------*
790 * Dewarpa insertion/extraction *
791 *----------------------------------------------------------------------*/
811l_ok
813 L_DEWARP *dew)
814{
815l_int32 pageno, n, newsize;
816L_DEWARP *prevdew;
817
818 PROCNAME("dewarpaInsertDewarp");
819
820 if (!dewa)
821 return ERROR_INT("dewa not defined", procName, 1);
822 if (!dew)
823 return ERROR_INT("dew not defined", procName, 1);
824
825 dew->dewa = dewa;
826 pageno = dew->pageno;
827 if (pageno > MaxPtrArraySize)
828 return ERROR_INT("too many pages", procName, 1);
829 if (pageno > dewa->maxpage)
830 dewa->maxpage = pageno;
831 dewa->modelsready = 0; /* force re-evaluation at application time */
832
833 /* Extend ptr array if necessary */
834 n = dewa->nalloc;
835 newsize = n;
836 if (pageno >= 2 * n)
837 newsize = 2 * pageno;
838 else if (pageno >= n)
839 newsize = 2 * n;
840 if (newsize > n) {
841 if (dewarpaExtendArraysToSize(dewa, newsize))
842 return ERROR_INT("extension failed", procName, 1);
843 }
844
845 if ((prevdew = dewarpaGetDewarp(dewa, pageno)) != NULL)
846 dewarpDestroy(&prevdew);
847 dewa->dewarp[pageno] = dew;
848
849 dew->sampling = dewa->sampling;
850 dew->redfactor = dewa->redfactor;
851 dew->minlines = dewa->minlines;
852
853 /* Get the dimensions of the sampled array. This will be
854 * stored in an fpix, and the input resolution version is
855 * guaranteed to be larger than pixs. However, if you
856 * want to apply the disparity to an image with a width
857 * w > nx * s - 2 * s + 2
858 * you will need to extend the input res fpix.
859 * And similarly for h. */
860 dew->nx = (dew->w + 2 * dew->sampling - 2) / dew->sampling;
861 dew->ny = (dew->h + 2 * dew->sampling - 2) / dew->sampling;
862 return 0;
863}
864
865
878static l_int32
880 l_int32 size)
881{
882 PROCNAME("dewarpaExtendArraysToSize");
883
884 if (!dewa)
885 return ERROR_INT("dewa not defined", procName, 1);
886
887 if (size > dewa->nalloc) {
888 if ((dewa->dewarp = (L_DEWARP **)reallocNew((void **)&dewa->dewarp,
889 sizeof(L_DEWARP *) * dewa->nalloc,
890 size * sizeof(L_DEWARP *))) == NULL)
891 return ERROR_INT("new ptr array not returned", procName, 1);
892 if ((dewa->dewarpcache =
893 (L_DEWARP **)reallocNew((void **)&dewa->dewarpcache,
894 sizeof(L_DEWARP *) * dewa->nalloc,
895 size * sizeof(L_DEWARP *))) == NULL)
896 return ERROR_INT("new ptr cache array not returned", procName, 1);
897 dewa->nalloc = size;
898 }
899 return 0;
900}
901
902
910L_DEWARP *
912 l_int32 index)
913{
914 PROCNAME("dewarpaGetDewarp");
915
916 if (!dewa)
917 return (L_DEWARP *)ERROR_PTR("dewa not defined", procName, NULL);
918 if (index < 0 || index > dewa->maxpage) {
919 L_ERROR("index = %d is invalid; max index = %d\n",
920 procName, index, dewa->maxpage);
921 return NULL;
922 }
923
924 return dewa->dewarp[index];
925}
926
927
928/*----------------------------------------------------------------------*
929 * Setting parameters to control rendering from the model *
930 *----------------------------------------------------------------------*/
979l_ok
981 l_int32 max_linecurv,
982 l_int32 min_diff_linecurv,
983 l_int32 max_diff_linecurv,
984 l_int32 max_edgecurv,
985 l_int32 max_diff_edgecurv,
986 l_int32 max_edgeslope)
987{
988 PROCNAME("dewarpaSetCurvatures");
989
990 if (!dewa)
991 return ERROR_INT("dewa not defined", procName, 1);
992
993 if (max_linecurv == -1)
994 dewa->max_linecurv = DefaultMaxLineCurv;
995 else
996 dewa->max_linecurv = L_ABS(max_linecurv);
997
998 if (min_diff_linecurv == -1)
999 dewa->min_diff_linecurv = DefaultMinDiffLineCurv;
1000 else
1001 dewa->min_diff_linecurv = L_ABS(min_diff_linecurv);
1002
1003 if (max_diff_linecurv == -1)
1004 dewa->max_diff_linecurv = DefaultMaxDiffLineCurv;
1005 else
1006 dewa->max_diff_linecurv = L_ABS(max_diff_linecurv);
1007
1008 if (max_edgecurv == -1)
1009 dewa->max_edgecurv = DefaultMaxEdgeCurv;
1010 else
1011 dewa->max_edgecurv = L_ABS(max_edgecurv);
1012
1013 if (max_diff_edgecurv == -1)
1014 dewa->max_diff_edgecurv = DefaultMaxDiffEdgeCurv;
1015 else
1016 dewa->max_diff_edgecurv = L_ABS(max_diff_edgecurv);
1017
1018 if (max_edgeslope == -1)
1019 dewa->max_edgeslope = DefaultMaxEdgeSlope;
1020 else
1021 dewa->max_edgeslope = L_ABS(max_edgeslope);
1022
1023 dewa->modelsready = 0; /* force validation */
1024 return 0;
1025}
1026
1027
1043l_ok
1045 l_int32 useboth)
1046{
1047 PROCNAME("dewarpaUseBothArrays");
1048
1049 if (!dewa)
1050 return ERROR_INT("dewa not defined", procName, 1);
1051
1052 dewa->useboth = useboth;
1053 dewa->modelsready = 0; /* force validation */
1054 return 0;
1055}
1056
1057
1082l_ok
1084 l_int32 check_columns)
1085{
1086 PROCNAME("dewarpaSetCheckColumns");
1087
1088 if (!dewa)
1089 return ERROR_INT("dewa not defined", procName, 1);
1090
1091 dewa->check_columns = check_columns;
1092 return 0;
1093}
1094
1095
1108l_ok
1110 l_int32 maxdist)
1111{
1112 PROCNAME("dewarpaSetMaxDistance");
1113
1114 if (!dewa)
1115 return ERROR_INT("dewa not defined", procName, 1);
1116
1117 dewa->maxdist = maxdist;
1118 dewa->modelsready = 0; /* force validation */
1119 return 0;
1120}
1121
1122
1123/*----------------------------------------------------------------------*
1124 * Dewarp serialized I/O *
1125 *----------------------------------------------------------------------*/
1132L_DEWARP *
1133dewarpRead(const char *filename)
1134{
1135FILE *fp;
1136L_DEWARP *dew;
1137
1138 PROCNAME("dewarpRead");
1139
1140 if (!filename)
1141 return (L_DEWARP *)ERROR_PTR("filename not defined", procName, NULL);
1142 if ((fp = fopenReadStream(filename)) == NULL)
1143 return (L_DEWARP *)ERROR_PTR("stream not opened", procName, NULL);
1144
1145 if ((dew = dewarpReadStream(fp)) == NULL) {
1146 fclose(fp);
1147 return (L_DEWARP *)ERROR_PTR("dew not read", procName, NULL);
1148 }
1149
1150 fclose(fp);
1151 return dew;
1152}
1153
1154
1172L_DEWARP *
1174{
1175l_int32 version, sampling, redfactor, minlines, pageno, hasref, refpage;
1176l_int32 w, h, nx, ny, vdispar, hdispar, nlines;
1177l_int32 mincurv, maxcurv, leftslope, rightslope, leftcurv, rightcurv;
1178L_DEWARP *dew;
1179FPIX *fpixv, *fpixh;
1180
1181 PROCNAME("dewarpReadStream");
1182
1183 if (!fp)
1184 return (L_DEWARP *)ERROR_PTR("stream not defined", procName, NULL);
1185
1186 if (fscanf(fp, "\nDewarp Version %d\n", &version) != 1)
1187 return (L_DEWARP *)ERROR_PTR("not a dewarp file", procName, NULL);
1188 if (version != DEWARP_VERSION_NUMBER)
1189 return (L_DEWARP *)ERROR_PTR("invalid dewarp version", procName, NULL);
1190 if (fscanf(fp, "pageno = %d\n", &pageno) != 1)
1191 return (L_DEWARP *)ERROR_PTR("read fail for pageno", procName, NULL);
1192 if (fscanf(fp, "hasref = %d, refpage = %d\n", &hasref, &refpage) != 2)
1193 return (L_DEWARP *)ERROR_PTR("read fail for hasref, refpage",
1194 procName, NULL);
1195 if (fscanf(fp, "sampling = %d, redfactor = %d\n", &sampling, &redfactor)
1196 != 2)
1197 return (L_DEWARP *)ERROR_PTR("read fail for sampling/redfactor",
1198 procName, NULL);
1199 if (fscanf(fp, "nlines = %d, minlines = %d\n", &nlines, &minlines) != 2)
1200 return (L_DEWARP *)ERROR_PTR("read fail for nlines/minlines",
1201 procName, NULL);
1202 if (fscanf(fp, "w = %d, h = %d\n", &w, &h) != 2)
1203 return (L_DEWARP *)ERROR_PTR("read fail for w, h", procName, NULL);
1204 if (fscanf(fp, "nx = %d, ny = %d\n", &nx, &ny) != 2)
1205 return (L_DEWARP *)ERROR_PTR("read fail for nx, ny", procName, NULL);
1206 if (fscanf(fp, "vert_dispar = %d, horiz_dispar = %d\n", &vdispar, &hdispar)
1207 != 2)
1208 return (L_DEWARP *)ERROR_PTR("read fail for flags", procName, NULL);
1209 if (vdispar) {
1210 if (fscanf(fp, "min line curvature = %d, max line curvature = %d\n",
1211 &mincurv, &maxcurv) != 2)
1212 return (L_DEWARP *)ERROR_PTR("read fail for mincurv & maxcurv",
1213 procName, NULL);
1214 }
1215 if (hdispar) {
1216 if (fscanf(fp, "left edge slope = %d, right edge slope = %d\n",
1217 &leftslope, &rightslope) != 2)
1218 return (L_DEWARP *)ERROR_PTR("read fail for leftslope & rightslope",
1219 procName, NULL);
1220 if (fscanf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1221 &leftcurv, &rightcurv) != 2)
1222 return (L_DEWARP *)ERROR_PTR("read fail for leftcurv & rightcurv",
1223 procName, NULL);
1224 }
1225 if (vdispar) {
1226 if ((fpixv = fpixReadStream(fp)) == NULL)
1227 return (L_DEWARP *)ERROR_PTR("read fail for vdispar",
1228 procName, NULL);
1229 }
1230 if (hdispar) {
1231 if ((fpixh = fpixReadStream(fp)) == NULL)
1232 return (L_DEWARP *)ERROR_PTR("read fail for hdispar",
1233 procName, NULL);
1234 }
1235 getc(fp);
1236
1237 dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
1238 dew->w = w;
1239 dew->h = h;
1240 dew->pageno = pageno;
1241 dew->sampling = sampling;
1242 dew->redfactor = redfactor;
1243 dew->minlines = minlines;
1244 dew->nlines = nlines;
1245 dew->hasref = hasref;
1246 dew->refpage = refpage;
1247 if (hasref == 0) /* any dew without a ref has an actual model */
1248 dew->vsuccess = 1;
1249 dew->nx = nx;
1250 dew->ny = ny;
1251 if (vdispar) {
1252 dew->mincurv = mincurv;
1253 dew->maxcurv = maxcurv;
1254 dew->vsuccess = 1;
1255 dew->sampvdispar = fpixv;
1256 }
1257 if (hdispar) {
1258 dew->leftslope = leftslope;
1259 dew->rightslope = rightslope;
1260 dew->leftcurv = leftcurv;
1261 dew->rightcurv = rightcurv;
1262 dew->hsuccess = 1;
1263 dew->samphdispar = fpixh;
1264 }
1265
1266 return dew;
1267}
1268
1269
1277L_DEWARP *
1278dewarpReadMem(const l_uint8 *data,
1279 size_t size)
1280{
1281FILE *fp;
1282L_DEWARP *dew;
1283
1284 PROCNAME("dewarpReadMem");
1285
1286 if (!data)
1287 return (L_DEWARP *)ERROR_PTR("data not defined", procName, NULL);
1288 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1289 return (L_DEWARP *)ERROR_PTR("stream not opened", procName, NULL);
1290
1291 dew = dewarpReadStream(fp);
1292 fclose(fp);
1293 if (!dew) L_ERROR("dew not read\n", procName);
1294 return dew;
1295}
1296
1297
1305l_ok
1306dewarpWrite(const char *filename,
1307 L_DEWARP *dew)
1308{
1309l_int32 ret;
1310FILE *fp;
1311
1312 PROCNAME("dewarpWrite");
1313
1314 if (!filename)
1315 return ERROR_INT("filename not defined", procName, 1);
1316 if (!dew)
1317 return ERROR_INT("dew not defined", procName, 1);
1318
1319 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1320 return ERROR_INT("stream not opened", procName, 1);
1321 ret = dewarpWriteStream(fp, dew);
1322 fclose(fp);
1323 if (ret)
1324 return ERROR_INT("dew not written to stream", procName, 1);
1325 return 0;
1326}
1327
1328
1343l_ok
1345 L_DEWARP *dew)
1346{
1347l_int32 vdispar, hdispar;
1348
1349 PROCNAME("dewarpWriteStream");
1350
1351 if (!fp)
1352 return ERROR_INT("stream not defined", procName, 1);
1353 if (!dew)
1354 return ERROR_INT("dew not defined", procName, 1);
1355
1356 fprintf(fp, "\nDewarp Version %d\n", DEWARP_VERSION_NUMBER);
1357 fprintf(fp, "pageno = %d\n", dew->pageno);
1358 fprintf(fp, "hasref = %d, refpage = %d\n", dew->hasref, dew->refpage);
1359 fprintf(fp, "sampling = %d, redfactor = %d\n",
1360 dew->sampling, dew->redfactor);
1361 fprintf(fp, "nlines = %d, minlines = %d\n", dew->nlines, dew->minlines);
1362 fprintf(fp, "w = %d, h = %d\n", dew->w, dew->h);
1363 fprintf(fp, "nx = %d, ny = %d\n", dew->nx, dew->ny);
1364 vdispar = (dew->sampvdispar) ? 1 : 0;
1365 hdispar = (dew->samphdispar) ? 1 : 0;
1366 fprintf(fp, "vert_dispar = %d, horiz_dispar = %d\n", vdispar, hdispar);
1367 if (vdispar)
1368 fprintf(fp, "min line curvature = %d, max line curvature = %d\n",
1369 dew->mincurv, dew->maxcurv);
1370 if (hdispar) {
1371 fprintf(fp, "left edge slope = %d, right edge slope = %d\n",
1372 dew->leftslope, dew->rightslope);
1373 fprintf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1374 dew->leftcurv, dew->rightcurv);
1375 }
1376 if (vdispar) fpixWriteStream(fp, dew->sampvdispar);
1377 if (hdispar) fpixWriteStream(fp, dew->samphdispar);
1378 fprintf(fp, "\n");
1379
1380 if (!vdispar)
1381 L_WARNING("no disparity arrays!\n", procName);
1382 return 0;
1383}
1384
1385
1399l_ok
1400dewarpWriteMem(l_uint8 **pdata,
1401 size_t *psize,
1402 L_DEWARP *dew)
1403{
1404l_int32 ret;
1405FILE *fp;
1406
1407 PROCNAME("dewarpWriteMem");
1408
1409 if (pdata) *pdata = NULL;
1410 if (psize) *psize = 0;
1411 if (!pdata)
1412 return ERROR_INT("&data not defined", procName, 1);
1413 if (!psize)
1414 return ERROR_INT("&size not defined", procName, 1);
1415 if (!dew)
1416 return ERROR_INT("dew not defined", procName, 1);
1417
1418#if HAVE_FMEMOPEN
1419 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1420 return ERROR_INT("stream not opened", procName, 1);
1421 ret = dewarpWriteStream(fp, dew);
1422 fputc('\0', fp);
1423 fclose(fp);
1424 *psize = *psize - 1;
1425#else
1426 L_INFO("work-around: writing to a temp file\n", procName);
1427 #ifdef _WIN32
1428 if ((fp = fopenWriteWinTempfile()) == NULL)
1429 return ERROR_INT("tmpfile stream not opened", procName, 1);
1430 #else
1431 if ((fp = tmpfile()) == NULL)
1432 return ERROR_INT("tmpfile stream not opened", procName, 1);
1433 #endif /* _WIN32 */
1434 ret = dewarpWriteStream(fp, dew);
1435 rewind(fp);
1436 *pdata = l_binaryReadStream(fp, psize);
1437 fclose(fp);
1438#endif /* HAVE_FMEMOPEN */
1439 return ret;
1440}
1441
1442
1443/*----------------------------------------------------------------------*
1444 * Dewarpa serialized I/O *
1445 *----------------------------------------------------------------------*/
1452L_DEWARPA *
1453dewarpaRead(const char *filename)
1454{
1455FILE *fp;
1456L_DEWARPA *dewa;
1457
1458 PROCNAME("dewarpaRead");
1459
1460 if (!filename)
1461 return (L_DEWARPA *)ERROR_PTR("filename not defined", procName, NULL);
1462 if ((fp = fopenReadStream(filename)) == NULL)
1463 return (L_DEWARPA *)ERROR_PTR("stream not opened", procName, NULL);
1464
1465 if ((dewa = dewarpaReadStream(fp)) == NULL) {
1466 fclose(fp);
1467 return (L_DEWARPA *)ERROR_PTR("dewa not read", procName, NULL);
1468 }
1469
1470 fclose(fp);
1471 return dewa;
1472}
1473
1474
1489L_DEWARPA *
1491{
1492l_int32 i, version, ndewarp, maxpage;
1493l_int32 sampling, redfactor, minlines, maxdist, useboth;
1494l_int32 max_linecurv, min_diff_linecurv, max_diff_linecurv;
1495l_int32 max_edgeslope, max_edgecurv, max_diff_edgecurv;
1496L_DEWARP *dew;
1497L_DEWARPA *dewa;
1498NUMA *namodels;
1499
1500 PROCNAME("dewarpaReadStream");
1501
1502 if (!fp)
1503 return (L_DEWARPA *)ERROR_PTR("stream not defined", procName, NULL);
1504
1505 if (fscanf(fp, "\nDewarpa Version %d\n", &version) != 1)
1506 return (L_DEWARPA *)ERROR_PTR("not a dewarpa file", procName, NULL);
1507 if (version != DEWARP_VERSION_NUMBER)
1508 return (L_DEWARPA *)ERROR_PTR("invalid dewarp version", procName, NULL);
1509
1510 if (fscanf(fp, "ndewarp = %d, maxpage = %d\n", &ndewarp, &maxpage) != 2)
1511 return (L_DEWARPA *)ERROR_PTR("read fail for maxpage+", procName, NULL);
1512 if (ndewarp < 1)
1513 return (L_DEWARPA *)ERROR_PTR("pages not >= 1", procName, NULL);
1514 if (ndewarp > MaxPtrArraySize)
1515 return (L_DEWARPA *)ERROR_PTR("too many pages", procName, NULL);
1516 if (fscanf(fp,
1517 "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1518 &sampling, &redfactor, &minlines, &maxdist) != 4)
1519 return (L_DEWARPA *)ERROR_PTR("read fail for 4 params", procName, NULL);
1520 if (fscanf(fp,
1521 "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1522 &max_linecurv, &min_diff_linecurv, &max_diff_linecurv) != 3)
1523 return (L_DEWARPA *)ERROR_PTR("read fail for linecurv", procName, NULL);
1524 if (fscanf(fp,
1525 "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1526 &max_edgeslope, &max_edgecurv, &max_diff_edgecurv) != 3)
1527 return (L_DEWARPA *)ERROR_PTR("read fail for edgecurv", procName, NULL);
1528 if (fscanf(fp, "fullmodel = %d\n", &useboth) != 1)
1529 return (L_DEWARPA *)ERROR_PTR("read fail for useboth", procName, NULL);
1530
1531 dewa = dewarpaCreate(maxpage + 1, sampling, redfactor, minlines, maxdist);
1532 dewa->maxpage = maxpage;
1533 dewa->max_linecurv = max_linecurv;
1534 dewa->min_diff_linecurv = min_diff_linecurv;
1535 dewa->max_diff_linecurv = max_diff_linecurv;
1536 dewa->max_edgeslope = max_edgeslope;
1537 dewa->max_edgecurv = max_edgecurv;
1538 dewa->max_diff_edgecurv = max_diff_edgecurv;
1539 dewa->useboth = useboth;
1540 namodels = numaCreate(ndewarp);
1541 dewa->namodels = namodels;
1542 for (i = 0; i < ndewarp; i++) {
1543 if ((dew = dewarpReadStream(fp)) == NULL) {
1544 L_ERROR("read fail for dew[%d]\n", procName, i);
1545 dewarpaDestroy(&dewa);
1546 return NULL;
1547 }
1548 dewarpaInsertDewarp(dewa, dew);
1549 numaAddNumber(namodels, dew->pageno);
1550 }
1551
1552 /* Validate the models and insert reference models */
1553 dewarpaInsertRefModels(dewa, 0, 0);
1554 return dewa;
1555}
1556
1557
1565L_DEWARPA *
1566dewarpaReadMem(const l_uint8 *data,
1567 size_t size)
1568{
1569FILE *fp;
1570L_DEWARPA *dewa;
1571
1572 PROCNAME("dewarpaReadMem");
1573
1574 if (!data)
1575 return (L_DEWARPA *)ERROR_PTR("data not defined", procName, NULL);
1576 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1577 return (L_DEWARPA *)ERROR_PTR("stream not opened", procName, NULL);
1578
1579 dewa = dewarpaReadStream(fp);
1580 fclose(fp);
1581 if (!dewa) L_ERROR("dewa not read\n", procName);
1582 return dewa;
1583}
1584
1585
1593l_ok
1594dewarpaWrite(const char *filename,
1595 L_DEWARPA *dewa)
1596{
1597l_int32 ret;
1598FILE *fp;
1599
1600 PROCNAME("dewarpaWrite");
1601
1602 if (!filename)
1603 return ERROR_INT("filename not defined", procName, 1);
1604 if (!dewa)
1605 return ERROR_INT("dewa not defined", procName, 1);
1606
1607 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1608 return ERROR_INT("stream not opened", procName, 1);
1609 ret = dewarpaWriteStream(fp, dewa);
1610 fclose(fp);
1611 if (ret)
1612 return ERROR_INT("dewa not written to stream", procName, 1);
1613 return 0;
1614}
1615
1616
1624l_ok
1626 L_DEWARPA *dewa)
1627{
1628l_int32 ndewarp, i, pageno;
1629
1630 PROCNAME("dewarpaWriteStream");
1631
1632 if (!fp)
1633 return ERROR_INT("stream not defined", procName, 1);
1634 if (!dewa)
1635 return ERROR_INT("dewa not defined", procName, 1);
1636
1637 /* Generate the list of page numbers for which a model exists.
1638 * Note that no attempt is made to determine if the model is
1639 * valid, because that determination is associated with
1640 * using the model to remove the warping, which typically
1641 * can happen later, after all the models have been built. */
1642 dewarpaListPages(dewa);
1643 if (!dewa->namodels)
1644 return ERROR_INT("dewa->namodels not made", procName, 1);
1645 ndewarp = numaGetCount(dewa->namodels); /* with actual page models */
1646
1647 fprintf(fp, "\nDewarpa Version %d\n", DEWARP_VERSION_NUMBER);
1648 fprintf(fp, "ndewarp = %d, maxpage = %d\n", ndewarp, dewa->maxpage);
1649 fprintf(fp, "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1650 dewa->sampling, dewa->redfactor, dewa->minlines, dewa->maxdist);
1651 fprintf(fp,
1652 "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1654 fprintf(fp,
1655 "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1656 dewa->max_edgeslope, dewa->max_edgecurv, dewa->max_diff_edgecurv);
1657 fprintf(fp, "fullmodel = %d\n", dewa->useboth);
1658 for (i = 0; i < ndewarp; i++) {
1659 numaGetIValue(dewa->namodels, i, &pageno);
1660 dewarpWriteStream(fp, dewarpaGetDewarp(dewa, pageno));
1661 }
1662
1663 return 0;
1664}
1665
1666
1680l_ok
1681dewarpaWriteMem(l_uint8 **pdata,
1682 size_t *psize,
1683 L_DEWARPA *dewa)
1684{
1685l_int32 ret;
1686FILE *fp;
1687
1688 PROCNAME("dewarpaWriteMem");
1689
1690 if (pdata) *pdata = NULL;
1691 if (psize) *psize = 0;
1692 if (!pdata)
1693 return ERROR_INT("&data not defined", procName, 1);
1694 if (!psize)
1695 return ERROR_INT("&size not defined", procName, 1);
1696 if (!dewa)
1697 return ERROR_INT("dewa not defined", procName, 1);
1698
1699#if HAVE_FMEMOPEN
1700 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1701 return ERROR_INT("stream not opened", procName, 1);
1702 ret = dewarpaWriteStream(fp, dewa);
1703 fputc('\0', fp);
1704 fclose(fp);
1705 *psize = *psize - 1;
1706#else
1707 L_INFO("work-around: writing to a temp file\n", procName);
1708 #ifdef _WIN32
1709 if ((fp = fopenWriteWinTempfile()) == NULL)
1710 return ERROR_INT("tmpfile stream not opened", procName, 1);
1711 #else
1712 if ((fp = tmpfile()) == NULL)
1713 return ERROR_INT("tmpfile stream not opened", procName, 1);
1714 #endif /* _WIN32 */
1715 ret = dewarpaWriteStream(fp, dewa);
1716 rewind(fp);
1717 *pdata = l_binaryReadStream(fp, psize);
1718 fclose(fp);
1719#endif /* HAVE_FMEMOPEN */
1720 return ret;
1721}
L_DEWARP * dewarpaGetDewarp(L_DEWARPA *dewa, l_int32 index)
dewarpaGetDewarp()
Definition: dewarp1.c:911
l_ok dewarpaUseBothArrays(L_DEWARPA *dewa, l_int32 useboth)
dewarpaUseBothArrays()
Definition: dewarp1.c:1044
L_DEWARP * dewarpRead(const char *filename)
dewarpRead()
Definition: dewarp1.c:1133
l_ok dewarpaSetMaxDistance(L_DEWARPA *dewa, l_int32 maxdist)
dewarpaSetMaxDistance()
Definition: dewarp1.c:1109
L_DEWARP * dewarpReadStream(FILE *fp)
dewarpReadStream()
Definition: dewarp1.c:1173
L_DEWARP * dewarpCreateRef(l_int32 pageno, l_int32 refpage)
dewarpCreateRef()
Definition: dewarp1.c:498
void dewarpaDestroy(L_DEWARPA **pdewa)
dewarpaDestroy()
Definition: dewarp1.c:730
static l_int32 dewarpaExtendArraysToSize(L_DEWARPA *dewa, l_int32 size)
dewarpaExtendArraysToSize()
Definition: dewarp1.c:879
l_ok dewarpWriteStream(FILE *fp, L_DEWARP *dew)
dewarpWriteStream()
Definition: dewarp1.c:1344
l_ok dewarpaDestroyDewarp(L_DEWARPA *dewa, l_int32 pageno)
dewarpaDestroyDewarp()
Definition: dewarp1.c:769
L_DEWARPA * dewarpaReadMem(const l_uint8 *data, size_t size)
dewarpaReadMem()
Definition: dewarp1.c:1566
l_ok dewarpaInsertDewarp(L_DEWARPA *dewa, L_DEWARP *dew)
dewarpaInsertDewarp()
Definition: dewarp1.c:812
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:669
void dewarpDestroy(L_DEWARP **pdew)
dewarpDestroy()
Definition: dewarp1.c:518
l_ok dewarpWrite(const char *filename, L_DEWARP *dew)
dewarpWrite()
Definition: dewarp1.c:1306
l_ok dewarpaSetCheckColumns(L_DEWARPA *dewa, l_int32 check_columns)
dewarpaSetCheckColumns()
Definition: dewarp1.c:1083
l_ok dewarpaWriteStream(FILE *fp, L_DEWARPA *dewa)
dewarpaWriteStream()
Definition: dewarp1.c:1625
l_ok dewarpWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARP *dew)
dewarpWriteMem()
Definition: dewarp1.c:1400
L_DEWARPA * dewarpaRead(const char *filename)
dewarpaRead()
Definition: dewarp1.c:1453
l_ok dewarpaWrite(const char *filename, L_DEWARPA *dewa)
dewarpaWrite()
Definition: dewarp1.c:1594
L_DEWARP * dewarpReadMem(const l_uint8 *data, size_t size)
dewarpReadMem()
Definition: dewarp1.c:1278
l_ok dewarpaWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARPA *dewa)
dewarpaWriteMem()
Definition: dewarp1.c:1681
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:980
L_DEWARPA * dewarpaCreate(l_int32 nptrs, l_int32 sampling, l_int32 redfactor, l_int32 minlines, l_int32 maxdist)
dewarpaCreate()
Definition: dewarp1.c:580
L_DEWARPA * dewarpaReadStream(FILE *fp)
dewarpaReadStream()
Definition: dewarp1.c:1490
l_ok dewarpBuildPageModel(L_DEWARP *dew, const char *debugfile)
dewarpBuildPageModel()
Definition: dewarp2.c:156
l_ok dewarpMinimize(L_DEWARP *dew)
dewarpMinimize()
Definition: dewarp3.c:731
l_ok dewarpaListPages(L_DEWARPA *dewa)
dewarpaListPages()
Definition: dewarp4.c:296
l_ok dewarpaInsertRefModels(L_DEWARPA *dewa, l_int32 notests, l_int32 debug)
dewarpaInsertRefModels()
Definition: dewarp4.c:454
#define DEWARP_VERSION_NUMBER
Definition: dewarp.h:110
FPIX * fpixReadStream(FILE *fp)
fpixReadStream()
Definition: fpix1.c:1580
l_ok fpixWriteStream(FILE *fp, FPIX *fpix)
fpixWriteStream()
Definition: fpix1.c:1692
void fpixDestroy(FPIX **pfpix)
fpixDestroy()
Definition: fpix1.c:292
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
l_int32 pixacompGetOffset(PIXAC *pixac)
pixacompGetOffset()
Definition: pixcomp.c:1440
l_int32 pixacompGetCount(PIXAC *pixac)
pixacompGetCount()
Definition: pixcomp.c:1162
PIX * pixacompGetPix(PIXAC *pixac, l_int32 index)
pixacompGetPix()
Definition: pixcomp.c:1227
Definition: pix.h:579
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
Definition: array.h:71
Definition: pix.h:139
Definition: pix.h:654
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302