/************************************************************************* * * This software module was originally contributed by Microsoft * Corporation in the course of development of the * ITU-T T.832 | ISO/IEC 29199-2 ("JPEG XR") format standard for * reference purposes and its performance may not have been optimized. * * This software module is an implementation of one or more * tools as specified by the JPEG XR standard. * * ITU/ISO/IEC give You a royalty-free, worldwide, non-exclusive * copyright license to copy, distribute, and make derivative works * of this software module or modifications thereof for use in * products claiming conformance to the JPEG XR standard as * specified by ITU-T T.832 | ISO/IEC 29199-2. * * ITU/ISO/IEC give users the same free license to this software * module or modifications thereof for research purposes and further * ITU/ISO/IEC standardization. * * Those intending to use this software module in products are advised * that its use may infringe existing patents. ITU/ISO/IEC have no * liability for use of this software module or modifications thereof. * * Copyright is not released for products that do not conform to * to the JPEG XR standard as specified by ITU-T T.832 | * ISO/IEC 29199-2. * * Microsoft Corporation retains full right to modify and use the code * for its own purpose, to assign or donate the code to a third party, * and to inhibit third parties from using the code for products that * do not conform to the JPEG XR standard as specified by ITU-T T.832 | * ISO/IEC 29199-2. * * This copyright notice must be included in all copies or derivative * works. * * Copyright (c) ITU-T/ISO/IEC 2008, 2009. ***********************************************************************/ #ifdef _MSC_VER #pragma comment (user,"$Id: io.c,v 1.14 2008/03/05 06:58:10 gus Exp $") #else #ident "$Id: io.c,v 1.14 2008/03/05 06:58:10 gus Exp $" #endif # include "jxr_priv.h" # include void _jxr_rbitstream_initialize(struct rbitstream*str, FILE*fd) { str->bits_avail = 0; str->fd = fd; str->read_count = 0; } size_t _jxr_rbitstream_bitpos(struct rbitstream*str) { return str->read_count*8 - str->bits_avail; } void _jxr_rbitstream_mark(struct rbitstream*str) { assert(str->bits_avail == 0); str->mark_stream_position = ftell(str->fd); assert(str->mark_stream_position >= 0); str->read_count = 0; } void _jxr_rbitstream_seek(struct rbitstream*str, uint64_t off) { int rc; assert(str->bits_avail == 0); /* NOTE: Should be using fseek64? */ rc = fseek(str->fd, str->mark_stream_position + (long)off, SEEK_SET); str->read_count = (size_t) off; assert(rc >= 0); } /* * Cause the bitstream to consume enough bits that the next bit is on * a byte boundary. This is for getting alignment, which is sometimes * needed. */ void _jxr_rbitstream_syncbyte(struct rbitstream*str) { str->bits_avail = 0; } /* * Get the next 8 bits from the input file and adjust the bitstream * pointers so that the bits can be read out. */ static int get_byte(struct rbitstream*str) { int tmp; assert(str->bits_avail == 0); tmp = fgetc(str->fd); if (tmp == EOF) return EOF; str->byte = tmp; str->bits_avail = 8; str->read_count += 1; #if 0 DEBUG(" in byte: 0x%02x (bitpos=%zd)\n", str->byte, str->read_count*8-8); #endif return 0; } /* * The following read integers of various width from the data input * stream. This handles the bit ordering and packing of the bits. */ int _jxr_rbitstream_uint1(struct rbitstream*str) { if (str->bits_avail == 0) { get_byte(str); } assert(str->bits_avail > 0); str->bits_avail -= 1; return (str->byte & (1 << str->bits_avail))? 1 : 0; } uint8_t _jxr_rbitstream_uint2(struct rbitstream*str) { uint8_t tmp = 0; tmp |= _jxr_rbitstream_uint1(str); tmp <<= 1; tmp |= _jxr_rbitstream_uint1(str); return tmp; } uint8_t _jxr_rbitstream_uint3(struct rbitstream*str) { uint8_t tmp = 0; tmp |= _jxr_rbitstream_uint1(str); tmp <<= 1; tmp |= _jxr_rbitstream_uint1(str); tmp <<= 1; tmp |= _jxr_rbitstream_uint1(str); return tmp; } uint8_t _jxr_rbitstream_uint4(struct rbitstream*str) { uint8_t tmp; int idx; if (str->bits_avail == 0) get_byte(str); if (str->bits_avail == 4) { str->bits_avail = 0; return str->byte & 0x0f; } tmp = 0; for (idx = 0 ; idx < 4 ; idx += 1) { tmp <<= 1; tmp |= _jxr_rbitstream_uint1(str); } return tmp; } uint8_t _jxr_rbitstream_uint6(struct rbitstream*str) { uint8_t tmp; int idx; tmp = _jxr_rbitstream_uint4(str); for (idx = 4 ; idx < 6 ; idx += 1) { tmp <<= 1; tmp |= _jxr_rbitstream_uint1(str); } return tmp; } uint8_t _jxr_rbitstream_uint8(struct rbitstream*str) { uint8_t tmp; int idx; if (str->bits_avail == 0) get_byte(str); if (str->bits_avail == 8) { str->bits_avail = 0; return str->byte; } tmp = 0; for (idx = 0 ; idx < 8 ; idx += 1) { tmp <<= 1; tmp |= _jxr_rbitstream_uint1(str); } return tmp; } uint16_t _jxr_rbitstream_uint12(struct rbitstream*str) { uint16_t tmp = 0; tmp = _jxr_rbitstream_uint8(str); tmp <<= 4; tmp |= _jxr_rbitstream_uint4(str); return tmp; } uint16_t _jxr_rbitstream_uint15(struct rbitstream*str) { uint16_t tmp = 0; tmp = _jxr_rbitstream_uint8(str); tmp <<= 4; tmp |= _jxr_rbitstream_uint4(str); tmp <<= 3; tmp |= _jxr_rbitstream_uint3(str); return tmp; } uint16_t _jxr_rbitstream_uint16(struct rbitstream*str) { uint16_t tmp = 0; tmp = _jxr_rbitstream_uint8(str); tmp <<= 8; tmp |= _jxr_rbitstream_uint8(str); return tmp; } uint32_t _jxr_rbitstream_uint32(struct rbitstream*str) { uint32_t tmp = 0; tmp = _jxr_rbitstream_uint16(str); tmp <<= 16; tmp |= _jxr_rbitstream_uint16(str); return tmp; } uint32_t _jxr_rbitstream_uintN(struct rbitstream*str, int N) { uint32_t tmp = 0; assert(N <= 32); while (N > 0) { tmp <<= 1; tmp |= _jxr_rbitstream_uint1(str); N -= 1; } return tmp; } int _jxr_rbitstream_intE(struct rbitstream*str, int code_size, const unsigned char*codeb, const signed char*codev) { int bits = 0; unsigned val = 0; while (codeb[val << (code_size-bits)] != bits) { val <<= 1; val |= _jxr_rbitstream_uint1(str); bits += 1; assert(bits <= code_size); } return codev[val << (code_size-bits)]; } int64_t _jxr_rbitstream_intVLW(struct rbitstream*str) { uint64_t val = _jxr_rbitstream_uint8(str); if (val < 0xfb) { uint64_t tmp = _jxr_rbitstream_uint8(str); val = val*256 + tmp; } else if (val == 0xfb) { val = _jxr_rbitstream_uint32(str); } else if (val == 0xfc) { uint64_t tmp; val = _jxr_rbitstream_uint32(str); tmp = _jxr_rbitstream_uint32(str); val = (val << (uint64_t)32) + tmp; } else { return 0; } return val; } void _jxr_wbitstream_initialize(struct wbitstream*str, FILE*fd) { str->byte = 0; str->bits_ready = 0; str->fd = fd; str->write_count = 0; } size_t _jxr_wbitstream_bitpos(struct wbitstream*str) { return str->write_count*8 + str->bits_ready; } static void put_byte(struct wbitstream*str) { assert(str->bits_ready == 8); fputc(str->byte, str->fd); str->byte = 0; str->bits_ready = 0; str->write_count += 1; } void _jxr_wbitstream_syncbyte(struct wbitstream*str) { if (str->bits_ready > 0) str->bits_ready = 8; } void _jxr_wbitstream_flush(struct wbitstream*str) { _jxr_wbitstream_syncbyte(str); if (str->bits_ready > 0) put_byte(str); } void _jxr_wbitstream_uint1(struct wbitstream*str, int val) { if (str->bits_ready == 8) put_byte(str); if (val) str->byte |= 0x80 >> str->bits_ready; str->bits_ready += 1; } void _jxr_wbitstream_uint2(struct wbitstream*str, uint8_t val) { int idx; for (idx = 0 ; idx < 2 ; idx += 1) { _jxr_wbitstream_uint1(str, val & (0x02 >> idx)); } } void _jxr_wbitstream_uint3(struct wbitstream*str, uint8_t val) { int idx; for (idx = 0 ; idx < 3 ; idx += 1) { _jxr_wbitstream_uint1(str, val & (0x04 >> idx)); } } void _jxr_wbitstream_uint4(struct wbitstream*str, uint8_t val) { int idx; for (idx = 0 ; idx < 4 ; idx += 1) { _jxr_wbitstream_uint1(str, val & (0x08 >> idx)); } } void _jxr_wbitstream_uint6(struct wbitstream*str, uint8_t val) { int idx; for (idx = 0 ; idx < 6 ; idx += 1) { _jxr_wbitstream_uint1(str, val & (0x20 >> idx)); } } void _jxr_wbitstream_uint8(struct wbitstream*str, uint8_t val) { int idx; if (str->bits_ready == 8) put_byte(str); if (str->bits_ready == 0) { str->bits_ready = 8; str->byte = val; return; } for (idx = 0 ; idx < 8 ; idx += 1) { _jxr_wbitstream_uint1(str, val & (0x80 >> idx)); } } void _jxr_wbitstream_uint12(struct wbitstream*str, uint16_t val) { int idx; for (idx = 0 ; idx < 12 ; idx += 1) { _jxr_wbitstream_uint1(str, val & (0x800 >> idx)); } } void _jxr_wbitstream_uint15(struct wbitstream*str, uint16_t val) { int idx; for (idx = 0 ; idx < 15 ; idx += 1) { _jxr_wbitstream_uint1(str, val & (0x4000 >> idx)); } } void _jxr_wbitstream_uint16(struct wbitstream*str, uint16_t val) { _jxr_wbitstream_uint8(str, val >> 8); _jxr_wbitstream_uint8(str, val >> 0); } void _jxr_wbitstream_uint32(struct wbitstream*str, uint32_t val) { _jxr_wbitstream_uint8(str, val >> 24); _jxr_wbitstream_uint8(str, val >> 16); _jxr_wbitstream_uint8(str, val >> 8); _jxr_wbitstream_uint8(str, val >> 0); } void _jxr_wbitstream_uintN(struct wbitstream*str, uint32_t val, int N) { assert(N <= 32); while (N > 0) { _jxr_wbitstream_uint1(str, 1 & (val >> (N-1))); N -= 1; } } void _jxr_wbitstream_intVLW(struct wbitstream*str, uint64_t val) { if (val == 0) { _jxr_wbitstream_uint8(str, 0xfe); } else if (val < 0xfb00) { _jxr_wbitstream_uint16(str, (uint16_t)val); } else if (val < 0x100000000ULL) { _jxr_wbitstream_uint8(str, 0xfb); _jxr_wbitstream_uint32(str, (uint32_t)val); } else { _jxr_wbitstream_uint8(str, 0xfc); _jxr_wbitstream_uint32(str, val >> 32ULL); _jxr_wbitstream_uint32(str, val >> 0ULL); } } void _jxr_wbitstream_mark(struct wbitstream*str) { if (str->bits_ready == 8) _jxr_wbitstream_flush(str); assert(str->bits_ready == 0); /* str->mark_stream_position = ftell(str->fd); */ str->write_count = 0; } const char* _jxr_vlc_index_name(int vlc) { switch (vlc) { case AbsLevelIndDCLum: return "AbsLevelIndDCLum"; case AbsLevelIndDCChr: return "AbsLevelIndDCChr"; case DecFirstIndLPLum: return "DecFirstIndLPLum"; case AbsLevelIndLP0: return "AbsLevelIndLP0"; case AbsLevelIndLP1: return "AbsLevelIndLP1"; case AbsLevelIndHP0: return "AbsLevelIndHP0"; case AbsLevelIndHP1: return "AbsLevelIndHP1"; case DecIndLPLum0: return "DecIndLPLum0"; case DecIndLPLum1: return "DecIndLPLum1"; case DecFirstIndLPChr: return "DecFirstIndLPChr"; case DecIndLPChr0: return "DecIndLPChr0"; case DecIndLPChr1: return "DecIndLPChr1"; case DecNumCBP: return "DecNumCBP"; case DecNumBlkCBP: return "DecNumBlkCBP"; case DecIndHPLum0: return "DecIndHPLum0"; case DecIndHPLum1: return "DecIndHPLum1"; case DecFirstIndHPLum: return "DecFirstIndHPLum"; case DecFirstIndHPChr: return "DecFirstIndHPChr"; case DecIndHPChr0: return "DecIndHPChr0"; case DecIndHPChr1: return "DecIndHPChr1"; default: return "?????"; } } /* * $Log: io.c,v $ * Revision 1.16 2009/05/29 12:00:00 microsoft * Reference Software v1.6 updates. * * Revision 1.15 2009/04/13 12:00:00 microsoft * Reference Software v1.5 updates. * * Revision 1.14 2008/03/05 06:58:10 gus * *** empty log message *** * * Revision 1.13 2008/02/28 18:50:31 steve * Portability fixes. * * Revision 1.12 2008/02/26 23:52:44 steve * Remove ident for MS compilers. * * Revision 1.11 2007/12/07 01:20:34 steve * Fix adapt not adapting on line ends. * * Revision 1.10 2007/12/06 17:53:35 steve * No longer need bitval dump. * * Revision 1.9 2007/11/30 01:50:58 steve * Compression of DCONLY GRAY. * * Revision 1.8 2007/11/26 01:47:15 steve * Add copyright notices per MS request. * * Revision 1.7 2007/11/19 18:22:34 steve * Skip ESCaped FLEXBITS tiles. * * Revision 1.6 2007/11/14 23:56:17 steve * Fix TILE ordering, using seeks, for FREQUENCY mode. * * Revision 1.5 2007/11/08 19:38:38 steve * Get stub DCONLY compression to work. * * Revision 1.4 2007/11/08 02:52:32 steve * Some progress in some encoding infrastructure. * * Revision 1.3 2007/08/15 01:54:11 steve * Add level2 filter to decoder. * * Revision 1.2 2007/06/21 17:31:22 steve * Successfully parse LP components. * * Revision 1.1 2007/06/06 17:19:12 steve * Introduce to CVS. * */