1b815c7f3Sopenharmony_ci/* 2b815c7f3Sopenharmony_ci * Copyright (c) 2011 Apple Inc. All rights reserved. 3b815c7f3Sopenharmony_ci * 4b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_START@ 5b815c7f3Sopenharmony_ci * 6b815c7f3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License") ; 7b815c7f3Sopenharmony_ci * you may not use this file except in compliance with the License. 8b815c7f3Sopenharmony_ci * You may obtain a copy of the License at 9b815c7f3Sopenharmony_ci * 10b815c7f3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 11b815c7f3Sopenharmony_ci * 12b815c7f3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 13b815c7f3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 14b815c7f3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15b815c7f3Sopenharmony_ci * See the License for the specific language governing permissions and 16b815c7f3Sopenharmony_ci * limitations under the License. 17b815c7f3Sopenharmony_ci * 18b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_END@ 19b815c7f3Sopenharmony_ci */ 20b815c7f3Sopenharmony_ci 21b815c7f3Sopenharmony_ci/* 22b815c7f3Sopenharmony_ci File: ag_dec.c 23b815c7f3Sopenharmony_ci 24b815c7f3Sopenharmony_ci Contains: Adaptive Golomb decode routines. 25b815c7f3Sopenharmony_ci 26b815c7f3Sopenharmony_ci Copyright: (c) 2001-2011 Apple, Inc. 27b815c7f3Sopenharmony_ci*/ 28b815c7f3Sopenharmony_ci 29b815c7f3Sopenharmony_ci#include <math.h> 30b815c7f3Sopenharmony_ci#include <stdio.h> 31b815c7f3Sopenharmony_ci#include <stdlib.h> 32b815c7f3Sopenharmony_ci#include <string.h> 33b815c7f3Sopenharmony_ci 34b815c7f3Sopenharmony_ci#include "aglib.h" 35b815c7f3Sopenharmony_ci#include "ALACBitUtilities.h" 36b815c7f3Sopenharmony_ci#include "ALACAudioTypes.h" 37b815c7f3Sopenharmony_ci 38b815c7f3Sopenharmony_ci#define CODE_TO_LONG_MAXBITS 32 39b815c7f3Sopenharmony_ci#define N_MAX_MEAN_CLAMP 0xffff 40b815c7f3Sopenharmony_ci#define N_MEAN_CLAMP_VAL 0xffff 41b815c7f3Sopenharmony_ci#define REPORT_VAL 40 42b815c7f3Sopenharmony_ci 43b815c7f3Sopenharmony_ci#if __GNUC__ 44b815c7f3Sopenharmony_ci#define ALWAYS_INLINE __attribute__ ((always_inline)) 45b815c7f3Sopenharmony_ci#elif defined _MSC_VER 46b815c7f3Sopenharmony_ci#define ALWAYS_INLINE __forceinline 47b815c7f3Sopenharmony_ci#else 48b815c7f3Sopenharmony_ci#define ALWAYS_INLINE 49b815c7f3Sopenharmony_ci#endif 50b815c7f3Sopenharmony_ci 51b815c7f3Sopenharmony_ci/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this 52b815c7f3Sopenharmony_ci to help the compiler out. In many cases this required manual inlining or a macro. Sorry 53b815c7f3Sopenharmony_ci if it is ugly but the performance gains are well worth it. 54b815c7f3Sopenharmony_ci - WSK 5/19/04 55b815c7f3Sopenharmony_ci*/ 56b815c7f3Sopenharmony_ci 57b815c7f3Sopenharmony_civoid set_standard_ag_params (AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth) 58b815c7f3Sopenharmony_ci{ 59b815c7f3Sopenharmony_ci /* Use 60b815c7f3Sopenharmony_ci fullwidth = sectorwidth = numOfSamples, for analog 1-dimensional type-short data, 61b815c7f3Sopenharmony_ci but use 62b815c7f3Sopenharmony_ci fullwidth = full image width, sectorwidth = sector (patch) width 63b815c7f3Sopenharmony_ci for such as image (2-dim.) data. 64b815c7f3Sopenharmony_ci */ 65b815c7f3Sopenharmony_ci set_ag_params (params, MB0, PB0, KB0, fullwidth, sectorwidth, MAX_RUN_DEFAULT) ; 66b815c7f3Sopenharmony_ci} 67b815c7f3Sopenharmony_ci 68b815c7f3Sopenharmony_civoid set_ag_params (AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun) 69b815c7f3Sopenharmony_ci{ 70b815c7f3Sopenharmony_ci params->mb = params->mb0 = m ; 71b815c7f3Sopenharmony_ci params->pb = p ; 72b815c7f3Sopenharmony_ci params->kb = k ; 73b815c7f3Sopenharmony_ci params->wb = (1u << params->kb) - 1 ; 74b815c7f3Sopenharmony_ci params->qb = QB-params->pb ; 75b815c7f3Sopenharmony_ci params->fw = f ; 76b815c7f3Sopenharmony_ci params->sw = s ; 77b815c7f3Sopenharmony_ci params->maxrun = maxrun ; 78b815c7f3Sopenharmony_ci} 79b815c7f3Sopenharmony_ci 80b815c7f3Sopenharmony_ci#if PRAGMA_MARK 81b815c7f3Sopenharmony_ci#pragma mark - 82b815c7f3Sopenharmony_ci#endif 83b815c7f3Sopenharmony_ci 84b815c7f3Sopenharmony_ci 85b815c7f3Sopenharmony_ci// note: implementing this with some kind of "count leading zeros" assembly is a big performance win 86b815c7f3Sopenharmony_cistatic inline int32_t lead (int32_t m) 87b815c7f3Sopenharmony_ci{ 88b815c7f3Sopenharmony_ci long j ; 89b815c7f3Sopenharmony_ci unsigned long c = (1ul << 31) ; 90b815c7f3Sopenharmony_ci 91b815c7f3Sopenharmony_ci for (j = 0 ; j < 32 ; j++) 92b815c7f3Sopenharmony_ci { 93b815c7f3Sopenharmony_ci if ((c & m) != 0) 94b815c7f3Sopenharmony_ci break ; 95b815c7f3Sopenharmony_ci c >>= 1 ; 96b815c7f3Sopenharmony_ci } 97b815c7f3Sopenharmony_ci return j ; 98b815c7f3Sopenharmony_ci} 99b815c7f3Sopenharmony_ci 100b815c7f3Sopenharmony_ci#define arithmin(a, b) ((a) < (b) ? (a) : (b)) 101b815c7f3Sopenharmony_ci 102b815c7f3Sopenharmony_cistatic inline int32_t ALWAYS_INLINE lg3a (int32_t x) 103b815c7f3Sopenharmony_ci{ 104b815c7f3Sopenharmony_ci int32_t result ; 105b815c7f3Sopenharmony_ci 106b815c7f3Sopenharmony_ci x += 3 ; 107b815c7f3Sopenharmony_ci result = lead (x) ; 108b815c7f3Sopenharmony_ci 109b815c7f3Sopenharmony_ci return 31 - result ; 110b815c7f3Sopenharmony_ci} 111b815c7f3Sopenharmony_ci 112b815c7f3Sopenharmony_cistatic inline uint32_t ALWAYS_INLINE read32bit (uint8_t * buffer) 113b815c7f3Sopenharmony_ci{ 114b815c7f3Sopenharmony_ci // embedded CPUs typically can't read unaligned 32-bit words so just read the bytes 115b815c7f3Sopenharmony_ci uint32_t value ; 116b815c7f3Sopenharmony_ci 117b815c7f3Sopenharmony_ci value = ((uint32_t) buffer [0] << 24) | ((uint32_t) buffer [1] << 16) | 118b815c7f3Sopenharmony_ci ((uint32_t) buffer [2] << 8) | (uint32_t) buffer [3] ; 119b815c7f3Sopenharmony_ci return value ; 120b815c7f3Sopenharmony_ci 121b815c7f3Sopenharmony_ci} 122b815c7f3Sopenharmony_ci 123b815c7f3Sopenharmony_ci#if PRAGMA_MARK 124b815c7f3Sopenharmony_ci#pragma mark - 125b815c7f3Sopenharmony_ci#endif 126b815c7f3Sopenharmony_ci 127b815c7f3Sopenharmony_ci#define get_next_fromlong(inlong, suff) ((inlong) >> (32 - (suff))) 128b815c7f3Sopenharmony_ci 129b815c7f3Sopenharmony_ci 130b815c7f3Sopenharmony_cistatic inline uint32_t ALWAYS_INLINE 131b815c7f3Sopenharmony_cigetstreambits (uint8_t *in, int32_t bitoffset, int32_t numbits) 132b815c7f3Sopenharmony_ci{ 133b815c7f3Sopenharmony_ci uint32_t load1, load2 ; 134b815c7f3Sopenharmony_ci uint32_t byteoffset = bitoffset / 8 ; 135b815c7f3Sopenharmony_ci uint32_t result ; 136b815c7f3Sopenharmony_ci 137b815c7f3Sopenharmony_ci //Assert (numbits <= 32) ; 138b815c7f3Sopenharmony_ci 139b815c7f3Sopenharmony_ci load1 = read32bit (in + byteoffset) ; 140b815c7f3Sopenharmony_ci 141b815c7f3Sopenharmony_ci if ((numbits + (bitoffset & 0x7)) > 32) 142b815c7f3Sopenharmony_ci { 143b815c7f3Sopenharmony_ci int32_t load2shift ; 144b815c7f3Sopenharmony_ci 145b815c7f3Sopenharmony_ci result = load1 << (bitoffset & 0x7) ; 146b815c7f3Sopenharmony_ci load2 = (uint32_t) in [byteoffset + 4] ; 147b815c7f3Sopenharmony_ci load2shift = (8 - (numbits + (bitoffset & 0x7) - 32)) ; 148b815c7f3Sopenharmony_ci load2 >>= load2shift ; 149b815c7f3Sopenharmony_ci result >>= (32 - numbits) ; 150b815c7f3Sopenharmony_ci result |= load2 ; 151b815c7f3Sopenharmony_ci } 152b815c7f3Sopenharmony_ci else 153b815c7f3Sopenharmony_ci { 154b815c7f3Sopenharmony_ci result = load1 >> (32 - numbits - (bitoffset & 7)) ; 155b815c7f3Sopenharmony_ci } 156b815c7f3Sopenharmony_ci 157b815c7f3Sopenharmony_ci // a shift of >= "the number of bits in the type of the value being shifted" results in undefined 158b815c7f3Sopenharmony_ci // behavior so don't try to shift by 32 159b815c7f3Sopenharmony_ci if (numbits != (sizeof (result) * 8)) 160b815c7f3Sopenharmony_ci result &= ~ (0xfffffffful << numbits) ; 161b815c7f3Sopenharmony_ci 162b815c7f3Sopenharmony_ci return result ; 163b815c7f3Sopenharmony_ci} 164b815c7f3Sopenharmony_ci 165b815c7f3Sopenharmony_ci 166b815c7f3Sopenharmony_cistatic inline int32_t dyn_get (unsigned char *in, uint32_t *bitPos, uint32_t m, uint32_t k) 167b815c7f3Sopenharmony_ci{ 168b815c7f3Sopenharmony_ci uint32_t tempbits = *bitPos ; 169b815c7f3Sopenharmony_ci uint32_t result ; 170b815c7f3Sopenharmony_ci uint32_t pre = 0, v ; 171b815c7f3Sopenharmony_ci uint32_t streamlong ; 172b815c7f3Sopenharmony_ci 173b815c7f3Sopenharmony_ci streamlong = read32bit (in + (tempbits >> 3)) ; 174b815c7f3Sopenharmony_ci streamlong <<= (tempbits & 7) ; 175b815c7f3Sopenharmony_ci 176b815c7f3Sopenharmony_ci /* find the number of bits in the prefix */ 177b815c7f3Sopenharmony_ci { 178b815c7f3Sopenharmony_ci uint32_t notI = ~streamlong ; 179b815c7f3Sopenharmony_ci pre = lead (notI) ; 180b815c7f3Sopenharmony_ci } 181b815c7f3Sopenharmony_ci 182b815c7f3Sopenharmony_ci if (pre >= MAX_PREFIX_16) 183b815c7f3Sopenharmony_ci { 184b815c7f3Sopenharmony_ci pre = MAX_PREFIX_16 ; 185b815c7f3Sopenharmony_ci tempbits += pre ; 186b815c7f3Sopenharmony_ci streamlong <<= pre ; 187b815c7f3Sopenharmony_ci result = get_next_fromlong (streamlong, MAX_DATATYPE_BITS_16) ; 188b815c7f3Sopenharmony_ci tempbits += MAX_DATATYPE_BITS_16 ; 189b815c7f3Sopenharmony_ci 190b815c7f3Sopenharmony_ci } 191b815c7f3Sopenharmony_ci else 192b815c7f3Sopenharmony_ci { 193b815c7f3Sopenharmony_ci // all of the bits must fit within the long we have loaded 194b815c7f3Sopenharmony_ci //Assert (pre+1+k <= 32) ; 195b815c7f3Sopenharmony_ci 196b815c7f3Sopenharmony_ci tempbits += pre ; 197b815c7f3Sopenharmony_ci tempbits += 1 ; 198b815c7f3Sopenharmony_ci streamlong <<= pre + 1 ; 199b815c7f3Sopenharmony_ci v = get_next_fromlong (streamlong, k) ; 200b815c7f3Sopenharmony_ci tempbits += k ; 201b815c7f3Sopenharmony_ci 202b815c7f3Sopenharmony_ci result = pre*m + v-1 ; 203b815c7f3Sopenharmony_ci 204b815c7f3Sopenharmony_ci if (v < 2) 205b815c7f3Sopenharmony_ci { 206b815c7f3Sopenharmony_ci result -= (v-1) ; 207b815c7f3Sopenharmony_ci tempbits -= 1 ; 208b815c7f3Sopenharmony_ci } 209b815c7f3Sopenharmony_ci } 210b815c7f3Sopenharmony_ci 211b815c7f3Sopenharmony_ci *bitPos = tempbits ; 212b815c7f3Sopenharmony_ci return result ; 213b815c7f3Sopenharmony_ci} 214b815c7f3Sopenharmony_ci 215b815c7f3Sopenharmony_ci 216b815c7f3Sopenharmony_cistatic inline int32_t dyn_get_32bit (uint8_t * in, uint32_t * bitPos, int32_t m, int32_t k, int32_t maxbits) 217b815c7f3Sopenharmony_ci{ 218b815c7f3Sopenharmony_ci uint32_t tempbits = *bitPos ; 219b815c7f3Sopenharmony_ci uint32_t v ; 220b815c7f3Sopenharmony_ci uint32_t streamlong ; 221b815c7f3Sopenharmony_ci uint32_t result ; 222b815c7f3Sopenharmony_ci 223b815c7f3Sopenharmony_ci streamlong = read32bit (in + (tempbits >> 3)) ; 224b815c7f3Sopenharmony_ci streamlong <<= (tempbits & 7) ; 225b815c7f3Sopenharmony_ci 226b815c7f3Sopenharmony_ci /* find the number of bits in the prefix */ 227b815c7f3Sopenharmony_ci { 228b815c7f3Sopenharmony_ci uint32_t notI = ~streamlong ; 229b815c7f3Sopenharmony_ci result = lead (notI) ; 230b815c7f3Sopenharmony_ci } 231b815c7f3Sopenharmony_ci 232b815c7f3Sopenharmony_ci if (result >= MAX_PREFIX_32) 233b815c7f3Sopenharmony_ci { 234b815c7f3Sopenharmony_ci result = getstreambits (in, tempbits+MAX_PREFIX_32, maxbits) ; 235b815c7f3Sopenharmony_ci tempbits += MAX_PREFIX_32 + maxbits ; 236b815c7f3Sopenharmony_ci } 237b815c7f3Sopenharmony_ci else 238b815c7f3Sopenharmony_ci { 239b815c7f3Sopenharmony_ci /* all of the bits must fit within the long we have loaded*/ 240b815c7f3Sopenharmony_ci //Assert (k<=14) ; 241b815c7f3Sopenharmony_ci //Assert (result<MAX_PREFIX_32) ; 242b815c7f3Sopenharmony_ci //Assert (result+1+k <= 32) ; 243b815c7f3Sopenharmony_ci 244b815c7f3Sopenharmony_ci tempbits += result ; 245b815c7f3Sopenharmony_ci tempbits += 1 ; 246b815c7f3Sopenharmony_ci 247b815c7f3Sopenharmony_ci if (k != 1) 248b815c7f3Sopenharmony_ci { 249b815c7f3Sopenharmony_ci streamlong <<= result + 1 ; 250b815c7f3Sopenharmony_ci v = get_next_fromlong (streamlong, k) ; 251b815c7f3Sopenharmony_ci tempbits += k ; 252b815c7f3Sopenharmony_ci tempbits -= 1 ; 253b815c7f3Sopenharmony_ci result = result*m ; 254b815c7f3Sopenharmony_ci 255b815c7f3Sopenharmony_ci if (v >= 2) 256b815c7f3Sopenharmony_ci { 257b815c7f3Sopenharmony_ci result += (v-1) ; 258b815c7f3Sopenharmony_ci tempbits += 1 ; 259b815c7f3Sopenharmony_ci } 260b815c7f3Sopenharmony_ci } 261b815c7f3Sopenharmony_ci } 262b815c7f3Sopenharmony_ci 263b815c7f3Sopenharmony_ci *bitPos = tempbits ; 264b815c7f3Sopenharmony_ci 265b815c7f3Sopenharmony_ci return result ; 266b815c7f3Sopenharmony_ci} 267b815c7f3Sopenharmony_ci 268b815c7f3Sopenharmony_ciint32_t dyn_decomp (AGParamRecPtr params, BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits) 269b815c7f3Sopenharmony_ci{ 270b815c7f3Sopenharmony_ci uint8_t *in ; 271b815c7f3Sopenharmony_ci int32_t *outPtr = pc ; 272b815c7f3Sopenharmony_ci uint32_t bitPos, startPos, maxPos ; 273b815c7f3Sopenharmony_ci uint32_t j, m, k, n, c, mz ; 274b815c7f3Sopenharmony_ci int32_t del, zmode ; 275b815c7f3Sopenharmony_ci uint32_t mb ; 276b815c7f3Sopenharmony_ci uint32_t pb_local = params->pb ; 277b815c7f3Sopenharmony_ci uint32_t kb_local = params->kb ; 278b815c7f3Sopenharmony_ci uint32_t wb_local = params->wb ; 279b815c7f3Sopenharmony_ci int32_t status ; 280b815c7f3Sopenharmony_ci 281b815c7f3Sopenharmony_ci RequireAction ((bitstream != NULL) && (pc != NULL) && (outNumBits != NULL), return kALAC_ParamError ;) ; 282b815c7f3Sopenharmony_ci *outNumBits = 0 ; 283b815c7f3Sopenharmony_ci 284b815c7f3Sopenharmony_ci in = bitstream->cur ; 285b815c7f3Sopenharmony_ci startPos = bitstream->bitIndex ; 286b815c7f3Sopenharmony_ci maxPos = bitstream->byteSize * 8 ; 287b815c7f3Sopenharmony_ci bitPos = startPos ; 288b815c7f3Sopenharmony_ci 289b815c7f3Sopenharmony_ci mb = params->mb0 ; 290b815c7f3Sopenharmony_ci zmode = 0 ; 291b815c7f3Sopenharmony_ci 292b815c7f3Sopenharmony_ci c = 0 ; 293b815c7f3Sopenharmony_ci status = ALAC_noErr ; 294b815c7f3Sopenharmony_ci 295b815c7f3Sopenharmony_ci while (c < (uint32_t) numSamples) 296b815c7f3Sopenharmony_ci { 297b815c7f3Sopenharmony_ci // bail if we've run off the end of the buffer 298b815c7f3Sopenharmony_ci RequireAction (bitPos < maxPos, status = kALAC_ParamError ; goto Exit ;) ; 299b815c7f3Sopenharmony_ci 300b815c7f3Sopenharmony_ci m = (mb) >> QBSHIFT ; 301b815c7f3Sopenharmony_ci k = lg3a (m) ; 302b815c7f3Sopenharmony_ci 303b815c7f3Sopenharmony_ci k = arithmin (k, kb_local) ; 304b815c7f3Sopenharmony_ci m = (1 << k) - 1 ; 305b815c7f3Sopenharmony_ci 306b815c7f3Sopenharmony_ci n = dyn_get_32bit (in, &bitPos, m, k, maxSize) ; 307b815c7f3Sopenharmony_ci 308b815c7f3Sopenharmony_ci // least significant bit is sign bit 309b815c7f3Sopenharmony_ci { 310b815c7f3Sopenharmony_ci uint32_t ndecode = n + zmode ; 311b815c7f3Sopenharmony_ci int32_t multiplier = - (int) (ndecode & 1) ; 312b815c7f3Sopenharmony_ci 313b815c7f3Sopenharmony_ci multiplier |= 1 ; 314b815c7f3Sopenharmony_ci del = ((ndecode+1) >> 1) * (multiplier) ; 315b815c7f3Sopenharmony_ci } 316b815c7f3Sopenharmony_ci 317b815c7f3Sopenharmony_ci *outPtr++ = del ; 318b815c7f3Sopenharmony_ci 319b815c7f3Sopenharmony_ci c++ ; 320b815c7f3Sopenharmony_ci 321b815c7f3Sopenharmony_ci mb = pb_local * (n + zmode) + mb - ((pb_local * mb) >> QBSHIFT) ; 322b815c7f3Sopenharmony_ci 323b815c7f3Sopenharmony_ci // update mean tracking 324b815c7f3Sopenharmony_ci if (n > N_MAX_MEAN_CLAMP) 325b815c7f3Sopenharmony_ci mb = N_MEAN_CLAMP_VAL ; 326b815c7f3Sopenharmony_ci 327b815c7f3Sopenharmony_ci zmode = 0 ; 328b815c7f3Sopenharmony_ci 329b815c7f3Sopenharmony_ci if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples)) 330b815c7f3Sopenharmony_ci { 331b815c7f3Sopenharmony_ci zmode = 1 ; 332b815c7f3Sopenharmony_ci k = lead (mb) - BITOFF + ((mb + MOFF) >> MDENSHIFT) ; 333b815c7f3Sopenharmony_ci mz = ((1 << k) - 1) & wb_local ; 334b815c7f3Sopenharmony_ci 335b815c7f3Sopenharmony_ci n = dyn_get (in, &bitPos, mz, k) ; 336b815c7f3Sopenharmony_ci 337b815c7f3Sopenharmony_ci RequireAction (c+n <= (uint32_t) numSamples, status = kALAC_ParamError ; goto Exit ;) ; 338b815c7f3Sopenharmony_ci 339b815c7f3Sopenharmony_ci for (j = 0 ; j < n ; j++) 340b815c7f3Sopenharmony_ci { 341b815c7f3Sopenharmony_ci *outPtr++ = 0 ; 342b815c7f3Sopenharmony_ci ++c ; 343b815c7f3Sopenharmony_ci } 344b815c7f3Sopenharmony_ci 345b815c7f3Sopenharmony_ci if (n >= 65535) 346b815c7f3Sopenharmony_ci zmode = 0 ; 347b815c7f3Sopenharmony_ci 348b815c7f3Sopenharmony_ci mb = 0 ; 349b815c7f3Sopenharmony_ci } 350b815c7f3Sopenharmony_ci } 351b815c7f3Sopenharmony_ci 352b815c7f3Sopenharmony_ciExit: 353b815c7f3Sopenharmony_ci *outNumBits = (bitPos - startPos) ; 354b815c7f3Sopenharmony_ci BitBufferAdvance (bitstream, *outNumBits) ; 355b815c7f3Sopenharmony_ci RequireAction (bitstream->cur <= bitstream->end, status = kALAC_ParamError ;) ; 356b815c7f3Sopenharmony_ci 357b815c7f3Sopenharmony_ci return status ; 358b815c7f3Sopenharmony_ci} 359