Leptonica 1.82.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
95#ifdef HAVE_CONFIG_H
96#include <config_auto.h>
97#endif /* HAVE_CONFIG_H */
98
99#include <string.h>
100#include "allheaders.h"
101
102static const l_uint32 MaxArraySize = 100000000; /* 100 million */
103static const l_uint32 MaxPtrArraySize = 10000000; /* 10 million */
104static const l_int32 InitialArraySize = 50;
106 /* Static functions */
107static l_int32 ptaExtendArrays(PTA *pta);
108static l_int32 ptaaExtendArray(PTAA *ptaa);
109
110/*---------------------------------------------------------------------*
111 * Pta creation, destruction, copy, clone *
112 *---------------------------------------------------------------------*/
119PTA *
120ptaCreate(l_int32 n)
121{
122PTA *pta;
123
124 PROCNAME("ptaCreate");
125
126 if (n <= 0 || n > MaxArraySize)
128
129 pta = (PTA *)LEPT_CALLOC(1, sizeof(PTA));
130 pta->n = 0;
131 pta->nalloc = n;
132 ptaChangeRefcount(pta, 1); /* sets to 1 */
133 pta->x = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
134 pta->y = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
135 if (!pta->x || !pta->y) {
136 ptaDestroy(&pta);
137 return (PTA *)ERROR_PTR("x and y arrays not both made", procName, NULL);
138 }
139
140 return pta;
141}
142
143
151PTA *
153 NUMA *nay)
154{
155l_int32 i, n;
156l_float32 startx, delx, xval, yval;
157PTA *pta;
158
159 PROCNAME("ptaCreateFromNuma");
160
161 if (!nay)
162 return (PTA *)ERROR_PTR("nay not defined", procName, NULL);
163 n = numaGetCount(nay);
164 if (nax && numaGetCount(nax) != n)
165 return (PTA *)ERROR_PTR("nax and nay sizes differ", procName, NULL);
166
167 pta = ptaCreate(n);
168 numaGetParameters(nay, &startx, &delx);
169 for (i = 0; i < n; i++) {
170 if (nax)
171 numaGetFValue(nax, i, &xval);
172 else /* use implicit x values from nay */
173 xval = startx + i * delx;
174 numaGetFValue(nay, i, &yval);
175 ptaAddPt(pta, xval, yval);
176 }
177
178 return pta;
179}
180
181
194void
196{
197PTA *pta;
198
199 PROCNAME("ptaDestroy");
200
201 if (ppta == NULL) {
202 L_WARNING("ptr address is NULL!\n", procName);
203 return;
204 }
205
206 if ((pta = *ppta) == NULL)
207 return;
208
209 ptaChangeRefcount(pta, -1);
210 if (ptaGetRefcount(pta) <= 0) {
211 LEPT_FREE(pta->x);
212 LEPT_FREE(pta->y);
213 LEPT_FREE(pta);
214 }
215 *ppta = NULL;
216}
217
218
225PTA *
227{
228l_int32 i;
229l_float32 x, y;
230PTA *npta;
231
232 PROCNAME("ptaCopy");
233
234 if (!pta)
235 return (PTA *)ERROR_PTR("pta not defined", procName, NULL);
236
237 if ((npta = ptaCreate(pta->nalloc)) == NULL)
238 return (PTA *)ERROR_PTR("npta not made", procName, NULL);
239
240 for (i = 0; i < pta->n; i++) {
241 ptaGetPt(pta, i, &x, &y);
242 ptaAddPt(npta, x, y);
243 }
244
245 return npta;
246}
247
248
257PTA *
259 l_int32 istart,
260 l_int32 iend)
261{
262l_int32 n, i, x, y;
263PTA *ptad;
264
265 PROCNAME("ptaCopyRange");
266
267 if (!ptas)
268 return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
269 n = ptaGetCount(ptas);
270 if (istart < 0)
271 istart = 0;
272 if (istart >= n)
273 return (PTA *)ERROR_PTR("istart out of bounds", procName, NULL);
274 if (iend <= 0 || iend >= n)
275 iend = n - 1;
276 if (istart > iend)
277 return (PTA *)ERROR_PTR("istart > iend; no pts", procName, NULL);
278
279 if ((ptad = ptaCreate(iend - istart + 1)) == NULL)
280 return (PTA *)ERROR_PTR("ptad not made", procName, NULL);
281 for (i = istart; i <= iend; i++) {
282 ptaGetIPt(ptas, i, &x, &y);
283 ptaAddPt(ptad, x, y);
284 }
285
286 return ptad;
287}
288
289
296PTA *
298{
299 PROCNAME("ptaClone");
300
301 if (!pta)
302 return (PTA *)ERROR_PTR("pta not defined", procName, NULL);
303
304 ptaChangeRefcount(pta, 1);
305 return pta;
306}
307
308
320l_ok
322{
323 PROCNAME("ptaEmpty");
324
325 if (!pta)
326 return ERROR_INT("ptad not defined", procName, 1);
327 pta->n = 0;
328 return 0;
329}
330
331
332/*---------------------------------------------------------------------*
333 * Pta array extension *
334 *---------------------------------------------------------------------*/
342l_ok
344 l_float32 x,
345 l_float32 y)
346{
347l_int32 n;
348
349 PROCNAME("ptaAddPt");
350
351 if (!pta)
352 return ERROR_INT("pta not defined", procName, 1);
353
354 n = pta->n;
355 if (n >= pta->nalloc) {
356 if (ptaExtendArrays(pta))
357 return ERROR_INT("extension failed", procName, 1);
358 }
359
360 pta->x[n] = x;
361 pta->y[n] = y;
362 pta->n++;
363 return 0;
364}
365
366
379static l_int32
381{
382size_t oldsize, newsize;
383
384 PROCNAME("ptaExtendArrays");
385
386 if (!pta)
387 return ERROR_INT("pta not defined", procName, 1);
388 if (pta->nalloc > MaxArraySize)
389 return ERROR_INT("pta at maximum size; can't extend", procName, 1);
390 oldsize = 4 * pta->nalloc;
391 if (pta->nalloc > MaxArraySize / 2) {
392 newsize = 4 * MaxArraySize;
393 pta->nalloc = MaxArraySize;
394 } else {
395 newsize = 2 * oldsize;
396 pta->nalloc *= 2;
397 }
398 if ((pta->x = (l_float32 *)reallocNew((void **)&pta->x,
399 oldsize, newsize)) == NULL)
400 return ERROR_INT("new x array not returned", procName, 1);
401 if ((pta->y = (l_float32 *)reallocNew((void **)&pta->y,
402 oldsize, newsize)) == NULL)
403 return ERROR_INT("new y array not returned", procName, 1);
404
405 return 0;
406}
407
408
409/*---------------------------------------------------------------------*
410 * Pta insertion and removal *
411 *---------------------------------------------------------------------*/
420l_ok
422 l_int32 index,
423 l_int32 x,
424 l_int32 y)
425{
426l_int32 i, n;
427
428 PROCNAME("ptaInsertPt");
429
430 if (!pta)
431 return ERROR_INT("pta not defined", procName, 1);
432 n = ptaGetCount(pta);
433 if (index < 0 || index > n) {
434 L_ERROR("index %d not in [0,...,%d]\n", procName, index, n);
435 return 1;
436 }
437
438 if (n > pta->nalloc) {
439 if (ptaExtendArrays(pta))
440 return ERROR_INT("extension failed", procName, 1);
441 }
442 pta->n++;
443 for (i = n; i > index; i--) {
444 pta->x[i] = pta->x[i - 1];
445 pta->y[i] = pta->y[i - 1];
446 }
447 pta->x[index] = x;
448 pta->y[index] = y;
449 return 0;
450}
451
452
467l_ok
469 l_int32 index)
470{
471l_int32 i, n;
472
473 PROCNAME("ptaRemovePt");
474
475 if (!pta)
476 return ERROR_INT("pta not defined", procName, 1);
477 n = ptaGetCount(pta);
478 if (index < 0 || index >= n) {
479 L_ERROR("index %d not in [0,...,%d]\n", procName, index, n - 1);
480 return 1;
481 }
482
483 /* Remove the point */
484 for (i = index + 1; i < n; i++) {
485 pta->x[i - 1] = pta->x[i];
486 pta->y[i - 1] = pta->y[i];
487 }
488 pta->n--;
489 return 0;
490}
491
492
493/*---------------------------------------------------------------------*
494 * Pta accessors *
495 *---------------------------------------------------------------------*/
496l_int32
497ptaGetRefcount(PTA *pta)
498{
499 PROCNAME("ptaGetRefcount");
500
501 if (!pta)
502 return ERROR_INT("pta not defined", procName, 1);
503 return pta->refcount;
504}
505
506
507l_int32
508ptaChangeRefcount(PTA *pta,
509 l_int32 delta)
510{
511 PROCNAME("ptaChangeRefcount");
512
513 if (!pta)
514 return ERROR_INT("pta not defined", procName, 1);
515 pta->refcount += delta;
516 return 0;
517}
518
519
526l_int32
528{
529 PROCNAME("ptaGetCount");
530
531 if (!pta)
532 return ERROR_INT("pta not defined", procName, 0);
533
534 return pta->n;
535}
536
537
547l_ok
549 l_int32 index,
550 l_float32 *px,
551 l_float32 *py)
552{
553 PROCNAME("ptaGetPt");
554
555 if (px) *px = 0;
556 if (py) *py = 0;
557 if (!pta)
558 return ERROR_INT("pta not defined", procName, 1);
559 if (index < 0 || index >= pta->n)
560 return ERROR_INT("invalid index", procName, 1);
561
562 if (px) *px = pta->x[index];
563 if (py) *py = pta->y[index];
564 return 0;
565}
566
567
577l_ok
579 l_int32 index,
580 l_int32 *px,
581 l_int32 *py)
582{
583 PROCNAME("ptaGetIPt");
584
585 if (px) *px = 0;
586 if (py) *py = 0;
587 if (!pta)
588 return ERROR_INT("pta not defined", procName, 1);
589 if (index < 0 || index >= pta->n)
590 return ERROR_INT("invalid index", procName, 1);
591
592 if (px) *px = (l_int32)(pta->x[index] + 0.5);
593 if (py) *py = (l_int32)(pta->y[index] + 0.5);
594 return 0;
595}
596
597
606l_ok
608 l_int32 index,
609 l_float32 x,
610 l_float32 y)
611{
612 PROCNAME("ptaSetPt");
613
614 if (!pta)
615 return ERROR_INT("pta not defined", procName, 1);
616 if (index < 0 || index >= pta->n)
617 return ERROR_INT("invalid index", procName, 1);
618
619 pta->x[index] = x;
620 pta->y[index] = y;
621 return 0;
622}
623
624
638l_ok
640 NUMA **pnax,
641 NUMA **pnay)
642{
643l_int32 i, n;
644NUMA *nax, *nay;
645
646 PROCNAME("ptaGetArrays");
647
648 if (!pnax && !pnay)
649 return ERROR_INT("no output requested", procName, 1);
650 if (pnax) *pnax = NULL;
651 if (pnay) *pnay = NULL;
652 if (!pta)
653 return ERROR_INT("pta not defined", procName, 1);
654 if ((n = ptaGetCount(pta)) == 0)
655 return ERROR_INT("pta is empty", procName, 1);
656
657 if (pnax) {
658 if ((nax = numaCreate(n)) == NULL)
659 return ERROR_INT("nax not made", procName, 1);
660 *pnax = nax;
661 for (i = 0; i < n; i++)
662 nax->array[i] = pta->x[i];
663 nax->n = n;
664 }
665 if (pnay) {
666 if ((nay = numaCreate(n)) == NULL)
667 return ERROR_INT("nay not made", procName, 1);
668 *pnay = nay;
669 for (i = 0; i < n; i++)
670 nay->array[i] = pta->y[i];
671 nay->n = n;
672 }
673 return 0;
674}
675
676
677/*---------------------------------------------------------------------*
678 * Pta serialized for I/O *
679 *---------------------------------------------------------------------*/
686PTA *
687ptaRead(const char *filename)
688{
689FILE *fp;
690PTA *pta;
691
692 PROCNAME("ptaRead");
693
694 if (!filename)
695 return (PTA *)ERROR_PTR("filename not defined", procName, NULL);
696
697 if ((fp = fopenReadStream(filename)) == NULL)
698 return (PTA *)ERROR_PTR("stream not opened", procName, NULL);
699 pta = ptaReadStream(fp);
700 fclose(fp);
701 if (!pta)
702 return (PTA *)ERROR_PTR("pta not read", procName, NULL);
703 return pta;
704}
705
706
719PTA *
721{
722char typestr[128]; /* hardcoded below in fscanf */
723l_int32 i, n, ix, iy, type, version;
724l_float32 x, y;
725PTA *pta;
726
727 PROCNAME("ptaReadStream");
728
729 if (!fp)
730 return (PTA *)ERROR_PTR("stream not defined", procName, NULL);
731
732 if (fscanf(fp, "\n Pta Version %d\n", &version) != 1)
733 return (PTA *)ERROR_PTR("not a pta file", procName, NULL);
734 if (version != PTA_VERSION_NUMBER)
735 return (PTA *)ERROR_PTR("invalid pta version", procName, NULL);
736 if (fscanf(fp, " Number of pts = %d; format = %127s\n", &n, typestr) != 2)
737 return (PTA *)ERROR_PTR("not a pta file", procName, NULL);
738 if (n < 0)
739 return (PTA *)ERROR_PTR("num pts <= 0", procName, NULL);
740 if (n > MaxArraySize)
741 return (PTA *)ERROR_PTR("too many pts", procName, NULL);
742 if (n == 0) L_INFO("the pta is empty\n", procName);
743
744 if (!strcmp(typestr, "float"))
745 type = 0;
746 else /* typestr is "integer" */
747 type = 1;
748 if ((pta = ptaCreate(n)) == NULL)
749 return (PTA *)ERROR_PTR("pta not made", procName, NULL);
750 for (i = 0; i < n; i++) {
751 if (type == 0) { /* data is float */
752 if (fscanf(fp, " (%f, %f)\n", &x, &y) != 2) {
753 ptaDestroy(&pta);
754 return (PTA *)ERROR_PTR("error reading floats", procName, NULL);
755 }
756 ptaAddPt(pta, x, y);
757 } else { /* data is integer */
758 if (fscanf(fp, " (%d, %d)\n", &ix, &iy) != 2) {
759 ptaDestroy(&pta);
760 return (PTA *)ERROR_PTR("error reading ints", procName, NULL);
761 }
762 ptaAddPt(pta, ix, iy);
763 }
764 }
765
766 return pta;
767}
768
769
777PTA *
778ptaReadMem(const l_uint8 *data,
779 size_t size)
780{
781FILE *fp;
782PTA *pta;
783
784 PROCNAME("ptaReadMem");
785
786 if (!data)
787 return (PTA *)ERROR_PTR("data not defined", procName, NULL);
788 if ((fp = fopenReadFromMemory(data, size)) == NULL)
789 return (PTA *)ERROR_PTR("stream not opened", procName, NULL);
790
791 pta = ptaReadStream(fp);
792 fclose(fp);
793 if (!pta) L_ERROR("pta not read\n", procName);
794 return pta;
795}
796
797
815l_ok
816ptaWriteDebug(const char *filename,
817 PTA *pta,
818 l_int32 type)
819{
820 PROCNAME("ptaWriteDebug");
821
822 if (LeptDebugOK) {
823 return ptaWrite(filename, pta, type);
824 } else {
825 L_INFO("write to named temp file %s is disabled\n", procName, filename);
826 return 0;
827 }
828}
829
830
839l_ok
840ptaWrite(const char *filename,
841 PTA *pta,
842 l_int32 type)
843{
844l_int32 ret;
845FILE *fp;
846
847 PROCNAME("ptaWrite");
848
849 if (!filename)
850 return ERROR_INT("filename not defined", procName, 1);
851 if (!pta)
852 return ERROR_INT("pta not defined", procName, 1);
853
854 if ((fp = fopenWriteStream(filename, "w")) == NULL)
855 return ERROR_INT("stream not opened", procName, 1);
856 ret = ptaWriteStream(fp, pta, type);
857 fclose(fp);
858 if (ret)
859 return ERROR_INT("pta not written to stream", procName, 1);
860 return 0;
861}
862
863
872l_ok
874 PTA *pta,
875 l_int32 type)
876{
877l_int32 i, n, ix, iy;
878l_float32 x, y;
879
880 PROCNAME("ptaWriteStream");
881
882 if (!fp)
883 return ERROR_INT("stream not defined", procName, 1);
884 if (!pta)
885 return ERROR_INT("pta not defined", procName, 1);
886
887 n = ptaGetCount(pta);
888 fprintf(fp, "\n Pta Version %d\n", PTA_VERSION_NUMBER);
889 if (type == 0)
890 fprintf(fp, " Number of pts = %d; format = float\n", n);
891 else /* type == 1 */
892 fprintf(fp, " Number of pts = %d; format = integer\n", n);
893 for (i = 0; i < n; i++) {
894 if (type == 0) { /* data is float */
895 ptaGetPt(pta, i, &x, &y);
896 fprintf(fp, " (%f, %f)\n", x, y);
897 } else { /* data is integer */
898 ptaGetIPt(pta, i, &ix, &iy);
899 fprintf(fp, " (%d, %d)\n", ix, iy);
900 }
901 }
902
903 return 0;
904}
905
906
921l_ok
922ptaWriteMem(l_uint8 **pdata,
923 size_t *psize,
924 PTA *pta,
925 l_int32 type)
926{
927l_int32 ret;
928FILE *fp;
929
930 PROCNAME("ptaWriteMem");
931
932 if (pdata) *pdata = NULL;
933 if (psize) *psize = 0;
934 if (!pdata)
935 return ERROR_INT("&data not defined", procName, 1);
936 if (!psize)
937 return ERROR_INT("&size not defined", procName, 1);
938 if (!pta)
939 return ERROR_INT("pta not defined", procName, 1);
940
941#if HAVE_FMEMOPEN
942 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
943 return ERROR_INT("stream not opened", procName, 1);
944 ret = ptaWriteStream(fp, pta, type);
945 fputc('\0', fp);
946 fclose(fp);
947 *psize = *psize - 1;
948#else
949 L_INFO("work-around: writing to a temp file\n", procName);
950 #ifdef _WIN32
951 if ((fp = fopenWriteWinTempfile()) == NULL)
952 return ERROR_INT("tmpfile stream not opened", procName, 1);
953 #else
954 if ((fp = tmpfile()) == NULL)
955 return ERROR_INT("tmpfile stream not opened", procName, 1);
956 #endif /* _WIN32 */
957 ret = ptaWriteStream(fp, pta, type);
958 rewind(fp);
959 *pdata = l_binaryReadStream(fp, psize);
960 fclose(fp);
961#endif /* HAVE_FMEMOPEN */
962 return ret;
963}
964
965
966/*---------------------------------------------------------------------*
967 * PTAA creation, destruction *
968 *---------------------------------------------------------------------*/
975PTAA *
976ptaaCreate(l_int32 n)
977{
978PTAA *ptaa;
979
980 PROCNAME("ptaaCreate");
981
982 if (n <= 0 || n > MaxPtrArraySize)
984
985 ptaa = (PTAA *)LEPT_CALLOC(1, sizeof(PTAA));
986 ptaa->n = 0;
987 ptaa->nalloc = n;
988 if ((ptaa->pta = (PTA **)LEPT_CALLOC(n, sizeof(PTA *))) == NULL) {
989 ptaaDestroy(&ptaa);
990 return (PTAA *)ERROR_PTR("pta ptrs not made", procName, NULL);
991 }
992 return ptaa;
993}
994
995
1002void
1004{
1005l_int32 i;
1006PTAA *ptaa;
1007
1008 PROCNAME("ptaaDestroy");
1009
1010 if (pptaa == NULL) {
1011 L_WARNING("ptr address is NULL!\n", procName);
1012 return;
1013 }
1014
1015 if ((ptaa = *pptaa) == NULL)
1016 return;
1017
1018 for (i = 0; i < ptaa->n; i++)
1019 ptaDestroy(&ptaa->pta[i]);
1020 LEPT_FREE(ptaa->pta);
1021 LEPT_FREE(ptaa);
1022 *pptaa = NULL;
1023}
1024
1025
1026/*---------------------------------------------------------------------*
1027 * PTAA array extension *
1028 *---------------------------------------------------------------------*/
1037l_ok
1039 PTA *pta,
1040 l_int32 copyflag)
1041{
1042l_int32 n;
1043PTA *ptac;
1044
1045 PROCNAME("ptaaAddPta");
1046
1047 if (!ptaa)
1048 return ERROR_INT("ptaa not defined", procName, 1);
1049 if (!pta)
1050 return ERROR_INT("pta not defined", procName, 1);
1051
1052 if (copyflag == L_INSERT) {
1053 ptac = pta;
1054 } else if (copyflag == L_COPY) {
1055 if ((ptac = ptaCopy(pta)) == NULL)
1056 return ERROR_INT("ptac not made", procName, 1);
1057 } else if (copyflag == L_CLONE) {
1058 if ((ptac = ptaClone(pta)) == NULL)
1059 return ERROR_INT("pta clone not made", procName, 1);
1060 } else {
1061 return ERROR_INT("invalid copyflag", procName, 1);
1062 }
1063
1064 n = ptaaGetCount(ptaa);
1065 if (n >= ptaa->nalloc) {
1066 if (ptaaExtendArray(ptaa)) {
1067 if (copyflag != L_INSERT)
1068 ptaDestroy(&ptac);
1069 return ERROR_INT("extension failed", procName, 1);
1070 }
1071 }
1072
1073 ptaa->pta[n] = ptac;
1074 ptaa->n++;
1075 return 0;
1076}
1077
1078
1092static l_int32
1094{
1095size_t oldsize, newsize;
1096
1097 PROCNAME("ptaaExtendArray");
1098
1099 if (!ptaa)
1100 return ERROR_INT("ptaa not defined", procName, 1);
1101 oldsize = ptaa->nalloc * sizeof(PTA *);
1102 newsize = 2 * oldsize;
1103 if (newsize > 8 * MaxPtrArraySize)
1104 return ERROR_INT("newsize > 80 MB; too large", procName, 1);
1105
1106 if ((ptaa->pta = (PTA **)reallocNew((void **)&ptaa->pta,
1107 oldsize, newsize)) == NULL)
1108 return ERROR_INT("new ptr array not returned", procName, 1);
1109
1110 ptaa->nalloc *= 2;
1111 return 0;
1112}
1113
1114
1115/*---------------------------------------------------------------------*
1116 * Ptaa accessors *
1117 *---------------------------------------------------------------------*/
1124l_int32
1126{
1127 PROCNAME("ptaaGetCount");
1128
1129 if (!ptaa)
1130 return ERROR_INT("ptaa not defined", procName, 0);
1131
1132 return ptaa->n;
1133}
1134
1135
1144PTA *
1146 l_int32 index,
1147 l_int32 accessflag)
1148{
1149 PROCNAME("ptaaGetPta");
1150
1151 if (!ptaa)
1152 return (PTA *)ERROR_PTR("ptaa not defined", procName, NULL);
1153 if (index < 0 || index >= ptaa->n)
1154 return (PTA *)ERROR_PTR("index not valid", procName, NULL);
1155
1156 if (accessflag == L_COPY)
1157 return ptaCopy(ptaa->pta[index]);
1158 else if (accessflag == L_CLONE)
1159 return ptaClone(ptaa->pta[index]);
1160 else
1161 return (PTA *)ERROR_PTR("invalid accessflag", procName, NULL);
1162}
1163
1164
1175l_ok
1177 l_int32 ipta,
1178 l_int32 jpt,
1179 l_float32 *px,
1180 l_float32 *py)
1181{
1182PTA *pta;
1183
1184 PROCNAME("ptaaGetPt");
1185
1186 if (px) *px = 0;
1187 if (py) *py = 0;
1188 if (!ptaa)
1189 return ERROR_INT("ptaa not defined", procName, 1);
1190 if (ipta < 0 || ipta >= ptaa->n)
1191 return ERROR_INT("index ipta not valid", procName, 1);
1192
1193 pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1194 if (jpt < 0 || jpt >= pta->n) {
1195 ptaDestroy(&pta);
1196 return ERROR_INT("index jpt not valid", procName, 1);
1197 }
1198
1199 ptaGetPt(pta, jpt, px, py);
1200 ptaDestroy(&pta);
1201 return 0;
1202}
1203
1204
1205/*---------------------------------------------------------------------*
1206 * Ptaa array modifiers *
1207 *---------------------------------------------------------------------*/
1215l_ok
1217 PTA *pta)
1218{
1219l_int32 n, i;
1220PTA *ptat;
1221
1222 PROCNAME("ptaaInitFull");
1223
1224 if (!ptaa)
1225 return ERROR_INT("ptaa not defined", procName, 1);
1226 if (!pta)
1227 return ERROR_INT("pta not defined", procName, 1);
1228
1229 n = ptaa->nalloc;
1230 ptaa->n = n;
1231 for (i = 0; i < n; i++) {
1232 ptat = ptaCopy(pta);
1233 ptaaReplacePta(ptaa, i, ptat);
1234 }
1235 return 0;
1236}
1237
1238
1254l_ok
1256 l_int32 index,
1257 PTA *pta)
1258{
1259l_int32 n;
1260
1261 PROCNAME("ptaaReplacePta");
1262
1263 if (!ptaa)
1264 return ERROR_INT("ptaa not defined", procName, 1);
1265 if (!pta)
1266 return ERROR_INT("pta not defined", procName, 1);
1267 n = ptaaGetCount(ptaa);
1268 if (index < 0 || index >= n)
1269 return ERROR_INT("index not valid", procName, 1);
1270
1271 ptaDestroy(&ptaa->pta[index]);
1272 ptaa->pta[index] = pta;
1273 return 0;
1274}
1275
1276
1285l_ok
1287 l_int32 ipta,
1288 l_float32 x,
1289 l_float32 y)
1290{
1291PTA *pta;
1292
1293 PROCNAME("ptaaAddPt");
1294
1295 if (!ptaa)
1296 return ERROR_INT("ptaa not defined", procName, 1);
1297 if (ipta < 0 || ipta >= ptaa->n)
1298 return ERROR_INT("index ipta not valid", procName, 1);
1299
1300 pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1301 ptaAddPt(pta, x, y);
1302 ptaDestroy(&pta);
1303 return 0;
1304}
1305
1306
1320l_ok
1322{
1323l_int32 i, n, np;
1324PTA *pta;
1325
1326 PROCNAME("ptaaTruncate");
1327
1328 if (!ptaa)
1329 return ERROR_INT("ptaa not defined", procName, 1);
1330
1331 n = ptaaGetCount(ptaa);
1332 for (i = n - 1; i >= 0; i--) {
1333 pta = ptaaGetPta(ptaa, i, L_CLONE);
1334 if (!pta) {
1335 ptaa->n--;
1336 continue;
1337 }
1338 np = ptaGetCount(pta);
1339 ptaDestroy(&pta);
1340 if (np == 0) {
1341 ptaDestroy(&ptaa->pta[i]);
1342 ptaa->n--;
1343 } else {
1344 break;
1345 }
1346 }
1347 return 0;
1348}
1349
1350
1351/*---------------------------------------------------------------------*
1352 * Ptaa serialized for I/O *
1353 *---------------------------------------------------------------------*/
1360PTAA *
1361ptaaRead(const char *filename)
1362{
1363FILE *fp;
1364PTAA *ptaa;
1365
1366 PROCNAME("ptaaRead");
1367
1368 if (!filename)
1369 return (PTAA *)ERROR_PTR("filename not defined", procName, NULL);
1370
1371 if ((fp = fopenReadStream(filename)) == NULL)
1372 return (PTAA *)ERROR_PTR("stream not opened", procName, NULL);
1373 ptaa = ptaaReadStream(fp);
1374 fclose(fp);
1375 if (!ptaa)
1376 return (PTAA *)ERROR_PTR("ptaa not read", procName, NULL);
1377 return ptaa;
1378}
1379
1380
1392PTAA *
1394{
1395l_int32 i, n, version;
1396PTA *pta;
1397PTAA *ptaa;
1398
1399 PROCNAME("ptaaReadStream");
1400
1401 if (!fp)
1402 return (PTAA *)ERROR_PTR("stream not defined", procName, NULL);
1403
1404 if (fscanf(fp, "\nPtaa Version %d\n", &version) != 1)
1405 return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL);
1406 if (version != PTA_VERSION_NUMBER)
1407 return (PTAA *)ERROR_PTR("invalid ptaa version", procName, NULL);
1408 if (fscanf(fp, "Number of Pta = %d\n", &n) != 1)
1409 return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL);
1410 if (n < 0)
1411 return (PTAA *)ERROR_PTR("num pta ptrs <= 0", procName, NULL);
1412 if (n > MaxPtrArraySize)
1413 return (PTAA *)ERROR_PTR("too many pta ptrs", procName, NULL);
1414 if (n == 0) L_INFO("the ptaa is empty\n", procName);
1415
1416 if ((ptaa = ptaaCreate(n)) == NULL)
1417 return (PTAA *)ERROR_PTR("ptaa not made", procName, NULL);
1418 for (i = 0; i < n; i++) {
1419 if ((pta = ptaReadStream(fp)) == NULL) {
1420 ptaaDestroy(&ptaa);
1421 return (PTAA *)ERROR_PTR("error reading pta", procName, NULL);
1422 }
1423 ptaaAddPta(ptaa, pta, L_INSERT);
1424 }
1425
1426 return ptaa;
1427}
1428
1429
1437PTAA *
1438ptaaReadMem(const l_uint8 *data,
1439 size_t size)
1440{
1441FILE *fp;
1442PTAA *ptaa;
1443
1444 PROCNAME("ptaaReadMem");
1445
1446 if (!data)
1447 return (PTAA *)ERROR_PTR("data not defined", procName, NULL);
1448 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1449 return (PTAA *)ERROR_PTR("stream not opened", procName, NULL);
1450
1451 ptaa = ptaaReadStream(fp);
1452 fclose(fp);
1453 if (!ptaa) L_ERROR("ptaa not read\n", procName);
1454 return ptaa;
1455}
1456
1457
1475l_ok
1476ptaaWriteDebug(const char *filename,
1477 PTAA *ptaa,
1478 l_int32 type)
1479{
1480 PROCNAME("ptaaWriteDebug");
1481
1482 if (LeptDebugOK) {
1483 return ptaaWrite(filename, ptaa, type);
1484 } else {
1485 L_INFO("write to named temp file %s is disabled\n", procName, filename);
1486 return 0;
1487 }
1488}
1489
1490
1499l_ok
1500ptaaWrite(const char *filename,
1501 PTAA *ptaa,
1502 l_int32 type)
1503{
1504l_int32 ret;
1505FILE *fp;
1506
1507 PROCNAME("ptaaWrite");
1508
1509 if (!filename)
1510 return ERROR_INT("filename not defined", procName, 1);
1511 if (!ptaa)
1512 return ERROR_INT("ptaa not defined", procName, 1);
1513
1514 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1515 return ERROR_INT("stream not opened", procName, 1);
1516 ret = ptaaWriteStream(fp, ptaa, type);
1517 fclose(fp);
1518 if (ret)
1519 return ERROR_INT("ptaa not written to stream", procName, 1);
1520 return 0;
1521}
1522
1523
1532l_ok
1534 PTAA *ptaa,
1535 l_int32 type)
1536{
1537l_int32 i, n;
1538PTA *pta;
1539
1540 PROCNAME("ptaaWriteStream");
1541
1542 if (!fp)
1543 return ERROR_INT("stream not defined", procName, 1);
1544 if (!ptaa)
1545 return ERROR_INT("ptaa not defined", procName, 1);
1546
1547 n = ptaaGetCount(ptaa);
1548 fprintf(fp, "\nPtaa Version %d\n", PTA_VERSION_NUMBER);
1549 fprintf(fp, "Number of Pta = %d\n", n);
1550 for (i = 0; i < n; i++) {
1551 pta = ptaaGetPta(ptaa, i, L_CLONE);
1552 ptaWriteStream(fp, pta, type);
1553 ptaDestroy(&pta);
1554 }
1555
1556 return 0;
1557}
1558
1559
1574l_ok
1575ptaaWriteMem(l_uint8 **pdata,
1576 size_t *psize,
1577 PTAA *ptaa,
1578 l_int32 type)
1579{
1580l_int32 ret;
1581FILE *fp;
1582
1583 PROCNAME("ptaaWriteMem");
1584
1585 if (pdata) *pdata = NULL;
1586 if (psize) *psize = 0;
1587 if (!pdata)
1588 return ERROR_INT("&data not defined", procName, 1);
1589 if (!psize)
1590 return ERROR_INT("&size not defined", procName, 1);
1591 if (!ptaa)
1592 return ERROR_INT("ptaa not defined", procName, 1);
1593
1594#if HAVE_FMEMOPEN
1595 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1596 return ERROR_INT("stream not opened", procName, 1);
1597 ret = ptaaWriteStream(fp, ptaa, type);
1598 fputc('\0', fp);
1599 fclose(fp);
1600 *psize = *psize - 1;
1601#else
1602 L_INFO("work-around: writing to a temp file\n", procName);
1603 #ifdef _WIN32
1604 if ((fp = fopenWriteWinTempfile()) == NULL)
1605 return ERROR_INT("tmpfile stream not opened", procName, 1);
1606 #else
1607 if ((fp = tmpfile()) == NULL)
1608 return ERROR_INT("tmpfile stream not opened", procName, 1);
1609 #endif /* _WIN32 */
1610 ret = ptaaWriteStream(fp, ptaa, type);
1611 rewind(fp);
1612 *pdata = l_binaryReadStream(fp, psize);
1613 fclose(fp);
1614#endif /* HAVE_FMEMOPEN */
1615 return ret;
1616}
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:719
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:658
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:963
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_INSERT
Definition: pix.h:711
#define PTA_VERSION_NUMBER
Definition: pix.h:513
l_ok ptaWriteStream(FILE *fp, PTA *pta, l_int32 type)
ptaWriteStream()
Definition: ptabasic.c:873
static l_int32 ptaaExtendArray(PTAA *ptaa)
ptaaExtendArray()
Definition: ptabasic.c:1093
PTA * ptaCreateFromNuma(NUMA *nax, NUMA *nay)
ptaCreateFromNuma()
Definition: ptabasic.c:152
l_ok ptaWriteMem(l_uint8 **pdata, size_t *psize, PTA *pta, l_int32 type)
ptaWriteMem()
Definition: ptabasic.c:922
PTA * ptaRead(const char *filename)
ptaRead()
Definition: ptabasic.c:687
l_ok ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition: ptabasic.c:1286
l_ok ptaSetPt(PTA *pta, l_int32 index, l_float32 x, l_float32 y)
ptaSetPt()
Definition: ptabasic.c:607
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition: ptabasic.c:226
l_ok ptaEmpty(PTA *pta)
ptaEmpty()
Definition: ptabasic.c:321
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:578
l_ok ptaRemovePt(PTA *pta, l_int32 index)
ptaRemovePt()
Definition: ptabasic.c:468
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:297
l_ok ptaWriteDebug(const char *filename, PTA *pta, l_int32 type)
ptaWriteDebug()
Definition: ptabasic.c:816
l_ok ptaaWriteMem(l_uint8 **pdata, size_t *psize, PTAA *ptaa, l_int32 type)
ptaaWriteMem()
Definition: ptabasic.c:1575
PTA * ptaReadStream(FILE *fp)
ptaReadStream()
Definition: ptabasic.c:720
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:1038
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1125
l_ok ptaaWrite(const char *filename, PTAA *ptaa, l_int32 type)
ptaaWrite()
Definition: ptabasic.c:1500
PTA * ptaReadMem(const l_uint8 *data, size_t size)
ptaReadMem()
Definition: ptabasic.c:778
l_ok ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition: ptabasic.c:1216
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1145
PTAA * ptaaReadMem(const l_uint8 *data, size_t size)
ptaaReadMem()
Definition: ptabasic.c:1438
PTA * ptaCopyRange(PTA *ptas, l_int32 istart, l_int32 iend)
ptaCopyRange()
Definition: ptabasic.c:258
l_ok ptaaGetPt(PTAA *ptaa, l_int32 ipta, l_int32 jpt, l_float32 *px, l_float32 *py)
ptaaGetPt()
Definition: ptabasic.c:1176
l_ok ptaaWriteStream(FILE *fp, PTAA *ptaa, l_int32 type)
ptaaWriteStream()
Definition: ptabasic.c:1533
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:343
l_ok ptaaWriteDebug(const char *filename, PTAA *ptaa, l_int32 type)
ptaaWriteDebug()
Definition: ptabasic.c:1476
l_ok ptaGetArrays(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaGetArrays()
Definition: ptabasic.c:639
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition: ptabasic.c:548
l_ok ptaInsertPt(PTA *pta, l_int32 index, l_int32 x, l_int32 y)
ptaInsertPt()
Definition: ptabasic.c:421
l_ok ptaWrite(const char *filename, PTA *pta, l_int32 type)
ptaWrite()
Definition: ptabasic.c:840
static const l_int32 InitialArraySize
Definition: ptabasic.c:104
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:527
PTAA * ptaaRead(const char *filename)
ptaaRead()
Definition: ptabasic.c:1361
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:976
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition: ptabasic.c:1003
PTAA * ptaaReadStream(FILE *fp)
ptaaReadStream()
Definition: ptabasic.c:1393
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
l_ok ptaaReplacePta(PTAA *ptaa, l_int32 index, PTA *pta)
ptaaReplacePta()
Definition: ptabasic.c:1255
static l_int32 ptaExtendArrays(PTA *pta)
ptaExtendArrays()
Definition: ptabasic.c:380
l_ok ptaaTruncate(PTAA *ptaa)
ptaaTruncate()
Definition: ptabasic.c:1321
Definition: array.h:71
l_float32 * array
Definition: array.h:77
l_int32 n
Definition: array.h:73
Definition: pix.h:517
l_int32 nalloc
Definition: pix.h:519
l_int32 n
Definition: pix.h:518
l_float32 * y
Definition: pix.h:521
l_uint32 refcount
Definition: pix.h:520
Definition: pix.h:531
struct Pta ** pta
Definition: pix.h:534
l_int32 n
Definition: pix.h:532
l_int32 nalloc
Definition: pix.h:533
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302