Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 00017 /* 00018 * ptabasic.c 00019 * 00020 * Pta creation, destruction, copy, clone, empty 00021 * PTA *ptaCreate() 00022 * PTA *ptaCreateFromNuma() 00023 * void ptaDestroy() 00024 * PTA *ptaCopy() 00025 * PTA *ptaClone() 00026 * l_int32 ptaEmpty() 00027 * 00028 * Pta array extension 00029 * l_int32 ptaAddPt() 00030 * l_int32 ptaExtendArrays() 00031 * 00032 * Pta Accessors 00033 * l_int32 ptaGetRefcount() 00034 * l_int32 ptaChangeRefcount() 00035 * l_int32 ptaGetCount() 00036 * l_int32 ptaGetPt() 00037 * l_int32 ptaGetIPt() 00038 * l_int32 ptaSetPt() 00039 * l_int32 ptaGetArrays() 00040 * 00041 * Pta serialized for I/O 00042 * PTA *ptaRead() 00043 * PTA *ptaReadStream() 00044 * l_int32 ptaWrite() 00045 * l_int32 ptaWriteStream() 00046 * 00047 * Ptaa creation, destruction 00048 * PTAA *ptaaCreate() 00049 * void ptaaDestroy() 00050 * 00051 * Ptaa array extension 00052 * l_int32 ptaaAddPta() 00053 * l_int32 ptaaExtendArray() 00054 * 00055 * Ptaa Accessors 00056 * l_int32 ptaaGetCount() 00057 * l_int32 ptaaGetPta() 00058 * l_int32 ptaaGetPt() 00059 * 00060 * Ptaa serialized for I/O 00061 * PTAA *ptaaRead() 00062 * PTAA *ptaaReadStream() 00063 * l_int32 ptaaWrite() 00064 * l_int32 ptaaWriteStream() 00065 */ 00066 00067 #include <string.h> 00068 #include "allheaders.h" 00069 00070 static const l_int32 INITIAL_PTR_ARRAYSIZE = 20; /* n'import quoi */ 00071 00072 00073 /*---------------------------------------------------------------------* 00074 * Pta creation, destruction, copy, clone * 00075 *---------------------------------------------------------------------*/ 00076 /*! 00077 * ptaCreate() 00078 * 00079 * Input: n (initial array sizes) 00080 * Return: pta, or null on error. 00081 */ 00082 PTA * 00083 ptaCreate(l_int32 n) 00084 { 00085 PTA *pta; 00086 00087 PROCNAME("ptaCreate"); 00088 00089 if (n <= 0) 00090 n = INITIAL_PTR_ARRAYSIZE; 00091 00092 if ((pta = (PTA *)CALLOC(1, sizeof(PTA))) == NULL) 00093 return (PTA *)ERROR_PTR("pta not made", procName, NULL); 00094 pta->n = 0; 00095 pta->nalloc = n; 00096 ptaChangeRefcount(pta, 1); /* sets to 1 */ 00097 00098 if ((pta->x = (l_float32 *)CALLOC(n, sizeof(l_float32))) == NULL) 00099 return (PTA *)ERROR_PTR("x array not made", procName, NULL); 00100 if ((pta->y = (l_float32 *)CALLOC(n, sizeof(l_float32))) == NULL) 00101 return (PTA *)ERROR_PTR("y array not made", procName, NULL); 00102 00103 return pta; 00104 } 00105 00106 00107 /*! 00108 * ptaCreateFromNuma() 00109 * 00110 * Input: nax (<optional> can be null) 00111 * nay 00112 * Return: pta, or null on error. 00113 */ 00114 PTA * 00115 ptaCreateFromNuma(NUMA *nax, 00116 NUMA *nay) 00117 { 00118 l_int32 i, n; 00119 l_float32 startx, delx, xval, yval; 00120 PTA *pta; 00121 00122 PROCNAME("ptaCreateFromNuma"); 00123 00124 if (!nay) 00125 return (PTA *)ERROR_PTR("nay not defined", procName, NULL); 00126 n = numaGetCount(nay); 00127 if (nax && numaGetCount(nax) != n) 00128 return (PTA *)ERROR_PTR("nax and nay sizes differ", procName, NULL); 00129 00130 pta = ptaCreate(n); 00131 numaGetXParameters(nay, &startx, &delx); 00132 for (i = 0; i < n; i++) { 00133 if (nax) 00134 numaGetFValue(nax, i, &xval); 00135 else /* use implicit x values from nay */ 00136 xval = startx + i * delx; 00137 numaGetFValue(nay, i, &yval); 00138 ptaAddPt(pta, xval, yval); 00139 } 00140 00141 return pta; 00142 } 00143 00144 00145 /*! 00146 * ptaDestroy() 00147 * 00148 * Input: &pta (<to be nulled>) 00149 * Return: void 00150 * 00151 * Note: 00152 * - Decrements the ref count and, if 0, destroys the pta. 00153 * - Always nulls the input ptr. 00154 */ 00155 void 00156 ptaDestroy(PTA **ppta) 00157 { 00158 PTA *pta; 00159 00160 PROCNAME("ptaDestroy"); 00161 00162 if (ppta == NULL) { 00163 L_WARNING("ptr address is NULL!", procName); 00164 return; 00165 } 00166 00167 if ((pta = *ppta) == NULL) 00168 return; 00169 00170 ptaChangeRefcount(pta, -1); 00171 if (ptaGetRefcount(pta) <= 0) { 00172 FREE(pta->x); 00173 FREE(pta->y); 00174 FREE(pta); 00175 } 00176 00177 *ppta = NULL; 00178 return; 00179 } 00180 00181 00182 /*! 00183 * ptaCopy() 00184 * 00185 * Input: pta 00186 * Return: copy of pta, or null on error 00187 */ 00188 PTA * 00189 ptaCopy(PTA *pta) 00190 { 00191 l_int32 i; 00192 l_float32 x, y; 00193 PTA *npta; 00194 00195 PROCNAME("ptaCopy"); 00196 00197 if (!pta) 00198 return (PTA *)ERROR_PTR("pta not defined", procName, NULL); 00199 00200 if ((npta = ptaCreate(pta->nalloc)) == NULL) 00201 return (PTA *)ERROR_PTR("npta not made", procName, NULL); 00202 00203 for (i = 0; i < pta->n; i++) { 00204 ptaGetPt(pta, i, &x, &y); 00205 ptaAddPt(npta, x, y); 00206 } 00207 00208 return npta; 00209 } 00210 00211 00212 /*! 00213 * ptaClone() 00214 * 00215 * Input: pta 00216 * Return: ptr to same pta, or null on error 00217 */ 00218 PTA * 00219 ptaClone(PTA *pta) 00220 { 00221 PROCNAME("ptaClone"); 00222 00223 if (!pta) 00224 return (PTA *)ERROR_PTR("pta not defined", procName, NULL); 00225 00226 ptaChangeRefcount(pta, 1); 00227 return pta; 00228 } 00229 00230 00231 /*! 00232 * ptaEmpty() 00233 * 00234 * Input: pta 00235 * Return: 0 if OK, 1 on error 00236 * 00237 * Note: this only resets the "n" field, for reuse 00238 */ 00239 l_int32 00240 ptaEmpty(PTA *pta) 00241 { 00242 PROCNAME("ptaEmpty"); 00243 00244 if (!pta) 00245 return ERROR_INT("ptad not defined", procName, 1); 00246 pta->n = 0; 00247 return 0; 00248 } 00249 00250 00251 /*---------------------------------------------------------------------* 00252 * Pta array extension * 00253 *---------------------------------------------------------------------*/ 00254 /*! 00255 * ptaAddPt() 00256 * 00257 * Input: pta 00258 * x, y 00259 * Return: 0 if OK, 1 on error 00260 */ 00261 l_int32 00262 ptaAddPt(PTA *pta, 00263 l_float32 x, 00264 l_float32 y) 00265 { 00266 l_int32 n; 00267 00268 PROCNAME("ptaAddPt"); 00269 00270 if (!pta) 00271 return ERROR_INT("pta not defined", procName, 1); 00272 00273 n = pta->n; 00274 if (n >= pta->nalloc) 00275 ptaExtendArrays(pta); 00276 pta->x[n] = x; 00277 pta->y[n] = y; 00278 pta->n++; 00279 00280 return 0; 00281 } 00282 00283 00284 /*! 00285 * ptaExtendArrays() 00286 * 00287 * Input: pta 00288 * Return: 0 if OK; 1 on error 00289 */ 00290 l_int32 00291 ptaExtendArrays(PTA *pta) 00292 { 00293 PROCNAME("ptaExtendArrays"); 00294 00295 if (!pta) 00296 return ERROR_INT("pta not defined", procName, 1); 00297 00298 if ((pta->x = (l_float32 *)reallocNew((void **)&pta->x, 00299 sizeof(l_float32) * pta->nalloc, 00300 2 * sizeof(l_float32) * pta->nalloc)) == NULL) 00301 return ERROR_INT("new x array not returned", procName, 1); 00302 if ((pta->y = (l_float32 *)reallocNew((void **)&pta->y, 00303 sizeof(l_float32) * pta->nalloc, 00304 2 * sizeof(l_float32) * pta->nalloc)) == NULL) 00305 return ERROR_INT("new y array not returned", procName, 1); 00306 00307 pta->nalloc = 2 * pta->nalloc; 00308 return 0; 00309 } 00310 00311 00312 /*---------------------------------------------------------------------* 00313 * Pta accessors * 00314 *---------------------------------------------------------------------*/ 00315 l_int32 00316 ptaGetRefcount(PTA *pta) 00317 { 00318 PROCNAME("ptaGetRefcount"); 00319 00320 if (!pta) 00321 return ERROR_INT("pta not defined", procName, 1); 00322 return pta->refcount; 00323 } 00324 00325 00326 l_int32 00327 ptaChangeRefcount(PTA *pta, 00328 l_int32 delta) 00329 { 00330 PROCNAME("ptaChangeRefcount"); 00331 00332 if (!pta) 00333 return ERROR_INT("pta not defined", procName, 1); 00334 pta->refcount += delta; 00335 return 0; 00336 } 00337 00338 00339 /*! 00340 * ptaGetCount() 00341 * 00342 * Input: pta 00343 * Return: count, or 0 if no pta 00344 */ 00345 l_int32 00346 ptaGetCount(PTA *pta) 00347 { 00348 PROCNAME("ptaGetCount"); 00349 00350 if (!pta) 00351 return ERROR_INT("pta not defined", procName, 0); 00352 00353 return pta->n; 00354 } 00355 00356 00357 /*! 00358 * ptaGetPt() 00359 * 00360 * Input: pta 00361 * index (into arrays) 00362 * &x (<optional return> float x value) 00363 * &y (<optional return> float y value) 00364 * Return: 0 if OK; 1 on error 00365 */ 00366 l_int32 00367 ptaGetPt(PTA *pta, 00368 l_int32 index, 00369 l_float32 *px, 00370 l_float32 *py) 00371 { 00372 PROCNAME("ptaGetPt"); 00373 00374 if (px) *px = 0; 00375 if (py) *py = 0; 00376 if (!pta) 00377 return ERROR_INT("pta not defined", procName, 1); 00378 if (index < 0 || index >= pta->n) 00379 return ERROR_INT("invalid index", procName, 1); 00380 00381 if (px) *px = pta->x[index]; 00382 if (py) *py = pta->y[index]; 00383 return 0; 00384 } 00385 00386 00387 /*! 00388 * ptaGetIPt() 00389 * 00390 * Input: pta 00391 * index (into arrays) 00392 * &x (<optional return> integer x value) 00393 * &y (<optional return> integer y value) 00394 * Return: 0 if OK; 1 on error 00395 */ 00396 l_int32 00397 ptaGetIPt(PTA *pta, 00398 l_int32 index, 00399 l_int32 *px, 00400 l_int32 *py) 00401 { 00402 PROCNAME("ptaGetIPt"); 00403 00404 if (px) *px = 0; 00405 if (py) *py = 0; 00406 if (!pta) 00407 return ERROR_INT("pta not defined", procName, 1); 00408 if (index < 0 || index >= pta->n) 00409 return ERROR_INT("invalid index", procName, 1); 00410 00411 if (px) *px = (l_int32)(pta->x[index] + 0.5); 00412 if (py) *py = (l_int32)(pta->y[index] + 0.5); 00413 return 0; 00414 } 00415 00416 00417 /*! 00418 * ptaSetPt() 00419 * 00420 * Input: pta 00421 * index (into arrays) 00422 * x, y 00423 * Return: 0 if OK; 1 on error 00424 */ 00425 l_int32 00426 ptaSetPt(PTA *pta, 00427 l_int32 index, 00428 l_float32 x, 00429 l_float32 y) 00430 { 00431 PROCNAME("ptaSetPt"); 00432 00433 if (!pta) 00434 return ERROR_INT("pta not defined", procName, 1); 00435 if (index < 0 || index >= pta->n) 00436 return ERROR_INT("invalid index", procName, 1); 00437 00438 pta->x[index] = x; 00439 pta->y[index] = y; 00440 return 0; 00441 } 00442 00443 00444 /*! 00445 * ptaGetArrays() 00446 * 00447 * Input: pta 00448 * &nax (<optional return> numa of x array) 00449 * &nay (<optional return> numa of y array) 00450 * Return: 0 if OK; 1 on error or if pta is empty 00451 * 00452 * Notes: 00453 * (1) This copies the internal arrays into new Numas. 00454 */ 00455 l_int32 00456 ptaGetArrays(PTA *pta, 00457 NUMA **pnax, 00458 NUMA **pnay) 00459 { 00460 l_int32 i, n; 00461 NUMA *nax, *nay; 00462 00463 PROCNAME("ptaGetArrays"); 00464 00465 if (!pnax && !pnay) 00466 return ERROR_INT("no output requested", procName, 1); 00467 if (pnax) *pnax = NULL; 00468 if (pnay) *pnay = NULL; 00469 if (!pta) 00470 return ERROR_INT("pta not defined", procName, 1); 00471 if ((n = ptaGetCount(pta)) == 0) 00472 return ERROR_INT("pta is empty", procName, 1); 00473 00474 if (pnax) { 00475 if ((nax = numaCreate(n)) == NULL) 00476 return ERROR_INT("nax not made", procName, 1); 00477 *pnax = nax; 00478 for (i = 0; i < n; i++) 00479 nax->array[i] = pta->x[i]; 00480 nax->n = n; 00481 } 00482 if (pnay) { 00483 if ((nay = numaCreate(n)) == NULL) 00484 return ERROR_INT("nay not made", procName, 1); 00485 *pnay = nay; 00486 for (i = 0; i < n; i++) 00487 nay->array[i] = pta->y[i]; 00488 nay->n = n; 00489 } 00490 return 0; 00491 } 00492 00493 00494 /*---------------------------------------------------------------------* 00495 * Pta serialized for I/O * 00496 *---------------------------------------------------------------------*/ 00497 /*! 00498 * ptaRead() 00499 * 00500 * Input: filename 00501 * Return: pta, or null on error 00502 */ 00503 PTA * 00504 ptaRead(const char *filename) 00505 { 00506 FILE *fp; 00507 PTA *pta; 00508 00509 PROCNAME("ptaRead"); 00510 00511 if (!filename) 00512 return (PTA *)ERROR_PTR("filename not defined", procName, NULL); 00513 if ((fp = fopenReadStream(filename)) == NULL) 00514 return (PTA *)ERROR_PTR("stream not opened", procName, NULL); 00515 00516 if ((pta = ptaReadStream(fp)) == NULL) { 00517 fclose(fp); 00518 return (PTA *)ERROR_PTR("pta not read", procName, NULL); 00519 } 00520 00521 fclose(fp); 00522 return pta; 00523 } 00524 00525 00526 /*! 00527 * ptaReadStream() 00528 * 00529 * Input: stream 00530 * Return: pta, or null on error 00531 */ 00532 PTA * 00533 ptaReadStream(FILE *fp) 00534 { 00535 char typestr[128]; 00536 l_int32 i, n, ix, iy, type, version; 00537 l_float32 x, y; 00538 PTA *pta; 00539 00540 PROCNAME("ptaReadStream"); 00541 00542 if (!fp) 00543 return (PTA *)ERROR_PTR("stream not defined", procName, NULL); 00544 00545 if (fscanf(fp, "\n Pta Version %d\n", &version) != 1) 00546 return (PTA *)ERROR_PTR("not a pta file", procName, NULL); 00547 if (version != PTA_VERSION_NUMBER) 00548 return (PTA *)ERROR_PTR("invalid pta version", procName, NULL); 00549 if (fscanf(fp, " Number of pts = %d; format = %s\n", &n, typestr) != 2) 00550 return (PTA *)ERROR_PTR("not a pta file", procName, NULL); 00551 if (!strcmp(typestr, "float")) 00552 type = 0; 00553 else /* typestr is "integer" */ 00554 type = 1; 00555 00556 if ((pta = ptaCreate(n)) == NULL) 00557 return (PTA *)ERROR_PTR("pta not made", procName, NULL); 00558 for (i = 0; i < n; i++) { 00559 if (type == 0) { /* data is float */ 00560 if (fscanf(fp, " (%f, %f)\n", &x, &y) != 2) 00561 return (PTA *)ERROR_PTR("error reading floats", procName, NULL); 00562 ptaAddPt(pta, x, y); 00563 } 00564 else { /* data is integer */ 00565 if (fscanf(fp, " (%d, %d)\n", &ix, &iy) != 2) 00566 return (PTA *)ERROR_PTR("error reading ints", procName, NULL); 00567 ptaAddPt(pta, ix, iy); 00568 } 00569 } 00570 00571 return pta; 00572 } 00573 00574 00575 /*! 00576 * ptaWrite() 00577 * 00578 * Input: filename 00579 * pta 00580 * type (0 for float values; 1 for integer values) 00581 * Return: 0 if OK, 1 on error 00582 */ 00583 l_int32 00584 ptaWrite(const char *filename, 00585 PTA *pta, 00586 l_int32 type) 00587 { 00588 FILE *fp; 00589 00590 PROCNAME("ptaWrite"); 00591 00592 if (!filename) 00593 return ERROR_INT("filename not defined", procName, 1); 00594 if (!pta) 00595 return ERROR_INT("pta not defined", procName, 1); 00596 00597 if ((fp = fopenWriteStream(filename, "w")) == NULL) 00598 return ERROR_INT("stream not opened", procName, 1); 00599 if (ptaWriteStream(fp, pta, type)) 00600 return ERROR_INT("pta not written to stream", procName, 1); 00601 fclose(fp); 00602 00603 return 0; 00604 } 00605 00606 00607 /*! 00608 * ptaWriteStream() 00609 * 00610 * Input: stream 00611 * pta 00612 * type (0 for float values; 1 for integer values) 00613 * Return: 0 if OK; 1 on error 00614 */ 00615 l_int32 00616 ptaWriteStream(FILE *fp, 00617 PTA *pta, 00618 l_int32 type) 00619 { 00620 l_int32 i, n, ix, iy; 00621 l_float32 x, y; 00622 00623 PROCNAME("ptaWriteStream"); 00624 00625 if (!fp) 00626 return ERROR_INT("stream not defined", procName, 1); 00627 if (!pta) 00628 return ERROR_INT("pta not defined", procName, 1); 00629 00630 n = ptaGetCount(pta); 00631 fprintf(fp, "\n Pta Version %d\n", PTA_VERSION_NUMBER); 00632 if (type == 0) 00633 fprintf(fp, " Number of pts = %d; format = float\n", n); 00634 else /* type == 1 */ 00635 fprintf(fp, " Number of pts = %d; format = integer\n", n); 00636 for (i = 0; i < n; i++) { 00637 if (type == 0) { /* data is float */ 00638 ptaGetPt(pta, i, &x, &y); 00639 fprintf(fp, " (%f, %f)\n", x, y); 00640 } 00641 else { /* data is integer */ 00642 ptaGetIPt(pta, i, &ix, &iy); 00643 fprintf(fp, " (%d, %d)\n", ix, iy); 00644 } 00645 } 00646 00647 return 0; 00648 } 00649 00650 00651 /*---------------------------------------------------------------------* 00652 * PTAA creation, destruction * 00653 *---------------------------------------------------------------------*/ 00654 /*! 00655 * ptaaCreate() 00656 * 00657 * Input: n (initial number of ptrs) 00658 * Return: ptaa, or null on error 00659 */ 00660 PTAA * 00661 ptaaCreate(l_int32 n) 00662 { 00663 PTAA *ptaa; 00664 00665 PROCNAME("ptaaCreate"); 00666 00667 if (n <= 0) 00668 n = INITIAL_PTR_ARRAYSIZE; 00669 00670 if ((ptaa = (PTAA *)CALLOC(1, sizeof(PTAA))) == NULL) 00671 return (PTAA *)ERROR_PTR("ptaa not made", procName, NULL); 00672 ptaa->n = 0; 00673 ptaa->nalloc = n; 00674 00675 if ((ptaa->pta = (PTA **)CALLOC(n, sizeof(PTA *))) == NULL) 00676 return (PTAA *)ERROR_PTR("pta ptrs not made", procName, NULL); 00677 00678 return ptaa; 00679 } 00680 00681 00682 /*! 00683 * ptaaDestroy() 00684 * 00685 * Input: &ptaa <to be nulled> 00686 * Return: void 00687 */ 00688 void 00689 ptaaDestroy(PTAA **pptaa) 00690 { 00691 l_int32 i; 00692 PTAA *ptaa; 00693 00694 PROCNAME("ptaaDestroy"); 00695 00696 if (pptaa == NULL) { 00697 L_WARNING("ptr address is NULL!", procName); 00698 return; 00699 } 00700 00701 if ((ptaa = *pptaa) == NULL) 00702 return; 00703 00704 for (i = 0; i < ptaa->n; i++) 00705 ptaDestroy(&ptaa->pta[i]); 00706 FREE(ptaa->pta); 00707 00708 FREE(ptaa); 00709 *pptaa = NULL; 00710 return; 00711 } 00712 00713 00714 /*---------------------------------------------------------------------* 00715 * PTAA array extension * 00716 *---------------------------------------------------------------------*/ 00717 /*! 00718 * ptaaAddPta() 00719 * 00720 * Input: ptaa 00721 * pta (to be added) 00722 * copyflag (L_INSERT, L_COPY, L_CLONE) 00723 * Return: 0 if OK, 1 on error 00724 */ 00725 l_int32 00726 ptaaAddPta(PTAA *ptaa, 00727 PTA *pta, 00728 l_int32 copyflag) 00729 { 00730 l_int32 n; 00731 PTA *ptac; 00732 00733 PROCNAME("ptaaAddPta"); 00734 00735 if (!ptaa) 00736 return ERROR_INT("ptaa not defined", procName, 1); 00737 if (!pta) 00738 return ERROR_INT("pta not defined", procName, 1); 00739 00740 if (copyflag == L_INSERT) 00741 ptac = pta; 00742 else if (copyflag == L_COPY) { 00743 if ((ptac = ptaCopy(pta)) == NULL) 00744 return ERROR_INT("ptac not made", procName, 1); 00745 } 00746 else if (copyflag == L_CLONE) { 00747 if ((ptac = ptaClone(pta)) == NULL) 00748 return ERROR_INT("pta clone not made", procName, 1); 00749 } 00750 else 00751 return ERROR_INT("invalid copyflag", procName, 1); 00752 00753 n = ptaaGetCount(ptaa); 00754 if (n >= ptaa->nalloc) 00755 ptaaExtendArray(ptaa); 00756 ptaa->pta[n] = ptac; 00757 ptaa->n++; 00758 00759 return 0; 00760 } 00761 00762 00763 /*! 00764 * ptaaExtendArray() 00765 * 00766 * Input: ptaa 00767 * Return: 0 if OK, 1 on error 00768 */ 00769 l_int32 00770 ptaaExtendArray(PTAA *ptaa) 00771 { 00772 PROCNAME("ptaaExtendArray"); 00773 00774 if (!ptaa) 00775 return ERROR_INT("ptaa not defined", procName, 1); 00776 00777 if ((ptaa->pta = (PTA **)reallocNew((void **)&ptaa->pta, 00778 sizeof(PTA *) * ptaa->nalloc, 00779 2 * sizeof(PTA *) * ptaa->nalloc)) == NULL) 00780 return ERROR_INT("new ptr array not returned", procName, 1); 00781 00782 ptaa->nalloc = 2 * ptaa->nalloc; 00783 return 0; 00784 } 00785 00786 00787 /*---------------------------------------------------------------------* 00788 * Ptaa accessors * 00789 *---------------------------------------------------------------------*/ 00790 /*! 00791 * ptaaGetCount() 00792 * 00793 * Input: ptaa 00794 * Return: count, or 0 if no ptaa 00795 */ 00796 l_int32 00797 ptaaGetCount(PTAA *ptaa) 00798 { 00799 PROCNAME("ptaaGetCount"); 00800 00801 if (!ptaa) 00802 return ERROR_INT("ptaa not defined", procName, 0); 00803 00804 return ptaa->n; 00805 } 00806 00807 00808 /*! 00809 * ptaaGetPta() 00810 * 00811 * Input: ptaa 00812 * index (to the i-th pta) 00813 * accessflag (L_COPY or L_CLONE) 00814 * Return: pta, or null on error 00815 */ 00816 PTA * 00817 ptaaGetPta(PTAA *ptaa, 00818 l_int32 index, 00819 l_int32 accessflag) 00820 { 00821 PROCNAME("ptaaGetPta"); 00822 00823 if (!ptaa) 00824 return (PTA *)ERROR_PTR("ptaa not defined", procName, NULL); 00825 if (index < 0 || index >= ptaa->n) 00826 return (PTA *)ERROR_PTR("index not valid", procName, NULL); 00827 00828 if (accessflag == L_COPY) 00829 return ptaCopy(ptaa->pta[index]); 00830 else if (accessflag == L_CLONE) 00831 return ptaClone(ptaa->pta[index]); 00832 else 00833 return (PTA *)ERROR_PTR("invalid accessflag", procName, NULL); 00834 } 00835 00836 00837 /*! 00838 * ptaaGetPt() 00839 * 00840 * Input: ptaa 00841 * ipta (to the i-th pta) 00842 * jpt (index to the j-th pt in the pta) 00843 * &x (<optional return> float x value) 00844 * &y (<optional return> float y value) 00845 * Return: 0 if OK; 1 on error 00846 */ 00847 l_int32 00848 ptaaGetPt(PTAA *ptaa, 00849 l_int32 ipta, 00850 l_int32 jpt, 00851 l_float32 *px, 00852 l_float32 *py) 00853 { 00854 PTA *pta; 00855 00856 PROCNAME("ptaaGetPt"); 00857 00858 if (px) *px = 0; 00859 if (py) *py = 0; 00860 if (!ptaa) 00861 return ERROR_INT("ptaa not defined", procName, 1); 00862 if (ipta < 0 || ipta >= ptaa->n) 00863 return ERROR_INT("index ipta not valid", procName, 1); 00864 00865 pta = ptaaGetPta(ptaa, ipta, L_CLONE); 00866 if (jpt < 0 || jpt >= pta->n) { 00867 ptaDestroy(&pta); 00868 return ERROR_INT("index jpt not valid", procName, 1); 00869 } 00870 00871 ptaGetPt(pta, jpt, px, py); 00872 ptaDestroy(&pta); 00873 return 0; 00874 } 00875 00876 00877 /*---------------------------------------------------------------------* 00878 * Ptaa serialized for I/O * 00879 *---------------------------------------------------------------------*/ 00880 /*! 00881 * ptaaRead() 00882 * 00883 * Input: filename 00884 * Return: ptaa, or null on error 00885 */ 00886 PTAA * 00887 ptaaRead(const char *filename) 00888 { 00889 FILE *fp; 00890 PTAA *ptaa; 00891 00892 PROCNAME("ptaaRead"); 00893 00894 if (!filename) 00895 return (PTAA *)ERROR_PTR("filename not defined", procName, NULL); 00896 if ((fp = fopenReadStream(filename)) == NULL) 00897 return (PTAA *)ERROR_PTR("stream not opened", procName, NULL); 00898 00899 if ((ptaa = ptaaReadStream(fp)) == NULL) { 00900 fclose(fp); 00901 return (PTAA *)ERROR_PTR("ptaa not read", procName, NULL); 00902 } 00903 00904 fclose(fp); 00905 return ptaa; 00906 } 00907 00908 00909 /*! 00910 * ptaaReadStream() 00911 * 00912 * Input: stream 00913 * Return: ptaa, or null on error 00914 */ 00915 PTAA * 00916 ptaaReadStream(FILE *fp) 00917 { 00918 l_int32 i, n, version; 00919 PTA *pta; 00920 PTAA *ptaa; 00921 00922 PROCNAME("ptaaReadStream"); 00923 00924 if (!fp) 00925 return (PTAA *)ERROR_PTR("stream not defined", procName, NULL); 00926 00927 if (fscanf(fp, "\nPtaa Version %d\n", &version) != 1) 00928 return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL); 00929 if (version != PTA_VERSION_NUMBER) 00930 return (PTAA *)ERROR_PTR("invalid ptaa version", procName, NULL); 00931 if (fscanf(fp, "Number of Pta = %d\n", &n) != 1) 00932 return (PTAA *)ERROR_PTR("not a ptaa file", procName, NULL); 00933 00934 if ((ptaa = ptaaCreate(n)) == NULL) 00935 return (PTAA *)ERROR_PTR("ptaa not made", procName, NULL); 00936 for (i = 0; i < n; i++) { 00937 if ((pta = ptaReadStream(fp)) == NULL) 00938 return (PTAA *)ERROR_PTR("error reading pta", procName, NULL); 00939 ptaaAddPta(ptaa, pta, L_INSERT); 00940 } 00941 00942 return ptaa; 00943 } 00944 00945 00946 /*! 00947 * ptaaWrite() 00948 * 00949 * Input: filename 00950 * ptaa 00951 * type (0 for float values; 1 for integer values) 00952 * Return: 0 if OK, 1 on error 00953 */ 00954 l_int32 00955 ptaaWrite(const char *filename, 00956 PTAA *ptaa, 00957 l_int32 type) 00958 { 00959 FILE *fp; 00960 00961 PROCNAME("ptaaWrite"); 00962 00963 if (!filename) 00964 return ERROR_INT("filename not defined", procName, 1); 00965 if (!ptaa) 00966 return ERROR_INT("ptaa not defined", procName, 1); 00967 00968 if ((fp = fopenWriteStream(filename, "w")) == NULL) 00969 return ERROR_INT("stream not opened", procName, 1); 00970 if (ptaaWriteStream(fp, ptaa, type)) 00971 return ERROR_INT("ptaa not written to stream", procName, 1); 00972 fclose(fp); 00973 00974 return 0; 00975 } 00976 00977 00978 /*! 00979 * ptaaWriteStream() 00980 * 00981 * Input: stream 00982 * ptaa 00983 * type (0 for float values; 1 for integer values) 00984 * Return: 0 if OK; 1 on error 00985 */ 00986 l_int32 00987 ptaaWriteStream(FILE *fp, 00988 PTAA *ptaa, 00989 l_int32 type) 00990 { 00991 l_int32 i, n; 00992 PTA *pta; 00993 00994 PROCNAME("ptaaWriteStream"); 00995 00996 if (!fp) 00997 return ERROR_INT("stream not defined", procName, 1); 00998 if (!ptaa) 00999 return ERROR_INT("ptaa not defined", procName, 1); 01000 01001 n = ptaaGetCount(ptaa); 01002 fprintf(fp, "\nPtaa Version %d\n", PTA_VERSION_NUMBER); 01003 fprintf(fp, "Number of Pta = %d\n", n); 01004 for (i = 0; i < n; i++) { 01005 pta = ptaaGetPta(ptaa, i, L_CLONE); 01006 ptaWriteStream(fp, pta, type); 01007 ptaDestroy(&pta); 01008 } 01009 01010 return 0; 01011 } 01012