/** * @param hfile valid GslHFile * @return offset of first zero byte or -1 * * Find the offset of the first zero byte in a GslHFile. * This function is MT-safe and may be called from any thread. */ GslLong gsl_hfile_zoffset (GslHFile *hfile) { GslLong zoffset, l; guint8 sdata[1024], *p; gboolean seen_zero = FALSE; errno = EFAULT; g_return_val_if_fail (hfile != NULL, -1); g_return_val_if_fail (hfile->ocount > 0, -1); sfi_mutex_lock (&hfile->mutex); if (hfile->zoffset > -2) /* got valid offset already */ { zoffset = hfile->zoffset; sfi_mutex_unlock (&hfile->mutex); return zoffset; } if (!hfile->ocount) /* bad */ { sfi_mutex_unlock (&hfile->mutex); return -1; } hfile->ocount += 1; /* keep open for a while */ sfi_mutex_unlock (&hfile->mutex); /* seek to literal '\0' */ zoffset = 0; do { do l = gsl_hfile_pread (hfile, zoffset, sizeof (sdata), sdata); while (l < 0 && errno == EINTR); if (l < 0) { gsl_hfile_close (hfile); return -1; } p = memchr (sdata, 0, l); seen_zero = p != NULL; zoffset += seen_zero ? p - sdata : l; } while (!seen_zero && l); if (!seen_zero) zoffset = -1; sfi_mutex_lock (&hfile->mutex); if (hfile->zoffset < -1) hfile->zoffset = zoffset; sfi_mutex_unlock (&hfile->mutex); gsl_hfile_close (hfile); return zoffset; }
/** * @param rfile valid GslRFile * @param offset offset in bytes within 0 and gsl_rfile_length() * @param n_bytes number of bytes to read * @param bytes buffer to store read bytes * @return amount of bytes read or -1 if an error occoured (errno set) * * Read a block of bytes from a GslRFile at a specified position. */ GslLong gsl_rfile_pread (GslRFile *rfile, GslLong offset, GslLong n_bytes, gpointer bytes) { errno = EFAULT; g_return_val_if_fail (rfile != NULL, -1); return gsl_hfile_pread (rfile->hfile, offset, n_bytes, bytes); }
/** * @param rfile valid GslRFile * @param n_bytes number of bytes to read * @param bytes buffer to store read bytes * @return amount of bytes read or -1 if an error occoured (errno set) * * Read a block of bytes from a GslRFile from the current seek position * and advance the seek position. */ GslLong gsl_rfile_read (GslRFile *rfile, GslLong n_bytes, gpointer bytes) { GslLong l; errno = EFAULT; g_return_val_if_fail (rfile != NULL, -1); l = gsl_hfile_pread (rfile->hfile, rfile->offset, n_bytes, bytes); if (l > 0) rfile->offset += l; return l; }
static GslLong wave_handle_read (GslDataHandle *data_handle, GslLong voffset, GslLong n_values, gfloat *values) { WaveHandle *whandle = (WaveHandle*) data_handle; gpointer buffer = values; GslLong l, i, byte_offset; byte_offset = voffset * wave_format_byte_width (whandle->format); /* float offset into bytes */ byte_offset += whandle->byte_offset; switch (whandle->format) { guint8 *u8; gint8 *s8; guint16 *u16; guint32 *u32; case GSL_WAVE_FORMAT_UNSIGNED_8: u8 = buffer; u8 += n_values * 3; l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values, u8); if (l < 1) return l; for (i = 0; i < l; i++) { int v = u8[i] - 128; values[i] = v * (1. / 128.); } break; case GSL_WAVE_FORMAT_SIGNED_8: s8 = buffer; s8 += n_values * 3; l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values, s8); if (l < 1) return l; for (i = 0; i < l; i++) values[i] = s8[i] * (1. / 128.); break; case GSL_WAVE_FORMAT_SIGNED_12: case GSL_WAVE_FORMAT_UNSIGNED_12: case GSL_WAVE_FORMAT_SIGNED_16: case GSL_WAVE_FORMAT_UNSIGNED_16: u16 = buffer; u16 += n_values; l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values << 1, u16); if (l < 2) return l < 0 ? l : 0; l >>= 1; switch (whandle->format) { case GSL_WAVE_FORMAT_UNSIGNED_16: if (whandle->byte_order != G_BYTE_ORDER) for (i = 0; i < l; i++) { int v = GUINT16_SWAP_LE_BE (u16[i]); v -= 32768; values[i] = v * (1. / 32768.); } else /* whandle->byte_order == G_BYTE_ORDER */ for (i = 0; i < l; i++) { int v = u16[i]; v -= 32768; values[i] = v * (1. / 32768.); } break; case GSL_WAVE_FORMAT_UNSIGNED_12: if (whandle->byte_order != G_BYTE_ORDER) for (i = 0; i < l; i++) { int v = GUINT16_SWAP_LE_BE (u16[i]); v &= 0x0fff; v -= 4096; values[i] = v * (1. / 4096.); } else /* whandle->byte_order == G_BYTE_ORDER */ for (i = 0; i < l; i++) { int v = u16[i]; v &= 0x0fff; v -= 4096; values[i] = v * (1. / 4096.); } break; case GSL_WAVE_FORMAT_SIGNED_16: if (whandle->byte_order != G_BYTE_ORDER) for (i = 0; i < l; i++) { gint16 v = GUINT16_SWAP_LE_BE (u16[i]); values[i] = v * (1. / 32768.); } else /* whandle->byte_order == G_BYTE_ORDER */ for (i = 0; i < l; i++) { gint16 v = u16[i]; values[i] = v * (1. / 32768.); } break; case GSL_WAVE_FORMAT_SIGNED_12: if (whandle->byte_order != G_BYTE_ORDER) for (i = 0; i < l; i++) { gint16 v = GUINT16_SWAP_LE_BE (u16[i]); values[i] = CLAMP (v, -4096, 4096) * (1. / 4096.); } else /* whandle->byte_order == G_BYTE_ORDER */ for (i = 0; i < l; i++) { gint16 v = u16[i]; values[i] = CLAMP (v, -4096, 4096) * (1. / 4096.); } break; default: g_assert_not_reached (); } break; case GSL_WAVE_FORMAT_FLOAT: u32 = buffer; l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values << 2, u32); if (l < 4) return l < 0 ? l : 0; l >>= 2; if (whandle->byte_order != G_BYTE_ORDER) for (i = 0; i < l; i++) u32[i] = GUINT32_SWAP_LE_BE (u32[i]); break; default: l = -1; g_assert_not_reached (); } return l; }