Leptonica  1.77.0
Image processing and image analysis suite
ptabasic.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
27 
96 #include <string.h>
97 #include "allheaders.h"
98 
99 static const l_int32 INITIAL_PTR_ARRAYSIZE = 20; /* n'import quoi */
100 
101  /* Static functions */
102 static l_int32 ptaExtendArrays(PTA *pta);
103 static l_int32 ptaaExtendArray(PTAA *ptaa);
104 
105 
106 /*---------------------------------------------------------------------*
107  * Pta creation, destruction, copy, clone *
108  *---------------------------------------------------------------------*/
115 PTA *
116 ptaCreate(l_int32 n)
117 {
118 PTA *pta;
119 
120  PROCNAME("ptaCreate");
121 
122  if (n <= 0)
123  n = INITIAL_PTR_ARRAYSIZE;
124 
125  pta = (PTA *)LEPT_CALLOC(1, sizeof(PTA));
126  pta->n = 0;
127  pta->nalloc = n;
128  ptaChangeRefcount(pta, 1); /* sets to 1 */
129 
130  pta->x = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
131  pta->y = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
132  if (!pta->x || !pta->y) {
133  ptaDestroy(&pta);
134  return (PTA *)ERROR_PTR("x and y arrays not both made", procName, NULL);
135  }
136 
137  return pta;
138 }
139 
140 
148 PTA *
150  NUMA *nay)
151 {
152 l_int32 i, n;
153 l_float32 startx, delx, xval, yval;
154 PTA *pta;
155 
156  PROCNAME("ptaCreateFromNuma");
157 
158  if (!nay)
159  return (PTA *)ERROR_PTR("nay not defined", procName, NULL);
160  n = numaGetCount(nay);
161  if (nax && numaGetCount(nax) != n)
162  return (PTA *)ERROR_PTR("nax and nay sizes differ", procName, NULL);
163 
164  pta = ptaCreate(n);
165  numaGetParameters(nay, &startx, &delx);
166  for (i = 0; i < n; i++) {
167  if (nax)
168  numaGetFValue(nax, i, &xval);
169  else /* use implicit x values from nay */
170  xval = startx + i * delx;
171  numaGetFValue(nay, i, &yval);
172  ptaAddPt(pta, xval, yval);
173  }
174 
175  return pta;
176 }
177 
178 
191 void
193 {
194 PTA *pta;
195 
196  PROCNAME("ptaDestroy");
197 
198  if (ppta == NULL) {
199  L_WARNING("ptr address is NULL!\n", procName);
200  return;
201  }
202 
203  if ((pta = *ppta) == NULL)
204  return;
205 
206  ptaChangeRefcount(pta, -1);
207  if (ptaGetRefcount(pta) <= 0) {
208  LEPT_FREE(pta->x);
209  LEPT_FREE(pta->y);
210  LEPT_FREE(pta);
211  }
212 
213  *ppta = NULL;
214  return;
215 }
216 
217 
224 PTA *
226 {
227 l_int32 i;
228 l_float32 x, y;
229 PTA *npta;
230 
231  PROCNAME("ptaCopy");
232 
233  if (!pta)
234  return (PTA *)ERROR_PTR("pta not defined", procName, NULL);
235 
236  if ((npta = ptaCreate(pta->nalloc)) == NULL)
237  return (PTA *)ERROR_PTR("npta not made", procName, NULL);
238 
239  for (i = 0; i < pta->n; i++) {
240  ptaGetPt(pta, i, &x, &y);
241  ptaAddPt(npta, x, y);
242  }
243 
244  return npta;
245 }
246 
247 
256 PTA *
258  l_int32 istart,
259  l_int32 iend)
260 {
261 l_int32 n, i, x, y;
262 PTA *ptad;
263 
264  PROCNAME("ptaCopyRange");
265 
266  if (!ptas)
267  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
268  n = ptaGetCount(ptas);
269  if (istart < 0)
270  istart = 0;
271  if (istart >= n)
272  return (PTA *)ERROR_PTR("istart out of bounds", procName, NULL);
273  if (iend <= 0 || iend >= n)
274  iend = n - 1;
275  if (istart > iend)
276  return (PTA *)ERROR_PTR("istart > iend; no pts", procName, NULL);
277 
278  if ((ptad = ptaCreate(iend - istart + 1)) == NULL)
279  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
280  for (i = istart; i <= iend; i++) {
281  ptaGetIPt(ptas, i, &x, &y);
282  ptaAddPt(ptad, x, y);
283  }
284 
285  return ptad;
286 }
287 
288 
295 PTA *
297 {
298  PROCNAME("ptaClone");
299 
300  if (!pta)
301  return (PTA *)ERROR_PTR("pta not defined", procName, NULL);
302 
303  ptaChangeRefcount(pta, 1);
304  return pta;
305 }
306 
307 
319 l_ok
321 {
322  PROCNAME("ptaEmpty");
323 
324  if (!pta)
325  return ERROR_INT("ptad not defined", procName, 1);
326  pta->n = 0;
327  return 0;
328 }
329 
330 
331 /*---------------------------------------------------------------------*
332  * Pta array extension *
333  *---------------------------------------------------------------------*/
341 l_ok
343  l_float32 x,
344  l_float32 y)
345 {
346 l_int32 n;
347 
348  PROCNAME("ptaAddPt");
349 
350  if (!pta)
351  return ERROR_INT("pta not defined", procName, 1);
352 
353  n = pta->n;
354  if (n >= pta->nalloc)
355  ptaExtendArrays(pta);
356  pta->x[n] = x;
357  pta->y[n] = y;
358  pta->n++;
359 
360  return 0;
361 }
362 
363 
370 static l_int32
372 {
373  PROCNAME("ptaExtendArrays");
374 
375  if (!pta)
376  return ERROR_INT("pta not defined", procName, 1);
377 
378  if ((pta->x = (l_float32 *)reallocNew((void **)&pta->x,
379  sizeof(l_float32) * pta->nalloc,
380  2 * sizeof(l_float32) * pta->nalloc)) == NULL)
381  return ERROR_INT("new x array not returned", procName, 1);
382  if ((pta->y = (l_float32 *)reallocNew((void **)&pta->y,
383  sizeof(l_float32) * pta->nalloc,
384  2 * sizeof(l_float32) * pta->nalloc)) == NULL)
385  return ERROR_INT("new y array not returned", procName, 1);
386 
387  pta->nalloc = 2 * pta->nalloc;
388  return 0;
389 }
390 
391 
392 /*---------------------------------------------------------------------*
393  * Pta insertion and removal *
394  *---------------------------------------------------------------------*/
403 l_ok
405  l_int32 index,
406  l_int32 x,
407  l_int32 y)
408 {
409 l_int32 i, n;
410 
411  PROCNAME("ptaInsertPt");
412 
413  if (!pta)
414  return ERROR_INT("pta not defined", procName, 1);
415  n = ptaGetCount(pta);
416  if (index < 0 || index > n)
417  return ERROR_INT("index not in {0...n}", procName, 1);
418 
419  if (n > pta->nalloc)
420  ptaExtendArrays(pta);
421  pta->n++;
422  for (i = n; i > index; i--) {
423  pta->x[i] = pta->x[i - 1];
424  pta->y[i] = pta->y[i - 1];
425  }
426  pta->x[index] = x;
427  pta->y[index] = y;
428  return 0;
429 }
430 
431 
446 l_ok
448  l_int32 index)
449 {
450 l_int32 i, n;
451 
452  PROCNAME("ptaRemovePt");
453 
454  if (!pta)
455  return ERROR_INT("pta not defined", procName, 1);
456  n = ptaGetCount(pta);
457  if (index < 0 || index >= n)
458  return ERROR_INT("index not in {0...n - 1}", procName, 1);
459 
460  /* Remove the point */
461  for (i = index + 1; i < n; i++) {
462  pta->x[i - 1] = pta->x[i];
463  pta->y[i - 1] = pta->y[i];
464  }
465  pta->n--;
466  return 0;
467 }
468 
469 
470 /*---------------------------------------------------------------------*
471  * Pta accessors *
472  *---------------------------------------------------------------------*/
473 l_int32
474 ptaGetRefcount(PTA *pta)
475 {
476  PROCNAME("ptaGetRefcount");
477 
478  if (!pta)
479  return ERROR_INT("pta not defined", procName, 1);
480  return pta->refcount;
481 }
482 
483 
484 l_int32
485 ptaChangeRefcount(PTA *pta,
486  l_int32 delta)
487 {
488  PROCNAME("ptaChangeRefcount");
489 
490  if (!pta)
491  return ERROR_INT("pta not defined", procName, 1);
492  pta->refcount += delta;
493  return 0;
494 }
495 
496 
503 l_int32
505 {
506  PROCNAME("ptaGetCount");
507 
508  if (!pta)
509  return ERROR_INT("pta not defined", procName, 0);
510 
511  return pta->n;
512 }
513 
514 
524 l_ok
526  l_int32 index,
527  l_float32 *px,
528  l_float32 *py)
529 {
530  PROCNAME("ptaGetPt");
531 
532  if (px) *px = 0;
533  if (py) *py = 0;
534  if (!pta)
535  return ERROR_INT("pta not defined", procName, 1);
536  if (index < 0 || index >= pta->n)
537  return ERROR_INT("invalid index", procName, 1);
538 
539  if (px) *px = pta->x[index];
540  if (py) *py = pta->y[index];
541  return 0;
542 }
543 
544 
554 l_ok
556  l_int32 index,
557  l_int32 *px,
558  l_int32 *py)
559 {
560  PROCNAME("ptaGetIPt");
561 
562  if (px) *px = 0;
563  if (py) *py = 0;
564  if (!pta)
565  return ERROR_INT("pta not defined", procName, 1);
566  if (index < 0 || index >= pta->n)
567  return ERROR_INT("invalid index", procName, 1);
568 
569  if (px) *px = (l_int32)(pta->x[index] + 0.5);
570  if (py) *py = (l_int32)(pta->y[index] + 0.5);
571  return 0;
572 }
573 
574 
583 l_ok
585  l_int32 index,
586  l_float32 x,
587  l_float32 y)
588 {
589  PROCNAME("ptaSetPt");
590 
591  if (!pta)
592  return ERROR_INT("pta not defined", procName, 1);
593  if (index < 0 || index >= pta->n)
594  return ERROR_INT("invalid index", procName, 1);
595 
596  pta->x[index] = x;
597  pta->y[index] = y;
598  return 0;
599 }
600 
601 
615 l_ok
617  NUMA **pnax,
618  NUMA **pnay)
619 {
620 l_int32 i, n;
621 NUMA *nax, *nay;
622 
623  PROCNAME("ptaGetArrays");
624 
625  if (!pnax && !pnay)
626  return ERROR_INT("no output requested", procName, 1);
627  if (pnax) *pnax = NULL;
628  if (pnay) *pnay = NULL;
629  if (!pta)
630  return ERROR_INT("pta not defined", procName, 1);
631  if ((n = ptaGetCount(pta)) == 0)
632  return ERROR_INT("pta is empty", procName, 1);
633 
634  if (pnax) {
635  if ((nax = numaCreate(n)) == NULL)
636  return ERROR_INT("nax not made", procName, 1);
637  *pnax = nax;
638  for (i = 0; i < n; i++)
639  nax->array[i] = pta->x[i];
640  nax->n = n;
641  }
642  if (pnay) {
643  if ((nay = numaCreate(n)) == NULL)
644  return ERROR_INT("nay not made", procName, 1);
645  *pnay = nay;
646  for (i = 0; i < n; i++)
647  nay->array[i] = pta->y[i];
648  nay->n = n;
649  }
650  return 0;
651 }
652 
653 
654 /*---------------------------------------------------------------------*
655  * Pta serialized for I/O *
656  *---------------------------------------------------------------------*/
663 PTA *
664 ptaRead(const char *filename)
665 {
666 FILE *fp;
667 PTA *pta;
668 
669  PROCNAME("ptaRead");
670 
671  if (!filename)
672  return (PTA *)ERROR_PTR("filename not defined", procName, NULL);
673 
674  if ((fp = fopenReadStream(filename)) == NULL)
675  return (PTA *)ERROR_PTR("stream not opened", procName, NULL);
676  pta = ptaReadStream(fp);
677  fclose(fp);
678  if (!pta)
679  return (PTA *)ERROR_PTR("pta not read", procName, NULL);
680  return pta;
681 }
682 
683 
690 PTA *
691 ptaReadStream(FILE *fp)
692 {
693 char typestr[128]; /* hardcoded below in fscanf */
694 l_int32 i, n, ix, iy, type, version;
695 l_float32 x, y;
696 PTA *pta;
697 
698  PROCNAME("ptaReadStream");
699 
700  if (!fp)
701  return (PTA *)ERROR_PTR("stream not defined", procName, NULL);
702 
703  if (fscanf(fp, "\n Pta Version %d\n", &version) != 1)
704  return (PTA *)ERROR_PTR("not a pta file", procName, NULL);
705  if (version != PTA_VERSION_NUMBER)
706  return (PTA *)ERROR_PTR("invalid pta version", procName, NULL);
707  if (fscanf(fp, " Number of pts = %d; format = %127s\n", &n, typestr) != 2)
708  return (PTA *)ERROR_PTR("not a pta file", procName, NULL);
709  if (!strcmp(typestr, "float"))
710  type = 0;
711  else /* typestr is "integer" */
712  type = 1;
713 
714  if ((pta = ptaCreate(n)) == NULL)
715  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
716  for (i = 0; i < n; i++) {
717  if (type == 0) { /* data is float */
718  if (fscanf(fp, " (%f, %f)\n", &x, &y) != 2) {
719  ptaDestroy(&pta);
720  return (PTA *)ERROR_PTR("error reading floats", procName, NULL);
721  }
722  ptaAddPt(pta, x, y);
723  } else { /* data is integer */
724  if (fscanf(fp, " (%d, %d)\n", &ix, &iy) != 2) {
725  ptaDestroy(&pta);
726  return (PTA *)ERROR_PTR("error reading ints", procName, NULL);
727  }
728  ptaAddPt(pta, ix, iy);
729  }
730  }
731 
732  return pta;
733 }
734 
735 
743 PTA *
744 ptaReadMem(const l_uint8 *data,
745  size_t size)
746 {
747 FILE *fp;
748 PTA *pta;
749 
750  PROCNAME("ptaReadMem");
751 
752  if (!data)
753  return (PTA *)ERROR_PTR("data not defined", procName, NULL);
754  if ((fp = fopenReadFromMemory(data, size)) == NULL)
755  return (PTA *)ERROR_PTR("stream not opened", procName, NULL);
756 
757  pta = ptaReadStream(fp);
758  fclose(fp);
759  if (!pta) L_ERROR("pta not read\n", procName);
760  return pta;
761 }
762 
763 
781 l_ok
782 ptaWriteDebug(const char *filename,
783  PTA *pta,
784  l_int32 type)
785 {
786  PROCNAME("ptaWriteDebug");
787 
788  if (LeptDebugOK) {
789  return ptaWrite(filename, pta, type);
790  } else {
791  L_INFO("write to named temp file %s is disabled\n", procName, filename);
792  return 0;
793  }
794 }
795 
796 
805 l_ok
806 ptaWrite(const char *filename,
807  PTA *pta,
808  l_int32 type)
809 {
810 l_int32 ret;
811 FILE *fp;
812 
813  PROCNAME("ptaWrite");
814 
815  if (!filename)
816  return ERROR_INT("filename not defined", procName, 1);
817  if (!pta)
818  return ERROR_INT("pta not defined", procName, 1);
819 
820  if ((fp = fopenWriteStream(filename, "w")) == NULL)
821  return ERROR_INT("stream not opened", procName, 1);
822  ret = ptaWriteStream(fp, pta, type);
823  fclose(fp);
824  if (ret)
825  return ERROR_INT("pta not written to stream", procName, 1);
826  return 0;
827 }
828 
829 
838 l_ok
839 ptaWriteStream(FILE *fp,
840  PTA *pta,
841  l_int32 type)
842 {
843 l_int32 i, n, ix, iy;
844 l_float32 x, y;
845 
846  PROCNAME("ptaWriteStream");
847 
848  if (!fp)
849  return ERROR_INT("stream not defined", procName, 1);
850  if (!pta)
851  return ERROR_INT("pta not defined", procName, 1);
852 
853  n = ptaGetCount(pta);
854  fprintf(fp, "\n Pta Version %d\n", PTA_VERSION_NUMBER);
855  if (type == 0)
856  fprintf(fp, " Number of pts = %d; format = float\n", n);
857  else /* type == 1 */
858  fprintf(fp, " Number of pts = %d; format = integer\n", n);
859  for (i = 0; i < n; i++) {
860  if (type == 0) { /* data is float */
861  ptaGetPt(pta, i, &x, &y);
862  fprintf(fp, " (%f, %f)\n", x, y);
863  } else { /* data is integer */
864  ptaGetIPt(pta, i, &ix, &iy);
865  fprintf(fp, " (%d, %d)\n", ix, iy);
866  }
867  }
868 
869  return 0;
870 }
871 
872 
887 l_ok
888 ptaWriteMem(l_uint8 **pdata,
889  size_t *psize,
890  PTA *pta,
891  l_int32 type)
892 {
893 l_int32 ret;
894 FILE *fp;
895 
896  PROCNAME("ptaWriteMem");
897 
898  if (pdata) *pdata = NULL;
899  if (psize) *psize = 0;
900  if (!pdata)
901  return ERROR_INT("&data not defined", procName, 1);
902  if (!psize)
903  return ERROR_INT("&size not defined", procName, 1);
904  if (!pta)
905  return ERROR_INT("pta not defined", procName, 1);
906 
907 #if HAVE_FMEMOPEN
908  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
909  return ERROR_INT("stream not opened", procName, 1);
910  ret = ptaWriteStream(fp, pta, type);
911 #else
912  L_INFO("work-around: writing to a temp file\n", procName);
913  #ifdef _WIN32
914  if ((fp = fopenWriteWinTempfile()) == NULL)
915  return ERROR_INT("tmpfile stream not opened", procName, 1);
916  #else
917  if ((fp = tmpfile()) == NULL)
918  return ERROR_INT("tmpfile stream not opened", procName, 1);
919  #endif /* _WIN32 */
920  ret = ptaWriteStream(fp, pta, type);
921  rewind(fp);
922  *pdata = l_binaryReadStream(fp, psize);
923 #endif /* HAVE_FMEMOPEN */
924  fclose(fp);
925  return ret;
926 }
927 
928 
929 /*---------------------------------------------------------------------*
930  * PTAA creation, destruction *
931  *---------------------------------------------------------------------*/
938 PTAA *
939 ptaaCreate(l_int32 n)
940 {
941 PTAA *ptaa;
942 
943  PROCNAME("ptaaCreate");
944 
945  if (n <= 0)
946  n = INITIAL_PTR_ARRAYSIZE;
947 
948  if ((ptaa = (PTAA *)LEPT_CALLOC(1, sizeof(PTAA))) == NULL)
949  return (PTAA *)ERROR_PTR("ptaa not made", procName, NULL);
950  ptaa->n = 0;
951  ptaa->nalloc = n;
952  if ((ptaa->pta = (PTA **)LEPT_CALLOC(n, sizeof(PTA *))) == NULL) {
953  ptaaDestroy(&ptaa);
954  return (PTAA *)ERROR_PTR("pta ptrs not made", procName, NULL);
955  }
956  return ptaa;
957 }
958 
959 
966 void
968 {
969 l_int32 i;
970 PTAA *ptaa;
971 
972  PROCNAME("ptaaDestroy");
973 
974  if (pptaa == NULL) {
975  L_WARNING("ptr address is NULL!\n", procName);
976  return;
977  }
978 
979  if ((ptaa = *pptaa) == NULL)
980  return;
981 
982  for (i = 0; i < ptaa->n; i++)
983  ptaDestroy(&ptaa->pta[i]);
984  LEPT_FREE(ptaa->pta);
985 
986  LEPT_FREE(ptaa);
987  *pptaa = NULL;
988  return;
989 }
990 
991 
992 /*---------------------------------------------------------------------*
993  * PTAA array extension *
994  *---------------------------------------------------------------------*/
1003 l_ok
1005  PTA *pta,
1006  l_int32 copyflag)
1007 {
1008 l_int32 n;
1009 PTA *ptac;
1010 
1011  PROCNAME("ptaaAddPta");
1012 
1013  if (!ptaa)
1014  return ERROR_INT("ptaa not defined", procName, 1);
1015  if (!pta)
1016  return ERROR_INT("pta not defined", procName, 1);
1017 
1018  if (copyflag == L_INSERT) {
1019  ptac = pta;
1020  } else if (copyflag == L_COPY) {
1021  if ((ptac = ptaCopy(pta)) == NULL)
1022  return ERROR_INT("ptac not made", procName, 1);
1023  } else if (copyflag == L_CLONE) {
1024  if ((ptac = ptaClone(pta)) == NULL)
1025  return ERROR_INT("pta clone not made", procName, 1);
1026  } else {
1027  return ERROR_INT("invalid copyflag", procName, 1);
1028  }
1029 
1030  n = ptaaGetCount(ptaa);
1031  if (n >= ptaa->nalloc)
1032  ptaaExtendArray(ptaa);
1033  ptaa->pta[n] = ptac;
1034  ptaa->n++;
1035 
1036  return 0;
1037 }
1038 
1039 
1046 static l_int32
1048 {
1049  PROCNAME("ptaaExtendArray");
1050 
1051  if (!ptaa)
1052  return ERROR_INT("ptaa not defined", procName, 1);
1053 
1054  if ((ptaa->pta = (PTA **)reallocNew((void **)&ptaa->pta,
1055  sizeof(PTA *) * ptaa->nalloc,
1056  2 * sizeof(PTA *) * ptaa->nalloc)) == NULL)
1057  return ERROR_INT("new ptr array not returned", procName, 1);
1058 
1059  ptaa->nalloc = 2 * ptaa->nalloc;
1060  return 0;
1061 }
1062 
1063 
1064 /*---------------------------------------------------------------------*
1065  * Ptaa accessors *
1066  *---------------------------------------------------------------------*/
1073 l_int32
1075 {
1076  PROCNAME("ptaaGetCount");
1077 
1078  if (!ptaa)
1079  return ERROR_INT("ptaa not defined", procName, 0);
1080 
1081  return ptaa->n;
1082 }
1083 
1084 
1093 PTA *
1095  l_int32 index,
1096  l_int32 accessflag)
1097 {
1098  PROCNAME("ptaaGetPta");
1099 
1100  if (!ptaa)
1101  return (PTA *)ERROR_PTR("ptaa not defined", procName, NULL);
1102  if (index < 0 || index >= ptaa->n)
1103  return (PTA *)ERROR_PTR("index not valid", procName, NULL);
1104 
1105  if (accessflag == L_COPY)
1106  return ptaCopy(ptaa->pta[index]);
1107  else if (accessflag == L_CLONE)
1108  return ptaClone(ptaa->pta[index]);
1109  else
1110  return (PTA *)ERROR_PTR("invalid accessflag", procName, NULL);
1111 }
1112 
1113 
1124 l_ok
1126  l_int32 ipta,
1127  l_int32 jpt,
1128  l_float32 *px,
1129  l_float32 *py)
1130 {
1131 PTA *pta;
1132 
1133  PROCNAME("ptaaGetPt");
1134 
1135  if (px) *px = 0;
1136  if (py) *py = 0;
1137  if (!ptaa)
1138  return ERROR_INT("ptaa not defined", procName, 1);
1139  if (ipta < 0 || ipta >= ptaa->n)
1140  return ERROR_INT("index ipta not valid", procName, 1);
1141 
1142  pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1143  if (jpt < 0 || jpt >= pta->n) {
1144  ptaDestroy(&pta);
1145  return ERROR_INT("index jpt not valid", procName, 1);
1146  }
1147 
1148  ptaGetPt(pta, jpt, px, py);
1149  ptaDestroy(&pta);
1150  return 0;
1151 }
1152 
1153 
1154 /*---------------------------------------------------------------------*
1155  * Ptaa array modifiers *
1156  *---------------------------------------------------------------------*/
1164 l_ok
1166  PTA *pta)
1167 {
1168 l_int32 n, i;
1169 PTA *ptat;
1170 
1171  PROCNAME("ptaaInitFull");
1172 
1173  if (!ptaa)
1174  return ERROR_INT("ptaa not defined", procName, 1);
1175  if (!pta)
1176  return ERROR_INT("pta not defined", procName, 1);
1177 
1178  n = ptaa->nalloc;
1179  ptaa->n = n;
1180  for (i = 0; i < n; i++) {
1181  ptat = ptaCopy(pta);
1182  ptaaReplacePta(ptaa, i, ptat);
1183  }
1184  return 0;
1185 }
1186 
1187 
1203 l_ok
1205  l_int32 index,
1206  PTA *pta)
1207 {
1208 l_int32 n;
1209 
1210  PROCNAME("ptaaReplacePta");
1211 
1212  if (!ptaa)
1213  return ERROR_INT("ptaa not defined", procName, 1);
1214  if (!pta)
1215  return ERROR_INT("pta not defined", procName, 1);
1216  n = ptaaGetCount(ptaa);
1217  if (index < 0 || index >= n)
1218  return ERROR_INT("index not valid", procName, 1);
1219 
1220  ptaDestroy(&ptaa->pta[index]);
1221  ptaa->pta[index] = pta;
1222  return 0;
1223 }
1224 
1225 
1234 l_ok
1236  l_int32 ipta,
1237  l_float32 x,
1238  l_float32 y)
1239 {
1240 PTA *pta;
1241 
1242  PROCNAME("ptaaAddPt");
1243 
1244  if (!ptaa)
1245  return ERROR_INT("ptaa not defined", procName, 1);
1246  if (ipta < 0 || ipta >= ptaa->n)
1247  return ERROR_INT("index ipta not valid", procName, 1);
1248 
1249  pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1250  ptaAddPt(pta, x, y);
1251  ptaDestroy(&pta);
1252  return 0;
1253 }
1254 
1255 
1269 l_ok
1271 {
1272 l_int32 i, n, np;
1273 PTA *pta;
1274 
1275  PROCNAME("ptaaTruncate");
1276 
1277  if (!ptaa)
1278  return ERROR_INT("ptaa not defined", procName, 1);
1279 
1280  n = ptaaGetCount(ptaa);
1281  for (i = n - 1; i >= 0; i--) {
1282  pta = ptaaGetPta(ptaa, i, L_CLONE);
1283  if (!pta) {
1284  ptaa->n--;
1285  continue;
1286  }
1287  np = ptaGetCount(pta);
1288  ptaDestroy(&pta);
1289  if (np == 0) {
1290  ptaDestroy(&ptaa->pta[i]);
1291  ptaa->n--;
1292  } else {
1293  break;
1294  }
1295  }
1296  return 0;
1297 }
1298 
1299 
1300 /*---------------------------------------------------------------------*
1301  * Ptaa serialized for I/O *
1302  *---------------------------------------------------------------------*/
1309 PTAA *
1310 ptaaRead(const char *filename)
1311 {
1312 FILE *fp;
1313 PTAA *ptaa;
1314 
1315  PROCNAME("ptaaRead");
1316 
1317  if (!filename)
1318  return (PTAA *)ERROR_PTR("filename not defined", procName, NULL);
1319 
1320  if ((fp = fopenReadStream(filename)) == NULL)
1321  return (PTAA *)ERROR_PTR("stream not opened", procName, NULL);
1322  ptaa = ptaaReadStream(fp);
1323  fclose(fp);
1324  if (!ptaa)
1325  return (PTAA *)ERROR_PTR("ptaa not read", procName, NULL);
1326  return ptaa;
1327 }
1328 
1329 
1336 PTAA *
1338 {
1339 l_int32 i, n, version;
1340 PTA *pta;
1341 PTAA *ptaa;
1342 
1343  PROCNAME("ptaaReadStream");
1344 
1345  if (!fp)
1346  return (PTAA *)ERROR_PTR("stream not defined", procName, NULL);
1347 
1348  if (fscanf(fp, "\nPtaa Version %d\n", &version) != 1)
1349  return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL);
1350  if (version != PTA_VERSION_NUMBER)
1351  return (PTAA *)ERROR_PTR("invalid ptaa version", procName, NULL);
1352  if (fscanf(fp, "Number of Pta = %d\n", &n) != 1)
1353  return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL);
1354 
1355  if ((ptaa = ptaaCreate(n)) == NULL)
1356  return (PTAA *)ERROR_PTR("ptaa not made", procName, NULL);
1357  for (i = 0; i < n; i++) {
1358  if ((pta = ptaReadStream(fp)) == NULL) {
1359  ptaaDestroy(&ptaa);
1360  return (PTAA *)ERROR_PTR("error reading pta", procName, NULL);
1361  }
1362  ptaaAddPta(ptaa, pta, L_INSERT);
1363  }
1364 
1365  return ptaa;
1366 }
1367 
1368 
1376 PTAA *
1377 ptaaReadMem(const l_uint8 *data,
1378  size_t size)
1379 {
1380 FILE *fp;
1381 PTAA *ptaa;
1382 
1383  PROCNAME("ptaaReadMem");
1384 
1385  if (!data)
1386  return (PTAA *)ERROR_PTR("data not defined", procName, NULL);
1387  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1388  return (PTAA *)ERROR_PTR("stream not opened", procName, NULL);
1389 
1390  ptaa = ptaaReadStream(fp);
1391  fclose(fp);
1392  if (!ptaa) L_ERROR("ptaa not read\n", procName);
1393  return ptaa;
1394 }
1395 
1396 
1414 l_ok
1415 ptaaWriteDebug(const char *filename,
1416  PTAA *ptaa,
1417  l_int32 type)
1418 {
1419  PROCNAME("ptaaWriteDebug");
1420 
1421  if (LeptDebugOK) {
1422  return ptaaWrite(filename, ptaa, type);
1423  } else {
1424  L_INFO("write to named temp file %s is disabled\n", procName, filename);
1425  return 0;
1426  }
1427 }
1428 
1429 
1438 l_ok
1439 ptaaWrite(const char *filename,
1440  PTAA *ptaa,
1441  l_int32 type)
1442 {
1443 l_int32 ret;
1444 FILE *fp;
1445 
1446  PROCNAME("ptaaWrite");
1447 
1448  if (!filename)
1449  return ERROR_INT("filename not defined", procName, 1);
1450  if (!ptaa)
1451  return ERROR_INT("ptaa not defined", procName, 1);
1452 
1453  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1454  return ERROR_INT("stream not opened", procName, 1);
1455  ret = ptaaWriteStream(fp, ptaa, type);
1456  fclose(fp);
1457  if (ret)
1458  return ERROR_INT("ptaa not written to stream", procName, 1);
1459  return 0;
1460 }
1461 
1462 
1471 l_ok
1473  PTAA *ptaa,
1474  l_int32 type)
1475 {
1476 l_int32 i, n;
1477 PTA *pta;
1478 
1479  PROCNAME("ptaaWriteStream");
1480 
1481  if (!fp)
1482  return ERROR_INT("stream not defined", procName, 1);
1483  if (!ptaa)
1484  return ERROR_INT("ptaa not defined", procName, 1);
1485 
1486  n = ptaaGetCount(ptaa);
1487  fprintf(fp, "\nPtaa Version %d\n", PTA_VERSION_NUMBER);
1488  fprintf(fp, "Number of Pta = %d\n", n);
1489  for (i = 0; i < n; i++) {
1490  pta = ptaaGetPta(ptaa, i, L_CLONE);
1491  ptaWriteStream(fp, pta, type);
1492  ptaDestroy(&pta);
1493  }
1494 
1495  return 0;
1496 }
1497 
1498 
1513 l_ok
1514 ptaaWriteMem(l_uint8 **pdata,
1515  size_t *psize,
1516  PTAA *ptaa,
1517  l_int32 type)
1518 {
1519 l_int32 ret;
1520 FILE *fp;
1521 
1522  PROCNAME("ptaaWriteMem");
1523 
1524  if (pdata) *pdata = NULL;
1525  if (psize) *psize = 0;
1526  if (!pdata)
1527  return ERROR_INT("&data not defined", procName, 1);
1528  if (!psize)
1529  return ERROR_INT("&size not defined", procName, 1);
1530  if (!ptaa)
1531  return ERROR_INT("ptaa not defined", procName, 1);
1532 
1533 #if HAVE_FMEMOPEN
1534  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1535  return ERROR_INT("stream not opened", procName, 1);
1536  ret = ptaaWriteStream(fp, ptaa, type);
1537 #else
1538  L_INFO("work-around: writing to a temp file\n", procName);
1539  #ifdef _WIN32
1540  if ((fp = fopenWriteWinTempfile()) == NULL)
1541  return ERROR_INT("tmpfile stream not opened", procName, 1);
1542  #else
1543  if ((fp = tmpfile()) == NULL)
1544  return ERROR_INT("tmpfile stream not opened", procName, 1);
1545  #endif /* _WIN32 */
1546  ret = ptaaWriteStream(fp, ptaa, type);
1547  rewind(fp);
1548  *pdata = l_binaryReadStream(fp, psize);
1549 #endif /* HAVE_FMEMOPEN */
1550  fclose(fp);
1551  return ret;
1552 }
1553 
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:692
l_ok ptaaGetPt(PTAA *ptaa, l_int32 ipta, l_int32 jpt, l_float32 *px, l_float32 *py)
ptaaGetPt()
Definition: ptabasic.c:1125
Definition: pix.h:717
PTA * ptaCopyRange(PTA *ptas, l_int32 istart, l_int32 iend)
ptaCopyRange()
Definition: ptabasic.c:257
l_ok ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition: ptabasic.c:1235
l_ok ptaWriteStream(FILE *fp, PTA *pta, l_int32 type)
ptaWriteStream()
Definition: ptabasic.c:839
l_ok ptaInsertPt(PTA *pta, l_int32 index, l_int32 x, l_int32 y)
ptaInsertPt()
Definition: ptabasic.c:404
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:342
PTA * ptaReadMem(const l_uint8 *data, size_t size)
ptaReadMem()
Definition: ptabasic.c:744
#define PTA_VERSION_NUMBER
Definition: pix.h:514
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:116
static l_int32 ptaaExtendArray(PTAA *ptaa)
ptaaExtendArray()
Definition: ptabasic.c:1047
l_ok ptaaTruncate(PTAA *ptaa)
ptaaTruncate()
Definition: ptabasic.c:1270
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1734
l_ok ptaGetArrays(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaGetArrays()
Definition: ptabasic.c:616
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:187
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:504
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1161
PTA * ptaRead(const char *filename)
ptaRead()
Definition: ptabasic.c:664
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1094
Definition: array.h:59
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:631
l_int32 nalloc
Definition: pix.h:535
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:296
l_ok ptaaWriteStream(FILE *fp, PTAA *ptaa, l_int32 type)
ptaaWriteStream()
Definition: ptabasic.c:1472
Definition: pix.h:532
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition: ptabasic.c:967
l_float32 * array
Definition: array.h:66
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:525
PTA * ptaCreateFromNuma(NUMA *nax, NUMA *nay)
ptaCreateFromNuma()
Definition: ptabasic.c:149
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
Definition: utils2.c:1780
l_ok ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition: ptabasic.c:1165
l_ok ptaaReplacePta(PTAA *ptaa, l_int32 index, PTA *pta)
ptaaReplacePta()
Definition: ptabasic.c:1204
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:936
l_ok ptaRemovePt(PTA *pta, l_int32 index)
ptaRemovePt()
Definition: ptabasic.c:447
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:225
static l_int32 ptaExtendArrays(PTA *pta)
ptaExtendArrays()
Definition: ptabasic.c:371
l_ok ptaSetPt(PTA *pta, l_int32 index, l_float32 x, l_float32 y)
ptaSetPt()
Definition: ptabasic.c:584
l_float32 * y
Definition: pix.h:522
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1700
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_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1074
l_ok ptaEmpty(PTA *pta)
ptaEmpty()
Definition: ptabasic.c:320
l_ok ptaWrite(const char *filename, PTA *pta, l_int32 type)
ptaWrite()
Definition: ptabasic.c:806
l_int32 n
Definition: array.h:62
l_ok ptaWriteDebug(const char *filename, PTA *pta, l_int32 type)
ptaWriteDebug()
Definition: ptabasic.c:782
l_ok ptaaWriteMem(l_uint8 **pdata, size_t *psize, PTAA *ptaa, l_int32 type)
ptaaWriteMem()
Definition: ptabasic.c:1514
Definition: pix.h:718
l_ok ptaaWrite(const char *filename, PTAA *ptaa, l_int32 type)
ptaaWrite()
Definition: ptabasic.c:1439
l_int32 nalloc
Definition: pix.h:520
Definition: pix.h:719
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:192
PTAA * ptaaReadStream(FILE *fp)
ptaaReadStream()
Definition: ptabasic.c:1337
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:555
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:1004
l_ok ptaWriteMem(l_uint8 **pdata, size_t *psize, PTA *pta, l_int32 type)
ptaWriteMem()
Definition: ptabasic.c:888
PTAA * ptaaReadMem(const l_uint8 *data, size_t size)
ptaaReadMem()
Definition: ptabasic.c:1377
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:939
l_int32 n
Definition: pix.h:519
PTA * ptaReadStream(FILE *fp)
ptaReadStream()
Definition: ptabasic.c:691
Definition: pix.h:517
l_uint32 refcount
Definition: pix.h:521
l_int32 n
Definition: pix.h:534
l_ok ptaaWriteDebug(const char *filename, PTAA *ptaa, l_int32 type)
ptaaWriteDebug()
Definition: ptabasic.c:1415
PTAA * ptaaRead(const char *filename)
ptaaRead()
Definition: ptabasic.c:1310
struct Pta ** pta
Definition: pix.h:536