Changeset 5 in 3DVCSoftware for trunk/source/Lib/TLibDecoder/TDecSbac.cpp
- Timestamp:
- 12 Dec 2011, 18:35:44 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/Lib/TLibDecoder/TDecSbac.cpp
r2 r5 1 /* The copyright in this software is being made available under the BSD 2 * License, included below. This software may be subject to other third party 3 * and contributor rights, including patent rights, and no such rights are 4 * granted under this license. 5 * 6 * Copyright (c) 2010-2011, ISO/IEC 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 12 * * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * * Neither the name of the ISO/IEC nor the names of its contributors may 18 * be used to endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 1 34 2 35 … … 19 52 , m_cCUSkipFlagSCModel ( 1, 1, NUM_SKIP_FLAG_CTX ) 20 53 , m_cCUSplitFlagSCModel ( 1, 1, NUM_SPLIT_FLAG_CTX ) 21 #if MW_MVI_SIGNALLING_MODE == 022 , m_cCUMvInheritanceFlagSCModel(1, 1, NUM_MVI_FLAG_CTX )23 #endif24 54 , m_cCUMergeFlagExtSCModel ( 1, 1, NUM_MERGE_FLAG_EXT_CTX ) 25 55 , m_cCUMergeIdxExtSCModel ( 1, 1, NUM_MERGE_IDX_EXT_CTX ) … … 64 94 #endif 65 95 , m_cViewIdxSCModel ( 1, 1, NUM_VIEW_IDX_CTX ) 66 #if HHI_DMM_ INTRA96 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 67 97 , m_cIntraDMMSCModel ( 1, 1, NUM_DMM_CTX ) 68 98 , m_cIntraWedgeSCModel ( 1, 1, NUM_WEDGE_CTX ) … … 85 115 86 116 m_cCUSplitFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_SPLIT_FLAG ); 87 #if MW_MVI_SIGNALLING_MODE == 088 m_cCUMvInheritanceFlagSCModel.initBuffer( eSliceType, iQp, (Short*)INIT_MVI_FLAG );89 #endif90 117 m_cCUSkipFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_SKIP_FLAG ); 91 118 m_cCUMergeFlagExtSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_MERGE_FLAG_EXT ); … … 127 154 m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_TRANS_SUBDIV_FLAG ); 128 155 m_cViewIdxSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_VIEW_IDX ); 129 #if HHI_DMM_ INTRA156 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 130 157 m_cIntraDMMSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_INTRA_DMM ); 131 158 m_cIntraWedgeSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_INTRA_WEDGELET ); … … 361 388 return; 362 389 } 363 #if HHI_DMM_ INTRA390 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 364 391 Void TDecSbac::xReadExGolombLevel( UInt& ruiSymbol, ContextModel& rcSCModel ) 365 392 { … … 552 579 553 580 581 #if HHI_INTER_VIEW_MOTION_PRED || HHI_MPI 554 582 Void TDecSbac::parseMergeIndexMV( TComDataCU* pcCU, UInt& ruiMergeIndex, UInt uiAbsPartIdx, UInt uiDepth ) 555 583 { 556 #if MW_MVI_SIGNALLING_MODE == 1584 #if HHI_MPI 557 585 const Bool bMVIAvailable = pcCU->getSlice()->getSPS()->getUseMVI() && pcCU->getSlice()->getSliceType() != I_SLICE; 558 const UInt uiMviMergePos = bMVIAvailable ? MVI_MERGE_POS : MRG_MAX_NUM_CANDS;586 const UInt uiMviMergePos = bMVIAvailable ? HHI_MPI_MERGE_POS : MRG_MAX_NUM_CANDS; 559 587 #endif 560 588 //--- set number of candidates and availability --- … … 563 591 for( UInt uiIdx = 0; uiIdx < MRG_MAX_NUM_CANDS; uiIdx++ ) 564 592 { 565 #if MW_MVI_SIGNALLING_MODE == 1593 #if HHI_MPI 566 594 if( uiIdx == uiMviMergePos ) 567 595 { … … 629 657 } 630 658 631 #if MW_MVI_SIGNALLING_MODE == 1659 #if HHI_MPI 632 660 if( ruiMergeIndex > uiMviMergePos ) 633 661 { … … 661 689 DTRACE_CABAC_T( "\n" ); 662 690 } 691 #endif 663 692 664 693 665 694 Void TDecSbac::parseMergeIndex ( TComDataCU* pcCU, UInt& ruiMergeIndex, UInt uiAbsPartIdx, UInt uiDepth ) 666 695 { 667 #if MW_MVI_SIGNALLING_MODE == 1 668 if( ( pcCU->getSlice()->getSPS()->getViewId() > 0 && ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() & PDM_USE_FOR_MERGE ) == PDM_USE_FOR_MERGE ) || 669 ( pcCU->getSlice()->getSPS()->getUseMVI() && pcCU->getSlice()->getSliceType() != I_SLICE && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ) ) 670 #else 671 if( pcCU->getSlice()->getSPS()->getViewId() > 0 && ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() & PDM_USE_FOR_MERGE ) == PDM_USE_FOR_MERGE ) 672 #endif 696 #if HHI_INTER_VIEW_MOTION_PRED || HHI_MPI 697 if( 698 #if HHI_INTER_VIEW_MOTION_PRED 699 ( pcCU->getSlice()->getSPS()->getViewId() > 0 && ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() & PDM_USE_FOR_MERGE ) == PDM_USE_FOR_MERGE ) || 700 #endif 701 #if HHI_MPI 702 ( pcCU->getSlice()->getSPS()->getUseMVI() && pcCU->getSlice()->getSliceType() != I_SLICE && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ) || 703 #endif 704 0 705 ) 673 706 { 674 707 parseMergeIndexMV( pcCU, ruiMergeIndex, uiAbsPartIdx, uiDepth ); 675 708 return; 676 709 } 710 #endif 677 711 678 712 Bool bLeftInvolved = false; … … 827 861 } 828 862 829 #if MW_MVI_SIGNALLING_MODE == 0830 Void TDecSbac::parseMvInheritanceFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )831 {832 const Int iTextureModeDepth = pcCU->getTextureModeDepth( uiAbsPartIdx );833 if( iTextureModeDepth != -1 && uiDepth > iTextureModeDepth )834 return;835 836 UInt uiSymbol;837 m_pcTDecBinIf->decodeBin( uiSymbol, m_cCUMvInheritanceFlagSCModel.get( 0, 0, pcCU->getCtxMvInheritanceFlag( uiAbsPartIdx, uiDepth ) ) );838 if( uiSymbol == 1 )839 {840 pcCU->setTextureModeDepthSubParts( uiDepth, uiAbsPartIdx, uiDepth );841 }842 }843 #endif844 845 863 /** parse partition size 846 864 * \param pcCU … … 965 983 } 966 984 967 #if HHI_DMM_ INTRA985 #if HHI_DMM_WEDGE_INTRA 968 986 Void TDecSbac::xParseWedgeFullInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) 969 987 { … … 1136 1154 pcCU->setWedgePredDirDeltaDC2SubParts( iDC2, uiAbsPartIdx, uiDepth ); 1137 1155 } 1138 1156 #endif 1157 #if HHI_DMM_PRED_TEX 1139 1158 Void TDecSbac::xParseWedgePredTexDeltaInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) 1140 1159 { … … 1204 1223 UInt uiSymbol; 1205 1224 1206 #if HHI_DMM_ INTRA1225 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 1207 1226 UInt uiFlag = 0; 1208 if ( pcCU->getSlice()->getSPS()->isDepth() && pcCU->getSlice()->getSPS()->getUseD epthModelModes() && g_uiMaxCUWidth>>uiDepth < 64 )1227 if ( pcCU->getSlice()->getSPS()->isDepth() && pcCU->getSlice()->getSPS()->getUseDMM() && g_uiMaxCUWidth>>uiDepth < 64 ) 1209 1228 { 1210 1229 m_pcTDecBinIf->decodeBin( uiFlag, m_cIntraDMMSCModel.get(0, 0, 0) ); … … 1214 1233 UInt uiDMMode; 1215 1234 1216 #if DMM_NO_TEXTURE_MODES1217 pcCU->setTextureModeAllowanceSubParts( false, uiAbsPartIdx, uiDepth );1218 1235 #if HHI_DMM_WEDGE_INTRA && HHI_DMM_PRED_TEX 1236 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1237 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; 1219 1238 if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && g_uiMaxCUWidth>>uiDepth > 4 ) 1220 1239 { 1221 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1222 if( DMM_INTRA_MODE_BITS > 1 ) { m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; } 1223 1224 if( uiDMMode > 1 ) 1225 { 1226 uiDMMode += 4; 1227 } 1228 } 1229 else 1230 { 1231 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1240 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 2; 1232 1241 } 1233 1242 #else 1234 TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getTexturePic()->getPicYuvRec(); 1235 Int iRefStride = pcPicYuvRef->getStride(); 1236 Pel* piRefY; 1237 1238 TComYuv cTempYuv; 1239 UInt uiTempStride = 0; 1240 Pel* piTempY; 1241 1242 UInt uiWidth = g_uiMaxCUWidth>>uiDepth; 1243 UInt uiHeight = g_uiMaxCUHeight>>uiDepth; 1244 piRefY = pcPicYuvRef->getLumaAddr( pcCU->getAddr(), uiAbsPartIdx ); 1245 cTempYuv.create( uiWidth, uiHeight ); cTempYuv.clear(); 1246 piTempY = cTempYuv.getLumaAddr( 0, uiWidth ); 1247 uiTempStride = cTempYuv.getStride(); 1248 1249 for ( Int y = 0; y < uiHeight; y++ ) 1250 { 1251 ::memcpy(piTempY, piRefY, sizeof(Pel)*uiWidth); 1252 piTempY += uiTempStride; 1253 piRefY += iRefStride; 1254 } 1255 1256 UInt64 uiDCSAD = cTempYuv.getLumaDistDCSAD( uiWidth ); 1257 1258 cTempYuv.destroy(); 1259 1260 if( uiDCSAD < (UInt)(pcCU->getQP(0))/2 ) 1261 { 1262 pcCU->setTextureModeAllowanceSubParts( false, uiAbsPartIdx, uiDepth ); 1263 1243 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1264 1244 if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && g_uiMaxCUWidth>>uiDepth > 4 ) 1265 1245 { 1266 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1267 if( DMM_INTRA_MODE_BITS > 1 ) { m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; } 1268 1269 if( uiDMMode > 1 ) 1270 { 1271 uiDMMode += 4; 1272 } 1273 } 1274 else 1275 { 1276 pcCU->setTextureModeAllowanceSubParts( true, uiAbsPartIdx, uiDepth ); 1277 1278 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1279 } 1280 } 1281 else 1282 { 1283 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1284 if( DMM_INTRA_MODE_BITS > 1 ) { m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; } 1285 if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && g_uiMaxCUWidth>>uiDepth > 4 ) 1286 { 1287 if( DMM_INTRA_MODE_BITS > 2 ) { m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 2; } 1288 } 1289 } 1290 #endif 1291 uiIPredMode = g_aucAdditionalIntraModeList[uiDMMode]; 1292 1246 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; 1247 } 1248 #endif 1249 uiIPredMode = uiDMMode + MAX_MODE_ID_INTRA_DIR + 1; 1250 1251 #if HHI_DMM_WEDGE_INTRA 1293 1252 if( uiIPredMode == DMM_WEDGE_FULL_IDX ) { xParseWedgeFullInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1294 1253 if( uiIPredMode == DMM_WEDGE_FULL_D_IDX ) { xParseWedgeFullDeltaInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1295 1254 if( uiIPredMode == DMM_WEDGE_PREDDIR_IDX ) { xParseWedgePredDirInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1296 1255 if( uiIPredMode == DMM_WEDGE_PREDDIR_D_IDX ) { xParseWedgePredDirDeltaInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1256 #endif 1257 #if HHI_DMM_PRED_TEX 1297 1258 if( uiIPredMode == DMM_WEDGE_PREDTEX_D_IDX ) { xParseWedgePredTexDeltaInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1298 1259 if( uiIPredMode == DMM_CONTOUR_PREDTEX_D_IDX ) { xParseContourPredTexDeltaInfo( pcCU, uiAbsPartIdx, uiDepth ); } 1260 #endif 1299 1261 } 1300 1262 else … … 1370 1332 UInt uiSymbol; 1371 1333 1372 #if HHI_DMM_ INTRA1334 #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX 1373 1335 UInt uiFlag = 0; 1374 if ( pcCU->getSlice()->getSPS()->isDepth() && pcCU->getSlice()->getSPS()->getUseD epthModelModes() && g_uiMaxCUWidth>>uiDepth < 64 )1336 if ( pcCU->getSlice()->getSPS()->isDepth() && pcCU->getSlice()->getSPS()->getUseDMM() && g_uiMaxCUWidth>>uiDepth < 64 ) 1375 1337 { 1376 1338 m_pcTDecBinIf->decodeBin( uiFlag, m_cIntraDMMSCModel.get(0, 0, 0) ); … … 1379 1341 { 1380 1342 UInt uiDMMode; 1381 TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getTexturePic()->getPicYuvRec(); 1382 Int iRefStride = pcPicYuvRef->getStride(); 1383 Pel* piRefY; 1384 1385 TComYuv cTempYuv; 1386 UInt uiTempStride = 0; 1387 Pel* piTempY; 1388 1389 UInt uiWidth = g_uiMaxCUWidth>>uiDepth; 1390 UInt uiHeight = g_uiMaxCUHeight>>uiDepth; 1391 piRefY = pcPicYuvRef->getLumaAddr( pcCU->getAddr(), uiAbsPartIdx ); 1392 cTempYuv.create( uiWidth, uiHeight ); cTempYuv.clear(); 1393 piTempY = cTempYuv.getLumaAddr( 0, uiWidth ); 1394 uiTempStride = cTempYuv.getStride(); 1395 1396 for ( Int y = 0; y < uiHeight; y++ ) 1397 { 1398 ::memcpy(piTempY, piRefY, sizeof(Pel)*uiWidth); 1399 piTempY += uiTempStride; 1400 piRefY += iRefStride; 1401 } 1402 1403 UInt64 uiDCSAD = cTempYuv.getLumaDistDCSAD( uiWidth ); 1404 1405 if( uiDCSAD < 23 ) 1406 { 1343 1344 #if HHI_DMM_WEDGE_INTRA && HHI_DMM_PRED_TEX 1345 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1346 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; 1407 1347 if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && g_uiMaxCUWidth>>uiDepth > 4 ) 1408 1348 { 1409 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1410 if( DMM_INTRA_MODE_BITS > 1 ) { m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; } 1411 1412 if( uiDMMode > 1 ) 1413 { 1414 uiDMMode += 4; 1349 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 2; 1415 1350 } 1416 } 1417 else 1418 { 1419 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1420 } 1421 } 1422 else 1423 { 1351 #else 1424 1352 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode = uiSymbol; 1425 if( DMM_INTRA_MODE_BITS > 1 ) { m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; }1426 1353 if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && g_uiMaxCUWidth>>uiDepth > 4 ) 1427 1354 { 1428 if( DMM_INTRA_MODE_BITS > 2 ) { m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 2; }1429 1430 } 1355 m_pcTDecBinIf->decodeBin( uiSymbol, m_cIntraDMMSCModel.get(0, 0, 1) ); uiDMMode |= uiSymbol << 1; 1356 } 1357 #endif 1431 1358 uiIPredMode = g_aucAdditionalIntraModeList[uiDMMode]; 1432 1359 1360 #if HHI_DMM_WEDGE_INTRA 1433 1361 if( uiIPredMode == DMM_WEDGE_FULL_IDX ) { xParseWedgeFullInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1434 1362 if( uiIPredMode == DMM_WEDGE_FULL_D_IDX ) { xParseWedgeFullDeltaInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1435 1363 if( uiIPredMode == DMM_WEDGE_PREDDIR_IDX ) { xParseWedgePredDirInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1436 1364 if( uiIPredMode == DMM_WEDGE_PREDDIR_D_IDX ) { xParseWedgePredDirDeltaInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1365 #endif 1366 #if HHI_DMM_PRED_TEX 1437 1367 if( uiIPredMode == DMM_WEDGE_PREDTEX_D_IDX ) { xParseWedgePredTexDeltaInfo ( pcCU, uiAbsPartIdx, uiDepth ); } 1438 1368 if( uiIPredMode == DMM_CONTOUR_PREDTEX_D_IDX ) { xParseContourPredTexDeltaInfo( pcCU, uiAbsPartIdx, uiDepth ); } 1369 #endif 1439 1370 } 1440 1371 else
Note: See TracChangeset for help on using the changeset viewer.