patch_code.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llmath.h"
00035 //#include "vmath.h"
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 //                                      printf("patch quatization exceeding allowable bits!");
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 //                                      printf("patch quatization exceeding allowable bits!");
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                 // End of data, blitz the rest.
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                         // either 0 EOB or Value
00302                         bitpack.bitUnpack((U8 *)&tempu8, 1);
00303                         if (tempu8)
00304                         {
00305                                 // value
00306                                 bitpack.bitUnpack((U8 *)&tempu8, 1);
00307                                 if (tempu8)
00308                                 {
00309                                         // negative
00310                                         patches[i] = -1;
00311                                 }
00312                                 else
00313                                 {
00314                                         // positive
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                         // either 0 EOB or Value
00374                         temp = 0;
00375                         bitpack.bitUnpack((U8 *)&temp, 1);
00376                         if (temp)
00377                         {
00378                                 // value
00379                                 temp = 0;
00380                                 bitpack.bitUnpack((U8 *)&temp, 1);
00381                                 if (temp)
00382                                 {
00383                                         // negative
00384                                         temp = 0;
00385                                         bitpack.bitUnpack((U8 *)&temp, wbits);
00386                                         patches[i] = temp;
00387                                         patches[i] *= -1;
00388                                 }
00389                                 else
00390                                 {
00391                                         // positive
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 

Generated on Thu Jul 1 06:09:57 2010 for Second Life Viewer by  doxygen 1.4.7