00001
00032 #include "linden_common.h"
00033
00034 #include "llmath.h"
00035
00036 #include "v3math.h"
00037 #include "patch_dct.h"
00038 #include "patch_code.h"
00039 #include "bitpack.h"
00040
00041 U32 gPatchSize, gWordBits;
00042
00043 void init_patch_coding(LLBitPack &bitpack)
00044 {
00045 bitpack.resetBitPacking();
00046 }
00047
00048 void code_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp)
00049 {
00050 #ifdef LL_BIG_ENDIAN
00051 U8 *stride = (U8 *)&gopp->stride;
00052 bitpack.bitPack(&(stride[1]), 8);
00053 bitpack.bitPack(&(stride[0]), 8);
00054 #else
00055 bitpack.bitPack((U8 *)&gopp->stride, 16);
00056 #endif
00057 bitpack.bitPack((U8 *)&gopp->patch_size, 8);
00058 bitpack.bitPack((U8 *)&gopp->layer_type, 8);
00059
00060 gPatchSize = gopp->patch_size;
00061 }
00062
00063 void code_patch_header(LLBitPack &bitpack, LLPatchHeader *ph, S32 *patch)
00064 {
00065 S32 i, j, temp, patch_size = gPatchSize, wbits = (ph->quant_wbits & 0xf) + 2;
00066 U32 max_wbits = wbits + 5, min_wbits = wbits>>1;
00067
00068 wbits = min_wbits;
00069
00070 for (i = 0; i < (int) patch_size*patch_size; i++)
00071 {
00072 temp = patch[i];
00073 if (temp)
00074 {
00075 if (temp < 0)
00076 temp *= -1;
00077 for (j = max_wbits; j > (int) min_wbits; j--)
00078 {
00079 if (temp & (1<<j))
00080 {
00081 if (j > wbits)
00082 wbits = j;
00083 break;
00084 }
00085 }
00086 }
00087 }
00088
00089 wbits += 1;
00090
00091 ph->quant_wbits &= 0xf0;
00092
00093 if ( (wbits > 17)
00094 ||(wbits < 2))
00095 {
00096 llerrs << "Bits needed per word in code_patch_header out of legal range. Adjust compression quatization." << llendl;
00097 }
00098
00099 ph->quant_wbits |= (wbits - 2);
00100
00101 bitpack.bitPack((U8 *)&ph->quant_wbits, 8);
00102 #ifdef LL_BIG_ENDIAN
00103 U8 *offset = (U8 *)&ph->dc_offset;
00104 bitpack.bitPack(&(offset[3]), 8);
00105 bitpack.bitPack(&(offset[2]), 8);
00106 bitpack.bitPack(&(offset[1]), 8);
00107 bitpack.bitPack(&(offset[0]), 8);
00108 #else
00109 bitpack.bitPack((U8 *)&ph->dc_offset, 32);
00110 #endif
00111 #ifdef LL_BIG_ENDIAN
00112 U8 *range = (U8 *)&ph->range;
00113 bitpack.bitPack(&(range[1]), 8);
00114 bitpack.bitPack(&(range[0]), 8);
00115 #else
00116 bitpack.bitPack((U8 *)&ph->range, 16);
00117 #endif
00118 #ifdef LL_BIG_ENDIAN
00119 U8 *ids = (U8 *)&ph->patchids;
00120 bitpack.bitPack(&(ids[1]), 8);
00121 bitpack.bitPack(&(ids[0]), 2);
00122 #else
00123 bitpack.bitPack((U8 *)&ph->patchids, 10);
00124 #endif
00125
00126 gWordBits = wbits;
00127 }
00128
00129 void code_end_of_data(LLBitPack &bitpack)
00130 {
00131 bitpack.bitPack((U8 *)&END_OF_PATCHES, 8);
00132 }
00133
00134 void code_patch(LLBitPack &bitpack, S32 *patch, S32 postquant)
00135 {
00136 S32 i, j, patch_size = gPatchSize, wbits = gWordBits;
00137 S32 temp;
00138 BOOL b_eob;
00139
00140 if ( (postquant > patch_size*patch_size)
00141 ||(postquant < 0))
00142 {
00143 llerrs << "Bad postquant in code_patch!" << llendl;
00144 }
00145
00146 if (postquant)
00147 patch[patch_size*patch_size - postquant] = 0;
00148
00149 for (i = 0; i < patch_size*patch_size; i++)
00150 {
00151 b_eob = FALSE;
00152 temp = patch[i];
00153 if (!temp)
00154 {
00155 b_eob = TRUE;
00156 for (j = i; j < patch_size*patch_size - postquant; j++)
00157 {
00158 if (patch[j])
00159 {
00160 b_eob = FALSE;
00161 break;
00162 }
00163 }
00164 if (b_eob)
00165 {
00166 bitpack.bitPack((U8 *)&ZERO_EOB, 2);
00167 return;
00168 }
00169 else
00170 {
00171 bitpack.bitPack((U8 *)&ZERO_CODE, 1);
00172 }
00173 }
00174 else
00175 {
00176 if (temp < 0)
00177 {
00178 temp *= -1;
00179 if (temp > (1<<wbits))
00180 {
00181 temp = (1<<wbits);
00182
00183 }
00184 bitpack.bitPack((U8 *)&NEGATIVE_VALUE, 3);
00185 bitpack.bitPack((U8 *)&temp, wbits);
00186 }
00187 else
00188 {
00189 if (temp > (1<<wbits))
00190 {
00191 temp = (1<<wbits);
00192
00193 }
00194 bitpack.bitPack((U8 *)&POSITIVE_VALUE, 3);
00195 bitpack.bitPack((U8 *)&temp, wbits);
00196 }
00197 }
00198 }
00199 }
00200
00201
00202 void end_patch_coding(LLBitPack &bitpack)
00203 {
00204 bitpack.flushBitPack();
00205 }
00206
00207 void init_patch_decoding(LLBitPack &bitpack)
00208 {
00209 bitpack.resetBitPacking();
00210 }
00211
00212 void decode_patch_group_header(LLBitPack &bitpack, LLGroupHeader *gopp)
00213 {
00214 U16 retvalu16;
00215
00216 retvalu16 = 0;
00217 #ifdef LL_BIG_ENDIAN
00218 U8 *ret = (U8 *)&retvalu16;
00219 bitpack.bitUnpack(&(ret[1]), 8);
00220 bitpack.bitUnpack(&(ret[0]), 8);
00221 #else
00222 bitpack.bitUnpack((U8 *)&retvalu16, 16);
00223 #endif
00224 gopp->stride = retvalu16;
00225
00226 U8 retvalu8 = 0;
00227 bitpack.bitUnpack(&retvalu8, 8);
00228 gopp->patch_size = retvalu8;
00229
00230 retvalu8 = 0;
00231 bitpack.bitUnpack(&retvalu8, 8);
00232 gopp->layer_type = retvalu8;
00233
00234 gPatchSize = gopp->patch_size;
00235 }
00236
00237 void decode_patch_header(LLBitPack &bitpack, LLPatchHeader *ph)
00238 {
00239 U8 retvalu8;
00240
00241 retvalu8 = 0;
00242 bitpack.bitUnpack(&retvalu8, 8);
00243 ph->quant_wbits = retvalu8;
00244
00245 if (END_OF_PATCHES == ph->quant_wbits)
00246 {
00247
00248 ph->dc_offset = 0;
00249 ph->range = 0;
00250 ph->patchids = 0;
00251 return;
00252 }
00253
00254 U32 retvalu32 = 0;
00255 #ifdef LL_BIG_ENDIAN
00256 U8 *ret = (U8 *)&retvalu32;
00257 bitpack.bitUnpack(&(ret[3]), 8);
00258 bitpack.bitUnpack(&(ret[2]), 8);
00259 bitpack.bitUnpack(&(ret[1]), 8);
00260 bitpack.bitUnpack(&(ret[0]), 8);
00261 #else
00262 bitpack.bitUnpack((U8 *)&retvalu32, 32);
00263 #endif
00264 ph->dc_offset = *(F32 *)&retvalu32;
00265
00266 U16 retvalu16 = 0;
00267 #ifdef LL_BIG_ENDIAN
00268 ret = (U8 *)&retvalu16;
00269 bitpack.bitUnpack(&(ret[1]), 8);
00270 bitpack.bitUnpack(&(ret[0]), 8);
00271 #else
00272 bitpack.bitUnpack((U8 *)&retvalu16, 16);
00273 #endif
00274 ph->range = retvalu16;
00275
00276 retvalu16 = 0;
00277 #ifdef LL_BIG_ENDIAN
00278 ret = (U8 *)&retvalu16;
00279 bitpack.bitUnpack(&(ret[1]), 8);
00280 bitpack.bitUnpack(&(ret[0]), 2);
00281 #else
00282 bitpack.bitUnpack((U8 *)&retvalu16, 10);
00283 #endif
00284 ph->patchids = retvalu16;
00285
00286 gWordBits = (ph->quant_wbits & 0xf) + 2;
00287 }
00288
00289 void decode_patch(LLBitPack &bitpack, S32 *patches)
00290 {
00291 #ifdef LL_BIG_ENDIAN
00292 S32 i, j, patch_size = gPatchSize, wbits = gWordBits;
00293 U8 tempu8;
00294 U16 tempu16;
00295 U32 tempu32;
00296 for (i = 0; i < patch_size*patch_size; i++)
00297 {
00298 bitpack.bitUnpack((U8 *)&tempu8, 1);
00299 if (tempu8)
00300 {
00301
00302 bitpack.bitUnpack((U8 *)&tempu8, 1);
00303 if (tempu8)
00304 {
00305
00306 bitpack.bitUnpack((U8 *)&tempu8, 1);
00307 if (tempu8)
00308 {
00309
00310 patches[i] = -1;
00311 }
00312 else
00313 {
00314
00315 patches[i] = 1;
00316 }
00317 if (wbits <= 8)
00318 {
00319 bitpack.bitUnpack((U8 *)&tempu8, wbits);
00320 patches[i] *= tempu8;
00321 }
00322 else if (wbits <= 16)
00323 {
00324 tempu16 = 0;
00325 U8 *ret = (U8 *)&tempu16;
00326 bitpack.bitUnpack(&(ret[1]), 8);
00327 bitpack.bitUnpack(&(ret[0]), wbits - 8);
00328 patches[i] *= tempu16;
00329 }
00330 else if (wbits <= 24)
00331 {
00332 tempu32 = 0;
00333 U8 *ret = (U8 *)&tempu32;
00334 bitpack.bitUnpack(&(ret[2]), 8);
00335 bitpack.bitUnpack(&(ret[1]), 8);
00336 bitpack.bitUnpack(&(ret[0]), wbits - 16);
00337 patches[i] *= tempu32;
00338 }
00339 else if (wbits <= 32)
00340 {
00341 tempu32 = 0;
00342 U8 *ret = (U8 *)&tempu32;
00343 bitpack.bitUnpack(&(ret[3]), 8);
00344 bitpack.bitUnpack(&(ret[2]), 8);
00345 bitpack.bitUnpack(&(ret[1]), 8);
00346 bitpack.bitUnpack(&(ret[0]), wbits - 24);
00347 patches[i] *= tempu32;
00348 }
00349 }
00350 else
00351 {
00352 for (j = i; j < patch_size*patch_size; j++)
00353 {
00354 patches[j] = 0;
00355 }
00356 return;
00357 }
00358 }
00359 else
00360 {
00361 patches[i] = 0;
00362 }
00363 }
00364 #else
00365 S32 i, j, patch_size = gPatchSize, wbits = gWordBits;
00366 U32 temp;
00367 for (i = 0; i < patch_size*patch_size; i++)
00368 {
00369 temp = 0;
00370 bitpack.bitUnpack((U8 *)&temp, 1);
00371 if (temp)
00372 {
00373
00374 temp = 0;
00375 bitpack.bitUnpack((U8 *)&temp, 1);
00376 if (temp)
00377 {
00378
00379 temp = 0;
00380 bitpack.bitUnpack((U8 *)&temp, 1);
00381 if (temp)
00382 {
00383
00384 temp = 0;
00385 bitpack.bitUnpack((U8 *)&temp, wbits);
00386 patches[i] = temp;
00387 patches[i] *= -1;
00388 }
00389 else
00390 {
00391
00392 temp = 0;
00393 bitpack.bitUnpack((U8 *)&temp, wbits);
00394 patches[i] = temp;
00395 }
00396 }
00397 else
00398 {
00399 for (j = i; j < patch_size*patch_size; j++)
00400 {
00401 patches[j] = 0;
00402 }
00403 return;
00404 }
00405 }
00406 else
00407 {
00408 patches[i] = 0;
00409 }
00410 }
00411 #endif
00412 }
00413