Leptonica  1.83.1
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 #include "array_internal.h"
74 
75  /* Bounds on array size */
76 static const l_uint32 MaxArraySize = 1000000000; /* 10^9 bytes */
77 static const l_int32 InitialArraySize = 200;
79  /* Static function */
80 static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size);
81 
82 /*---------------------------------------------------------------------*
83  * Creation, copy, clone, destruction *
84  *---------------------------------------------------------------------*/
97 L_BYTEA *
98 l_byteaCreate(size_t nbytes)
99 {
100 L_BYTEA *ba;
101 
102  if (nbytes <= 0 || nbytes > MaxArraySize)
103  nbytes = InitialArraySize;
104  ba = (L_BYTEA *)LEPT_CALLOC(1, sizeof(L_BYTEA));
105  ba->data = (l_uint8 *)LEPT_CALLOC(nbytes + 1, sizeof(l_uint8));
106  if (!ba->data) {
107  l_byteaDestroy(&ba);
108  return (L_BYTEA *)ERROR_PTR("ba array not made", __func__, NULL);
109  }
110  ba->nalloc = nbytes + 1;
111  ba->refcount = 1;
112  return ba;
113 }
114 
115 
123 L_BYTEA *
124 l_byteaInitFromMem(const l_uint8 *data,
125  size_t size)
126 {
127 L_BYTEA *ba;
128 
129  if (!data)
130  return (L_BYTEA *)ERROR_PTR("data not defined", __func__, NULL);
131  if (size <= 0)
132  return (L_BYTEA *)ERROR_PTR("no bytes to initialize", __func__, NULL);
133  if (size > MaxArraySize)
134  return (L_BYTEA *)ERROR_PTR("size is too big", __func__, NULL);
135 
136  if ((ba = l_byteaCreate(size)) == NULL)
137  return (L_BYTEA *)ERROR_PTR("ba not made", __func__, NULL);
138  memcpy(ba->data, data, size);
139  ba->size = size;
140  return ba;
141 }
142 
143 
150 L_BYTEA *
151 l_byteaInitFromFile(const char *fname)
152 {
153 FILE *fp;
154 L_BYTEA *ba;
155 
156  if (!fname)
157  return (L_BYTEA *)ERROR_PTR("fname not defined", __func__, NULL);
158 
159  if ((fp = fopenReadStream(fname)) == NULL)
160  return (L_BYTEA *)ERROR_PTR("file stream not opened", __func__, NULL);
161  ba = l_byteaInitFromStream(fp);
162  fclose(fp);
163  if (!ba)
164  return (L_BYTEA *)ERROR_PTR("ba not made", __func__, NULL);
165  return ba;
166 }
167 
168 
175 L_BYTEA *
177 {
178 l_uint8 *data;
179 size_t nbytes;
180 L_BYTEA *ba;
181 
182  if (!fp)
183  return (L_BYTEA *)ERROR_PTR("stream not defined", __func__, NULL);
184 
185  if ((data = l_binaryReadStream(fp, &nbytes)) == NULL)
186  return (L_BYTEA *)ERROR_PTR("data not read", __func__, NULL);
187  if ((ba = l_byteaCreate(nbytes)) == NULL) {
188  LEPT_FREE(data);
189  return (L_BYTEA *)ERROR_PTR("ba not made", __func__, NULL);
190  }
191  memcpy(ba->data, data, nbytes);
192  ba->size = nbytes;
193  LEPT_FREE(data);
194  return ba;
195 }
196 
197 
210 L_BYTEA *
212  l_int32 copyflag)
213 {
214  if (!bas)
215  return (L_BYTEA *)ERROR_PTR("bas not defined", __func__, NULL);
216 
217  if (copyflag == L_CLONE) {
218  bas->refcount++;
219  return bas;
220  }
221 
222  return l_byteaInitFromMem(bas->data, bas->size);
223 }
224 
225 
240 void
242 {
243 L_BYTEA *ba;
244 
245  if (pba == NULL) {
246  L_WARNING("ptr address is null!\n", __func__);
247  return;
248  }
249 
250  if ((ba = *pba) == NULL)
251  return;
252 
253  /* Decrement the ref count. If it is 0, destroy the lba. */
254  if (--ba->refcount == 0) {
255  if (ba->data) LEPT_FREE(ba->data);
256  LEPT_FREE(ba);
257  }
258  *pba = NULL;
259 }
260 
261 
262 /*---------------------------------------------------------------------*
263  * Accessors *
264  *---------------------------------------------------------------------*/
271 size_t
273 {
274  if (!ba)
275  return ERROR_INT("ba not defined", __func__, 0);
276  return ba->size;
277 }
278 
279 
292 l_uint8 *
294  size_t *psize)
295 {
296  if (!ba)
297  return (l_uint8 *)ERROR_PTR("ba not defined", __func__, NULL);
298  if (!psize)
299  return (l_uint8 *)ERROR_PTR("&size not defined", __func__, NULL);
300 
301  *psize = ba->size;
302  return ba->data;
303 }
304 
305 
319 l_uint8 *
321  size_t *psize)
322 {
323 l_uint8 *data;
324 
325  if (!psize)
326  return (l_uint8 *)ERROR_PTR("&size not defined", __func__, NULL);
327  *psize = 0;
328  if (!ba)
329  return (l_uint8 *)ERROR_PTR("ba not defined", __func__, NULL);
330 
331  data = l_byteaGetData(ba, psize);
332  return l_binaryCopy(data, *psize);
333 }
334 
335 
336 /*---------------------------------------------------------------------*
337  * Appending *
338  *---------------------------------------------------------------------*/
347 l_ok
349  const l_uint8 *newdata,
350  size_t newbytes)
351 {
352 size_t size, nalloc, reqsize;
353 
354  if (!ba)
355  return ERROR_INT("ba not defined", __func__, 1);
356  if (!newdata)
357  return ERROR_INT("newdata not defined", __func__, 1);
358 
359  size = l_byteaGetSize(ba);
360  reqsize = size + newbytes + 1;
361  nalloc = ba->nalloc;
362  if (nalloc < reqsize) {
363  if (l_byteaExtendArrayToSize(ba, 2 * reqsize))
364  return ERROR_INT("extension failed", __func__, 1);
365  }
366 
367  memcpy(ba->data + size, newdata, newbytes);
368  ba->size += newbytes;
369  return 0;
370 }
371 
372 
380 l_ok
382  const char *str)
383 {
384 size_t size, len, nalloc, reqsize;
385 
386  if (!ba)
387  return ERROR_INT("ba not defined", __func__, 1);
388  if (!str)
389  return ERROR_INT("str not defined", __func__, 1);
390 
391  size = l_byteaGetSize(ba);
392  len = strlen(str);
393  reqsize = size + len + 1;
394  nalloc = ba->nalloc;
395  if (nalloc < reqsize) {
396  if (l_byteaExtendArrayToSize(ba, 2 * reqsize))
397  return ERROR_INT("extension failed", __func__, 1);
398  }
399 
400  memcpy(ba->data + size, str, len);
401  ba->size += len;
402  return 0;
403 }
404 
405 
419 static l_int32
421  size_t size)
422 {
423  if (!ba)
424  return ERROR_INT("ba not defined", __func__, 1);
425  if (ba->nalloc > MaxArraySize) /* belt & suspenders */
426  return ERROR_INT("ba has too many ptrs", __func__, 1);
427  if (size > MaxArraySize)
428  return ERROR_INT("size > 1 GB; too large", __func__, 1);
429  if (size <= ba->nalloc) {
430  L_INFO("size too small; no extension\n", __func__);
431  return 0;
432  }
433 
434  if ((ba->data =
435  (l_uint8 *)reallocNew((void **)&ba->data, ba->nalloc, size)) == NULL)
436  return ERROR_INT("new array not returned", __func__, 1);
437  ba->nalloc = size;
438  return 0;
439 }
440 
441 
442 /*---------------------------------------------------------------------*
443  * String join/split *
444  *---------------------------------------------------------------------*/
458 l_ok
460  L_BYTEA **pba2)
461 {
462 l_uint8 *data2;
463 size_t nbytes2;
464 L_BYTEA *ba2;
465 
466  if (!ba1)
467  return ERROR_INT("ba1 not defined", __func__, 1);
468  if (!pba2)
469  return ERROR_INT("&ba2 not defined", __func__, 1);
470  if ((ba2 = *pba2) == NULL) return 0;
471 
472  data2 = l_byteaGetData(ba2, &nbytes2);
473  l_byteaAppendData(ba1, data2, nbytes2);
474 
475  l_byteaDestroy(pba2);
476  return 0;
477 }
478 
479 
488 l_ok
490  size_t splitloc,
491  L_BYTEA **pba2)
492 {
493 l_uint8 *data1;
494 size_t nbytes1, nbytes2;
495 
496  if (!pba2)
497  return ERROR_INT("&ba2 not defined", __func__, 1);
498  *pba2 = NULL;
499  if (!ba1)
500  return ERROR_INT("ba1 not defined", __func__, 1);
501 
502  data1 = l_byteaGetData(ba1, &nbytes1);
503  if (splitloc >= nbytes1)
504  return ERROR_INT("splitloc invalid", __func__, 1);
505  nbytes2 = nbytes1 - splitloc;
506 
507  /* Make the new lba */
508  *pba2 = l_byteaInitFromMem(data1 + splitloc, nbytes2);
509 
510  /* Null the removed bytes in the input lba */
511  memset(data1 + splitloc, 0, nbytes2);
512  ba1->size = splitloc;
513  return 0;
514 }
515 
516 
517 /*---------------------------------------------------------------------*
518  * Search *
519  *---------------------------------------------------------------------*/
529 l_ok
531  const l_uint8 *sequence,
532  size_t seqlen,
533  L_DNA **pda)
534 {
535 l_uint8 *data;
536 size_t size;
537 
538  if (!pda)
539  return ERROR_INT("&da not defined", __func__, 1);
540  *pda = NULL;
541  if (!ba)
542  return ERROR_INT("ba not defined", __func__, 1);
543  if (!sequence)
544  return ERROR_INT("sequence not defined", __func__, 1);
545 
546  data = l_byteaGetData(ba, &size);
547  *pda = arrayFindEachSequence(data, size, sequence, seqlen);
548  return 0;
549 }
550 
551 
552 /*---------------------------------------------------------------------*
553  * Output to file *
554  *---------------------------------------------------------------------*/
565 l_ok
566 l_byteaWrite(const char *fname,
567  L_BYTEA *ba,
568  size_t startloc,
569  size_t nbytes)
570 {
571 l_int32 ret;
572 FILE *fp;
573 
574  if (!fname)
575  return ERROR_INT("fname not defined", __func__, 1);
576  if (!ba)
577  return ERROR_INT("ba not defined", __func__, 1);
578 
579  if ((fp = fopenWriteStream(fname, "wb")) == NULL)
580  return ERROR_INT("stream not opened", __func__, 1);
581  ret = l_byteaWriteStream(fp, ba, startloc, nbytes);
582  fclose(fp);
583  return ret;
584 }
585 
586 
597 l_ok
599  L_BYTEA *ba,
600  size_t startloc,
601  size_t nbytes)
602 {
603 l_uint8 *data;
604 size_t size, maxbytes;
605 
606  if (!fp)
607  return ERROR_INT("stream not defined", __func__, 1);
608  if (!ba)
609  return ERROR_INT("ba not defined", __func__, 1);
610 
611  data = l_byteaGetData(ba, &size);
612  if (startloc >= size)
613  return ERROR_INT("invalid startloc", __func__, 1);
614  maxbytes = size - startloc;
615  nbytes = (nbytes == 0) ? maxbytes : L_MIN(nbytes, maxbytes);
616 
617  fwrite(data + startloc, 1, nbytes, fp);
618  return 0;
619 }
l_uint8 * l_byteaCopyData(L_BYTEA *ba, size_t *psize)
l_byteaCopyData()
Definition: bytearray.c:320
size_t l_byteaGetSize(L_BYTEA *ba)
l_byteaGetSize()
Definition: bytearray.c:272
l_ok l_byteaFindEachSequence(L_BYTEA *ba, const l_uint8 *sequence, size_t seqlen, L_DNA **pda)
l_byteaFindEachSequence()
Definition: bytearray.c:530
l_uint8 * l_byteaGetData(L_BYTEA *ba, size_t *psize)
l_byteaGetData()
Definition: bytearray.c:293
L_BYTEA * l_byteaCopy(L_BYTEA *bas, l_int32 copyflag)
l_byteaCopy()
Definition: bytearray.c:211
l_ok l_byteaSplit(L_BYTEA *ba1, size_t splitloc, L_BYTEA **pba2)
l_byteaSplit()
Definition: bytearray.c:489
static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size)
l_byteaExtendArrayToSize()
Definition: bytearray.c:420
l_ok l_byteaWrite(const char *fname, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWrite()
Definition: bytearray.c:566
L_BYTEA * l_byteaCreate(size_t nbytes)
l_byteaCreate()
Definition: bytearray.c:98
void l_byteaDestroy(L_BYTEA **pba)
l_byteaDestroy()
Definition: bytearray.c:241
L_BYTEA * l_byteaInitFromMem(const l_uint8 *data, size_t size)
l_byteaInitFromMem()
Definition: bytearray.c:124
l_ok l_byteaWriteStream(FILE *fp, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWriteStream()
Definition: bytearray.c:598
l_ok l_byteaAppendString(L_BYTEA *ba, const char *str)
l_byteaAppendString()
Definition: bytearray.c:381
static const l_int32 InitialArraySize
Definition: bytearray.c:77
L_BYTEA * l_byteaInitFromStream(FILE *fp)
l_byteaInitFromStream()
Definition: bytearray.c:176
L_BYTEA * l_byteaInitFromFile(const char *fname)
l_byteaInitFromFile()
Definition: bytearray.c:151
l_ok l_byteaJoin(L_BYTEA *ba1, L_BYTEA **pba2)
l_byteaJoin()
Definition: bytearray.c:459
l_ok l_byteaAppendData(L_BYTEA *ba, const l_uint8 *newdata, size_t newbytes)
l_byteaAppendData()
Definition: bytearray.c:348
@ L_CLONE
Definition: pix.h:506
l_atomic refcount
size_t size
size_t nalloc
l_uint8 * data
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1358
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1905
L_DNA * arrayFindEachSequence(const l_uint8 *data, size_t datalen, const l_uint8 *sequence, size_t seqlen)
arrayFindEachSequence()
Definition: utils2.c:1137
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1262
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1864
l_uint8 * l_binaryCopy(const l_uint8 *datas, size_t size)
l_binaryCopy()
Definition: utils2.c:1619