Leptonica 1.82.0
Image processing and image analysis suite
bytearray.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
67#ifdef HAVE_CONFIG_H
68#include <config_auto.h>
69#endif /* HAVE_CONFIG_H */
70
71#include <string.h>
72#include "allheaders.h"
73
74 /* Bounds on array size */
75static const l_uint32 MaxArraySize = 1000000000; /* 10^9 bytes */
76static const l_int32 InitialArraySize = 200;
78 /* Static function */
79static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size);
80
81/*---------------------------------------------------------------------*
82 * Creation, copy, clone, destruction *
83 *---------------------------------------------------------------------*/
96L_BYTEA *
97l_byteaCreate(size_t nbytes)
98{
99L_BYTEA *ba;
100
101 PROCNAME("l_byteaCreate");
102
103 if (nbytes <= 0 || nbytes > MaxArraySize)
104 nbytes = InitialArraySize;
105 ba = (L_BYTEA *)LEPT_CALLOC(1, sizeof(L_BYTEA));
106 ba->data = (l_uint8 *)LEPT_CALLOC(nbytes + 1, sizeof(l_uint8));
107 if (!ba->data) {
108 l_byteaDestroy(&ba);
109 return (L_BYTEA *)ERROR_PTR("ba array not made", procName, NULL);
110 }
111 ba->nalloc = nbytes + 1;
112 ba->refcount = 1;
113 return ba;
114}
115
116
124L_BYTEA *
125l_byteaInitFromMem(const l_uint8 *data,
126 size_t size)
127{
128L_BYTEA *ba;
129
130 PROCNAME("l_byteaInitFromMem");
131
132 if (!data)
133 return (L_BYTEA *)ERROR_PTR("data not defined", procName, NULL);
134 if (size <= 0)
135 return (L_BYTEA *)ERROR_PTR("no bytes to initialize", procName, NULL);
136 if (size > MaxArraySize)
137 return (L_BYTEA *)ERROR_PTR("size is too big", procName, NULL);
138
139 if ((ba = l_byteaCreate(size)) == NULL)
140 return (L_BYTEA *)ERROR_PTR("ba not made", procName, NULL);
141 memcpy(ba->data, data, size);
142 ba->size = size;
143 return ba;
144}
145
146
153L_BYTEA *
154l_byteaInitFromFile(const char *fname)
155{
156FILE *fp;
157L_BYTEA *ba;
158
159 PROCNAME("l_byteaInitFromFile");
160
161 if (!fname)
162 return (L_BYTEA *)ERROR_PTR("fname not defined", procName, NULL);
163
164 if ((fp = fopenReadStream(fname)) == NULL)
165 return (L_BYTEA *)ERROR_PTR("file stream not opened", procName, NULL);
166 ba = l_byteaInitFromStream(fp);
167 fclose(fp);
168 if (!ba)
169 return (L_BYTEA *)ERROR_PTR("ba not made", procName, NULL);
170 return ba;
171}
172
173
180L_BYTEA *
182{
183l_uint8 *data;
184size_t nbytes;
185L_BYTEA *ba;
186
187 PROCNAME("l_byteaInitFromStream");
188
189 if (!fp)
190 return (L_BYTEA *)ERROR_PTR("stream not defined", procName, NULL);
191
192 if ((data = l_binaryReadStream(fp, &nbytes)) == NULL)
193 return (L_BYTEA *)ERROR_PTR("data not read", procName, NULL);
194 if ((ba = l_byteaCreate(nbytes)) == NULL) {
195 LEPT_FREE(data);
196 return (L_BYTEA *)ERROR_PTR("ba not made", procName, NULL);
197 }
198 memcpy(ba->data, data, nbytes);
199 ba->size = nbytes;
200 LEPT_FREE(data);
201 return ba;
202}
203
204
217L_BYTEA *
219 l_int32 copyflag)
220{
221 PROCNAME("l_byteaCopy");
222
223 if (!bas)
224 return (L_BYTEA *)ERROR_PTR("bas not defined", procName, NULL);
225
226 if (copyflag == L_CLONE) {
227 bas->refcount++;
228 return bas;
229 }
230
231 return l_byteaInitFromMem(bas->data, bas->size);
232}
233
234
249void
251{
252L_BYTEA *ba;
253
254 PROCNAME("l_byteaDestroy");
255
256 if (pba == NULL) {
257 L_WARNING("ptr address is null!\n", procName);
258 return;
259 }
260
261 if ((ba = *pba) == NULL)
262 return;
263
264 /* Decrement the ref count. If it is 0, destroy the lba. */
265 ba->refcount--;
266 if (ba->refcount <= 0) {
267 if (ba->data) LEPT_FREE(ba->data);
268 LEPT_FREE(ba);
269 }
270 *pba = NULL;
271}
272
273
274/*---------------------------------------------------------------------*
275 * Accessors *
276 *---------------------------------------------------------------------*/
283size_t
285{
286 PROCNAME("l_byteaGetSize");
287
288 if (!ba)
289 return ERROR_INT("ba not defined", procName, 0);
290 return ba->size;
291}
292
293
306l_uint8 *
308 size_t *psize)
309{
310 PROCNAME("l_byteaGetData");
311
312 if (!ba)
313 return (l_uint8 *)ERROR_PTR("ba not defined", procName, NULL);
314 if (!psize)
315 return (l_uint8 *)ERROR_PTR("&size not defined", procName, NULL);
316
317 *psize = ba->size;
318 return ba->data;
319}
320
321
335l_uint8 *
337 size_t *psize)
338{
339l_uint8 *data;
340
341 PROCNAME("l_byteaCopyData");
342
343 if (!psize)
344 return (l_uint8 *)ERROR_PTR("&size not defined", procName, NULL);
345 *psize = 0;
346 if (!ba)
347 return (l_uint8 *)ERROR_PTR("ba not defined", procName, NULL);
348
349 data = l_byteaGetData(ba, psize);
350 return l_binaryCopy(data, *psize);
351}
352
353
354/*---------------------------------------------------------------------*
355 * Appending *
356 *---------------------------------------------------------------------*/
365l_ok
367 const l_uint8 *newdata,
368 size_t newbytes)
369{
370size_t size, nalloc, reqsize;
371
372 PROCNAME("l_byteaAppendData");
373
374 if (!ba)
375 return ERROR_INT("ba not defined", procName, 1);
376 if (!newdata)
377 return ERROR_INT("newdata not defined", procName, 1);
378
379 size = l_byteaGetSize(ba);
380 reqsize = size + newbytes + 1;
381 nalloc = ba->nalloc;
382 if (nalloc < reqsize) {
383 if (l_byteaExtendArrayToSize(ba, 2 * reqsize))
384 return ERROR_INT("extension failed", procName, 1);
385 }
386
387 memcpy(ba->data + size, newdata, newbytes);
388 ba->size += newbytes;
389 return 0;
390}
391
392
400l_ok
402 const char *str)
403{
404size_t size, len, nalloc, reqsize;
405
406 PROCNAME("l_byteaAppendString");
407
408 if (!ba)
409 return ERROR_INT("ba not defined", procName, 1);
410 if (!str)
411 return ERROR_INT("str not defined", procName, 1);
412
413 size = l_byteaGetSize(ba);
414 len = strlen(str);
415 reqsize = size + len + 1;
416 nalloc = ba->nalloc;
417 if (nalloc < reqsize) {
418 if (l_byteaExtendArrayToSize(ba, 2 * reqsize))
419 return ERROR_INT("extension failed", procName, 1);
420 }
421
422 memcpy(ba->data + size, str, len);
423 ba->size += len;
424 return 0;
425}
426
427
441static l_int32
443 size_t size)
444{
445 PROCNAME("l_byteaExtendArrayToSize");
446
447 if (!ba)
448 return ERROR_INT("ba not defined", procName, 1);
449 if (ba->nalloc > MaxArraySize) /* belt & suspenders */
450 return ERROR_INT("ba has too many ptrs", procName, 1);
451 if (size > MaxArraySize)
452 return ERROR_INT("size > 1 GB; too large", procName, 1);
453 if (size <= ba->nalloc) {
454 L_INFO("size too small; no extension\n", procName);
455 return 0;
456 }
457
458 if ((ba->data =
459 (l_uint8 *)reallocNew((void **)&ba->data, ba->nalloc, size)) == NULL)
460 return ERROR_INT("new array not returned", procName, 1);
461 ba->nalloc = size;
462 return 0;
463}
464
465
466/*---------------------------------------------------------------------*
467 * String join/split *
468 *---------------------------------------------------------------------*/
482l_ok
484 L_BYTEA **pba2)
485{
486l_uint8 *data2;
487size_t nbytes2;
488L_BYTEA *ba2;
489
490 PROCNAME("l_byteaJoin");
491
492 if (!ba1)
493 return ERROR_INT("ba1 not defined", procName, 1);
494 if (!pba2)
495 return ERROR_INT("&ba2 not defined", procName, 1);
496 if ((ba2 = *pba2) == NULL) return 0;
497
498 data2 = l_byteaGetData(ba2, &nbytes2);
499 l_byteaAppendData(ba1, data2, nbytes2);
500
501 l_byteaDestroy(pba2);
502 return 0;
503}
504
505
514l_ok
516 size_t splitloc,
517 L_BYTEA **pba2)
518{
519l_uint8 *data1;
520size_t nbytes1, nbytes2;
521
522 PROCNAME("l_byteaSplit");
523
524 if (!pba2)
525 return ERROR_INT("&ba2 not defined", procName, 1);
526 *pba2 = NULL;
527 if (!ba1)
528 return ERROR_INT("ba1 not defined", procName, 1);
529
530 data1 = l_byteaGetData(ba1, &nbytes1);
531 if (splitloc >= nbytes1)
532 return ERROR_INT("splitloc invalid", procName, 1);
533 nbytes2 = nbytes1 - splitloc;
534
535 /* Make the new lba */
536 *pba2 = l_byteaInitFromMem(data1 + splitloc, nbytes2);
537
538 /* Null the removed bytes in the input lba */
539 memset(data1 + splitloc, 0, nbytes2);
540 ba1->size = splitloc;
541 return 0;
542}
543
544
545/*---------------------------------------------------------------------*
546 * Search *
547 *---------------------------------------------------------------------*/
557l_ok
559 const l_uint8 *sequence,
560 size_t seqlen,
561 L_DNA **pda)
562{
563l_uint8 *data;
564size_t size;
565
566 PROCNAME("l_byteaFindEachSequence");
567
568 if (!pda)
569 return ERROR_INT("&da not defined", procName, 1);
570 *pda = NULL;
571 if (!ba)
572 return ERROR_INT("ba not defined", procName, 1);
573 if (!sequence)
574 return ERROR_INT("sequence not defined", procName, 1);
575
576 data = l_byteaGetData(ba, &size);
577 *pda = arrayFindEachSequence(data, size, sequence, seqlen);
578 return 0;
579}
580
581
582/*---------------------------------------------------------------------*
583 * Output to file *
584 *---------------------------------------------------------------------*/
595l_ok
596l_byteaWrite(const char *fname,
597 L_BYTEA *ba,
598 size_t startloc,
599 size_t nbytes)
600{
601l_int32 ret;
602FILE *fp;
603
604 PROCNAME("l_byteaWrite");
605
606 if (!fname)
607 return ERROR_INT("fname not defined", procName, 1);
608 if (!ba)
609 return ERROR_INT("ba not defined", procName, 1);
610
611 if ((fp = fopenWriteStream(fname, "wb")) == NULL)
612 return ERROR_INT("stream not opened", procName, 1);
613 ret = l_byteaWriteStream(fp, ba, startloc, nbytes);
614 fclose(fp);
615 return ret;
616}
617
618
629l_ok
631 L_BYTEA *ba,
632 size_t startloc,
633 size_t nbytes)
634{
635l_uint8 *data;
636size_t size, maxbytes;
637
638 PROCNAME("l_byteaWriteStream");
639
640 if (!fp)
641 return ERROR_INT("stream not defined", procName, 1);
642 if (!ba)
643 return ERROR_INT("ba not defined", procName, 1);
644
645 data = l_byteaGetData(ba, &size);
646 if (startloc >= size)
647 return ERROR_INT("invalid startloc", procName, 1);
648 maxbytes = size - startloc;
649 nbytes = (nbytes == 0) ? maxbytes : L_MIN(nbytes, maxbytes);
650
651 fwrite(data + startloc, 1, nbytes, fp);
652 return 0;
653}
L_BYTEA * l_byteaInitFromMem(const l_uint8 *data, size_t size)
l_byteaInitFromMem()
Definition: bytearray.c:125
L_BYTEA * l_byteaCreate(size_t nbytes)
l_byteaCreate()
Definition: bytearray.c:97
size_t l_byteaGetSize(L_BYTEA *ba)
l_byteaGetSize()
Definition: bytearray.c:284
L_BYTEA * l_byteaInitFromFile(const char *fname)
l_byteaInitFromFile()
Definition: bytearray.c:154
l_ok l_byteaFindEachSequence(L_BYTEA *ba, const l_uint8 *sequence, size_t seqlen, L_DNA **pda)
l_byteaFindEachSequence()
Definition: bytearray.c:558
l_ok l_byteaSplit(L_BYTEA *ba1, size_t splitloc, L_BYTEA **pba2)
l_byteaSplit()
Definition: bytearray.c:515
L_BYTEA * l_byteaInitFromStream(FILE *fp)
l_byteaInitFromStream()
Definition: bytearray.c:181
l_uint8 * l_byteaCopyData(L_BYTEA *ba, size_t *psize)
l_byteaCopyData()
Definition: bytearray.c:336
static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size)
l_byteaExtendArrayToSize()
Definition: bytearray.c:442
l_ok l_byteaWrite(const char *fname, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWrite()
Definition: bytearray.c:596
void l_byteaDestroy(L_BYTEA **pba)
l_byteaDestroy()
Definition: bytearray.c:250
l_uint8 * l_byteaGetData(L_BYTEA *ba, size_t *psize)
l_byteaGetData()
Definition: bytearray.c:307
L_BYTEA * l_byteaCopy(L_BYTEA *bas, l_int32 copyflag)
l_byteaCopy()
Definition: bytearray.c:218
l_ok l_byteaWriteStream(FILE *fp, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWriteStream()
Definition: bytearray.c:630
l_ok l_byteaAppendString(L_BYTEA *ba, const char *str)
l_byteaAppendString()
Definition: bytearray.c:401
static const l_int32 InitialArraySize
Definition: bytearray.c:76
l_ok l_byteaJoin(L_BYTEA *ba1, L_BYTEA **pba2)
l_byteaJoin()
Definition: bytearray.c:483
l_ok l_byteaAppendData(L_BYTEA *ba, const l_uint8 *newdata, size_t newbytes)
l_byteaAppendData()
Definition: bytearray.c:366
@ L_CLONE
Definition: pix.h:713
Definition: array.h:137
size_t size
Definition: array.h:139
size_t nalloc
Definition: array.h:138
l_int32 refcount
Definition: array.h:140
l_uint8 * data
Definition: array.h:141
Definition: array.h:95
l_uint8 * l_binaryCopy(const l_uint8 *datas, size_t size)
l_binaryCopy()
Definition: utils2.c:1675
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302
L_DNA * arrayFindEachSequence(const l_uint8 *data, size_t datalen, const l_uint8 *sequence, size_t seqlen)
arrayFindEachSequence()
Definition: utils2.c:1173