Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
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
93#ifdef HAVE_CONFIG_H
94#include <config_auto.h>
95#endif /* HAVE_CONFIG_H */
96
97#include <string.h>
98#include "allheaders.h"
99#include "array_internal.h"
100#include "pix_internal.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 if (n <= 0 || n > (l_int32)MaxArraySize)
126
127 pta = (PTA *)LEPT_CALLOC(1, sizeof(PTA));
128 pta->n = 0;
129 pta->nalloc = n;
130 pta->refcount = 1;
131 pta->x = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
132 pta->y = (l_float32 *)LEPT_CALLOC(n, sizeof(l_float32));
133 if (!pta->x || !pta->y) {
134 ptaDestroy(&pta);
135 return (PTA *)ERROR_PTR("x and y arrays not both made", __func__, NULL);
136 }
137
138 return pta;
139}
140
141
149PTA *
151 NUMA *nay)
152{
153l_int32 i, n;
154l_float32 startx, delx, xval, yval;
155PTA *pta;
156
157 if (!nay)
158 return (PTA *)ERROR_PTR("nay not defined", __func__, NULL);
159 n = numaGetCount(nay);
160 if (nax && numaGetCount(nax) != n)
161 return (PTA *)ERROR_PTR("nax and nay sizes differ", __func__, 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
190void
192{
193PTA *pta;
194
195 if (ppta == NULL) {
196 L_WARNING("ptr address is NULL!\n", __func__);
197 return;
198 }
199
200 if ((pta = *ppta) == NULL)
201 return;
202
203 if (--pta->refcount == 0) {
204 LEPT_FREE(pta->x);
205 LEPT_FREE(pta->y);
206 LEPT_FREE(pta);
207 }
208 *ppta = NULL;
209}
210
211
218PTA *
220{
221l_int32 i;
222l_float32 x, y;
223PTA *npta;
224
225 if (!pta)
226 return (PTA *)ERROR_PTR("pta not defined", __func__, NULL);
227
228 if ((npta = ptaCreate(pta->nalloc)) == NULL)
229 return (PTA *)ERROR_PTR("npta not made", __func__, NULL);
230
231 for (i = 0; i < pta->n; i++) {
232 ptaGetPt(pta, i, &x, &y);
233 ptaAddPt(npta, x, y);
234 }
235
236 return npta;
237}
238
239
248PTA *
250 l_int32 istart,
251 l_int32 iend)
252{
253l_int32 n, i, x, y;
254PTA *ptad;
255
256 if (!ptas)
257 return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
258 n = ptaGetCount(ptas);
259 if (istart < 0)
260 istart = 0;
261 if (istart >= n)
262 return (PTA *)ERROR_PTR("istart out of bounds", __func__, NULL);
263 if (iend <= 0 || iend >= n)
264 iend = n - 1;
265 if (istart > iend)
266 return (PTA *)ERROR_PTR("istart > iend; no pts", __func__, NULL);
267
268 if ((ptad = ptaCreate(iend - istart + 1)) == NULL)
269 return (PTA *)ERROR_PTR("ptad not made", __func__, NULL);
270 for (i = istart; i <= iend; i++) {
271 ptaGetIPt(ptas, i, &x, &y);
272 ptaAddPt(ptad, x, y);
273 }
274
275 return ptad;
276}
277
278
285PTA *
287{
288 if (!pta)
289 return (PTA *)ERROR_PTR("pta not defined", __func__, NULL);
290
291 ++pta->refcount;
292 return pta;
293}
294
295
307l_ok
309{
310 if (!pta)
311 return ERROR_INT("ptad not defined", __func__, 1);
312 pta->n = 0;
313 return 0;
314}
315
316
317/*---------------------------------------------------------------------*
318 * Pta array extension *
319 *---------------------------------------------------------------------*/
327l_ok
329 l_float32 x,
330 l_float32 y)
331{
332l_int32 n;
333
334 if (!pta)
335 return ERROR_INT("pta not defined", __func__, 1);
336
337 n = pta->n;
338 if (n >= pta->nalloc) {
339 if (ptaExtendArrays(pta))
340 return ERROR_INT("extension failed", __func__, 1);
341 }
342
343 pta->x[n] = x;
344 pta->y[n] = y;
345 pta->n++;
346 return 0;
347}
348
349
362static l_int32
364{
365size_t oldsize, newsize;
366
367 if (!pta)
368 return ERROR_INT("pta not defined", __func__, 1);
369 if (pta->nalloc > (l_int32)MaxArraySize) /* belt & suspenders */
370 return ERROR_INT("pta at maximum size; can't extend", __func__, 1);
371 oldsize = 4 * pta->nalloc;
372 if (pta->nalloc > MaxArraySize / 2) {
373 newsize = 4 * MaxArraySize;
374 pta->nalloc = MaxArraySize;
375 } else {
376 newsize = 2 * oldsize;
377 pta->nalloc *= 2;
378 }
379 if ((pta->x = (l_float32 *)reallocNew((void **)&pta->x,
380 oldsize, newsize)) == NULL)
381 return ERROR_INT("new x array not returned", __func__, 1);
382 if ((pta->y = (l_float32 *)reallocNew((void **)&pta->y,
383 oldsize, newsize)) == NULL)
384 return ERROR_INT("new y array not returned", __func__, 1);
385
386 return 0;
387}
388
389
390/*---------------------------------------------------------------------*
391 * Pta insertion and removal *
392 *---------------------------------------------------------------------*/
401l_ok
403 l_int32 index,
404 l_int32 x,
405 l_int32 y)
406{
407l_int32 i, n;
408
409 if (!pta)
410 return ERROR_INT("pta not defined", __func__, 1);
411 n = ptaGetCount(pta);
412 if (index < 0 || index > n) {
413 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n);
414 return 1;
415 }
416
417 if (n > pta->nalloc) {
418 if (ptaExtendArrays(pta))
419 return ERROR_INT("extension failed", __func__, 1);
420 }
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
446l_ok
448 l_int32 index)
449{
450l_int32 i, n;
451
452 if (!pta)
453 return ERROR_INT("pta not defined", __func__, 1);
454 n = ptaGetCount(pta);
455 if (index < 0 || index >= n) {
456 L_ERROR("index %d not in [0,...,%d]\n", __func__, index, n - 1);
457 return 1;
458 }
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 *---------------------------------------------------------------------*/
479l_int32
481{
482 if (!pta)
483 return ERROR_INT("pta not defined", __func__, 0);
484
485 return pta->n;
486}
487
488
498l_ok
500 l_int32 index,
501 l_float32 *px,
502 l_float32 *py)
503{
504 if (px) *px = 0;
505 if (py) *py = 0;
506 if (!pta)
507 return ERROR_INT("pta not defined", __func__, 1);
508 if (index < 0 || index >= pta->n)
509 return ERROR_INT("invalid index", __func__, 1);
510
511 if (px) *px = pta->x[index];
512 if (py) *py = pta->y[index];
513 return 0;
514}
515
516
526l_ok
528 l_int32 index,
529 l_int32 *px,
530 l_int32 *py)
531{
532 if (px) *px = 0;
533 if (py) *py = 0;
534 if (!pta)
535 return ERROR_INT("pta not defined", __func__, 1);
536 if (index < 0 || index >= pta->n)
537 return ERROR_INT("invalid index", __func__, 1);
538
539 if (px) *px = (l_int32)(pta->x[index] + 0.5);
540 if (py) *py = (l_int32)(pta->y[index] + 0.5);
541 return 0;
542}
543
544
553l_ok
555 l_int32 index,
556 l_float32 x,
557 l_float32 y)
558{
559 if (!pta)
560 return ERROR_INT("pta not defined", __func__, 1);
561 if (index < 0 || index >= pta->n)
562 return ERROR_INT("invalid index", __func__, 1);
563
564 pta->x[index] = x;
565 pta->y[index] = y;
566 return 0;
567}
568
569
583l_ok
585 NUMA **pnax,
586 NUMA **pnay)
587{
588l_int32 i, n;
589NUMA *nax, *nay;
590
591 if (!pnax && !pnay)
592 return ERROR_INT("no output requested", __func__, 1);
593 if (pnax) *pnax = NULL;
594 if (pnay) *pnay = NULL;
595 if (!pta)
596 return ERROR_INT("pta not defined", __func__, 1);
597 if ((n = ptaGetCount(pta)) == 0)
598 return ERROR_INT("pta is empty", __func__, 1);
599
600 if (pnax) {
601 if ((nax = numaCreate(n)) == NULL)
602 return ERROR_INT("nax not made", __func__, 1);
603 *pnax = nax;
604 for (i = 0; i < n; i++)
605 nax->array[i] = pta->x[i];
606 nax->n = n;
607 }
608 if (pnay) {
609 if ((nay = numaCreate(n)) == NULL)
610 return ERROR_INT("nay not made", __func__, 1);
611 *pnay = nay;
612 for (i = 0; i < n; i++)
613 nay->array[i] = pta->y[i];
614 nay->n = n;
615 }
616 return 0;
617}
618
619
620/*---------------------------------------------------------------------*
621 * Pta serialized for I/O *
622 *---------------------------------------------------------------------*/
629PTA *
630ptaRead(const char *filename)
631{
632FILE *fp;
633PTA *pta;
634
635 if (!filename)
636 return (PTA *)ERROR_PTR("filename not defined", __func__, NULL);
637
638 if ((fp = fopenReadStream(filename)) == NULL)
639 return (PTA *)ERROR_PTR_1("stream not opened",
640 filename, __func__, NULL);
641 pta = ptaReadStream(fp);
642 fclose(fp);
643 if (!pta)
644 return (PTA *)ERROR_PTR_1("pta not read", filename, __func__, NULL);
645 return pta;
646}
647
648
661PTA *
663{
664char typestr[128]; /* hardcoded below in fscanf */
665l_int32 i, n, ix, iy, type, version;
666l_float32 x, y;
667PTA *pta;
668
669 if (!fp)
670 return (PTA *)ERROR_PTR("stream not defined", __func__, NULL);
671
672 if (fscanf(fp, "\n Pta Version %d\n", &version) != 1)
673 return (PTA *)ERROR_PTR("not a pta file", __func__, NULL);
674 if (version != PTA_VERSION_NUMBER)
675 return (PTA *)ERROR_PTR("invalid pta version", __func__, NULL);
676 if (fscanf(fp, " Number of pts = %d; format = %127s\n", &n, typestr) != 2)
677 return (PTA *)ERROR_PTR("not a pta file", __func__, NULL);
678 if (n < 0)
679 return (PTA *)ERROR_PTR("num pts <= 0", __func__, NULL);
680 if (n > (l_int32)MaxArraySize)
681 return (PTA *)ERROR_PTR("too many pts", __func__, NULL);
682 if (n == 0) L_INFO("the pta is empty\n", __func__);
683
684 if (!strcmp(typestr, "float"))
685 type = 0;
686 else /* typestr is "integer" */
687 type = 1;
688 if ((pta = ptaCreate(n)) == NULL)
689 return (PTA *)ERROR_PTR("pta not made", __func__, NULL);
690 for (i = 0; i < n; i++) {
691 if (type == 0) { /* data is float */
692 if (fscanf(fp, " (%f, %f)\n", &x, &y) != 2) {
693 ptaDestroy(&pta);
694 return (PTA *)ERROR_PTR("error reading floats", __func__, NULL);
695 }
696 ptaAddPt(pta, x, y);
697 } else { /* data is integer */
698 if (fscanf(fp, " (%d, %d)\n", &ix, &iy) != 2) {
699 ptaDestroy(&pta);
700 return (PTA *)ERROR_PTR("error reading ints", __func__, NULL);
701 }
702 ptaAddPt(pta, ix, iy);
703 }
704 }
705
706 return pta;
707}
708
709
717PTA *
718ptaReadMem(const l_uint8 *data,
719 size_t size)
720{
721FILE *fp;
722PTA *pta;
723
724 if (!data)
725 return (PTA *)ERROR_PTR("data not defined", __func__, NULL);
726 if ((fp = fopenReadFromMemory(data, size)) == NULL)
727 return (PTA *)ERROR_PTR("stream not opened", __func__, NULL);
728
729 pta = ptaReadStream(fp);
730 fclose(fp);
731 if (!pta) L_ERROR("pta not read\n", __func__);
732 return pta;
733}
734
735
753l_ok
754ptaWriteDebug(const char *filename,
755 PTA *pta,
756 l_int32 type)
757{
758 if (LeptDebugOK) {
759 return ptaWrite(filename, pta, type);
760 } else {
761 L_INFO("write to named temp file %s is disabled\n", __func__, filename);
762 return 0;
763 }
764}
765
766
775l_ok
776ptaWrite(const char *filename,
777 PTA *pta,
778 l_int32 type)
779{
780l_int32 ret;
781FILE *fp;
782
783 if (!filename)
784 return ERROR_INT("filename not defined", __func__, 1);
785 if (!pta)
786 return ERROR_INT("pta not defined", __func__, 1);
787
788 if ((fp = fopenWriteStream(filename, "w")) == NULL)
789 return ERROR_INT_1("stream not opened", filename, __func__, 1);
790 ret = ptaWriteStream(fp, pta, type);
791 fclose(fp);
792 if (ret)
793 return ERROR_INT_1("pta not written to stream", filename, __func__, 1);
794 return 0;
795}
796
797
806l_ok
808 PTA *pta,
809 l_int32 type)
810{
811l_int32 i, n, ix, iy;
812l_float32 x, y;
813
814 if (!fp)
815 return ERROR_INT("stream not defined", __func__, 1);
816 if (!pta)
817 return ERROR_INT("pta not defined", __func__, 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
853l_ok
854ptaWriteMem(l_uint8 **pdata,
855 size_t *psize,
856 PTA *pta,
857 l_int32 type)
858{
859l_int32 ret;
860FILE *fp;
861
862 if (pdata) *pdata = NULL;
863 if (psize) *psize = 0;
864 if (!pdata)
865 return ERROR_INT("&data not defined", __func__, 1);
866 if (!psize)
867 return ERROR_INT("&size not defined", __func__, 1);
868 if (!pta)
869 return ERROR_INT("pta not defined", __func__, 1);
870
871#if HAVE_FMEMOPEN
872 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
873 return ERROR_INT("stream not opened", __func__, 1);
874 ret = ptaWriteStream(fp, pta, type);
875 fputc('\0', fp);
876 fclose(fp);
877 if (*psize > 0) *psize = *psize - 1;
878#else
879 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
880 #ifdef _WIN32
881 if ((fp = fopenWriteWinTempfile()) == NULL)
882 return ERROR_INT("tmpfile stream not opened", __func__, 1);
883 #else
884 if ((fp = tmpfile()) == NULL)
885 return ERROR_INT("tmpfile stream not opened", __func__, 1);
886 #endif /* _WIN32 */
887 ret = ptaWriteStream(fp, pta, type);
888 rewind(fp);
889 *pdata = l_binaryReadStream(fp, psize);
890 fclose(fp);
891#endif /* HAVE_FMEMOPEN */
892 return ret;
893}
894
895
896/*---------------------------------------------------------------------*
897 * PTAA creation, destruction *
898 *---------------------------------------------------------------------*/
905PTAA *
906ptaaCreate(l_int32 n)
907{
908PTAA *ptaa;
909
910 if (n <= 0 || n > (l_int32)MaxPtrArraySize)
912
913 ptaa = (PTAA *)LEPT_CALLOC(1, sizeof(PTAA));
914 ptaa->n = 0;
915 ptaa->nalloc = n;
916 if ((ptaa->pta = (PTA **)LEPT_CALLOC(n, sizeof(PTA *))) == NULL) {
917 ptaaDestroy(&ptaa);
918 return (PTAA *)ERROR_PTR("pta ptrs not made", __func__, NULL);
919 }
920 return ptaa;
921}
922
923
930void
932{
933l_int32 i;
934PTAA *ptaa;
935
936 if (pptaa == NULL) {
937 L_WARNING("ptr address is NULL!\n", __func__);
938 return;
939 }
940
941 if ((ptaa = *pptaa) == NULL)
942 return;
943
944 for (i = 0; i < ptaa->n; i++)
945 ptaDestroy(&ptaa->pta[i]);
946 LEPT_FREE(ptaa->pta);
947 LEPT_FREE(ptaa);
948 *pptaa = NULL;
949}
950
951
952/*---------------------------------------------------------------------*
953 * PTAA array extension *
954 *---------------------------------------------------------------------*/
963l_ok
965 PTA *pta,
966 l_int32 copyflag)
967{
968l_int32 n;
969PTA *ptac;
970
971 if (!ptaa)
972 return ERROR_INT("ptaa not defined", __func__, 1);
973 if (!pta)
974 return ERROR_INT("pta not defined", __func__, 1);
975
976 if (copyflag == L_INSERT) {
977 ptac = pta;
978 } else if (copyflag == L_COPY) {
979 if ((ptac = ptaCopy(pta)) == NULL)
980 return ERROR_INT("ptac not made", __func__, 1);
981 } else if (copyflag == L_CLONE) {
982 if ((ptac = ptaClone(pta)) == NULL)
983 return ERROR_INT("pta clone not made", __func__, 1);
984 } else {
985 return ERROR_INT("invalid copyflag", __func__, 1);
986 }
987
988 n = ptaaGetCount(ptaa);
989 if (n >= ptaa->nalloc) {
990 if (ptaaExtendArray(ptaa)) {
991 if (copyflag != L_INSERT)
992 ptaDestroy(&ptac);
993 return ERROR_INT("extension failed", __func__, 1);
994 }
995 }
996
997 ptaa->pta[n] = ptac;
998 ptaa->n++;
999 return 0;
1000}
1001
1002
1016static l_int32
1018{
1019size_t oldsize, newsize;
1020
1021 if (!ptaa)
1022 return ERROR_INT("ptaa not defined", __func__, 1);
1023 oldsize = ptaa->nalloc * sizeof(PTA *);
1024 newsize = 2 * oldsize;
1025 if (newsize > 8 * MaxPtrArraySize)
1026 return ERROR_INT("newsize > 80 MB; too large", __func__, 1);
1027
1028 if ((ptaa->pta = (PTA **)reallocNew((void **)&ptaa->pta,
1029 oldsize, newsize)) == NULL)
1030 return ERROR_INT("new ptr array not returned", __func__, 1);
1031
1032 ptaa->nalloc *= 2;
1033 return 0;
1034}
1035
1036
1037/*---------------------------------------------------------------------*
1038 * Ptaa accessors *
1039 *---------------------------------------------------------------------*/
1046l_int32
1048{
1049 if (!ptaa)
1050 return ERROR_INT("ptaa not defined", __func__, 0);
1051
1052 return ptaa->n;
1053}
1054
1055
1064PTA *
1066 l_int32 index,
1067 l_int32 accessflag)
1068{
1069 if (!ptaa)
1070 return (PTA *)ERROR_PTR("ptaa not defined", __func__, NULL);
1071 if (index < 0 || index >= ptaa->n)
1072 return (PTA *)ERROR_PTR("index not valid", __func__, NULL);
1073
1074 if (accessflag == L_COPY)
1075 return ptaCopy(ptaa->pta[index]);
1076 else if (accessflag == L_CLONE)
1077 return ptaClone(ptaa->pta[index]);
1078 else
1079 return (PTA *)ERROR_PTR("invalid accessflag", __func__, NULL);
1080}
1081
1082
1093l_ok
1095 l_int32 ipta,
1096 l_int32 jpt,
1097 l_float32 *px,
1098 l_float32 *py)
1099{
1100PTA *pta;
1101
1102 if (px) *px = 0;
1103 if (py) *py = 0;
1104 if (!ptaa)
1105 return ERROR_INT("ptaa not defined", __func__, 1);
1106 if (ipta < 0 || ipta >= ptaa->n)
1107 return ERROR_INT("index ipta not valid", __func__, 1);
1108
1109 pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1110 if (jpt < 0 || jpt >= pta->n) {
1111 ptaDestroy(&pta);
1112 return ERROR_INT("index jpt not valid", __func__, 1);
1113 }
1114
1115 ptaGetPt(pta, jpt, px, py);
1116 ptaDestroy(&pta);
1117 return 0;
1118}
1119
1120
1121/*---------------------------------------------------------------------*
1122 * Ptaa array modifiers *
1123 *---------------------------------------------------------------------*/
1131l_ok
1133 PTA *pta)
1134{
1135l_int32 n, i;
1136PTA *ptat;
1137
1138 if (!ptaa)
1139 return ERROR_INT("ptaa not defined", __func__, 1);
1140 if (!pta)
1141 return ERROR_INT("pta not defined", __func__, 1);
1142
1143 n = ptaa->nalloc;
1144 ptaa->n = n;
1145 for (i = 0; i < n; i++) {
1146 ptat = ptaCopy(pta);
1147 ptaaReplacePta(ptaa, i, ptat);
1148 }
1149 return 0;
1150}
1151
1152
1168l_ok
1170 l_int32 index,
1171 PTA *pta)
1172{
1173l_int32 n;
1174
1175 if (!ptaa)
1176 return ERROR_INT("ptaa not defined", __func__, 1);
1177 if (!pta)
1178 return ERROR_INT("pta not defined", __func__, 1);
1179 n = ptaaGetCount(ptaa);
1180 if (index < 0 || index >= n)
1181 return ERROR_INT("index not valid", __func__, 1);
1182
1183 ptaDestroy(&ptaa->pta[index]);
1184 ptaa->pta[index] = pta;
1185 return 0;
1186}
1187
1188
1197l_ok
1199 l_int32 ipta,
1200 l_float32 x,
1201 l_float32 y)
1202{
1203PTA *pta;
1204
1205 if (!ptaa)
1206 return ERROR_INT("ptaa not defined", __func__, 1);
1207 if (ipta < 0 || ipta >= ptaa->n)
1208 return ERROR_INT("index ipta not valid", __func__, 1);
1209
1210 pta = ptaaGetPta(ptaa, ipta, L_CLONE);
1211 ptaAddPt(pta, x, y);
1212 ptaDestroy(&pta);
1213 return 0;
1214}
1215
1216
1230l_ok
1232{
1233l_int32 i, n, np;
1234PTA *pta;
1235
1236 if (!ptaa)
1237 return ERROR_INT("ptaa not defined", __func__, 1);
1238
1239 n = ptaaGetCount(ptaa);
1240 for (i = n - 1; i >= 0; i--) {
1241 pta = ptaaGetPta(ptaa, i, L_CLONE);
1242 if (!pta) {
1243 ptaa->n--;
1244 continue;
1245 }
1246 np = ptaGetCount(pta);
1247 ptaDestroy(&pta);
1248 if (np == 0) {
1249 ptaDestroy(&ptaa->pta[i]);
1250 ptaa->n--;
1251 } else {
1252 break;
1253 }
1254 }
1255 return 0;
1256}
1257
1258
1259/*---------------------------------------------------------------------*
1260 * Ptaa serialized for I/O *
1261 *---------------------------------------------------------------------*/
1268PTAA *
1269ptaaRead(const char *filename)
1270{
1271FILE *fp;
1272PTAA *ptaa;
1273
1274 if (!filename)
1275 return (PTAA *)ERROR_PTR("filename not defined", __func__, NULL);
1276
1277 if ((fp = fopenReadStream(filename)) == NULL)
1278 return (PTAA *)ERROR_PTR_1("stream not opened",
1279 filename, __func__, NULL);
1280 ptaa = ptaaReadStream(fp);
1281 fclose(fp);
1282 if (!ptaa)
1283 return (PTAA *)ERROR_PTR_1("ptaa not read", filename, __func__, NULL);
1284 return ptaa;
1285}
1286
1287
1299PTAA *
1301{
1302l_int32 i, n, version;
1303PTA *pta;
1304PTAA *ptaa;
1305
1306 if (!fp)
1307 return (PTAA *)ERROR_PTR("stream not defined", __func__, NULL);
1308
1309 if (fscanf(fp, "\nPtaa Version %d\n", &version) != 1)
1310 return (PTAA *)ERROR_PTR("not a ptaa file", __func__, NULL);
1311 if (version != PTA_VERSION_NUMBER)
1312 return (PTAA *)ERROR_PTR("invalid ptaa version", __func__, NULL);
1313 if (fscanf(fp, "Number of Pta = %d\n", &n) != 1)
1314 return (PTAA *)ERROR_PTR("not a ptaa file", __func__, NULL);
1315 if (n < 0)
1316 return (PTAA *)ERROR_PTR("num pta ptrs <= 0", __func__, NULL);
1317 if (n > (l_int32)MaxPtrArraySize)
1318 return (PTAA *)ERROR_PTR("too many pta ptrs", __func__, NULL);
1319 if (n == 0) L_INFO("the ptaa is empty\n", __func__);
1320
1321 if ((ptaa = ptaaCreate(n)) == NULL)
1322 return (PTAA *)ERROR_PTR("ptaa not made", __func__, 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", __func__, NULL);
1327 }
1328 ptaaAddPta(ptaa, pta, L_INSERT);
1329 }
1330
1331 return ptaa;
1332}
1333
1334
1342PTAA *
1343ptaaReadMem(const l_uint8 *data,
1344 size_t size)
1345{
1346FILE *fp;
1347PTAA *ptaa;
1348
1349 if (!data)
1350 return (PTAA *)ERROR_PTR("data not defined", __func__, NULL);
1351 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1352 return (PTAA *)ERROR_PTR("stream not opened", __func__, NULL);
1353
1354 ptaa = ptaaReadStream(fp);
1355 fclose(fp);
1356 if (!ptaa) L_ERROR("ptaa not read\n", __func__);
1357 return ptaa;
1358}
1359
1360
1378l_ok
1379ptaaWriteDebug(const char *filename,
1380 PTAA *ptaa,
1381 l_int32 type)
1382{
1383 if (LeptDebugOK) {
1384 return ptaaWrite(filename, ptaa, type);
1385 } else {
1386 L_INFO("write to named temp file %s is disabled\n", __func__, filename);
1387 return 0;
1388 }
1389}
1390
1391
1400l_ok
1401ptaaWrite(const char *filename,
1402 PTAA *ptaa,
1403 l_int32 type)
1404{
1405l_int32 ret;
1406FILE *fp;
1407
1408 if (!filename)
1409 return ERROR_INT("filename not defined", __func__, 1);
1410 if (!ptaa)
1411 return ERROR_INT("ptaa not defined", __func__, 1);
1412
1413 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1414 return ERROR_INT_1("stream not opened", filename, __func__, 1);
1415 ret = ptaaWriteStream(fp, ptaa, type);
1416 fclose(fp);
1417 if (ret)
1418 return ERROR_INT_1("ptaa not written to stream", filename, __func__, 1);
1419 return 0;
1420}
1421
1422
1431l_ok
1433 PTAA *ptaa,
1434 l_int32 type)
1435{
1436l_int32 i, n;
1437PTA *pta;
1438
1439 if (!fp)
1440 return ERROR_INT("stream not defined", __func__, 1);
1441 if (!ptaa)
1442 return ERROR_INT("ptaa not defined", __func__, 1);
1443
1444 n = ptaaGetCount(ptaa);
1445 fprintf(fp, "\nPtaa Version %d\n", PTA_VERSION_NUMBER);
1446 fprintf(fp, "Number of Pta = %d\n", n);
1447 for (i = 0; i < n; i++) {
1448 pta = ptaaGetPta(ptaa, i, L_CLONE);
1449 ptaWriteStream(fp, pta, type);
1450 ptaDestroy(&pta);
1451 }
1452
1453 return 0;
1454}
1455
1456
1471l_ok
1472ptaaWriteMem(l_uint8 **pdata,
1473 size_t *psize,
1474 PTAA *ptaa,
1475 l_int32 type)
1476{
1477l_int32 ret;
1478FILE *fp;
1479
1480 if (pdata) *pdata = NULL;
1481 if (psize) *psize = 0;
1482 if (!pdata)
1483 return ERROR_INT("&data not defined", __func__, 1);
1484 if (!psize)
1485 return ERROR_INT("&size not defined", __func__, 1);
1486 if (!ptaa)
1487 return ERROR_INT("ptaa not defined", __func__, 1);
1488
1489#if HAVE_FMEMOPEN
1490 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1491 return ERROR_INT("stream not opened", __func__, 1);
1492 ret = ptaaWriteStream(fp, ptaa, type);
1493 fputc('\0', fp);
1494 fclose(fp);
1495 if (*psize > 0) *psize = *psize - 1;
1496#else
1497 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1498 #ifdef _WIN32
1499 if ((fp = fopenWriteWinTempfile()) == NULL)
1500 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1501 #else
1502 if ((fp = tmpfile()) == NULL)
1503 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1504 #endif /* _WIN32 */
1505 ret = ptaaWriteStream(fp, ptaa, type);
1506 rewind(fp);
1507 *pdata = l_binaryReadStream(fp, psize);
1508 fclose(fp);
1509#endif /* HAVE_FMEMOPEN */
1510 return ret;
1511}
@ L_COPY
Definition pix.h:505
@ L_CLONE
Definition pix.h:506
@ L_INSERT
Definition pix.h:504
#define PTA_VERSION_NUMBER
l_ok ptaWriteStream(FILE *fp, PTA *pta, l_int32 type)
ptaWriteStream()
Definition ptabasic.c:807
static l_int32 ptaaExtendArray(PTAA *ptaa)
ptaaExtendArray()
Definition ptabasic.c:1017
PTA * ptaCreateFromNuma(NUMA *nax, NUMA *nay)
ptaCreateFromNuma()
Definition ptabasic.c:150
l_ok ptaWriteMem(l_uint8 **pdata, size_t *psize, PTA *pta, l_int32 type)
ptaWriteMem()
Definition ptabasic.c:854
PTA * ptaRead(const char *filename)
ptaRead()
Definition ptabasic.c:630
l_ok ptaaAddPt(PTAA *ptaa, l_int32 ipta, l_float32 x, l_float32 y)
ptaaAddPt()
Definition ptabasic.c:1198
l_ok ptaSetPt(PTA *pta, l_int32 index, l_float32 x, l_float32 y)
ptaSetPt()
Definition ptabasic.c:554
PTA * ptaCopy(PTA *pta)
ptaCopy()
Definition ptabasic.c:219
l_ok ptaEmpty(PTA *pta)
ptaEmpty()
Definition ptabasic.c:308
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition ptabasic.c:527
l_ok ptaRemovePt(PTA *pta, l_int32 index)
ptaRemovePt()
Definition ptabasic.c:447
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition ptabasic.c:120
PTA * ptaClone(PTA *pta)
ptaClone()
Definition ptabasic.c:286
l_ok ptaWriteDebug(const char *filename, PTA *pta, l_int32 type)
ptaWriteDebug()
Definition ptabasic.c:754
l_ok ptaaWriteMem(l_uint8 **pdata, size_t *psize, PTAA *ptaa, l_int32 type)
ptaaWriteMem()
Definition ptabasic.c:1472
PTA * ptaReadStream(FILE *fp)
ptaReadStream()
Definition ptabasic.c:662
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition ptabasic.c:964
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition ptabasic.c:1047
l_ok ptaaWrite(const char *filename, PTAA *ptaa, l_int32 type)
ptaaWrite()
Definition ptabasic.c:1401
PTA * ptaReadMem(const l_uint8 *data, size_t size)
ptaReadMem()
Definition ptabasic.c:718
l_ok ptaaInitFull(PTAA *ptaa, PTA *pta)
ptaaInitFull()
Definition ptabasic.c:1132
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition ptabasic.c:1065
PTAA * ptaaReadMem(const l_uint8 *data, size_t size)
ptaaReadMem()
Definition ptabasic.c:1343
PTA * ptaCopyRange(PTA *ptas, l_int32 istart, l_int32 iend)
ptaCopyRange()
Definition ptabasic.c:249
l_ok ptaaGetPt(PTAA *ptaa, l_int32 ipta, l_int32 jpt, l_float32 *px, l_float32 *py)
ptaaGetPt()
Definition ptabasic.c:1094
l_ok ptaaWriteStream(FILE *fp, PTAA *ptaa, l_int32 type)
ptaaWriteStream()
Definition ptabasic.c:1432
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition ptabasic.c:328
l_ok ptaaWriteDebug(const char *filename, PTAA *ptaa, l_int32 type)
ptaaWriteDebug()
Definition ptabasic.c:1379
l_ok ptaGetArrays(PTA *pta, NUMA **pnax, NUMA **pnay)
ptaGetArrays()
Definition ptabasic.c:584
l_ok ptaGetPt(PTA *pta, l_int32 index, l_float32 *px, l_float32 *py)
ptaGetPt()
Definition ptabasic.c:499
l_ok ptaInsertPt(PTA *pta, l_int32 index, l_int32 x, l_int32 y)
ptaInsertPt()
Definition ptabasic.c:402
l_ok ptaWrite(const char *filename, PTA *pta, l_int32 type)
ptaWrite()
Definition ptabasic.c:776
static const l_int32 InitialArraySize
Definition ptabasic.c:104
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition ptabasic.c:480
PTAA * ptaaRead(const char *filename)
ptaaRead()
Definition ptabasic.c:1269
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition ptabasic.c:906
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition ptabasic.c:931
PTAA * ptaaReadStream(FILE *fp)
ptaaReadStream()
Definition ptabasic.c:1300
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition ptabasic.c:191
l_ok ptaaReplacePta(PTAA *ptaa, l_int32 index, PTA *pta)
ptaaReplacePta()
Definition ptabasic.c:1169
static l_int32 ptaExtendArrays(PTA *pta)
ptaExtendArrays()
Definition ptabasic.c:363
l_ok ptaaTruncate(PTAA *ptaa)
ptaaTruncate()
Definition ptabasic.c:1231
l_float32 * array
l_int32 n
l_atomic refcount
l_int32 nalloc
l_int32 n
l_float32 * y
struct Pta ** pta
l_int32 n
l_int32 nalloc