/*---------------------------------------------------------------------------* Project: Horizon File: cx_StreamingUncompression.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 25056 $ *---------------------------------------------------------------------------*/ #ifndef NN_CX_STREAMING_UNCOMPRESSION_H_ #define NN_CX_STREAMING_UNCOMPRESSION_H_ #include #include namespace nn { namespace cx { /*! @brief ランレングス圧縮データ展開用コンテキスト */ struct UncompContextRL { u8 *destp; //!< 書き込み先ポインタ 4B s32 destCount; //!< 残り書き込みサイズ 4B s32 forceDestCount; //!< 強制的に展開先サイズを設定 4B u16 length; //!< 連続書き込み残りサイズ 2B u8 flags; //!< 圧縮フラグ 1B u8 headerSize; //!< 読み込み途中のヘッダサイズ 1B // 計 16B }; /*! @brief LZ77 圧縮データ展開用コンテキスト */ struct UncompContextLZ { u8 *destp; //!< 書き込み先ポインタ 4B s32 destCount; //!< 残り書き込みサイズ 4B s32 forceDestCount; //!< 強制的に展開先サイズを設定 4B s32 length; //!< 連続書き込み残り長 4B u8 lengthFlg; //!< length取得済フラグ 1B u8 flags; //!< 圧縮フラグ 1B u8 flagIndex; //!< カレント圧縮フラグインデックス 1B u8 headerSize; //!< 読み込み途中のヘッダサイズ 1B u8 exFormat; //!< LZ77圧縮拡張オプション 1B u8 padding_[3]; // 3B // 計 24B }; /*! @brief ハフマン圧縮データ展開用コンテキスト */ struct UncompContextHuffman { u8 *destp; //!< 書き込み先ポインタ 4B s32 destCount; //!< 残り書き込みサイズ 4B s32 forceDestCount; //!< 強制的に展開先サイズを設定 4B u8 *treep; //!< ハフマン符号テーブル、カレントポインタ 4B u32 srcTmp; //!< 読み込み途中のデータ 4B u32 destTmp; //!< 復号化途中のデータ 4B s16 treeSize; //!< ハフマン符号テーブルサイズ 2B u8 srcTmpCnt; //!< 読み込み途中のデータサイズ 1B u8 destTmpCnt; //!< 復号化済のビット数 1B u8 bitSize; //!< 符号化ビットサイズ 1B u8 headerSize; //!< 読み込み途中のヘッダサイズ 1B u8 padding_[2]; // 2B u8 tree[0x200]; //!< ハフマン符号テーブル 512B (4bit符号化であれば32Bで十分なのですが8bit分確保) // 計 544B (4bit符号化の場合は60Bあればよい) }; /*! @brief LZ-ハフマン複合圧縮データ展開用コンテキスト */ struct UncompContextLH { u8 *destp; //!< 書き込み先ポインタ 4B s32 destCount; //!< 残り書き込みサイズ 4B s32 forceDestCount; //!< 強制的に展開先サイズを設定 4B u16 huffTable9 [ 1 << (9 + 1) ]; //!< ハフマン符号テーブル 2048B u16 huffTable12[ 1 << (5 + 1) ]; //!< ハフマン符号テーブル 128B u16 *nodep; //!< ハフマンテーブルの探索中ノード 4B s32 tableSize9; //!< 読み込み途中のテーブルサイズ 4B s32 tableSize12; //!< 読み込み途中のテーブルサイズ 4B u32 tableIdx; //!< テーブル読み込み位置インデクス 4B u32 stream; //!< 読み込み用ビットストリーム 4B u32 stream_len; //!< 読み込み用ストリームの有効ビット数 4B u16 length; //!< LZ圧縮の読み取り長 2B s8 offset_bits; //!< オフセット情報のビット長 1B u8 headerSize; //!< 読み込み途中のヘッダサイズ 1B }; // 計 2216B /*! @brief LZ-RangeCoder 複合圧縮データ展開用コンテキスト */ struct UncompContextLRC { u8 *destp; //!< 書き込み先ポインタ 4B s32 destCount; //!< 残り書き込みサイズ 4B s32 forceDestCount; //!< 強制的に展開先サイズを設定 4B u32 freq9 [ 1 << 9 ]; //!< codeデータ頻度テーブル 2048B u32 low_cnt9 [ 1 << 9 ]; //!< codeデータlow_cntテーブル 2048B u32 freq12 [ 1 << 12 ]; //!< offsetデータ頻度テーブル 16384B u32 low_cnt12[ 1 << 12 ]; //!< offsetデータlow_cntテーブル 16384B u32 total9; //!< codeデータtotal値 4B u32 total12; //!< offsetデータtotal値 4B u32 range; //!< レンジコーダrange状態 4B u32 code; //!< レンジコーダcode状態 4B u32 low; //!< レンジコーダlow状態 4B u32 carry_cnt; //!< レンジコーダキャリー桁数 4B u8 carry; //!< レンジコーダキャリー状態 1B u8 codeLen; //!< レンジコーダ必要コード長 1B u16 length; //!< LZ圧縮の読み取り長 2B u8 headerSize; //!< 読み込み途中のヘッダサイズ 1B u8 padding_[3]; // 3B }; // 計 36908B /*! @brief ランレングス圧縮データのストリーミング展開コンテキストを初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス */ void InitUncompContextRL( UncompContextRL *context, void *dest ); /*! @brief LZ77 圧縮データのストリーミング展開コンテキストを初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス */ void InitUncompContextLZ( UncompContextLZ *context, void *dest ); /*! @brief ハフマン圧縮データのストリーミング展開コンテキストを初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス */ void InitUncompContextHuffman( UncompContextHuffman *context, void *dest ); /*! @brief LZ-ハフマン複合圧縮データのストリーミング展開コンテキストを初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス */ void InitUncompContextLH( UncompContextLH * context, void* dest ); /*! @brief LZ-RangeCoder 複合圧縮データのストリーミング展開コンテキストを初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス */ void InitUncompContextLRC( UncompContextLRC * context, void* dest ); /*! @brief ランレングス圧縮データをストリーミング展開します。 @param[in] context 展開コンテキストへのポインタ @param[in] data 圧縮データへのポインタ @param[in] len データサイズ @return 残り展開データサイズを返します。 */ s32 ReadUncompRL( UncompContextRL *context, const void *data, u32 len ); /*! @brief LZ77 圧縮データをストリーミング展開します。 @param[in] context 展開コンテキストへのポインタ @param[in] data 圧縮データへのポインタ @param[in] len データサイズ @return 残り展開データサイズを返します。 */ s32 ReadUncompLZ( UncompContextLZ *context, const void *data, u32 len ); /*! @brief ハフマン圧縮データをストリーミング展開します。 @param[in] context 展開コンテキストへのポインタ @param[in] data 圧縮データへのポインタ @param[in] len データサイズ @return 残り展開データサイズを返します。 */ s32 ReadUncompHuffman( UncompContextHuffman *context, const void *data, u32 len ); /*! @brief LZ-ハフマン複合圧縮データをストリーミング展開します。 @param[in] context 展開コンテキストへのポインタ @param[in] data 圧縮データへのポインタ @param[in] len データサイズ @return 残り展開データサイズを返します。 */ s32 ReadUncompLH( UncompContextLH *context, const void* data, u32 len ); /*! @brief LZ-RangeCoder 複合圧縮データをストリーミング展開します。 @param[in] context 展開コンテキストへのポインタ @param[in] data 圧縮データへのポインタ @param[in] len データサイズ @return 残り展開データサイズを返します。 */ s32 ReadUncompLRC( UncompContextLRC *context, const void* data, u32 len ); /*! @brief 圧縮のストリーミング展開が完了しているかどうかを判定します。 @param[in] context 展開コンテキストへのポインタ @return 展開が完了している場合には true を、 まだ読み込むべきデータが残っている場合には false を返します */ template inline bool IsFinishedUncompRL( const UncompContext *context ) { return (context->destCount > 0 || context->headerSize > 0)? false : true; } /*! @brief ランレングス圧縮データのストリーミング展開コンテキストを、 展開サイズを指定して初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス @param[in] destSize 展開サイズ */ inline void InitUncompContextRLFront( UncompContextRL *context, void *dest, s32 destSize ) { NN_ASSERT( destSize > 0 ); InitUncompContextRL( context, dest ); context->forceDestCount = destSize; } /*! @brief LZ77 圧縮データのストリーミング展開コンテキストを、 展開サイズを指定して初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス @param[in] destSize 展開サイズ */ inline void InitUncompContextLZFront( UncompContextLZ *context, void *dest, s32 destSize ) { NN_ASSERT( destSize > 0 ); InitUncompContextLZ( context, dest ); context->forceDestCount = destSize; } /*! @brief ハフマン圧縮データのストリーミング展開コンテキストを、 展開サイズを指定して初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス @param[in] destSize 展開サイズ */ inline void InitUncompContextHuffmanFront( UncompContextHuffman *context, void *dest, s32 destSize ) { NN_ASSERT( destSize > 0 ); InitUncompContextHuffman( context, dest ); context->forceDestCount = destSize; } /*! @brief LZ-ハフマン複合圧縮データのストリーミング展開コンテキストを、 展開サイズを指定して初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス @param[in] destSize 展開サイズ */ inline void InitUncompContextLHFront( UncompContextLH *context, void *dest, s32 destSize ) { NN_ASSERT( destSize > 0 ); InitUncompContextLH( context, dest ); context->forceDestCount = destSize; } /*! @brief LZ-RangeCoder 複合圧縮データのストリーミング展開コンテキストを、 展開サイズを指定して初期化します。 @param[in] context 展開コンテキストへのポインタ @param[in] dest 展開先アドレス @param[in] destSize 展開サイズ */ inline void InitUncompContextLRCFront( UncompContextLRC *context, void *dest, s32 destSize ) { NN_ASSERT( destSize > 0 ); InitUncompContextLRC( context, dest ); context->forceDestCount = destSize; } } // namespace cx } // namespace nn /* NN_CX_STREAMING_UNCOMPRESSION_H_ */ #endif