summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libwavpack/bits.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libwavpack/bits.c')
-rw-r--r--lib/rbcodec/codecs/libwavpack/bits.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libwavpack/bits.c b/lib/rbcodec/codecs/libwavpack/bits.c
new file mode 100644
index 0000000000..0f0e79c292
--- /dev/null
+++ b/lib/rbcodec/codecs/libwavpack/bits.c
@@ -0,0 +1,170 @@
1////////////////////////////////////////////////////////////////////////////
2// **** WAVPACK **** //
3// Hybrid Lossless Wavefile Compressor //
4// Copyright (c) 1998 - 2004 Conifer Software. //
5// All Rights Reserved. //
6// Distributed under the BSD Software License (see license.txt) //
7////////////////////////////////////////////////////////////////////////////
8
9// bits.c
10
11// This module provides utilities to support the BitStream structure which is
12// used to read and write all WavPack audio data streams. It also contains a
13// wrapper for the stream I/O functions and a set of functions dealing with
14// endian-ness, both for enhancing portability. Finally, a debug wrapper for
15// the malloc() system is provided.
16
17#include "wavpack.h"
18#include "system.h"
19
20#include <string.h>
21
22////////////////////////// Bitstream functions ////////////////////////////////
23
24// Open the specified BitStream and associate with the specified buffer.
25
26static void bs_read (Bitstream *bs);
27
28void bs_open_read (Bitstream *bs, uchar *buffer_start, uchar *buffer_end, read_stream file, uint32_t file_bytes)
29{
30 CLEAR (*bs);
31 bs->buf = buffer_start;
32 bs->end = buffer_end;
33
34 if (file) {
35 bs->ptr = bs->end - 1;
36 bs->file_bytes = file_bytes;
37 bs->file = file;
38 }
39 else
40 bs->ptr = bs->buf - 1;
41
42 bs->wrap = bs_read;
43}
44
45// This function is only called from the getbit() and getbits() macros when
46// the BitStream has been exhausted and more data is required. Sinve these
47// bistreams no longer access files, this function simple sets an error and
48// resets the buffer.
49
50static void bs_read (Bitstream *bs)
51{
52 if (bs->file && bs->file_bytes) {
53 uint32_t bytes_read, bytes_to_read = bs->end - bs->buf;
54
55 if (bytes_to_read > bs->file_bytes)
56 bytes_to_read = bs->file_bytes;
57
58 bytes_read = bs->file (bs->buf, bytes_to_read);
59
60 if (bytes_read) {
61 bs->end = bs->buf + bytes_read;
62 bs->file_bytes -= bytes_read;
63 }
64 else {
65 memset (bs->buf, -1, bs->end - bs->buf);
66 bs->error = 1;
67 }
68 }
69 else
70 bs->error = 1;
71
72 if (bs->error)
73 memset (bs->buf, -1, bs->end - bs->buf);
74
75 bs->ptr = bs->buf;
76}
77
78// Open the specified BitStream using the specified buffer pointers. It is
79// assumed that enough buffer space has been allocated for all data that will
80// be written, otherwise an error will be generated.
81
82static void bs_write (Bitstream *bs);
83
84void bs_open_write (Bitstream *bs, uchar *buffer_start, uchar *buffer_end)
85{
86 bs->error = bs->sr = bs->bc = 0;
87 bs->ptr = bs->buf = buffer_start;
88 bs->end = buffer_end;
89 bs->wrap = bs_write;
90}
91
92// This function is only called from the putbit() and putbits() macros when
93// the buffer is full, which is now flagged as an error.
94
95static void bs_write (Bitstream *bs)
96{
97 bs->ptr = bs->buf;
98 bs->error = 1;
99}
100
101// This function forces a flushing write of the specified BitStream, and
102// returns the total number of bytes written into the buffer.
103
104uint32_t bs_close_write (Bitstream *bs)
105{
106 uint32_t bytes_written;
107
108 if (bs->error)
109 return (uint32_t) -1;
110
111 while (bs->bc || ((bs->ptr - bs->buf) & 1)) putbit_1 (bs);
112 bytes_written = bs->ptr - bs->buf;
113 CLEAR (*bs);
114 return bytes_written;
115}
116
117/////////////////////// Endian Correction Routines ////////////////////////////
118
119void little_endian_to_native (void *data, char *format)
120{
121 uchar *cp = (uchar *) data;
122
123 while (*format) {
124 switch (*format) {
125 case 'L':
126 *(long *)cp = letoh32(*(long *)cp);
127 cp += 4;
128 break;
129
130 case 'S':
131 *(short *)cp = letoh16(*(short *)cp);
132 cp += 2;
133 break;
134
135 default:
136 if (*format >= '0' && *format <= '9')
137 cp += *format - '0';
138
139 break;
140 }
141
142 format++;
143 }
144}
145
146void native_to_little_endian (void *data, char *format)
147{
148 uchar *cp = (uchar *) data;
149
150 while (*format) {
151 switch (*format) {
152 case 'L':
153 *(long *)cp = htole32(*(long *)cp);
154 cp += 4;
155 break;
156
157 case 'S':
158 *(short *)cp = htole16(*(short *)cp);
159 cp += 2;
160 break;
161
162 default:
163 if (*format >= '0' && *format <= '9')
164 cp += *format - '0';
165 break;
166 }
167
168 format++;
169 }
170}