Leptonica  1.77.0
Image processing and image analysis suite
queue.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 
65 #include <string.h>
66 #include "allheaders.h"
67 
68 static const l_int32 MIN_BUFFER_SIZE = 20; /* n'importe quoi */
69 static const l_int32 INITIAL_BUFFER_ARRAYSIZE = 1024; /* n'importe quoi */
70 
71  /* Static function */
72 static l_int32 lqueueExtendArray(L_QUEUE *lq);
73 
74 
75 /*--------------------------------------------------------------------------*
76  * L_Queue create/destroy *
77  *--------------------------------------------------------------------------*/
89 L_QUEUE *
91 {
92 L_QUEUE *lq;
93 
94  PROCNAME("lqueueCreate");
95 
96  if (nalloc < MIN_BUFFER_SIZE)
98 
99  lq = (L_QUEUE *)LEPT_CALLOC(1, sizeof(L_QUEUE));
100  if ((lq->array = (void **)LEPT_CALLOC(nalloc, sizeof(void *))) == NULL) {
101  lqueueDestroy(&lq, 0);
102  return (L_QUEUE *)ERROR_PTR("ptr array not made", procName, NULL);
103  }
104  lq->nalloc = nalloc;
105  lq->nhead = lq->nelem = 0;
106  return lq;
107 }
108 
109 
130 void
132  l_int32 freeflag)
133 {
134 void *item;
135 L_QUEUE *lq;
136 
137  PROCNAME("lqueueDestroy");
138 
139  if (plq == NULL) {
140  L_WARNING("ptr address is NULL\n", procName);
141  return;
142  }
143  if ((lq = *plq) == NULL)
144  return;
145 
146  if (freeflag) {
147  while(lq->nelem > 0) {
148  item = lqueueRemove(lq);
149  LEPT_FREE(item);
150  }
151  } else if (lq->nelem > 0) {
152  L_WARNING("memory leak of %d items in lqueue!\n", procName, lq->nelem);
153  }
154 
155  if (lq->array)
156  LEPT_FREE(lq->array);
157  if (lq->stack)
158  lstackDestroy(&lq->stack, freeflag);
159  LEPT_FREE(lq);
160  *plq = NULL;
161 
162  return;
163 }
164 
165 
166 /*--------------------------------------------------------------------------*
167  * Accessors *
168  *--------------------------------------------------------------------------*/
186 l_ok
188  void *item)
189 {
190  PROCNAME("lqueueAdd");
191 
192  if (!lq)
193  return ERROR_INT("lq not defined", procName, 1);
194  if (!item)
195  return ERROR_INT("item not defined", procName, 1);
196 
197  /* If filled to the end and the ptrs can be shifted to the left,
198  * shift them. */
199  if ((lq->nhead + lq->nelem >= lq->nalloc) && (lq->nhead != 0)) {
200  memmove(lq->array, lq->array + lq->nhead, sizeof(void *) * lq->nelem);
201  lq->nhead = 0;
202  }
203 
204  /* If necessary, expand the allocated array by a factor of 2 */
205  if (lq->nelem > 0.75 * lq->nalloc)
206  lqueueExtendArray(lq);
207 
208  /* Now add the item */
209  lq->array[lq->nhead + lq->nelem] = (void *)item;
210  lq->nelem++;
211 
212  return 0;
213 }
214 
215 
222 static l_int32
224 {
225  PROCNAME("lqueueExtendArray");
226 
227  if (!lq)
228  return ERROR_INT("lq not defined", procName, 1);
229 
230  if ((lq->array = (void **)reallocNew((void **)&lq->array,
231  sizeof(void *) * lq->nalloc,
232  2 * sizeof(void *) * lq->nalloc)) == NULL)
233  return ERROR_INT("new ptr array not returned", procName, 1);
234 
235  lq->nalloc = 2 * lq->nalloc;
236  return 0;
237 }
238 
239 
253 void *
255 {
256 void *item;
257 
258  PROCNAME("lqueueRemove");
259 
260  if (!lq)
261  return (void *)ERROR_PTR("lq not defined", procName, NULL);
262 
263  if (lq->nelem == 0)
264  return NULL;
265  item = lq->array[lq->nhead];
266  lq->array[lq->nhead] = NULL;
267  if (lq->nelem == 1)
268  lq->nhead = 0; /* reset head ptr */
269  else
270  (lq->nhead)++; /* can't go off end of array because nelem > 1 */
271  lq->nelem--;
272  return item;
273 }
274 
275 
282 l_int32
284 {
285  PROCNAME("lqueueGetCount");
286 
287  if (!lq)
288  return ERROR_INT("lq not defined", procName, 0);
289 
290  return lq->nelem;
291 }
292 
293 
294 /*---------------------------------------------------------------------*
295  * Debug output *
296  *---------------------------------------------------------------------*/
304 l_ok
305 lqueuePrint(FILE *fp,
306  L_QUEUE *lq)
307 {
308 l_int32 i;
309 
310  PROCNAME("lqueuePrint");
311 
312  if (!fp)
313  return ERROR_INT("stream not defined", procName, 1);
314  if (!lq)
315  return ERROR_INT("lq not defined", procName, 1);
316 
317  fprintf(fp, "\n L_Queue: nalloc = %d, nhead = %d, nelem = %d, array = %p\n",
318  lq->nalloc, lq->nhead, lq->nelem, lq->array);
319  for (i = lq->nhead; i < lq->nhead + lq->nelem; i++)
320  fprintf(fp, "array[%d] = %p\n", i, lq->array[i]);
321 
322  return 0;
323 }
l_int32 nalloc
Definition: queue.h:66
l_ok lqueuePrint(FILE *fp, L_QUEUE *lq)
lqueuePrint()
Definition: queue.c:305
void lstackDestroy(L_STACK **plstack, l_int32 freeflag)
lstackDestroy()
Definition: stack.c:121
L_QUEUE * lqueueCreate(l_int32 nalloc)
lqueueCreate()
Definition: queue.c:90
l_int32 nelem
Definition: queue.h:69
struct L_Stack * stack
Definition: queue.h:71
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1161
void * lqueueRemove(L_QUEUE *lq)
lqueueRemove()
Definition: queue.c:254
void ** array
Definition: queue.h:70
l_int32 nalloc
Definition: ptra.h:64
l_ok lqueueAdd(L_QUEUE *lq, void *item)
lqueueAdd()
Definition: queue.c:187
Definition: queue.h:64
l_int32 lqueueGetCount(L_QUEUE *lq)
lqueueGetCount()
Definition: queue.c:283
void lqueueDestroy(L_QUEUE **plq, l_int32 freeflag)
lqueueDestroy()
Definition: queue.c:131
static l_int32 lqueueExtendArray(L_QUEUE *lq)
lqueueExtendArray()
Definition: queue.c:223
static const l_int32 INITIAL_BUFFER_ARRAYSIZE
Definition: bbuffer.c:103
l_int32 nhead
Definition: queue.h:67