Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
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 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
169void
171{
172L_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
201l_uint8 *
203 size_t *pnbytes)
204{
205l_uint8 *array;
206size_t nbytes;
207L_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 *--------------------------------------------------------------------------*/
258l_ok
260 l_uint8 *src,
261 l_int32 nbytes)
262{
263l_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
302l_ok
304 FILE *fp,
305 l_int32 nbytes)
306{
307l_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
352l_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 *--------------------------------------------------------------------------*/
381l_ok
383 l_uint8 *dest,
384 size_t nbytes,
385 size_t *pnout)
386{
387size_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
431l_ok
433 FILE *fp,
434 size_t nbytes,
435 size_t *pnout)
436{
437size_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_uint8 * bbufferDestroyAndSaveData(L_BBUFFER **pbb, size_t *pnbytes)
bbufferDestroyAndSaveData()
Definition bbuffer.c:202
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
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