102f5b5447de349216a40086ca6061efefb5a3025James Dong/* ------------------------------------------------------------------ 202f5b5447de349216a40086ca6061efefb5a3025James Dong * Copyright (C) 1998-2009 PacketVideo 302f5b5447de349216a40086ca6061efefb5a3025James Dong * 402f5b5447de349216a40086ca6061efefb5a3025James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 502f5b5447de349216a40086ca6061efefb5a3025James Dong * you may not use this file except in compliance with the License. 602f5b5447de349216a40086ca6061efefb5a3025James Dong * You may obtain a copy of the License at 702f5b5447de349216a40086ca6061efefb5a3025James Dong * 802f5b5447de349216a40086ca6061efefb5a3025James Dong * http://www.apache.org/licenses/LICENSE-2.0 902f5b5447de349216a40086ca6061efefb5a3025James Dong * 1002f5b5447de349216a40086ca6061efefb5a3025James Dong * Unless required by applicable law or agreed to in writing, software 1102f5b5447de349216a40086ca6061efefb5a3025James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1202f5b5447de349216a40086ca6061efefb5a3025James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 1302f5b5447de349216a40086ca6061efefb5a3025James Dong * express or implied. 1402f5b5447de349216a40086ca6061efefb5a3025James Dong * See the License for the specific language governing permissions 1502f5b5447de349216a40086ca6061efefb5a3025James Dong * and limitations under the License. 1602f5b5447de349216a40086ca6061efefb5a3025James Dong * ------------------------------------------------------------------- 1702f5b5447de349216a40086ca6061efefb5a3025James Dong */ 1802f5b5447de349216a40086ca6061efefb5a3025James Dong/* 1902f5b5447de349216a40086ca6061efefb5a3025James Dong------------------------------------------------------------------------------ 2002f5b5447de349216a40086ca6061efefb5a3025James Dong INPUT AND OUTPUT DEFINITIONS 2102f5b5447de349216a40086ca6061efefb5a3025James Dong 2202f5b5447de349216a40086ca6061efefb5a3025James Dong Inputs: 2302f5b5447de349216a40086ca6061efefb5a3025James Dong q_block = pointer to buffer of inverse quantized DCT coefficients of type 2402f5b5447de349216a40086ca6061efefb5a3025James Dong int for intra-VOP mode or buffer of residual data of type int 2502f5b5447de349216a40086ca6061efefb5a3025James Dong for inter-VOP mode 2602f5b5447de349216a40086ca6061efefb5a3025James Dong 2702f5b5447de349216a40086ca6061efefb5a3025James Dong Local Stores/Buffers/Pointers Needed: 2802f5b5447de349216a40086ca6061efefb5a3025James Dong None 2902f5b5447de349216a40086ca6061efefb5a3025James Dong 3002f5b5447de349216a40086ca6061efefb5a3025James Dong Global Stores/Buffers/Pointers Needed: 3102f5b5447de349216a40086ca6061efefb5a3025James Dong None 3202f5b5447de349216a40086ca6061efefb5a3025James Dong 3302f5b5447de349216a40086ca6061efefb5a3025James Dong Outputs: 3402f5b5447de349216a40086ca6061efefb5a3025James Dong postmode = post processing semaphore with the vertical deblocking, 3502f5b5447de349216a40086ca6061efefb5a3025James Dong horizontal deblocking, and deringing bits set up accordingly 3602f5b5447de349216a40086ca6061efefb5a3025James Dong 3702f5b5447de349216a40086ca6061efefb5a3025James Dong Pointers and Buffers Modified: 3802f5b5447de349216a40086ca6061efefb5a3025James Dong None 3902f5b5447de349216a40086ca6061efefb5a3025James Dong 4002f5b5447de349216a40086ca6061efefb5a3025James Dong Local Stores Modified: 4102f5b5447de349216a40086ca6061efefb5a3025James Dong None 4202f5b5447de349216a40086ca6061efefb5a3025James Dong 4302f5b5447de349216a40086ca6061efefb5a3025James Dong Global Stores Modified: 4402f5b5447de349216a40086ca6061efefb5a3025James Dong None 4502f5b5447de349216a40086ca6061efefb5a3025James Dong 4602f5b5447de349216a40086ca6061efefb5a3025James Dong------------------------------------------------------------------------------ 4702f5b5447de349216a40086ca6061efefb5a3025James Dong FUNCTION DESCRIPTION 4802f5b5447de349216a40086ca6061efefb5a3025James Dong 4902f5b5447de349216a40086ca6061efefb5a3025James Dong This function sets up the postmode semaphore based on the contents of the 5002f5b5447de349216a40086ca6061efefb5a3025James Dong buffer pointed to by q_block. The function starts out with the assumption 5102f5b5447de349216a40086ca6061efefb5a3025James Dong that all entries of q_block, except for the first entry (q_block[0]), are 5202f5b5447de349216a40086ca6061efefb5a3025James Dong zero. This case can induce horizontal and vertical blocking artifacts, 5302f5b5447de349216a40086ca6061efefb5a3025James Dong therefore, both horizontal and vertical deblocking bits are enabled. 5402f5b5447de349216a40086ca6061efefb5a3025James Dong 5502f5b5447de349216a40086ca6061efefb5a3025James Dong The following conditions are tested when setting up the horizontal/vertical 5602f5b5447de349216a40086ca6061efefb5a3025James Dong deblocking and deringing bits: 5702f5b5447de349216a40086ca6061efefb5a3025James Dong 1. When only the elements of the top row of the B_SIZE x B_SIZE block 5802f5b5447de349216a40086ca6061efefb5a3025James Dong (q_block[n], n = 0,..., B_SIZE-1) are non-zero, vertical blocking artifacts 5902f5b5447de349216a40086ca6061efefb5a3025James Dong may result, therefore, only the vertical deblocking bit is enabled. 6002f5b5447de349216a40086ca6061efefb5a3025James Dong Otherwise, the vertical deblocking bit is disabled. 6102f5b5447de349216a40086ca6061efefb5a3025James Dong 2. When only the elements of the far left column of the B_SIZE x B_SIZE block 6202f5b5447de349216a40086ca6061efefb5a3025James Dong (q_block[n*B_SIZE], n = 0, ..., B_SIZE-1) are non-zero, horizontal blocking 6302f5b5447de349216a40086ca6061efefb5a3025James Dong artifacts may result, therefore, only the horizontal deblocking bit is 6402f5b5447de349216a40086ca6061efefb5a3025James Dong enabled. Otherwise, the horizontal deblocking bit is disabled. 6502f5b5447de349216a40086ca6061efefb5a3025James Dong 3. If any non-zero elements exist in positions other than q_block[0], 6602f5b5447de349216a40086ca6061efefb5a3025James Dong q_block[1], or q_block[B_SIZE], the deringing bit is enabled. Otherwise, 6702f5b5447de349216a40086ca6061efefb5a3025James Dong it is disabled. 6802f5b5447de349216a40086ca6061efefb5a3025James Dong 6902f5b5447de349216a40086ca6061efefb5a3025James Dong The 3 least significant bits of postmode defines vertical or horizontal 7002f5b5447de349216a40086ca6061efefb5a3025James Dong deblocking and deringing. 7102f5b5447de349216a40086ca6061efefb5a3025James Dong 7202f5b5447de349216a40086ca6061efefb5a3025James Dong The valid values are shown below: 7302f5b5447de349216a40086ca6061efefb5a3025James Dong ------------------------------------------------------- 7402f5b5447de349216a40086ca6061efefb5a3025James Dong | Type | Enabled | Disabled | 7502f5b5447de349216a40086ca6061efefb5a3025James Dong ------------------------------------------------------- 7602f5b5447de349216a40086ca6061efefb5a3025James Dong | Vertical Deblocking (Bit #0) | 1 | 0 | 7702f5b5447de349216a40086ca6061efefb5a3025James Dong ------------------------------------------------------- 7802f5b5447de349216a40086ca6061efefb5a3025James Dong | Horizontal Deblocking (Bit #1) | 1 | 0 | 7902f5b5447de349216a40086ca6061efefb5a3025James Dong ------------------------------------------------------- 8002f5b5447de349216a40086ca6061efefb5a3025James Dong | Deringing (Bit #2) | 1 | 0 | 8102f5b5447de349216a40086ca6061efefb5a3025James Dong ------------------------------------------------------- 8202f5b5447de349216a40086ca6061efefb5a3025James Dong 8302f5b5447de349216a40086ca6061efefb5a3025James Dong*/ 8402f5b5447de349216a40086ca6061efefb5a3025James Dong 8502f5b5447de349216a40086ca6061efefb5a3025James Dong 8602f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 8702f5b5447de349216a40086ca6061efefb5a3025James Dong; INCLUDES 8802f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 8902f5b5447de349216a40086ca6061efefb5a3025James Dong#include "mp4dec_lib.h" 9002f5b5447de349216a40086ca6061efefb5a3025James Dong#include "mp4def.h" 9102f5b5447de349216a40086ca6061efefb5a3025James Dong#include "post_proc.h" 9202f5b5447de349216a40086ca6061efefb5a3025James Dong 9302f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 9402f5b5447de349216a40086ca6061efefb5a3025James Dong; MACROS 9502f5b5447de349216a40086ca6061efefb5a3025James Dong; Define module specific macros here 9602f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 9702f5b5447de349216a40086ca6061efefb5a3025James Dong 9802f5b5447de349216a40086ca6061efefb5a3025James Dong 9902f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 10002f5b5447de349216a40086ca6061efefb5a3025James Dong; DEFINES 10102f5b5447de349216a40086ca6061efefb5a3025James Dong; Include all pre-processor statements here. Include conditional 10202f5b5447de349216a40086ca6061efefb5a3025James Dong; compile variables also. 10302f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 10402f5b5447de349216a40086ca6061efefb5a3025James Dong 10502f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 10602f5b5447de349216a40086ca6061efefb5a3025James Dong; LOCAL FUNCTION DEFINITIONS 10702f5b5447de349216a40086ca6061efefb5a3025James Dong; Function Prototype declaration 10802f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 10902f5b5447de349216a40086ca6061efefb5a3025James Dong 11002f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 11102f5b5447de349216a40086ca6061efefb5a3025James Dong; LOCAL STORE/BUFFER/POINTER DEFINITIONS 11202f5b5447de349216a40086ca6061efefb5a3025James Dong; Variable declaration - defined here and used outside this module 11302f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 11402f5b5447de349216a40086ca6061efefb5a3025James Dong 11502f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 11602f5b5447de349216a40086ca6061efefb5a3025James Dong; EXTERNAL FUNCTION REFERENCES 11702f5b5447de349216a40086ca6061efefb5a3025James Dong; Declare functions defined elsewhere and referenced in this module 11802f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 11902f5b5447de349216a40086ca6061efefb5a3025James Dong 12002f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 12102f5b5447de349216a40086ca6061efefb5a3025James Dong; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 12202f5b5447de349216a40086ca6061efefb5a3025James Dong; Declare variables used in this module but defined elsewhere 12302f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 12402f5b5447de349216a40086ca6061efefb5a3025James Dong#ifdef PV_POSTPROC_ON 12502f5b5447de349216a40086ca6061efefb5a3025James Dong/*---------------------------------------------------------------------------- 12602f5b5447de349216a40086ca6061efefb5a3025James Dong; FUNCTION CODE 12702f5b5447de349216a40086ca6061efefb5a3025James Dong----------------------------------------------------------------------------*/ 12802f5b5447de349216a40086ca6061efefb5a3025James Dongint PostProcSemaphore( 12902f5b5447de349216a40086ca6061efefb5a3025James Dong int16 *q_block) 13002f5b5447de349216a40086ca6061efefb5a3025James Dong{ 13102f5b5447de349216a40086ca6061efefb5a3025James Dong /*---------------------------------------------------------------------------- 13202f5b5447de349216a40086ca6061efefb5a3025James Dong ; Define all local variables 13302f5b5447de349216a40086ca6061efefb5a3025James Dong ----------------------------------------------------------------------------*/ 13402f5b5447de349216a40086ca6061efefb5a3025James Dong int i, j; 13502f5b5447de349216a40086ca6061efefb5a3025James Dong 13602f5b5447de349216a40086ca6061efefb5a3025James Dong /* Set default value to vertical and horizontal deblocking enabled */ 13702f5b5447de349216a40086ca6061efefb5a3025James Dong /* Initial assumption is that only q_block[0] element is non-zero, */ 13802f5b5447de349216a40086ca6061efefb5a3025James Dong /* therefore, vertical and horizontal deblocking bits are set to 1 */ 13902f5b5447de349216a40086ca6061efefb5a3025James Dong int postmode = 0x3; 14002f5b5447de349216a40086ca6061efefb5a3025James Dong 14102f5b5447de349216a40086ca6061efefb5a3025James Dong /*---------------------------------------------------------------------------- 14202f5b5447de349216a40086ca6061efefb5a3025James Dong ; Function body here 14302f5b5447de349216a40086ca6061efefb5a3025James Dong ----------------------------------------------------------------------------*/ 14402f5b5447de349216a40086ca6061efefb5a3025James Dong /* Vertical deblocking bit is enabled when only the entire top row of */ 14502f5b5447de349216a40086ca6061efefb5a3025James Dong /* the B_SIZE x B_SIZE block, i.e., q_block[n], n = 0,..., B_SIZE-1, */ 14602f5b5447de349216a40086ca6061efefb5a3025James Dong /* are non-zero. Since initial assumption is that all elements, except */ 14702f5b5447de349216a40086ca6061efefb5a3025James Dong /* q_block[0], is zero, we need to check the remaining elements in the */ 14802f5b5447de349216a40086ca6061efefb5a3025James Dong /* top row to determine if all or some are non-zero. */ 14902f5b5447de349216a40086ca6061efefb5a3025James Dong if (q_block[1] != 0) 15002f5b5447de349216a40086ca6061efefb5a3025James Dong { 15102f5b5447de349216a40086ca6061efefb5a3025James Dong /* At this point, q_block[0] and q_block[1] are non-zero, while */ 15202f5b5447de349216a40086ca6061efefb5a3025James Dong /* q_block[n], n = 2,..., B_SIZE-1, are zero. Therefore, we */ 15302f5b5447de349216a40086ca6061efefb5a3025James Dong /* need to disable vertical deblocking */ 15402f5b5447de349216a40086ca6061efefb5a3025James Dong postmode &= 0xE; 15502f5b5447de349216a40086ca6061efefb5a3025James Dong } 15602f5b5447de349216a40086ca6061efefb5a3025James Dong 15702f5b5447de349216a40086ca6061efefb5a3025James Dong for (i = 2; i < B_SIZE; i++) 15802f5b5447de349216a40086ca6061efefb5a3025James Dong { 15902f5b5447de349216a40086ca6061efefb5a3025James Dong if (q_block[i]) 16002f5b5447de349216a40086ca6061efefb5a3025James Dong { 16102f5b5447de349216a40086ca6061efefb5a3025James Dong /* Check if q_block[n], n = 2,..., B_SIZE-1, are non-zero.*/ 16202f5b5447de349216a40086ca6061efefb5a3025James Dong /* If any of them turn out to be non-zero, we need to */ 16302f5b5447de349216a40086ca6061efefb5a3025James Dong /* disable vertical deblocking. */ 16402f5b5447de349216a40086ca6061efefb5a3025James Dong postmode &= 0xE; 16502f5b5447de349216a40086ca6061efefb5a3025James Dong 16602f5b5447de349216a40086ca6061efefb5a3025James Dong /* Deringing is enabled if any nonzero elements exist in */ 16702f5b5447de349216a40086ca6061efefb5a3025James Dong /* positions other than q_block[0], q_block[1] or */ 16802f5b5447de349216a40086ca6061efefb5a3025James Dong /* q_block[B_SIZE]. */ 16902f5b5447de349216a40086ca6061efefb5a3025James Dong postmode |= 0x4; 17002f5b5447de349216a40086ca6061efefb5a3025James Dong 17102f5b5447de349216a40086ca6061efefb5a3025James Dong break; 17202f5b5447de349216a40086ca6061efefb5a3025James Dong } 17302f5b5447de349216a40086ca6061efefb5a3025James Dong } 17402f5b5447de349216a40086ca6061efefb5a3025James Dong 17502f5b5447de349216a40086ca6061efefb5a3025James Dong /* Horizontal deblocking bit is enabled when only the entire far */ 17602f5b5447de349216a40086ca6061efefb5a3025James Dong /* left column, i.e., q_block[n*B_SIZE], n = 0, ..., B_SIZE-1, */ 17702f5b5447de349216a40086ca6061efefb5a3025James Dong /* are non-zero. Since initial assumption is that all elements, */ 17802f5b5447de349216a40086ca6061efefb5a3025James Dong /* except q_block[0], is zero, we need to check the remaining */ 17902f5b5447de349216a40086ca6061efefb5a3025James Dong /* elements in the far left column to determine if all or some */ 18002f5b5447de349216a40086ca6061efefb5a3025James Dong /* are non-zero. */ 18102f5b5447de349216a40086ca6061efefb5a3025James Dong if (q_block[B_SIZE]) 18202f5b5447de349216a40086ca6061efefb5a3025James Dong { 18302f5b5447de349216a40086ca6061efefb5a3025James Dong /* At this point, only q_block[0] and q_block[B_SIZE] are non-zero, */ 18402f5b5447de349216a40086ca6061efefb5a3025James Dong /* while q_block[n*B_SIZE], n = 2, 3,..., B_SIZE-1, are zero. */ 18502f5b5447de349216a40086ca6061efefb5a3025James Dong /* Therefore, we need to disable horizontal deblocking. */ 18602f5b5447de349216a40086ca6061efefb5a3025James Dong postmode &= 0xD; 18702f5b5447de349216a40086ca6061efefb5a3025James Dong } 18802f5b5447de349216a40086ca6061efefb5a3025James Dong 18902f5b5447de349216a40086ca6061efefb5a3025James Dong for (i = 16; i < NCOEFF_BLOCK; i += B_SIZE) 19002f5b5447de349216a40086ca6061efefb5a3025James Dong { 19102f5b5447de349216a40086ca6061efefb5a3025James Dong if (q_block[i]) 19202f5b5447de349216a40086ca6061efefb5a3025James Dong { 19302f5b5447de349216a40086ca6061efefb5a3025James Dong /* Check if q_block[n], n = 2*B_SIZE,...,(B_SIZE-1)*B_SIZE, */ 19402f5b5447de349216a40086ca6061efefb5a3025James Dong /* are non-zero. If any of them turn out to be non-zero, */ 19502f5b5447de349216a40086ca6061efefb5a3025James Dong /* we need to disable horizontal deblocking. */ 19602f5b5447de349216a40086ca6061efefb5a3025James Dong postmode &= 0xD; 19702f5b5447de349216a40086ca6061efefb5a3025James Dong 19802f5b5447de349216a40086ca6061efefb5a3025James Dong /* Deringing is enabled if any nonzero elements exist in */ 19902f5b5447de349216a40086ca6061efefb5a3025James Dong /* positions other than q_block[0], q_block[1] or */ 20002f5b5447de349216a40086ca6061efefb5a3025James Dong /* q_block[B_SIZE]. */ 20102f5b5447de349216a40086ca6061efefb5a3025James Dong postmode |= 0x4; 20202f5b5447de349216a40086ca6061efefb5a3025James Dong 20302f5b5447de349216a40086ca6061efefb5a3025James Dong break; 20402f5b5447de349216a40086ca6061efefb5a3025James Dong } 20502f5b5447de349216a40086ca6061efefb5a3025James Dong } 20602f5b5447de349216a40086ca6061efefb5a3025James Dong 20702f5b5447de349216a40086ca6061efefb5a3025James Dong /* At this point, only the first row and far left column elements */ 20802f5b5447de349216a40086ca6061efefb5a3025James Dong /* have been tested. If deringing bit is still not set at this */ 20902f5b5447de349216a40086ca6061efefb5a3025James Dong /* point, check the rest of q_block to determine if the elements */ 21002f5b5447de349216a40086ca6061efefb5a3025James Dong /* are non-zero. If all elements, besides q_block[0], q_block[1], */ 21102f5b5447de349216a40086ca6061efefb5a3025James Dong /* or q_block[B_SIZE] are non-zero, deringing bit must be set */ 21202f5b5447de349216a40086ca6061efefb5a3025James Dong if ((postmode & 0x4) == 0) 21302f5b5447de349216a40086ca6061efefb5a3025James Dong { 21402f5b5447de349216a40086ca6061efefb5a3025James Dong for (i = 1; i < B_SIZE; i++) 21502f5b5447de349216a40086ca6061efefb5a3025James Dong { 21602f5b5447de349216a40086ca6061efefb5a3025James Dong for (j = 1; j < B_SIZE; j++) 21702f5b5447de349216a40086ca6061efefb5a3025James Dong { 21802f5b5447de349216a40086ca6061efefb5a3025James Dong if (q_block[(i<<3)+j]) 21902f5b5447de349216a40086ca6061efefb5a3025James Dong { 22002f5b5447de349216a40086ca6061efefb5a3025James Dong /* At this point, q_block[0] and another q_block */ 22102f5b5447de349216a40086ca6061efefb5a3025James Dong /* element are non-zero, therefore, we need to */ 22202f5b5447de349216a40086ca6061efefb5a3025James Dong /* disable vertical and horizontal deblocking */ 22302f5b5447de349216a40086ca6061efefb5a3025James Dong postmode &= 0xC; 22402f5b5447de349216a40086ca6061efefb5a3025James Dong 22502f5b5447de349216a40086ca6061efefb5a3025James Dong /* Deringing is enabled if any nonzero elements exist in */ 22602f5b5447de349216a40086ca6061efefb5a3025James Dong /* positions other than q_block[0], q_block[1] or */ 22702f5b5447de349216a40086ca6061efefb5a3025James Dong /* q_block[B_SIZE]. */ 22802f5b5447de349216a40086ca6061efefb5a3025James Dong postmode |= 0x4; 22902f5b5447de349216a40086ca6061efefb5a3025James Dong 23002f5b5447de349216a40086ca6061efefb5a3025James Dong /* Set outer FOR loop count to B_SIZE to get out of */ 23102f5b5447de349216a40086ca6061efefb5a3025James Dong /* outer FOR loop */ 23202f5b5447de349216a40086ca6061efefb5a3025James Dong i = B_SIZE; 23302f5b5447de349216a40086ca6061efefb5a3025James Dong 23402f5b5447de349216a40086ca6061efefb5a3025James Dong /* Get out of inner FOR loop */ 23502f5b5447de349216a40086ca6061efefb5a3025James Dong break; 23602f5b5447de349216a40086ca6061efefb5a3025James Dong } 23702f5b5447de349216a40086ca6061efefb5a3025James Dong } 23802f5b5447de349216a40086ca6061efefb5a3025James Dong } 23902f5b5447de349216a40086ca6061efefb5a3025James Dong } 24002f5b5447de349216a40086ca6061efefb5a3025James Dong 24102f5b5447de349216a40086ca6061efefb5a3025James Dong /*---------------------------------------------------------------------------- 24202f5b5447de349216a40086ca6061efefb5a3025James Dong ; Return nothing or data or data pointer 24302f5b5447de349216a40086ca6061efefb5a3025James Dong ----------------------------------------------------------------------------*/ 24402f5b5447de349216a40086ca6061efefb5a3025James Dong return (postmode); 24502f5b5447de349216a40086ca6061efefb5a3025James Dong} 24602f5b5447de349216a40086ca6061efefb5a3025James Dong 24702f5b5447de349216a40086ca6061efefb5a3025James Dong#endif 248