BitOutputStream.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * Copyright (C) 2007-2012 Siemens AG
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published
  6. * by the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. * GNU Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*******************************************************************
  19. *
  20. * @author Daniel.Peintner.EXT@siemens.com
  21. * @version 2012-01-31
  22. * @contact Joerg.Heuer@siemens.com
  23. *
  24. * <p>Code generated by EXIdizer</p>
  25. ********************************************************************/
  26. #include "EXITypes.h"
  27. #include "BitOutputStream.h"
  28. #ifndef BIT_OUTPUT_STREAM_C
  29. #define BIT_OUTPUT_STREAM_C
  30. /* NOTE: nbits <= 8 */
  31. int writeBits(bitstream_t* stream, uint16_t nbits, uint32_t val) {
  32. /* is there enough space in the buffer */
  33. if (nbits <= stream->capacity) {
  34. /* all bits fit into the current buffer */
  35. stream->buffer = (stream->buffer << (nbits)) | (val & (0xff
  36. >> (BITS_IN_BYTE - nbits)));
  37. stream->capacity -= nbits;
  38. /* if the buffer is full write byte */
  39. if (stream->capacity == 0) {
  40. #if EXI_STREAM == BYTE_ARRAY
  41. if ((*stream->pos) >= stream->size) {
  42. return EXI_ERROR_OUTPUT_STREAM_EOF;
  43. }
  44. stream->data[(*stream->pos)++] = stream->buffer;
  45. #endif
  46. #if EXI_STREAM == FILE_STREAM
  47. if ( putc(stream->buffer, stream->file) == EOF ) {
  48. return EXI_ERROR_OUTPUT_STREAM_EOF;
  49. }
  50. #endif
  51. stream->capacity = BITS_IN_BYTE;
  52. stream->buffer = 0;
  53. }
  54. } else {
  55. /* the buffer is not enough
  56. * fill the buffer */
  57. stream->buffer = (stream->buffer << stream->capacity) | ((val >> (nbits
  58. - stream->capacity)) & (0xff >> (BITS_IN_BYTE
  59. - stream->capacity)));
  60. nbits -= stream->capacity;
  61. #if EXI_STREAM == BYTE_ARRAY
  62. if ((*stream->pos) >= stream->size) {
  63. return EXI_ERROR_OUTPUT_STREAM_EOF;
  64. }
  65. stream->data[(*stream->pos)++] = stream->buffer;
  66. #endif
  67. #if EXI_STREAM == FILE_STREAM
  68. if ( putc(stream->buffer, stream->file) == EOF ) {
  69. return EXI_ERROR_OUTPUT_STREAM_EOF;
  70. }
  71. #endif
  72. stream->buffer = 0;
  73. /* write whole bytes */
  74. while (nbits >= BITS_IN_BYTE) {
  75. nbits -= BITS_IN_BYTE;
  76. #if EXI_STREAM == BYTE_ARRAY
  77. if ((*stream->pos) >= stream->size) {
  78. return EXI_ERROR_OUTPUT_STREAM_EOF;
  79. }
  80. stream->data[(*stream->pos)++] = (val >> (nbits));
  81. #endif
  82. #if EXI_STREAM == FILE_STREAM
  83. if ( putc((val >> (nbits)), stream->file) == EOF ) {
  84. return EXI_ERROR_OUTPUT_STREAM_EOF;
  85. }
  86. #endif
  87. }
  88. /* spared bits are kept in the buffer */
  89. stream->buffer = val; /* Note: the high bits will be shifted out during further filling */
  90. stream->capacity = BITS_IN_BYTE - (nbits);
  91. }
  92. return 0;
  93. }
  94. /**
  95. * Flush output
  96. */
  97. int flush(bitstream_t* stream) {
  98. if (stream->capacity == BITS_IN_BYTE) {
  99. /* nothing to do, no bits in buffer */
  100. return 0;
  101. } else {
  102. return writeBits(stream, stream->capacity, 0);
  103. }
  104. }
  105. #endif