Leptonica  1.73
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 
95 #include <string.h>
96 #include "allheaders.h"
97 
98 static const l_int32 INITIAL_PTR_ARRAYSIZE = 20; /* n'import quoi */
99 
100  /* Static functions */
101 static l_int32 ptaExtendArrays(PTA *pta);
102 static l_int32 ptaaExtendArray(PTAA *ptaa);
103 
104 
105 /*---------------------------------------------------------------------*
106  * Pta creation, destruction, copy, clone *
107  *---------------------------------------------------------------------*/
114 PTA *
115 ptaCreate(l_int32 n)
116 {
117 PTA *pta;
118 
119  PROCNAME("ptaCreate");
120 
121  if (n <= 0)
122  n = INITIAL_PTR_ARRAYSIZE;
123 
124  pta = (PTA *)LEPT_CALLOC(1, sizeof(PTA));
125  pta->n = 0;
126  pta->nalloc = n;
127  ptaChangeRefcount(pta, 1); /* sets to 1 */
128 
129  pta->x = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
130  pta->y = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
131  if (!pta->x || !pta->y) {
132  ptaDestroy(&pta);
133  return (PTA *)ERROR_PTR("x and y arrays not both made", procName, NULL);
134  }
135 
136  return pta;
137 }
138 
139 
147 PTA *
149  NUMA *nay)
150 {
151 l_int32 i, n;
152 l_float32 startx, delx, xval, yval;
153 PTA *pta;
154 
155  PROCNAME("ptaCreateFromNuma");
156 
157  if (!nay)
158  return (PTA *)ERROR_PTR("nay not defined", procName, NULL);
159  n = numaGetCount(nay);
160  if (nax && numaGetCount(nax) != n)
161  return (PTA *)ERROR_PTR("nax and nay sizes differ", procName, NULL);
162 
163  pta = ptaCreate(n);
164  numaGetParameters(nay, &startx, &delx);
165  for (i = 0; i < n; i++) {
166  if (nax)
167  numaGetFValue(nax, i, &xval);
168  else /* use implicit x values from nay */
169  xval = startx + i * delx;
170  numaGetFValue(nay, i, &yval);
171  ptaAddPt(pta, xval, yval);
172  }
173 
174  return pta;
175 }
176 
177 
190 void
192 {
193 PTA *pta;
194 
195  PROCNAME("ptaDestroy");
196 
197  if (ppta == NULL) {
198  L_WARNING("ptr address is NULL!\n", procName);
199  return;
200  }
201 
202  if ((pta = *ppta) == NULL)
203  return;
204 
205  ptaChangeRefcount(pta, -1);
206  if (ptaGetRefcount(pta) <= 0) {
207  LEPT_FREE(pta->x);
208  LEPT_FREE(pta->y);
209  LEPT_FREE(pta);
210  }
211 
212  *ppta = NULL;
213  return;
214 }
215 
216 
223 PTA *
225 {
226 l_int32 i;
227 l_float32 x, y;
228 PTA *npta;
229 
230  PROCNAME("ptaCopy");
231 
232  if (!pta)
233  return (PTA *)ERROR_PTR("pta not defined", procName, NULL);
234 
235  if ((npta = ptaCreate(pta->nalloc)) == NULL)
236  return (PTA *)ERROR_PTR("npta not made", procName, NULL);
237 
238  for (i = 0; i < pta->n; i++) {
239  ptaGetPt(pta, i, &x, &y);
240  ptaAddPt(npta, x, y);
241  }
242 
243  return npta;
244 }
245 
246 
255 PTA *
257  l_int32 istart,
258  l_int32 iend)
259 {
260 l_int32 n, i, x, y;
261 PTA *ptad;
262 
263  PROCNAME("ptaCopyRange");
264 
265  if (!ptas)
266  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
267  n = ptaGetCount(ptas);
268  if (istart < 0)
269  istart = 0;
270  if (istart >= n)
271  return (PTA *)ERROR_PTR("istart out of bounds", procName, NULL);
272  if (iend <= 0 || iend >= n)
273  iend = n - 1;
274  if (istart > iend)
275  return (PTA *)ERROR_PTR("istart > iend; no pts", procName, NULL);
276 
277  if ((ptad = ptaCreate(iend - istart + 1)) == NULL)
278  return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
279  for (i = istart; i <= iend; i++) {
280  ptaGetIPt(ptas, i, &x, &y);
281  ptaAddPt(ptad, x, y);
282  }
283 
284  return ptad;
285 }
286 
287 
294 PTA *
296 {
297  PROCNAME("ptaClone");
298 
299  if (!pta)
300  return (PTA *)ERROR_PTR("pta not defined", procName, NULL);
301 
302  ptaChangeRefcount(pta, 1);
303  return pta;
304 }
305 
306 
318 l_int32
320 {
321  PROCNAME("ptaEmpty");
322 
323  if (!pta)
324  return ERROR_INT("ptad not defined", procName, 1);
325  pta->n = 0;
326  return 0;
327 }
328 
329 
330 /*---------------------------------------------------------------------*
331  * Pta array extension *
332  *---------------------------------------------------------------------*/
340 l_int32
342  l_float32 x,
343  l_float32 y)
344 {
345 l_int32 n;
346 
347  PROCNAME("ptaAddPt");
348 
349  if (!pta)
350  return ERROR_INT("pta not defined", procName, 1);
351 
352  n = pta->n;
353  if (n >= pta->nalloc)
354  ptaExtendArrays(pta);
355  pta->x[n] = x;
356  pta->y[n] = y;
357  pta->n++;
358 
359  return 0;
360 }
361 
362 
369 static l_int32
371 {
372  PROCNAME("ptaExtendArrays");
373 
374  if (!pta)
375  return ERROR_INT("pta not defined", procName, 1);
376 
377  if ((pta->x = (l_float32 *)reallocNew((void **)&pta->x,
378  sizeof(l_float32) * pta->nalloc,
379  2 * sizeof(l_float32) * pta->nalloc)) == NULL)
380  return ERROR_INT("new x array not returned", procName, 1);
381  if ((pta->y = (l_float32 *)reallocNew((void **)&pta->y,
382  sizeof(l_float32) * pta->nalloc,
383  2 * sizeof(l_float32) * pta->nalloc)) == NULL)
384  return ERROR_INT("new y array not returned", procName, 1);
385 
386  pta->nalloc = 2 * pta->nalloc;
387  return 0;
388 }
389 
390 
391 /*---------------------------------------------------------------------*
392  * Pta insertion and removal *
393  *---------------------------------------------------------------------*/
402 l_int32
404  l_int32 index,
405  l_int32 x,
406  l_int32 y)
407 {
408 l_int32 i, n;
409 
410  PROCNAME("ptaInsertPt");
411 
412  if (!pta)
413  return ERROR_INT("pta not defined", procName, 1);
414  n = ptaGetCount(pta);
415  if (index < 0 || index > n)
416  return ERROR_INT("index not in {0...n}", procName, 1);
417 
418  if (n > pta->nalloc)
419  ptaExtendArrays(pta);
420  pta->n++;
421  for (i = n; i > index; i--) {
422  pta->x[i] = pta->x[i - 1];
423  pta->y[i] = pta->y[i - 1];
424  }
425  pta->x[index] = x;
426  pta->y[index] = y;
427  return 0;
428 }
429 
430 
445 l_int32
447  l_int32 index)
448 {
449 l_int32 i, n;
450 
451  PROCNAME("ptaRemovePt");
452 
453  if (!pta)
454  return ERROR_INT("pta not defined", procName, 1);
455  n = ptaGetCount(pta);
456  if (index < 0 || index >= n)
457  return ERROR_INT("index not in {0...n - 1}", procName, 1);
458 
459  /* Remove the point */
460  for (i = index + 1; i < n; i++) {
461  pta->x[i - 1] = pta->x[i];
462  pta->y[i - 1] = pta->y[i];
463  }
464  pta->n--;
465  return 0;
466 }
467 
468 
469 /*---------------------------------------------------------------------*
470  * Pta accessors *
471  *---------------------------------------------------------------------*/
472 l_int32
473 ptaGetRefcount(PTA *pta)
474 {
475  PROCNAME("ptaGetRefcount");
476 
477  if (!pta)
478  return ERROR_INT("pta not defined", procName, 1);
479  return pta->refcount;
480 }
481 
482 
483 l_int32
484 ptaChangeRefcount(PTA *pta,
485  l_int32 delta)
486 {
487  PROCNAME("ptaChangeRefcount");
488 
489  if (!pta)
490  return ERROR_INT("pta not defined", procName, 1);
491  pta->refcount += delta;
492  return 0;
493 }
494 
495 
502 l_int32
504 {
505  PROCNAME("ptaGetCount");
506 
507  if (!pta)
508  return ERROR_INT("pta not defined", procName, 0);
509 
510  return pta->n;
511 }
512 
513 
523 l_int32
525  l_int32 index,
526  l_float32 *px,
527  l_float32 *py)
528 {
529  PROCNAME("ptaGetPt");
530 
531  if (px) *px = 0;
532  if (py) *py = 0;
533  if (!pta)
534  return ERROR_INT("pta not defined", procName, 1);
535  if (index < 0 || index >= pta->n)
536  return ERROR_INT("invalid index", procName, 1);
537 
538  if (px) *px = pta->x[index];
539  if (py) *py = pta->y[index];
540  return 0;
541 }
542 
543 
553 l_int32
555  l_int32 index,
556  l_int32 *px,
557  l_int32 *py)
558 {
559  PROCNAME("ptaGetIPt");
560 
561  if (px) *px = 0;
562  if (py) *py = 0;
563  if (!pta)
564  return ERROR_INT("pta not defined", procName, 1);
565  if (index < 0 || index >= pta->n)
566  return ERROR_INT("invalid index", procName, 1);
567 
568  if (px) *px = (l_int32)(pta->x[index] + 0.5);
569  if (py) *py = (l_int32)(pta->y[index] + 0.5);
570  return 0;
571 }
572 
573 
582 l_int32
584  l_int32 index,
585  l_float32 x,
586  l_float32 y)
587 {
588  PROCNAME("ptaSetPt");
589 
590  if (!pta)
591  return ERROR_INT("pta not defined", procName, 1);
592  if (index < 0 || index >= pta->n)
593  return ERROR_INT("invalid index", procName, 1);
594 
595  pta->x[index] = x;
596  pta->y[index] = y;
597  return 0;
598 }
599 
600 
614 l_int32
616  NUMA **pnax,
617  NUMA **pnay)
618 {
619 l_int32 i, n;
620 NUMA *nax, *nay;
621 
622  PROCNAME("ptaGetArrays");
623 
624  if (!pnax && !pnay)
625  return ERROR_INT("no output requested", procName, 1);
626  if (pnax) *pnax = NULL;
627  if (pnay) *pnay = NULL;
628  if (!pta)
629  return ERROR_INT("pta not defined", procName, 1);
630  if ((n = ptaGetCount(pta)) == 0)
631  return ERROR_INT("pta is empty", procName, 1);
632 
633  if (pnax) {
634  if ((nax = numaCreate(n)) == NULL)
635  return ERROR_INT("nax not made", procName, 1);
636  *pnax = nax;
637  for (i = 0; i < n; i++)
638  nax->array[i] = pta->x[i];
639  nax->n = n;
640  }
641  if (pnay) {
642  if ((nay = numaCreate(n)) == NULL)
643  return ERROR_INT("nay not made", procName, 1);
644  *pnay = nay;
645  for (i = 0; i < n; i++)
646  nay->array[i] = pta->y[i];
647  nay->n = n;
648  }
649  return 0;
650 }
651 
652 
653 /*---------------------------------------------------------------------*
654  * Pta serialized for I/O *
655  *---------------------------------------------------------------------*/
662 PTA *
663 ptaRead(const char *filename)
664 {
665 FILE *fp;
666 PTA *pta;
667 
668  PROCNAME("ptaRead");
669 
670  if (!filename)
671  return (PTA *)ERROR_PTR("filename not defined", procName, NULL);
672 
673  if ((fp = fopenReadStream(filename)) == NULL)
674  return (PTA *)ERROR_PTR("stream not opened", procName, NULL);
675  pta = ptaReadStream(fp);
676  fclose(fp);
677  if (!pta)
678  return (PTA *)ERROR_PTR("pta not read", procName, NULL);
679  return pta;
680 }
681 
682 
689 PTA *
690 ptaReadStream(FILE *fp)
691 {
692 char typestr[128]; /* hardcoded below in fscanf */
693 l_int32 i, n, ix, iy, type, version;
694 l_float32 x, y;
695 PTA *pta;
696 
697  PROCNAME("ptaReadStream");
698 
699  if (!fp)
700  return (PTA *)ERROR_PTR("stream not defined", procName, NULL);
701 
702  if (fscanf(fp, "\n Pta Version %d\n", &version) != 1)
703  return (PTA *)ERROR_PTR("not a pta file", procName, NULL);
704  if (version != PTA_VERSION_NUMBER)
705  return (PTA *)ERROR_PTR("invalid pta version", procName, NULL);
706  if (fscanf(fp, " Number of pts = %d; format = %127s\n", &n, typestr) != 2)
707  return (PTA *)ERROR_PTR("not a pta file", procName, NULL);
708  if (!strcmp(typestr, "float"))
709  type = 0;
710  else /* typestr is "integer" */
711  type = 1;
712 
713  if ((pta = ptaCreate(n)) == NULL)
714  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
715  for (i = 0; i < n; i++) {
716  if (type == 0) { /* data is float */
717  if (fscanf(fp, " (%f, %f)\n", &x, &y) != 2) {
718  ptaDestroy(&pta);
719  return (PTA *)ERROR_PTR("error reading floats", procName, NULL);
720  }
721  ptaAddPt(pta, x, y);
722  } else { /* data is integer */
723  if (fscanf(fp, " (%d, %d)\n", &ix, &iy) != 2) {
724  ptaDestroy(&pta);
725  return (PTA *)ERROR_PTR("error reading ints", procName, NULL);
726  }
727  ptaAddPt(pta, ix, iy);
728  }
729  }
730 
731  return pta;
732 }
733 
734 
742 PTA *
743 ptaReadMem(const l_uint8 *data,
744  size_t size)
745 {
746 FILE *fp;
747 PTA *pta;
748 
749  PROCNAME("ptaReadMem");
750 
751  if (!data)
752  return (PTA *)ERROR_PTR("data not defined", procName, NULL);
753  if ((fp = fopenReadFromMemory(data, size)) == NULL)
754  return (PTA *)ERROR_PTR("stream not opened", procName, NULL);
755 
756  pta = ptaReadStream(fp);
757  fclose(fp);
758  if (!pta) L_ERROR("pta not read\n", procName);
759  return pta;
760 }
761 
762 
771 l_int32
772 ptaWrite(const char *filename,
773  PTA *pta,
774  l_int32 type)
775 {
776 l_int32 ret;
777 FILE *fp;
778 
779  PROCNAME("ptaWrite");
780 
781  if (!filename)
782  return ERROR_INT("filename not defined", procName, 1);
783  if (!pta)
784  return ERROR_INT("pta not defined", procName, 1);
785 
786  if ((fp = fopenWriteStream(filename, "w")) == NULL)
787  return ERROR_INT("stream not opened", procName, 1);
788  ret = ptaWriteStream(fp, pta, type);
789  fclose(fp);
790  if (ret)
791  return ERROR_INT("pta not written to stream", procName, 1);
792  return 0;
793 }
794 
795 
804 l_int32
805 ptaWriteStream(FILE *fp,
806  PTA *pta,
807  l_int32 type)
808 {
809 l_int32 i, n, ix, iy;
810 l_float32 x, y;
811 
812  PROCNAME("ptaWriteStream");
813 
814  if (!fp)
815  return ERROR_INT("stream not defined", procName, 1);
816  if (!pta)
817  return ERROR_INT("pta not defined", procName, 1);
818 
819  n = ptaGetCount(pta);
820  fprintf(fp, "\n Pta Version %d\n", PTA_VERSION_NUMBER);
821  if (type == 0)
822  fprintf(fp, " Number of pts = %d; format = float\n", n);
823  else /* type == 1 */
824  fprintf(fp, " Number of pts = %d; format = integer\n", n);
825  for (i = 0; i < n; i++) {
826  if (type == 0) { /* data is float */
827  ptaGetPt(pta, i, &x, &y);
828  fprintf(fp, " (%f, %f)\n", x, y);
829  } else { /* data is integer */
830  ptaGetIPt(pta, i, &ix, &iy);
831  fprintf(fp, " (%d, %d)\n", ix, iy);
832  }
833  }
834 
835  return 0;
836 }
837 
838 
853 l_int32
854 ptaWriteMem(l_uint8 **pdata,
855  size_t *psize,
856  PTA *pta,
857  l_int32 type)
858 {
859 l_int32 ret;
860 FILE *fp;
861 
862  PROCNAME("ptaWriteMem");
863 
864  if (pdata) *pdata = NULL;
865  if (psize) *psize = 0;
866  if (!pdata)
867  return ERROR_INT("&data not defined", procName, 1);
868  if (!psize)
869  return ERROR_INT("&size not defined", procName, 1);
870  if (!pta)
871  return ERROR_INT("pta not defined", procName, 1);
872 
873 #if HAVE_FMEMOPEN
874  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
875  return ERROR_INT("stream not opened", procName, 1);
876  ret = ptaWriteStream(fp, pta, type);
877 #else
878  L_INFO("work-around: writing to a temp file\n", procName);
879  #ifdef _WIN32
880  if ((fp = fopenWriteWinTempfile()) == NULL)
881  return ERROR_INT("tmpfile stream not opened", procName, 1);
882  #else
883  if ((fp = tmpfile()) == NULL)
884  return ERROR_INT("tmpfile stream not opened", procName, 1);
885  #endif /* _WIN32 */
886  ret = ptaWriteStream(fp, pta, type);
887  rewind(fp);
888  *pdata = l_binaryReadStream(fp, psize);
889 #endif /* HAVE_FMEMOPEN */
890  fclose(fp);
891  return ret;
892 }
893 
894 
895 /*---------------------------------------------------------------------*
896  * PTAA creation, destruction *
897  *---------------------------------------------------------------------*/
904 PTAA *
905 ptaaCreate(l_int32 n)
906 {
907 PTAA *ptaa;
908 
909  PROCNAME("ptaaCreate");
910 
911  if (n <= 0)
912  n = INITIAL_PTR_ARRAYSIZE;
913 
914  if ((ptaa = (PTAA *)LEPT_CALLOC(1, sizeof(PTAA))) == NULL)
915  return (PTAA *)ERROR_PTR("ptaa not made", procName, NULL);
916  ptaa->n = 0;
917  ptaa->nalloc = n;
918  if ((ptaa->pta = (PTA **)LEPT_CALLOC(n, sizeof(PTA *))) == NULL) {
919  ptaaDestroy(&ptaa);
920  return (PTAA *)ERROR_PTR("pta ptrs not made", procName, NULL);
921  }
922  return ptaa;
923 }
924 
925 
932 void
934 {
935 l_int32 i;
936 PTAA *ptaa;
937 
938  PROCNAME("ptaaDestroy");
939 
940  if (pptaa == NULL) {
941  L_WARNING("ptr address is NULL!\n", procName);
942  return;
943  }
944 
945  if ((ptaa = *pptaa) == NULL)
946  return;
947 
948  for (i = 0; i < ptaa->n; i++)
949  ptaDestroy(&ptaa->pta[i]);
950  LEPT_FREE(ptaa->pta);
951 
952  LEPT_FREE(ptaa);
953  *pptaa = NULL;
954  return;
955 }
956 
957 
958 /*---------------------------------------------------------------------*
959  * PTAA array extension *
960  *---------------------------------------------------------------------*/
969 l_int32
971  PTA *pta,
972  l_int32 copyflag)
973 {
974 l_int32 n;
975 PTA *ptac;
976 
977  PROCNAME("ptaaAddPta");
978 
979  if (!ptaa)
980  return ERROR_INT("ptaa not defined", procName, 1);
981  if (!pta)
982  return ERROR_INT("pta not defined", procName, 1);
983 
984  if (copyflag == L_INSERT) {
985  ptac = pta;
986  } else if (copyflag == L_COPY) {
987  if ((ptac = ptaCopy(pta)) == NULL)
988  return ERROR_INT("ptac not made", procName, 1);
989  } else if (copyflag == L_CLONE) {
990  if ((ptac = ptaClone(pta)) == NULL)
991  return ERROR_INT("pta clone not made", procName, 1);
992  } else {
993  return ERROR_INT("invalid copyflag", procName, 1);
994  }
995 
996  n = ptaaGetCount(ptaa);
997  if (n >= ptaa->nalloc)
998  ptaaExtendArray(ptaa);
999  ptaa->pta[n] = ptac;
1000  ptaa->n++;
1001 
1002  return 0;
1003 }
1004 
1005 
1012 static l_int32
1014 {
1015  PROCNAME("ptaaExtendArray");
1016 
1017  if (!ptaa)
1018  return ERROR_INT("ptaa not defined", procName, 1);
1019 
1020  if ((ptaa->pta = (PTA **)reallocNew((void **)&ptaa->pta,
1021  sizeof(PTA *) * ptaa->nalloc,
1022  2 * sizeof(PTA *) * ptaa->nalloc)) == NULL)
1023  return ERROR_INT("new ptr array not returned", procName, 1);
1024 
1025  ptaa->nalloc = 2 * ptaa->nalloc;
1026  return 0;
1027 }
1028 
1029 
1030 /*---------------------------------------------------------------------*
1031  * Ptaa accessors *
1032  *---------------------------------------------------------------------*/
1039 l_int32
1041 {
1042  PROCNAME("ptaaGetCount");
1043 
1044  if (!ptaa)
1045  return ERROR_INT("ptaa not defined", procName, 0);
1046 
1047  return ptaa->n;
1048 }
1049 
1050 
1059 PTA *
1061  l_int32 index,
1062  l_int32 accessflag)
1063 {
1064  PROCNAME("ptaaGetPta");
1065 
1066  if (!ptaa)
1067  return (PTA *)ERROR_PTR("ptaa not defined", procName, NULL);
1068  if (index < 0 || index >= ptaa->n)
1069  return (PTA *)ERROR_PTR("index not valid", procName, NULL);
1070 
1071  if (accessflag == L_COPY)
1072  return ptaCopy(ptaa->pta[index]);
1073  else if (accessflag == L_CLONE)
1074  return ptaClone(ptaa->pta[index]);
1075  else
1076  return (PTA *)ERROR_PTR("invalid accessflag", procName, NULL);
1077 }
1078 
1079 
1090 l_int32
1092  l_int32 ipta,
1093  l_int32 jpt,
1094  l_float32 *px,
1095  l_float32 *py)
1096 {
1097 PTA *pta;
1098 
1099  PROCNAME("ptaaGetPt");
1100 
1101  if (px) *px = 0;
1102  if (py) *py = 0;
1103  if (!ptaa)
1104  return ERROR_INT("ptaa not defined", procName, 1);
1105  if (ipta < 0 || ipta >= ptaa->n)
1106  return ERROR_INT("index ipta not valid", procName, 1);
1107 
1108  pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1109  if (jpt < 0 || jpt >= pta->n) {
1110  ptaDestroy(&pta);
1111  return ERROR_INT("index jpt not valid", procName, 1);
1112  }
1113 
1114  ptaGetPt(pta, jpt, px, py);
1115  ptaDestroy(&pta);
1116  return 0;
1117 }
1118 
1119 
1120 /*---------------------------------------------------------------------*
1121  * Ptaa array modifiers *
1122  *---------------------------------------------------------------------*/
1130 l_int32
1132  PTA *pta)
1133 {
1134 l_int32 n, i;
1135 PTA *ptat;
1136 
1137  PROCNAME("ptaaInitFull");
1138 
1139  if (!ptaa)
1140  return ERROR_INT("ptaa not defined", procName, 1);
1141  if (!pta)
1142  return ERROR_INT("pta not defined", procName, 1);
1143 
1144  n = ptaa->nalloc;
1145  ptaa->n = n;
1146  for (i = 0; i < n; i++) {
1147  ptat = ptaCopy(pta);
1148  ptaaReplacePta(ptaa, i, ptat);
1149  }
1150  return 0;
1151 }
1152 
1153 
1169 l_int32
1171  l_int32 index,
1172  PTA *pta)
1173 {
1174 l_int32 n;
1175 
1176  PROCNAME("ptaaReplacePta");
1177 
1178  if (!ptaa)
1179  return ERROR_INT("ptaa not defined", procName, 1);
1180  if (!pta)
1181  return ERROR_INT("pta not defined", procName, 1);
1182  n = ptaaGetCount(ptaa);
1183  if (index < 0 || index >= n)
1184  return ERROR_INT("index not valid", procName, 1);
1185 
1186  ptaDestroy(&ptaa->pta[index]);
1187  ptaa->pta[index] = pta;
1188  return 0;
1189 }
1190 
1191 
1200 l_int32
1202  l_int32 ipta,
1203  l_float32 x,
1204  l_float32 y)
1205 {
1206 PTA *pta;
1207 
1208  PROCNAME("ptaaAddPt");
1209 
1210  if (!ptaa)
1211  return ERROR_INT("ptaa not defined", procName, 1);
1212  if (ipta < 0 || ipta >= ptaa->n)
1213  return ERROR_INT("index ipta not valid", procName, 1);
1214 
1215  pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1216  ptaAddPt(pta, x, y);
1217  ptaDestroy(&pta);
1218  return 0;
1219 }
1220 
1221 
1235 l_int32
1237 {
1238 l_int32 i, n, np;
1239 PTA *pta;
1240 
1241  PROCNAME("ptaaTruncate");
1242 
1243  if (!ptaa)
1244  return ERROR_INT("ptaa not defined", procName, 1);
1245 
1246  n = ptaaGetCount(ptaa);
1247  for (i = n - 1; i >= 0; i--) {
1248  pta = ptaaGetPta(ptaa, i, L_CLONE);
1249  if (!pta) {
1250  ptaa->n--;
1251  continue;
1252  }
1253  np = ptaGetCount(pta);
1254  ptaDestroy(&pta);
1255  if (np == 0) {
1256  ptaDestroy(&ptaa->pta[i]);
1257  ptaa->n--;
1258  } else {
1259  break;
1260  }
1261  }
1262  return 0;
1263 }
1264 
1265 
1266 /*---------------------------------------------------------------------*
1267  * Ptaa serialized for I/O *
1268  *---------------------------------------------------------------------*/
1275 PTAA *
1276 ptaaRead(const char *filename)
1277 {
1278 FILE *fp;
1279 PTAA *ptaa;
1280 
1281  PROCNAME("ptaaRead");
1282 
1283  if (!filename)
1284  return (PTAA *)ERROR_PTR("filename not defined", procName, NULL);
1285 
1286  if ((fp = fopenReadStream(filename)) == NULL)
1287  return (PTAA *)ERROR_PTR("stream not opened", procName, NULL);
1288  ptaa = ptaaReadStream(fp);
1289  fclose(fp);
1290  if (!ptaa)
1291  return (PTAA *)ERROR_PTR("ptaa not read", procName, NULL);
1292  return ptaa;
1293 }
1294 
1295 
1302 PTAA *
1304 {
1305 l_int32 i, n, version;
1306 PTA *pta;
1307 PTAA *ptaa;
1308 
1309  PROCNAME("ptaaReadStream");
1310 
1311  if (!fp)
1312  return (PTAA *)ERROR_PTR("stream not defined", procName, NULL);
1313 
1314  if (fscanf(fp, "\nPtaa Version %d\n", &version) != 1)
1315  return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL);
1316  if (version != PTA_VERSION_NUMBER)
1317  return (PTAA *)ERROR_PTR("invalid ptaa version", procName, NULL);
1318  if (fscanf(fp, "Number of Pta = %d\n", &n) != 1)
1319  return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL);
1320 
1321  if ((ptaa = ptaaCreate(n)) == NULL)
1322  return (PTAA *)ERROR_PTR("ptaa not made", procName, NULL);
1323  for (i = 0; i < n; i++) {
1324  if ((pta = ptaReadStream(fp)) == NULL) {
1325  ptaaDestroy(&ptaa);
1326  return (PTAA *)ERROR_PTR("error reading pta", procName, NULL);
1327  }
1328  ptaaAddPta(ptaa, pta, L_INSERT);
1329  }
1330 
1331  return ptaa;
1332 }
1333 
1334 
1342 PTAA *
1343 ptaaReadMem(const l_uint8 *data,
1344  size_t size)
1345 {
1346 FILE *fp;
1347 PTAA *ptaa;
1348 
1349  PROCNAME("ptaaReadMem");
1350 
1351  if (!data)
1352  return (PTAA *)ERROR_PTR("data not defined", procName, NULL);
1353  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1354  return (PTAA *)ERROR_PTR("stream not opened", procName, NULL);
1355 
1356  ptaa = ptaaReadStream(fp);
1357  fclose(fp);
1358  if (!ptaa) L_ERROR("ptaa not read\n", procName);
1359  return ptaa;
1360 }
1361 
1362 
1371 l_int32
1372 ptaaWrite(const char *filename,
1373  PTAA *ptaa,
1374  l_int32 type)
1375 {
1376 l_int32 ret;
1377 FILE *fp;
1378 
1379  PROCNAME("ptaaWrite");
1380 
1381  if (!filename)
1382  return ERROR_INT("filename not defined", procName, 1);
1383  if (!ptaa)
1384  return ERROR_INT("ptaa not defined", procName, 1);
1385 
1386  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1387  return ERROR_INT("stream not opened", procName, 1);
1388  ret = ptaaWriteStream(fp, ptaa, type);
1389  fclose(fp);
1390  if (ret)
1391  return ERROR_INT("ptaa not written to stream", procName, 1);
1392  return 0;
1393 }
1394 
1395 
1404 l_int32
1406  PTAA *ptaa,
1407  l_int32 type)
1408 {
1409 l_int32 i, n;
1410 PTA *pta;
1411 
1412  PROCNAME("ptaaWriteStream");
1413 
1414  if (!fp)
1415  return ERROR_INT("stream not defined", procName, 1);
1416  if (!ptaa)
1417  return ERROR_INT("ptaa not defined", procName, 1);
1418 
1419  n = ptaaGetCount(ptaa);
1420  fprintf(fp, "\nPtaa Version %d\n", PTA_VERSION_NUMBER);
1421  fprintf(fp, "Number of Pta = %d\n", n);
1422  for (i = 0; i < n; i++) {
1423  pta = ptaaGetPta(ptaa, i, L_CLONE);
1424  ptaWriteStream(fp, pta, type);
1425  ptaDestroy(&pta);
1426  }
1427 
1428  return 0;
1429 }
1430 
1431 
1446 l_int32
1447 ptaaWriteMem(l_uint8 **pdata,
1448  size_t *psize,
1449  PTAA *ptaa,
1450  l_int32 type)
1451 {
1452 l_int32 ret;
1453 FILE *fp;
1454 
1455  PROCNAME("ptaaWriteMem");
1456 
1457  if (pdata) *pdata = NULL;
1458  if (psize) *psize = 0;
1459  if (!pdata)
1460  return ERROR_INT("&data not defined", procName, 1);
1461  if (!psize)
1462  return ERROR_INT("&size not defined", procName, 1);
1463  if (!ptaa)
1464  return ERROR_INT("ptaa not defined", procName, 1);
1465 
1466 #if HAVE_FMEMOPEN
1467  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1468  return ERROR_INT("stream not opened", procName, 1);
1469  ret = ptaaWriteStream(fp, ptaa, type);
1470 #else
1471  L_INFO("work-around: writing to a temp file\n", procName);
1472  #ifdef _WIN32
1473  if ((fp = fopenWriteWinTempfile()) == NULL)
1474  return ERROR_INT("tmpfile stream not opened", procName, 1);
1475  #else
1476  if ((fp = tmpfile()) == NULL)
1477  return ERROR_INT("tmpfile stream not opened", procName, 1);
1478  #endif /* _WIN32 */
1479  ret = ptaaWriteStream(fp, ptaa, type);
1480  rewind(fp);
1481  *pdata = l_binaryReadStream(fp, psize);
1482 #endif /* HAVE_FMEMOPEN */
1483  fclose(fp);
1484  return ret;
1485 }
1486 
l_int32 ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition: ptabasic.c:1131
l_int32 ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:970
PTA * ptaCopyRange(PTA *ptas, l_int32 istart, l_int32 iend)
ptaCopyRange()
Definition: ptabasic.c:256
l_int32 ptaSetPt(PTA *pta, l_int32 index, l_float32 x, l_float32 y)
ptaSetPt()
Definition: ptabasic.c:583
l_int32 ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:341
PTA * ptaReadMem(const l_uint8 *data, size_t size)
ptaReadMem()
Definition: ptabasic.c:743
l_int32 ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:524
#define PTA_VERSION_NUMBER
Definition: pix.h:514
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:115
l_int32 numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:691
static l_int32 ptaaExtendArray(PTAA *ptaa)
ptaaExtendArray()
Definition: ptabasic.c:1013
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1670
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:186
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:503
l_int32 numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:935
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1102
l_int32 ptaaWriteMem(l_uint8 **pdata, size_t *psize, PTAA *ptaa, l_int32 type)
ptaaWriteMem()
Definition: ptabasic.c:1447
PTA * ptaRead(const char *filename)
ptaRead()
Definition: ptabasic.c:663
l_int32 ptaaGetPt(PTAA *ptaa, l_int32 ipta, l_int32 jpt, l_float32 *px, l_float32 *py)
ptaaGetPt()
Definition: ptabasic.c:1091
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1060
Definition: array.h:59
static const l_int32 L_INSERT
Definition: pix.h:710
l_int32 ptaWriteMem(l_uint8 **pdata, size_t *psize, PTA *pta, l_int32 type)
ptaWriteMem()
Definition: ptabasic.c:854
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
l_int32 nalloc
Definition: pix.h:535
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:295
Definition: pix.h:532
l_int32 ptaEmpty(PTA *pta)
ptaEmpty()
Definition: ptabasic.c:319
l_int32 ptaInsertPt(PTA *pta, l_int32 index, l_int32 x, l_int32 y)
ptaInsertPt()
Definition: ptabasic.c:403
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition: ptabasic.c:933
l_float32 * array
Definition: array.h:66
PTA * ptaCreateFromNuma(NUMA *nax, NUMA *nay)
ptaCreateFromNuma()
Definition: ptabasic.c:148
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
Definition: utils2.c:1716
l_int32 ptaRemovePt(PTA *pta, l_int32 index)
ptaRemovePt()
Definition: ptabasic.c:446
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:224
static l_int32 ptaExtendArrays(PTA *pta)
ptaExtendArrays()
Definition: ptabasic.c:370
l_float32 * y
Definition: pix.h:522
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1636
l_int32 ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:554
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 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1040
l_int32 n
Definition: array.h:62
Definition: pix.h:705
l_int32 nalloc
Definition: pix.h:520
Definition: pix.h:706
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
l_int32 ptaWrite(const char *filename, PTA *pta, l_int32 type)
ptaWrite()
Definition: ptabasic.c:772
l_int32 ptaaTruncate(PTAA *ptaa)
ptaaTruncate()
Definition: ptabasic.c:1236
l_int32 ptaaWriteStream(FILE *fp, PTAA *ptaa, l_int32 type)
ptaaWriteStream()
Definition: ptabasic.c:1405
l_int32 ptaaReplacePta(PTAA *ptaa, l_int32 index, PTA *pta)
ptaaReplacePta()
Definition: ptabasic.c:1170
PTAA * ptaaReadStream(FILE *fp)
ptaaReadStream()
Definition: ptabasic.c:1303
l_int32 ptaaWrite(const char *filename, PTAA *ptaa, l_int32 type)
ptaaWrite()
Definition: ptabasic.c:1372
PTAA * ptaaReadMem(const l_uint8 *data, size_t size)
ptaaReadMem()
Definition: ptabasic.c:1343
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:905
l_int32 ptaWriteStream(FILE *fp, PTA *pta, l_int32 type)
ptaWriteStream()
Definition: ptabasic.c:805
l_int32 n
Definition: pix.h:519
PTA * ptaReadStream(FILE *fp)
ptaReadStream()
Definition: ptabasic.c:690
l_int32 ptaGetArrays(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaGetArrays()
Definition: ptabasic.c:615
Definition: pix.h:517
l_uint32 refcount
Definition: pix.h:521
l_int32 n
Definition: pix.h:534
PTAA * ptaaRead(const char *filename)
ptaaRead()
Definition: ptabasic.c:1276
l_int32 ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition: ptabasic.c:1201
struct Pta ** pta
Definition: pix.h:536