Commit 5e26e2ab authored by Max Kellermann's avatar Max Kellermann

system/ByteOrder: new library for byte ordering / endianess

Replacing GLib macros.
parent 08eca827
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "CheckAudioFormat.hxx" #include "CheckAudioFormat.hxx"
#include "util/bit_reverse.h" #include "util/bit_reverse.h"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "system/ByteOrder.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "DsdLib.hxx" #include "DsdLib.hxx"
#include "Log.hxx" #include "Log.hxx"
...@@ -56,8 +57,8 @@ struct DsdiffChunkHeader { ...@@ -56,8 +57,8 @@ struct DsdiffChunkHeader {
*/ */
gcc_const gcc_const
uint64_t GetSize() const { uint64_t GetSize() const {
return (((uint64_t)GUINT32_FROM_BE(size_high)) << 32) | return (uint64_t(FromBE32(size_high)) << 32) |
((uint64_t)GUINT32_FROM_BE(size_low)); uint64_t(FromBE32(size_low));
} }
}; };
...@@ -141,7 +142,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is, ...@@ -141,7 +142,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
sizeof(sample_rate))) sizeof(sample_rate)))
return false; return false;
metadata->sample_rate = GUINT32_FROM_BE(sample_rate); metadata->sample_rate = FromBE32(sample_rate);
} else if (dsdlib_id_equals(&header.id, "CHNL")) { } else if (dsdlib_id_equals(&header.id, "CHNL")) {
uint16_t channels; uint16_t channels;
if (header.GetSize() < sizeof(channels) || if (header.GetSize() < sizeof(channels) ||
...@@ -150,7 +151,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is, ...@@ -150,7 +151,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
!dsdlib_skip_to(decoder, is, chunk_end_offset)) !dsdlib_skip_to(decoder, is, chunk_end_offset))
return false; return false;
metadata->channels = GUINT16_FROM_BE(channels); metadata->channels = FromBE16(channels);
} else if (dsdlib_id_equals(&header.id, "CMPR")) { } else if (dsdlib_id_equals(&header.id, "CMPR")) {
struct dsdlib_id type; struct dsdlib_id type;
if (header.GetSize() < sizeof(type) || if (header.GetSize() < sizeof(type) ||
...@@ -211,7 +212,7 @@ dsdiff_handle_native_tag(struct input_stream *is, ...@@ -211,7 +212,7 @@ dsdiff_handle_native_tag(struct input_stream *is,
if (!dsdlib_read(nullptr, is, &metatag, sizeof(metatag))) if (!dsdlib_read(nullptr, is, &metatag, sizeof(metatag)))
return; return;
uint32_t length = GUINT32_FROM_BE(metatag.size); uint32_t length = FromBE32(metatag.size);
/* Check and limit size of the tag to prevent a stack overflow */ /* Check and limit size of the tag to prevent a stack overflow */
if (length == 0 || length > 60) if (length == 0 || length > 60)
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "CheckAudioFormat.hxx" #include "CheckAudioFormat.hxx"
#include "util/bit_reverse.h" #include "util/bit_reverse.h"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "system/ByteOrder.hxx"
#include "DsdLib.hxx" #include "DsdLib.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "Log.hxx" #include "Log.hxx"
...@@ -107,16 +108,16 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is, ...@@ -107,16 +108,16 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
!dsdlib_id_equals(&dsf_header.id, "DSD ")) !dsdlib_id_equals(&dsf_header.id, "DSD "))
return false; return false;
chunk_size = (((uint64_t)GUINT32_FROM_LE(dsf_header.size_high)) << 32) | chunk_size = (uint64_t(FromLE32(dsf_header.size_high)) << 32) |
((uint64_t)GUINT32_FROM_LE(dsf_header.size_low)); uint64_t(FromLE32(dsf_header.size_low));
if (sizeof(dsf_header) != chunk_size) if (sizeof(dsf_header) != chunk_size)
return false; return false;
#ifdef HAVE_ID3TAG #ifdef HAVE_ID3TAG
uint64_t metadata_offset; uint64_t metadata_offset;
metadata_offset = (((uint64_t)GUINT32_FROM_LE(dsf_header.pmeta_high)) << 32) | metadata_offset = (uint64_t(FromLE32(dsf_header.pmeta_high)) << 32) |
((uint64_t)GUINT32_FROM_LE(dsf_header.pmeta_low)); uint64_t(FromLE32(dsf_header.pmeta_low));
#endif #endif
/* read the 'fmt ' chunk of the DSF file */ /* read the 'fmt ' chunk of the DSF file */
...@@ -126,13 +127,13 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is, ...@@ -126,13 +127,13 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
return false; return false;
uint64_t fmt_chunk_size; uint64_t fmt_chunk_size;
fmt_chunk_size = (((uint64_t)GUINT32_FROM_LE(dsf_fmt_chunk.size_high)) << 32) | fmt_chunk_size = (uint64_t(FromLE32(dsf_fmt_chunk.size_high)) << 32) |
((uint64_t)GUINT32_FROM_LE(dsf_fmt_chunk.size_low)); uint64_t(FromLE32(dsf_fmt_chunk.size_low));
if (fmt_chunk_size != sizeof(dsf_fmt_chunk)) if (fmt_chunk_size != sizeof(dsf_fmt_chunk))
return false; return false;
uint32_t samplefreq = (uint32_t)GUINT32_FROM_LE(dsf_fmt_chunk.sample_freq); uint32_t samplefreq = FromLE32(dsf_fmt_chunk.sample_freq);
/* for now, only support version 1 of the standard, DSD raw stereo /* for now, only support version 1 of the standard, DSD raw stereo
files with a sample freq of 2822400 Hz */ files with a sample freq of 2822400 Hz */
...@@ -143,7 +144,7 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is, ...@@ -143,7 +144,7 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
|| samplefreq != 2822400) || samplefreq != 2822400)
return false; return false;
uint32_t chblksize = (uint32_t)GUINT32_FROM_LE(dsf_fmt_chunk.block_size); uint32_t chblksize = FromLE32(dsf_fmt_chunk.block_size);
/* according to the spec block size should always be 4096 */ /* according to the spec block size should always be 4096 */
if (chblksize != 4096) if (chblksize != 4096)
return false; return false;
...@@ -158,8 +159,8 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is, ...@@ -158,8 +159,8 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
we use the actual data size as chunk size */ we use the actual data size as chunk size */
uint64_t data_size; uint64_t data_size;
data_size = (((uint64_t)GUINT32_FROM_LE(data_chunk.size_high)) << 32) | data_size = (uint64_t(FromLE32(data_chunk.size_high)) << 32) |
((uint64_t)GUINT32_FROM_LE(data_chunk.size_low)); uint64_t(FromLE32(data_chunk.size_low));
data_size -= sizeof(data_chunk); data_size -= sizeof(data_chunk);
metadata->chunk_size = data_size; metadata->chunk_size = data_size;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/UriUtil.hxx" #include "util/UriUtil.hxx"
#include "util/Macros.hxx" #include "util/Macros.hxx"
#include "system/ByteOrder.hxx"
#include "CheckAudioFormat.hxx" #include "CheckAudioFormat.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "Log.hxx" #include "Log.hxx"
...@@ -47,18 +48,10 @@ ...@@ -47,18 +48,10 @@
#define ov_time_seek_page(VF, S) (ov_time_seek_page(VF, (S)*1000)) #define ov_time_seek_page(VF, S) (ov_time_seek_page(VF, (S)*1000))
#endif /* HAVE_TREMOR */ #endif /* HAVE_TREMOR */
#include <glib.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#if G_BYTE_ORDER == G_BIG_ENDIAN
#define VORBIS_BIG_ENDIAN true
#else
#define VORBIS_BIG_ENDIAN false
#endif
struct vorbis_input_stream { struct vorbis_input_stream {
struct decoder *decoder; struct decoder *decoder;
...@@ -248,7 +241,7 @@ vorbis_stream_decode(struct decoder *decoder, ...@@ -248,7 +241,7 @@ vorbis_stream_decode(struct decoder *decoder,
#ifdef HAVE_TREMOR #ifdef HAVE_TREMOR
long nbytes = ov_read(&vf, buffer, sizeof(buffer), long nbytes = ov_read(&vf, buffer, sizeof(buffer),
VORBIS_BIG_ENDIAN, 2, 1, IsBigEndian(), 2, 1,
&current_section); &current_section);
#else #else
float **per_channel; float **per_channel;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "../DecoderAPI.hxx" #include "../DecoderAPI.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "system/ByteOrder.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <errno.h> #include <errno.h>
...@@ -265,11 +266,9 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs) ...@@ -265,11 +266,9 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
config.sidEmulation = &builder; config.sidEmulation = &builder;
config.sidModel = SID2_MODEL_CORRECT; config.sidModel = SID2_MODEL_CORRECT;
config.sidSamples = true; config.sidSamples = true;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN config.sampleFormat = IsLittleEndian()
config.sampleFormat = SID2_LITTLE_SIGNED; ? SID2_LITTLE_SIGNED
#else : SID2_BIG_SIGNED;
config.sampleFormat = SID2_BIG_SIGNED;
#endif
if (tune.isStereo()) { if (tune.isStereo()) {
config.playback = sid2_stereo; config.playback = sid2_stereo;
channels = 2; channels = 2;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "ConfigError.hxx" #include "ConfigError.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "system/ByteOrder.hxx"
#include <opus.h> #include <opus.h>
#include <ogg/ogg.h> #include <ogg/ogg.h>
...@@ -338,9 +339,9 @@ opus_encoder_generate_head(struct opus_encoder *encoder) ...@@ -338,9 +339,9 @@ opus_encoder_generate_head(struct opus_encoder *encoder)
memcpy(header, "OpusHead", 8); memcpy(header, "OpusHead", 8);
header[8] = 1; header[8] = 1;
header[9] = encoder->audio_format.channels; header[9] = encoder->audio_format.channels;
*(uint16_t *)(header + 10) = GUINT16_TO_LE(encoder->lookahead); *(uint16_t *)(header + 10) = ToLE16(encoder->lookahead);
*(uint32_t *)(header + 12) = *(uint32_t *)(header + 12) =
GUINT32_TO_LE(encoder->audio_format.sample_rate); ToLE32(encoder->audio_format.sample_rate);
header[16] = 0; header[16] = 0;
header[17] = 0; header[17] = 0;
header[18] = 0; header[18] = 0;
...@@ -365,9 +366,9 @@ opus_encoder_generate_tags(struct opus_encoder *encoder) ...@@ -365,9 +366,9 @@ opus_encoder_generate_tags(struct opus_encoder *encoder)
size_t comments_size = 8 + 4 + version_length + 4; size_t comments_size = 8 + 4 + version_length + 4;
unsigned char *comments = (unsigned char *)g_malloc(comments_size); unsigned char *comments = (unsigned char *)g_malloc(comments_size);
memcpy(comments, "OpusTags", 8); memcpy(comments, "OpusTags", 8);
*(uint32_t *)(comments + 8) = GUINT32_TO_LE(version_length); *(uint32_t *)(comments + 8) = ToLE32(version_length);
memcpy(comments + 12, version, version_length); memcpy(comments + 12, version, version_length);
*(uint32_t *)(comments + 12 + version_length) = GUINT32_TO_LE(0); *(uint32_t *)(comments + 12 + version_length) = ToLE32(0);
ogg_packet packet; ogg_packet packet;
packet.packet = comments; packet.packet = comments;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "config.h" #include "config.h"
#include "WaveEncoderPlugin.hxx" #include "WaveEncoderPlugin.hxx"
#include "EncoderAPI.hxx" #include "EncoderAPI.hxx"
#include "system/ByteOrder.hxx"
#include "util/fifo_buffer.h" #include "util/fifo_buffer.h"
extern "C" { extern "C" {
#include "util/growing_fifo.h" #include "util/growing_fifo.h"
...@@ -62,24 +63,23 @@ fill_wave_header(struct wave_header *header, int channels, int bits, ...@@ -62,24 +63,23 @@ fill_wave_header(struct wave_header *header, int channels, int bits,
int data_size = 0x0FFFFFFF; int data_size = 0x0FFFFFFF;
/* constants */ /* constants */
header->id_riff = GUINT32_TO_LE(0x46464952); header->id_riff = ToLE32(0x46464952);
header->id_wave = GUINT32_TO_LE(0x45564157); header->id_wave = ToLE32(0x45564157);
header->id_fmt = GUINT32_TO_LE(0x20746d66); header->id_fmt = ToLE32(0x20746d66);
header->id_data = GUINT32_TO_LE(0x61746164); header->id_data = ToLE32(0x61746164);
/* wave format */ /* wave format */
header->format = GUINT16_TO_LE(1); // PCM_FORMAT header->format = ToLE16(1); // PCM_FORMAT
header->channels = GUINT16_TO_LE(channels); header->channels = ToLE16(channels);
header->bits = GUINT16_TO_LE(bits); header->bits = ToLE16(bits);
header->freq = GUINT32_TO_LE(freq); header->freq = ToLE32(freq);
header->blocksize = GUINT16_TO_LE(block_size); header->blocksize = ToLE16(block_size);
header->byterate = GUINT32_TO_LE(freq * block_size); header->byterate = ToLE32(freq * block_size);
/* chunk sizes (fake data length) */ /* chunk sizes (fake data length) */
header->fmt_size = GUINT32_TO_LE(16); header->fmt_size = ToLE32(16);
header->data_size = GUINT32_TO_LE(data_size); header->data_size = ToLE32(data_size);
header->riff_size = GUINT32_TO_LE(4 + (8 + 16) + header->riff_size = ToLE32(4 + (8 + 16) + (8 + data_size));
(8 + data_size));
} }
static Encoder * static Encoder *
...@@ -153,29 +153,29 @@ wave_encoder_close(Encoder *_encoder) ...@@ -153,29 +153,29 @@ wave_encoder_close(Encoder *_encoder)
fifo_buffer_free(encoder->buffer); fifo_buffer_free(encoder->buffer);
} }
static inline size_t static size_t
pcm16_to_wave(uint16_t *dst16, const uint16_t *src16, size_t length) pcm16_to_wave(uint16_t *dst16, const uint16_t *src16, size_t length)
{ {
size_t cnt = length >> 1; size_t cnt = length >> 1;
while (cnt > 0) { while (cnt > 0) {
*dst16++ = GUINT16_TO_LE(*src16++); *dst16++ = ToLE16(*src16++);
cnt--; cnt--;
} }
return length; return length;
} }
static inline size_t static size_t
pcm32_to_wave(uint32_t *dst32, const uint32_t *src32, size_t length) pcm32_to_wave(uint32_t *dst32, const uint32_t *src32, size_t length)
{ {
size_t cnt = length >> 2; size_t cnt = length >> 2;
while (cnt > 0){ while (cnt > 0){
*dst32++ = GUINT32_TO_LE(*src32++); *dst32++ = ToLE32(*src32++);
cnt--; cnt--;
} }
return length; return length;
} }
static inline size_t static size_t
pcm24_to_wave(uint8_t *dst8, const uint32_t *src32, size_t length) pcm24_to_wave(uint8_t *dst8, const uint32_t *src32, size_t length)
{ {
uint32_t value; uint32_t value;
...@@ -202,35 +202,35 @@ wave_encoder_write(Encoder *_encoder, ...@@ -202,35 +202,35 @@ wave_encoder_write(Encoder *_encoder,
uint8_t *dst = (uint8_t *)growing_fifo_write(&encoder->buffer, length); uint8_t *dst = (uint8_t *)growing_fifo_write(&encoder->buffer, length);
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN) if (IsLittleEndian()) {
switch (encoder->bits) { switch (encoder->bits) {
case 8: case 8:
case 16: case 16:
case 32:// optimized cases case 32:// optimized cases
memcpy(dst, src, length); memcpy(dst, src, length);
break; break;
case 24: case 24:
length = pcm24_to_wave(dst, (const uint32_t *)src, length); length = pcm24_to_wave(dst, (const uint32_t *)src, length);
break; break;
} }
#elif (G_BYTE_ORDER == G_BIG_ENDIAN) } else {
switch (encoder->bits) { switch (encoder->bits) {
case 8: case 8:
memcpy(dst, src, length); memcpy(dst, src, length);
break; break;
case 16: case 16:
length = pcm16_to_wave(dst, (const uint16_t *)src, length); length = pcm16_to_wave((uint16_t *)dst,
break; (const uint16_t *)src, length);
case 24: break;
length = pcm24_to_wave(dst, (const uint32_t *)src, length); case 24:
break; length = pcm24_to_wave(dst, (const uint32_t *)src, length);
case 32: break;
length = pcm32_to_wave(dst, (const uint32_t *)src, length); case 32:
break; length = pcm32_to_wave((uint32_t *)dst,
(const uint32_t *)src, length);
break;
}
} }
#else
#error G_BYTE_ORDER set to G_PDP_ENDIAN is not supported by wave_encoder
#endif
fifo_buffer_append(encoder->buffer, length); fifo_buffer_append(encoder->buffer, length);
return true; return true;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "InputPlugin.hxx" #include "InputPlugin.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "system/ByteOrder.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <stdio.h> #include <stdio.h>
...@@ -202,12 +203,12 @@ input_cdio_open(const char *uri, ...@@ -202,12 +203,12 @@ input_cdio_open(const char *uri,
case 0: case 0:
LogDebug(cdio_domain, "drive returns audio data Little Endian"); LogDebug(cdio_domain, "drive returns audio data Little Endian");
reverse_endian = G_BYTE_ORDER == G_BIG_ENDIAN; reverse_endian = IsBigEndian();
break; break;
case 1: case 1:
LogDebug(cdio_domain, "drive returns audio data Big Endian"); LogDebug(cdio_domain, "drive returns audio data Big Endian");
reverse_endian = G_BYTE_ORDER == G_LITTLE_ENDIAN; reverse_endian = IsLittleEndian();
break; break;
default: default:
......
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
#include "system/ByteOrder.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <glib.h>
#include <CoreAudio/AudioHardware.h> #include <CoreAudio/AudioHardware.h>
#include <AudioUnit/AudioUnit.h> #include <AudioUnit/AudioUnit.h>
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
...@@ -342,9 +342,8 @@ osx_output_open(struct audio_output *ao, AudioFormat &audio_format, ...@@ -342,9 +342,8 @@ osx_output_open(struct audio_output *ao, AudioFormat &audio_format,
break; break;
} }
#if G_BYTE_ORDER == G_BIG_ENDIAN if (IsBigEndian())
stream_description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; stream_description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
#endif
stream_description.mBytesPerPacket = audio_format.GetFrameSize(); stream_description.mBytesPerPacket = audio_format.GetFrameSize();
stream_description.mFramesPerPacket = 1; stream_description.mFramesPerPacket = 1;
......
...@@ -25,10 +25,9 @@ ...@@ -25,10 +25,9 @@
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "util/Macros.hxx" #include "util/Macros.hxx"
#include "system/ByteOrder.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <glib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -532,7 +531,7 @@ oss_probe_sample_format(int fd, SampleFormat sample_format, ...@@ -532,7 +531,7 @@ oss_probe_sample_format(int fd, SampleFormat sample_format,
pcm_export.Open(sample_format, 0, false, false, pcm_export.Open(sample_format, 0, false, false,
oss_format == AFMT_S24_PACKED, oss_format == AFMT_S24_PACKED,
oss_format == AFMT_S24_PACKED && oss_format == AFMT_S24_PACKED &&
G_BYTE_ORDER != G_LITTLE_ENDIAN); !IsLittleEndian());
#endif #endif
return SUCCESS; return SUCCESS;
......
...@@ -18,15 +18,14 @@ ...@@ -18,15 +18,14 @@
*/ */
#include "PcmPack.hxx" #include "PcmPack.hxx"
#include "system/ByteOrder.hxx"
#include <glib.h>
static void static void
pack_sample(uint8_t *dest, const int32_t *src0) pack_sample(uint8_t *dest, const int32_t *src0)
{ {
const uint8_t *src = (const uint8_t *)src0; const uint8_t *src = (const uint8_t *)src0;
if (G_BYTE_ORDER == G_BIG_ENDIAN) if (IsBigEndian())
++src; ++src;
*dest++ = *src++; *dest++ = *src++;
...@@ -51,7 +50,7 @@ unpack_sample(int32_t *dest0, const uint8_t *src) ...@@ -51,7 +50,7 @@ unpack_sample(int32_t *dest0, const uint8_t *src)
{ {
uint8_t *dest = (uint8_t *)dest0; uint8_t *dest = (uint8_t *)dest0;
if (G_BYTE_ORDER == G_BIG_ENDIAN) if (IsBigEndian())
/* extend the sign bit to the most fourth byte */ /* extend the sign bit to the most fourth byte */
*dest++ = *src & 0x80 ? 0xff : 0x00; *dest++ = *src & 0x80 ? 0xff : 0x00;
...@@ -59,7 +58,7 @@ unpack_sample(int32_t *dest0, const uint8_t *src) ...@@ -59,7 +58,7 @@ unpack_sample(int32_t *dest0, const uint8_t *src)
*dest++ = *src++; *dest++ = *src++;
*dest++ = *src; *dest++ = *src;
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) if (IsLittleEndian())
/* extend the sign bit to the most fourth byte */ /* extend the sign bit to the most fourth byte */
*dest++ = *src & 0x80 ? 0xff : 0x00; *dest++ = *src & 0x80 ? 0xff : 0x00;
} }
......
/*
* Copyright (C) 2011-2013 Max Kellermann <max@duempel.org>,
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BYTE_ORDER_HXX
#define BYTE_ORDER_HXX
#include <stdint.h>
#if defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__)
#define IS_LITTLE_ENDIAN true
#define IS_BIG_ENDIAN false
#else
#define IS_LITTLE_ENDIAN true
#define IS_BIG_ENDIAN false;
#endif
static inline constexpr bool
IsLittleEndian()
{
return IS_LITTLE_ENDIAN;
}
static inline constexpr bool
IsBigEndian()
{
return IS_BIG_ENDIAN;
}
static inline constexpr uint16_t
ByteSwap16(uint16_t value)
{
return (value >> 8) | (value << 8);
}
static inline constexpr uint32_t
ByteSwap32(uint32_t value)
{
return (value >> 24) | ((value >> 8) & 0x0000ff00) |
((value << 8) & 0x00ff0000) | (value << 24);
}
static inline constexpr uint64_t
ByteSwap64(uint64_t value)
{
return uint64_t(ByteSwap32(uint32_t(value >> 32)))
| (uint64_t(ByteSwap32(value)) << 32);
}
/**
* Converts a 16bit value from big endian to the system's byte order
*/
static inline constexpr uint16_t
FromBE16(uint16_t value)
{
return IsBigEndian() ? value : ByteSwap16(value);
}
/**
* Converts a 32bit value from big endian to the system's byte order
*/
static inline constexpr uint32_t
FromBE32(uint32_t value)
{
return IsBigEndian() ? value : ByteSwap32(value);
}
/**
* Converts a 64bit value from big endian to the system's byte order
*/
static inline constexpr uint64_t
FromBE64(uint64_t value)
{
return IsBigEndian() ? value : ByteSwap64(value);
}
/**
* Converts a 16bit value from little endian to the system's byte order
*/
static inline constexpr uint16_t
FromLE16(uint16_t value)
{
return IsLittleEndian() ? value : ByteSwap16(value);
}
/**
* Converts a 32bit value from little endian to the system's byte order
*/
static inline constexpr uint32_t
FromLE32(uint32_t value)
{
return IsLittleEndian() ? value : ByteSwap32(value);
}
/**
* Converts a 64bit value from little endian to the system's byte order
*/
static inline constexpr uint64_t
FromLE64(uint64_t value)
{
return IsLittleEndian() ? value : ByteSwap64(value);
}
/**
* Converts a 16bit value from the system's byte order to big endian
*/
static inline constexpr uint16_t
ToBE16(uint16_t value)
{
return IsBigEndian() ? value : ByteSwap16(value);
}
/**
* Converts a 32bit value from the system's byte order to big endian
*/
static inline constexpr uint32_t
ToBE32(uint32_t value)
{
return IsBigEndian() ? value : ByteSwap32(value);
}
/**
* Converts a 64bit value from the system's byte order to big endian
*/
static inline constexpr uint64_t
ToBE64(uint64_t value)
{
return IsBigEndian() ? value : ByteSwap64(value);
}
/**
* Converts a 16bit value from the system's byte order to little endian
*/
static inline constexpr uint16_t
ToLE16(uint16_t value)
{
return IsLittleEndian() ? value : ByteSwap16(value);
}
/**
* Converts a 32bit value from the system's byte order to little endian
*/
static inline constexpr uint32_t
ToLE32(uint32_t value)
{
return IsLittleEndian() ? value : ByteSwap32(value);
}
/**
* Converts a 64bit value from the system's byte order to little endian
*/
static inline constexpr uint64_t
ToLE64(uint64_t value)
{
return IsLittleEndian() ? value : ByteSwap64(value);
}
#endif
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "config.h" /* must be first for large file support */ #include "config.h" /* must be first for large file support */
#include "Aiff.hxx" #include "Aiff.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "system/ByteOrder.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <glib.h> #include <glib.h>
...@@ -65,7 +66,7 @@ aiff_seek_id3(FILE *file) ...@@ -65,7 +66,7 @@ aiff_seek_id3(FILE *file)
size_t size = fread(&header, sizeof(header), 1, file); size_t size = fread(&header, sizeof(header), 1, file);
if (size != 1 || if (size != 1 ||
memcmp(header.id, "FORM", 4) != 0 || memcmp(header.id, "FORM", 4) != 0 ||
GUINT32_FROM_BE(header.size) > (uint32_t)st.st_size || FromBE32(header.size) > (uint32_t)st.st_size ||
(memcmp(header.format, "AIFF", 4) != 0 && (memcmp(header.format, "AIFF", 4) != 0 &&
memcmp(header.format, "AIFC", 4) != 0)) memcmp(header.format, "AIFC", 4) != 0))
/* not a AIFF file */ /* not a AIFF file */
...@@ -79,7 +80,7 @@ aiff_seek_id3(FILE *file) ...@@ -79,7 +80,7 @@ aiff_seek_id3(FILE *file)
if (size != 1) if (size != 1)
return 0; return 0;
size = GUINT32_FROM_BE(chunk.size); size = FromBE32(chunk.size);
if (size > G_MAXINT32) if (size > G_MAXINT32)
/* too dangerous, bail out: possible integer /* too dangerous, bail out: possible integer
underflow when casting to off_t */ underflow when casting to off_t */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "config.h" #include "config.h"
#include "ApeLoader.hxx" #include "ApeLoader.hxx"
#include "system/ByteOrder.hxx"
#include <glib.h> #include <glib.h>
...@@ -44,11 +45,11 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) ...@@ -44,11 +45,11 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback)
if (fseek(fp, -(long)sizeof(footer), SEEK_END) || if (fseek(fp, -(long)sizeof(footer), SEEK_END) ||
fread(&footer, 1, sizeof(footer), fp) != sizeof(footer) || fread(&footer, 1, sizeof(footer), fp) != sizeof(footer) ||
memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0 || memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0 ||
GUINT32_FROM_LE(footer.version) != 2000) FromLE32(footer.version) != 2000)
return false; return false;
/* find beginning of ape tag */ /* find beginning of ape tag */
size_t remaining = GUINT32_FROM_LE(footer.length); size_t remaining = FromLE32(footer.length);
if (remaining <= sizeof(footer) + 10 || if (remaining <= sizeof(footer) + 10 ||
/* refuse to load more than one megabyte of tag data */ /* refuse to load more than one megabyte of tag data */
remaining > 1024 * 1024 || remaining > 1024 * 1024 ||
...@@ -66,13 +67,13 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback) ...@@ -66,13 +67,13 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback)
} }
/* read tags */ /* read tags */
unsigned n = GUINT32_FROM_LE(footer.count); unsigned n = FromLE32(footer.count);
const char *p = buffer; const char *p = buffer;
while (n-- && remaining > 10) { while (n-- && remaining > 10) {
size_t size = GUINT32_FROM_LE(*(const uint32_t *)p); size_t size = FromLE32(*(const uint32_t *)p);
p += 4; p += 4;
remaining -= 4; remaining -= 4;
unsigned long flags = GUINT32_FROM_LE(*(const uint32_t *)p); unsigned long flags = FromLE32(*(const uint32_t *)p);
p += 4; p += 4;
remaining -= 4; remaining -= 4;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "config.h" /* must be first for large file support */ #include "config.h" /* must be first for large file support */
#include "Riff.hxx" #include "Riff.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "system/ByteOrder.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <glib.h> #include <glib.h>
...@@ -65,7 +66,7 @@ riff_seek_id3(FILE *file) ...@@ -65,7 +66,7 @@ riff_seek_id3(FILE *file)
size_t size = fread(&header, sizeof(header), 1, file); size_t size = fread(&header, sizeof(header), 1, file);
if (size != 1 || if (size != 1 ||
memcmp(header.id, "RIFF", 4) != 0 || memcmp(header.id, "RIFF", 4) != 0 ||
GUINT32_FROM_LE(header.size) > (uint32_t)st.st_size) FromLE32(header.size) > (uint32_t)st.st_size)
/* not a RIFF file */ /* not a RIFF file */
return 0; return 0;
...@@ -77,7 +78,7 @@ riff_seek_id3(FILE *file) ...@@ -77,7 +78,7 @@ riff_seek_id3(FILE *file)
if (size != 1) if (size != 1)
return 0; return 0;
size = GUINT32_FROM_LE(chunk.size); size = FromLE32(chunk.size);
if (size > G_MAXINT32) if (size > G_MAXINT32)
/* too dangerous, bail out: possible integer /* too dangerous, bail out: possible integer
underflow when casting to off_t */ underflow when casting to off_t */
......
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
*/ */
#include "ByteReverse.hxx" #include "ByteReverse.hxx"
#include "system/ByteOrder.hxx"
#include "Compiler.h" #include "Compiler.h"
#include <glib.h>
#include <assert.h> #include <assert.h>
void void
...@@ -33,7 +33,7 @@ reverse_bytes_16(uint16_t *gcc_restrict dest, ...@@ -33,7 +33,7 @@ reverse_bytes_16(uint16_t *gcc_restrict dest,
while (src < src_end) { while (src < src_end) {
const uint16_t x = *src++; const uint16_t x = *src++;
*dest++ = GUINT16_SWAP_LE_BE(x); *dest++ = ByteSwap16(x);
} }
} }
...@@ -47,7 +47,7 @@ reverse_bytes_32(uint32_t *gcc_restrict dest, ...@@ -47,7 +47,7 @@ reverse_bytes_32(uint32_t *gcc_restrict dest,
while (src < src_end) { while (src < src_end) {
const uint32_t x = *src++; const uint32_t x = *src++;
*dest++ = GUINT32_SWAP_LE_BE(x); *dest++ = ByteSwap32(x);
} }
} }
...@@ -61,7 +61,7 @@ reverse_bytes_64(uint64_t *gcc_restrict dest, ...@@ -61,7 +61,7 @@ reverse_bytes_64(uint64_t *gcc_restrict dest,
while (src < src_end) { while (src < src_end) {
const uint64_t x = *src++; const uint64_t x = *src++;
*dest++ = GUINT64_SWAP_LE_BE(x); *dest++ = ByteSwap64(x);
} }
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "test_pcm_all.hxx" #include "test_pcm_all.hxx"
#include "test_pcm_util.hxx" #include "test_pcm_util.hxx"
#include "pcm/PcmPack.hxx" #include "pcm/PcmPack.hxx"
#include "system/ByteOrder.hxx"
#include <glib.h> #include <glib.h>
...@@ -34,7 +35,7 @@ test_pcm_pack_24() ...@@ -34,7 +35,7 @@ test_pcm_pack_24()
for (unsigned i = 0; i < N; ++i) { for (unsigned i = 0; i < N; ++i) {
int32_t d; int32_t d;
if (G_BYTE_ORDER == G_BIG_ENDIAN) if (IsBigEndian())
d = (dest[i * 3] << 16) | (dest[i * 3 + 1] << 8) d = (dest[i * 3] << 16) | (dest[i * 3 + 1] << 8)
| dest[i * 3 + 2]; | dest[i * 3 + 2];
else else
...@@ -58,7 +59,7 @@ test_pcm_unpack_24() ...@@ -58,7 +59,7 @@ test_pcm_unpack_24()
for (unsigned i = 0; i < N; ++i) { for (unsigned i = 0; i < N; ++i) {
int32_t s; int32_t s;
if (G_BYTE_ORDER == G_BIG_ENDIAN) if (IsBigEndian())
s = (src[i * 3] << 16) | (src[i * 3 + 1] << 8) s = (src[i * 3] << 16) | (src[i * 3 + 1] << 8)
| src[i * 3 + 2]; | src[i * 3 + 2];
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment