PageRenderTime 31ms CodeModel.GetById 2ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmessage/patch_code.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 408 lines | 334 code | 37 blank | 37 comment | 36 complexity | bd12f5c223fa0c8df78ae277a0a61e61 MD5 | raw file
  1/** 
  2 * @file patch_code.cpp
  3 * @brief Encode patch DCT data into bitcode.
  4 *
  5 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "linden_common.h"
 28
 29#include "llmath.h"
 30//#include "vmath.h"
 31#include "v3math.h"
 32#include "patch_dct.h"
 33#include "patch_code.h"
 34#include "bitpack.h"
 35
 36U32 gPatchSize, gWordBits;
 37
 38void	init_patch_coding(LLBitPack &bitpack)
 39{
 40	bitpack.resetBitPacking();
 41}
 42
 43void	code_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp)
 44{
 45#ifdef LL_BIG_ENDIAN
 46	U8 *stride = (U8 *)&gopp->stride;
 47	bitpack.bitPack(&(stride[1]), 8);
 48	bitpack.bitPack(&(stride[0]), 8);
 49#else
 50	bitpack.bitPack((U8 *)&gopp->stride, 16);
 51#endif
 52	bitpack.bitPack((U8 *)&gopp->patch_size, 8);
 53	bitpack.bitPack((U8 *)&gopp->layer_type, 8);
 54
 55	gPatchSize = gopp->patch_size; 
 56}
 57
 58void	code_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, S32 *patch)
 59{
 60	S32		i, j, temp, patch_size = gPatchSize, wbits = (ph->quant_wbits & 0xf) + 2;
 61	U32     max_wbits = wbits + 5, min_wbits = wbits>>1;
 62
 63	wbits = min_wbits;
 64
 65	for (i = 0; i < (int) patch_size*patch_size; i++)
 66	{
 67		temp = patch[i];
 68		if (temp)
 69		{
 70			if (temp < 0)
 71				temp *= -1;
 72			for (j = max_wbits; j > (int) min_wbits; j--)
 73			{
 74				if (temp & (1<<j))
 75				{
 76					if (j > wbits)
 77						wbits = j;
 78					break;
 79				}
 80			}
 81		}
 82	}
 83
 84	wbits += 1;
 85
 86	ph->quant_wbits &= 0xf0;
 87
 88	if (  (wbits > 17)
 89		||(wbits < 2))
 90	{
 91		llerrs << "Bits needed per word in code_patch_header out of legal range.  Adjust compression quatization." << llendl;
 92	}
 93
 94	ph->quant_wbits |= (wbits - 2);
 95
 96	bitpack.bitPack((U8 *)&ph->quant_wbits, 8);
 97#ifdef LL_BIG_ENDIAN
 98	U8 *offset = (U8 *)&ph->dc_offset;
 99	bitpack.bitPack(&(offset[3]), 8);
100	bitpack.bitPack(&(offset[2]), 8);
101	bitpack.bitPack(&(offset[1]), 8);
102	bitpack.bitPack(&(offset[0]), 8);
103#else
104	bitpack.bitPack((U8 *)&ph->dc_offset, 32);
105#endif
106#ifdef LL_BIG_ENDIAN
107	U8 *range = (U8 *)&ph->range;
108	bitpack.bitPack(&(range[1]), 8);
109	bitpack.bitPack(&(range[0]), 8);
110#else
111	bitpack.bitPack((U8 *)&ph->range, 16);
112#endif
113#ifdef LL_BIG_ENDIAN
114	U8 *ids = (U8 *)&ph->patchids;
115	bitpack.bitPack(&(ids[1]), 8);
116	bitpack.bitPack(&(ids[0]), 2);
117#else
118	bitpack.bitPack((U8 *)&ph->patchids, 10);
119#endif
120
121	gWordBits = wbits;
122}
123
124void	code_end_of_data(LLBitPack &bitpack)
125{
126	bitpack.bitPack((U8 *)&END_OF_PATCHES, 8);
127}
128
129void code_patch(LLBitPack &bitpack, S32 *patch, S32 postquant)
130{
131	S32		i, j, patch_size = gPatchSize, wbits = gWordBits;
132	S32		temp;
133	BOOL	b_eob;
134
135	if (  (postquant > patch_size*patch_size)
136		||(postquant < 0))
137	{
138		llerrs << "Bad postquant in code_patch!"  << llendl;
139	}
140
141	if (postquant)
142		patch[patch_size*patch_size - postquant] = 0;
143
144	for (i = 0; i < patch_size*patch_size; i++)
145	{
146		b_eob = FALSE;
147		temp = patch[i];
148		if (!temp)
149		{
150			b_eob = TRUE;
151			for (j = i; j < patch_size*patch_size - postquant; j++)
152			{
153				if (patch[j])
154				{
155					b_eob = FALSE;
156					break;
157				}
158			}
159			if (b_eob)
160			{
161				bitpack.bitPack((U8 *)&ZERO_EOB, 2);
162				return;
163			}
164			else
165			{
166				bitpack.bitPack((U8 *)&ZERO_CODE, 1);
167			}
168		}
169		else
170		{
171			if (temp < 0)
172			{
173				temp *= -1;
174				if (temp > (1<<wbits))
175				{
176					temp = (1<<wbits);
177//					printf("patch quatization exceeding allowable bits!");
178				}
179				bitpack.bitPack((U8 *)&NEGATIVE_VALUE, 3);
180				bitpack.bitPack((U8 *)&temp, wbits);
181			}
182			else
183			{
184				if (temp > (1<<wbits))
185				{
186					temp = (1<<wbits);
187//					printf("patch quatization exceeding allowable bits!");
188				}
189				bitpack.bitPack((U8 *)&POSITIVE_VALUE, 3);
190				bitpack.bitPack((U8 *)&temp, wbits);
191			}
192		}
193	}
194}
195
196
197void	end_patch_coding(LLBitPack &bitpack)
198{
199	bitpack.flushBitPack();
200}
201
202void	init_patch_decoding(LLBitPack &bitpack)
203{
204	bitpack.resetBitPacking();
205}
206
207void	decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp)
208{
209	U16 retvalu16;
210
211	retvalu16 = 0;
212#ifdef LL_BIG_ENDIAN
213	U8 *ret = (U8 *)&retvalu16;
214	bitpack.bitUnpack(&(ret[1]), 8);
215	bitpack.bitUnpack(&(ret[0]), 8);
216#else
217	bitpack.bitUnpack((U8 *)&retvalu16, 16);
218#endif
219	gopp->stride = retvalu16;
220
221	U8 retvalu8 = 0;
222	bitpack.bitUnpack(&retvalu8, 8);
223	gopp->patch_size = retvalu8;
224
225	retvalu8 = 0;
226	bitpack.bitUnpack(&retvalu8, 8);
227	gopp->layer_type = retvalu8;
228
229	gPatchSize = gopp->patch_size; 
230}
231
232void	decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph)
233{
234	U8 retvalu8;
235
236	retvalu8 = 0;
237	bitpack.bitUnpack(&retvalu8, 8);
238	ph->quant_wbits = retvalu8;
239
240	if (END_OF_PATCHES == ph->quant_wbits)
241	{
242		// End of data, blitz the rest.
243		ph->dc_offset = 0;
244		ph->range = 0;
245		ph->patchids = 0;
246		return;
247	}
248
249	U32 retvalu32 = 0;
250#ifdef LL_BIG_ENDIAN
251	U8 *ret = (U8 *)&retvalu32;
252	bitpack.bitUnpack(&(ret[3]), 8);
253	bitpack.bitUnpack(&(ret[2]), 8);
254	bitpack.bitUnpack(&(ret[1]), 8);
255	bitpack.bitUnpack(&(ret[0]), 8);
256#else
257	bitpack.bitUnpack((U8 *)&retvalu32, 32);
258#endif
259	ph->dc_offset = *(F32 *)&retvalu32;
260
261	U16 retvalu16 = 0;
262#ifdef LL_BIG_ENDIAN
263	ret = (U8 *)&retvalu16;
264	bitpack.bitUnpack(&(ret[1]), 8);
265	bitpack.bitUnpack(&(ret[0]), 8);
266#else
267	bitpack.bitUnpack((U8 *)&retvalu16, 16);
268#endif
269	ph->range = retvalu16;
270
271	retvalu16 = 0;
272#ifdef LL_BIG_ENDIAN
273	ret = (U8 *)&retvalu16;
274	bitpack.bitUnpack(&(ret[1]), 8);
275	bitpack.bitUnpack(&(ret[0]), 2);
276#else
277	bitpack.bitUnpack((U8 *)&retvalu16, 10);
278#endif
279	ph->patchids = retvalu16;
280
281	gWordBits = (ph->quant_wbits & 0xf) + 2;
282}
283
284void	decode_patch(LLBitPack &bitpack, S32 *patches)
285{
286#ifdef LL_BIG_ENDIAN
287	S32		i, j, patch_size = gPatchSize, wbits = gWordBits;
288	U8		tempu8;
289	U16		tempu16;
290	U32		tempu32;
291	for (i = 0; i < patch_size*patch_size; i++)
292	{
293		bitpack.bitUnpack((U8 *)&tempu8, 1);
294		if (tempu8)
295		{
296			// either 0 EOB or Value
297			bitpack.bitUnpack((U8 *)&tempu8, 1);
298			if (tempu8)
299			{
300				// value
301				bitpack.bitUnpack((U8 *)&tempu8, 1);
302				if (tempu8)
303				{
304					// negative
305					patches[i] = -1;
306				}
307				else
308				{
309					// positive
310					patches[i] = 1;
311				}
312				if (wbits <= 8)
313				{
314					bitpack.bitUnpack((U8 *)&tempu8, wbits);
315					patches[i] *= tempu8;
316				}
317				else if (wbits <= 16)
318				{
319					tempu16 = 0;
320					U8 *ret = (U8 *)&tempu16;
321					bitpack.bitUnpack(&(ret[1]), 8);
322					bitpack.bitUnpack(&(ret[0]), wbits - 8);
323					patches[i] *= tempu16;
324				}
325				else if (wbits <= 24)
326				{
327					tempu32 = 0;
328					U8 *ret = (U8 *)&tempu32;
329					bitpack.bitUnpack(&(ret[2]), 8);
330					bitpack.bitUnpack(&(ret[1]), 8);
331					bitpack.bitUnpack(&(ret[0]), wbits - 16);
332					patches[i] *= tempu32;
333				}
334				else if (wbits <= 32)
335				{
336					tempu32 = 0;
337					U8 *ret = (U8 *)&tempu32;
338					bitpack.bitUnpack(&(ret[3]), 8);
339					bitpack.bitUnpack(&(ret[2]), 8);
340					bitpack.bitUnpack(&(ret[1]), 8);
341					bitpack.bitUnpack(&(ret[0]), wbits - 24);
342					patches[i] *= tempu32;
343				}
344			}
345			else
346			{
347				for (j = i; j < patch_size*patch_size; j++)
348				{
349					patches[j] = 0;
350				}
351				return;
352			}
353		}
354		else
355		{
356			patches[i] = 0;
357		}
358	}
359#else
360	S32		i, j, patch_size = gPatchSize, wbits = gWordBits;
361	U32		temp;
362	for (i = 0; i < patch_size*patch_size; i++)
363	{
364		temp = 0;
365		bitpack.bitUnpack((U8 *)&temp, 1);
366		if (temp)
367		{
368			// either 0 EOB or Value
369			temp = 0;
370			bitpack.bitUnpack((U8 *)&temp, 1);
371			if (temp)
372			{
373				// value
374				temp = 0;
375				bitpack.bitUnpack((U8 *)&temp, 1);
376				if (temp)
377				{
378					// negative
379					temp = 0;
380					bitpack.bitUnpack((U8 *)&temp, wbits);
381					patches[i] = temp;
382					patches[i] *= -1;
383				}
384				else
385				{
386					// positive
387					temp = 0;
388					bitpack.bitUnpack((U8 *)&temp, wbits);
389					patches[i] = temp;
390				}
391			}
392			else
393			{
394				for (j = i; j < patch_size*patch_size; j++)
395				{
396					patches[j] = 0;
397				}
398				return;
399			}
400		}
401		else
402		{
403			patches[i] = 0;
404		}
405	}
406#endif
407}
408