diff options
Diffstat (limited to 'libs/libqrencode/src/bitstream.c')
-rw-r--r-- | libs/libqrencode/src/bitstream.c | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/libs/libqrencode/src/bitstream.c b/libs/libqrencode/src/bitstream.c new file mode 100644 index 0000000000..f620050dc6 --- /dev/null +++ b/libs/libqrencode/src/bitstream.c @@ -0,0 +1,231 @@ +/* + * qrencode - QR Code encoder + * + * Binary sequence class. + * Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "bitstream.h" + +#define DEFAULT_BUFSIZE (128) + +BitStream *BitStream_new(void) +{ + BitStream *bstream; + + bstream = (BitStream *)malloc(sizeof(BitStream)); + if(bstream == NULL) return NULL; + + bstream->length = 0; + bstream->data = (unsigned char *)malloc(DEFAULT_BUFSIZE); + if(bstream->data == NULL) { + free(bstream); + return NULL; + } + bstream->datasize = DEFAULT_BUFSIZE; + + return bstream; +} + +#ifdef WITH_TESTS +BitStream *BitStream_newWithBits(size_t size, unsigned char *bits) +{ + BitStream *bstream; + + if(size == 0) return BitStream_new(); + + bstream = (BitStream *)malloc(sizeof(BitStream)); + if(bstream == NULL) return NULL; + + bstream->data = (unsigned char *)malloc(size); + if(bstream->data == NULL) { + free(bstream); + return NULL; + } + + bstream->length = size; + bstream->datasize = size; + memcpy(bstream->data, bits, size); + + return bstream; +} +#endif + +static int BitStream_expand(BitStream *bstream) +{ + unsigned char *data; + + data = (unsigned char *)realloc(bstream->data, bstream->datasize * 2); + if(data == NULL) { + return -1; + } + + bstream->data = data; + bstream->datasize *= 2; + + return 0; +} + +static void BitStream_writeNum(unsigned char *dest, size_t bits, unsigned int num) +{ + unsigned int mask; + size_t i; + unsigned char *p; + + p = dest; + mask = 1U << (bits - 1); + for(i = 0; i < bits; i++) { + if(num & mask) { + *p = 1; + } else { + *p = 0; + } + p++; + mask = mask >> 1; + } +} + +static void BitStream_writeBytes(unsigned char *dest, size_t size, unsigned char *data) +{ + unsigned char mask; + size_t i, j; + unsigned char *p; + + p = dest; + for(i = 0; i < size; i++) { + mask = 0x80; + for(j = 0; j < 8; j++) { + if(data[i] & mask) { + *p = 1; + } else { + *p = 0; + } + p++; + mask = mask >> 1; + } + } +} + +int BitStream_append(BitStream *bstream, BitStream *arg) +{ + int ret; + + if(arg == NULL) { + return -1; + } + if(arg->length == 0) { + return 0; + } + + while(bstream->length + arg->length > bstream->datasize) { + ret = BitStream_expand(bstream); + if(ret < 0) return ret; + } + + memcpy(bstream->data + bstream->length, arg->data, arg->length); + bstream->length += arg->length; + + return 0; +} + +int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num) +{ + int ret; + + if(bits == 0) return 0; + + while(bstream->datasize - bstream->length < bits) { + ret = BitStream_expand(bstream); + if(ret < 0) return ret; + } + BitStream_writeNum(bstream->data + bstream->length, bits, num); + bstream->length += bits; + + return 0; +} + +int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data) +{ + int ret; + + if(size == 0) return 0; + + while(bstream->datasize - bstream->length < size * 8) { + ret = BitStream_expand(bstream); + if(ret < 0) return ret; + } + BitStream_writeBytes(bstream->data + bstream->length, size, data); + bstream->length += size * 8; + + return 0; +} + +unsigned char *BitStream_toByte(BitStream *bstream) +{ + size_t i, j, size, bytes, oddbits; + unsigned char *data, v; + unsigned char *p; + + size = BitStream_size(bstream); + if(size == 0) { + return NULL; + } + data = (unsigned char *)malloc((size + 7) / 8); + if(data == NULL) { + return NULL; + } + + bytes = size / 8; + + p = bstream->data; + for(i = 0; i < bytes; i++) { + v = 0; + for(j = 0; j < 8; j++) { + v = (unsigned char)(v << 1); + v |= *p; + p++; + } + data[i] = v; + } + oddbits = size & 7; + if(oddbits > 0) { + v = 0; + for(j = 0; j < oddbits; j++) { + v = (unsigned char)(v << 1); + v |= *p; + p++; + } + data[bytes] = (unsigned char)(v << (8 - oddbits)); + } + + return data; +} + +void BitStream_free(BitStream *bstream) +{ + if(bstream != NULL) { + free(bstream->data); + free(bstream); + } +} |