/*! * lstackDestroy() * * Input: &lstack (<to be nulled>) * freeflag (TRUE to free each remaining struct in the array) * Return: void * * Notes: * (1) If freeflag is TRUE, frees each struct in the array. * (2) If freeflag is FALSE but there are elements on the array, * gives a warning and destroys the array. This will * cause a memory leak of all the items that were on the lstack. * So if the items require their own destroy function, they * must be destroyed before the lstack. * (3) To destroy the lstack, we destroy the ptr array, then * the lstack, and then null the contents of the input ptr. */ void lstackDestroy(L_STACK **plstack, l_int32 freeflag) { void *item; L_STACK *lstack; PROCNAME("lstackDestroy"); if (plstack == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((lstack = *plstack) == NULL) return; if (freeflag) { while(lstack->n > 0) { item = lstackRemove(lstack); LEPT_FREE(item); } } else if (lstack->n > 0) { L_WARNING("memory leak of %d items in lstack\n", procName, lstack->n); } if (lstack->auxstack) lstackDestroy(&lstack->auxstack, freeflag); if (lstack->array) LEPT_FREE(lstack->array); LEPT_FREE(lstack); *plstack = NULL; }
/*! * \brief popFillseg() * * \param[in] stack * \param[out] pxleft left x * \param[out] pxright right x * \param[out] py y coordinate * \param[out] pdy delta y * \return void * * <pre> * Notes: * (1) This removes a line segment from the stack, and returns its size. * (2) The surplussed fillseg is placed on the auxiliary stack * for future use. * </pre> */ static void popFillseg(L_STACK *stack, l_int32 *pxleft, l_int32 *pxright, l_int32 *py, l_int32 *pdy) { FILLSEG *fseg; L_STACK *auxstack; PROCNAME("popFillseg"); if (!stack) { L_ERROR("stack not defined\n", procName); return; } if ((auxstack = stack->auxstack) == NULL) { L_ERROR("auxstack not defined\n", procName); return; } if ((fseg = (FILLSEG *)lstackRemove(stack)) == NULL) return; *pxleft = fseg->xleft; *pxright = fseg->xright; *py = fseg->y + fseg->dy; /* this now points to the new line */ *pdy = fseg->dy; /* Save it for re-use */ lstackAdd(auxstack, fseg); return; }
/* * pushWSPixel() * * Input: lh (priority queue) * stack (of reusable WSPixels) * val (pixel value: used for ordering the heap) * x, y (pixel coordinates) * index (label for set to which pixel belongs) * Return: void * * Notes: * (1) This is a wrapper for adding a WSPixel to a heap. It * uses the storage stack to retrieve a WSPixel. */ static void pushWSPixel(L_HEAP *lh, L_STACK *stack, l_int32 val, l_int32 x, l_int32 y, l_int32 index) { L_WSPIXEL *wsp; PROCNAME("pushWSPixel"); if (!lh) { L_ERROR("heap not defined\n", procName); return; } if (!stack) { L_ERROR("stack not defined\n", procName); return; } /* Get a wspixel to use */ if (lstackGetCount(stack) > 0) wsp = (L_WSPIXEL *) lstackRemove(stack); else wsp = (L_WSPIXEL *) CALLOC(1, sizeof(L_WSPIXEL)); wsp->val = (l_float32) val; wsp->x = x; wsp->y = y; wsp->index = index; lheapAdd(lh, wsp); return; }
/* * pushNewPixel() * * Input: lqueue * x, y (pixel coordinates) * &minx, &maxx, &miny, &maxy (<return> bounding box update) * Return: void * * Notes: * (1) This is a wrapper for adding a NewPixel to a queue, which * updates the bounding box for all pixels on that queue and * uses the storage stack to retrieve a NewPixel. */ static void pushNewPixel(L_QUEUE *lq, l_int32 x, l_int32 y, l_int32 *pminx, l_int32 *pmaxx, l_int32 *pminy, l_int32 *pmaxy) { L_NEWPIXEL *np; PROCNAME("pushNewPixel"); if (!lq) { L_ERROR("queue not defined\n", procName); return; } /* Adjust bounding box */ *pminx = L_MIN(*pminx, x); *pmaxx = L_MAX(*pmaxx, x); *pminy = L_MIN(*pminy, y); *pmaxy = L_MAX(*pmaxy, y); /* Get a newpixel to use */ if (lstackGetCount(lq->stack) > 0) np = (L_NEWPIXEL *) lstackRemove(lq->stack); else np = (L_NEWPIXEL *) CALLOC(1, sizeof(L_NEWPIXEL)); np->x = x; np->y = y; lqueueAdd(lq, np); return; }
/*! * \brief pushFillsegBB() * * \param[in] stack * \param[in] xleft, xright * \param[in] y * \param[in] dy * \param[in] ymax * \param[out] pminx minimum x * \param[out] pmaxx maximum x * \param[out] pminy minimum y * \param[out] pmaxy maximum y * \return void * * <pre> * Notes: * (1) This adds a line segment to the stack, and returns its size. * (2) The auxiliary stack is used as a storage area to recycle * fillsegs that are no longer in use. We only calloc new * fillsegs if the auxiliary stack is empty. * </pre> */ static void pushFillsegBB(L_STACK *stack, l_int32 xleft, l_int32 xright, l_int32 y, l_int32 dy, l_int32 ymax, l_int32 *pminx, l_int32 *pmaxx, l_int32 *pminy, l_int32 *pmaxy) { FILLSEG *fseg; L_STACK *auxstack; PROCNAME("pushFillsegBB"); if (!stack) { L_ERROR("stack not defined\n", procName); return; } *pminx = L_MIN(*pminx, xleft); *pmaxx = L_MAX(*pmaxx, xright); *pminy = L_MIN(*pminy, y); *pmaxy = L_MAX(*pmaxy, y); if (y + dy >= 0 && y + dy <= ymax) { if ((auxstack = stack->auxstack) == NULL) { L_ERROR("auxstack not defined\n", procName); return; } /* Get a fillseg to use */ if (lstackGetCount(auxstack) > 0) { fseg = (FILLSEG *)lstackRemove(auxstack); } else { if ((fseg = (FILLSEG *)LEPT_CALLOC(1, sizeof(FILLSEG))) == NULL) { L_ERROR("fillseg not made\n", procName); return; } } fseg->xleft = xleft; fseg->xright = xright; fseg->y = y; fseg->dy = dy; lstackAdd(stack, fseg); } return; }
/*! * pushFillseg() * * Input: lstack * xleft, xright * y * dy * ymax * Return: void * * Notes: * (1) This adds a line segment to the stack. * (2) The auxiliary stack is used as a storage area to recycle * fillsegs that are no longer in use. We only calloc new * fillsegs if the auxiliary stack is empty. */ static void pushFillseg(L_STACK *lstack, l_int32 xleft, l_int32 xright, l_int32 y, l_int32 dy, l_int32 ymax) { FILLSEG *fseg; L_STACK *auxstack; PROCNAME("pushFillseg"); if (!lstack) { L_ERROR(procName, "lstack not defined"); return; } if (y + dy >= 0 && y + dy <= ymax) { if ((auxstack = lstack->auxstack) == NULL) { L_ERROR("auxstack not defined", procName); return; } /* Get a fillseg to use */ if (lstackGetCount(auxstack) > 0) fseg = (FILLSEG *)lstackRemove(auxstack); else { if ((fseg = (FILLSEG *)CALLOC(1, sizeof(FILLSEG))) == NULL) { L_ERROR("fillseg not made", procName); return; } } fseg->xleft = xleft; fseg->xright = xright; fseg->y = y; fseg->dy = dy; lstackAdd(lstack, fseg); } return; }