vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

jpc_bs.c (12949B)


      1 /*
      2  * Copyright (c) 1999-2000, Image Power, Inc. and the University of
      3  *   British Columbia.
      4  * Copyright (c) 2001-2003 Michael David Adams.
      5  * All rights reserved.
      6  */
      7 
      8 /* __START_OF_JASPER_LICENSE__
      9  * 
     10  * JasPer License Version 2.0
     11  * 
     12  * Copyright (c) 1999-2000 Image Power, Inc.
     13  * Copyright (c) 1999-2000 The University of British Columbia
     14  * Copyright (c) 2001-2003 Michael David Adams
     15  * 
     16  * All rights reserved.
     17  * 
     18  * Permission is hereby granted, free of charge, to any person (the
     19  * "User") obtaining a copy of this software and associated documentation
     20  * files (the "Software"), to deal in the Software without restriction,
     21  * including without limitation the rights to use, copy, modify, merge,
     22  * publish, distribute, and/or sell copies of the Software, and to permit
     23  * persons to whom the Software is furnished to do so, subject to the
     24  * following conditions:
     25  * 
     26  * 1.  The above copyright notices and this permission notice (which
     27  * includes the disclaimer below) shall be included in all copies or
     28  * substantial portions of the Software.
     29  * 
     30  * 2.  The name of a copyright holder shall not be used to endorse or
     31  * promote products derived from the Software without specific prior
     32  * written permission.
     33  * 
     34  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
     35  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
     36  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
     37  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
     38  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
     39  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
     40  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
     41  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
     42  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
     43  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     44  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
     45  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
     46  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
     47  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
     48  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
     49  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
     50  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
     51  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
     52  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
     53  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
     54  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
     55  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
     56  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
     57  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
     58  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
     59  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
     60  * 
     61  * __END_OF_JASPER_LICENSE__
     62  */
     63 
     64 /*
     65  * Bit Stream Class
     66  *
     67  * $Id: jpc_bs.c 1918 2005-07-24 14:12:08Z baford $
     68  */
     69 
     70 /******************************************************************************\
     71 * Includes.
     72 \******************************************************************************/
     73 
     74 #include <assert.h>
     75 #include <stdlib.h>
     76 #include <stdarg.h>
     77 
     78 #include "jasper/jas_malloc.h"
     79 #include "jasper/jas_math.h"
     80 #include "jasper/jas_debug.h"
     81 
     82 #include "jpc_bs.h"
     83 
     84 /******************************************************************************\
     85 * Local function prototypes.
     86 \******************************************************************************/
     87 
     88 static jpc_bitstream_t *jpc_bitstream_alloc(void);
     89 
     90 /******************************************************************************\
     91 * Code for opening and closing bit streams.
     92 \******************************************************************************/
     93 
     94 /* Open a bit stream from a stream. */
     95 jpc_bitstream_t *jpc_bitstream_sopen(jas_stream_t *stream, char *mode)
     96 {
     97 	jpc_bitstream_t *bitstream;
     98 
     99 	/* Ensure that the open mode is valid. */
    100 	assert(!strcmp(mode, "r") || !strcmp(mode, "w") || !strcmp(mode, "r+")
    101 	  || !strcmp(mode, "w+"));
    102 
    103 	if (!(bitstream = jpc_bitstream_alloc())) {
    104 		return 0;
    105 	}
    106 
    107 	/* By default, do not close the underlying (character) stream, upon
    108 	  the close of the bit stream. */
    109 	bitstream->flags_ = JPC_BITSTREAM_NOCLOSE;
    110 
    111 	bitstream->stream_ = stream;
    112 	bitstream->openmode_ = (mode[0] == 'w') ? JPC_BITSTREAM_WRITE :
    113 	  JPC_BITSTREAM_READ;
    114 
    115 	/* Mark the data buffer as empty. */
    116 	bitstream->cnt_ = (bitstream->openmode_ == JPC_BITSTREAM_READ) ? 0 : 8;
    117 	bitstream->buf_ = 0;
    118 
    119 	return bitstream;
    120 }
    121 
    122 /* Close a bit stream. */
    123 int jpc_bitstream_close(jpc_bitstream_t *bitstream)
    124 {
    125 	int ret = 0;
    126 
    127 	/* Align to the next byte boundary while considering the effects of
    128 	  bit stuffing. */
    129 	if (jpc_bitstream_align(bitstream)) {
    130 		ret = -1;
    131 	}
    132 
    133 	/* If necessary, close the underlying (character) stream. */
    134 	if (!(bitstream->flags_ & JPC_BITSTREAM_NOCLOSE) && bitstream->stream_) {
    135 		if (jas_stream_close(bitstream->stream_)) {
    136 			ret = -1;
    137 		}
    138 		bitstream->stream_ = 0;
    139 	}
    140 
    141 	jas_free(bitstream);
    142 	return ret;
    143 }
    144 
    145 /* Allocate a new bit stream. */
    146 static jpc_bitstream_t *jpc_bitstream_alloc()
    147 {
    148 	jpc_bitstream_t *bitstream;
    149 
    150 	/* Allocate memory for the new bit stream object. */
    151 	if (!(bitstream = jas_malloc(sizeof(jpc_bitstream_t)))) {
    152 		return 0;
    153 	}
    154 	/* Initialize all of the data members. */
    155 	bitstream->stream_ = 0;
    156 	bitstream->cnt_ = 0;
    157 	bitstream->flags_ = 0;
    158 	bitstream->openmode_ = 0;
    159 
    160 	return bitstream;
    161 }
    162 
    163 /******************************************************************************\
    164 * Code for reading/writing from/to bit streams.
    165 \******************************************************************************/
    166 
    167 /* Get a bit from a bit stream. */
    168 int jpc_bitstream_getbit_func(jpc_bitstream_t *bitstream)
    169 {
    170 	int ret;
    171 	JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func(%p)\n", bitstream));
    172 	ret = jpc_bitstream_getbit_macro(bitstream);
    173 	JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func -> %d\n", ret));
    174 	return ret;
    175 }
    176 
    177 /* Put a bit to a bit stream. */
    178 int jpc_bitstream_putbit_func(jpc_bitstream_t *bitstream, int b)
    179 {
    180 	int ret;
    181 	JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func(%p, %d)\n", bitstream, b));
    182 	ret = jpc_bitstream_putbit_macro(bitstream, b);
    183 	JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func() -> %d\n", ret));
    184 	return ret;
    185 }
    186 
    187 /* Get one or more bits from a bit stream. */
    188 long jpc_bitstream_getbits(jpc_bitstream_t *bitstream, int n)
    189 {
    190 	long v;
    191 	int u;
    192 
    193 	/* We can reliably get at most 31 bits since ISO/IEC 9899 only
    194 	  guarantees that a long can represent values up to 2^31-1. */
    195 	assert(n >= 0 && n < 32);
    196 
    197 	/* Get the number of bits requested from the specified bit stream. */
    198 	v = 0;
    199 	while (--n >= 0) {
    200 		if ((u = jpc_bitstream_getbit(bitstream)) < 0) {
    201 			return -1;
    202 		}
    203 		v = (v << 1) | u;
    204 	}
    205 	return v;
    206 }
    207 
    208 /* Put one or more bits to a bit stream. */
    209 int jpc_bitstream_putbits(jpc_bitstream_t *bitstream, int n, long v)
    210 {
    211 	int m;
    212 
    213 	/* We can reliably put at most 31 bits since ISO/IEC 9899 only
    214 	  guarantees that a long can represent values up to 2^31-1. */
    215 	assert(n >= 0 && n < 32);
    216 	/* Ensure that only the bits to be output are nonzero. */
    217 	assert(!(v & (~JAS_ONES(n))));
    218 
    219 	/* Put the desired number of bits to the specified bit stream. */
    220 	m = n - 1;
    221 	while (--n >= 0) {
    222 		if (jpc_bitstream_putbit(bitstream, (v >> m) & 1) == EOF) {
    223 			return EOF;
    224 		}
    225 		v <<= 1;
    226 	}
    227 	return 0;
    228 }
    229 
    230 /******************************************************************************\
    231 * Code for buffer filling and flushing.
    232 \******************************************************************************/
    233 
    234 /* Fill the buffer for a bit stream. */
    235 int jpc_bitstream_fillbuf(jpc_bitstream_t *bitstream)
    236 {
    237 	int c;
    238 	/* Note: The count has already been decremented by the caller. */
    239 	assert(bitstream->openmode_ & JPC_BITSTREAM_READ);
    240 	assert(bitstream->cnt_ <= 0);
    241 
    242 	if (bitstream->flags_ & JPC_BITSTREAM_ERR) {
    243 		bitstream->cnt_ = 0;
    244 		return -1;
    245 	}
    246 
    247 	if (bitstream->flags_ & JPC_BITSTREAM_EOF) {
    248 		bitstream->buf_ = 0x7f;
    249 		bitstream->cnt_ = 7;
    250 		return 1;
    251 	}
    252 
    253 	bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff;
    254 	if ((c = jas_stream_getc((bitstream)->stream_)) == EOF) {
    255 		bitstream->flags_ |= JPC_BITSTREAM_EOF;
    256 		return 1;
    257 	}
    258 	bitstream->cnt_ = (bitstream->buf_ == 0xff00) ? 6 : 7;
    259 	bitstream->buf_ |= c & ((1 << (bitstream->cnt_ + 1)) - 1);
    260 	return (bitstream->buf_ >> bitstream->cnt_) & 1;
    261 }
    262 
    263 
    264 /******************************************************************************\
    265 * Code related to flushing.
    266 \******************************************************************************/
    267 
    268 /* Does the bit stream need to be aligned to a byte boundary (considering
    269   the effects of bit stuffing)? */
    270 int jpc_bitstream_needalign(jpc_bitstream_t *bitstream)
    271 {
    272 	if (bitstream->openmode_ & JPC_BITSTREAM_READ) {
    273 		/* The bit stream is open for reading. */
    274 		/* If there are any bits buffered for reading, or the
    275 		  previous byte forced a stuffed bit, alignment is
    276 		  required. */
    277 		if ((bitstream->cnt_ < 8 && bitstream->cnt_ > 0) ||
    278 		  ((bitstream->buf_ >> 8) & 0xff) == 0xff) {
    279 			return 1;
    280 		}
    281 	} else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) {
    282 		/* The bit stream is open for writing. */
    283 		/* If there are any bits buffered for writing, or the
    284 		  previous byte forced a stuffed bit, alignment is
    285 		  required. */
    286 		if ((bitstream->cnt_ < 8 && bitstream->cnt_ >= 0) ||
    287 		  ((bitstream->buf_ >> 8) & 0xff) == 0xff) {
    288 			return 1;
    289 		}
    290 	} else {
    291 		/* This should not happen.  Famous last words, eh? :-) */
    292 		assert(0);
    293 		return -1;
    294 	}
    295 	return 0;
    296 }
    297 
    298 /* How many additional bytes would be output if we align the bit stream? */
    299 int jpc_bitstream_pending(jpc_bitstream_t *bitstream)
    300 {
    301 	if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) {
    302 		/* The bit stream is being used for writing. */
    303 #if 1
    304 		/* XXX - Is this really correct?  Check someday... */
    305 		if (bitstream->cnt_ < 8) {
    306 			return 1;
    307 		}
    308 #else
    309 		if (bitstream->cnt_ < 8) {
    310 			if (((bitstream->buf_ >> 8) & 0xff) == 0xff) {
    311 				return 2;
    312 			}
    313 			return 1;
    314 		}
    315 #endif
    316 		return 0;
    317 	} else {
    318 		/* This operation should not be invoked on a bit stream that
    319 		  is being used for reading. */
    320 		return -1;
    321 	}
    322 }
    323 
    324 /* Align the bit stream to a byte boundary. */
    325 int jpc_bitstream_align(jpc_bitstream_t *bitstream)
    326 {
    327 	int ret;
    328 	if (bitstream->openmode_ & JPC_BITSTREAM_READ) {
    329 		ret = jpc_bitstream_inalign(bitstream, 0, 0);
    330 	} else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) {
    331 		ret = jpc_bitstream_outalign(bitstream, 0);
    332 	} else {
    333 		abort();
    334 	}
    335 	return ret;
    336 }
    337 
    338 /* Align a bit stream in the input case. */
    339 int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask,
    340   int filldata)
    341 {
    342 	int n;
    343 	int v;
    344 	int u;
    345 	int numfill;
    346 	int m;
    347 
    348 	numfill = 7;
    349 	m = 0;
    350 	v = 0;
    351 	if (bitstream->cnt_ > 0) {
    352 		n = bitstream->cnt_;
    353 	} else if (!bitstream->cnt_) {
    354 		n = ((bitstream->buf_ & 0xff) == 0xff) ? 7 : 0;
    355 	} else {
    356 		n = 0;
    357 	}
    358 	if (n > 0) {
    359 		if ((u = jpc_bitstream_getbits(bitstream, n)) < 0) {
    360 			return -1;
    361 		}
    362 		m += n;
    363 		v = (v << n) | u;
    364 	}
    365 	if ((bitstream->buf_ & 0xff) == 0xff) {
    366 		if ((u = jpc_bitstream_getbits(bitstream, 7)) < 0) {
    367 			return -1;
    368 		}
    369 		v = (v << 7) | u;
    370 		m += 7;
    371 	}
    372 	if (m > numfill) {
    373 		v >>= m - numfill;
    374 	} else {
    375 		filldata >>= numfill - m;
    376 		fillmask >>= numfill - m;
    377 	}
    378 	if (((~(v ^ filldata)) & fillmask) != fillmask) {
    379 		/* The actual fill pattern does not match the expected one. */
    380 		return 1;
    381 	}
    382 
    383 	return 0;
    384 }
    385 
    386 /* Align a bit stream in the output case. */
    387 int jpc_bitstream_outalign(jpc_bitstream_t *bitstream, int filldata)
    388 {
    389 	int n;
    390 	int v;
    391 
    392 	/* Ensure that this bit stream is open for writing. */
    393 	assert(bitstream->openmode_ & JPC_BITSTREAM_WRITE);
    394 
    395 	/* Ensure that the first bit of fill data is zero. */
    396 	/* Note: The first bit of fill data must be zero.  If this were not
    397 	  the case, the fill data itself could cause further bit stuffing to
    398 	  be required (which would cause numerous complications). */
    399 	assert(!(filldata & (~0x3f)));
    400 
    401 	if (!bitstream->cnt_) {
    402 		if ((bitstream->buf_ & 0xff) == 0xff) {
    403 			n = 7;
    404 			v = filldata;
    405 		} else {
    406 			n = 0;
    407 			v = 0;
    408 		}
    409 	} else if (bitstream->cnt_ > 0 && bitstream->cnt_ < 8) {
    410 		n = bitstream->cnt_;
    411 		v = filldata >> (7 - n);
    412 	} else {
    413 		n = 0;
    414 		v = 0;
    415 		return 0;
    416 	}
    417 
    418 	/* Write the appropriate fill data to the bit stream. */
    419 	if (n > 0) {
    420 		if (jpc_bitstream_putbits(bitstream, n, v)) {
    421 			return -1;
    422 		}
    423 	}
    424 	if (bitstream->cnt_ < 8) {
    425 		assert(bitstream->cnt_ >= 0 && bitstream->cnt_ < 8);
    426 		assert((bitstream->buf_ & 0xff) != 0xff);
    427 		/* Force the pending byte of output to be written to the
    428 		  underlying (character) stream. */
    429 		if (jas_stream_putc(bitstream->stream_, bitstream->buf_ & 0xff) == EOF) {
    430 			return -1;
    431 		}
    432 		bitstream->cnt_ = 8;
    433 		bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff;
    434 	}
    435 
    436 	return 0;
    437 }