Initial revision
[openjpeg.git] / libopenjpeg / bio.c
1 /*
2  * Copyright (c) 2001-2002, David Janssens
3  * Copyright (c) 2003, Yannick Verschueren
4  * Copyright (c) 2003,  Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "bio.h"
31 #include <stdio.h>
32 #include <setjmp.h>
33
34 static unsigned char *bio_start, *bio_end, *bio_bp;
35 static unsigned int bio_buf;
36 static int bio_ct;
37
38 extern jmp_buf j2k_error;
39
40 /* <summary> */
41 /* Number of bytes written. */
42 /* </summary> */
43 int bio_numbytes()
44 {
45         return bio_bp - bio_start;
46 }
47
48 /* <summary> */
49 /* Init encoder. */
50 /* </summary> */
51 /* <param name="bp">Output buffer</param> */
52 /* <param name="len">Output buffer length</param> */
53 void bio_init_enc(unsigned char *bp, int len)
54 {
55         bio_start = bp;
56         bio_end = bp + len;
57         bio_bp = bp;
58         bio_buf = 0;
59         bio_ct = 8;
60 }
61
62 /* <summary> */
63 /* Init decoder. */
64 /* </summary> */
65 /* <param name="bp">Input buffer</param> */
66 /* <param name="len">Input buffer length</param> */
67 void bio_init_dec(unsigned char *bp, int len)
68 {
69         bio_start = bp;
70         bio_end = bp + len;
71         bio_bp = bp;
72         bio_buf = 0;
73         bio_ct = 0;
74 }
75
76 /* <summary> */
77 /* Write byte. --> function modified to eliminate longjmp !!! */
78 /* </summary> */
79 int bio_byteout()
80 {
81         bio_buf = (bio_buf << 8) & 0xffff;
82         bio_ct = bio_buf == 0xff00 ? 7 : 8;
83         if (bio_bp >= bio_end)
84                 return 1;
85         *bio_bp++ = bio_buf >> 8;
86         return 0;
87 }
88
89 /* <summary> */
90 /* Read byte. --> function modified to eliminate longjmp !!  */
91 /* </summary> */
92 int bio_bytein()
93 {
94         bio_buf = (bio_buf << 8) & 0xffff;
95         bio_ct = bio_buf == 0xff00 ? 7 : 8;
96         if (bio_bp >= bio_end)
97                 return 1;
98         bio_buf |= *bio_bp++;
99         return 0;
100 }
101
102 /* <summary> */
103 /* Write bit. */
104 /* </summary> */
105 /* <param name="b">Bit to write (0 or 1)</param> */
106 void bio_putbit(int b)
107 {
108         if (bio_ct == 0) {
109                 bio_byteout();
110         }
111         bio_ct--;
112         bio_buf |= b << bio_ct;
113 }
114
115 /* <summary> */
116 /* Read bit. */
117 /* </summary> */
118 int bio_getbit()
119 {
120         if (bio_ct == 0) {
121                 bio_bytein();
122         }
123         bio_ct--;
124         return (bio_buf >> bio_ct) & 1;
125 }
126
127 /* <summary> */
128 /* Write bits. */
129 /* </summary> */
130 /* <param name="v">Value of bits</param> */
131 /* <param name="n">Number of bits to write</param> */
132 void bio_write(int v, int n)
133 {
134         int i;
135         for (i = n - 1; i >= 0; i--) {
136                 bio_putbit((v >> i) & 1);
137         }
138 }
139
140 /* <summary> */
141 /* Read bits. */
142 /* </summary> */
143 /* <param name="n">Number of bits to read</param> */
144 int bio_read(int n)
145 {
146         int i, v;
147         v = 0;
148         for (i = n - 1; i >= 0; i--) {
149                 v += bio_getbit() << i;
150         }
151         return v;
152 }
153
154 /* <summary> */
155 /* Flush bits. MOdified to eliminate longjmp !! */
156 /* </summary> */
157 int bio_flush()
158 {
159         bio_ct = 0;
160         if (bio_byteout())
161                 return 1;
162         if (bio_ct == 7) {
163                 bio_ct = 0;
164
165                 if (bio_byteout())
166                         return 1;
167         }
168         return 0;
169 }
170
171 /* <summary> */
172 /* </summary> */
173 int bio_inalign()
174 {
175         bio_ct = 0;
176         if ((bio_buf & 0xff) == 0xff) {
177                 if (bio_bytein())
178                         return 1;
179                 bio_ct = 0;
180         }
181         return 0;
182 }