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 */
75 static const l_uint32 MaxArraySize = 1000000000; /* 10^9 bytes */
76 static const l_int32 InitialArraySize = 200;
78  /* Static function */
79 static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size);
80 
81 /*---------------------------------------------------------------------*
82  * Creation, copy, clone, destruction *
83  *---------------------------------------------------------------------*/
96 L_BYTEA *
97 l_byteaCreate(size_t nbytes)
98 {
99 L_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 
124 L_BYTEA *
125 l_byteaInitFromMem(const l_uint8 *data,
126  size_t size)
127 {
128 L_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 
153 L_BYTEA *
154 l_byteaInitFromFile(const char *fname)
155 {
156 FILE *fp;
157 L_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 
180 L_BYTEA *
182 {
183 l_uint8 *data;
184 size_t nbytes;
185 L_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 
217 L_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 
249 void
251 {
252 L_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  *---------------------------------------------------------------------*/
283 size_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 
306 l_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 
335 l_uint8 *
337  size_t *psize)
338 {
339 l_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  *---------------------------------------------------------------------*/
365 l_ok
367  const l_uint8 *newdata,
368  size_t newbytes)
369 {
370 size_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 
400 l_ok
402  const char *str)
403 {
404 size_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 
441 static 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  *---------------------------------------------------------------------*/
482 l_ok
484  L_BYTEA **pba2)
485 {
486 l_uint8 *data2;
487 size_t nbytes2;
488 L_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 
514 l_ok
516  size_t splitloc,
517  L_BYTEA **pba2)
518 {
519 l_uint8 *data1;
520 size_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  *---------------------------------------------------------------------*/
557 l_ok
559  const l_uint8 *sequence,
560  size_t seqlen,
561  L_DNA **pda)
562 {
563 l_uint8 *data;
564 size_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  *---------------------------------------------------------------------*/
595 l_ok
596 l_byteaWrite(const char *fname,
597  L_BYTEA *ba,
598  size_t startloc,
599  size_t nbytes)
600 {
601 l_int32 ret;
602 FILE *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 
629 l_ok
631  L_BYTEA *ba,
632  size_t startloc,
633  size_t nbytes)
634 {
635 l_uint8 *data;
636 size_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_uint8 * l_byteaCopyData(L_BYTEA *ba, size_t *psize)
l_byteaCopyData()
Definition: bytearray.c:336
size_t l_byteaGetSize(L_BYTEA *ba)
l_byteaGetSize()
Definition: bytearray.c:284
l_ok l_byteaFindEachSequence(L_BYTEA *ba, const l_uint8 *sequence, size_t seqlen, L_DNA **pda)
l_byteaFindEachSequence()
Definition: bytearray.c:558
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_byteaSplit(L_BYTEA *ba1, size_t splitloc, L_BYTEA **pba2)
l_byteaSplit()
Definition: bytearray.c:515
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
L_BYTEA * l_byteaCreate(size_t nbytes)
l_byteaCreate()
Definition: bytearray.c:97
void l_byteaDestroy(L_BYTEA **pba)
l_byteaDestroy()
Definition: bytearray.c:250
L_BYTEA * l_byteaInitFromMem(const l_uint8 *data, size_t size)
l_byteaInitFromMem()
Definition: bytearray.c:125
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_BYTEA * l_byteaInitFromStream(FILE *fp)
l_byteaInitFromStream()
Definition: bytearray.c:181
L_BYTEA * l_byteaInitFromFile(const char *fname)
l_byteaInitFromFile()
Definition: bytearray.c:154
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_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
L_DNA * arrayFindEachSequence(const l_uint8 *data, size_t datalen, const l_uint8 *sequence, size_t seqlen)
arrayFindEachSequence()
Definition: utils2.c:1173
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_uint8 * l_binaryCopy(const l_uint8 *datas, size_t size)
l_binaryCopy()
Definition: utils2.c:1675