Leptonica  1.77.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 
402 #include <math.h>
403 #include "allheaders.h"
404 
405 static l_int32 dewarpaExtendArraysToSize(L_DEWARPA *dewa, l_int32 size);
406 
407  /* Parameter values used in dewarpaCreate() */
408 static const l_int32 INITIAL_PTR_ARRAYSIZE = 20; /* n'import quoi */
409 static const l_int32 MAX_PTR_ARRAYSIZE = 10000;
410 static const l_int32 DEFAULT_ARRAY_SAMPLING = 30;
411 static const l_int32 MIN_ARRAY_SAMPLING = 8;
412 static const l_int32 DEFAULT_MIN_LINES = 15;
413 static const l_int32 MIN_MIN_LINES = 4;
414 static const l_int32 DEFAULT_MAX_REF_DIST = 16;
415 static const l_int32 DEFAULT_USE_BOTH = TRUE;
416 static const l_int32 DEFAULT_CHECK_COLUMNS = FALSE;
417 
418  /* Parameter values used in dewarpaSetCurvatures() */
419 static const l_int32 DEFAULT_MAX_LINECURV = 180;
420 static const l_int32 DEFAULT_MIN_DIFF_LINECURV = 0;
421 static const l_int32 DEFAULT_MAX_DIFF_LINECURV = 200;
422 static const l_int32 DEFAULT_MAX_EDGECURV = 50;
423 static const l_int32 DEFAULT_MAX_DIFF_EDGECURV = 40;
424 static const l_int32 DEFAULT_MAX_EDGESLOPE = 80;
425 
426 
427 /*----------------------------------------------------------------------*
428  * Create/destroy Dewarp *
429  *----------------------------------------------------------------------*/
445 L_DEWARP *
447  l_int32 pageno)
448 {
449 L_DEWARP *dew;
450 
451  PROCNAME("dewarpCreate");
452 
453  if (!pixs)
454  return (L_DEWARP *)ERROR_PTR("pixs not defined", procName, NULL);
455  if (pixGetDepth(pixs) != 1)
456  return (L_DEWARP *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
457 
458  if ((dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP))) == NULL)
459  return (L_DEWARP *)ERROR_PTR("dew not made", procName, NULL);
460  dew->pixs = pixClone(pixs);
461  dew->pageno = pageno;
462  dew->w = pixGetWidth(pixs);
463  dew->h = pixGetHeight(pixs);
464  return dew;
465 }
466 
467 
485 L_DEWARP *
487  l_int32 refpage)
488 {
489 L_DEWARP *dew;
490 
491  PROCNAME("dewarpCreateRef");
492 
493  if ((dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP))) == NULL)
494  return (L_DEWARP *)ERROR_PTR("dew not made", procName, NULL);
495  dew->pageno = pageno;
496  dew->hasref = 1;
497  dew->refpage = refpage;
498  return dew;
499 }
500 
501 
508 void
510 {
511 L_DEWARP *dew;
512 
513  PROCNAME("dewarpDestroy");
514 
515  if (pdew == NULL) {
516  L_WARNING("ptr address is null!\n", procName);
517  return;
518  }
519  if ((dew = *pdew) == NULL)
520  return;
521 
522  pixDestroy(&dew->pixs);
523  fpixDestroy(&dew->sampvdispar);
524  fpixDestroy(&dew->samphdispar);
525  fpixDestroy(&dew->sampydispar);
526  fpixDestroy(&dew->fullvdispar);
527  fpixDestroy(&dew->fullhdispar);
528  fpixDestroy(&dew->fullydispar);
529  numaDestroy(&dew->namidys);
530  numaDestroy(&dew->nacurves);
531  LEPT_FREE(dew);
532  *pdew = NULL;
533  return;
534 }
535 
536 
537 /*----------------------------------------------------------------------*
538  * Create/destroy Dewarpa *
539  *----------------------------------------------------------------------*/
571 L_DEWARPA *
572 dewarpaCreate(l_int32 nptrs,
573  l_int32 sampling,
574  l_int32 redfactor,
575  l_int32 minlines,
576  l_int32 maxdist)
577 {
578 L_DEWARPA *dewa;
579 
580  PROCNAME("dewarpaCreate");
581 
582  if (nptrs <= 0)
583  nptrs = INITIAL_PTR_ARRAYSIZE;
584  if (nptrs > MAX_PTR_ARRAYSIZE)
585  return (L_DEWARPA *)ERROR_PTR("too many pages", procName, NULL);
586  if (redfactor != 1 && redfactor != 2)
587  return (L_DEWARPA *)ERROR_PTR("redfactor not in {1,2}",
588  procName, NULL);
589  if (sampling == 0) {
590  sampling = DEFAULT_ARRAY_SAMPLING;
591  } else if (sampling < MIN_ARRAY_SAMPLING) {
592  L_WARNING("sampling too small; setting to %d\n", procName,
593  MIN_ARRAY_SAMPLING);
594  sampling = MIN_ARRAY_SAMPLING;
595  }
596  if (minlines == 0) {
597  minlines = DEFAULT_MIN_LINES;
598  } else if (minlines < MIN_MIN_LINES) {
599  L_WARNING("minlines too small; setting to %d\n", procName,
600  MIN_MIN_LINES);
601  minlines = DEFAULT_MIN_LINES;
602  }
603  if (maxdist < 0)
604  maxdist = DEFAULT_MAX_REF_DIST;
605 
606  dewa = (L_DEWARPA *)LEPT_CALLOC(1, sizeof(L_DEWARPA));
607  dewa->dewarp = (L_DEWARP **)LEPT_CALLOC(nptrs, sizeof(L_DEWARPA *));
608  dewa->dewarpcache = (L_DEWARP **)LEPT_CALLOC(nptrs, sizeof(L_DEWARPA *));
609  if (!dewa->dewarp || !dewa->dewarpcache) {
611  return (L_DEWARPA *)ERROR_PTR("dewarp ptrs not made", procName, NULL);
612  }
613  dewa->nalloc = nptrs;
617  dewa->maxdist = maxdist;
618  dewa->max_linecurv = DEFAULT_MAX_LINECURV;
619  dewa->min_diff_linecurv = DEFAULT_MIN_DIFF_LINECURV;
620  dewa->max_diff_linecurv = DEFAULT_MAX_DIFF_LINECURV;
621  dewa->max_edgeslope = DEFAULT_MAX_EDGESLOPE;
622  dewa->max_edgecurv = DEFAULT_MAX_EDGECURV;
623  dewa->max_diff_edgecurv = DEFAULT_MAX_DIFF_EDGECURV;
624  dewa->check_columns = DEFAULT_CHECK_COLUMNS;
625  dewa->useboth = DEFAULT_USE_BOTH;
626  return dewa;
627 }
628 
629 
660 L_DEWARPA *
662  l_int32 useboth,
663  l_int32 sampling,
664  l_int32 minlines,
665  l_int32 maxdist)
666 {
667 l_int32 i, nptrs, pageno;
668 L_DEWARP *dew;
669 L_DEWARPA *dewa;
670 PIX *pixt;
671 
672  PROCNAME("dewarpaCreateFromPixacomp");
673 
674  if (!pixac)
675  return (L_DEWARPA *)ERROR_PTR("pixac not defined", procName, 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", procName, 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!", procName, 1);
691  continue;
692  }
693 
694  /* Insert into dewa for this page */
696 
697  /* Build disparity arrays for this page */
698  dewarpBuildPageModel(dew, NULL);
699  if (!dew->vsuccess) { /* will need to use model from nearby page */
701  L_ERROR("unable to build model for page %d\n", procName, i);
702  continue;
703  }
704  /* Remove all extraneous data */
705  dewarpMinimize(dew);
706  }
707  pixDestroy(&pixt);
708  }
710 
711  return dewa;
712 }
713 
714 
721 void
723 {
724 l_int32 i;
725 L_DEWARP *dew;
726 L_DEWARPA *dewa;
727 
728  PROCNAME("dewarpaDestroy");
729 
730  if (pdewa == NULL) {
731  L_WARNING("ptr address is null!\n", procName);
732  return;
733  }
734  if ((dewa = *pdewa) == NULL)
735  return;
736 
737  for (i = 0; i < dewa->nalloc; i++) {
738  if ((dew = dewa->dewarp[i]) != NULL)
739  dewarpDestroy(&dew);
740  if ((dew = dewa->dewarpcache[i]) != NULL)
741  dewarpDestroy(&dew);
742  }
745 
746  LEPT_FREE(dewa->dewarp);
747  LEPT_FREE(dewa->dewarpcache);
748  LEPT_FREE(dewa);
749  *pdewa = NULL;
750  return;
751 }
752 
753 
761 l_ok
763  l_int32 pageno)
764 {
765 L_DEWARP *dew;
766 
767  PROCNAME("dewarpaDestroyDewarp");
768 
769  if (!dewa)
770  return ERROR_INT("dewa or dew not defined", procName, 1);
771  if (pageno < 0 || pageno > dewa->maxpage)
772  return ERROR_INT("page out of bounds", procName, 1);
773  if ((dew = dewa->dewarp[pageno]) == NULL)
774  return ERROR_INT("dew not defined", procName, 1);
775 
776  dewarpDestroy(&dew);
777  dewa->dewarp[pageno] = NULL;
778  return 0;
779 }
780 
781 
782 /*----------------------------------------------------------------------*
783  * Dewarpa insertion/extraction *
784  *----------------------------------------------------------------------*/
804 l_ok
806  L_DEWARP *dew)
807 {
808 l_int32 pageno, n, newsize;
809 L_DEWARP *prevdew;
810 
811  PROCNAME("dewarpaInsertDewarp");
812 
813  if (!dewa)
814  return ERROR_INT("dewa not defined", procName, 1);
815  if (!dew)
816  return ERROR_INT("dew not defined", procName, 1);
817 
818  dew->dewa = dewa;
819  pageno = dew->pageno;
820  if (pageno > MAX_PTR_ARRAYSIZE)
821  return ERROR_INT("too many pages", procName, 1);
822  if (pageno > dewa->maxpage)
823  dewa->maxpage = pageno;
824  dewa->modelsready = 0; /* force re-evaluation at application time */
825 
826  /* Extend ptr array if necessary */
827  n = dewa->nalloc;
828  newsize = n;
829  if (pageno >= 2 * n)
830  newsize = 2 * pageno;
831  else if (pageno >= n)
832  newsize = 2 * n;
833  if (newsize > n)
835 
836  if ((prevdew = dewarpaGetDewarp(dewa, pageno)) != NULL)
837  dewarpDestroy(&prevdew);
838  dewa->dewarp[pageno] = dew;
839 
840  dew->sampling = dewa->sampling;
841  dew->redfactor = dewa->redfactor;
842  dew->minlines = dewa->minlines;
843 
844  /* Get the dimensions of the sampled array. This will be
845  * stored in an fpix, and the input resolution version is
846  * guaranteed to be larger than pixs. However, if you
847  * want to apply the disparity to an image with a width
848  * w > nx * s - 2 * s + 2
849  * you will need to extend the input res fpix.
850  * And similarly for h. */
851  dew->nx = (dew->w + 2 * dew->sampling - 2) / dew->sampling;
852  dew->ny = (dew->h + 2 * dew->sampling - 2) / dew->sampling;
853  return 0;
854 }
855 
856 
869 static l_int32
871  l_int32 size)
872 {
873  PROCNAME("dewarpaExtendArraysToSize");
874 
875  if (!dewa)
876  return ERROR_INT("dewa not defined", procName, 1);
877 
878  if (size > dewa->nalloc) {
879  if ((dewa->dewarp = (L_DEWARP **)reallocNew((void **)&dewa->dewarp,
880  sizeof(L_DEWARP *) * dewa->nalloc,
881  size * sizeof(L_DEWARP *))) == NULL)
882  return ERROR_INT("new ptr array not returned", procName, 1);
883  if ((dewa->dewarpcache =
884  (L_DEWARP **)reallocNew((void **)&dewa->dewarpcache,
885  sizeof(L_DEWARP *) * dewa->nalloc,
886  size * sizeof(L_DEWARP *))) == NULL)
887  return ERROR_INT("new ptr cache array not returned", procName, 1);
888  dewa->nalloc = size;
889  }
890  return 0;
891 }
892 
893 
901 L_DEWARP *
903  l_int32 index)
904 {
905  PROCNAME("dewarpaGetDewarp");
906 
907  if (!dewa)
908  return (L_DEWARP *)ERROR_PTR("dewa not defined", procName, NULL);
909  if (index < 0 || index > dewa->maxpage) {
910  L_ERROR("index = %d is invalid; max index = %d\n",
911  procName, index, dewa->maxpage);
912  return NULL;
913  }
914 
915  return dewa->dewarp[index];
916 }
917 
918 
919 /*----------------------------------------------------------------------*
920  * Setting parameters to control rendering from the model *
921  *----------------------------------------------------------------------*/
965 l_ok
967  l_int32 max_linecurv,
968  l_int32 min_diff_linecurv,
969  l_int32 max_diff_linecurv,
970  l_int32 max_edgecurv,
971  l_int32 max_diff_edgecurv,
972  l_int32 max_edgeslope)
973 {
974  PROCNAME("dewarpaSetCurvatures");
975 
976  if (!dewa)
977  return ERROR_INT("dewa not defined", procName, 1);
978 
979  if (max_linecurv == -1)
980  dewa->max_linecurv = DEFAULT_MAX_LINECURV;
981  else
982  dewa->max_linecurv = L_ABS(max_linecurv);
983 
984  if (min_diff_linecurv == -1)
985  dewa->min_diff_linecurv = DEFAULT_MIN_DIFF_LINECURV;
986  else
987  dewa->min_diff_linecurv = L_ABS(min_diff_linecurv);
988 
989  if (max_diff_linecurv == -1)
990  dewa->max_diff_linecurv = DEFAULT_MAX_DIFF_LINECURV;
991  else
992  dewa->max_diff_linecurv = L_ABS(max_diff_linecurv);
993 
994  if (max_edgecurv == -1)
995  dewa->max_edgecurv = DEFAULT_MAX_EDGECURV;
996  else
997  dewa->max_edgecurv = L_ABS(max_edgecurv);
998 
999  if (max_diff_edgecurv == -1)
1000  dewa->max_diff_edgecurv = DEFAULT_MAX_DIFF_EDGECURV;
1001  else
1002  dewa->max_diff_edgecurv = L_ABS(max_diff_edgecurv);
1003 
1004  if (max_edgeslope == -1)
1005  dewa->max_edgeslope = DEFAULT_MAX_EDGESLOPE;
1006  else
1007  dewa->max_edgeslope = L_ABS(max_edgeslope);
1008 
1009  dewa->modelsready = 0; /* force validation */
1010  return 0;
1011 }
1012 
1013 
1029 l_ok
1031  l_int32 useboth)
1032 {
1033  PROCNAME("dewarpaUseBothArrays");
1034 
1035  if (!dewa)
1036  return ERROR_INT("dewa not defined", procName, 1);
1037 
1038  dewa->useboth = useboth;
1039  dewa->modelsready = 0; /* force validation */
1040  return 0;
1041 }
1042 
1043 
1068 l_ok
1070  l_int32 check_columns)
1071 {
1072  PROCNAME("dewarpaSetCheckColumns");
1073 
1074  if (!dewa)
1075  return ERROR_INT("dewa not defined", procName, 1);
1076 
1077  dewa->check_columns = check_columns;
1078  return 0;
1079 }
1080 
1081 
1094 l_ok
1096  l_int32 maxdist)
1097 {
1098  PROCNAME("dewarpaSetMaxDistance");
1099 
1100  if (!dewa)
1101  return ERROR_INT("dewa not defined", procName, 1);
1102 
1103  dewa->maxdist = maxdist;
1104  dewa->modelsready = 0; /* force validation */
1105  return 0;
1106 }
1107 
1108 
1109 /*----------------------------------------------------------------------*
1110  * Dewarp serialized I/O *
1111  *----------------------------------------------------------------------*/
1118 L_DEWARP *
1119 dewarpRead(const char *filename)
1120 {
1121 FILE *fp;
1122 L_DEWARP *dew;
1123 
1124  PROCNAME("dewarpRead");
1125 
1126  if (!filename)
1127  return (L_DEWARP *)ERROR_PTR("filename not defined", procName, NULL);
1128  if ((fp = fopenReadStream(filename)) == NULL)
1129  return (L_DEWARP *)ERROR_PTR("stream not opened", procName, NULL);
1130 
1131  if ((dew = dewarpReadStream(fp)) == NULL) {
1132  fclose(fp);
1133  return (L_DEWARP *)ERROR_PTR("dew not read", procName, NULL);
1134  }
1135 
1136  fclose(fp);
1137  return dew;
1138 }
1139 
1140 
1158 L_DEWARP *
1160 {
1161 l_int32 version, sampling, redfactor, minlines, pageno, hasref, refpage;
1162 l_int32 w, h, nx, ny, vdispar, hdispar, nlines;
1164 L_DEWARP *dew;
1165 FPIX *fpixv, *fpixh;
1166 
1167  PROCNAME("dewarpReadStream");
1168 
1169  if (!fp)
1170  return (L_DEWARP *)ERROR_PTR("stream not defined", procName, NULL);
1171 
1172  if (fscanf(fp, "\nDewarp Version %d\n", &version) != 1)
1173  return (L_DEWARP *)ERROR_PTR("not a dewarp file", procName, NULL);
1174  if (version != DEWARP_VERSION_NUMBER)
1175  return (L_DEWARP *)ERROR_PTR("invalid dewarp version", procName, NULL);
1176  if (fscanf(fp, "pageno = %d\n", &pageno) != 1)
1177  return (L_DEWARP *)ERROR_PTR("read fail for pageno", procName, NULL);
1178  if (fscanf(fp, "hasref = %d, refpage = %d\n", &hasref, &refpage) != 2)
1179  return (L_DEWARP *)ERROR_PTR("read fail for hasref, refpage",
1180  procName, NULL);
1181  if (fscanf(fp, "sampling = %d, redfactor = %d\n", &sampling, &redfactor)
1182  != 2)
1183  return (L_DEWARP *)ERROR_PTR("read fail for sampling/redfactor",
1184  procName, NULL);
1185  if (fscanf(fp, "nlines = %d, minlines = %d\n", &nlines, &minlines) != 2)
1186  return (L_DEWARP *)ERROR_PTR("read fail for nlines/minlines",
1187  procName, NULL);
1188  if (fscanf(fp, "w = %d, h = %d\n", &w, &h) != 2)
1189  return (L_DEWARP *)ERROR_PTR("read fail for w, h", procName, NULL);
1190  if (fscanf(fp, "nx = %d, ny = %d\n", &nx, &ny) != 2)
1191  return (L_DEWARP *)ERROR_PTR("read fail for nx, ny", procName, NULL);
1192  if (fscanf(fp, "vert_dispar = %d, horiz_dispar = %d\n", &vdispar, &hdispar)
1193  != 2)
1194  return (L_DEWARP *)ERROR_PTR("read fail for flags", procName, NULL);
1195  if (vdispar) {
1196  if (fscanf(fp, "min line curvature = %d, max line curvature = %d\n",
1197  &mincurv, &maxcurv) != 2)
1198  return (L_DEWARP *)ERROR_PTR("read fail for mincurv & maxcurv",
1199  procName, NULL);
1200  }
1201  if (hdispar) {
1202  if (fscanf(fp, "left edge slope = %d, right edge slope = %d\n",
1203  &leftslope, &rightslope) != 2)
1204  return (L_DEWARP *)ERROR_PTR("read fail for leftslope & rightslope",
1205  procName, NULL);
1206  if (fscanf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1207  &leftcurv, &rightcurv) != 2)
1208  return (L_DEWARP *)ERROR_PTR("read fail for leftcurv & rightcurv",
1209  procName, NULL);
1210  }
1211  if (vdispar) {
1212  if ((fpixv = fpixReadStream(fp)) == NULL)
1213  return (L_DEWARP *)ERROR_PTR("read fail for vdispar",
1214  procName, NULL);
1215  }
1216  if (hdispar) {
1217  if ((fpixh = fpixReadStream(fp)) == NULL)
1218  return (L_DEWARP *)ERROR_PTR("read fail for hdispar",
1219  procName, NULL);
1220  }
1221  getc(fp);
1222 
1223  dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
1224  dew->w = w;
1225  dew->h = h;
1226  dew->pageno = pageno;
1227  dew->sampling = sampling;
1228  dew->redfactor = redfactor;
1229  dew->minlines = minlines;
1230  dew->nlines = nlines;
1231  dew->hasref = hasref;
1232  dew->refpage = refpage;
1233  if (hasref == 0) /* any dew without a ref has an actual model */
1234  dew->vsuccess = 1;
1235  dew->nx = nx;
1236  dew->ny = ny;
1237  if (vdispar) {
1238  dew->mincurv = mincurv;
1239  dew->maxcurv = maxcurv;
1240  dew->vsuccess = 1;
1241  dew->sampvdispar = fpixv;
1242  }
1243  if (hdispar) {
1244  dew->leftslope = leftslope;
1245  dew->rightslope = rightslope;
1246  dew->leftcurv = leftcurv;
1247  dew->rightcurv = rightcurv;
1248  dew->hsuccess = 1;
1249  dew->samphdispar = fpixh;
1250  }
1251 
1252  return dew;
1253 }
1254 
1255 
1263 L_DEWARP *
1264 dewarpReadMem(const l_uint8 *data,
1265  size_t size)
1266 {
1267 FILE *fp;
1268 L_DEWARP *dew;
1269 
1270  PROCNAME("dewarpReadMem");
1271 
1272  if (!data)
1273  return (L_DEWARP *)ERROR_PTR("data not defined", procName, NULL);
1274  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1275  return (L_DEWARP *)ERROR_PTR("stream not opened", procName, NULL);
1276 
1277  dew = dewarpReadStream(fp);
1278  fclose(fp);
1279  if (!dew) L_ERROR("dew not read\n", procName);
1280  return dew;
1281 }
1282 
1283 
1291 l_ok
1292 dewarpWrite(const char *filename,
1293  L_DEWARP *dew)
1294 {
1295 l_int32 ret;
1296 FILE *fp;
1297 
1298  PROCNAME("dewarpWrite");
1299 
1300  if (!filename)
1301  return ERROR_INT("filename not defined", procName, 1);
1302  if (!dew)
1303  return ERROR_INT("dew not defined", procName, 1);
1304 
1305  if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1306  return ERROR_INT("stream not opened", procName, 1);
1307  ret = dewarpWriteStream(fp, dew);
1308  fclose(fp);
1309  if (ret)
1310  return ERROR_INT("dew not written to stream", procName, 1);
1311  return 0;
1312 }
1313 
1314 
1329 l_ok
1331  L_DEWARP *dew)
1332 {
1333 l_int32 vdispar, hdispar;
1334 
1335  PROCNAME("dewarpWriteStream");
1336 
1337  if (!fp)
1338  return ERROR_INT("stream not defined", procName, 1);
1339  if (!dew)
1340  return ERROR_INT("dew not defined", procName, 1);
1341 
1342  fprintf(fp, "\nDewarp Version %d\n", DEWARP_VERSION_NUMBER);
1343  fprintf(fp, "pageno = %d\n", dew->pageno);
1344  fprintf(fp, "hasref = %d, refpage = %d\n", dew->hasref, dew->refpage);
1345  fprintf(fp, "sampling = %d, redfactor = %d\n",
1346  dew->sampling, dew->redfactor);
1347  fprintf(fp, "nlines = %d, minlines = %d\n", dew->nlines, dew->minlines);
1348  fprintf(fp, "w = %d, h = %d\n", dew->w, dew->h);
1349  fprintf(fp, "nx = %d, ny = %d\n", dew->nx, dew->ny);
1350  vdispar = (dew->sampvdispar) ? 1 : 0;
1351  hdispar = (dew->samphdispar) ? 1 : 0;
1352  fprintf(fp, "vert_dispar = %d, horiz_dispar = %d\n", vdispar, hdispar);
1353  if (vdispar)
1354  fprintf(fp, "min line curvature = %d, max line curvature = %d\n",
1355  dew->mincurv, dew->maxcurv);
1356  if (hdispar) {
1357  fprintf(fp, "left edge slope = %d, right edge slope = %d\n",
1358  dew->leftslope, dew->rightslope);
1359  fprintf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1360  dew->leftcurv, dew->rightcurv);
1361  }
1362  if (vdispar) fpixWriteStream(fp, dew->sampvdispar);
1363  if (hdispar) fpixWriteStream(fp, dew->samphdispar);
1364  fprintf(fp, "\n");
1365 
1366  if (!vdispar)
1367  L_WARNING("no disparity arrays!\n", procName);
1368  return 0;
1369 }
1370 
1371 
1385 l_ok
1386 dewarpWriteMem(l_uint8 **pdata,
1387  size_t *psize,
1388  L_DEWARP *dew)
1389 {
1390 l_int32 ret;
1391 FILE *fp;
1392 
1393  PROCNAME("dewarpWriteMem");
1394 
1395  if (pdata) *pdata = NULL;
1396  if (psize) *psize = 0;
1397  if (!pdata)
1398  return ERROR_INT("&data not defined", procName, 1);
1399  if (!psize)
1400  return ERROR_INT("&size not defined", procName, 1);
1401  if (!dew)
1402  return ERROR_INT("dew not defined", procName, 1);
1403 
1404 #if HAVE_FMEMOPEN
1405  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1406  return ERROR_INT("stream not opened", procName, 1);
1407  ret = dewarpWriteStream(fp, dew);
1408 #else
1409  L_INFO("work-around: writing to a temp file\n", procName);
1410  #ifdef _WIN32
1411  if ((fp = fopenWriteWinTempfile()) == NULL)
1412  return ERROR_INT("tmpfile stream not opened", procName, 1);
1413  #else
1414  if ((fp = tmpfile()) == NULL)
1415  return ERROR_INT("tmpfile stream not opened", procName, 1);
1416  #endif /* _WIN32 */
1417  ret = dewarpWriteStream(fp, dew);
1418  rewind(fp);
1419  *pdata = l_binaryReadStream(fp, psize);
1420 #endif /* HAVE_FMEMOPEN */
1421  fclose(fp);
1422  return ret;
1423 }
1424 
1425 
1426 /*----------------------------------------------------------------------*
1427  * Dewarpa serialized I/O *
1428  *----------------------------------------------------------------------*/
1435 L_DEWARPA *
1436 dewarpaRead(const char *filename)
1437 {
1438 FILE *fp;
1439 L_DEWARPA *dewa;
1440 
1441  PROCNAME("dewarpaRead");
1442 
1443  if (!filename)
1444  return (L_DEWARPA *)ERROR_PTR("filename not defined", procName, NULL);
1445  if ((fp = fopenReadStream(filename)) == NULL)
1446  return (L_DEWARPA *)ERROR_PTR("stream not opened", procName, NULL);
1447 
1448  if ((dewa = dewarpaReadStream(fp)) == NULL) {
1449  fclose(fp);
1450  return (L_DEWARPA *)ERROR_PTR("dewa not read", procName, NULL);
1451  }
1452 
1453  fclose(fp);
1454  return dewa;
1455 }
1456 
1457 
1472 L_DEWARPA *
1474 {
1475 l_int32 i, version, ndewarp, maxpage;
1476 l_int32 sampling, redfactor, minlines, maxdist, useboth;
1477 l_int32 max_linecurv, min_diff_linecurv, max_diff_linecurv;
1478 l_int32 max_edgeslope, max_edgecurv, max_diff_edgecurv;
1479 L_DEWARP *dew;
1480 L_DEWARPA *dewa;
1481 NUMA *namodels;
1482 
1483  PROCNAME("dewarpaReadStream");
1484 
1485  if (!fp)
1486  return (L_DEWARPA *)ERROR_PTR("stream not defined", procName, NULL);
1487 
1488  if (fscanf(fp, "\nDewarpa Version %d\n", &version) != 1)
1489  return (L_DEWARPA *)ERROR_PTR("not a dewarpa file", procName, NULL);
1490  if (version != DEWARP_VERSION_NUMBER)
1491  return (L_DEWARPA *)ERROR_PTR("invalid dewarp version", procName, NULL);
1492 
1493  if (fscanf(fp, "ndewarp = %d, maxpage = %d\n", &ndewarp, &maxpage) != 2)
1494  return (L_DEWARPA *)ERROR_PTR("read fail for maxpage+", procName, NULL);
1495  if (fscanf(fp,
1496  "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1497  &sampling, &redfactor, &minlines, &maxdist) != 4)
1498  return (L_DEWARPA *)ERROR_PTR("read fail for 4 params", procName, NULL);
1499  if (fscanf(fp,
1500  "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1501  &max_linecurv, &min_diff_linecurv, &max_diff_linecurv) != 3)
1502  return (L_DEWARPA *)ERROR_PTR("read fail for linecurv", procName, NULL);
1503  if (fscanf(fp,
1504  "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1505  &max_edgeslope, &max_edgecurv, &max_diff_edgecurv) != 3)
1506  return (L_DEWARPA *)ERROR_PTR("read fail for edgecurv", procName, NULL);
1507  if (fscanf(fp, "fullmodel = %d\n", &useboth) != 1)
1508  return (L_DEWARPA *)ERROR_PTR("read fail for useboth", procName, NULL);
1509 
1510  dewa = dewarpaCreate(maxpage + 1, sampling, redfactor, minlines, maxdist);
1511  dewa->maxpage = maxpage;
1512  dewa->max_linecurv = max_linecurv;
1513  dewa->min_diff_linecurv = min_diff_linecurv;
1514  dewa->max_diff_linecurv = max_diff_linecurv;
1515  dewa->max_edgeslope = max_edgeslope;
1516  dewa->max_edgecurv = max_edgecurv;
1517  dewa->max_diff_edgecurv = max_diff_edgecurv;
1518  dewa->useboth = useboth;
1519  namodels = numaCreate(ndewarp);
1520  dewa->namodels = namodels;
1521  for (i = 0; i < ndewarp; i++) {
1522  if ((dew = dewarpReadStream(fp)) == NULL) {
1523  L_ERROR("read fail for dew[%d]\n", procName, i);
1524  return NULL;
1525  }
1526  dewarpaInsertDewarp(dewa, dew);
1527  numaAddNumber(namodels, dew->pageno);
1528  }
1529 
1530  /* Validate the models and insert reference models */
1532 
1533  return dewa;
1534 }
1535 
1536 
1544 L_DEWARPA *
1545 dewarpaReadMem(const l_uint8 *data,
1546  size_t size)
1547 {
1548 FILE *fp;
1549 L_DEWARPA *dewa;
1550 
1551  PROCNAME("dewarpaReadMem");
1552 
1553  if (!data)
1554  return (L_DEWARPA *)ERROR_PTR("data not defined", procName, NULL);
1555  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1556  return (L_DEWARPA *)ERROR_PTR("stream not opened", procName, NULL);
1557 
1558  dewa = dewarpaReadStream(fp);
1559  fclose(fp);
1560  if (!dewa) L_ERROR("dewa not read\n", procName);
1561  return dewa;
1562 }
1563 
1564 
1572 l_ok
1573 dewarpaWrite(const char *filename,
1574  L_DEWARPA *dewa)
1575 {
1576 l_int32 ret;
1577 FILE *fp;
1578 
1579  PROCNAME("dewarpaWrite");
1580 
1581  if (!filename)
1582  return ERROR_INT("filename not defined", procName, 1);
1583  if (!dewa)
1584  return ERROR_INT("dewa not defined", procName, 1);
1585 
1586  if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1587  return ERROR_INT("stream not opened", procName, 1);
1588  ret = dewarpaWriteStream(fp, dewa);
1589  fclose(fp);
1590  if (ret)
1591  return ERROR_INT("dewa not written to stream", procName, 1);
1592  return 0;
1593 }
1594 
1595 
1603 l_ok
1605  L_DEWARPA *dewa)
1606 {
1607 l_int32 ndewarp, i, pageno;
1608 
1609  PROCNAME("dewarpaWriteStream");
1610 
1611  if (!fp)
1612  return ERROR_INT("stream not defined", procName, 1);
1613  if (!dewa)
1614  return ERROR_INT("dewa not defined", procName, 1);
1615 
1616  /* Generate the list of page numbers for which a model exists.
1617  * Note that no attempt is made to determine if the model is
1618  * valid, because that determination is associated with
1619  * using the model to remove the warping, which typically
1620  * can happen later, after all the models have been built. */
1622  if (!dewa->namodels)
1623  return ERROR_INT("dewa->namodels not made", procName, 1);
1624  ndewarp = numaGetCount(dewa->namodels); /* with actual page models */
1625 
1626  fprintf(fp, "\nDewarpa Version %d\n", DEWARP_VERSION_NUMBER);
1627  fprintf(fp, "ndewarp = %d, maxpage = %d\n", ndewarp, dewa->maxpage);
1628  fprintf(fp, "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1630  fprintf(fp,
1631  "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1633  fprintf(fp,
1634  "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1636  fprintf(fp, "fullmodel = %d\n", dewa->useboth);
1637  for (i = 0; i < ndewarp; i++) {
1640  }
1641 
1642  return 0;
1643 }
1644 
1645 
1659 l_ok
1660 dewarpaWriteMem(l_uint8 **pdata,
1661  size_t *psize,
1662  L_DEWARPA *dewa)
1663 {
1664 l_int32 ret;
1665 FILE *fp;
1666 
1667  PROCNAME("dewarpaWriteMem");
1668 
1669  if (pdata) *pdata = NULL;
1670  if (psize) *psize = 0;
1671  if (!pdata)
1672  return ERROR_INT("&data not defined", procName, 1);
1673  if (!psize)
1674  return ERROR_INT("&size not defined", procName, 1);
1675  if (!dewa)
1676  return ERROR_INT("dewa not defined", procName, 1);
1677 
1678 #if HAVE_FMEMOPEN
1679  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1680  return ERROR_INT("stream not opened", procName, 1);
1681  ret = dewarpaWriteStream(fp, dewa);
1682 #else
1683  L_INFO("work-around: writing to a temp file\n", procName);
1684  #ifdef _WIN32
1685  if ((fp = fopenWriteWinTempfile()) == NULL)
1686  return ERROR_INT("tmpfile stream not opened", procName, 1);
1687  #else
1688  if ((fp = tmpfile()) == NULL)
1689  return ERROR_INT("tmpfile stream not opened", procName, 1);
1690  #endif /* _WIN32 */
1691  ret = dewarpaWriteStream(fp, dewa);
1692  rewind(fp);
1693  *pdata = l_binaryReadStream(fp, psize);
1694 #endif /* HAVE_FMEMOPEN */
1695  fclose(fp);
1696  return ret;
1697 }
struct FPix * sampvdispar
Definition: dewarp.h:155
l_int32 maxdist
Definition: dewarp.h:126
l_int32 nlines
Definition: dewarp.h:169
struct L_Dewarp ** dewarp
Definition: dewarp.h:117
l_int32 max_edgeslope
Definition: dewarp.h:133
struct Numa * napages
Definition: dewarp.h:121
struct L_Dewarp ** dewarpcache
Definition: dewarp.h:118
struct FPix * samphdispar
Definition: dewarp.h:156
l_int32 minlines
Definition: dewarp.h:125
l_ok dewarpaDestroyDewarp(L_DEWARPA *dewa, l_int32 pageno)
dewarpaDestroyDewarp()
Definition: dewarp1.c:762
l_int32 h
Definition: dewarp.h:164
PIX * pixacompGetPix(PIXAC *pixac, l_int32 index)
pixacompGetPix()
Definition: pixcomp.c:1201
l_int32 max_diff_linecurv
Definition: dewarp.h:131
l_int32 ny
Definition: dewarp.h:177
l_int32 pixacompGetOffset(PIXAC *pixac)
pixacompGetOffset()
Definition: pixcomp.c:1414
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:473
l_ok dewarpaWriteStream(FILE *fp, L_DEWARPA *dewa)
dewarpaWriteStream()
Definition: dewarp1.c:1604
L_DEWARP * dewarpCreate(PIX *pixs, l_int32 pageno)
dewarpCreate()
Definition: dewarp1.c:446
l_int32 max_diff_edgecurv
Definition: dewarp.h:137
l_ok fpixWriteStream(FILE *fp, FPIX *fpix)
fpixWriteStream()
Definition: fpix1.c:1847
l_int32 sampling
Definition: dewarp.h:166
struct Numa * namidys
Definition: dewarp.h:161
l_int32 leftcurv
Definition: dewarp.h:174
static l_int32 dewarpaExtendArraysToSize(L_DEWARPA *dewa, l_int32 size)
dewarpaExtendArraysToSize()
Definition: dewarp1.c:870
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1734
void dewarpDestroy(L_DEWARP **pdew)
dewarpDestroy()
Definition: dewarp1.c:509
l_ok dewarpWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARP *dew)
dewarpWriteMem()
Definition: dewarp1.c:1386
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:187
l_int32 refpage
Definition: dewarp.h:179
l_ok dewarpaWrite(const char *filename, L_DEWARPA *dewa)
dewarpaWrite()
Definition: dewarp1.c:1573
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:966
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1161
l_int32 max_linecurv
Definition: dewarp.h:127
l_int32 pageno
Definition: dewarp.h:165
void dewarpaDestroy(L_DEWARPA **pdewa)
dewarpaDestroy()
Definition: dewarp1.c:722
l_ok dewarpaSetMaxDistance(L_DEWARPA *dewa, l_int32 maxdist)
dewarpaSetMaxDistance()
Definition: dewarp1.c:1095
struct L_Dewarpa * dewa
Definition: dewarp.h:153
l_ok dewarpBuildPageModel(L_DEWARP *dew, const char *debugfile)
dewarpBuildPageModel()
Definition: dewarp2.c:148
l_ok dewarpaListPages(L_DEWARPA *dewa)
dewarpaListPages()
Definition: dewarp4.c:289
l_int32 useboth
Definition: dewarp.h:139
struct Pix * pixs
Definition: dewarp.h:154
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:727
#define DEWARP_VERSION_NUMBER
Definition: dewarp.h:110
Definition: array.h:59
l_int32 min_diff_linecurv
Definition: dewarp.h:129
l_int32 redfactor
Definition: dewarp.h:167
l_int32 minlines
Definition: dewarp.h:168
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:631
struct FPix * fullydispar
Definition: dewarp.h:160
l_ok dewarpMinimize(L_DEWARP *dew)
dewarpMinimize()
Definition: dewarp3.c:729
l_int32 nalloc
Definition: dewarp.h:115
l_ok dewarpaWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARPA *dewa)
dewarpaWriteMem()
Definition: dewarp1.c:1660
l_int32 sampling
Definition: dewarp.h:124
l_int32 modelsready
Definition: dewarp.h:144
l_int32 maxpage
Definition: dewarp.h:116
l_int32 mincurv
Definition: dewarp.h:170
L_DEWARPA * dewarpaReadMem(const l_uint8 *data, size_t size)
dewarpaReadMem()
Definition: dewarp1.c:1545
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
Definition: utils2.c:1780
l_int32 rightcurv
Definition: dewarp.h:175
L_DEWARPA * dewarpaRead(const char *filename)
dewarpaRead()
Definition: dewarp1.c:1436
struct Numa * namodels
Definition: dewarp.h:119
L_DEWARPA * dewarpaCreate(l_int32 nptrs, l_int32 sampling, l_int32 redfactor, l_int32 minlines, l_int32 maxdist)
dewarpaCreate()
Definition: dewarp1.c:572
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:515
Definition: pix.h:658
l_ok dewarpWriteStream(FILE *fp, L_DEWARP *dew)
dewarpWriteStream()
Definition: dewarp1.c:1330
L_DEWARPA * dewarpaReadStream(FILE *fp)
dewarpaReadStream()
Definition: dewarp1.c:1473
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
struct FPix * sampydispar
Definition: dewarp.h:157
L_DEWARP * dewarpReadStream(FILE *fp)
dewarpReadStream()
Definition: dewarp1.c:1159
l_int32 maxcurv
Definition: dewarp.h:171
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:360
L_DEWARP * dewarpRead(const char *filename)
dewarpRead()
Definition: dewarp1.c:1119
l_int32 vsuccess
Definition: dewarp.h:180
l_int32 max_edgecurv
Definition: dewarp.h:135
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1700
l_int32 hsuccess
Definition: dewarp.h:181
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1657
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1262
l_ok dewarpaUseBothArrays(L_DEWARPA *dewa, l_int32 useboth)
dewarpaUseBothArrays()
Definition: dewarp1.c:1030
l_int32 leftslope
Definition: dewarp.h:172
L_DEWARPA * dewarpaCreateFromPixacomp(PIXAC *pixac, l_int32 useboth, l_int32 sampling, l_int32 minlines, l_int32 maxdist)
dewarpaCreateFromPixacomp()
Definition: dewarp1.c:661
l_int32 check_columns
Definition: dewarp.h:141
l_ok dewarpaInsertDewarp(L_DEWARPA *dewa, L_DEWARP *dew)
dewarpaInsertDewarp()
Definition: dewarp1.c:805
L_DEWARP * dewarpReadMem(const l_uint8 *data, size_t size)
dewarpReadMem()
Definition: dewarp1.c:1264
struct FPix * fullvdispar
Definition: dewarp.h:158
l_ok dewarpWrite(const char *filename, L_DEWARP *dew)
dewarpWrite()
Definition: dewarp1.c:1292
l_ok dewarpaSetCheckColumns(L_DEWARPA *dewa, l_int32 check_columns)
dewarpaSetCheckColumns()
Definition: dewarp1.c:1069
Definition: pix.h:134
l_int32 redfactor
Definition: dewarp.h:123
l_int32 rightslope
Definition: dewarp.h:173
l_int32 pixacompGetCount(PIXAC *pixac)
pixacompGetCount()
Definition: pixcomp.c:1136
struct FPix * fullhdispar
Definition: dewarp.h:159
l_int32 nx
Definition: dewarp.h:176
FPIX * fpixReadStream(FILE *fp)
fpixReadStream()
Definition: fpix1.c:1735
l_int32 hasref
Definition: dewarp.h:178
l_int32 w
Definition: dewarp.h:163
void fpixDestroy(FPIX **pfpix)
fpixDestroy()
Definition: fpix1.c:373
l_ok dewarpaInsertRefModels(L_DEWARPA *dewa, l_int32 notests, l_int32 debug)
dewarpaInsertRefModels()
Definition: dewarp4.c:447
struct Numa * nacurves
Definition: dewarp.h:162
L_DEWARP * dewarpCreateRef(l_int32 pageno, l_int32 refpage)
dewarpCreateRef()
Definition: dewarp1.c:486
L_DEWARP * dewarpaGetDewarp(L_DEWARPA *dewa, l_int32 index)
dewarpaGetDewarp()
Definition: dewarp1.c:902
Definition: pix.h:582