Leptonica  1.77.0
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(const 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(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(array, 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_ok
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(bb->array, bb->array + nwritten, bb->n - nwritten);
279  bb->nwritten = 0;
280  bb->n -= nwritten;
281  }
282 
283  /* If necessary, expand the allocated array. Do so by
284  * by at least a factor of two. */
285  navail = bb->nalloc - bb->n;
286  if (nbytes > navail) {
287  nadd = L_MAX(bb->nalloc, nbytes);
288  bbufferExtendArray(bb, nadd);
289  }
290 
291  /* Read in the new bytes */
292  memcpy(bb->array + bb->n, src, nbytes);
293  bb->n += nbytes;
294 
295  return 0;
296 }
297 
298 
307 l_ok
309  FILE *fp,
310  l_int32 nbytes)
311 {
312 l_int32 navail, nadd, nread, nwritten;
313 
314  PROCNAME("bbufferReadStream");
315 
316  if (!bb)
317  return ERROR_INT("bb not defined", procName, 1);
318  if (!fp)
319  return ERROR_INT("fp not defined", procName, 1);
320  if (nbytes == 0)
321  return ERROR_INT("no bytes to read", procName, 1);
322 
323  if ((nwritten = bb->nwritten)) { /* move any unwritten bytes over */
324  memmove(bb->array, bb->array + nwritten, bb->n - nwritten);
325  bb->nwritten = 0;
326  bb->n -= nwritten;
327  }
328 
329  /* If necessary, expand the allocated array. Do so by
330  * by at least a factor of two. */
331  navail = bb->nalloc - bb->n;
332  if (nbytes > navail) {
333  nadd = L_MAX(bb->nalloc, nbytes);
334  bbufferExtendArray(bb, nadd);
335  }
336 
337  /* Read in the new bytes */
338  nread = fread(bb->array + bb->n, 1, nbytes, fp);
339  bb->n += nread;
340 
341  return 0;
342 }
343 
344 
358 l_ok
360  l_int32 nbytes)
361 {
362  PROCNAME("bbufferExtendArray");
363 
364  if (!bb)
365  return ERROR_INT("bb not defined", procName, 1);
366 
367  if ((bb->array = (l_uint8 *)reallocNew((void **)&bb->array,
368  bb->nalloc,
369  bb->nalloc + nbytes)) == NULL)
370  return ERROR_INT("new ptr array not returned", procName, 1);
371 
372  bb->nalloc += nbytes;
373  return 0;
374 }
375 
376 
377 /*--------------------------------------------------------------------------*
378  * Operations to write data FROM a BBuffer *
379  *--------------------------------------------------------------------------*/
389 l_ok
391  l_uint8 *dest,
392  size_t nbytes,
393  size_t *pnout)
394 {
395 size_t nleft, nout;
396 
397  PROCNAME("bbufferWrite");
398 
399  if (!bb)
400  return ERROR_INT("bb not defined", procName, 1);
401  if (!dest)
402  return ERROR_INT("dest not defined", procName, 1);
403  if (nbytes <= 0)
404  return ERROR_INT("no bytes requested to write", procName, 1);
405  if (!pnout)
406  return ERROR_INT("&nout not defined", procName, 1);
407 
408  nleft = bb->n - bb->nwritten;
409  nout = L_MIN(nleft, nbytes);
410  *pnout = nout;
411 
412  if (nleft == 0) { /* nothing to write; reinitialize the buffer */
413  bb->n = 0;
414  bb->nwritten = 0;
415  return 0;
416  }
417 
418  /* nout > 0; transfer the data out */
419  memcpy(dest, bb->array + bb->nwritten, nout);
420  bb->nwritten += nout;
421 
422  /* If all written; "empty" the buffer */
423  if (nout == nleft) {
424  bb->n = 0;
425  bb->nwritten = 0;
426  }
427 
428  return 0;
429 }
430 
431 
441 l_ok
443  FILE *fp,
444  size_t nbytes,
445  size_t *pnout)
446 {
447 size_t nleft, nout;
448 
449  PROCNAME("bbufferWriteStream");
450 
451  if (!bb)
452  return ERROR_INT("bb not defined", procName, 1);
453  if (!fp)
454  return ERROR_INT("output stream not defined", procName, 1);
455  if (nbytes <= 0)
456  return ERROR_INT("no bytes requested to write", procName, 1);
457  if (!pnout)
458  return ERROR_INT("&nout not defined", procName, 1);
459 
460  nleft = bb->n - bb->nwritten;
461  nout = L_MIN(nleft, nbytes);
462  *pnout = nout;
463 
464  if (nleft == 0) { /* nothing to write; reinitialize the buffer */
465  bb->n = 0;
466  bb->nwritten = 0;
467  return 0;
468  }
469 
470  /* nout > 0; transfer the data out */
471  fwrite(bb->array + bb->nwritten, 1, nout, fp);
472  bb->nwritten += nout;
473 
474  /* If all written; "empty" the buffer */
475  if (nout == nleft) {
476  bb->n = 0;
477  bb->nwritten = 0;
478  }
479 
480  return 0;
481 }
l_int32 n
Definition: bbuffer.h:53
L_BBUFFER * bbufferCreate(const l_uint8 *indata, l_int32 nalloc)
bbufferCreate()
Definition: bbuffer.c:124
l_ok bbufferWrite(L_BBUFFER *bb, l_uint8 *dest, size_t nbytes, size_t *pnout)
bbufferWrite()
Definition: bbuffer.c:390
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1161
l_uint8 * bbufferDestroyAndSaveData(L_BBUFFER **pbb, size_t *pnbytes)
bbufferDestroyAndSaveData()
Definition: bbuffer.c:203
l_ok bbufferWriteStream(L_BBUFFER *bb, FILE *fp, size_t nbytes, size_t *pnout)
bbufferWriteStream()
Definition: bbuffer.c:442
l_int32 nalloc
Definition: bbuffer.h:52
l_uint8 * array
Definition: bbuffer.h:55
l_ok bbufferReadStream(L_BBUFFER *bb, FILE *fp, l_int32 nbytes)
bbufferReadStream()
Definition: bbuffer.c:308
void bbufferDestroy(L_BBUFFER **pbb)
bbufferDestroy()
Definition: bbuffer.c:167
l_ok bbufferRead(L_BBUFFER *bb, l_uint8 *src, l_int32 nbytes)
bbufferRead()
Definition: bbuffer.c:262
l_ok bbufferExtendArray(L_BBUFFER *bb, l_int32 nbytes)
bbufferExtendArray()
Definition: bbuffer.c:359
static const l_int32 INITIAL_BUFFER_ARRAYSIZE
Definition: bbuffer.c:103
l_int32 nwritten
Definition: bbuffer.h:54
size_t nalloc
Definition: array.h:128