Leptonica  1.73
Image processing and image analysis suite
bbuffer.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 
100 #include <string.h>
101 #include "allheaders.h"
102 
103 static const l_int32 INITIAL_BUFFER_ARRAYSIZE = 1024;
105 /*--------------------------------------------------------------------------*
106  * BBuffer create/destroy *
107  *--------------------------------------------------------------------------*/
123 L_BBUFFER *
124 bbufferCreate(l_uint8 *indata,
125  l_int32 nalloc)
126 {
127 L_BBUFFER *bb;
128 
129  PROCNAME("bbufferCreate");
130 
131  if (nalloc <= 0)
133 
134  if ((bb = (L_BBUFFER *)LEPT_CALLOC(1, sizeof(L_BBUFFER))) == NULL)
135  return (L_BBUFFER *)ERROR_PTR("bb not made", procName, NULL);
136  if ((bb->array = (l_uint8 *)LEPT_CALLOC(nalloc, sizeof(l_uint8))) == NULL) {
137  LEPT_FREE(bb);
138  return (L_BBUFFER *)ERROR_PTR("byte array not made", procName, NULL);
139  }
140  bb->nalloc = nalloc;
141  bb->nwritten = 0;
142 
143  if (indata) {
144  memcpy((l_uint8 *)bb->array, indata, nalloc);
145  bb->n = nalloc;
146  } else {
147  bb->n = 0;
148  }
149 
150  return bb;
151 }
152 
153 
166 void
168 {
169 L_BBUFFER *bb;
170 
171  PROCNAME("bbufferDestroy");
172 
173  if (pbb == NULL) {
174  L_WARNING("ptr address is NULL\n", procName);
175  return;
176  }
177 
178  if ((bb = *pbb) == NULL)
179  return;
180 
181  if (bb->array)
182  LEPT_FREE(bb->array);
183  LEPT_FREE(bb);
184  *pbb = NULL;
185 
186  return;
187 }
188 
189 
202 l_uint8 *
204  size_t *pnbytes)
205 {
206 l_uint8 *array;
207 size_t nbytes;
208 L_BBUFFER *bb;
209 
210  PROCNAME("bbufferDestroyAndSaveData");
211 
212  if (pbb == NULL) {
213  L_WARNING("ptr address is NULL\n", procName);
214  return NULL;
215  }
216  if (pnbytes == NULL) {
217  L_WARNING("&nbytes is NULL\n", procName);
218  bbufferDestroy(pbb);
219  return NULL;
220  }
221 
222  if ((bb = *pbb) == NULL)
223  return NULL;
224 
225  /* write all unwritten bytes out to a new array */
226  nbytes = bb->n - bb->nwritten;
227  *pnbytes = nbytes;
228  if ((array = (l_uint8 *)LEPT_CALLOC(nbytes, sizeof(l_uint8))) == NULL) {
229  L_WARNING("calloc failure for array\n", procName);
230  return NULL;
231  }
232  memcpy((void *)array, (void *)(bb->array + bb->nwritten), nbytes);
233 
234  bbufferDestroy(pbb);
235  return array;
236 }
237 
238 
239 /*--------------------------------------------------------------------------*
240  * Operations to read data INTO a BBuffer *
241  *--------------------------------------------------------------------------*/
261 l_int32
263  l_uint8 *src,
264  l_int32 nbytes)
265 {
266 l_int32 navail, nadd, nwritten;
267 
268  PROCNAME("bbufferRead");
269 
270  if (!bb)
271  return ERROR_INT("bb not defined", procName, 1);
272  if (!src)
273  return ERROR_INT("src not defined", procName, 1);
274  if (nbytes == 0)
275  return ERROR_INT("no bytes to read", procName, 1);
276 
277  if ((nwritten = bb->nwritten)) { /* move the unwritten bytes over */
278  memmove((l_uint8 *)bb->array, (l_uint8 *)(bb->array + nwritten),
279  bb->n - nwritten);
280  bb->nwritten = 0;
281  bb->n -= nwritten;
282  }
283 
284  /* If necessary, expand the allocated array. Do so by
285  * by at least a factor of two. */
286  navail = bb->nalloc - bb->n;
287  if (nbytes > navail) {
288  nadd = L_MAX(bb->nalloc, nbytes);
289  bbufferExtendArray(bb, nadd);
290  }
291 
292  /* Read in the new bytes */
293  memcpy((l_uint8 *)(bb->array + bb->n), src, nbytes);
294  bb->n += nbytes;
295 
296  return 0;
297 }
298 
299 
308 l_int32
310  FILE *fp,
311  l_int32 nbytes)
312 {
313 l_int32 navail, nadd, nread, nwritten;
314 
315  PROCNAME("bbufferReadStream");
316 
317  if (!bb)
318  return ERROR_INT("bb not defined", procName, 1);
319  if (!fp)
320  return ERROR_INT("fp not defined", procName, 1);
321  if (nbytes == 0)
322  return ERROR_INT("no bytes to read", procName, 1);
323 
324  if ((nwritten = bb->nwritten)) { /* move any unwritten bytes over */
325  memmove((l_uint8 *)bb->array, (l_uint8 *)(bb->array + nwritten),
326  bb->n - nwritten);
327  bb->nwritten = 0;
328  bb->n -= nwritten;
329  }
330 
331  /* If necessary, expand the allocated array. Do so by
332  * by at least a factor of two. */
333  navail = bb->nalloc - bb->n;
334  if (nbytes > navail) {
335  nadd = L_MAX(bb->nalloc, nbytes);
336  bbufferExtendArray(bb, nadd);
337  }
338 
339  /* Read in the new bytes */
340  nread = fread((void *)(bb->array + bb->n), 1, nbytes, fp);
341  bb->n += nread;
342 
343  return 0;
344 }
345 
346 
360 l_int32
362  l_int32 nbytes)
363 {
364  PROCNAME("bbufferExtendArray");
365 
366  if (!bb)
367  return ERROR_INT("bb not defined", procName, 1);
368 
369  if ((bb->array = (l_uint8 *)reallocNew((void **)&bb->array,
370  bb->nalloc,
371  bb->nalloc + nbytes)) == NULL)
372  return ERROR_INT("new ptr array not returned", procName, 1);
373 
374  bb->nalloc += nbytes;
375  return 0;
376 }
377 
378 
379 /*--------------------------------------------------------------------------*
380  * Operations to write data FROM a BBuffer *
381  *--------------------------------------------------------------------------*/
391 l_int32
393  l_uint8 *dest,
394  size_t nbytes,
395  size_t *pnout)
396 {
397 size_t nleft, nout;
398 
399  PROCNAME("bbufferWrite");
400 
401  if (!bb)
402  return ERROR_INT("bb not defined", procName, 1);
403  if (!dest)
404  return ERROR_INT("dest not defined", procName, 1);
405  if (nbytes <= 0)
406  return ERROR_INT("no bytes requested to write", procName, 1);
407  if (!pnout)
408  return ERROR_INT("&nout not defined", procName, 1);
409 
410  nleft = bb->n - bb->nwritten;
411  nout = L_MIN(nleft, nbytes);
412  *pnout = nout;
413 
414  if (nleft == 0) { /* nothing to write; reinitialize the buffer */
415  bb->n = 0;
416  bb->nwritten = 0;
417  return 0;
418  }
419 
420  /* nout > 0; transfer the data out */
421  memcpy(dest, (l_uint8 *)(bb->array + bb->nwritten), nout);
422  bb->nwritten += nout;
423 
424  /* If all written; "empty" the buffer */
425  if (nout == nleft) {
426  bb->n = 0;
427  bb->nwritten = 0;
428  }
429 
430  return 0;
431 }
432 
433 
443 l_int32
445  FILE *fp,
446  size_t nbytes,
447  size_t *pnout)
448 {
449 size_t nleft, nout;
450 
451  PROCNAME("bbufferWriteStream");
452 
453  if (!bb)
454  return ERROR_INT("bb not defined", procName, 1);
455  if (!fp)
456  return ERROR_INT("output stream not defined", procName, 1);
457  if (nbytes <= 0)
458  return ERROR_INT("no bytes requested to write", procName, 1);
459  if (!pnout)
460  return ERROR_INT("&nout not defined", procName, 1);
461 
462  nleft = bb->n - bb->nwritten;
463  nout = L_MIN(nleft, nbytes);
464  *pnout = nout;
465 
466  if (nleft == 0) { /* nothing to write; reinitialize the buffer */
467  bb->n = 0;
468  bb->nwritten = 0;
469  return 0;
470  }
471 
472  /* nout > 0; transfer the data out */
473  fwrite((void *)(bb->array + bb->nwritten), 1, nout, fp);
474  bb->nwritten += nout;
475 
476  /* If all written; "empty" the buffer */
477  if (nout == nleft) {
478  bb->n = 0;
479  bb->nwritten = 0;
480  }
481 
482  return 0;
483 }
l_int32 n
Definition: bbuffer.h:53
l_int32 bbufferWrite(L_BBUFFER *bb, l_uint8 *dest, size_t nbytes, size_t *pnout)
bbufferWrite()
Definition: bbuffer.c:392
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1102
l_uint8 * bbufferDestroyAndSaveData(L_BBUFFER **pbb, size_t *pnbytes)
bbufferDestroyAndSaveData()
Definition: bbuffer.c:203
l_int32 bbufferReadStream(L_BBUFFER *bb, FILE *fp, l_int32 nbytes)
bbufferReadStream()
Definition: bbuffer.c:309
l_int32 nalloc
Definition: bbuffer.h:52
l_uint8 * array
Definition: bbuffer.h:55
l_int32 bbufferExtendArray(L_BBUFFER *bb, l_int32 nbytes)
bbufferExtendArray()
Definition: bbuffer.c:361
void bbufferDestroy(L_BBUFFER **pbb)
bbufferDestroy()
Definition: bbuffer.c:167
l_int32 bbufferWriteStream(L_BBUFFER *bb, FILE *fp, size_t nbytes, size_t *pnout)
bbufferWriteStream()
Definition: bbuffer.c:444
l_int32 bbufferRead(L_BBUFFER *bb, l_uint8 *src, l_int32 nbytes)
bbufferRead()
Definition: bbuffer.c:262
static const l_int32 INITIAL_BUFFER_ARRAYSIZE
Definition: bbuffer.c:103
l_int32 nwritten
Definition: bbuffer.h:54
L_BBUFFER * bbufferCreate(l_uint8 *indata, l_int32 nalloc)
bbufferCreate()
Definition: bbuffer.c:124
size_t nalloc
Definition: array.h:128