bitstream.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * qrencode - QR Code encoder
  3. *
  4. * Binary sequence class.
  5. * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include "bitstream.h"
  25. BitStream *BitStream_new(void)
  26. {
  27. BitStream *bstream;
  28. bstream = (BitStream *)malloc(sizeof(BitStream));
  29. if(bstream == NULL) return NULL;
  30. bstream->length = 0;
  31. bstream->data = NULL;
  32. return bstream;
  33. }
  34. static int BitStream_allocate(BitStream *bstream, int length)
  35. {
  36. unsigned char *data;
  37. if(bstream == NULL) {
  38. return -1;
  39. }
  40. data = (unsigned char *)malloc(length);
  41. if(data == NULL) {
  42. return -1;
  43. }
  44. if(bstream->data) {
  45. free(bstream->data);
  46. }
  47. bstream->length = length;
  48. bstream->data = data;
  49. return 0;
  50. }
  51. static BitStream *BitStream_newFromNum(int bits, unsigned int num)
  52. {
  53. unsigned int mask;
  54. int i;
  55. unsigned char *p;
  56. BitStream *bstream;
  57. bstream = BitStream_new();
  58. if(bstream == NULL) return NULL;
  59. if(BitStream_allocate(bstream, bits)) {
  60. BitStream_free(bstream);
  61. return NULL;
  62. }
  63. p = bstream->data;
  64. mask = 1 << (bits - 1);
  65. for(i=0; i<bits; i++) {
  66. if(num & mask) {
  67. *p = 1;
  68. } else {
  69. *p = 0;
  70. }
  71. p++;
  72. mask = mask >> 1;
  73. }
  74. return bstream;
  75. }
  76. static BitStream *BitStream_newFromBytes(int size, unsigned char *data)
  77. {
  78. unsigned char mask;
  79. int i, j;
  80. unsigned char *p;
  81. BitStream *bstream;
  82. bstream = BitStream_new();
  83. if(bstream == NULL) return NULL;
  84. if(BitStream_allocate(bstream, size * 8)) {
  85. BitStream_free(bstream);
  86. return NULL;
  87. }
  88. p = bstream->data;
  89. for(i=0; i<size; i++) {
  90. mask = 0x80;
  91. for(j=0; j<8; j++) {
  92. if(data[i] & mask) {
  93. *p = 1;
  94. } else {
  95. *p = 0;
  96. }
  97. p++;
  98. mask = mask >> 1;
  99. }
  100. }
  101. return bstream;
  102. }
  103. int BitStream_append(BitStream *bstream, BitStream *arg)
  104. {
  105. unsigned char *data;
  106. if(arg == NULL) {
  107. return -1;
  108. }
  109. if(arg->length == 0) {
  110. return 0;
  111. }
  112. if(bstream->length == 0) {
  113. if(BitStream_allocate(bstream, arg->length)) {
  114. return -1;
  115. }
  116. memcpy(bstream->data, arg->data, arg->length);
  117. return 0;
  118. }
  119. data = (unsigned char *)malloc(bstream->length + arg->length);
  120. if(data == NULL) {
  121. return -1;
  122. }
  123. memcpy(data, bstream->data, bstream->length);
  124. memcpy(data + bstream->length, arg->data, arg->length);
  125. free(bstream->data);
  126. bstream->length += arg->length;
  127. bstream->data = data;
  128. return 0;
  129. }
  130. int BitStream_appendNum(BitStream *bstream, int bits, unsigned int num)
  131. {
  132. BitStream *b;
  133. int ret;
  134. if(bits == 0) return 0;
  135. b = BitStream_newFromNum(bits, num);
  136. if(b == NULL) return -1;
  137. ret = BitStream_append(bstream, b);
  138. BitStream_free(b);
  139. return ret;
  140. }
  141. int BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data)
  142. {
  143. BitStream *b;
  144. int ret;
  145. if(size == 0) return 0;
  146. b = BitStream_newFromBytes(size, data);
  147. if(b == NULL) return -1;
  148. ret = BitStream_append(bstream, b);
  149. BitStream_free(b);
  150. return ret;
  151. }
  152. unsigned char *BitStream_toByte(BitStream *bstream)
  153. {
  154. int i, j, size, bytes;
  155. unsigned char *data, v;
  156. unsigned char *p;
  157. size = BitStream_size(bstream);
  158. if(size == 0) {
  159. return NULL;
  160. }
  161. data = (unsigned char *)malloc((size + 7) / 8);
  162. if(data == NULL) {
  163. return NULL;
  164. }
  165. bytes = size / 8;
  166. p = bstream->data;
  167. for(i=0; i<bytes; i++) {
  168. v = 0;
  169. for(j=0; j<8; j++) {
  170. v = v << 1;
  171. v |= *p;
  172. p++;
  173. }
  174. data[i] = v;
  175. }
  176. if(size & 7) {
  177. v = 0;
  178. for(j=0; j<(size & 7); j++) {
  179. v = v << 1;
  180. v |= *p;
  181. p++;
  182. }
  183. data[bytes] = v;
  184. }
  185. return data;
  186. }
  187. void BitStream_free(BitStream *bstream)
  188. {
  189. if(bstream != NULL) {
  190. free(bstream->data);
  191. free(bstream);
  192. }
  193. }