Leptonica  1.77.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 #include <string.h>
68 #include "allheaders.h"
69 
70 static const l_int32 INITIAL_ARRAYSIZE = 200; /* n'import quoi */
71 
72  /* Static function */
73 static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size);
74 
75 
76 /*---------------------------------------------------------------------*
77  * Creation, copy, clone, destruction *
78  *---------------------------------------------------------------------*/
91 L_BYTEA *
92 l_byteaCreate(size_t nbytes)
93 {
94 L_BYTEA *ba;
95 
96  PROCNAME("l_byteaCreate");
97 
98  if (nbytes <= 0)
99  nbytes = INITIAL_ARRAYSIZE;
100 
101  ba = (L_BYTEA *)LEPT_CALLOC(1, sizeof(L_BYTEA));
102  ba->data = (l_uint8 *)LEPT_CALLOC(nbytes + 1, sizeof(l_uint8));
103  if (!ba->data) {
104  l_byteaDestroy(&ba);
105  return (L_BYTEA *)ERROR_PTR("ba array not made", procName, NULL);
106  }
107  ba->nalloc = nbytes + 1;
108  ba->refcount = 1;
109  return ba;
110 }
111 
112 
120 L_BYTEA *
121 l_byteaInitFromMem(const l_uint8 *data,
122  size_t size)
123 {
124 L_BYTEA *ba;
125 
126  PROCNAME("l_byteaInitFromMem");
127 
128  if (!data)
129  return (L_BYTEA *)ERROR_PTR("data not defined", procName, NULL);
130  if (size <= 0)
131  return (L_BYTEA *)ERROR_PTR("no bytes to initialize", procName, NULL);
132 
133  if ((ba = l_byteaCreate(size)) == NULL)
134  return (L_BYTEA *)ERROR_PTR("ba not made", procName, NULL);
135  memcpy(ba->data, data, size);
136  ba->size = size;
137  return ba;
138 }
139 
140 
147 L_BYTEA *
148 l_byteaInitFromFile(const char *fname)
149 {
150 FILE *fp;
151 L_BYTEA *ba;
152 
153  PROCNAME("l_byteaInitFromFile");
154 
155  if (!fname)
156  return (L_BYTEA *)ERROR_PTR("fname not defined", procName, NULL);
157 
158  if ((fp = fopenReadStream(fname)) == NULL)
159  return (L_BYTEA *)ERROR_PTR("file stream not opened", procName, NULL);
160  ba = l_byteaInitFromStream(fp);
161  fclose(fp);
162  if (!ba)
163  return (L_BYTEA *)ERROR_PTR("ba not made", procName, NULL);
164  return ba;
165 }
166 
167 
174 L_BYTEA *
176 {
177 l_uint8 *data;
178 size_t nbytes;
179 L_BYTEA *ba;
180 
181  PROCNAME("l_byteaInitFromStream");
182 
183  if (!fp)
184  return (L_BYTEA *)ERROR_PTR("stream not defined", procName, NULL);
185 
186  if ((data = l_binaryReadStream(fp, &nbytes)) == NULL)
187  return (L_BYTEA *)ERROR_PTR("data not read", procName, NULL);
188  if ((ba = l_byteaCreate(nbytes)) == NULL) {
189  LEPT_FREE(data);
190  return (L_BYTEA *)ERROR_PTR("ba not made", procName, NULL);
191  }
192  memcpy(ba->data, data, nbytes);
193  ba->size = nbytes;
194  LEPT_FREE(data);
195  return ba;
196 }
197 
198 
211 L_BYTEA *
213  l_int32 copyflag)
214 {
215  PROCNAME("l_byteaCopy");
216 
217  if (!bas)
218  return (L_BYTEA *)ERROR_PTR("bas not defined", procName, NULL);
219 
220  if (copyflag == L_CLONE) {
221  bas->refcount++;
222  return bas;
223  }
224 
225  return l_byteaInitFromMem(bas->data, bas->size);
226 }
227 
228 
243 void
245 {
246 L_BYTEA *ba;
247 
248  PROCNAME("l_byteaDestroy");
249 
250  if (pba == NULL) {
251  L_WARNING("ptr address is null!\n", procName);
252  return;
253  }
254 
255  if ((ba = *pba) == NULL)
256  return;
257 
258  /* Decrement the ref count. If it is 0, destroy the lba. */
259  ba->refcount--;
260  if (ba->refcount <= 0) {
261  if (ba->data) LEPT_FREE(ba->data);
262  LEPT_FREE(ba);
263  }
264 
265  *pba = NULL;
266  return;
267 }
268 
269 
270 /*---------------------------------------------------------------------*
271  * Accessors *
272  *---------------------------------------------------------------------*/
279 size_t
281 {
282  PROCNAME("l_byteaGetSize");
283 
284  if (!ba)
285  return ERROR_INT("ba not defined", procName, 0);
286  return ba->size;
287 }
288 
289 
302 l_uint8 *
304  size_t *psize)
305 {
306  PROCNAME("l_byteaGetData");
307 
308  if (!ba)
309  return (l_uint8 *)ERROR_PTR("ba not defined", procName, NULL);
310  if (!psize)
311  return (l_uint8 *)ERROR_PTR("&size not defined", procName, NULL);
312 
313  *psize = ba->size;
314  return ba->data;
315 }
316 
317 
331 l_uint8 *
333  size_t *psize)
334 {
335 l_uint8 *data;
336 
337  PROCNAME("l_byteaCopyData");
338 
339  if (!psize)
340  return (l_uint8 *)ERROR_PTR("&size not defined", procName, NULL);
341  *psize = 0;
342  if (!ba)
343  return (l_uint8 *)ERROR_PTR("ba not defined", procName, NULL);
344 
345  data = l_byteaGetData(ba, psize);
346  return l_binaryCopy(data, *psize);
347 }
348 
349 
350 /*---------------------------------------------------------------------*
351  * Appending *
352  *---------------------------------------------------------------------*/
361 l_ok
363  const l_uint8 *newdata,
364  size_t newbytes)
365 {
366 size_t size, nalloc, reqsize;
367 
368  PROCNAME("l_byteaAppendData");
369 
370  if (!ba)
371  return ERROR_INT("ba not defined", procName, 1);
372  if (!newdata)
373  return ERROR_INT("newdata not defined", procName, 1);
374 
375  size = l_byteaGetSize(ba);
376  reqsize = size + newbytes + 1;
377  nalloc = ba->nalloc;
378  if (nalloc < reqsize)
379  l_byteaExtendArrayToSize(ba, 2 * reqsize);
380 
381  memcpy(ba->data + size, newdata, newbytes);
382  ba->size += newbytes;
383  return 0;
384 }
385 
386 
394 l_ok
396  const char *str)
397 {
398 size_t size, len, nalloc, reqsize;
399 
400  PROCNAME("l_byteaAppendString");
401 
402  if (!ba)
403  return ERROR_INT("ba not defined", procName, 1);
404  if (!str)
405  return ERROR_INT("str not defined", procName, 1);
406 
407  size = l_byteaGetSize(ba);
408  len = strlen(str);
409  reqsize = size + len + 1;
410  nalloc = ba->nalloc;
411  if (nalloc < reqsize)
412  l_byteaExtendArrayToSize(ba, 2 * reqsize);
413 
414  memcpy(ba->data + size, str, len);
415  ba->size += len;
416  return 0;
417 }
418 
419 
427 static l_int32
429  size_t size)
430 {
431  PROCNAME("l_byteaExtendArrayToSize");
432 
433  if (!ba)
434  return ERROR_INT("ba not defined", procName, 1);
435 
436  if (size > ba->nalloc) {
437  if ((ba->data =
438  (l_uint8 *)reallocNew((void **)&ba->data, ba->nalloc, size))
439  == NULL)
440  return ERROR_INT("new array not returned", procName, 1);
441  ba->nalloc = size;
442  }
443  return 0;
444 }
445 
446 
447 /*---------------------------------------------------------------------*
448  * String join/split *
449  *---------------------------------------------------------------------*/
463 l_ok
465  L_BYTEA **pba2)
466 {
467 l_uint8 *data2;
468 size_t nbytes2;
469 L_BYTEA *ba2;
470 
471  PROCNAME("l_byteaJoin");
472 
473  if (!ba1)
474  return ERROR_INT("ba1 not defined", procName, 1);
475  if (!pba2)
476  return ERROR_INT("&ba2 not defined", procName, 1);
477  if ((ba2 = *pba2) == NULL) return 0;
478 
479  data2 = l_byteaGetData(ba2, &nbytes2);
480  l_byteaAppendData(ba1, data2, nbytes2);
481 
482  l_byteaDestroy(pba2);
483  return 0;
484 }
485 
486 
495 l_ok
497  size_t splitloc,
498  L_BYTEA **pba2)
499 {
500 l_uint8 *data1;
501 size_t nbytes1, nbytes2;
502 
503  PROCNAME("l_byteaSplit");
504 
505  if (!pba2)
506  return ERROR_INT("&ba2 not defined", procName, 1);
507  *pba2 = NULL;
508  if (!ba1)
509  return ERROR_INT("ba1 not defined", procName, 1);
510 
511  data1 = l_byteaGetData(ba1, &nbytes1);
512  if (splitloc >= nbytes1)
513  return ERROR_INT("splitloc invalid", procName, 1);
514  nbytes2 = nbytes1 - splitloc;
515 
516  /* Make the new lba */
517  *pba2 = l_byteaInitFromMem(data1 + splitloc, nbytes2);
518 
519  /* Null the removed bytes in the input lba */
520  memset(data1 + splitloc, 0, nbytes2);
521  ba1->size = splitloc;
522  return 0;
523 }
524 
525 
526 /*---------------------------------------------------------------------*
527  * Search *
528  *---------------------------------------------------------------------*/
538 l_ok
540  const l_uint8 *sequence,
541  size_t seqlen,
542  L_DNA **pda)
543 {
544 l_uint8 *data;
545 size_t size;
546 
547  PROCNAME("l_byteaFindEachSequence");
548 
549  if (!pda)
550  return ERROR_INT("&da not defined", procName, 1);
551  *pda = NULL;
552  if (!ba)
553  return ERROR_INT("ba not defined", procName, 1);
554  if (!sequence)
555  return ERROR_INT("sequence not defined", procName, 1);
556 
557  data = l_byteaGetData(ba, &size);
558  *pda = arrayFindEachSequence(data, size, sequence, seqlen);
559  return 0;
560 }
561 
562 
563 /*---------------------------------------------------------------------*
564  * Output to file *
565  *---------------------------------------------------------------------*/
576 l_ok
577 l_byteaWrite(const char *fname,
578  L_BYTEA *ba,
579  size_t startloc,
580  size_t nbytes)
581 {
582 l_int32 ret;
583 FILE *fp;
584 
585  PROCNAME("l_byteaWrite");
586 
587  if (!fname)
588  return ERROR_INT("fname not defined", procName, 1);
589  if (!ba)
590  return ERROR_INT("ba not defined", procName, 1);
591 
592  if ((fp = fopenWriteStream(fname, "wb")) == NULL)
593  return ERROR_INT("stream not opened", procName, 1);
594  ret = l_byteaWriteStream(fp, ba, startloc, nbytes);
595  fclose(fp);
596  return ret;
597 }
598 
599 
610 l_ok
612  L_BYTEA *ba,
613  size_t startloc,
614  size_t nbytes)
615 {
616 l_uint8 *data;
617 size_t size, maxbytes;
618 
619  PROCNAME("l_byteaWriteStream");
620 
621  if (!fp)
622  return ERROR_INT("stream not defined", procName, 1);
623  if (!ba)
624  return ERROR_INT("ba not defined", procName, 1);
625 
626  data = l_byteaGetData(ba, &size);
627  startloc = L_MAX(0, startloc);
628  if (startloc >= size)
629  return ERROR_INT("invalid startloc", procName, 1);
630  maxbytes = size - startloc;
631  nbytes = (nbytes == 0) ? maxbytes : L_MIN(nbytes, maxbytes);
632 
633  fwrite(data + startloc, 1, nbytes, fp);
634  return 0;
635 }
l_ok l_byteaWriteStream(FILE *fp, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWriteStream()
Definition: bytearray.c:611
size_t l_byteaGetSize(L_BYTEA *ba)
l_byteaGetSize()
Definition: bytearray.c:280
L_BYTEA * l_byteaCopy(L_BYTEA *bas, l_int32 copyflag)
l_byteaCopy()
Definition: bytearray.c:212
l_ok l_byteaAppendString(L_BYTEA *ba, const char *str)
l_byteaAppendString()
Definition: bytearray.c:395
L_DNA * arrayFindEachSequence(const l_uint8 *data, size_t datalen, const l_uint8 *sequence, size_t seqlen)
arrayFindEachSequence()
Definition: utils2.c:1032
L_BYTEA * l_byteaCreate(size_t nbytes)
l_byteaCreate()
Definition: bytearray.c:92
l_uint8 * l_byteaGetData(L_BYTEA *ba, size_t *psize)
l_byteaGetData()
Definition: bytearray.c:303
L_BYTEA * l_byteaInitFromMem(const l_uint8 *data, size_t size)
l_byteaInitFromMem()
Definition: bytearray.c:121
L_BYTEA * l_byteaInitFromStream(FILE *fp)
l_byteaInitFromStream()
Definition: bytearray.c:175
Definition: array.h:83
l_uint8 * l_binaryCopy(l_uint8 *datas, size_t size)
l_binaryCopy()
Definition: utils2.c:1533
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1161
size_t size
Definition: array.h:129
l_int32 refcount
Definition: array.h:130
l_ok l_byteaAppendData(L_BYTEA *ba, const l_uint8 *newdata, size_t newbytes)
l_byteaAppendData()
Definition: bytearray.c:362
l_uint8 * data
Definition: array.h:131
l_ok l_byteaSplit(L_BYTEA *ba1, size_t splitloc, L_BYTEA **pba2)
l_byteaSplit()
Definition: bytearray.c:496
L_BYTEA * l_byteaInitFromFile(const char *fname)
l_byteaInitFromFile()
Definition: bytearray.c:148
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1700
l_ok l_byteaFindEachSequence(L_BYTEA *ba, const l_uint8 *sequence, size_t seqlen, L_DNA **pda)
l_byteaFindEachSequence()
Definition: bytearray.c:539
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1657
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1262
static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size)
l_byteaExtendArrayToSize()
Definition: bytearray.c:428
Definition: pix.h:719
l_ok l_byteaWrite(const char *fname, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWrite()
Definition: bytearray.c:577
void l_byteaDestroy(L_BYTEA **pba)
l_byteaDestroy()
Definition: bytearray.c:244
l_ok l_byteaJoin(L_BYTEA *ba1, L_BYTEA **pba2)
l_byteaJoin()
Definition: bytearray.c:464
l_uint8 * l_byteaCopyData(L_BYTEA *ba, size_t *psize)
l_byteaCopyData()
Definition: bytearray.c:332
size_t nalloc
Definition: array.h:128
Definition: array.h:126