aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-10-16 21:09:19 +0200
committerMax Kellermann <max@duempel.org>2013-10-16 22:09:44 +0200
commit5e26e2ab1dadb1e4176d5a4cac03100a7d21c22f (patch)
treefccf16ec9b798ab06913250073e003b2830d2817
parent08eca827b659f2becc872c151919948b5a9ffe4d (diff)
downloadmpd-5e26e2ab1dadb1e4176d5a4cac03100a7d21c22f.tar.gz
mpd-5e26e2ab1dadb1e4176d5a4cac03100a7d21c22f.tar.xz
mpd-5e26e2ab1dadb1e4176d5a4cac03100a7d21c22f.zip
system/ByteOrder: new library for byte ordering / endianess
Replacing GLib macros.
-rw-r--r--src/decoder/DsdiffDecoderPlugin.cxx11
-rw-r--r--src/decoder/DsfDecoderPlugin.cxx21
-rw-r--r--src/decoder/VorbisDecoderPlugin.cxx11
-rw-r--r--src/decoder/sidplay_decoder_plugin.cxx9
-rw-r--r--src/encoder/OpusEncoderPlugin.cxx9
-rw-r--r--src/encoder/WaveEncoderPlugin.cxx94
-rw-r--r--src/input/CdioParanoiaInputPlugin.cxx5
-rw-r--r--src/output/OSXOutputPlugin.cxx7
-rw-r--r--src/output/OssOutputPlugin.cxx5
-rw-r--r--src/pcm/PcmPack.cxx9
-rw-r--r--src/system/ByteOrder.hxx183
-rw-r--r--src/tag/Aiff.cxx5
-rw-r--r--src/tag/ApeLoader.cxx11
-rw-r--r--src/tag/Riff.cxx5
-rw-r--r--src/util/ByteReverse.cxx8
-rw-r--r--test/test_pcm_pack.cxx5
16 files changed, 289 insertions, 109 deletions
diff --git a/src/decoder/DsdiffDecoderPlugin.cxx b/src/decoder/DsdiffDecoderPlugin.cxx
index 43002768a..c4150dd91 100644
--- a/src/decoder/DsdiffDecoderPlugin.cxx
+++ b/src/decoder/DsdiffDecoderPlugin.cxx
@@ -33,6 +33,7 @@
#include "CheckAudioFormat.hxx"
#include "util/bit_reverse.h"
#include "util/Error.hxx"
+#include "system/ByteOrder.hxx"
#include "tag/TagHandler.hxx"
#include "DsdLib.hxx"
#include "Log.hxx"
@@ -56,8 +57,8 @@ struct DsdiffChunkHeader {
*/
gcc_const
uint64_t GetSize() const {
- return (((uint64_t)GUINT32_FROM_BE(size_high)) << 32) |
- ((uint64_t)GUINT32_FROM_BE(size_low));
+ return (uint64_t(FromBE32(size_high)) << 32) |
+ uint64_t(FromBE32(size_low));
}
};
@@ -141,7 +142,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
sizeof(sample_rate)))
return false;
- metadata->sample_rate = GUINT32_FROM_BE(sample_rate);
+ metadata->sample_rate = FromBE32(sample_rate);
} else if (dsdlib_id_equals(&header.id, "CHNL")) {
uint16_t channels;
if (header.GetSize() < sizeof(channels) ||
@@ -150,7 +151,7 @@ dsdiff_read_prop_snd(struct decoder *decoder, struct input_stream *is,
!dsdlib_skip_to(decoder, is, chunk_end_offset))
return false;
- metadata->channels = GUINT16_FROM_BE(channels);
+ metadata->channels = FromBE16(channels);
} else if (dsdlib_id_equals(&header.id, "CMPR")) {
struct dsdlib_id type;
if (header.GetSize() < sizeof(type) ||
@@ -211,7 +212,7 @@ dsdiff_handle_native_tag(struct input_stream *is,
if (!dsdlib_read(nullptr, is, &metatag, sizeof(metatag)))
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 */
if (length == 0 || length > 60)
diff --git a/src/decoder/DsfDecoderPlugin.cxx b/src/decoder/DsfDecoderPlugin.cxx
index 4c4a66aaa..28004e8b7 100644
--- a/src/decoder/DsfDecoderPlugin.cxx
+++ b/src/decoder/DsfDecoderPlugin.cxx
@@ -34,6 +34,7 @@
#include "CheckAudioFormat.hxx"
#include "util/bit_reverse.h"
#include "util/Error.hxx"
+#include "system/ByteOrder.hxx"
#include "DsdLib.hxx"
#include "tag/TagHandler.hxx"
#include "Log.hxx"
@@ -107,16 +108,16 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
!dsdlib_id_equals(&dsf_header.id, "DSD "))
return false;
- chunk_size = (((uint64_t)GUINT32_FROM_LE(dsf_header.size_high)) << 32) |
- ((uint64_t)GUINT32_FROM_LE(dsf_header.size_low));
+ chunk_size = (uint64_t(FromLE32(dsf_header.size_high)) << 32) |
+ uint64_t(FromLE32(dsf_header.size_low));
if (sizeof(dsf_header) != chunk_size)
return false;
#ifdef HAVE_ID3TAG
uint64_t metadata_offset;
- metadata_offset = (((uint64_t)GUINT32_FROM_LE(dsf_header.pmeta_high)) << 32) |
- ((uint64_t)GUINT32_FROM_LE(dsf_header.pmeta_low));
+ metadata_offset = (uint64_t(FromLE32(dsf_header.pmeta_high)) << 32) |
+ uint64_t(FromLE32(dsf_header.pmeta_low));
#endif
/* read the 'fmt ' chunk of the DSF file */
@@ -126,13 +127,13 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
return false;
uint64_t fmt_chunk_size;
- fmt_chunk_size = (((uint64_t)GUINT32_FROM_LE(dsf_fmt_chunk.size_high)) << 32) |
- ((uint64_t)GUINT32_FROM_LE(dsf_fmt_chunk.size_low));
+ fmt_chunk_size = (uint64_t(FromLE32(dsf_fmt_chunk.size_high)) << 32) |
+ uint64_t(FromLE32(dsf_fmt_chunk.size_low));
if (fmt_chunk_size != sizeof(dsf_fmt_chunk))
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
files with a sample freq of 2822400 Hz */
@@ -143,7 +144,7 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
|| samplefreq != 2822400)
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 */
if (chblksize != 4096)
return false;
@@ -158,8 +159,8 @@ dsf_read_metadata(struct decoder *decoder, struct input_stream *is,
we use the actual data size as chunk size */
uint64_t data_size;
- data_size = (((uint64_t)GUINT32_FROM_LE(data_chunk.size_high)) << 32) |
- ((uint64_t)GUINT32_FROM_LE(data_chunk.size_low));
+ data_size = (uint64_t(FromLE32(data_chunk.size_high)) << 32) |
+ uint64_t(FromLE32(data_chunk.size_low));
data_size -= sizeof(data_chunk);
metadata->chunk_size = data_size;
diff --git a/src/decoder/VorbisDecoderPlugin.cxx b/src/decoder/VorbisDecoderPlugin.cxx
index 9ef5e2eea..52e0609b8 100644
--- a/src/decoder/VorbisDecoderPlugin.cxx
+++ b/src/decoder/VorbisDecoderPlugin.cxx
@@ -27,6 +27,7 @@
#include "util/Error.hxx"
#include "util/UriUtil.hxx"
#include "util/Macros.hxx"
+#include "system/ByteOrder.hxx"
#include "CheckAudioFormat.hxx"
#include "tag/TagHandler.hxx"
#include "Log.hxx"
@@ -47,18 +48,10 @@
#define ov_time_seek_page(VF, S) (ov_time_seek_page(VF, (S)*1000))
#endif /* HAVE_TREMOR */
-#include <glib.h>
-
#include <assert.h>
#include <errno.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 decoder *decoder;
@@ -248,7 +241,7 @@ vorbis_stream_decode(struct decoder *decoder,
#ifdef HAVE_TREMOR
long nbytes = ov_read(&vf, buffer, sizeof(buffer),
- VORBIS_BIG_ENDIAN, 2, 1,
+ IsBigEndian(), 2, 1,
&current_section);
#else
float **per_channel;
diff --git a/src/decoder/sidplay_decoder_plugin.cxx b/src/decoder/sidplay_decoder_plugin.cxx
index 486dd816f..5123b493f 100644
--- a/src/decoder/sidplay_decoder_plugin.cxx
+++ b/src/decoder/sidplay_decoder_plugin.cxx
@@ -21,6 +21,7 @@
#include "../DecoderAPI.hxx"
#include "tag/TagHandler.hxx"
#include "util/Domain.hxx"
+#include "system/ByteOrder.hxx"
#include "Log.hxx"
#include <errno.h>
@@ -265,11 +266,9 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs)
config.sidEmulation = &builder;
config.sidModel = SID2_MODEL_CORRECT;
config.sidSamples = true;
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- config.sampleFormat = SID2_LITTLE_SIGNED;
-#else
- config.sampleFormat = SID2_BIG_SIGNED;
-#endif
+ config.sampleFormat = IsLittleEndian()
+ ? SID2_LITTLE_SIGNED
+ : SID2_BIG_SIGNED;
if (tune.isStereo()) {
config.playback = sid2_stereo;
channels = 2;
diff --git a/src/encoder/OpusEncoderPlugin.cxx b/src/encoder/OpusEncoderPlugin.cxx
index f3803e2ec..982fdd9a2 100644
--- a/src/encoder/OpusEncoderPlugin.cxx
+++ b/src/encoder/OpusEncoderPlugin.cxx
@@ -25,6 +25,7 @@
#include "ConfigError.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
+#include "system/ByteOrder.hxx"
#include <opus.h>
#include <ogg/ogg.h>
@@ -338,9 +339,9 @@ opus_encoder_generate_head(struct opus_encoder *encoder)
memcpy(header, "OpusHead", 8);
header[8] = 1;
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) =
- GUINT32_TO_LE(encoder->audio_format.sample_rate);
+ ToLE32(encoder->audio_format.sample_rate);
header[16] = 0;
header[17] = 0;
header[18] = 0;
@@ -365,9 +366,9 @@ opus_encoder_generate_tags(struct opus_encoder *encoder)
size_t comments_size = 8 + 4 + version_length + 4;
unsigned char *comments = (unsigned char *)g_malloc(comments_size);
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);
- *(uint32_t *)(comments + 12 + version_length) = GUINT32_TO_LE(0);
+ *(uint32_t *)(comments + 12 + version_length) = ToLE32(0);
ogg_packet packet;
packet.packet = comments;
diff --git a/src/encoder/WaveEncoderPlugin.cxx b/src/encoder/WaveEncoderPlugin.cxx
index 2b614c2f9..48cf3181f 100644
--- a/src/encoder/WaveEncoderPlugin.cxx
+++ b/src/encoder/WaveEncoderPlugin.cxx
@@ -20,6 +20,7 @@
#include "config.h"
#include "WaveEncoderPlugin.hxx"
#include "EncoderAPI.hxx"
+#include "system/ByteOrder.hxx"
#include "util/fifo_buffer.h"
extern "C" {
#include "util/growing_fifo.h"
@@ -62,24 +63,23 @@ fill_wave_header(struct wave_header *header, int channels, int bits,
int data_size = 0x0FFFFFFF;
/* constants */
- header->id_riff = GUINT32_TO_LE(0x46464952);
- header->id_wave = GUINT32_TO_LE(0x45564157);
- header->id_fmt = GUINT32_TO_LE(0x20746d66);
- header->id_data = GUINT32_TO_LE(0x61746164);
+ header->id_riff = ToLE32(0x46464952);
+ header->id_wave = ToLE32(0x45564157);
+ header->id_fmt = ToLE32(0x20746d66);
+ header->id_data = ToLE32(0x61746164);
/* wave format */
- header->format = GUINT16_TO_LE(1); // PCM_FORMAT
- header->channels = GUINT16_TO_LE(channels);
- header->bits = GUINT16_TO_LE(bits);
- header->freq = GUINT32_TO_LE(freq);
- header->blocksize = GUINT16_TO_LE(block_size);
- header->byterate = GUINT32_TO_LE(freq * block_size);
+ header->format = ToLE16(1); // PCM_FORMAT
+ header->channels = ToLE16(channels);
+ header->bits = ToLE16(bits);
+ header->freq = ToLE32(freq);
+ header->blocksize = ToLE16(block_size);
+ header->byterate = ToLE32(freq * block_size);
/* chunk sizes (fake data length) */
- header->fmt_size = GUINT32_TO_LE(16);
- header->data_size = GUINT32_TO_LE(data_size);
- header->riff_size = GUINT32_TO_LE(4 + (8 + 16) +
- (8 + data_size));
+ header->fmt_size = ToLE32(16);
+ header->data_size = ToLE32(data_size);
+ header->riff_size = ToLE32(4 + (8 + 16) + (8 + data_size));
}
static Encoder *
@@ -153,29 +153,29 @@ wave_encoder_close(Encoder *_encoder)
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)
{
size_t cnt = length >> 1;
while (cnt > 0) {
- *dst16++ = GUINT16_TO_LE(*src16++);
+ *dst16++ = ToLE16(*src16++);
cnt--;
}
return length;
}
-static inline size_t
+static size_t
pcm32_to_wave(uint32_t *dst32, const uint32_t *src32, size_t length)
{
size_t cnt = length >> 2;
while (cnt > 0){
- *dst32++ = GUINT32_TO_LE(*src32++);
+ *dst32++ = ToLE32(*src32++);
cnt--;
}
return length;
}
-static inline size_t
+static size_t
pcm24_to_wave(uint8_t *dst8, const uint32_t *src32, size_t length)
{
uint32_t value;
@@ -202,35 +202,35 @@ wave_encoder_write(Encoder *_encoder,
uint8_t *dst = (uint8_t *)growing_fifo_write(&encoder->buffer, length);
-#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
- switch (encoder->bits) {
- case 8:
- case 16:
- case 32:// optimized cases
- memcpy(dst, src, length);
- break;
- case 24:
- length = pcm24_to_wave(dst, (const uint32_t *)src, length);
- break;
- }
-#elif (G_BYTE_ORDER == G_BIG_ENDIAN)
- switch (encoder->bits) {
- case 8:
- memcpy(dst, src, length);
- break;
- case 16:
- length = pcm16_to_wave(dst, (const uint16_t *)src, length);
- break;
- case 24:
- length = pcm24_to_wave(dst, (const uint32_t *)src, length);
- break;
- case 32:
- length = pcm32_to_wave(dst, (const uint32_t *)src, length);
- break;
+ if (IsLittleEndian()) {
+ switch (encoder->bits) {
+ case 8:
+ case 16:
+ case 32:// optimized cases
+ memcpy(dst, src, length);
+ break;
+ case 24:
+ length = pcm24_to_wave(dst, (const uint32_t *)src, length);
+ break;
+ }
+ } else {
+ switch (encoder->bits) {
+ case 8:
+ memcpy(dst, src, length);
+ break;
+ case 16:
+ length = pcm16_to_wave((uint16_t *)dst,
+ (const uint16_t *)src, length);
+ break;
+ case 24:
+ length = pcm24_to_wave(dst, (const uint32_t *)src, length);
+ break;
+ case 32:
+ 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);
return true;
diff --git a/src/input/CdioParanoiaInputPlugin.cxx b/src/input/CdioParanoiaInputPlugin.cxx
index e7fc83571..344bdc975 100644
--- a/src/input/CdioParanoiaInputPlugin.cxx
+++ b/src/input/CdioParanoiaInputPlugin.cxx
@@ -28,6 +28,7 @@
#include "InputPlugin.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
+#include "system/ByteOrder.hxx"
#include "Log.hxx"
#include <stdio.h>
@@ -202,12 +203,12 @@ input_cdio_open(const char *uri,
case 0:
LogDebug(cdio_domain, "drive returns audio data Little Endian");
- reverse_endian = G_BYTE_ORDER == G_BIG_ENDIAN;
+ reverse_endian = IsBigEndian();
break;
case 1:
LogDebug(cdio_domain, "drive returns audio data Big Endian");
- reverse_endian = G_BYTE_ORDER == G_LITTLE_ENDIAN;
+ reverse_endian = IsLittleEndian();
break;
default:
diff --git a/src/output/OSXOutputPlugin.cxx b/src/output/OSXOutputPlugin.cxx
index eee215b32..7debe6ab2 100644
--- a/src/output/OSXOutputPlugin.cxx
+++ b/src/output/OSXOutputPlugin.cxx
@@ -25,9 +25,9 @@
#include "util/Domain.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
+#include "system/ByteOrder.hxx"
#include "Log.hxx"
-#include <glib.h>
#include <CoreAudio/AudioHardware.h>
#include <AudioUnit/AudioUnit.h>
#include <CoreServices/CoreServices.h>
@@ -342,9 +342,8 @@ osx_output_open(struct audio_output *ao, AudioFormat &audio_format,
break;
}
-#if G_BYTE_ORDER == G_BIG_ENDIAN
- stream_description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
-#endif
+ if (IsBigEndian())
+ stream_description.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
stream_description.mBytesPerPacket = audio_format.GetFrameSize();
stream_description.mFramesPerPacket = 1;
diff --git a/src/output/OssOutputPlugin.cxx b/src/output/OssOutputPlugin.cxx
index 147ad7975..68f2a38aa 100644
--- a/src/output/OssOutputPlugin.cxx
+++ b/src/output/OssOutputPlugin.cxx
@@ -25,10 +25,9 @@
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/Macros.hxx"
+#include "system/ByteOrder.hxx"
#include "Log.hxx"
-#include <glib.h>
-
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
@@ -532,7 +531,7 @@ oss_probe_sample_format(int fd, SampleFormat sample_format,
pcm_export.Open(sample_format, 0, false, false,
oss_format == AFMT_S24_PACKED,
oss_format == AFMT_S24_PACKED &&
- G_BYTE_ORDER != G_LITTLE_ENDIAN);
+ !IsLittleEndian());
#endif
return SUCCESS;
diff --git a/src/pcm/PcmPack.cxx b/src/pcm/PcmPack.cxx
index fa020bf63..8920eb288 100644
--- a/src/pcm/PcmPack.cxx
+++ b/src/pcm/PcmPack.cxx
@@ -18,15 +18,14 @@
*/
#include "PcmPack.hxx"
-
-#include <glib.h>
+#include "system/ByteOrder.hxx"
static void
pack_sample(uint8_t *dest, const int32_t *src0)
{
const uint8_t *src = (const uint8_t *)src0;
- if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ if (IsBigEndian())
++src;
*dest++ = *src++;
@@ -51,7 +50,7 @@ unpack_sample(int32_t *dest0, const uint8_t *src)
{
uint8_t *dest = (uint8_t *)dest0;
- if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ if (IsBigEndian())
/* extend the sign bit to the most fourth byte */
*dest++ = *src & 0x80 ? 0xff : 0x00;
@@ -59,7 +58,7 @@ unpack_sample(int32_t *dest0, const uint8_t *src)
*dest++ = *src++;
*dest++ = *src;
- if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
+ if (IsLittleEndian())
/* extend the sign bit to the most fourth byte */
*dest++ = *src & 0x80 ? 0xff : 0x00;
}
diff --git a/src/system/ByteOrder.hxx b/src/system/ByteOrder.hxx
new file mode 100644
index 000000000..a070cd5d0
--- /dev/null
+++ b/src/system/ByteOrder.hxx
@@ -0,0 +1,183 @@
+/*
+ * 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
diff --git a/src/tag/Aiff.cxx b/src/tag/Aiff.cxx
index 51622fec7..4135565f7 100644
--- a/src/tag/Aiff.cxx
+++ b/src/tag/Aiff.cxx
@@ -20,6 +20,7 @@
#include "config.h" /* must be first for large file support */
#include "Aiff.hxx"
#include "util/Domain.hxx"
+#include "system/ByteOrder.hxx"
#include "Log.hxx"
#include <glib.h>
@@ -65,7 +66,7 @@ aiff_seek_id3(FILE *file)
size_t size = fread(&header, sizeof(header), 1, file);
if (size != 1 ||
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, "AIFC", 4) != 0))
/* not a AIFF file */
@@ -79,7 +80,7 @@ aiff_seek_id3(FILE *file)
if (size != 1)
return 0;
- size = GUINT32_FROM_BE(chunk.size);
+ size = FromBE32(chunk.size);
if (size > G_MAXINT32)
/* too dangerous, bail out: possible integer
underflow when casting to off_t */
diff --git a/src/tag/ApeLoader.cxx b/src/tag/ApeLoader.cxx
index dfbdb4ef3..19f4d06d4 100644
--- a/src/tag/ApeLoader.cxx
+++ b/src/tag/ApeLoader.cxx
@@ -19,6 +19,7 @@
#include "config.h"
#include "ApeLoader.hxx"
+#include "system/ByteOrder.hxx"
#include <glib.h>
@@ -44,11 +45,11 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback)
if (fseek(fp, -(long)sizeof(footer), SEEK_END) ||
fread(&footer, 1, sizeof(footer), fp) != sizeof(footer) ||
memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0 ||
- GUINT32_FROM_LE(footer.version) != 2000)
+ FromLE32(footer.version) != 2000)
return false;
/* find beginning of ape tag */
- size_t remaining = GUINT32_FROM_LE(footer.length);
+ size_t remaining = FromLE32(footer.length);
if (remaining <= sizeof(footer) + 10 ||
/* refuse to load more than one megabyte of tag data */
remaining > 1024 * 1024 ||
@@ -66,13 +67,13 @@ ape_scan_internal(FILE *fp, ApeTagCallback callback)
}
/* read tags */
- unsigned n = GUINT32_FROM_LE(footer.count);
+ unsigned n = FromLE32(footer.count);
const char *p = buffer;
while (n-- && remaining > 10) {
- size_t size = GUINT32_FROM_LE(*(const uint32_t *)p);
+ size_t size = FromLE32(*(const uint32_t *)p);
p += 4;
remaining -= 4;
- unsigned long flags = GUINT32_FROM_LE(*(const uint32_t *)p);
+ unsigned long flags = FromLE32(*(const uint32_t *)p);
p += 4;
remaining -= 4;
diff --git a/src/tag/Riff.cxx b/src/tag/Riff.cxx
index d756ebc30..3728d281c 100644
--- a/src/tag/Riff.cxx
+++ b/src/tag/Riff.cxx
@@ -20,6 +20,7 @@
#include "config.h" /* must be first for large file support */
#include "Riff.hxx"
#include "util/Domain.hxx"
+#include "system/ByteOrder.hxx"
#include "Log.hxx"
#include <glib.h>
@@ -65,7 +66,7 @@ riff_seek_id3(FILE *file)
size_t size = fread(&header, sizeof(header), 1, file);
if (size != 1 ||
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 */
return 0;
@@ -77,7 +78,7 @@ riff_seek_id3(FILE *file)
if (size != 1)
return 0;
- size = GUINT32_FROM_LE(chunk.size);
+ size = FromLE32(chunk.size);
if (size > G_MAXINT32)
/* too dangerous, bail out: possible integer
underflow when casting to off_t */
diff --git a/src/util/ByteReverse.cxx b/src/util/ByteReverse.cxx
index d1d0a935a..910c1e2a5 100644
--- a/src/util/ByteReverse.cxx
+++ b/src/util/ByteReverse.cxx
@@ -18,9 +18,9 @@
*/
#include "ByteReverse.hxx"
+#include "system/ByteOrder.hxx"
#include "Compiler.h"
-#include <glib.h>
#include <assert.h>
void
@@ -33,7 +33,7 @@ reverse_bytes_16(uint16_t *gcc_restrict dest,
while (src < src_end) {
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,
while (src < src_end) {
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,
while (src < src_end) {
const uint64_t x = *src++;
- *dest++ = GUINT64_SWAP_LE_BE(x);
+ *dest++ = ByteSwap64(x);
}
}
diff --git a/test/test_pcm_pack.cxx b/test/test_pcm_pack.cxx
index 4c105ce08..49840ddb0 100644
--- a/test/test_pcm_pack.cxx
+++ b/test/test_pcm_pack.cxx
@@ -20,6 +20,7 @@
#include "test_pcm_all.hxx"
#include "test_pcm_util.hxx"
#include "pcm/PcmPack.hxx"
+#include "system/ByteOrder.hxx"
#include <glib.h>
@@ -34,7 +35,7 @@ test_pcm_pack_24()
for (unsigned i = 0; i < N; ++i) {
int32_t d;
- if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ if (IsBigEndian())
d = (dest[i * 3] << 16) | (dest[i * 3 + 1] << 8)
| dest[i * 3 + 2];
else
@@ -58,7 +59,7 @@ test_pcm_unpack_24()
for (unsigned i = 0; i < N; ++i) {
int32_t s;
- if (G_BYTE_ORDER == G_BIG_ENDIAN)
+ if (IsBigEndian())
s = (src[i * 3] << 16) | (src[i * 3 + 1] << 8)
| src[i * 3 + 2];
else