Leptonica  1.83.1
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 #ifdef HAVE_CONFIG_H
101 #include <config_auto.h>
102 #endif /* HAVE_CONFIG_H */
103 
104 #include <string.h>
105 #include "allheaders.h"
106 
107  /* Bounds on array size */
108 static const l_uint32 MaxArraySize = 1000000000; /* 10^9 bytes */
109 static const l_int32 InitialArraySize = 1024;
111 /*--------------------------------------------------------------------------*
112  * BBuffer create/destroy *
113  *--------------------------------------------------------------------------*/
129 L_BBUFFER *
130 bbufferCreate(const l_uint8 *indata,
131  l_int32 nalloc)
132 {
133 L_BBUFFER *bb;
134 
135  if (nalloc <= 0 || nalloc > MaxArraySize)
136  nalloc = InitialArraySize;
137 
138  bb = (L_BBUFFER *)LEPT_CALLOC(1, sizeof(L_BBUFFER));
139  if ((bb->array = (l_uint8 *)LEPT_CALLOC(nalloc, sizeof(l_uint8))) == NULL) {
140  LEPT_FREE(bb);
141  return (L_BBUFFER *)ERROR_PTR("byte array not made", __func__, NULL);
142  }
143  bb->nalloc = nalloc;
144  bb->nwritten = 0;
145 
146  if (indata) {
147  memcpy(bb->array, indata, nalloc);
148  bb->n = nalloc;
149  } else {
150  bb->n = 0;
151  }
152 
153  return bb;
154 }
155 
156 
169 void
171 {
172 L_BBUFFER *bb;
173 
174  if (pbb == NULL) {
175  L_WARNING("ptr address is NULL\n", __func__);
176  return;
177  }
178 
179  if ((bb = *pbb) == NULL)
180  return;
181 
182  if (bb->array)
183  LEPT_FREE(bb->array);
184  LEPT_FREE(bb);
185  *pbb = NULL;
186 }
187 
188 
201 l_uint8 *
203  size_t *pnbytes)
204 {
205 l_uint8 *array;
206 size_t nbytes;
207 L_BBUFFER *bb;
208 
209  if (pbb == NULL) {
210  L_WARNING("ptr address is NULL\n", __func__);
211  return NULL;
212  }
213  if (pnbytes == NULL) {
214  L_WARNING("&nbytes is NULL\n", __func__);
215  bbufferDestroy(pbb);
216  return NULL;
217  }
218 
219  if ((bb = *pbb) == NULL)
220  return NULL;
221 
222  /* write all unwritten bytes out to a new array */
223  nbytes = bb->n - bb->nwritten;
224  *pnbytes = nbytes;
225  if ((array = (l_uint8 *)LEPT_CALLOC(nbytes, sizeof(l_uint8))) == NULL) {
226  L_WARNING("calloc failure for array\n", __func__);
227  return NULL;
228  }
229  memcpy(array, bb->array + bb->nwritten, nbytes);
230 
231  bbufferDestroy(pbb);
232  return array;
233 }
234 
235 
236 /*--------------------------------------------------------------------------*
237  * Operations to read data INTO a BBuffer *
238  *--------------------------------------------------------------------------*/
258 l_ok
260  l_uint8 *src,
261  l_int32 nbytes)
262 {
263 l_int32 navail, nadd, nwritten;
264 
265  if (!bb)
266  return ERROR_INT("bb not defined", __func__, 1);
267  if (!src)
268  return ERROR_INT("src not defined", __func__, 1);
269  if (nbytes == 0)
270  return ERROR_INT("no bytes to read", __func__, 1);
271 
272  if ((nwritten = bb->nwritten)) { /* move the unwritten bytes over */
273  memmove(bb->array, bb->array + nwritten, bb->n - nwritten);
274  bb->nwritten = 0;
275  bb->n -= nwritten;
276  }
277 
278  /* If necessary, expand the allocated array. Do so by
279  * by at least a factor of two. */
280  navail = bb->nalloc - bb->n;
281  if (nbytes > navail) {
282  nadd = L_MAX(bb->nalloc, nbytes);
283  if (bbufferExtendArray(bb, nadd))
284  return ERROR_INT("extension failed", __func__, 1);
285  }
286 
287  /* Read in the new bytes */
288  memcpy(bb->array + bb->n, src, nbytes);
289  bb->n += nbytes;
290  return 0;
291 }
292 
293 
302 l_ok
304  FILE *fp,
305  l_int32 nbytes)
306 {
307 l_int32 navail, nadd, nread, nwritten;
308 
309  if (!bb)
310  return ERROR_INT("bb not defined", __func__, 1);
311  if (!fp)
312  return ERROR_INT("fp not defined", __func__, 1);
313  if (nbytes == 0)
314  return ERROR_INT("no bytes to read", __func__, 1);
315 
316  if ((nwritten = bb->nwritten)) { /* move any unwritten bytes over */
317  memmove(bb->array, bb->array + nwritten, bb->n - nwritten);
318  bb->nwritten = 0;
319  bb->n -= nwritten;
320  }
321 
322  /* If necessary, expand the allocated array. Do so by
323  * by at least a factor of two. */
324  navail = bb->nalloc - bb->n;
325  if (nbytes > navail) {
326  nadd = L_MAX(bb->nalloc, nbytes);
327  if (bbufferExtendArray(bb, nadd))
328  return ERROR_INT("extension failed", __func__, 1);
329  }
330 
331  /* Read in the new bytes */
332  nread = fread(bb->array + bb->n, 1, nbytes, fp);
333  bb->n += nread;
334 
335  return 0;
336 }
337 
338 
352 l_ok
354  l_int32 nbytes)
355 {
356  if (!bb)
357  return ERROR_INT("bb not defined", __func__, 1);
358 
359  if ((bb->array = (l_uint8 *)reallocNew((void **)&bb->array,
360  bb->nalloc,
361  bb->nalloc + nbytes)) == NULL)
362  return ERROR_INT("new ptr array not returned", __func__, 1);
363 
364  bb->nalloc += nbytes;
365  return 0;
366 }
367 
368 
369 /*--------------------------------------------------------------------------*
370  * Operations to write data FROM a BBuffer *
371  *--------------------------------------------------------------------------*/
381 l_ok
383  l_uint8 *dest,
384  size_t nbytes,
385  size_t *pnout)
386 {
387 size_t nleft, nout;
388 
389  if (!bb)
390  return ERROR_INT("bb not defined", __func__, 1);
391  if (!dest)
392  return ERROR_INT("dest not defined", __func__, 1);
393  if (nbytes <= 0)
394  return ERROR_INT("no bytes requested to write", __func__, 1);
395  if (!pnout)
396  return ERROR_INT("&nout not defined", __func__, 1);
397 
398  nleft = bb->n - bb->nwritten;
399  nout = L_MIN(nleft, nbytes);
400  *pnout = nout;
401 
402  if (nleft == 0) { /* nothing to write; reinitialize the buffer */
403  bb->n = 0;
404  bb->nwritten = 0;
405  return 0;
406  }
407 
408  /* nout > 0; transfer the data out */
409  memcpy(dest, bb->array + bb->nwritten, nout);
410  bb->nwritten += nout;
411 
412  /* If all written; "empty" the buffer */
413  if (nout == nleft) {
414  bb->n = 0;
415  bb->nwritten = 0;
416  }
417 
418  return 0;
419 }
420 
421 
431 l_ok
433  FILE *fp,
434  size_t nbytes,
435  size_t *pnout)
436 {
437 size_t nleft, nout;
438 
439  if (!bb)
440  return ERROR_INT("bb not defined", __func__, 1);
441  if (!fp)
442  return ERROR_INT("output stream not defined", __func__, 1);
443  if (nbytes <= 0)
444  return ERROR_INT("no bytes requested to write", __func__, 1);
445  if (!pnout)
446  return ERROR_INT("&nout not defined", __func__, 1);
447 
448  nleft = bb->n - bb->nwritten;
449  nout = L_MIN(nleft, nbytes);
450  *pnout = nout;
451 
452  if (nleft == 0) { /* nothing to write; reinitialize the buffer */
453  bb->n = 0;
454  bb->nwritten = 0;
455  return 0;
456  }
457 
458  /* nout > 0; transfer the data out */
459  fwrite(bb->array + bb->nwritten, 1, nout, fp);
460  bb->nwritten += nout;
461 
462  /* If all written; "empty" the buffer */
463  if (nout == nleft) {
464  bb->n = 0;
465  bb->nwritten = 0;
466  }
467 
468  return 0;
469 }
l_ok bbufferWrite(L_BBUFFER *bb, l_uint8 *dest, size_t nbytes, size_t *pnout)
bbufferWrite()
Definition: bbuffer.c:382
l_ok bbufferRead(L_BBUFFER *bb, l_uint8 *src, l_int32 nbytes)
bbufferRead()
Definition: bbuffer.c:259
L_BBUFFER * bbufferCreate(const l_uint8 *indata, l_int32 nalloc)
bbufferCreate()
Definition: bbuffer.c:130
l_ok bbufferExtendArray(L_BBUFFER *bb, l_int32 nbytes)
bbufferExtendArray()
Definition: bbuffer.c:353
static const l_int32 InitialArraySize
Definition: bbuffer.c:109
l_ok bbufferReadStream(L_BBUFFER *bb, FILE *fp, l_int32 nbytes)
bbufferReadStream()
Definition: bbuffer.c:303
l_ok bbufferWriteStream(L_BBUFFER *bb, FILE *fp, size_t nbytes, size_t *pnout)
bbufferWriteStream()
Definition: bbuffer.c:432
l_uint8 * bbufferDestroyAndSaveData(L_BBUFFER **pbb, size_t *pnbytes)
bbufferDestroyAndSaveData()
Definition: bbuffer.c:202
void bbufferDestroy(L_BBUFFER **pbb)
bbufferDestroy()
Definition: bbuffer.c:170
l_int32 n
Definition: bbuffer.h:53
l_int32 nalloc
Definition: bbuffer.h:52
l_int32 nwritten
Definition: bbuffer.h:54
l_uint8 * array
Definition: bbuffer.h:55
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1262