1b815c7f3Sopenharmony_ci/* 2b815c7f3Sopenharmony_ci** Copyright (C) 1999-2019 Erik de Castro Lopo <erikd@mega-nerd.com> 3b815c7f3Sopenharmony_ci** 4b815c7f3Sopenharmony_ci** This program is free software; you can redistribute it and/or modify 5b815c7f3Sopenharmony_ci** it under the terms of the GNU Lesser General Public License as published by 6b815c7f3Sopenharmony_ci** the Free Software Foundation; either version 2.1 of the License, or 7b815c7f3Sopenharmony_ci** (at your option) any later version. 8b815c7f3Sopenharmony_ci** 9b815c7f3Sopenharmony_ci** This program is distributed in the hope that it will be useful, 10b815c7f3Sopenharmony_ci** but WITHOUT ANY WARRANTY; without even the implied warranty of 11b815c7f3Sopenharmony_ci** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12b815c7f3Sopenharmony_ci** GNU Lesser General Public License for more details. 13b815c7f3Sopenharmony_ci** 14b815c7f3Sopenharmony_ci** You should have received a copy of the GNU Lesser General Public License 15b815c7f3Sopenharmony_ci** along with this program; if not, write to the Free Software 16b815c7f3Sopenharmony_ci** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17b815c7f3Sopenharmony_ci*/ 18b815c7f3Sopenharmony_ci 19b815c7f3Sopenharmony_ci#include <config.h> 20b815c7f3Sopenharmony_ci 21b815c7f3Sopenharmony_ci#include <stdarg.h> 22b815c7f3Sopenharmony_ci#include <string.h> 23b815c7f3Sopenharmony_ci#if HAVE_UNISTD_H 24b815c7f3Sopenharmony_ci#include <unistd.h> 25b815c7f3Sopenharmony_ci#else 26b815c7f3Sopenharmony_ci#include "sf_unistd.h" 27b815c7f3Sopenharmony_ci#endif 28b815c7f3Sopenharmony_ci#include <ctype.h> 29b815c7f3Sopenharmony_ci#include <math.h> 30b815c7f3Sopenharmony_ci#include <time.h> 31b815c7f3Sopenharmony_ci#if HAVE_SYS_TIME_H 32b815c7f3Sopenharmony_ci#include <sys/time.h> 33b815c7f3Sopenharmony_ci#endif 34b815c7f3Sopenharmony_ci#include "sndfile.h" 35b815c7f3Sopenharmony_ci#include "sfendian.h" 36b815c7f3Sopenharmony_ci#include "common.h" 37b815c7f3Sopenharmony_ci 38b815c7f3Sopenharmony_ci#define INITIAL_HEADER_SIZE 256 39b815c7f3Sopenharmony_ci 40b815c7f3Sopenharmony_ci/* Allocate and initialize the SF_PRIVATE struct. */ 41b815c7f3Sopenharmony_ciSF_PRIVATE * 42b815c7f3Sopenharmony_cipsf_allocate (void) 43b815c7f3Sopenharmony_ci{ SF_PRIVATE * psf ; 44b815c7f3Sopenharmony_ci 45b815c7f3Sopenharmony_ci if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL) 46b815c7f3Sopenharmony_ci return NULL ; 47b815c7f3Sopenharmony_ci 48b815c7f3Sopenharmony_ci if ((psf->header.ptr = calloc (1, INITIAL_HEADER_SIZE)) == NULL) 49b815c7f3Sopenharmony_ci { free (psf) ; 50b815c7f3Sopenharmony_ci return NULL ; 51b815c7f3Sopenharmony_ci } ; 52b815c7f3Sopenharmony_ci psf->header.len = INITIAL_HEADER_SIZE ; 53b815c7f3Sopenharmony_ci 54b815c7f3Sopenharmony_ci return psf ; 55b815c7f3Sopenharmony_ci} /* psf_allocate */ 56b815c7f3Sopenharmony_ci 57b815c7f3Sopenharmony_cistatic int 58b815c7f3Sopenharmony_cipsf_bump_header_allocation (SF_PRIVATE * psf, sf_count_t needed) 59b815c7f3Sopenharmony_ci{ 60b815c7f3Sopenharmony_ci sf_count_t newlen, smallest = INITIAL_HEADER_SIZE ; 61b815c7f3Sopenharmony_ci void * ptr ; 62b815c7f3Sopenharmony_ci 63b815c7f3Sopenharmony_ci newlen = (needed > psf->header.len) ? 2 * SF_MAX (needed, smallest) : 2 * psf->header.len ; 64b815c7f3Sopenharmony_ci 65b815c7f3Sopenharmony_ci if (newlen > 100 * 1024) 66b815c7f3Sopenharmony_ci { psf_log_printf (psf, "Request for header allocation of %D denied.\n", newlen) ; 67b815c7f3Sopenharmony_ci return 1 ; 68b815c7f3Sopenharmony_ci } 69b815c7f3Sopenharmony_ci 70b815c7f3Sopenharmony_ci if ((ptr = realloc (psf->header.ptr, newlen)) == NULL) 71b815c7f3Sopenharmony_ci { psf_log_printf (psf, "realloc (%p, %D) failed\n", psf->header.ptr, newlen) ; 72b815c7f3Sopenharmony_ci psf->error = SFE_MALLOC_FAILED ; 73b815c7f3Sopenharmony_ci return 1 ; 74b815c7f3Sopenharmony_ci } ; 75b815c7f3Sopenharmony_ci 76b815c7f3Sopenharmony_ci /* Always zero-out new header memory to avoid un-initializer memory accesses. */ 77b815c7f3Sopenharmony_ci if (newlen > psf->header.len) 78b815c7f3Sopenharmony_ci memset ((char *) ptr + psf->header.len, 0, newlen - psf->header.len) ; 79b815c7f3Sopenharmony_ci 80b815c7f3Sopenharmony_ci psf->header.ptr = ptr ; 81b815c7f3Sopenharmony_ci psf->header.len = newlen ; 82b815c7f3Sopenharmony_ci return 0 ; 83b815c7f3Sopenharmony_ci} /* psf_bump_header_allocation */ 84b815c7f3Sopenharmony_ci 85b815c7f3Sopenharmony_ci/*----------------------------------------------------------------------------------------------- 86b815c7f3Sopenharmony_ci** psf_log_printf allows libsndfile internal functions to print to an internal parselog which 87b815c7f3Sopenharmony_ci** can later be displayed. 88b815c7f3Sopenharmony_ci** The format specifiers are as for printf but without the field width and other modifiers. 89b815c7f3Sopenharmony_ci** Printing is performed to the parselog char array of the SF_PRIVATE struct. 90b815c7f3Sopenharmony_ci** Printing is done in such a way as to guarantee that the log never overflows the end of the 91b815c7f3Sopenharmony_ci** parselog array. 92b815c7f3Sopenharmony_ci*/ 93b815c7f3Sopenharmony_ci 94b815c7f3Sopenharmony_cistatic inline void 95b815c7f3Sopenharmony_cilog_putchar (SF_PRIVATE *psf, char ch) 96b815c7f3Sopenharmony_ci{ if (psf->parselog.indx < SIGNED_SIZEOF (psf->parselog.buf) - 1) 97b815c7f3Sopenharmony_ci { psf->parselog.buf [psf->parselog.indx++] = ch ; 98b815c7f3Sopenharmony_ci psf->parselog.buf [psf->parselog.indx] = 0 ; 99b815c7f3Sopenharmony_ci } ; 100b815c7f3Sopenharmony_ci return ; 101b815c7f3Sopenharmony_ci} /* log_putchar */ 102b815c7f3Sopenharmony_ci 103b815c7f3Sopenharmony_civoid 104b815c7f3Sopenharmony_cipsf_log_printf (SF_PRIVATE *psf, const char *format, ...) 105b815c7f3Sopenharmony_ci{ va_list ap ; 106b815c7f3Sopenharmony_ci uint32_t u, tens ; 107b815c7f3Sopenharmony_ci int d, shift, width, width_specifier, left_align, slen, precision ; 108b815c7f3Sopenharmony_ci char c, *strptr, istr [5], lead_char, sign_char ; 109b815c7f3Sopenharmony_ci 110b815c7f3Sopenharmony_ci va_start (ap, format) ; 111b815c7f3Sopenharmony_ci 112b815c7f3Sopenharmony_ci while ((c = *format++)) 113b815c7f3Sopenharmony_ci { if (c != '%') 114b815c7f3Sopenharmony_ci { log_putchar (psf, c) ; 115b815c7f3Sopenharmony_ci continue ; 116b815c7f3Sopenharmony_ci } ; 117b815c7f3Sopenharmony_ci 118b815c7f3Sopenharmony_ci if (format [0] == '%') /* Handle %% */ 119b815c7f3Sopenharmony_ci { log_putchar (psf, '%') ; 120b815c7f3Sopenharmony_ci format ++ ; 121b815c7f3Sopenharmony_ci continue ; 122b815c7f3Sopenharmony_ci } ; 123b815c7f3Sopenharmony_ci 124b815c7f3Sopenharmony_ci sign_char = 0 ; 125b815c7f3Sopenharmony_ci left_align = SF_FALSE ; 126b815c7f3Sopenharmony_ci while (1) 127b815c7f3Sopenharmony_ci { switch (format [0]) 128b815c7f3Sopenharmony_ci { case ' ' : 129b815c7f3Sopenharmony_ci case '+' : 130b815c7f3Sopenharmony_ci sign_char = format [0] ; 131b815c7f3Sopenharmony_ci format ++ ; 132b815c7f3Sopenharmony_ci continue ; 133b815c7f3Sopenharmony_ci 134b815c7f3Sopenharmony_ci case '-' : 135b815c7f3Sopenharmony_ci left_align = SF_TRUE ; 136b815c7f3Sopenharmony_ci format ++ ; 137b815c7f3Sopenharmony_ci continue ; 138b815c7f3Sopenharmony_ci 139b815c7f3Sopenharmony_ci default : break ; 140b815c7f3Sopenharmony_ci } ; 141b815c7f3Sopenharmony_ci 142b815c7f3Sopenharmony_ci break ; 143b815c7f3Sopenharmony_ci } ; 144b815c7f3Sopenharmony_ci 145b815c7f3Sopenharmony_ci if (format [0] == 0) 146b815c7f3Sopenharmony_ci break ; 147b815c7f3Sopenharmony_ci 148b815c7f3Sopenharmony_ci lead_char = ' ' ; 149b815c7f3Sopenharmony_ci if (format [0] == '0') 150b815c7f3Sopenharmony_ci lead_char = '0' ; 151b815c7f3Sopenharmony_ci 152b815c7f3Sopenharmony_ci width_specifier = 0 ; 153b815c7f3Sopenharmony_ci while ((c = *format++) && isdigit (c)) 154b815c7f3Sopenharmony_ci width_specifier = width_specifier * 10 + (c - '0') ; 155b815c7f3Sopenharmony_ci 156b815c7f3Sopenharmony_ci precision = 0 ; 157b815c7f3Sopenharmony_ci if (c == '.') 158b815c7f3Sopenharmony_ci { while ((c = *format++) && isdigit (c)) 159b815c7f3Sopenharmony_ci precision = precision * 10 + (c - '0') ; 160b815c7f3Sopenharmony_ci } ; 161b815c7f3Sopenharmony_ci 162b815c7f3Sopenharmony_ci switch (c) 163b815c7f3Sopenharmony_ci { case 0 : /* NULL character. */ 164b815c7f3Sopenharmony_ci va_end (ap) ; 165b815c7f3Sopenharmony_ci return ; 166b815c7f3Sopenharmony_ci 167b815c7f3Sopenharmony_ci case 's': /* string */ 168b815c7f3Sopenharmony_ci strptr = va_arg (ap, char *) ; 169b815c7f3Sopenharmony_ci if (strptr == NULL) 170b815c7f3Sopenharmony_ci break ; 171b815c7f3Sopenharmony_ci if (precision > 0) 172b815c7f3Sopenharmony_ci slen = strnlen (strptr, precision) ; 173b815c7f3Sopenharmony_ci else 174b815c7f3Sopenharmony_ci slen = strlen (strptr) ; 175b815c7f3Sopenharmony_ci width_specifier = width_specifier >= slen ? width_specifier - slen : 0 ; 176b815c7f3Sopenharmony_ci if (left_align == SF_FALSE) 177b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 178b815c7f3Sopenharmony_ci log_putchar (psf, ' ') ; 179b815c7f3Sopenharmony_ci while (slen--) 180b815c7f3Sopenharmony_ci log_putchar (psf, *strptr++) ; 181b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 182b815c7f3Sopenharmony_ci log_putchar (psf, ' ') ; 183b815c7f3Sopenharmony_ci break ; 184b815c7f3Sopenharmony_ci 185b815c7f3Sopenharmony_ci case 'd': /* int */ 186b815c7f3Sopenharmony_ci d = va_arg (ap, int) ; 187b815c7f3Sopenharmony_ci 188b815c7f3Sopenharmony_ci if (d < 0) 189b815c7f3Sopenharmony_ci { sign_char = '-' ; 190b815c7f3Sopenharmony_ci if (lead_char != '0' && left_align == SF_FALSE) 191b815c7f3Sopenharmony_ci width_specifier -- ; 192b815c7f3Sopenharmony_ci 193b815c7f3Sopenharmony_ci u = - ((unsigned) d) ; 194b815c7f3Sopenharmony_ci } 195b815c7f3Sopenharmony_ci else 196b815c7f3Sopenharmony_ci { u = (unsigned) d ; 197b815c7f3Sopenharmony_ci } 198b815c7f3Sopenharmony_ci 199b815c7f3Sopenharmony_ci tens = 1 ; 200b815c7f3Sopenharmony_ci width = 1 ; 201b815c7f3Sopenharmony_ci while (u / tens >= 10) 202b815c7f3Sopenharmony_ci { tens *= 10 ; 203b815c7f3Sopenharmony_ci width ++ ; 204b815c7f3Sopenharmony_ci } ; 205b815c7f3Sopenharmony_ci 206b815c7f3Sopenharmony_ci width_specifier -= width ; 207b815c7f3Sopenharmony_ci 208b815c7f3Sopenharmony_ci if (sign_char == ' ') 209b815c7f3Sopenharmony_ci { log_putchar (psf, ' ') ; 210b815c7f3Sopenharmony_ci width_specifier -- ; 211b815c7f3Sopenharmony_ci } ; 212b815c7f3Sopenharmony_ci 213b815c7f3Sopenharmony_ci if (left_align == SF_FALSE && lead_char != '0') 214b815c7f3Sopenharmony_ci { if (sign_char == '+') 215b815c7f3Sopenharmony_ci width_specifier -- ; 216b815c7f3Sopenharmony_ci 217b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 218b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 219b815c7f3Sopenharmony_ci } ; 220b815c7f3Sopenharmony_ci 221b815c7f3Sopenharmony_ci if (sign_char == '+' || sign_char == '-') 222b815c7f3Sopenharmony_ci { log_putchar (psf, sign_char) ; 223b815c7f3Sopenharmony_ci width_specifier -- ; 224b815c7f3Sopenharmony_ci } ; 225b815c7f3Sopenharmony_ci 226b815c7f3Sopenharmony_ci if (left_align == SF_FALSE) 227b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 228b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 229b815c7f3Sopenharmony_ci 230b815c7f3Sopenharmony_ci while (tens > 0) 231b815c7f3Sopenharmony_ci { log_putchar (psf, '0' + u / tens) ; 232b815c7f3Sopenharmony_ci u %= tens ; 233b815c7f3Sopenharmony_ci tens /= 10 ; 234b815c7f3Sopenharmony_ci } ; 235b815c7f3Sopenharmony_ci 236b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 237b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 238b815c7f3Sopenharmony_ci break ; 239b815c7f3Sopenharmony_ci 240b815c7f3Sopenharmony_ci case 'D': /* sf_count_t */ 241b815c7f3Sopenharmony_ci { sf_count_t D ; 242b815c7f3Sopenharmony_ci uint64_t U, Tens ; 243b815c7f3Sopenharmony_ci 244b815c7f3Sopenharmony_ci D = va_arg (ap, sf_count_t) ; 245b815c7f3Sopenharmony_ci 246b815c7f3Sopenharmony_ci if (D == 0) 247b815c7f3Sopenharmony_ci { while (-- width_specifier > 0) 248b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 249b815c7f3Sopenharmony_ci log_putchar (psf, '0') ; 250b815c7f3Sopenharmony_ci break ; 251b815c7f3Sopenharmony_ci } 252b815c7f3Sopenharmony_ci else 253b815c7f3Sopenharmony_ci { if (D < 0) 254b815c7f3Sopenharmony_ci { log_putchar (psf, '-') ; 255b815c7f3Sopenharmony_ci U = -((uint64_t) D) ; 256b815c7f3Sopenharmony_ci } 257b815c7f3Sopenharmony_ci else 258b815c7f3Sopenharmony_ci { U = (uint64_t) D; 259b815c7f3Sopenharmony_ci } 260b815c7f3Sopenharmony_ci } 261b815c7f3Sopenharmony_ci 262b815c7f3Sopenharmony_ci Tens = 1 ; 263b815c7f3Sopenharmony_ci width = 1 ; 264b815c7f3Sopenharmony_ci while (U / Tens >= 10) 265b815c7f3Sopenharmony_ci { Tens *= 10 ; 266b815c7f3Sopenharmony_ci width ++ ; 267b815c7f3Sopenharmony_ci } ; 268b815c7f3Sopenharmony_ci 269b815c7f3Sopenharmony_ci while (width_specifier > width) 270b815c7f3Sopenharmony_ci { log_putchar (psf, lead_char) ; 271b815c7f3Sopenharmony_ci width_specifier-- ; 272b815c7f3Sopenharmony_ci } ; 273b815c7f3Sopenharmony_ci 274b815c7f3Sopenharmony_ci while (Tens > 0) 275b815c7f3Sopenharmony_ci { log_putchar (psf, '0' + U / Tens) ; 276b815c7f3Sopenharmony_ci U %= Tens ; 277b815c7f3Sopenharmony_ci Tens /= 10 ; 278b815c7f3Sopenharmony_ci } ; 279b815c7f3Sopenharmony_ci } ; 280b815c7f3Sopenharmony_ci break ; 281b815c7f3Sopenharmony_ci 282b815c7f3Sopenharmony_ci case 'u': /* unsigned int */ 283b815c7f3Sopenharmony_ci u = va_arg (ap, unsigned int) ; 284b815c7f3Sopenharmony_ci 285b815c7f3Sopenharmony_ci tens = 1 ; 286b815c7f3Sopenharmony_ci width = 1 ; 287b815c7f3Sopenharmony_ci while (u / tens >= 10) 288b815c7f3Sopenharmony_ci { tens *= 10 ; 289b815c7f3Sopenharmony_ci width ++ ; 290b815c7f3Sopenharmony_ci } ; 291b815c7f3Sopenharmony_ci 292b815c7f3Sopenharmony_ci width_specifier -= width ; 293b815c7f3Sopenharmony_ci 294b815c7f3Sopenharmony_ci if (sign_char == ' ') 295b815c7f3Sopenharmony_ci { log_putchar (psf, ' ') ; 296b815c7f3Sopenharmony_ci width_specifier -- ; 297b815c7f3Sopenharmony_ci } ; 298b815c7f3Sopenharmony_ci 299b815c7f3Sopenharmony_ci if (left_align == SF_FALSE && lead_char != '0') 300b815c7f3Sopenharmony_ci { if (sign_char == '+') 301b815c7f3Sopenharmony_ci width_specifier -- ; 302b815c7f3Sopenharmony_ci 303b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 304b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 305b815c7f3Sopenharmony_ci } ; 306b815c7f3Sopenharmony_ci 307b815c7f3Sopenharmony_ci if (sign_char == '+' || sign_char == '-') 308b815c7f3Sopenharmony_ci { log_putchar (psf, sign_char) ; 309b815c7f3Sopenharmony_ci width_specifier -- ; 310b815c7f3Sopenharmony_ci } ; 311b815c7f3Sopenharmony_ci 312b815c7f3Sopenharmony_ci if (left_align == SF_FALSE) 313b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 314b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 315b815c7f3Sopenharmony_ci 316b815c7f3Sopenharmony_ci while (tens > 0) 317b815c7f3Sopenharmony_ci { log_putchar (psf, '0' + u / tens) ; 318b815c7f3Sopenharmony_ci u %= tens ; 319b815c7f3Sopenharmony_ci tens /= 10 ; 320b815c7f3Sopenharmony_ci } ; 321b815c7f3Sopenharmony_ci 322b815c7f3Sopenharmony_ci while (width_specifier -- > 0) 323b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 324b815c7f3Sopenharmony_ci break ; 325b815c7f3Sopenharmony_ci 326b815c7f3Sopenharmony_ci case 'c': /* char */ 327b815c7f3Sopenharmony_ci c = va_arg (ap, int) & 0xFF ; 328b815c7f3Sopenharmony_ci log_putchar (psf, c) ; 329b815c7f3Sopenharmony_ci break ; 330b815c7f3Sopenharmony_ci 331b815c7f3Sopenharmony_ci case 'x': /* hex */ 332b815c7f3Sopenharmony_ci case 'X': /* hex */ 333b815c7f3Sopenharmony_ci d = va_arg (ap, int) ; 334b815c7f3Sopenharmony_ci 335b815c7f3Sopenharmony_ci if (d == 0) 336b815c7f3Sopenharmony_ci { while (--width_specifier > 0) 337b815c7f3Sopenharmony_ci log_putchar (psf, lead_char) ; 338b815c7f3Sopenharmony_ci log_putchar (psf, '0') ; 339b815c7f3Sopenharmony_ci break ; 340b815c7f3Sopenharmony_ci } ; 341b815c7f3Sopenharmony_ci shift = 28 ; 342b815c7f3Sopenharmony_ci width = (width_specifier < 8) ? 8 : width_specifier ; 343b815c7f3Sopenharmony_ci while (! ((((uint32_t) 0xF) << shift) & d)) 344b815c7f3Sopenharmony_ci { shift -= 4 ; 345b815c7f3Sopenharmony_ci width -- ; 346b815c7f3Sopenharmony_ci } ; 347b815c7f3Sopenharmony_ci 348b815c7f3Sopenharmony_ci while (width > 0 && width_specifier > width) 349b815c7f3Sopenharmony_ci { log_putchar (psf, lead_char) ; 350b815c7f3Sopenharmony_ci width_specifier-- ; 351b815c7f3Sopenharmony_ci } ; 352b815c7f3Sopenharmony_ci 353b815c7f3Sopenharmony_ci while (shift >= 0) 354b815c7f3Sopenharmony_ci { c = (d >> shift) & 0xF ; 355b815c7f3Sopenharmony_ci log_putchar (psf, (c > 9) ? c + 'A' - 10 : c + '0') ; 356b815c7f3Sopenharmony_ci shift -= 4 ; 357b815c7f3Sopenharmony_ci } ; 358b815c7f3Sopenharmony_ci break ; 359b815c7f3Sopenharmony_ci 360b815c7f3Sopenharmony_ci case 'M': /* int2str */ 361b815c7f3Sopenharmony_ci d = va_arg (ap, int) ; 362b815c7f3Sopenharmony_ci if (CPU_IS_LITTLE_ENDIAN) 363b815c7f3Sopenharmony_ci { istr [0] = d & 0xFF ; 364b815c7f3Sopenharmony_ci istr [1] = (d >> 8) & 0xFF ; 365b815c7f3Sopenharmony_ci istr [2] = (d >> 16) & 0xFF ; 366b815c7f3Sopenharmony_ci istr [3] = (d >> 24) & 0xFF ; 367b815c7f3Sopenharmony_ci } 368b815c7f3Sopenharmony_ci else 369b815c7f3Sopenharmony_ci { istr [3] = d & 0xFF ; 370b815c7f3Sopenharmony_ci istr [2] = (d >> 8) & 0xFF ; 371b815c7f3Sopenharmony_ci istr [1] = (d >> 16) & 0xFF ; 372b815c7f3Sopenharmony_ci istr [0] = (d >> 24) & 0xFF ; 373b815c7f3Sopenharmony_ci } ; 374b815c7f3Sopenharmony_ci istr [4] = 0 ; 375b815c7f3Sopenharmony_ci strptr = istr ; 376b815c7f3Sopenharmony_ci while (*strptr) 377b815c7f3Sopenharmony_ci { c = *strptr++ ; 378b815c7f3Sopenharmony_ci log_putchar (psf, psf_isprint (c) ? c : '.') ; 379b815c7f3Sopenharmony_ci } ; 380b815c7f3Sopenharmony_ci break ; 381b815c7f3Sopenharmony_ci 382b815c7f3Sopenharmony_ci default : 383b815c7f3Sopenharmony_ci log_putchar (psf, '*') ; 384b815c7f3Sopenharmony_ci log_putchar (psf, c) ; 385b815c7f3Sopenharmony_ci log_putchar (psf, '*') ; 386b815c7f3Sopenharmony_ci break ; 387b815c7f3Sopenharmony_ci } /* switch */ 388b815c7f3Sopenharmony_ci } /* while */ 389b815c7f3Sopenharmony_ci 390b815c7f3Sopenharmony_ci va_end (ap) ; 391b815c7f3Sopenharmony_ci return ; 392b815c7f3Sopenharmony_ci} /* psf_log_printf */ 393b815c7f3Sopenharmony_ci 394b815c7f3Sopenharmony_ci/*----------------------------------------------------------------------------------------------- 395b815c7f3Sopenharmony_ci** ASCII header printf functions. 396b815c7f3Sopenharmony_ci** Some formats (ie NIST) use ascii text in their headers. 397b815c7f3Sopenharmony_ci** Format specifiers are the same as the standard printf specifiers (uses vsnprintf). 398b815c7f3Sopenharmony_ci** If this generates a compile error on any system, the author should be notified 399b815c7f3Sopenharmony_ci** so an alternative vsnprintf can be provided. 400b815c7f3Sopenharmony_ci*/ 401b815c7f3Sopenharmony_ci 402b815c7f3Sopenharmony_civoid 403b815c7f3Sopenharmony_cipsf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...) 404b815c7f3Sopenharmony_ci{ va_list argptr ; 405b815c7f3Sopenharmony_ci int maxlen ; 406b815c7f3Sopenharmony_ci char *start ; 407b815c7f3Sopenharmony_ci 408b815c7f3Sopenharmony_ci if (! format) 409b815c7f3Sopenharmony_ci return ; 410b815c7f3Sopenharmony_ci 411b815c7f3Sopenharmony_ci maxlen = strlen ((char*) psf->header.ptr) ; 412b815c7f3Sopenharmony_ci start = ((char*) psf->header.ptr) + maxlen ; 413b815c7f3Sopenharmony_ci maxlen = psf->header.len - maxlen ; 414b815c7f3Sopenharmony_ci 415b815c7f3Sopenharmony_ci va_start (argptr, format) ; 416b815c7f3Sopenharmony_ci vsnprintf (start, maxlen, format, argptr) ; 417b815c7f3Sopenharmony_ci va_end (argptr) ; 418b815c7f3Sopenharmony_ci 419b815c7f3Sopenharmony_ci /* Make sure the string is properly terminated. */ 420b815c7f3Sopenharmony_ci start [maxlen - 1] = 0 ; 421b815c7f3Sopenharmony_ci 422b815c7f3Sopenharmony_ci psf->header.indx = strlen ((char*) psf->header.ptr) ; 423b815c7f3Sopenharmony_ci 424b815c7f3Sopenharmony_ci return ; 425b815c7f3Sopenharmony_ci} /* psf_asciiheader_printf */ 426b815c7f3Sopenharmony_ci 427b815c7f3Sopenharmony_ci/*----------------------------------------------------------------------------------------------- 428b815c7f3Sopenharmony_ci** Binary header writing functions. Returns number of bytes written. 429b815c7f3Sopenharmony_ci** 430b815c7f3Sopenharmony_ci** Format specifiers for psf_binheader_writef are as follows 431b815c7f3Sopenharmony_ci** m - marker - four bytes - no endian manipulation 432b815c7f3Sopenharmony_ci** 433b815c7f3Sopenharmony_ci** e - all following numerical values will be little endian 434b815c7f3Sopenharmony_ci** E - all following numerical values will be big endian 435b815c7f3Sopenharmony_ci** 436b815c7f3Sopenharmony_ci** t - all following O types will be truncated to 4 bytes 437b815c7f3Sopenharmony_ci** T - switch off truncation of all following O types 438b815c7f3Sopenharmony_ci** 439b815c7f3Sopenharmony_ci** 1 - single byte value 440b815c7f3Sopenharmony_ci** 2 - two byte value 441b815c7f3Sopenharmony_ci** 3 - three byte value 442b815c7f3Sopenharmony_ci** 4 - four byte value 443b815c7f3Sopenharmony_ci** 8 - eight byte value (sometimes written as 4 bytes) 444b815c7f3Sopenharmony_ci** 445b815c7f3Sopenharmony_ci** s - string preceded by a four byte length 446b815c7f3Sopenharmony_ci** S - string including null terminator 447b815c7f3Sopenharmony_ci** p - a Pascal string 448b815c7f3Sopenharmony_ci** 449b815c7f3Sopenharmony_ci** f - floating point data 450b815c7f3Sopenharmony_ci** d - double precision floating point data 451b815c7f3Sopenharmony_ci** h - 16 binary bytes value 452b815c7f3Sopenharmony_ci** 453b815c7f3Sopenharmony_ci** b - binary data (see below) 454b815c7f3Sopenharmony_ci** z - zero bytes (ses below) 455b815c7f3Sopenharmony_ci** j - jump forwards or backwards 456b815c7f3Sopenharmony_ci** 457b815c7f3Sopenharmony_ci** To write a word followed by an int (both little endian) use: 458b815c7f3Sopenharmony_ci** psf_binheader_writef ("e24", wordval, longval) ; 459b815c7f3Sopenharmony_ci** 460b815c7f3Sopenharmony_ci** To write binary data use: 461b815c7f3Sopenharmony_ci** psf_binheader_writef ("b", &bindata, sizeof (bindata)) ; 462b815c7f3Sopenharmony_ci** 463b815c7f3Sopenharmony_ci** To write N zero bytes use: 464b815c7f3Sopenharmony_ci** NOTE: due to platform issues (ie x86-64) you should cast the 465b815c7f3Sopenharmony_ci** argument to size_t or ensure the variable type is size_t. 466b815c7f3Sopenharmony_ci** psf_binheader_writef ("z", N) ; 467b815c7f3Sopenharmony_ci*/ 468b815c7f3Sopenharmony_ci 469b815c7f3Sopenharmony_ci/* These macros may seem a bit messy but do prevent problems with processors which 470b815c7f3Sopenharmony_ci** seg. fault when asked to write an int or short to a non-int/short aligned address. 471b815c7f3Sopenharmony_ci*/ 472b815c7f3Sopenharmony_ci 473b815c7f3Sopenharmony_cistatic inline void 474b815c7f3Sopenharmony_ciheader_put_byte (SF_PRIVATE *psf, char x) 475b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = x ; 476b815c7f3Sopenharmony_ci} /* header_put_byte */ 477b815c7f3Sopenharmony_ci 478b815c7f3Sopenharmony_ci#if (CPU_IS_BIG_ENDIAN == 1) 479b815c7f3Sopenharmony_cistatic inline void 480b815c7f3Sopenharmony_ciheader_put_marker (SF_PRIVATE *psf, int x) 481b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = (x >> 24) ; 482b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 16) ; 483b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 8) ; 484b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = x ; 485b815c7f3Sopenharmony_ci} /* header_put_marker */ 486b815c7f3Sopenharmony_ci 487b815c7f3Sopenharmony_ci#elif (CPU_IS_LITTLE_ENDIAN == 1) 488b815c7f3Sopenharmony_cistatic inline void 489b815c7f3Sopenharmony_ciheader_put_marker (SF_PRIVATE *psf, int x) 490b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = x ; 491b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 8) ; 492b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 16) ; 493b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 24) ; 494b815c7f3Sopenharmony_ci} /* header_put_marker */ 495b815c7f3Sopenharmony_ci 496b815c7f3Sopenharmony_ci#else 497b815c7f3Sopenharmony_ci# error "Cannot determine endian-ness of processor." 498b815c7f3Sopenharmony_ci#endif 499b815c7f3Sopenharmony_ci 500b815c7f3Sopenharmony_ci 501b815c7f3Sopenharmony_cistatic inline void 502b815c7f3Sopenharmony_ciheader_put_be_short (SF_PRIVATE *psf, int x) 503b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = (x >> 8) ; 504b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = x ; 505b815c7f3Sopenharmony_ci} /* header_put_be_short */ 506b815c7f3Sopenharmony_ci 507b815c7f3Sopenharmony_cistatic inline void 508b815c7f3Sopenharmony_ciheader_put_le_short (SF_PRIVATE *psf, int x) 509b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = x ; 510b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 8) ; 511b815c7f3Sopenharmony_ci} /* header_put_le_short */ 512b815c7f3Sopenharmony_ci 513b815c7f3Sopenharmony_cistatic inline void 514b815c7f3Sopenharmony_ciheader_put_be_3byte (SF_PRIVATE *psf, int x) 515b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = (x >> 16) ; 516b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 8) ; 517b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = x ; 518b815c7f3Sopenharmony_ci} /* header_put_be_3byte */ 519b815c7f3Sopenharmony_ci 520b815c7f3Sopenharmony_cistatic inline void 521b815c7f3Sopenharmony_ciheader_put_le_3byte (SF_PRIVATE *psf, int x) 522b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = x ; 523b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 8) ; 524b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 16) ; 525b815c7f3Sopenharmony_ci} /* header_put_le_3byte */ 526b815c7f3Sopenharmony_ci 527b815c7f3Sopenharmony_cistatic inline void 528b815c7f3Sopenharmony_ciheader_put_be_int (SF_PRIVATE *psf, int x) 529b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = (x >> 24) ; 530b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 16) ; 531b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 8) ; 532b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = x ; 533b815c7f3Sopenharmony_ci} /* header_put_be_int */ 534b815c7f3Sopenharmony_ci 535b815c7f3Sopenharmony_cistatic inline void 536b815c7f3Sopenharmony_ciheader_put_le_int (SF_PRIVATE *psf, int x) 537b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = x ; 538b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 8) ; 539b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 16) ; 540b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 24) ; 541b815c7f3Sopenharmony_ci} /* header_put_le_int */ 542b815c7f3Sopenharmony_ci 543b815c7f3Sopenharmony_cistatic inline void 544b815c7f3Sopenharmony_ciheader_put_be_8byte (SF_PRIVATE *psf, sf_count_t x) 545b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = (x >> 56) ; 546b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ; 547b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ; 548b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ; 549b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ; 550b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ; 551b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ; 552b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) x ; 553b815c7f3Sopenharmony_ci} /* header_put_be_8byte */ 554b815c7f3Sopenharmony_ci 555b815c7f3Sopenharmony_cistatic inline void 556b815c7f3Sopenharmony_ciheader_put_le_8byte (SF_PRIVATE *psf, sf_count_t x) 557b815c7f3Sopenharmony_ci{ psf->header.ptr [psf->header.indx++] = (unsigned char) x ; 558b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ; 559b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ; 560b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ; 561b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ; 562b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ; 563b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ; 564b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx++] = (x >> 56) ; 565b815c7f3Sopenharmony_ci} /* header_put_le_8byte */ 566b815c7f3Sopenharmony_ci 567b815c7f3Sopenharmony_ciint 568b815c7f3Sopenharmony_cipsf_binheader_writef (SF_PRIVATE *psf, const char *format, ...) 569b815c7f3Sopenharmony_ci{ va_list argptr ; 570b815c7f3Sopenharmony_ci sf_count_t countdata ; 571b815c7f3Sopenharmony_ci unsigned long longdata ; 572b815c7f3Sopenharmony_ci unsigned int data ; 573b815c7f3Sopenharmony_ci float floatdata ; 574b815c7f3Sopenharmony_ci double doubledata ; 575b815c7f3Sopenharmony_ci void *bindata ; 576b815c7f3Sopenharmony_ci size_t size ; 577b815c7f3Sopenharmony_ci char c, *strptr ; 578b815c7f3Sopenharmony_ci int count = 0, trunc_8to4 = SF_FALSE ; 579b815c7f3Sopenharmony_ci 580b815c7f3Sopenharmony_ci if (! format) 581b815c7f3Sopenharmony_ci return psf_ftell (psf) ; 582b815c7f3Sopenharmony_ci 583b815c7f3Sopenharmony_ci va_start (argptr, format) ; 584b815c7f3Sopenharmony_ci 585b815c7f3Sopenharmony_ci while ((c = *format++)) 586b815c7f3Sopenharmony_ci { 587b815c7f3Sopenharmony_ci if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16)) 588b815c7f3Sopenharmony_ci break ; 589b815c7f3Sopenharmony_ci 590b815c7f3Sopenharmony_ci switch (c) 591b815c7f3Sopenharmony_ci { case ' ' : /* Do nothing. Just used to space out format string. */ 592b815c7f3Sopenharmony_ci break ; 593b815c7f3Sopenharmony_ci 594b815c7f3Sopenharmony_ci case 'e' : /* All conversions are now from LE to host. */ 595b815c7f3Sopenharmony_ci psf->rwf_endian = SF_ENDIAN_LITTLE ; 596b815c7f3Sopenharmony_ci break ; 597b815c7f3Sopenharmony_ci 598b815c7f3Sopenharmony_ci case 'E' : /* All conversions are now from BE to host. */ 599b815c7f3Sopenharmony_ci psf->rwf_endian = SF_ENDIAN_BIG ; 600b815c7f3Sopenharmony_ci break ; 601b815c7f3Sopenharmony_ci 602b815c7f3Sopenharmony_ci case 't' : /* All 8 byte values now get written as 4 bytes. */ 603b815c7f3Sopenharmony_ci trunc_8to4 = SF_TRUE ; 604b815c7f3Sopenharmony_ci break ; 605b815c7f3Sopenharmony_ci 606b815c7f3Sopenharmony_ci case 'T' : /* All 8 byte values now get written as 8 bytes. */ 607b815c7f3Sopenharmony_ci trunc_8to4 = SF_FALSE ; 608b815c7f3Sopenharmony_ci break ; 609b815c7f3Sopenharmony_ci 610b815c7f3Sopenharmony_ci case 'm' : 611b815c7f3Sopenharmony_ci data = va_arg (argptr, unsigned int) ; 612b815c7f3Sopenharmony_ci header_put_marker (psf, data) ; 613b815c7f3Sopenharmony_ci count += 4 ; 614b815c7f3Sopenharmony_ci break ; 615b815c7f3Sopenharmony_ci 616b815c7f3Sopenharmony_ci case '1' : 617b815c7f3Sopenharmony_ci data = va_arg (argptr, unsigned int) ; 618b815c7f3Sopenharmony_ci header_put_byte (psf, data) ; 619b815c7f3Sopenharmony_ci count += 1 ; 620b815c7f3Sopenharmony_ci break ; 621b815c7f3Sopenharmony_ci 622b815c7f3Sopenharmony_ci case '2' : 623b815c7f3Sopenharmony_ci data = va_arg (argptr, unsigned int) ; 624b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 625b815c7f3Sopenharmony_ci { header_put_be_short (psf, data) ; 626b815c7f3Sopenharmony_ci } 627b815c7f3Sopenharmony_ci else 628b815c7f3Sopenharmony_ci { header_put_le_short (psf, data) ; 629b815c7f3Sopenharmony_ci } ; 630b815c7f3Sopenharmony_ci count += 2 ; 631b815c7f3Sopenharmony_ci break ; 632b815c7f3Sopenharmony_ci 633b815c7f3Sopenharmony_ci case '3' : /* tribyte */ 634b815c7f3Sopenharmony_ci data = va_arg (argptr, unsigned int) ; 635b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 636b815c7f3Sopenharmony_ci { header_put_be_3byte (psf, data) ; 637b815c7f3Sopenharmony_ci } 638b815c7f3Sopenharmony_ci else 639b815c7f3Sopenharmony_ci { header_put_le_3byte (psf, data) ; 640b815c7f3Sopenharmony_ci } ; 641b815c7f3Sopenharmony_ci count += 3 ; 642b815c7f3Sopenharmony_ci break ; 643b815c7f3Sopenharmony_ci 644b815c7f3Sopenharmony_ci case '4' : 645b815c7f3Sopenharmony_ci data = va_arg (argptr, unsigned int) ; 646b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 647b815c7f3Sopenharmony_ci { header_put_be_int (psf, data) ; 648b815c7f3Sopenharmony_ci } 649b815c7f3Sopenharmony_ci else 650b815c7f3Sopenharmony_ci { header_put_le_int (psf, data) ; 651b815c7f3Sopenharmony_ci } ; 652b815c7f3Sopenharmony_ci count += 4 ; 653b815c7f3Sopenharmony_ci break ; 654b815c7f3Sopenharmony_ci 655b815c7f3Sopenharmony_ci case '8' : 656b815c7f3Sopenharmony_ci countdata = va_arg (argptr, sf_count_t) ; 657b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_FALSE) 658b815c7f3Sopenharmony_ci { header_put_be_8byte (psf, countdata) ; 659b815c7f3Sopenharmony_ci count += 8 ; 660b815c7f3Sopenharmony_ci } 661b815c7f3Sopenharmony_ci else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_FALSE) 662b815c7f3Sopenharmony_ci { header_put_le_8byte (psf, countdata) ; 663b815c7f3Sopenharmony_ci count += 8 ; 664b815c7f3Sopenharmony_ci } 665b815c7f3Sopenharmony_ci else if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_TRUE) 666b815c7f3Sopenharmony_ci { longdata = countdata & 0xFFFFFFFF ; 667b815c7f3Sopenharmony_ci header_put_be_int (psf, longdata) ; 668b815c7f3Sopenharmony_ci count += 4 ; 669b815c7f3Sopenharmony_ci } 670b815c7f3Sopenharmony_ci else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_TRUE) 671b815c7f3Sopenharmony_ci { longdata = countdata & 0xFFFFFFFF ; 672b815c7f3Sopenharmony_ci header_put_le_int (psf, longdata) ; 673b815c7f3Sopenharmony_ci count += 4 ; 674b815c7f3Sopenharmony_ci } 675b815c7f3Sopenharmony_ci break ; 676b815c7f3Sopenharmony_ci 677b815c7f3Sopenharmony_ci case 'f' : 678b815c7f3Sopenharmony_ci /* Floats are passed as doubles. Is this always true? */ 679b815c7f3Sopenharmony_ci floatdata = (float) va_arg (argptr, double) ; 680b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 681b815c7f3Sopenharmony_ci float32_be_write (floatdata, psf->header.ptr + psf->header.indx) ; 682b815c7f3Sopenharmony_ci else 683b815c7f3Sopenharmony_ci float32_le_write (floatdata, psf->header.ptr + psf->header.indx) ; 684b815c7f3Sopenharmony_ci psf->header.indx += 4 ; 685b815c7f3Sopenharmony_ci count += 4 ; 686b815c7f3Sopenharmony_ci break ; 687b815c7f3Sopenharmony_ci 688b815c7f3Sopenharmony_ci case 'd' : 689b815c7f3Sopenharmony_ci doubledata = va_arg (argptr, double) ; 690b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 691b815c7f3Sopenharmony_ci double64_be_write (doubledata, psf->header.ptr + psf->header.indx) ; 692b815c7f3Sopenharmony_ci else 693b815c7f3Sopenharmony_ci double64_le_write (doubledata, psf->header.ptr + psf->header.indx) ; 694b815c7f3Sopenharmony_ci psf->header.indx += 8 ; 695b815c7f3Sopenharmony_ci count += 8 ; 696b815c7f3Sopenharmony_ci break ; 697b815c7f3Sopenharmony_ci 698b815c7f3Sopenharmony_ci case 's' : 699b815c7f3Sopenharmony_ci /* Write a C string (guaranteed to have a zero terminator). */ 700b815c7f3Sopenharmony_ci strptr = va_arg (argptr, char *) ; 701b815c7f3Sopenharmony_ci size = strlen (strptr) + 1 ; 702b815c7f3Sopenharmony_ci 703b815c7f3Sopenharmony_ci if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1))) 704b815c7f3Sopenharmony_ci break ; 705b815c7f3Sopenharmony_ci 706b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 707b815c7f3Sopenharmony_ci header_put_be_int (psf, size + (size & 1)) ; 708b815c7f3Sopenharmony_ci else 709b815c7f3Sopenharmony_ci header_put_le_int (psf, size + (size & 1)) ; 710b815c7f3Sopenharmony_ci memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ; 711b815c7f3Sopenharmony_ci size += (size & 1) ; 712b815c7f3Sopenharmony_ci psf->header.indx += size ; 713b815c7f3Sopenharmony_ci psf->header.ptr [psf->header.indx - 1] = 0 ; 714b815c7f3Sopenharmony_ci count += 4 + size ; 715b815c7f3Sopenharmony_ci break ; 716b815c7f3Sopenharmony_ci 717b815c7f3Sopenharmony_ci case 'S' : 718b815c7f3Sopenharmony_ci /* 719b815c7f3Sopenharmony_ci ** Write an AIFF style string (no zero terminator but possibly 720b815c7f3Sopenharmony_ci ** an extra pad byte if the string length is odd). 721b815c7f3Sopenharmony_ci */ 722b815c7f3Sopenharmony_ci strptr = va_arg (argptr, char *) ; 723b815c7f3Sopenharmony_ci size = strlen (strptr) ; 724b815c7f3Sopenharmony_ci if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1))) 725b815c7f3Sopenharmony_ci break ; 726b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 727b815c7f3Sopenharmony_ci header_put_be_int (psf, size) ; 728b815c7f3Sopenharmony_ci else 729b815c7f3Sopenharmony_ci header_put_le_int (psf, size) ; 730b815c7f3Sopenharmony_ci memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size + (size & 1)) ; 731b815c7f3Sopenharmony_ci size += (size & 1) ; 732b815c7f3Sopenharmony_ci psf->header.indx += size ; 733b815c7f3Sopenharmony_ci count += 4 + size ; 734b815c7f3Sopenharmony_ci break ; 735b815c7f3Sopenharmony_ci 736b815c7f3Sopenharmony_ci case 'p' : 737b815c7f3Sopenharmony_ci /* Write a PASCAL string (as used by AIFF files). 738b815c7f3Sopenharmony_ci */ 739b815c7f3Sopenharmony_ci strptr = va_arg (argptr, char *) ; 740b815c7f3Sopenharmony_ci size = strlen (strptr) ; 741b815c7f3Sopenharmony_ci size = (size & 1) ? size : size + 1 ; 742b815c7f3Sopenharmony_ci size = (size > 254) ? 254 : size ; 743b815c7f3Sopenharmony_ci 744b815c7f3Sopenharmony_ci if (psf->header.indx + 1 + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, 1 + size)) 745b815c7f3Sopenharmony_ci break ; 746b815c7f3Sopenharmony_ci 747b815c7f3Sopenharmony_ci header_put_byte (psf, size) ; 748b815c7f3Sopenharmony_ci memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ; 749b815c7f3Sopenharmony_ci psf->header.indx += size ; 750b815c7f3Sopenharmony_ci count += 1 + size ; 751b815c7f3Sopenharmony_ci break ; 752b815c7f3Sopenharmony_ci 753b815c7f3Sopenharmony_ci case 'b' : 754b815c7f3Sopenharmony_ci bindata = va_arg (argptr, void *) ; 755b815c7f3Sopenharmony_ci size = va_arg (argptr, size_t) ; 756b815c7f3Sopenharmony_ci 757b815c7f3Sopenharmony_ci if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size)) 758b815c7f3Sopenharmony_ci break ; 759b815c7f3Sopenharmony_ci 760b815c7f3Sopenharmony_ci memcpy (&(psf->header.ptr [psf->header.indx]), bindata, size) ; 761b815c7f3Sopenharmony_ci psf->header.indx += size ; 762b815c7f3Sopenharmony_ci count += size ; 763b815c7f3Sopenharmony_ci break ; 764b815c7f3Sopenharmony_ci 765b815c7f3Sopenharmony_ci case 'z' : 766b815c7f3Sopenharmony_ci size = va_arg (argptr, size_t) ; 767b815c7f3Sopenharmony_ci 768b815c7f3Sopenharmony_ci if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size)) 769b815c7f3Sopenharmony_ci break ; 770b815c7f3Sopenharmony_ci 771b815c7f3Sopenharmony_ci count += size ; 772b815c7f3Sopenharmony_ci while (size) 773b815c7f3Sopenharmony_ci { psf->header.ptr [psf->header.indx] = 0 ; 774b815c7f3Sopenharmony_ci psf->header.indx ++ ; 775b815c7f3Sopenharmony_ci size -- ; 776b815c7f3Sopenharmony_ci } ; 777b815c7f3Sopenharmony_ci break ; 778b815c7f3Sopenharmony_ci 779b815c7f3Sopenharmony_ci case 'h' : 780b815c7f3Sopenharmony_ci bindata = va_arg (argptr, void *) ; 781b815c7f3Sopenharmony_ci memcpy (&(psf->header.ptr [psf->header.indx]), bindata, 16) ; 782b815c7f3Sopenharmony_ci psf->header.indx += 16 ; 783b815c7f3Sopenharmony_ci count += 16 ; 784b815c7f3Sopenharmony_ci break ; 785b815c7f3Sopenharmony_ci 786b815c7f3Sopenharmony_ci case 'j' : /* Jump forwards/backwards by specified amount. */ 787b815c7f3Sopenharmony_ci size = va_arg (argptr, size_t) ; 788b815c7f3Sopenharmony_ci 789b815c7f3Sopenharmony_ci if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size)) 790b815c7f3Sopenharmony_ci break ; 791b815c7f3Sopenharmony_ci 792b815c7f3Sopenharmony_ci psf->header.indx += size ; 793b815c7f3Sopenharmony_ci count += size ; 794b815c7f3Sopenharmony_ci break ; 795b815c7f3Sopenharmony_ci 796b815c7f3Sopenharmony_ci case 'o' : /* Jump to specified offset. */ 797b815c7f3Sopenharmony_ci size = va_arg (argptr, size_t) ; 798b815c7f3Sopenharmony_ci 799b815c7f3Sopenharmony_ci if ((sf_count_t) size >= psf->header.len && psf_bump_header_allocation (psf, size)) 800b815c7f3Sopenharmony_ci break ; 801b815c7f3Sopenharmony_ci 802b815c7f3Sopenharmony_ci psf->header.indx = size ; 803b815c7f3Sopenharmony_ci break ; 804b815c7f3Sopenharmony_ci 805b815c7f3Sopenharmony_ci default : 806b815c7f3Sopenharmony_ci psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ; 807b815c7f3Sopenharmony_ci psf->error = SFE_INTERNAL ; 808b815c7f3Sopenharmony_ci break ; 809b815c7f3Sopenharmony_ci } ; 810b815c7f3Sopenharmony_ci } ; 811b815c7f3Sopenharmony_ci 812b815c7f3Sopenharmony_ci va_end (argptr) ; 813b815c7f3Sopenharmony_ci return count ; 814b815c7f3Sopenharmony_ci} /* psf_binheader_writef */ 815b815c7f3Sopenharmony_ci 816b815c7f3Sopenharmony_ci/*----------------------------------------------------------------------------------------------- 817b815c7f3Sopenharmony_ci** Binary header reading functions. Returns number of bytes read. 818b815c7f3Sopenharmony_ci** 819b815c7f3Sopenharmony_ci** Format specifiers are the same as for header write function above with the following 820b815c7f3Sopenharmony_ci** additions: 821b815c7f3Sopenharmony_ci** 822b815c7f3Sopenharmony_ci** p - jump a given number of position from start of file. 823b815c7f3Sopenharmony_ci** 824b815c7f3Sopenharmony_ci** If format is NULL, psf_binheader_readf returns the current offset. 825b815c7f3Sopenharmony_ci*/ 826b815c7f3Sopenharmony_ci 827b815c7f3Sopenharmony_ci#if (CPU_IS_BIG_ENDIAN == 1) 828b815c7f3Sopenharmony_ci#define GET_MARKER(ptr) ( (((uint32_t) (ptr) [0]) << 24) | ((ptr) [1] << 16) | \ 829b815c7f3Sopenharmony_ci ((ptr) [2] << 8) | ((ptr) [3])) 830b815c7f3Sopenharmony_ci 831b815c7f3Sopenharmony_ci#elif (CPU_IS_LITTLE_ENDIAN == 1) 832b815c7f3Sopenharmony_ci#define GET_MARKER(ptr) ( ((ptr) [0]) | ((ptr) [1] << 8) | \ 833b815c7f3Sopenharmony_ci ((ptr) [2] << 16) | (((uint32_t) (ptr) [3]) << 24)) 834b815c7f3Sopenharmony_ci 835b815c7f3Sopenharmony_ci#else 836b815c7f3Sopenharmony_ci# error "Cannot determine endian-ness of processor." 837b815c7f3Sopenharmony_ci#endif 838b815c7f3Sopenharmony_ci 839b815c7f3Sopenharmony_ci#define GET_LE_SHORT(ptr) (((ptr) [1] << 8) | ((ptr) [0])) 840b815c7f3Sopenharmony_ci#define GET_BE_SHORT(ptr) (((ptr) [0] << 8) | ((ptr) [1])) 841b815c7f3Sopenharmony_ci 842b815c7f3Sopenharmony_ci#define GET_LE_3BYTE(ptr) ( ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0])) 843b815c7f3Sopenharmony_ci#define GET_BE_3BYTE(ptr) ( ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2])) 844b815c7f3Sopenharmony_ci 845b815c7f3Sopenharmony_ci#define GET_LE_INT(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \ 846b815c7f3Sopenharmony_ci ((ptr) [1] << 8) | ((ptr) [0])) 847b815c7f3Sopenharmony_ci 848b815c7f3Sopenharmony_ci#define GET_BE_INT(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \ 849b815c7f3Sopenharmony_ci ((ptr) [2] << 8) | ((ptr) [3])) 850b815c7f3Sopenharmony_ci 851b815c7f3Sopenharmony_ci#define GET_LE_8BYTE(ptr) ( (((sf_count_t) (ptr) [7]) << 56) | (((sf_count_t) (ptr) [6]) << 48) | \ 852b815c7f3Sopenharmony_ci (((sf_count_t) (ptr) [5]) << 40) | (((sf_count_t) (ptr) [4]) << 32) | \ 853b815c7f3Sopenharmony_ci (((sf_count_t) (ptr) [3]) << 24) | (((sf_count_t) (ptr) [2]) << 16) | \ 854b815c7f3Sopenharmony_ci (((sf_count_t) (ptr) [1]) << 8) | ((ptr) [0])) 855b815c7f3Sopenharmony_ci 856b815c7f3Sopenharmony_ci#define GET_BE_8BYTE(ptr) ( (((sf_count_t) (ptr) [0]) << 56) | (((sf_count_t) (ptr) [1]) << 48) | \ 857b815c7f3Sopenharmony_ci (((sf_count_t) (ptr) [2]) << 40) | (((sf_count_t) (ptr) [3]) << 32) | \ 858b815c7f3Sopenharmony_ci (((sf_count_t) (ptr) [4]) << 24) | (((sf_count_t) (ptr) [5]) << 16) | \ 859b815c7f3Sopenharmony_ci (((sf_count_t) (ptr) [6]) << 8) | ((ptr) [7])) 860b815c7f3Sopenharmony_ci 861b815c7f3Sopenharmony_ci 862b815c7f3Sopenharmony_ci 863b815c7f3Sopenharmony_cistatic int 864b815c7f3Sopenharmony_ciheader_read (SF_PRIVATE *psf, void *ptr, int bytes) 865b815c7f3Sopenharmony_ci{ int count = 0 ; 866b815c7f3Sopenharmony_ci 867b815c7f3Sopenharmony_ci if (psf->header.indx + bytes >= psf->header.len && psf_bump_header_allocation (psf, bytes)) 868b815c7f3Sopenharmony_ci return count ; 869b815c7f3Sopenharmony_ci 870b815c7f3Sopenharmony_ci if (psf->header.indx + bytes > psf->header.end) 871b815c7f3Sopenharmony_ci { count = psf_fread (psf->header.ptr + psf->header.end, 1, bytes - (psf->header.end - psf->header.indx), psf) ; 872b815c7f3Sopenharmony_ci if (count != bytes - (int) (psf->header.end - psf->header.indx)) 873b815c7f3Sopenharmony_ci { psf_log_printf (psf, "Error : psf_fread returned short count.\n") ; 874b815c7f3Sopenharmony_ci return count ; 875b815c7f3Sopenharmony_ci } ; 876b815c7f3Sopenharmony_ci psf->header.end += count ; 877b815c7f3Sopenharmony_ci } ; 878b815c7f3Sopenharmony_ci 879b815c7f3Sopenharmony_ci memcpy (ptr, psf->header.ptr + psf->header.indx, bytes) ; 880b815c7f3Sopenharmony_ci psf->header.indx += bytes ; 881b815c7f3Sopenharmony_ci 882b815c7f3Sopenharmony_ci return bytes ; 883b815c7f3Sopenharmony_ci} /* header_read */ 884b815c7f3Sopenharmony_ci 885b815c7f3Sopenharmony_cistatic void 886b815c7f3Sopenharmony_ciheader_seek (SF_PRIVATE *psf, sf_count_t position, int whence) 887b815c7f3Sopenharmony_ci{ 888b815c7f3Sopenharmony_ci switch (whence) 889b815c7f3Sopenharmony_ci { case SEEK_SET : 890b815c7f3Sopenharmony_ci if (psf->header.indx + position >= psf->header.len) 891b815c7f3Sopenharmony_ci psf_bump_header_allocation (psf, position) ; 892b815c7f3Sopenharmony_ci if (position > psf->header.len) 893b815c7f3Sopenharmony_ci { /* Too much header to cache so just seek instead. */ 894b815c7f3Sopenharmony_ci psf->header.indx = psf->header.end = 0 ; 895b815c7f3Sopenharmony_ci psf_fseek (psf, position, whence) ; 896b815c7f3Sopenharmony_ci return ; 897b815c7f3Sopenharmony_ci } ; 898b815c7f3Sopenharmony_ci if (position > psf->header.end) 899b815c7f3Sopenharmony_ci psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - psf->header.end, psf) ; 900b815c7f3Sopenharmony_ci psf->header.indx = position ; 901b815c7f3Sopenharmony_ci break ; 902b815c7f3Sopenharmony_ci 903b815c7f3Sopenharmony_ci case SEEK_CUR : 904b815c7f3Sopenharmony_ci if (psf->header.indx + position >= psf->header.len) 905b815c7f3Sopenharmony_ci psf_bump_header_allocation (psf, position) ; 906b815c7f3Sopenharmony_ci 907b815c7f3Sopenharmony_ci if (psf->header.indx + position < 0) 908b815c7f3Sopenharmony_ci break ; 909b815c7f3Sopenharmony_ci 910b815c7f3Sopenharmony_ci if (psf->header.indx >= psf->header.len) 911b815c7f3Sopenharmony_ci { psf_fseek (psf, position, whence) ; 912b815c7f3Sopenharmony_ci return ; 913b815c7f3Sopenharmony_ci } ; 914b815c7f3Sopenharmony_ci 915b815c7f3Sopenharmony_ci if (psf->header.indx + position <= psf->header.end) 916b815c7f3Sopenharmony_ci { psf->header.indx += position ; 917b815c7f3Sopenharmony_ci break ; 918b815c7f3Sopenharmony_ci } ; 919b815c7f3Sopenharmony_ci 920b815c7f3Sopenharmony_ci if (psf->header.indx + position > psf->header.len) 921b815c7f3Sopenharmony_ci { /* Need to jump this without caching it. */ 922b815c7f3Sopenharmony_ci position -= (psf->header.end - psf->header.indx) ; 923b815c7f3Sopenharmony_ci psf->header.indx = psf->header.end ; 924b815c7f3Sopenharmony_ci if (psf->is_pipe) 925b815c7f3Sopenharmony_ci { 926b815c7f3Sopenharmony_ci /* seeking is not supported on pipe input, so we read instead */ 927b815c7f3Sopenharmony_ci size_t skip = position ; 928b815c7f3Sopenharmony_ci while (skip) 929b815c7f3Sopenharmony_ci { char junk [16 * 1024] ; 930b815c7f3Sopenharmony_ci size_t to_skip = SF_MIN (skip, sizeof (junk)) ; 931b815c7f3Sopenharmony_ci psf_fread (junk, 1, to_skip, psf) ; 932b815c7f3Sopenharmony_ci skip -= to_skip ; 933b815c7f3Sopenharmony_ci } 934b815c7f3Sopenharmony_ci } 935b815c7f3Sopenharmony_ci else 936b815c7f3Sopenharmony_ci { psf_fseek (psf, position, SEEK_CUR) ; 937b815c7f3Sopenharmony_ci } 938b815c7f3Sopenharmony_ci break ; 939b815c7f3Sopenharmony_ci } ; 940b815c7f3Sopenharmony_ci 941b815c7f3Sopenharmony_ci psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - (psf->header.end - psf->header.indx), psf) ; 942b815c7f3Sopenharmony_ci psf->header.indx = psf->header.end ; 943b815c7f3Sopenharmony_ci break ; 944b815c7f3Sopenharmony_ci 945b815c7f3Sopenharmony_ci case SEEK_END : 946b815c7f3Sopenharmony_ci default : 947b815c7f3Sopenharmony_ci psf_log_printf (psf, "Bad whence param in header_seek().\n") ; 948b815c7f3Sopenharmony_ci break ; 949b815c7f3Sopenharmony_ci } ; 950b815c7f3Sopenharmony_ci 951b815c7f3Sopenharmony_ci return ; 952b815c7f3Sopenharmony_ci} /* header_seek */ 953b815c7f3Sopenharmony_ci 954b815c7f3Sopenharmony_cistatic int 955b815c7f3Sopenharmony_ciheader_gets (SF_PRIVATE *psf, char *ptr, int bufsize) 956b815c7f3Sopenharmony_ci{ int k ; 957b815c7f3Sopenharmony_ci 958b815c7f3Sopenharmony_ci if (psf->header.indx + bufsize >= psf->header.len && psf_bump_header_allocation (psf, bufsize)) 959b815c7f3Sopenharmony_ci return 0 ; 960b815c7f3Sopenharmony_ci 961b815c7f3Sopenharmony_ci for (k = 0 ; k < bufsize - 1 ; k++) 962b815c7f3Sopenharmony_ci { if (psf->header.indx < psf->header.end) 963b815c7f3Sopenharmony_ci { ptr [k] = psf->header.ptr [psf->header.indx] ; 964b815c7f3Sopenharmony_ci psf->header.indx ++ ; 965b815c7f3Sopenharmony_ci } 966b815c7f3Sopenharmony_ci else 967b815c7f3Sopenharmony_ci { psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, 1, psf) ; 968b815c7f3Sopenharmony_ci ptr [k] = psf->header.ptr [psf->header.indx] ; 969b815c7f3Sopenharmony_ci psf->header.indx = psf->header.end ; 970b815c7f3Sopenharmony_ci } ; 971b815c7f3Sopenharmony_ci 972b815c7f3Sopenharmony_ci if (ptr [k] == '\n') 973b815c7f3Sopenharmony_ci break ; 974b815c7f3Sopenharmony_ci } ; 975b815c7f3Sopenharmony_ci 976b815c7f3Sopenharmony_ci ptr [k] = 0 ; 977b815c7f3Sopenharmony_ci 978b815c7f3Sopenharmony_ci return k ; 979b815c7f3Sopenharmony_ci} /* header_gets */ 980b815c7f3Sopenharmony_ci 981b815c7f3Sopenharmony_ciint 982b815c7f3Sopenharmony_cipsf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) 983b815c7f3Sopenharmony_ci{ va_list argptr ; 984b815c7f3Sopenharmony_ci sf_count_t *countptr, countdata ; 985b815c7f3Sopenharmony_ci unsigned char *ucptr, sixteen_bytes [16] = { 0 } ; 986b815c7f3Sopenharmony_ci unsigned int *intptr, intdata ; 987b815c7f3Sopenharmony_ci unsigned short *shortptr ; 988b815c7f3Sopenharmony_ci char *charptr ; 989b815c7f3Sopenharmony_ci float *floatptr ; 990b815c7f3Sopenharmony_ci double *doubleptr ; 991b815c7f3Sopenharmony_ci char c ; 992b815c7f3Sopenharmony_ci int byte_count = 0, count = 0 ; 993b815c7f3Sopenharmony_ci 994b815c7f3Sopenharmony_ci if (! format) 995b815c7f3Sopenharmony_ci return psf_ftell (psf) ; 996b815c7f3Sopenharmony_ci 997b815c7f3Sopenharmony_ci va_start (argptr, format) ; 998b815c7f3Sopenharmony_ci 999b815c7f3Sopenharmony_ci while ((c = *format++)) 1000b815c7f3Sopenharmony_ci { 1001b815c7f3Sopenharmony_ci if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16)) 1002b815c7f3Sopenharmony_ci break ; 1003b815c7f3Sopenharmony_ci 1004b815c7f3Sopenharmony_ci switch (c) 1005b815c7f3Sopenharmony_ci { case 'e' : /* All conversions are now from LE to host. */ 1006b815c7f3Sopenharmony_ci psf->rwf_endian = SF_ENDIAN_LITTLE ; 1007b815c7f3Sopenharmony_ci break ; 1008b815c7f3Sopenharmony_ci 1009b815c7f3Sopenharmony_ci case 'E' : /* All conversions are now from BE to host. */ 1010b815c7f3Sopenharmony_ci psf->rwf_endian = SF_ENDIAN_BIG ; 1011b815c7f3Sopenharmony_ci break ; 1012b815c7f3Sopenharmony_ci 1013b815c7f3Sopenharmony_ci case 'm' : /* 4 byte marker value eg 'RIFF' */ 1014b815c7f3Sopenharmony_ci intptr = va_arg (argptr, unsigned int*) ; 1015b815c7f3Sopenharmony_ci *intptr = 0 ; 1016b815c7f3Sopenharmony_ci ucptr = (unsigned char*) intptr ; 1017b815c7f3Sopenharmony_ci byte_count += header_read (psf, ucptr, sizeof (int)) ; 1018b815c7f3Sopenharmony_ci *intptr = GET_MARKER (ucptr) ; 1019b815c7f3Sopenharmony_ci break ; 1020b815c7f3Sopenharmony_ci 1021b815c7f3Sopenharmony_ci case 'h' : 1022b815c7f3Sopenharmony_ci intptr = va_arg (argptr, unsigned int*) ; 1023b815c7f3Sopenharmony_ci *intptr = 0 ; 1024b815c7f3Sopenharmony_ci ucptr = (unsigned char*) intptr ; 1025b815c7f3Sopenharmony_ci byte_count += header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ; 1026b815c7f3Sopenharmony_ci { int k ; 1027b815c7f3Sopenharmony_ci intdata = 0 ; 1028b815c7f3Sopenharmony_ci for (k = 0 ; k < 16 ; k++) 1029b815c7f3Sopenharmony_ci intdata ^= sixteen_bytes [k] << k ; 1030b815c7f3Sopenharmony_ci } 1031b815c7f3Sopenharmony_ci *intptr = intdata ; 1032b815c7f3Sopenharmony_ci break ; 1033b815c7f3Sopenharmony_ci 1034b815c7f3Sopenharmony_ci case '1' : 1035b815c7f3Sopenharmony_ci charptr = va_arg (argptr, char*) ; 1036b815c7f3Sopenharmony_ci *charptr = 0 ; 1037b815c7f3Sopenharmony_ci byte_count += header_read (psf, charptr, sizeof (char)) ; 1038b815c7f3Sopenharmony_ci break ; 1039b815c7f3Sopenharmony_ci 1040b815c7f3Sopenharmony_ci case '2' : /* 2 byte value with the current endian-ness */ 1041b815c7f3Sopenharmony_ci shortptr = va_arg (argptr, unsigned short*) ; 1042b815c7f3Sopenharmony_ci *shortptr = 0 ; 1043b815c7f3Sopenharmony_ci ucptr = (unsigned char*) shortptr ; 1044b815c7f3Sopenharmony_ci byte_count += header_read (psf, ucptr, sizeof (short)) ; 1045b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 1046b815c7f3Sopenharmony_ci *shortptr = GET_BE_SHORT (ucptr) ; 1047b815c7f3Sopenharmony_ci else 1048b815c7f3Sopenharmony_ci *shortptr = GET_LE_SHORT (ucptr) ; 1049b815c7f3Sopenharmony_ci break ; 1050b815c7f3Sopenharmony_ci 1051b815c7f3Sopenharmony_ci case '3' : /* 3 byte value with the current endian-ness */ 1052b815c7f3Sopenharmony_ci intptr = va_arg (argptr, unsigned int*) ; 1053b815c7f3Sopenharmony_ci *intptr = 0 ; 1054b815c7f3Sopenharmony_ci byte_count += header_read (psf, sixteen_bytes, 3) ; 1055b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 1056b815c7f3Sopenharmony_ci *intptr = GET_BE_3BYTE (sixteen_bytes) ; 1057b815c7f3Sopenharmony_ci else 1058b815c7f3Sopenharmony_ci *intptr = GET_LE_3BYTE (sixteen_bytes) ; 1059b815c7f3Sopenharmony_ci break ; 1060b815c7f3Sopenharmony_ci 1061b815c7f3Sopenharmony_ci case '4' : /* 4 byte value with the current endian-ness */ 1062b815c7f3Sopenharmony_ci intptr = va_arg (argptr, unsigned int*) ; 1063b815c7f3Sopenharmony_ci *intptr = 0 ; 1064b815c7f3Sopenharmony_ci ucptr = (unsigned char*) intptr ; 1065b815c7f3Sopenharmony_ci byte_count += header_read (psf, ucptr, sizeof (int)) ; 1066b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 1067b815c7f3Sopenharmony_ci *intptr = psf_get_be32 (ucptr, 0) ; 1068b815c7f3Sopenharmony_ci else 1069b815c7f3Sopenharmony_ci *intptr = psf_get_le32 (ucptr, 0) ; 1070b815c7f3Sopenharmony_ci break ; 1071b815c7f3Sopenharmony_ci 1072b815c7f3Sopenharmony_ci case '8' : /* 8 byte value with the current endian-ness */ 1073b815c7f3Sopenharmony_ci countptr = va_arg (argptr, sf_count_t *) ; 1074b815c7f3Sopenharmony_ci *countptr = 0 ; 1075b815c7f3Sopenharmony_ci byte_count += header_read (psf, sixteen_bytes, 8) ; 1076b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 1077b815c7f3Sopenharmony_ci countdata = psf_get_be64 (sixteen_bytes, 0) ; 1078b815c7f3Sopenharmony_ci else 1079b815c7f3Sopenharmony_ci countdata = psf_get_le64 (sixteen_bytes, 0) ; 1080b815c7f3Sopenharmony_ci *countptr = countdata ; 1081b815c7f3Sopenharmony_ci break ; 1082b815c7f3Sopenharmony_ci 1083b815c7f3Sopenharmony_ci case 'f' : /* Float conversion */ 1084b815c7f3Sopenharmony_ci floatptr = va_arg (argptr, float *) ; 1085b815c7f3Sopenharmony_ci *floatptr = 0.0 ; 1086b815c7f3Sopenharmony_ci byte_count += header_read (psf, floatptr, sizeof (float)) ; 1087b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 1088b815c7f3Sopenharmony_ci *floatptr = float32_be_read ((unsigned char*) floatptr) ; 1089b815c7f3Sopenharmony_ci else 1090b815c7f3Sopenharmony_ci *floatptr = float32_le_read ((unsigned char*) floatptr) ; 1091b815c7f3Sopenharmony_ci break ; 1092b815c7f3Sopenharmony_ci 1093b815c7f3Sopenharmony_ci case 'd' : /* double conversion */ 1094b815c7f3Sopenharmony_ci doubleptr = va_arg (argptr, double *) ; 1095b815c7f3Sopenharmony_ci *doubleptr = 0.0 ; 1096b815c7f3Sopenharmony_ci byte_count += header_read (psf, doubleptr, sizeof (double)) ; 1097b815c7f3Sopenharmony_ci if (psf->rwf_endian == SF_ENDIAN_BIG) 1098b815c7f3Sopenharmony_ci *doubleptr = double64_be_read ((unsigned char*) doubleptr) ; 1099b815c7f3Sopenharmony_ci else 1100b815c7f3Sopenharmony_ci *doubleptr = double64_le_read ((unsigned char*) doubleptr) ; 1101b815c7f3Sopenharmony_ci break ; 1102b815c7f3Sopenharmony_ci 1103b815c7f3Sopenharmony_ci case 's' : 1104b815c7f3Sopenharmony_ci psf_log_printf (psf, "Format conversion 's' not implemented yet.\n") ; 1105b815c7f3Sopenharmony_ci /* 1106b815c7f3Sopenharmony_ci strptr = va_arg (argptr, char *) ; 1107b815c7f3Sopenharmony_ci size = strlen (strptr) + 1 ; 1108b815c7f3Sopenharmony_ci size += (size & 1) ; 1109b815c7f3Sopenharmony_ci longdata = H2LE_32 (size) ; 1110b815c7f3Sopenharmony_ci get_int (psf, longdata) ; 1111b815c7f3Sopenharmony_ci memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ; 1112b815c7f3Sopenharmony_ci psf->header.indx += size ; 1113b815c7f3Sopenharmony_ci */ 1114b815c7f3Sopenharmony_ci break ; 1115b815c7f3Sopenharmony_ci 1116b815c7f3Sopenharmony_ci case 'b' : /* Raw bytes */ 1117b815c7f3Sopenharmony_ci charptr = va_arg (argptr, char*) ; 1118b815c7f3Sopenharmony_ci count = va_arg (argptr, size_t) ; 1119b815c7f3Sopenharmony_ci memset (charptr, 0, count) ; 1120b815c7f3Sopenharmony_ci byte_count += header_read (psf, charptr, count) ; 1121b815c7f3Sopenharmony_ci break ; 1122b815c7f3Sopenharmony_ci 1123b815c7f3Sopenharmony_ci case 'G' : 1124b815c7f3Sopenharmony_ci charptr = va_arg (argptr, char*) ; 1125b815c7f3Sopenharmony_ci count = va_arg (argptr, size_t) ; 1126b815c7f3Sopenharmony_ci memset (charptr, 0, count) ; 1127b815c7f3Sopenharmony_ci 1128b815c7f3Sopenharmony_ci if (psf->header.indx + count >= psf->header.len && psf_bump_header_allocation (psf, count)) 1129b815c7f3Sopenharmony_ci break ; 1130b815c7f3Sopenharmony_ci 1131b815c7f3Sopenharmony_ci byte_count += header_gets (psf, charptr, count) ; 1132b815c7f3Sopenharmony_ci break ; 1133b815c7f3Sopenharmony_ci 1134b815c7f3Sopenharmony_ci case 'z' : 1135b815c7f3Sopenharmony_ci psf_log_printf (psf, "Format conversion 'z' not implemented yet.\n") ; 1136b815c7f3Sopenharmony_ci /* 1137b815c7f3Sopenharmony_ci size = va_arg (argptr, size_t) ; 1138b815c7f3Sopenharmony_ci while (size) 1139b815c7f3Sopenharmony_ci { psf->header.ptr [psf->header.indx] = 0 ; 1140b815c7f3Sopenharmony_ci psf->header.indx ++ ; 1141b815c7f3Sopenharmony_ci size -- ; 1142b815c7f3Sopenharmony_ci } ; 1143b815c7f3Sopenharmony_ci */ 1144b815c7f3Sopenharmony_ci break ; 1145b815c7f3Sopenharmony_ci 1146b815c7f3Sopenharmony_ci case 'p' : /* Seek to position from start. */ 1147b815c7f3Sopenharmony_ci count = va_arg (argptr, size_t) ; 1148b815c7f3Sopenharmony_ci header_seek (psf, count, SEEK_SET) ; 1149b815c7f3Sopenharmony_ci byte_count = count ; 1150b815c7f3Sopenharmony_ci break ; 1151b815c7f3Sopenharmony_ci 1152b815c7f3Sopenharmony_ci case 'j' : /* Seek to position from current position. */ 1153b815c7f3Sopenharmony_ci count = va_arg (argptr, size_t) ; 1154b815c7f3Sopenharmony_ci header_seek (psf, count, SEEK_CUR) ; 1155b815c7f3Sopenharmony_ci byte_count += count ; 1156b815c7f3Sopenharmony_ci break ; 1157b815c7f3Sopenharmony_ci 1158b815c7f3Sopenharmony_ci case '!' : /* Clear buffer, forcing re-read. */ 1159b815c7f3Sopenharmony_ci psf->header.end = psf->header.indx = 0 ; 1160b815c7f3Sopenharmony_ci break ; 1161b815c7f3Sopenharmony_ci 1162b815c7f3Sopenharmony_ci default : 1163b815c7f3Sopenharmony_ci psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ; 1164b815c7f3Sopenharmony_ci psf->error = SFE_INTERNAL ; 1165b815c7f3Sopenharmony_ci break ; 1166b815c7f3Sopenharmony_ci } ; 1167b815c7f3Sopenharmony_ci } ; 1168b815c7f3Sopenharmony_ci 1169b815c7f3Sopenharmony_ci va_end (argptr) ; 1170b815c7f3Sopenharmony_ci 1171b815c7f3Sopenharmony_ci return byte_count ; 1172b815c7f3Sopenharmony_ci} /* psf_binheader_readf */ 1173b815c7f3Sopenharmony_ci 1174b815c7f3Sopenharmony_ci/*----------------------------------------------------------------------------------------------- 1175b815c7f3Sopenharmony_ci*/ 1176b815c7f3Sopenharmony_ci 1177b815c7f3Sopenharmony_cisf_count_t 1178b815c7f3Sopenharmony_cipsf_default_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t samples_from_start) 1179b815c7f3Sopenharmony_ci{ sf_count_t position, retval ; 1180b815c7f3Sopenharmony_ci 1181b815c7f3Sopenharmony_ci if (! (psf->blockwidth && psf->dataoffset >= 0)) 1182b815c7f3Sopenharmony_ci { psf->error = SFE_BAD_SEEK ; 1183b815c7f3Sopenharmony_ci return PSF_SEEK_ERROR ; 1184b815c7f3Sopenharmony_ci } ; 1185b815c7f3Sopenharmony_ci 1186b815c7f3Sopenharmony_ci if (! psf->sf.seekable) 1187b815c7f3Sopenharmony_ci { psf->error = SFE_NOT_SEEKABLE ; 1188b815c7f3Sopenharmony_ci return PSF_SEEK_ERROR ; 1189b815c7f3Sopenharmony_ci } ; 1190b815c7f3Sopenharmony_ci 1191b815c7f3Sopenharmony_ci position = psf->dataoffset + psf->blockwidth * samples_from_start ; 1192b815c7f3Sopenharmony_ci 1193b815c7f3Sopenharmony_ci if ((retval = psf_fseek (psf, position, SEEK_SET)) != position) 1194b815c7f3Sopenharmony_ci { psf->error = SFE_SEEK_FAILED ; 1195b815c7f3Sopenharmony_ci return PSF_SEEK_ERROR ; 1196b815c7f3Sopenharmony_ci } ; 1197b815c7f3Sopenharmony_ci 1198b815c7f3Sopenharmony_ci return samples_from_start ; 1199b815c7f3Sopenharmony_ci} /* psf_default_seek */ 1200b815c7f3Sopenharmony_ci 1201b815c7f3Sopenharmony_ci/*----------------------------------------------------------------------------------------------- 1202b815c7f3Sopenharmony_ci*/ 1203b815c7f3Sopenharmony_ci 1204b815c7f3Sopenharmony_civoid 1205b815c7f3Sopenharmony_cipsf_hexdump (const void *ptr, int len) 1206b815c7f3Sopenharmony_ci{ const char *data ; 1207b815c7f3Sopenharmony_ci char ascii [17] ; 1208b815c7f3Sopenharmony_ci int k, m ; 1209b815c7f3Sopenharmony_ci 1210b815c7f3Sopenharmony_ci if ((data = ptr) == NULL) 1211b815c7f3Sopenharmony_ci return ; 1212b815c7f3Sopenharmony_ci if (len <= 0) 1213b815c7f3Sopenharmony_ci return ; 1214b815c7f3Sopenharmony_ci 1215b815c7f3Sopenharmony_ci puts ("") ; 1216b815c7f3Sopenharmony_ci for (k = 0 ; k < len ; k += 16) 1217b815c7f3Sopenharmony_ci { memset (ascii, ' ', sizeof (ascii)) ; 1218b815c7f3Sopenharmony_ci 1219b815c7f3Sopenharmony_ci printf ("%08X: ", k) ; 1220b815c7f3Sopenharmony_ci for (m = 0 ; m < 16 && k + m < len ; m++) 1221b815c7f3Sopenharmony_ci { printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ; 1222b815c7f3Sopenharmony_ci ascii [m] = psf_isprint (data [k + m]) ? data [k + m] : '.' ; 1223b815c7f3Sopenharmony_ci } ; 1224b815c7f3Sopenharmony_ci 1225b815c7f3Sopenharmony_ci if (m <= 8) printf (" ") ; 1226b815c7f3Sopenharmony_ci for ( ; m < 16 ; m++) printf (" ") ; 1227b815c7f3Sopenharmony_ci 1228b815c7f3Sopenharmony_ci ascii [16] = 0 ; 1229b815c7f3Sopenharmony_ci printf (" %s\n", ascii) ; 1230b815c7f3Sopenharmony_ci } ; 1231b815c7f3Sopenharmony_ci 1232b815c7f3Sopenharmony_ci puts ("") ; 1233b815c7f3Sopenharmony_ci} /* psf_hexdump */ 1234b815c7f3Sopenharmony_ci 1235b815c7f3Sopenharmony_civoid 1236b815c7f3Sopenharmony_cipsf_log_SF_INFO (SF_PRIVATE *psf) 1237b815c7f3Sopenharmony_ci{ psf_log_printf (psf, "---------------------------------\n") ; 1238b815c7f3Sopenharmony_ci 1239b815c7f3Sopenharmony_ci psf_log_printf (psf, " Sample rate : %d\n", psf->sf.samplerate) ; 1240b815c7f3Sopenharmony_ci if (psf->sf.frames == SF_COUNT_MAX) 1241b815c7f3Sopenharmony_ci psf_log_printf (psf, " Frames : unknown\n") ; 1242b815c7f3Sopenharmony_ci else 1243b815c7f3Sopenharmony_ci psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ; 1244b815c7f3Sopenharmony_ci psf_log_printf (psf, " Channels : %d\n", psf->sf.channels) ; 1245b815c7f3Sopenharmony_ci 1246b815c7f3Sopenharmony_ci psf_log_printf (psf, " Format : 0x%X\n", psf->sf.format) ; 1247b815c7f3Sopenharmony_ci psf_log_printf (psf, " Sections : %d\n", psf->sf.sections) ; 1248b815c7f3Sopenharmony_ci psf_log_printf (psf, " Seekable : %s\n", psf->sf.seekable ? "TRUE" : "FALSE") ; 1249b815c7f3Sopenharmony_ci 1250b815c7f3Sopenharmony_ci psf_log_printf (psf, "---------------------------------\n") ; 1251b815c7f3Sopenharmony_ci} /* psf_dump_SFINFO */ 1252b815c7f3Sopenharmony_ci 1253b815c7f3Sopenharmony_ci/*======================================================================================== 1254b815c7f3Sopenharmony_ci*/ 1255b815c7f3Sopenharmony_ci 1256b815c7f3Sopenharmony_ciint 1257b815c7f3Sopenharmony_cipsf_isprint (int ch) 1258b815c7f3Sopenharmony_ci{ return (ch >= ' ' && ch <= '~') ; 1259b815c7f3Sopenharmony_ci} /* psf_isprint */ 1260b815c7f3Sopenharmony_ci 1261b815c7f3Sopenharmony_civoid 1262b815c7f3Sopenharmony_cipsf_strlcat (char *dest, size_t n, const char *src) 1263b815c7f3Sopenharmony_ci{ strncat (dest, src, n - strlen (dest) - 1) ; 1264b815c7f3Sopenharmony_ci dest [n - 1] = 0 ; 1265b815c7f3Sopenharmony_ci} /* psf_strlcat */ 1266b815c7f3Sopenharmony_ci 1267b815c7f3Sopenharmony_civoid 1268b815c7f3Sopenharmony_cipsf_strlcpy (char *dest, size_t n, const char *src) 1269b815c7f3Sopenharmony_ci{ strncpy (dest, src, n - 1) ; 1270b815c7f3Sopenharmony_ci dest [n - 1] = 0 ; 1271b815c7f3Sopenharmony_ci} /* psf_strlcpy */ 1272b815c7f3Sopenharmony_ci 1273b815c7f3Sopenharmony_ci/*======================================================================================== 1274b815c7f3Sopenharmony_ci*/ 1275b815c7f3Sopenharmony_ci 1276b815c7f3Sopenharmony_civoid * 1277b815c7f3Sopenharmony_cipsf_memdup (const void *src, size_t n) 1278b815c7f3Sopenharmony_ci{ if (src == NULL) 1279b815c7f3Sopenharmony_ci return NULL ; 1280b815c7f3Sopenharmony_ci 1281b815c7f3Sopenharmony_ci void * mem = calloc (1, n & 3 ? n + 4 - (n & 3) : n) ; 1282b815c7f3Sopenharmony_ci if (mem != NULL) 1283b815c7f3Sopenharmony_ci memcpy (mem, src, n) ; 1284b815c7f3Sopenharmony_ci return mem ; 1285b815c7f3Sopenharmony_ci} /* psf_memdup */ 1286b815c7f3Sopenharmony_ci 1287b815c7f3Sopenharmony_civoid* 1288b815c7f3Sopenharmony_cipsf_memset (void *s, int c, sf_count_t len) 1289b815c7f3Sopenharmony_ci{ char *ptr ; 1290b815c7f3Sopenharmony_ci int setcount ; 1291b815c7f3Sopenharmony_ci 1292b815c7f3Sopenharmony_ci ptr = (char *) s ; 1293b815c7f3Sopenharmony_ci 1294b815c7f3Sopenharmony_ci while (len > 0) 1295b815c7f3Sopenharmony_ci { setcount = (len > 0x10000000) ? 0x10000000 : (int) len ; 1296b815c7f3Sopenharmony_ci 1297b815c7f3Sopenharmony_ci memset (ptr, c, setcount) ; 1298b815c7f3Sopenharmony_ci 1299b815c7f3Sopenharmony_ci ptr += setcount ; 1300b815c7f3Sopenharmony_ci len -= setcount ; 1301b815c7f3Sopenharmony_ci } ; 1302b815c7f3Sopenharmony_ci 1303b815c7f3Sopenharmony_ci return s ; 1304b815c7f3Sopenharmony_ci} /* psf_memset */ 1305b815c7f3Sopenharmony_ci 1306b815c7f3Sopenharmony_ci 1307b815c7f3Sopenharmony_ci/* 1308b815c7f3Sopenharmony_ci** Clang refuses to do sizeof (SF_CUES_VAR (cue_count)) so we have to manually 1309b815c7f3Sopenharmony_ci** bodgy something up instead. 1310b815c7f3Sopenharmony_ci*/ 1311b815c7f3Sopenharmony_ci 1312b815c7f3Sopenharmony_ci#ifdef _MSC_VER 1313b815c7f3Sopenharmony_citypedef SF_CUES_VAR (0) SF_CUES_0 ; 1314b815c7f3Sopenharmony_ci#else 1315b815c7f3Sopenharmony_citypedef SF_CUES_VAR () SF_CUES_0 ; 1316b815c7f3Sopenharmony_ci#endif 1317b815c7f3Sopenharmony_ci 1318b815c7f3Sopenharmony_ci/* calculate size of SF_CUES struct given number of cues */ 1319b815c7f3Sopenharmony_ci#define SF_CUES_VAR_SIZE(count) (sizeof (SF_CUES_0) + count * sizeof (SF_CUE_POINT)) 1320b815c7f3Sopenharmony_ci 1321b815c7f3Sopenharmony_ci/* calculate number of cues in SF_CUES struct given data size */ 1322b815c7f3Sopenharmony_ci#define SF_CUES_COUNT(datasize) (((datasize) - sizeof (uint32_t)) / sizeof (SF_CUE_POINT)) 1323b815c7f3Sopenharmony_ci 1324b815c7f3Sopenharmony_ciSF_CUES * 1325b815c7f3Sopenharmony_cipsf_cues_alloc (uint32_t cue_count) 1326b815c7f3Sopenharmony_ci{ SF_CUES *pcues = calloc (1, SF_CUES_VAR_SIZE (cue_count)) ; 1327b815c7f3Sopenharmony_ci if (pcues) 1328b815c7f3Sopenharmony_ci { pcues->cue_count = cue_count ; 1329b815c7f3Sopenharmony_ci } ; 1330b815c7f3Sopenharmony_ci return pcues ; 1331b815c7f3Sopenharmony_ci} /* psf_cues_alloc */ 1332b815c7f3Sopenharmony_ci 1333b815c7f3Sopenharmony_ciSF_CUES * 1334b815c7f3Sopenharmony_cipsf_cues_dup (const void * ptr, size_t datasize) 1335b815c7f3Sopenharmony_ci{ const SF_CUES *pcues = ptr ; 1336b815c7f3Sopenharmony_ci SF_CUES *pnew = NULL ; 1337b815c7f3Sopenharmony_ci 1338b815c7f3Sopenharmony_ci if (pcues->cue_count <= SF_CUES_COUNT (datasize)) 1339b815c7f3Sopenharmony_ci { /* check that passed-in datasize is consistent with cue_count in passed-in SF_CUES struct */ 1340b815c7f3Sopenharmony_ci pnew = psf_cues_alloc (pcues->cue_count) ; 1341b815c7f3Sopenharmony_ci memcpy (pnew, pcues, SF_CUES_VAR_SIZE (pcues->cue_count)) ; 1342b815c7f3Sopenharmony_ci } 1343b815c7f3Sopenharmony_ci 1344b815c7f3Sopenharmony_ci return pnew ; 1345b815c7f3Sopenharmony_ci} /* psf_cues_dup */ 1346b815c7f3Sopenharmony_ci 1347b815c7f3Sopenharmony_civoid 1348b815c7f3Sopenharmony_cipsf_get_cues (SF_PRIVATE * psf, void * data, size_t datasize) 1349b815c7f3Sopenharmony_ci{ 1350b815c7f3Sopenharmony_ci if (psf->cues) 1351b815c7f3Sopenharmony_ci { uint32_t cue_count = SF_CUES_COUNT (datasize) ; 1352b815c7f3Sopenharmony_ci 1353b815c7f3Sopenharmony_ci cue_count = SF_MIN (cue_count, psf->cues->cue_count) ; 1354b815c7f3Sopenharmony_ci memcpy (data, psf->cues, SF_CUES_VAR_SIZE (cue_count)) ; 1355b815c7f3Sopenharmony_ci ((SF_CUES*) data)->cue_count = cue_count ; 1356b815c7f3Sopenharmony_ci } ; 1357b815c7f3Sopenharmony_ci 1358b815c7f3Sopenharmony_ci return ; 1359b815c7f3Sopenharmony_ci} /* psf_get_cues */ 1360b815c7f3Sopenharmony_ci 1361b815c7f3Sopenharmony_ci 1362b815c7f3Sopenharmony_ciSF_INSTRUMENT * 1363b815c7f3Sopenharmony_cipsf_instrument_alloc (void) 1364b815c7f3Sopenharmony_ci{ SF_INSTRUMENT *instr ; 1365b815c7f3Sopenharmony_ci 1366b815c7f3Sopenharmony_ci instr = calloc (1, sizeof (SF_INSTRUMENT)) ; 1367b815c7f3Sopenharmony_ci 1368b815c7f3Sopenharmony_ci if (instr == NULL) 1369b815c7f3Sopenharmony_ci return NULL ; 1370b815c7f3Sopenharmony_ci 1371b815c7f3Sopenharmony_ci /* Set non-zero default values. */ 1372b815c7f3Sopenharmony_ci instr->basenote = -1 ; 1373b815c7f3Sopenharmony_ci instr->velocity_lo = -1 ; 1374b815c7f3Sopenharmony_ci instr->velocity_hi = -1 ; 1375b815c7f3Sopenharmony_ci instr->key_lo = -1 ; 1376b815c7f3Sopenharmony_ci instr->key_hi = -1 ; 1377b815c7f3Sopenharmony_ci 1378b815c7f3Sopenharmony_ci return instr ; 1379b815c7f3Sopenharmony_ci} /* psf_instrument_alloc */ 1380b815c7f3Sopenharmony_ci 1381b815c7f3Sopenharmony_civoid 1382b815c7f3Sopenharmony_cipsf_sanitize_string (char * cptr, int len) 1383b815c7f3Sopenharmony_ci{ 1384b815c7f3Sopenharmony_ci do 1385b815c7f3Sopenharmony_ci { 1386b815c7f3Sopenharmony_ci len -- ; 1387b815c7f3Sopenharmony_ci cptr [len] = psf_isprint (cptr [len]) ? cptr [len] : '.' ; 1388b815c7f3Sopenharmony_ci } 1389b815c7f3Sopenharmony_ci while (len > 0) ; 1390b815c7f3Sopenharmony_ci} /* psf_sanitize_string */ 1391b815c7f3Sopenharmony_ci 1392b815c7f3Sopenharmony_civoid 1393b815c7f3Sopenharmony_cipsf_get_date_str (char *str, int maxlen) 1394b815c7f3Sopenharmony_ci{ time_t current ; 1395b815c7f3Sopenharmony_ci struct tm timedata, *tmptr ; 1396b815c7f3Sopenharmony_ci 1397b815c7f3Sopenharmony_ci time (¤t) ; 1398b815c7f3Sopenharmony_ci 1399b815c7f3Sopenharmony_ci#if defined (HAVE_GMTIME_R) 1400b815c7f3Sopenharmony_ci /* If the re-entrant version is available, use it. */ 1401b815c7f3Sopenharmony_ci tmptr = gmtime_r (¤t, &timedata) ; 1402b815c7f3Sopenharmony_ci#elif defined (HAVE_GMTIME) 1403b815c7f3Sopenharmony_ci /* Otherwise use the standard one and copy the data to local storage. */ 1404b815c7f3Sopenharmony_ci tmptr = gmtime (¤t) ; 1405b815c7f3Sopenharmony_ci memcpy (&timedata, tmptr, sizeof (timedata)) ; 1406b815c7f3Sopenharmony_ci#else 1407b815c7f3Sopenharmony_ci tmptr = NULL ; 1408b815c7f3Sopenharmony_ci#endif 1409b815c7f3Sopenharmony_ci 1410b815c7f3Sopenharmony_ci if (tmptr) 1411b815c7f3Sopenharmony_ci snprintf (str, maxlen, "%4d-%02d-%02d %02d:%02d:%02d UTC", 1412b815c7f3Sopenharmony_ci 1900 + timedata.tm_year, timedata.tm_mon, timedata.tm_mday, 1413b815c7f3Sopenharmony_ci timedata.tm_hour, timedata.tm_min, timedata.tm_sec) ; 1414b815c7f3Sopenharmony_ci else 1415b815c7f3Sopenharmony_ci snprintf (str, maxlen, "Unknown date") ; 1416b815c7f3Sopenharmony_ci 1417b815c7f3Sopenharmony_ci return ; 1418b815c7f3Sopenharmony_ci} /* psf_get_date_str */ 1419b815c7f3Sopenharmony_ci 1420b815c7f3Sopenharmony_ciint 1421b815c7f3Sopenharmony_cisubformat_to_bytewidth (int format) 1422b815c7f3Sopenharmony_ci{ 1423b815c7f3Sopenharmony_ci switch (format) 1424b815c7f3Sopenharmony_ci { case SF_FORMAT_PCM_U8 : 1425b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_S8 : 1426b815c7f3Sopenharmony_ci return 1 ; 1427b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_16 : 1428b815c7f3Sopenharmony_ci return 2 ; 1429b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_24 : 1430b815c7f3Sopenharmony_ci return 3 ; 1431b815c7f3Sopenharmony_ci case SF_FORMAT_PCM_32 : 1432b815c7f3Sopenharmony_ci case SF_FORMAT_FLOAT : 1433b815c7f3Sopenharmony_ci return 4 ; 1434b815c7f3Sopenharmony_ci case SF_FORMAT_DOUBLE : 1435b815c7f3Sopenharmony_ci return 8 ; 1436b815c7f3Sopenharmony_ci } ; 1437b815c7f3Sopenharmony_ci 1438b815c7f3Sopenharmony_ci return 0 ; 1439b815c7f3Sopenharmony_ci} /* subformat_to_bytewidth */ 1440b815c7f3Sopenharmony_ci 1441b815c7f3Sopenharmony_ciint 1442b815c7f3Sopenharmony_cis_bitwidth_to_subformat (int bits) 1443b815c7f3Sopenharmony_ci{ static int array [] = 1444b815c7f3Sopenharmony_ci { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32 1445b815c7f3Sopenharmony_ci } ; 1446b815c7f3Sopenharmony_ci 1447b815c7f3Sopenharmony_ci if (bits < 8 || bits > 32) 1448b815c7f3Sopenharmony_ci return 0 ; 1449b815c7f3Sopenharmony_ci 1450b815c7f3Sopenharmony_ci return array [((bits + 7) / 8) - 1] ; 1451b815c7f3Sopenharmony_ci} /* bitwidth_to_subformat */ 1452b815c7f3Sopenharmony_ci 1453b815c7f3Sopenharmony_ciint 1454b815c7f3Sopenharmony_ciu_bitwidth_to_subformat (int bits) 1455b815c7f3Sopenharmony_ci{ static int array [] = 1456b815c7f3Sopenharmony_ci { SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32 1457b815c7f3Sopenharmony_ci } ; 1458b815c7f3Sopenharmony_ci 1459b815c7f3Sopenharmony_ci if (bits < 8 || bits > 32) 1460b815c7f3Sopenharmony_ci return 0 ; 1461b815c7f3Sopenharmony_ci 1462b815c7f3Sopenharmony_ci return array [((bits + 7) / 8) - 1] ; 1463b815c7f3Sopenharmony_ci} /* bitwidth_to_subformat */ 1464b815c7f3Sopenharmony_ci 1465b815c7f3Sopenharmony_ci/* 1466b815c7f3Sopenharmony_ci** psf_rand_int32 : Not crypto quality, but more than adequate for things 1467b815c7f3Sopenharmony_ci** like stream serial numbers in Ogg files or the unique_id field of the 1468b815c7f3Sopenharmony_ci** SF_PRIVATE struct. 1469b815c7f3Sopenharmony_ci*/ 1470b815c7f3Sopenharmony_ci 1471b815c7f3Sopenharmony_ciint32_t 1472b815c7f3Sopenharmony_cipsf_rand_int32 (void) 1473b815c7f3Sopenharmony_ci{ static uint64_t value = 0 ; 1474b815c7f3Sopenharmony_ci int k, count ; 1475b815c7f3Sopenharmony_ci 1476b815c7f3Sopenharmony_ci if (value == 0) 1477b815c7f3Sopenharmony_ci { 1478b815c7f3Sopenharmony_ci#if HAVE_GETTIMEOFDAY 1479b815c7f3Sopenharmony_ci struct timeval tv ; 1480b815c7f3Sopenharmony_ci gettimeofday (&tv, NULL) ; 1481b815c7f3Sopenharmony_ci value = tv.tv_sec + tv.tv_usec ; 1482b815c7f3Sopenharmony_ci#else 1483b815c7f3Sopenharmony_ci value = time (NULL) ; 1484b815c7f3Sopenharmony_ci#endif 1485b815c7f3Sopenharmony_ci } ; 1486b815c7f3Sopenharmony_ci 1487b815c7f3Sopenharmony_ci count = 4 + (value & 7) ; 1488b815c7f3Sopenharmony_ci for (k = 0 ; k < count ; k++) 1489b815c7f3Sopenharmony_ci value = (11117 * value + 211231) & 0x7fffffff ; 1490b815c7f3Sopenharmony_ci 1491b815c7f3Sopenharmony_ci return (int32_t) value ; 1492b815c7f3Sopenharmony_ci} /* psf_rand_int32 */ 1493b815c7f3Sopenharmony_ci 1494b815c7f3Sopenharmony_civoid 1495b815c7f3Sopenharmony_ciappend_snprintf (char * dest, size_t maxlen, const char * fmt, ...) 1496b815c7f3Sopenharmony_ci{ size_t len = strlen (dest) ; 1497b815c7f3Sopenharmony_ci 1498b815c7f3Sopenharmony_ci if (len < maxlen) 1499b815c7f3Sopenharmony_ci { va_list ap ; 1500b815c7f3Sopenharmony_ci 1501b815c7f3Sopenharmony_ci va_start (ap, fmt) ; 1502b815c7f3Sopenharmony_ci vsnprintf (dest + len, maxlen - len, fmt, ap) ; 1503b815c7f3Sopenharmony_ci va_end (ap) ; 1504b815c7f3Sopenharmony_ci } ; 1505b815c7f3Sopenharmony_ci 1506b815c7f3Sopenharmony_ci return ; 1507b815c7f3Sopenharmony_ci} /* append_snprintf */ 1508b815c7f3Sopenharmony_ci 1509b815c7f3Sopenharmony_ci 1510b815c7f3Sopenharmony_civoid 1511b815c7f3Sopenharmony_cipsf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax) 1512b815c7f3Sopenharmony_ci{ /* Must be minus 2 so it can still expand a single trailing '\n' or '\r'. */ 1513b815c7f3Sopenharmony_ci char * destend = dest + destmax - 2 ; 1514b815c7f3Sopenharmony_ci const char * srcend = src + srcmax ; 1515b815c7f3Sopenharmony_ci 1516b815c7f3Sopenharmony_ci while (dest < destend && src < srcend) 1517b815c7f3Sopenharmony_ci { if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r')) 1518b815c7f3Sopenharmony_ci { *dest++ = '\r' ; 1519b815c7f3Sopenharmony_ci *dest++ = '\n' ; 1520b815c7f3Sopenharmony_ci src += 2 ; 1521b815c7f3Sopenharmony_ci continue ; 1522b815c7f3Sopenharmony_ci } ; 1523b815c7f3Sopenharmony_ci 1524b815c7f3Sopenharmony_ci if (src [0] == '\r') 1525b815c7f3Sopenharmony_ci { *dest++ = '\r' ; 1526b815c7f3Sopenharmony_ci *dest++ = '\n' ; 1527b815c7f3Sopenharmony_ci src += 1 ; 1528b815c7f3Sopenharmony_ci continue ; 1529b815c7f3Sopenharmony_ci } ; 1530b815c7f3Sopenharmony_ci 1531b815c7f3Sopenharmony_ci if (src [0] == '\n') 1532b815c7f3Sopenharmony_ci { *dest++ = '\r' ; 1533b815c7f3Sopenharmony_ci *dest++ = '\n' ; 1534b815c7f3Sopenharmony_ci src += 1 ; 1535b815c7f3Sopenharmony_ci continue ; 1536b815c7f3Sopenharmony_ci } ; 1537b815c7f3Sopenharmony_ci 1538b815c7f3Sopenharmony_ci *dest++ = *src++ ; 1539b815c7f3Sopenharmony_ci } ; 1540b815c7f3Sopenharmony_ci 1541b815c7f3Sopenharmony_ci /* Make sure dest is terminated. */ 1542b815c7f3Sopenharmony_ci *dest = 0 ; 1543b815c7f3Sopenharmony_ci} /* psf_strlcpy_crlf */ 1544b815c7f3Sopenharmony_ci 1545b815c7f3Sopenharmony_cisf_count_t 1546b815c7f3Sopenharmony_cipsf_decode_frame_count (SF_PRIVATE *psf) 1547b815c7f3Sopenharmony_ci{ sf_count_t count, readlen, total = 0 ; 1548b815c7f3Sopenharmony_ci BUF_UNION ubuf ; 1549b815c7f3Sopenharmony_ci 1550b815c7f3Sopenharmony_ci /* If we're reading from a pipe or the file is too long, just return SF_COUNT_MAX. */ 1551b815c7f3Sopenharmony_ci if (psf_is_pipe (psf) || psf->datalength > 0x1000000) 1552b815c7f3Sopenharmony_ci return SF_COUNT_MAX ; 1553b815c7f3Sopenharmony_ci 1554b815c7f3Sopenharmony_ci psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 1555b815c7f3Sopenharmony_ci 1556b815c7f3Sopenharmony_ci readlen = ARRAY_LEN (ubuf.ibuf) / psf->sf.channels ; 1557b815c7f3Sopenharmony_ci readlen *= psf->sf.channels ; 1558b815c7f3Sopenharmony_ci 1559b815c7f3Sopenharmony_ci while ((count = psf->read_int (psf, ubuf.ibuf, readlen)) > 0) 1560b815c7f3Sopenharmony_ci total += count ; 1561b815c7f3Sopenharmony_ci 1562b815c7f3Sopenharmony_ci psf_fseek (psf, psf->dataoffset, SEEK_SET) ; 1563b815c7f3Sopenharmony_ci 1564b815c7f3Sopenharmony_ci return total / psf->sf.channels ; 1565b815c7f3Sopenharmony_ci} /* psf_decode_frame_count */ 1566b815c7f3Sopenharmony_ci 1567b815c7f3Sopenharmony_ci/*============================================================================== 1568b815c7f3Sopenharmony_ci*/ 1569b815c7f3Sopenharmony_ci 1570b815c7f3Sopenharmony_ci#define CASE_NAME(x) case x : return #x ; break ; 1571b815c7f3Sopenharmony_ci 1572b815c7f3Sopenharmony_ciconst char * 1573b815c7f3Sopenharmony_cistr_of_major_format (int format) 1574b815c7f3Sopenharmony_ci{ switch (SF_CONTAINER (format)) 1575b815c7f3Sopenharmony_ci { CASE_NAME (SF_FORMAT_WAV) ; 1576b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_AIFF) ; 1577b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_AU) ; 1578b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_RAW) ; 1579b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_PAF) ; 1580b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_SVX) ; 1581b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_NIST) ; 1582b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_VOC) ; 1583b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_IRCAM) ; 1584b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_W64) ; 1585b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_MAT4) ; 1586b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_MAT5) ; 1587b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_PVF) ; 1588b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_XI) ; 1589b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_HTK) ; 1590b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_SDS) ; 1591b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_AVR) ; 1592b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_WAVEX) ; 1593b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_SD2) ; 1594b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_FLAC) ; 1595b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_CAF) ; 1596b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_WVE) ; 1597b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_OGG) ; 1598b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_MPEG) ; 1599b815c7f3Sopenharmony_ci default : 1600b815c7f3Sopenharmony_ci break ; 1601b815c7f3Sopenharmony_ci } ; 1602b815c7f3Sopenharmony_ci 1603b815c7f3Sopenharmony_ci return "BAD_MAJOR_FORMAT" ; 1604b815c7f3Sopenharmony_ci} /* str_of_major_format */ 1605b815c7f3Sopenharmony_ci 1606b815c7f3Sopenharmony_ciconst char * 1607b815c7f3Sopenharmony_cistr_of_minor_format (int format) 1608b815c7f3Sopenharmony_ci{ switch (SF_CODEC (format)) 1609b815c7f3Sopenharmony_ci { CASE_NAME (SF_FORMAT_PCM_S8) ; 1610b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_PCM_16) ; 1611b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_PCM_24) ; 1612b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_PCM_32) ; 1613b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_PCM_U8) ; 1614b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_FLOAT) ; 1615b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_DOUBLE) ; 1616b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_ULAW) ; 1617b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_ALAW) ; 1618b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_IMA_ADPCM) ; 1619b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_MS_ADPCM) ; 1620b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_GSM610) ; 1621b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_VOX_ADPCM) ; 1622b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_NMS_ADPCM_16) ; 1623b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_NMS_ADPCM_24) ; 1624b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_NMS_ADPCM_32) ; 1625b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_G721_32) ; 1626b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_G723_24) ; 1627b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_G723_40) ; 1628b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_DWVW_12) ; 1629b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_DWVW_16) ; 1630b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_DWVW_24) ; 1631b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_DWVW_N) ; 1632b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_DPCM_8) ; 1633b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_DPCM_16) ; 1634b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_VORBIS) ; 1635b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_MPEG_LAYER_I) ; 1636b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_MPEG_LAYER_II) ; 1637b815c7f3Sopenharmony_ci CASE_NAME (SF_FORMAT_MPEG_LAYER_III) ; 1638b815c7f3Sopenharmony_ci default : 1639b815c7f3Sopenharmony_ci break ; 1640b815c7f3Sopenharmony_ci } ; 1641b815c7f3Sopenharmony_ci 1642b815c7f3Sopenharmony_ci return "BAD_MINOR_FORMAT" ; 1643b815c7f3Sopenharmony_ci} /* str_of_minor_format */ 1644b815c7f3Sopenharmony_ci 1645b815c7f3Sopenharmony_ciconst char * 1646b815c7f3Sopenharmony_cistr_of_open_mode (int mode) 1647b815c7f3Sopenharmony_ci{ switch (mode) 1648b815c7f3Sopenharmony_ci { CASE_NAME (SFM_READ) ; 1649b815c7f3Sopenharmony_ci CASE_NAME (SFM_WRITE) ; 1650b815c7f3Sopenharmony_ci CASE_NAME (SFM_RDWR) ; 1651b815c7f3Sopenharmony_ci 1652b815c7f3Sopenharmony_ci default : 1653b815c7f3Sopenharmony_ci break ; 1654b815c7f3Sopenharmony_ci } ; 1655b815c7f3Sopenharmony_ci 1656b815c7f3Sopenharmony_ci return "BAD_MODE" ; 1657b815c7f3Sopenharmony_ci} /* str_of_open_mode */ 1658b815c7f3Sopenharmony_ci 1659b815c7f3Sopenharmony_ciconst char * 1660b815c7f3Sopenharmony_cistr_of_endianness (int end) 1661b815c7f3Sopenharmony_ci{ switch (end) 1662b815c7f3Sopenharmony_ci { CASE_NAME (SF_ENDIAN_BIG) ; 1663b815c7f3Sopenharmony_ci CASE_NAME (SF_ENDIAN_LITTLE) ; 1664b815c7f3Sopenharmony_ci CASE_NAME (SF_ENDIAN_CPU) ; 1665b815c7f3Sopenharmony_ci default : 1666b815c7f3Sopenharmony_ci break ; 1667b815c7f3Sopenharmony_ci } ; 1668b815c7f3Sopenharmony_ci 1669b815c7f3Sopenharmony_ci /* Zero length string for SF_ENDIAN_FILE. */ 1670b815c7f3Sopenharmony_ci return "" ; 1671b815c7f3Sopenharmony_ci} /* str_of_endianness */ 1672b815c7f3Sopenharmony_ci 1673b815c7f3Sopenharmony_ci/*============================================================================== 1674b815c7f3Sopenharmony_ci*/ 1675b815c7f3Sopenharmony_ci 1676b815c7f3Sopenharmony_civoid 1677b815c7f3Sopenharmony_cipsf_f2s_array (const float *src, short *dest, int count, int normalize) 1678b815c7f3Sopenharmony_ci{ float normfact ; 1679b815c7f3Sopenharmony_ci 1680b815c7f3Sopenharmony_ci normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ; 1681b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1682b815c7f3Sopenharmony_ci dest [i] = psf_lrintf (src [i] * normfact) ; 1683b815c7f3Sopenharmony_ci 1684b815c7f3Sopenharmony_ci return ; 1685b815c7f3Sopenharmony_ci} /* psf_f2s_array */ 1686b815c7f3Sopenharmony_ci 1687b815c7f3Sopenharmony_civoid 1688b815c7f3Sopenharmony_cipsf_f2s_clip_array (const float *src, short *dest, int count, int normalize) 1689b815c7f3Sopenharmony_ci{ float normfact, scaled_value ; 1690b815c7f3Sopenharmony_ci 1691b815c7f3Sopenharmony_ci normfact = normalize ? (1.0 * 0x8000) : 1.0 ; 1692b815c7f3Sopenharmony_ci 1693b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1694b815c7f3Sopenharmony_ci { scaled_value = src [i] * normfact ; 1695b815c7f3Sopenharmony_ci if (scaled_value >= (1.0 * 0x7FFF)) 1696b815c7f3Sopenharmony_ci { dest [i] = 0x7FFF ; 1697b815c7f3Sopenharmony_ci continue ; 1698b815c7f3Sopenharmony_ci } ; 1699b815c7f3Sopenharmony_ci if (scaled_value <= (-8.0 * 0x1000)) 1700b815c7f3Sopenharmony_ci { dest [i] = -0x7FFF - 1 ; 1701b815c7f3Sopenharmony_ci continue ; 1702b815c7f3Sopenharmony_ci } ; 1703b815c7f3Sopenharmony_ci 1704b815c7f3Sopenharmony_ci dest [i] = psf_lrintf (scaled_value) ; 1705b815c7f3Sopenharmony_ci } ; 1706b815c7f3Sopenharmony_ci 1707b815c7f3Sopenharmony_ci return ; 1708b815c7f3Sopenharmony_ci} /* psf_f2s_clip_array */ 1709b815c7f3Sopenharmony_ci 1710b815c7f3Sopenharmony_civoid 1711b815c7f3Sopenharmony_cipsf_d2s_array (const double *src, short *dest, int count, int normalize) 1712b815c7f3Sopenharmony_ci{ double normfact ; 1713b815c7f3Sopenharmony_ci 1714b815c7f3Sopenharmony_ci normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ; 1715b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1716b815c7f3Sopenharmony_ci dest [i] = psf_lrint (src [i] * normfact) ; 1717b815c7f3Sopenharmony_ci 1718b815c7f3Sopenharmony_ci return ; 1719b815c7f3Sopenharmony_ci} /* psf_f2s_array */ 1720b815c7f3Sopenharmony_ci 1721b815c7f3Sopenharmony_civoid 1722b815c7f3Sopenharmony_cipsf_d2s_clip_array (const double *src, short *dest, int count, int normalize) 1723b815c7f3Sopenharmony_ci{ double normfact, scaled_value ; 1724b815c7f3Sopenharmony_ci 1725b815c7f3Sopenharmony_ci normfact = normalize ? (1.0 * 0x8000) : 1.0 ; 1726b815c7f3Sopenharmony_ci 1727b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1728b815c7f3Sopenharmony_ci { scaled_value = src [i] * normfact ; 1729b815c7f3Sopenharmony_ci if (scaled_value >= (1.0 * 0x7FFF)) 1730b815c7f3Sopenharmony_ci { dest [i] = 0x7FFF ; 1731b815c7f3Sopenharmony_ci continue ; 1732b815c7f3Sopenharmony_ci } ; 1733b815c7f3Sopenharmony_ci if (scaled_value <= (-8.0 * 0x1000)) 1734b815c7f3Sopenharmony_ci { dest [i] = -0x7FFF - 1 ; 1735b815c7f3Sopenharmony_ci continue ; 1736b815c7f3Sopenharmony_ci } ; 1737b815c7f3Sopenharmony_ci 1738b815c7f3Sopenharmony_ci dest [i] = psf_lrint (scaled_value) ; 1739b815c7f3Sopenharmony_ci } ; 1740b815c7f3Sopenharmony_ci 1741b815c7f3Sopenharmony_ci return ; 1742b815c7f3Sopenharmony_ci} /* psf_d2s_clip_array */ 1743b815c7f3Sopenharmony_ci 1744b815c7f3Sopenharmony_ci 1745b815c7f3Sopenharmony_civoid 1746b815c7f3Sopenharmony_cipsf_f2i_array (const float *src, int *dest, int count, int normalize) 1747b815c7f3Sopenharmony_ci{ float normfact ; 1748b815c7f3Sopenharmony_ci 1749b815c7f3Sopenharmony_ci normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ; 1750b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1751b815c7f3Sopenharmony_ci dest [i] = psf_lrintf (src [i] * normfact) ; 1752b815c7f3Sopenharmony_ci 1753b815c7f3Sopenharmony_ci return ; 1754b815c7f3Sopenharmony_ci} /* psf_f2i_array */ 1755b815c7f3Sopenharmony_ci 1756b815c7f3Sopenharmony_civoid 1757b815c7f3Sopenharmony_cipsf_f2i_clip_array (const float *src, int *dest, int count, int normalize) 1758b815c7f3Sopenharmony_ci{ float normfact, scaled_value ; 1759b815c7f3Sopenharmony_ci 1760b815c7f3Sopenharmony_ci normfact = normalize ? (8.0 * 0x10000000) : 1.0 ; 1761b815c7f3Sopenharmony_ci 1762b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1763b815c7f3Sopenharmony_ci { scaled_value = src [i] * normfact ; 1764b815c7f3Sopenharmony_ci#if CPU_CLIPS_POSITIVE == 0 1765b815c7f3Sopenharmony_ci if (scaled_value >= (1.0 * 0x7FFFFFFF)) 1766b815c7f3Sopenharmony_ci { dest [i] = 0x7FFFFFFF ; 1767b815c7f3Sopenharmony_ci continue ; 1768b815c7f3Sopenharmony_ci } ; 1769b815c7f3Sopenharmony_ci#endif 1770b815c7f3Sopenharmony_ci#if CPU_CLIPS_NEGATIVE == 0 1771b815c7f3Sopenharmony_ci if (scaled_value <= (-8.0 * 0x10000000)) 1772b815c7f3Sopenharmony_ci { dest [i] = 0x80000000 ; 1773b815c7f3Sopenharmony_ci continue ; 1774b815c7f3Sopenharmony_ci } ; 1775b815c7f3Sopenharmony_ci#endif 1776b815c7f3Sopenharmony_ci 1777b815c7f3Sopenharmony_ci dest [i] = psf_lrintf (scaled_value) ; 1778b815c7f3Sopenharmony_ci } ; 1779b815c7f3Sopenharmony_ci 1780b815c7f3Sopenharmony_ci return ; 1781b815c7f3Sopenharmony_ci} /* psf_f2i_clip_array */ 1782b815c7f3Sopenharmony_ci 1783b815c7f3Sopenharmony_civoid 1784b815c7f3Sopenharmony_cipsf_d2i_array (const double *src, int *dest, int count, int normalize) 1785b815c7f3Sopenharmony_ci{ double normfact ; 1786b815c7f3Sopenharmony_ci 1787b815c7f3Sopenharmony_ci normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ; 1788b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1789b815c7f3Sopenharmony_ci dest [i] = psf_lrint (src [i] * normfact) ; 1790b815c7f3Sopenharmony_ci 1791b815c7f3Sopenharmony_ci return ; 1792b815c7f3Sopenharmony_ci} /* psf_f2i_array */ 1793b815c7f3Sopenharmony_ci 1794b815c7f3Sopenharmony_civoid 1795b815c7f3Sopenharmony_cipsf_d2i_clip_array (const double *src, int *dest, int count, int normalize) 1796b815c7f3Sopenharmony_ci{ double normfact, scaled_value ; 1797b815c7f3Sopenharmony_ci 1798b815c7f3Sopenharmony_ci normfact = normalize ? (8.0 * 0x10000000) : 1.0 ; 1799b815c7f3Sopenharmony_ci 1800b815c7f3Sopenharmony_ci for (int i = 0 ; i < count ; i++) 1801b815c7f3Sopenharmony_ci { scaled_value = src [i] * normfact ; 1802b815c7f3Sopenharmony_ci#if CPU_CLIPS_POSITIVE == 0 1803b815c7f3Sopenharmony_ci if (scaled_value >= (1.0 * 0x7FFFFFFF)) 1804b815c7f3Sopenharmony_ci { dest [i] = 0x7FFFFFFF ; 1805b815c7f3Sopenharmony_ci continue ; 1806b815c7f3Sopenharmony_ci } ; 1807b815c7f3Sopenharmony_ci#endif 1808b815c7f3Sopenharmony_ci#if CPU_CLIPS_NEGATIVE == 0 1809b815c7f3Sopenharmony_ci if (scaled_value <= (-8.0 * 0x10000000)) 1810b815c7f3Sopenharmony_ci { dest [i] = 0x80000000 ; 1811b815c7f3Sopenharmony_ci continue ; 1812b815c7f3Sopenharmony_ci } ; 1813b815c7f3Sopenharmony_ci#endif 1814b815c7f3Sopenharmony_ci 1815b815c7f3Sopenharmony_ci dest [i] = psf_lrint (scaled_value) ; 1816b815c7f3Sopenharmony_ci } ; 1817b815c7f3Sopenharmony_ci 1818b815c7f3Sopenharmony_ci return ; 1819b815c7f3Sopenharmony_ci} /* psf_d2i_clip_array */ 1820b815c7f3Sopenharmony_ci 1821b815c7f3Sopenharmony_ciFILE * 1822b815c7f3Sopenharmony_cipsf_open_tmpfile (char * fname, size_t fnamelen) 1823b815c7f3Sopenharmony_ci{ const char * tmpdir ; 1824b815c7f3Sopenharmony_ci FILE * file ; 1825b815c7f3Sopenharmony_ci 1826b815c7f3Sopenharmony_ci if (OS_IS_WIN32) 1827b815c7f3Sopenharmony_ci tmpdir = getenv ("TEMP") ; 1828b815c7f3Sopenharmony_ci else 1829b815c7f3Sopenharmony_ci { tmpdir = getenv ("TMPDIR") ; 1830b815c7f3Sopenharmony_ci tmpdir = tmpdir == NULL ? "/tmp" : tmpdir ; 1831b815c7f3Sopenharmony_ci } ; 1832b815c7f3Sopenharmony_ci 1833b815c7f3Sopenharmony_ci if (tmpdir && access (tmpdir, R_OK | W_OK | X_OK) == 0) 1834b815c7f3Sopenharmony_ci { snprintf (fname, fnamelen, "%s/%x%x-alac.tmp", tmpdir, psf_rand_int32 (), psf_rand_int32 ()) ; 1835b815c7f3Sopenharmony_ci if ((file = fopen (fname, "wb+")) != NULL) 1836b815c7f3Sopenharmony_ci return file ; 1837b815c7f3Sopenharmony_ci } ; 1838b815c7f3Sopenharmony_ci 1839b815c7f3Sopenharmony_ci snprintf (fname, fnamelen, "%x%x-alac.tmp", psf_rand_int32 (), psf_rand_int32 ()) ; 1840b815c7f3Sopenharmony_ci if ((file = fopen (fname, "wb+")) != NULL) 1841b815c7f3Sopenharmony_ci return file ; 1842b815c7f3Sopenharmony_ci 1843b815c7f3Sopenharmony_ci memset (fname, 0, fnamelen) ; 1844b815c7f3Sopenharmony_ci return NULL ; 1845b815c7f3Sopenharmony_ci} /* psf_open_tmpfile */ 1846