/*1* Copyright (c) 1999-2000, Image Power, Inc. and the University of2* British Columbia.3* Copyright (c) 2001-2003 Michael David Adams.4* All rights reserved.5*/67/* __START_OF_JASPER_LICENSE__8*9* JasPer License Version 2.010*11* Copyright (c) 2001-2006 Michael David Adams12* Copyright (c) 1999-2000 Image Power, Inc.13* Copyright (c) 1999-2000 The University of British Columbia14*15* All rights reserved.16*17* Permission is hereby granted, free of charge, to any person (the18* "User") obtaining a copy of this software and associated documentation19* files (the "Software"), to deal in the Software without restriction,20* including without limitation the rights to use, copy, modify, merge,21* publish, distribute, and/or sell copies of the Software, and to permit22* persons to whom the Software is furnished to do so, subject to the23* following conditions:24*25* 1. The above copyright notices and this permission notice (which26* includes the disclaimer below) shall be included in all copies or27* substantial portions of the Software.28*29* 2. The name of a copyright holder shall not be used to endorse or30* promote products derived from the Software without specific prior31* written permission.32*33* THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS34* LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER35* THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS36* "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING37* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A38* PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO39* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL40* INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING41* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,42* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION43* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE44* PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE45* THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.46* EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS47* BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL48* PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS49* GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE50* ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE51* IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL52* SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,53* AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL54* SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH55* THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,56* PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH57* RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY58* EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.59*60* __END_OF_JASPER_LICENSE__61*/6263/*64* Bit Stream Class65*66* $Id: jpc_bs.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $67*/6869/******************************************************************************\70* Includes.71\******************************************************************************/7273#include <assert.h>74#include <stdlib.h>75#include <stdarg.h>7677#include "jasper/jas_malloc.h"78#include "jasper/jas_math.h"79#include "jasper/jas_debug.h"8081#include "jpc_bs.h"8283/******************************************************************************\84* Local function prototypes.85\******************************************************************************/8687static jpc_bitstream_t *jpc_bitstream_alloc(void);8889/******************************************************************************\90* Code for opening and closing bit streams.91\******************************************************************************/9293/* Open a bit stream from a stream. */94jpc_bitstream_t *jpc_bitstream_sopen(jas_stream_t *stream, char *mode)95{96jpc_bitstream_t *bitstream;9798/* Ensure that the open mode is valid. */99#if 1100/* This causes a string literal too long error (with c99 pedantic mode). */101assert(!strcmp(mode, "r") || !strcmp(mode, "w") || !strcmp(mode, "r+")102|| !strcmp(mode, "w+"));103#endif104105if (!(bitstream = jpc_bitstream_alloc())) {106return 0;107}108109/* By default, do not close the underlying (character) stream, upon110the close of the bit stream. */111bitstream->flags_ = JPC_BITSTREAM_NOCLOSE;112113bitstream->stream_ = stream;114bitstream->openmode_ = (mode[0] == 'w') ? JPC_BITSTREAM_WRITE :115JPC_BITSTREAM_READ;116117/* Mark the data buffer as empty. */118bitstream->cnt_ = (bitstream->openmode_ == JPC_BITSTREAM_READ) ? 0 : 8;119bitstream->buf_ = 0;120121return bitstream;122}123124/* Close a bit stream. */125int jpc_bitstream_close(jpc_bitstream_t *bitstream)126{127int ret = 0;128129/* Align to the next byte boundary while considering the effects of130bit stuffing. */131if (jpc_bitstream_align(bitstream)) {132ret = -1;133}134135/* If necessary, close the underlying (character) stream. */136if (!(bitstream->flags_ & JPC_BITSTREAM_NOCLOSE) && bitstream->stream_) {137if (jas_stream_close(bitstream->stream_)) {138ret = -1;139}140bitstream->stream_ = 0;141}142143jas_free(bitstream);144return ret;145}146147/* Allocate a new bit stream. */148static jpc_bitstream_t *jpc_bitstream_alloc()149{150jpc_bitstream_t *bitstream;151152/* Allocate memory for the new bit stream object. */153if (!(bitstream = jas_malloc(sizeof(jpc_bitstream_t)))) {154return 0;155}156/* Initialize all of the data members. */157bitstream->stream_ = 0;158bitstream->cnt_ = 0;159bitstream->flags_ = 0;160bitstream->openmode_ = 0;161162return bitstream;163}164165/******************************************************************************\166* Code for reading/writing from/to bit streams.167\******************************************************************************/168169/* Get a bit from a bit stream. */170int jpc_bitstream_getbit_func(jpc_bitstream_t *bitstream)171{172int ret;173JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func(%p)\n", bitstream));174ret = jpc_bitstream_getbit_macro(bitstream);175JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func -> %d\n", ret));176return ret;177}178179/* Put a bit to a bit stream. */180int jpc_bitstream_putbit_func(jpc_bitstream_t *bitstream, int b)181{182int ret;183JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func(%p, %d)\n", bitstream, b));184ret = jpc_bitstream_putbit_macro(bitstream, b);185JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func() -> %d\n", ret));186return ret;187}188189/* Get one or more bits from a bit stream. */190long jpc_bitstream_getbits(jpc_bitstream_t *bitstream, int n)191{192long v;193int u;194195/* We can reliably get at most 31 bits since ISO/IEC 9899 only196guarantees that a long can represent values up to 2^31-1. */197assert(n >= 0 && n < 32);198199/* Get the number of bits requested from the specified bit stream. */200v = 0;201while (--n >= 0) {202if ((u = jpc_bitstream_getbit(bitstream)) < 0) {203return -1;204}205v = (v << 1) | u;206}207return v;208}209210/* Put one or more bits to a bit stream. */211int jpc_bitstream_putbits(jpc_bitstream_t *bitstream, int n, long v)212{213int m;214215/* We can reliably put at most 31 bits since ISO/IEC 9899 only216guarantees that a long can represent values up to 2^31-1. */217assert(n >= 0 && n < 32);218/* Ensure that only the bits to be output are nonzero. */219assert(!(v & (~JAS_ONES(n))));220221/* Put the desired number of bits to the specified bit stream. */222m = n - 1;223while (--n >= 0) {224if (jpc_bitstream_putbit(bitstream, (v >> m) & 1) == EOF) {225return EOF;226}227v <<= 1;228}229return 0;230}231232/******************************************************************************\233* Code for buffer filling and flushing.234\******************************************************************************/235236/* Fill the buffer for a bit stream. */237int jpc_bitstream_fillbuf(jpc_bitstream_t *bitstream)238{239int c;240/* Note: The count has already been decremented by the caller. */241assert(bitstream->openmode_ & JPC_BITSTREAM_READ);242assert(bitstream->cnt_ <= 0);243244if (bitstream->flags_ & JPC_BITSTREAM_ERR) {245bitstream->cnt_ = 0;246return -1;247}248249if (bitstream->flags_ & JPC_BITSTREAM_EOF) {250bitstream->buf_ = 0x7f;251bitstream->cnt_ = 7;252return 1;253}254255bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff;256if ((c = jas_stream_getc((bitstream)->stream_)) == EOF) {257bitstream->flags_ |= JPC_BITSTREAM_EOF;258return 1;259}260bitstream->cnt_ = (bitstream->buf_ == 0xff00) ? 6 : 7;261bitstream->buf_ |= c & ((1 << (bitstream->cnt_ + 1)) - 1);262return (bitstream->buf_ >> bitstream->cnt_) & 1;263}264265266/******************************************************************************\267* Code related to flushing.268\******************************************************************************/269270/* Does the bit stream need to be aligned to a byte boundary (considering271the effects of bit stuffing)? */272int jpc_bitstream_needalign(jpc_bitstream_t *bitstream)273{274if (bitstream->openmode_ & JPC_BITSTREAM_READ) {275/* The bit stream is open for reading. */276/* If there are any bits buffered for reading, or the277previous byte forced a stuffed bit, alignment is278required. */279if ((bitstream->cnt_ < 8 && bitstream->cnt_ > 0) ||280((bitstream->buf_ >> 8) & 0xff) == 0xff) {281return 1;282}283} else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) {284/* The bit stream is open for writing. */285/* If there are any bits buffered for writing, or the286previous byte forced a stuffed bit, alignment is287required. */288if ((bitstream->cnt_ < 8 && bitstream->cnt_ >= 0) ||289((bitstream->buf_ >> 8) & 0xff) == 0xff) {290return 1;291}292} else {293/* This should not happen. Famous last words, eh? :-) */294assert(0);295return -1;296}297return 0;298}299300/* How many additional bytes would be output if we align the bit stream? */301int jpc_bitstream_pending(jpc_bitstream_t *bitstream)302{303if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) {304/* The bit stream is being used for writing. */305#if 1306/* XXX - Is this really correct? Check someday... */307if (bitstream->cnt_ < 8) {308return 1;309}310#else311if (bitstream->cnt_ < 8) {312if (((bitstream->buf_ >> 8) & 0xff) == 0xff) {313return 2;314}315return 1;316}317#endif318return 0;319} else {320/* This operation should not be invoked on a bit stream that321is being used for reading. */322return -1;323}324}325326/* Align the bit stream to a byte boundary. */327int jpc_bitstream_align(jpc_bitstream_t *bitstream)328{329int ret;330if (bitstream->openmode_ & JPC_BITSTREAM_READ) {331ret = jpc_bitstream_inalign(bitstream, 0, 0);332} else if (bitstream->openmode_ & JPC_BITSTREAM_WRITE) {333ret = jpc_bitstream_outalign(bitstream, 0);334} else {335abort();336}337return ret;338}339340/* Align a bit stream in the input case. */341int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask,342int filldata)343{344int n;345int v;346int u;347int numfill;348int m;349350numfill = 7;351m = 0;352v = 0;353if (bitstream->cnt_ > 0) {354n = bitstream->cnt_;355} else if (!bitstream->cnt_) {356n = ((bitstream->buf_ & 0xff) == 0xff) ? 7 : 0;357} else {358n = 0;359}360if (n > 0) {361if ((u = jpc_bitstream_getbits(bitstream, n)) < 0) {362return -1;363}364m += n;365v = (v << n) | u;366}367if ((bitstream->buf_ & 0xff) == 0xff) {368if ((u = jpc_bitstream_getbits(bitstream, 7)) < 0) {369return -1;370}371v = (v << 7) | u;372m += 7;373}374if (m > numfill) {375v >>= m - numfill;376} else {377filldata >>= numfill - m;378fillmask >>= numfill - m;379}380if (((~(v ^ filldata)) & fillmask) != fillmask) {381/* The actual fill pattern does not match the expected one. */382return 1;383}384385return 0;386}387388/* Align a bit stream in the output case. */389int jpc_bitstream_outalign(jpc_bitstream_t *bitstream, int filldata)390{391int n;392int v;393394/* Ensure that this bit stream is open for writing. */395assert(bitstream->openmode_ & JPC_BITSTREAM_WRITE);396397/* Ensure that the first bit of fill data is zero. */398/* Note: The first bit of fill data must be zero. If this were not399the case, the fill data itself could cause further bit stuffing to400be required (which would cause numerous complications). */401assert(!(filldata & (~0x3f)));402403if (!bitstream->cnt_) {404if ((bitstream->buf_ & 0xff) == 0xff) {405n = 7;406v = filldata;407} else {408n = 0;409v = 0;410}411} else if (bitstream->cnt_ > 0 && bitstream->cnt_ < 8) {412n = bitstream->cnt_;413v = filldata >> (7 - n);414} else {415n = 0;416v = 0;417return 0;418}419420/* Write the appropriate fill data to the bit stream. */421if (n > 0) {422if (jpc_bitstream_putbits(bitstream, n, v)) {423return -1;424}425}426if (bitstream->cnt_ < 8) {427assert(bitstream->cnt_ >= 0 && bitstream->cnt_ < 8);428assert((bitstream->buf_ & 0xff) != 0xff);429/* Force the pending byte of output to be written to the430underlying (character) stream. */431if (jas_stream_putc(bitstream->stream_, bitstream->buf_ & 0xff) == EOF) {432return -1;433}434bitstream->cnt_ = 8;435bitstream->buf_ = (bitstream->buf_ << 8) & 0xffff;436}437438return 0;439}440441442