1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     cx_StreamingUncompression.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 25056 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_CX_STREAMING_UNCOMPRESSION_H_
17 #define NN_CX_STREAMING_UNCOMPRESSION_H_
18 
19 #include <nn/types.h>
20 #include <nn/assert.h>
21 
22 namespace nn {
23 namespace cx {
24 
25 /*!
26     @brief      ランレングス圧縮データ展開用コンテキスト
27  */
28 struct UncompContextRL
29 {
30     u8 *destp;                         //!< 書き込み先ポインタ          4B
31     s32 destCount;                     //!< 残り書き込みサイズ          4B
32     s32 forceDestCount;                //!< 強制的に展開先サイズを設定  4B
33     u16 length;                        //!< 連続書き込み残りサイズ      2B
34     u8  flags;                         //!< 圧縮フラグ                  1B
35     u8  headerSize;                    //!< 読み込み途中のヘッダサイズ  1B
36                                        //                           計 16B
37 };
38 
39 
40 /*!
41     @brief      LZ77 圧縮データ展開用コンテキスト
42  */
43 struct UncompContextLZ
44 {
45     u8 *destp;                         //!< 書き込み先ポインタ              4B
46     s32 destCount;                     //!< 残り書き込みサイズ              4B
47     s32 forceDestCount;                //!< 強制的に展開先サイズを設定      4B
48     s32 length;                        //!< 連続書き込み残り長              4B
49     u8  lengthFlg;                     //!< length取得済フラグ              1B
50     u8  flags;                         //!< 圧縮フラグ                      1B
51     u8  flagIndex;                     //!< カレント圧縮フラグインデックス  1B
52     u8  headerSize;                    //!< 読み込み途中のヘッダサイズ      1B
53     u8  exFormat;                      //!< LZ77圧縮拡張オプション          1B
54     u8  padding_[3];                   //                                   3B
55                                        //                               計 24B
56 };
57 
58 
59 /*!
60     @brief      ハフマン圧縮データ展開用コンテキスト
61  */
62 struct UncompContextHuffman
63 {
64     u8 *destp;                         //!< 書き込み先ポインタ                     4B
65     s32 destCount;                     //!< 残り書き込みサイズ                     4B
66     s32 forceDestCount;                //!< 強制的に展開先サイズを設定             4B
67     u8 *treep;                         //!< ハフマン符号テーブル、カレントポインタ 4B
68     u32 srcTmp;                        //!< 読み込み途中のデータ                   4B
69     u32 destTmp;                       //!< 復号化途中のデータ                     4B
70     s16 treeSize;                      //!< ハフマン符号テーブルサイズ             2B
71     u8  srcTmpCnt;                     //!< 読み込み途中のデータサイズ             1B
72     u8  destTmpCnt;                    //!< 復号化済のビット数                     1B
73     u8  bitSize;                       //!< 符号化ビットサイズ                     1B
74     u8  headerSize;                    //!< 読み込み途中のヘッダサイズ             1B
75     u8  padding_[2];                   //                                          2B
76     u8  tree[0x200];                   //!< ハフマン符号テーブル                 512B  (4bit符号化であれば32Bで十分なのですが8bit分確保)
77                                        //                                     計 544B  (4bit符号化の場合は60Bあればよい)
78 };
79 
80 
81 /*!
82     @brief      LZ-ハフマン複合圧縮データ展開用コンテキスト
83  */
84 struct UncompContextLH
85 {
86     u8   *destp;                         //!< 書き込み先ポインタ                 4B
87     s32  destCount;                      //!< 残り書き込みサイズ                 4B
88     s32  forceDestCount;                 //!< 強制的に展開先サイズを設定         4B
89     u16  huffTable9 [ 1 << (9 + 1) ];    //!< ハフマン符号テーブル            2048B
90     u16  huffTable12[ 1 << (5 + 1) ];    //!< ハフマン符号テーブル             128B
91     u16  *nodep;                         //!< ハフマンテーブルの探索中ノード     4B
92     s32  tableSize9;                     //!< 読み込み途中のテーブルサイズ       4B
93     s32  tableSize12;                    //!< 読み込み途中のテーブルサイズ       4B
94     u32  tableIdx;                       //!< テーブル読み込み位置インデクス     4B
95     u32  stream;                         //!< 読み込み用ビットストリーム         4B
96     u32  stream_len;                     //!< 読み込み用ストリームの有効ビット数 4B
97     u16  length;                         //!< LZ圧縮の読み取り長                 2B
98     s8   offset_bits;                    //!< オフセット情報のビット長           1B
99     u8   headerSize;                     //!< 読み込み途中のヘッダサイズ         1B
100 };                                       //                               計  2216B
101 
102 
103 /*!
104     @brief      LZ-RangeCoder 複合圧縮データ展開用コンテキスト
105  */
106 struct UncompContextLRC
107 {
108     u8   *destp;                         //!< 書き込み先ポインタ                 4B
109     s32  destCount;                      //!< 残り書き込みサイズ                 4B
110     s32  forceDestCount;                 //!< 強制的に展開先サイズを設定         4B
111     u32  freq9    [ 1 << 9  ];           //!< codeデータ頻度テーブル          2048B
112     u32  low_cnt9 [ 1 << 9  ];           //!< codeデータlow_cntテーブル       2048B
113     u32  freq12   [ 1 << 12 ];           //!< offsetデータ頻度テーブル       16384B
114     u32  low_cnt12[ 1 << 12 ];           //!< offsetデータlow_cntテーブル    16384B
115     u32  total9;                         //!< codeデータtotal値                  4B
116     u32  total12;                        //!< offsetデータtotal値                4B
117     u32  range;                          //!< レンジコーダrange状態              4B
118     u32  code;                           //!< レンジコーダcode状態               4B
119     u32  low;                            //!< レンジコーダlow状態                4B
120     u32  carry_cnt;                      //!< レンジコーダキャリー桁数           4B
121     u8   carry;                          //!< レンジコーダキャリー状態           1B
122     u8   codeLen;                        //!< レンジコーダ必要コード長           1B
123     u16  length;                         //!< LZ圧縮の読み取り長                 2B
124 
125     u8   headerSize;                     //!< 読み込み途中のヘッダサイズ         1B
126     u8   padding_[3];                    //                                      3B
127 };                                       //                               計 36908B
128 
129 
130 /*!
131     @brief      ランレングス圧縮データのストリーミング展開コンテキストを初期化します。
132     @param[in]  context     展開コンテキストへのポインタ
133     @param[in]  dest        展開先アドレス
134  */
135 void InitUncompContextRL( UncompContextRL *context, void *dest );
136 
137 
138 /*!
139     @brief      LZ77 圧縮データのストリーミング展開コンテキストを初期化します。
140     @param[in]  context     展開コンテキストへのポインタ
141     @param[in]  dest        展開先アドレス
142  */
143 void InitUncompContextLZ( UncompContextLZ *context, void *dest );
144 
145 
146 /*!
147     @brief      ハフマン圧縮データのストリーミング展開コンテキストを初期化します。
148     @param[in]  context     展開コンテキストへのポインタ
149     @param[in]  dest        展開先アドレス
150  */
151 void InitUncompContextHuffman( UncompContextHuffman    *context,
152                                  void                      *dest );
153 
154 /*!
155     @brief      LZ-ハフマン複合圧縮データのストリーミング展開コンテキストを初期化します。
156     @param[in]  context     展開コンテキストへのポインタ
157     @param[in]  dest        展開先アドレス
158  */
159 void InitUncompContextLH( UncompContextLH * context, void* dest );
160 
161 
162 /*!
163     @brief      LZ-RangeCoder 複合圧縮データのストリーミング展開コンテキストを初期化します。
164     @param[in]  context     展開コンテキストへのポインタ
165     @param[in]  dest        展開先アドレス
166  */
167 void InitUncompContextLRC( UncompContextLRC * context, void* dest );
168 
169 
170 /*!
171     @brief      ランレングス圧縮データをストリーミング展開します。
172     @param[in]  context     展開コンテキストへのポインタ
173     @param[in]  data        圧縮データへのポインタ
174     @param[in]  len         データサイズ
175     @return     残り展開データサイズを返します。
176  */
177 s32 ReadUncompRL( UncompContextRL *context, const void *data, u32 len );
178 
179 
180 /*!
181     @brief      LZ77 圧縮データをストリーミング展開します。
182     @param[in]  context     展開コンテキストへのポインタ
183     @param[in]  data        圧縮データへのポインタ
184     @param[in]  len         データサイズ
185     @return     残り展開データサイズを返します。
186  */
187 s32 ReadUncompLZ( UncompContextLZ *context, const void *data, u32 len );
188 
189 
190 /*!
191     @brief      ハフマン圧縮データをストリーミング展開します。
192     @param[in]  context     展開コンテキストへのポインタ
193     @param[in]  data        圧縮データへのポインタ
194     @param[in]  len         データサイズ
195     @return     残り展開データサイズを返します。
196  */
197 s32 ReadUncompHuffman( UncompContextHuffman *context, const void *data, u32 len );
198 
199 
200 /*!
201     @brief      LZ-ハフマン複合圧縮データをストリーミング展開します。
202     @param[in]  context     展開コンテキストへのポインタ
203     @param[in]  data        圧縮データへのポインタ
204     @param[in]  len         データサイズ
205     @return     残り展開データサイズを返します。
206  */
207 s32 ReadUncompLH( UncompContextLH *context, const void* data, u32 len );
208 
209 
210 /*!
211     @brief      LZ-RangeCoder 複合圧縮データをストリーミング展開します。
212     @param[in]  context     展開コンテキストへのポインタ
213     @param[in]  data        圧縮データへのポインタ
214     @param[in]  len         データサイズ
215     @return     残り展開データサイズを返します。
216  */
217 s32 ReadUncompLRC( UncompContextLRC *context, const void* data, u32 len );
218 
219 
220 /*!
221     @brief      圧縮のストリーミング展開が完了しているかどうかを判定します。
222     @param[in]  context     展開コンテキストへのポインタ
223     @return     展開が完了している場合には true を、
224                 まだ読み込むべきデータが残っている場合には false を返します
225  */
226 template <typename UncompContext>
IsFinishedUncompRL(const UncompContext * context)227 inline bool IsFinishedUncompRL( const UncompContext *context )
228 {
229     return (context->destCount > 0 || context->headerSize > 0)? false : true;
230 }
231 
232 
233 /*!
234     @brief      ランレングス圧縮データのストリーミング展開コンテキストを、
235                 展開サイズを指定して初期化します。
236     @param[in]  context     展開コンテキストへのポインタ
237     @param[in]  dest        展開先アドレス
238     @param[in]  destSize    展開サイズ
239  */
InitUncompContextRLFront(UncompContextRL * context,void * dest,s32 destSize)240 inline void InitUncompContextRLFront( UncompContextRL *context, void *dest, s32 destSize )
241 {
242     NN_ASSERT( destSize > 0 );
243     InitUncompContextRL( context, dest );
244     context->forceDestCount = destSize;
245 }
246 
247 
248 /*!
249     @brief      LZ77 圧縮データのストリーミング展開コンテキストを、
250                 展開サイズを指定して初期化します。
251     @param[in]  context     展開コンテキストへのポインタ
252     @param[in]  dest        展開先アドレス
253     @param[in]  destSize    展開サイズ
254  */
InitUncompContextLZFront(UncompContextLZ * context,void * dest,s32 destSize)255 inline void InitUncompContextLZFront( UncompContextLZ *context, void *dest, s32 destSize )
256 {
257     NN_ASSERT( destSize > 0 );
258     InitUncompContextLZ( context, dest );
259     context->forceDestCount = destSize;
260 }
261 
262 
263 /*!
264     @brief      ハフマン圧縮データのストリーミング展開コンテキストを、
265                 展開サイズを指定して初期化します。
266     @param[in]  context     展開コンテキストへのポインタ
267     @param[in]  dest        展開先アドレス
268     @param[in]  destSize    展開サイズ
269  */
InitUncompContextHuffmanFront(UncompContextHuffman * context,void * dest,s32 destSize)270 inline void InitUncompContextHuffmanFront( UncompContextHuffman *context, void *dest, s32 destSize )
271 {
272     NN_ASSERT( destSize > 0 );
273     InitUncompContextHuffman( context, dest );
274     context->forceDestCount = destSize;
275 }
276 
277 
278 /*!
279     @brief      LZ-ハフマン複合圧縮データのストリーミング展開コンテキストを、
280                 展開サイズを指定して初期化します。
281     @param[in]  context     展開コンテキストへのポインタ
282     @param[in]  dest        展開先アドレス
283     @param[in]  destSize    展開サイズ
284  */
InitUncompContextLHFront(UncompContextLH * context,void * dest,s32 destSize)285 inline void InitUncompContextLHFront( UncompContextLH *context, void *dest, s32 destSize )
286 {
287     NN_ASSERT( destSize > 0 );
288     InitUncompContextLH( context, dest );
289     context->forceDestCount = destSize;
290 }
291 
292 
293 /*!
294     @brief      LZ-RangeCoder 複合圧縮データのストリーミング展開コンテキストを、
295                 展開サイズを指定して初期化します。
296     @param[in]  context     展開コンテキストへのポインタ
297     @param[in]  dest        展開先アドレス
298     @param[in]  destSize    展開サイズ
299  */
InitUncompContextLRCFront(UncompContextLRC * context,void * dest,s32 destSize)300 inline void InitUncompContextLRCFront( UncompContextLRC *context, void *dest, s32 destSize )
301 {
302     NN_ASSERT( destSize > 0 );
303     InitUncompContextLRC( context, dest );
304     context->forceDestCount = destSize;
305 }
306 
307 }   // namespace cx
308 }   // namespace nn
309 
310 /* NN_CX_STREAMING_UNCOMPRESSION_H_ */
311 #endif
312