Leptonica  1.73
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_int32
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_int32
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_int32
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_int32
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 
1067 l_int32
1069  l_int32 check_columns)
1070 {
1071  PROCNAME("dewarpaSetCheckColumns");
1072 
1073  if (!dewa)
1074  return ERROR_INT("dewa not defined", procName, 1);
1075 
1076  dewa->check_columns = check_columns;
1077  return 0;
1078 }
1079 
1080 
1093 l_int32
1095  l_int32 maxdist)
1096 {
1097  PROCNAME("dewarpaSetMaxDistance");
1098 
1099  if (!dewa)
1100  return ERROR_INT("dewa not defined", procName, 1);
1101 
1102  dewa->maxdist = maxdist;
1103  dewa->modelsready = 0; /* force validation */
1104  return 0;
1105 }
1106 
1107 
1108 /*----------------------------------------------------------------------*
1109  * Dewarp serialized I/O *
1110  *----------------------------------------------------------------------*/
1117 L_DEWARP *
1118 dewarpRead(const char *filename)
1119 {
1120 FILE *fp;
1121 L_DEWARP *dew;
1122 
1123  PROCNAME("dewarpRead");
1124 
1125  if (!filename)
1126  return (L_DEWARP *)ERROR_PTR("filename not defined", procName, NULL);
1127  if ((fp = fopenReadStream(filename)) == NULL)
1128  return (L_DEWARP *)ERROR_PTR("stream not opened", procName, NULL);
1129 
1130  if ((dew = dewarpReadStream(fp)) == NULL) {
1131  fclose(fp);
1132  return (L_DEWARP *)ERROR_PTR("dew not read", procName, NULL);
1133  }
1134 
1135  fclose(fp);
1136  return dew;
1137 }
1138 
1139 
1157 L_DEWARP *
1159 {
1160 l_int32 version, sampling, redfactor, minlines, pageno, hasref, refpage;
1161 l_int32 w, h, nx, ny, vdispar, hdispar, nlines;
1163 L_DEWARP *dew;
1164 FPIX *fpixv, *fpixh;
1165 
1166  PROCNAME("dewarpReadStream");
1167 
1168  if (!fp)
1169  return (L_DEWARP *)ERROR_PTR("stream not defined", procName, NULL);
1170 
1171  if (fscanf(fp, "\nDewarp Version %d\n", &version) != 1)
1172  return (L_DEWARP *)ERROR_PTR("not a dewarp file", procName, NULL);
1173  if (version != DEWARP_VERSION_NUMBER)
1174  return (L_DEWARP *)ERROR_PTR("invalid dewarp version", procName, NULL);
1175  if (fscanf(fp, "pageno = %d\n", &pageno) != 1)
1176  return (L_DEWARP *)ERROR_PTR("read fail for pageno", procName, NULL);
1177  if (fscanf(fp, "hasref = %d, refpage = %d\n", &hasref, &refpage) != 2)
1178  return (L_DEWARP *)ERROR_PTR("read fail for hasref, refpage",
1179  procName, NULL);
1180  if (fscanf(fp, "sampling = %d, redfactor = %d\n", &sampling, &redfactor)
1181  != 2)
1182  return (L_DEWARP *)ERROR_PTR("read fail for sampling/redfactor",
1183  procName, NULL);
1184  if (fscanf(fp, "nlines = %d, minlines = %d\n", &nlines, &minlines) != 2)
1185  return (L_DEWARP *)ERROR_PTR("read fail for nlines/minlines",
1186  procName, NULL);
1187  if (fscanf(fp, "w = %d, h = %d\n", &w, &h) != 2)
1188  return (L_DEWARP *)ERROR_PTR("read fail for w, h", procName, NULL);
1189  if (fscanf(fp, "nx = %d, ny = %d\n", &nx, &ny) != 2)
1190  return (L_DEWARP *)ERROR_PTR("read fail for nx, ny", procName, NULL);
1191  if (fscanf(fp, "vert_dispar = %d, horiz_dispar = %d\n", &vdispar, &hdispar)
1192  != 2)
1193  return (L_DEWARP *)ERROR_PTR("read fail for flags", procName, NULL);
1194  if (vdispar) {
1195  if (fscanf(fp, "min line curvature = %d, max line curvature = %d\n",
1196  &mincurv, &maxcurv) != 2)
1197  return (L_DEWARP *)ERROR_PTR("read fail for mincurv & maxcurv",
1198  procName, NULL);
1199  }
1200  if (hdispar) {
1201  if (fscanf(fp, "left edge slope = %d, right edge slope = %d\n",
1202  &leftslope, &rightslope) != 2)
1203  return (L_DEWARP *)ERROR_PTR("read fail for leftslope & rightslope",
1204  procName, NULL);
1205  if (fscanf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1206  &leftcurv, &rightcurv) != 2)
1207  return (L_DEWARP *)ERROR_PTR("read fail for leftcurv & rightcurv",
1208  procName, NULL);
1209  }
1210  if (vdispar) {
1211  if ((fpixv = fpixReadStream(fp)) == NULL)
1212  return (L_DEWARP *)ERROR_PTR("read fail for vdispar",
1213  procName, NULL);
1214  }
1215  if (hdispar) {
1216  if ((fpixh = fpixReadStream(fp)) == NULL)
1217  return (L_DEWARP *)ERROR_PTR("read fail for hdispar",
1218  procName, NULL);
1219  }
1220  getc(fp);
1221 
1222  dew = (L_DEWARP *)LEPT_CALLOC(1, sizeof(L_DEWARP));
1223  dew->w = w;
1224  dew->h = h;
1225  dew->pageno = pageno;
1226  dew->sampling = sampling;
1227  dew->redfactor = redfactor;
1228  dew->minlines = minlines;
1229  dew->nlines = nlines;
1230  dew->hasref = hasref;
1231  dew->refpage = refpage;
1232  if (hasref == 0) /* any dew without a ref has an actual model */
1233  dew->vsuccess = 1;
1234  dew->nx = nx;
1235  dew->ny = ny;
1236  if (vdispar) {
1237  dew->mincurv = mincurv;
1238  dew->maxcurv = maxcurv;
1239  dew->vsuccess = 1;
1240  dew->sampvdispar = fpixv;
1241  }
1242  if (hdispar) {
1243  dew->leftslope = leftslope;
1244  dew->rightslope = rightslope;
1245  dew->leftcurv = leftcurv;
1246  dew->rightcurv = rightcurv;
1247  dew->hsuccess = 1;
1248  dew->samphdispar = fpixh;
1249  }
1250 
1251  return dew;
1252 }
1253 
1254 
1262 L_DEWARP *
1263 dewarpReadMem(const l_uint8 *data,
1264  size_t size)
1265 {
1266 FILE *fp;
1267 L_DEWARP *dew;
1268 
1269  PROCNAME("dewarpReadMem");
1270 
1271  if (!data)
1272  return (L_DEWARP *)ERROR_PTR("data not defined", procName, NULL);
1273  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1274  return (L_DEWARP *)ERROR_PTR("stream not opened", procName, NULL);
1275 
1276  dew = dewarpReadStream(fp);
1277  fclose(fp);
1278  if (!dew) L_ERROR("dew not read\n", procName);
1279  return dew;
1280 }
1281 
1282 
1290 l_int32
1291 dewarpWrite(const char *filename,
1292  L_DEWARP *dew)
1293 {
1294 l_int32 ret;
1295 FILE *fp;
1296 
1297  PROCNAME("dewarpWrite");
1298 
1299  if (!filename)
1300  return ERROR_INT("filename not defined", procName, 1);
1301  if (!dew)
1302  return ERROR_INT("dew not defined", procName, 1);
1303 
1304  if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1305  return ERROR_INT("stream not opened", procName, 1);
1306  ret = dewarpWriteStream(fp, dew);
1307  fclose(fp);
1308  if (ret)
1309  return ERROR_INT("dew not written to stream", procName, 1);
1310  return 0;
1311 }
1312 
1313 
1328 l_int32
1330  L_DEWARP *dew)
1331 {
1332 l_int32 vdispar, hdispar;
1333 
1334  PROCNAME("dewarpWriteStream");
1335 
1336  if (!fp)
1337  return ERROR_INT("stream not defined", procName, 1);
1338  if (!dew)
1339  return ERROR_INT("dew not defined", procName, 1);
1340 
1341  fprintf(fp, "\nDewarp Version %d\n", DEWARP_VERSION_NUMBER);
1342  fprintf(fp, "pageno = %d\n", dew->pageno);
1343  fprintf(fp, "hasref = %d, refpage = %d\n", dew->hasref, dew->refpage);
1344  fprintf(fp, "sampling = %d, redfactor = %d\n",
1345  dew->sampling, dew->redfactor);
1346  fprintf(fp, "nlines = %d, minlines = %d\n", dew->nlines, dew->minlines);
1347  fprintf(fp, "w = %d, h = %d\n", dew->w, dew->h);
1348  fprintf(fp, "nx = %d, ny = %d\n", dew->nx, dew->ny);
1349  vdispar = (dew->sampvdispar) ? 1 : 0;
1350  hdispar = (dew->samphdispar) ? 1 : 0;
1351  fprintf(fp, "vert_dispar = %d, horiz_dispar = %d\n", vdispar, hdispar);
1352  if (vdispar)
1353  fprintf(fp, "min line curvature = %d, max line curvature = %d\n",
1354  dew->mincurv, dew->maxcurv);
1355  if (hdispar) {
1356  fprintf(fp, "left edge slope = %d, right edge slope = %d\n",
1357  dew->leftslope, dew->rightslope);
1358  fprintf(fp, "left edge curvature = %d, right edge curvature = %d\n",
1359  dew->leftcurv, dew->rightcurv);
1360  }
1361  if (vdispar) fpixWriteStream(fp, dew->sampvdispar);
1362  if (hdispar) fpixWriteStream(fp, dew->samphdispar);
1363  fprintf(fp, "\n");
1364 
1365  if (!vdispar)
1366  L_WARNING("no disparity arrays!\n", procName);
1367  return 0;
1368 }
1369 
1370 
1384 l_int32
1385 dewarpWriteMem(l_uint8 **pdata,
1386  size_t *psize,
1387  L_DEWARP *dew)
1388 {
1389 l_int32 ret;
1390 FILE *fp;
1391 
1392  PROCNAME("dewarpWriteMem");
1393 
1394  if (pdata) *pdata = NULL;
1395  if (psize) *psize = 0;
1396  if (!pdata)
1397  return ERROR_INT("&data not defined", procName, 1);
1398  if (!psize)
1399  return ERROR_INT("&size not defined", procName, 1);
1400  if (!dew)
1401  return ERROR_INT("dew not defined", procName, 1);
1402 
1403 #if HAVE_FMEMOPEN
1404  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1405  return ERROR_INT("stream not opened", procName, 1);
1406  ret = dewarpWriteStream(fp, dew);
1407 #else
1408  L_INFO("work-around: writing to a temp file\n", procName);
1409  #ifdef _WIN32
1410  if ((fp = fopenWriteWinTempfile()) == NULL)
1411  return ERROR_INT("tmpfile stream not opened", procName, 1);
1412  #else
1413  if ((fp = tmpfile()) == NULL)
1414  return ERROR_INT("tmpfile stream not opened", procName, 1);
1415  #endif /* _WIN32 */
1416  ret = dewarpWriteStream(fp, dew);
1417  rewind(fp);
1418  *pdata = l_binaryReadStream(fp, psize);
1419 #endif /* HAVE_FMEMOPEN */
1420  fclose(fp);
1421  return ret;
1422 }
1423 
1424 
1425 /*----------------------------------------------------------------------*
1426  * Dewarpa serialized I/O *
1427  *----------------------------------------------------------------------*/
1434 L_DEWARPA *
1435 dewarpaRead(const char *filename)
1436 {
1437 FILE *fp;
1438 L_DEWARPA *dewa;
1439 
1440  PROCNAME("dewarpaRead");
1441 
1442  if (!filename)
1443  return (L_DEWARPA *)ERROR_PTR("filename not defined", procName, NULL);
1444  if ((fp = fopenReadStream(filename)) == NULL)
1445  return (L_DEWARPA *)ERROR_PTR("stream not opened", procName, NULL);
1446 
1447  if ((dewa = dewarpaReadStream(fp)) == NULL) {
1448  fclose(fp);
1449  return (L_DEWARPA *)ERROR_PTR("dewa not read", procName, NULL);
1450  }
1451 
1452  fclose(fp);
1453  return dewa;
1454 }
1455 
1456 
1471 L_DEWARPA *
1473 {
1474 l_int32 i, version, ndewarp, maxpage;
1475 l_int32 sampling, redfactor, minlines, maxdist, useboth;
1476 l_int32 max_linecurv, min_diff_linecurv, max_diff_linecurv;
1477 l_int32 max_edgeslope, max_edgecurv, max_diff_edgecurv;
1478 L_DEWARP *dew;
1479 L_DEWARPA *dewa;
1480 NUMA *namodels;
1481 
1482  PROCNAME("dewarpaReadStream");
1483 
1484  if (!fp)
1485  return (L_DEWARPA *)ERROR_PTR("stream not defined", procName, NULL);
1486 
1487  if (fscanf(fp, "\nDewarpa Version %d\n", &version) != 1)
1488  return (L_DEWARPA *)ERROR_PTR("not a dewarpa file", procName, NULL);
1489  if (version != DEWARP_VERSION_NUMBER)
1490  return (L_DEWARPA *)ERROR_PTR("invalid dewarp version", procName, NULL);
1491 
1492  if (fscanf(fp, "ndewarp = %d, maxpage = %d\n", &ndewarp, &maxpage) != 2)
1493  return (L_DEWARPA *)ERROR_PTR("read fail for maxpage+", procName, NULL);
1494  if (fscanf(fp,
1495  "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1496  &sampling, &redfactor, &minlines, &maxdist) != 4)
1497  return (L_DEWARPA *)ERROR_PTR("read fail for 4 params", procName, NULL);
1498  if (fscanf(fp,
1499  "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1500  &max_linecurv, &min_diff_linecurv, &max_diff_linecurv) != 3)
1501  return (L_DEWARPA *)ERROR_PTR("read fail for linecurv", procName, NULL);
1502  if (fscanf(fp,
1503  "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1504  &max_edgeslope, &max_edgecurv, &max_diff_edgecurv) != 3)
1505  return (L_DEWARPA *)ERROR_PTR("read fail for edgecurv", procName, NULL);
1506  if (fscanf(fp, "fullmodel = %d\n", &useboth) != 1)
1507  return (L_DEWARPA *)ERROR_PTR("read fail for useboth", procName, NULL);
1508 
1509  dewa = dewarpaCreate(maxpage + 1, sampling, redfactor, minlines, maxdist);
1510  dewa->maxpage = maxpage;
1511  dewa->max_linecurv = max_linecurv;
1512  dewa->min_diff_linecurv = min_diff_linecurv;
1513  dewa->max_diff_linecurv = max_diff_linecurv;
1514  dewa->max_edgeslope = max_edgeslope;
1515  dewa->max_edgecurv = max_edgecurv;
1516  dewa->max_diff_edgecurv = max_diff_edgecurv;
1517  dewa->useboth = useboth;
1518  namodels = numaCreate(ndewarp);
1519  dewa->namodels = namodels;
1520  for (i = 0; i < ndewarp; i++) {
1521  if ((dew = dewarpReadStream(fp)) == NULL) {
1522  L_ERROR("read fail for dew[%d]\n", procName, i);
1523  return NULL;
1524  }
1525  dewarpaInsertDewarp(dewa, dew);
1526  numaAddNumber(namodels, dew->pageno);
1527  }
1528 
1529  /* Validate the models and insert reference models */
1531 
1532  return dewa;
1533 }
1534 
1535 
1543 L_DEWARPA *
1544 dewarpaReadMem(const l_uint8 *data,
1545  size_t size)
1546 {
1547 FILE *fp;
1548 L_DEWARPA *dewa;
1549 
1550  PROCNAME("dewarpaReadMem");
1551 
1552  if (!data)
1553  return (L_DEWARPA *)ERROR_PTR("data not defined", procName, NULL);
1554  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1555  return (L_DEWARPA *)ERROR_PTR("stream not opened", procName, NULL);
1556 
1557  dewa = dewarpaReadStream(fp);
1558  fclose(fp);
1559  if (!dewa) L_ERROR("dewa not read\n", procName);
1560  return dewa;
1561 }
1562 
1563 
1571 l_int32
1572 dewarpaWrite(const char *filename,
1573  L_DEWARPA *dewa)
1574 {
1575 l_int32 ret;
1576 FILE *fp;
1577 
1578  PROCNAME("dewarpaWrite");
1579 
1580  if (!filename)
1581  return ERROR_INT("filename not defined", procName, 1);
1582  if (!dewa)
1583  return ERROR_INT("dewa not defined", procName, 1);
1584 
1585  if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1586  return ERROR_INT("stream not opened", procName, 1);
1587  ret = dewarpaWriteStream(fp, dewa);
1588  fclose(fp);
1589  if (ret)
1590  return ERROR_INT("dewa not written to stream", procName, 1);
1591  return 0;
1592 }
1593 
1594 
1602 l_int32
1604  L_DEWARPA *dewa)
1605 {
1606 l_int32 ndewarp, i, pageno;
1607 
1608  PROCNAME("dewarpaWriteStream");
1609 
1610  if (!fp)
1611  return ERROR_INT("stream not defined", procName, 1);
1612  if (!dewa)
1613  return ERROR_INT("dewa not defined", procName, 1);
1614 
1615  /* Generate the list of page numbers for which a model exists.
1616  * Note that no attempt is made to determine if the model is
1617  * valid, because that determination is associated with
1618  * using the model to remove the warping, which typically
1619  * can happen later, after all the models have been built. */
1621  if (!dewa->namodels)
1622  return ERROR_INT("dewa->namodels not made", procName, 1);
1623  ndewarp = numaGetCount(dewa->namodels); /* with actual page models */
1624 
1625  fprintf(fp, "\nDewarpa Version %d\n", DEWARP_VERSION_NUMBER);
1626  fprintf(fp, "ndewarp = %d, maxpage = %d\n", ndewarp, dewa->maxpage);
1627  fprintf(fp, "sampling = %d, redfactor = %d, minlines = %d, maxdist = %d\n",
1629  fprintf(fp,
1630  "max_linecurv = %d, min_diff_linecurv = %d, max_diff_linecurv = %d\n",
1632  fprintf(fp,
1633  "max_edgeslope = %d, max_edgecurv = %d, max_diff_edgecurv = %d\n",
1635  fprintf(fp, "fullmodel = %d\n", dewa->useboth);
1636  for (i = 0; i < ndewarp; i++) {
1639  }
1640 
1641  return 0;
1642 }
1643 
1644 
1658 l_int32
1659 dewarpaWriteMem(l_uint8 **pdata,
1660  size_t *psize,
1661  L_DEWARPA *dewa)
1662 {
1663 l_int32 ret;
1664 FILE *fp;
1665 
1666  PROCNAME("dewarpaWriteMem");
1667 
1668  if (pdata) *pdata = NULL;
1669  if (psize) *psize = 0;
1670  if (!pdata)
1671  return ERROR_INT("&data not defined", procName, 1);
1672  if (!psize)
1673  return ERROR_INT("&size not defined", procName, 1);
1674  if (!dewa)
1675  return ERROR_INT("dewa not defined", procName, 1);
1676 
1677 #if HAVE_FMEMOPEN
1678  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1679  return ERROR_INT("stream not opened", procName, 1);
1680  ret = dewarpaWriteStream(fp, dewa);
1681 #else
1682  L_INFO("work-around: writing to a temp file\n", procName);
1683  #ifdef _WIN32
1684  if ((fp = fopenWriteWinTempfile()) == NULL)
1685  return ERROR_INT("tmpfile stream not opened", procName, 1);
1686  #else
1687  if ((fp = tmpfile()) == NULL)
1688  return ERROR_INT("tmpfile stream not opened", procName, 1);
1689  #endif /* _WIN32 */
1690  ret = dewarpaWriteStream(fp, dewa);
1691  rewind(fp);
1692  *pdata = l_binaryReadStream(fp, psize);
1693 #endif /* HAVE_FMEMOPEN */
1694  fclose(fp);
1695  return ret;
1696 }
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 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
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_int32 h
Definition: dewarp.h:164
PIX * pixacompGetPix(PIXAC *pixac, l_int32 index)
pixacompGetPix()
Definition: pixcomp.c:1159
l_int32 numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:472
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:1369
l_int32 dewarpaListPages(L_DEWARPA *dewa)
dewarpaListPages()
Definition: dewarp4.c:289
l_int32 dewarpaInsertDewarp(L_DEWARPA *dewa, L_DEWARP *dew)
dewarpaInsertDewarp()
Definition: dewarp1.c:805
L_DEWARP * dewarpCreate(PIX *pixs, l_int32 pageno)
dewarpCreate()
Definition: dewarp1.c:446
l_int32 max_diff_edgecurv
Definition: dewarp.h:137
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:1670
void dewarpDestroy(L_DEWARP **pdew)
dewarpDestroy()
Definition: dewarp1.c:509
l_int32 dewarpWriteStream(FILE *fp, L_DEWARP *dew)
dewarpWriteStream()
Definition: dewarp1.c:1329
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:186
l_int32 refpage
Definition: dewarp.h:179
l_int32 dewarpaWrite(const char *filename, L_DEWARPA *dewa)
dewarpaWrite()
Definition: dewarp1.c:1572
l_int32 dewarpaSetMaxDistance(L_DEWARPA *dewa, l_int32 maxdist)
dewarpaSetMaxDistance()
Definition: dewarp1.c:1094
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1102
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
struct L_Dewarpa * dewa
Definition: dewarp.h:153
l_int32 dewarpaInsertRefModels(L_DEWARPA *dewa, l_int32 notests, l_int32 debug)
dewarpaInsertRefModels()
Definition: dewarp4.c:447
l_int32 dewarpWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARP *dew)
dewarpWriteMem()
Definition: dewarp1.c:1385
l_int32 useboth
Definition: dewarp.h:139
struct Pix * pixs
Definition: dewarp.h:154
l_int32 dewarpaSetCheckColumns(L_DEWARPA *dewa, l_int32 check_columns)
dewarpaSetCheckColumns()
Definition: dewarp1.c:1068
#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:630
struct FPix * fullydispar
Definition: dewarp.h:160
l_int32 nalloc
Definition: dewarp.h:115
l_int32 dewarpaWriteStream(FILE *fp, L_DEWARPA *dewa)
dewarpaWriteStream()
Definition: dewarp1.c:1603
l_int32 dewarpMinimize(L_DEWARP *dew)
dewarpMinimize()
Definition: dewarp3.c:729
l_int32 sampling
Definition: dewarp.h:124
l_int32 dewarpaUseBothArrays(L_DEWARPA *dewa, l_int32 useboth)
dewarpaUseBothArrays()
Definition: dewarp1.c:1030
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:1544
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
Definition: utils2.c:1716
l_int32 rightcurv
Definition: dewarp.h:175
L_DEWARPA * dewarpaRead(const char *filename)
dewarpaRead()
Definition: dewarp1.c:1435
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:517
Definition: pix.h:658
L_DEWARPA * dewarpaReadStream(FILE *fp)
dewarpaReadStream()
Definition: dewarp1.c:1472
l_int32 fpixWriteStream(FILE *fp, FPIX *fpix)
fpixWriteStream()
Definition: fpix1.c:1838
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:545
struct FPix * sampydispar
Definition: dewarp.h:157
L_DEWARP * dewarpReadStream(FILE *fp)
dewarpReadStream()
Definition: dewarp1.c:1158
l_int32 maxcurv
Definition: dewarp.h:171
l_int32 dewarpWrite(const char *filename, L_DEWARP *dew)
dewarpWrite()
Definition: dewarp1.c:1291
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:359
L_DEWARP * dewarpRead(const char *filename)
dewarpRead()
Definition: dewarp1.c:1118
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:1636
l_int32 hsuccess
Definition: dewarp.h:181
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1593
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1200
l_int32 dewarpaWriteMem(l_uint8 **pdata, size_t *psize, L_DEWARPA *dewa)
dewarpaWriteMem()
Definition: dewarp1.c:1659
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_DEWARP * dewarpReadMem(const l_uint8 *data, size_t size)
dewarpReadMem()
Definition: dewarp1.c:1263
l_int32 dewarpaDestroyDewarp(L_DEWARPA *dewa, l_int32 pageno)
dewarpaDestroyDewarp()
Definition: dewarp1.c:762
struct FPix * fullvdispar
Definition: dewarp.h:158
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:1094
l_int32 numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:726
struct FPix * fullhdispar
Definition: dewarp.h:159
l_int32 dewarpBuildPageModel(L_DEWARP *dew, const char *debugfile)
dewarpBuildPageModel()
Definition: dewarp2.c:148
l_int32 nx
Definition: dewarp.h:176
FPIX * fpixReadStream(FILE *fp)
fpixReadStream()
Definition: fpix1.c:1726
l_int32 hasref
Definition: dewarp.h:178
l_int32 w
Definition: dewarp.h:163
void fpixDestroy(FPIX **pfpix)
fpixDestroy()
Definition: fpix1.c:370
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