bitstream.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * qrencode - QR Code encoder
  3. *
  4. * Binary sequence class.
  5. * Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #if HAVE_CONFIG_H
  22. # include "config.h"
  23. #endif
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include "bitstream.h"
  28. #define DEFAULT_BUFSIZE (128)
  29. BitStream *BitStream_new(void)
  30. {
  31. BitStream *bstream;
  32. bstream = (BitStream *)malloc(sizeof(BitStream));
  33. if(bstream == NULL) return NULL;
  34. bstream->length = 0;
  35. bstream->data = (unsigned char *)malloc(DEFAULT_BUFSIZE);
  36. if(bstream->data == NULL) {
  37. free(bstream);
  38. return NULL;
  39. }
  40. bstream->datasize = DEFAULT_BUFSIZE;
  41. return bstream;
  42. }
  43. #ifdef WITH_TESTS
  44. BitStream *BitStream_newWithBits(size_t size, unsigned char *bits)
  45. {
  46. BitStream *bstream;
  47. if(size == 0) return BitStream_new();
  48. bstream = (BitStream *)malloc(sizeof(BitStream));
  49. if(bstream == NULL) return NULL;
  50. bstream->data = (unsigned char *)malloc(size);
  51. if(bstream->data == NULL) {
  52. free(bstream);
  53. return NULL;
  54. }
  55. bstream->length = size;
  56. bstream->datasize = size;
  57. memcpy(bstream->data, bits, size);
  58. return bstream;
  59. }
  60. #endif
  61. static int BitStream_expand(BitStream *bstream)
  62. {
  63. unsigned char *data;
  64. data = (unsigned char *)realloc(bstream->data, bstream->datasize * 2);
  65. if(data == NULL) {
  66. return -1;
  67. }
  68. bstream->data = data;
  69. bstream->datasize *= 2;
  70. return 0;
  71. }
  72. static void BitStream_writeNum(unsigned char *dest, size_t bits, unsigned int num)
  73. {
  74. unsigned int mask;
  75. size_t i;
  76. unsigned char *p;
  77. p = dest;
  78. mask = 1U << (bits - 1);
  79. for(i = 0; i < bits; i++) {
  80. if(num & mask) {
  81. *p = 1;
  82. } else {
  83. *p = 0;
  84. }
  85. p++;
  86. mask = mask >> 1;
  87. }
  88. }
  89. static void BitStream_writeBytes(unsigned char *dest, size_t size, unsigned char *data)
  90. {
  91. unsigned char mask;
  92. size_t i, j;
  93. unsigned char *p;
  94. p = dest;
  95. for(i = 0; i < size; i++) {
  96. mask = 0x80;
  97. for(j = 0; j < 8; j++) {
  98. if(data[i] & mask) {
  99. *p = 1;
  100. } else {
  101. *p = 0;
  102. }
  103. p++;
  104. mask = mask >> 1;
  105. }
  106. }
  107. }
  108. int BitStream_append(BitStream *bstream, BitStream *arg)
  109. {
  110. int ret;
  111. if(arg == NULL) {
  112. return -1;
  113. }
  114. if(arg->length == 0) {
  115. return 0;
  116. }
  117. while(bstream->length + arg->length > bstream->datasize) {
  118. ret = BitStream_expand(bstream);
  119. if(ret < 0) return ret;
  120. }
  121. memcpy(bstream->data + bstream->length, arg->data, arg->length);
  122. bstream->length += arg->length;
  123. return 0;
  124. }
  125. int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num)
  126. {
  127. int ret;
  128. if(bits == 0) return 0;
  129. while(bstream->datasize - bstream->length < bits) {
  130. ret = BitStream_expand(bstream);
  131. if(ret < 0) return ret;
  132. }
  133. BitStream_writeNum(bstream->data + bstream->length, bits, num);
  134. bstream->length += bits;
  135. return 0;
  136. }
  137. int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data)
  138. {
  139. int ret;
  140. if(size == 0) return 0;
  141. while(bstream->datasize - bstream->length < size * 8) {
  142. ret = BitStream_expand(bstream);
  143. if(ret < 0) return ret;
  144. }
  145. BitStream_writeBytes(bstream->data + bstream->length, size, data);
  146. bstream->length += size * 8;
  147. return 0;
  148. }
  149. unsigned char *BitStream_toByte(BitStream *bstream)
  150. {
  151. size_t i, j, size, bytes, oddbits;
  152. unsigned char *data, v;
  153. unsigned char *p;
  154. size = BitStream_size(bstream);
  155. if(size == 0) {
  156. return NULL;
  157. }
  158. data = (unsigned char *)malloc((size + 7) / 8);
  159. if(data == NULL) {
  160. return NULL;
  161. }
  162. bytes = size / 8;
  163. p = bstream->data;
  164. for(i = 0; i < bytes; i++) {
  165. v = 0;
  166. for(j = 0; j < 8; j++) {
  167. v = (unsigned char)(v << 1);
  168. v |= *p;
  169. p++;
  170. }
  171. data[i] = v;
  172. }
  173. oddbits = size & 7;
  174. if(oddbits > 0) {
  175. v = 0;
  176. for(j = 0; j < oddbits; j++) {
  177. v = (unsigned char)(v << 1);
  178. v |= *p;
  179. p++;
  180. }
  181. data[bytes] = (unsigned char)(v << (8 - oddbits));
  182. }
  183. return data;
  184. }
  185. void BitStream_free(BitStream *bstream)
  186. {
  187. if(bstream != NULL) {
  188. free(bstream->data);
  189. free(bstream);
  190. }
  191. }