Leptonica 1.68
C Image Processing Library

ptabasic.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines