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