File 70-endian-fixes.dpatch of Package gramofile

# Fix endianness bugs in WAV and VOC headers on big-endian archs.
# Use POSIX size types to avoid broken headers on 64bit archs.
# Disable padding in structs that read/write raw on-disk data.
# Merged with endianness patch by Tom Harvey <TomHarvey@IndustryFigure.com>
# [dk]

Index: bplaysrc/bplay.c
===================================================================
--- bplaysrc/bplay.c.orig	2012-04-20 16:01:14.461139421 +0200
+++ bplaysrc/bplay.c	2012-04-20 16:03:12.609289818 +0200
@@ -30,6 +30,30 @@
 #include <machine/soundcard.h>
 #endif
 
+/* Needed for BYTE_ORDER and BIG/LITTLE_ENDIAN macros. */
+#ifndef _BSD_SOURCE
+# define _BSD_SOURCE
+# include <endian.h>
+# undef  _BSD_SOURCE
+#else
+# include <endian.h>
+#endif
+
+#include <sys/types.h>
+#include <byteswap.h>
+
+/* Adapted from the byteorder macros in the Linux kernel. */
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define cpu_to_le32(x) (x)
+#define cpu_to_le16(x) (x)
+#else
+#define cpu_to_le32(x) bswap_32((x))
+#define cpu_to_le16(x) bswap_16((x))
+#endif
+
+#define le32_to_cpu(x)	cpu_to_le32((x))
+#define le16_to_cpu(x)	cpu_to_le16((x))
+
 #include "fmtheaders.h"
 
 #include "../yesnowindow.h"
@@ -287,23 +311,26 @@ int main(int argc, char *argv[])
 				char *data = "data";
 
 				memcpy(&(header.main_chunk), riff, 4);
-				header.length = sizeof(wavhead) - 8 + bcount;
+				header.length = cpu_to_le32(sizeof(wavhead)
+						- 8 + bcount);
 				memcpy(&(header.chunk_type), wave, 4);
 
 				memcpy(&(header.sub_chunk), fmt, 4);
-				header.sc_len = 16;
-				header.format = 1;
-				header.modus = stereo + 1;
-				header.sample_fq = speed;
-				header.byte_p_sec = ((bits > 8)? 2:1)*(stereo+1)*speed;
+				header.sc_len = cpu_to_le32(16);
+				header.format = cpu_to_le16(1);
+				header.modus = cpu_to_le16(stereo + 1);
+				header.sample_fq = cpu_to_le32(speed);
+				header.byte_p_sec = cpu_to_le32(((bits > 8)?
+						2:1)*(stereo+1)*speed);
 /* Correction by J.A. Bezemer: */
-				header.byte_p_spl = ((bits > 8)? 2:1)*(stereo+1);
+				header.byte_p_spl = cpu_to_le16(((bits > 8)?
+						2:1)*(stereo+1));
 			/* was: header.byte_p_spl = (bits > 8)? 2:1; */
 
-				header.bit_p_spl = bits;
+				header.bit_p_spl = cpu_to_le16(bits);
 
 				memcpy(&(header.data_chunk), data, 4);
-				header.data_length = bcount;
+				header.data_length = cpu_to_le32(bcount);
 				write(thefd, &header, sizeof(header));
 			}
 		case F_RAW:
@@ -333,9 +360,9 @@ int main(int argc, char *argv[])
 
 				for (i=0;i<20;i++)
 					header.Magic[i] = VOC_MAGIC[i];
-				header.BlockOffset = 0x1a;
-				header.Version = 0x0114;
-				header.IDCode = 0x111F;
+				header.BlockOffset = cpu_to_le16(0x1a);
+				header.Version = cpu_to_le16(0x0114);
+				header.IDCode = cpu_to_le16(0x111F);
 				write(thefd, &header, sizeof(vochead));
 
 				snd_parm(speed, bits, stereo);
@@ -346,10 +373,10 @@ int main(int argc, char *argv[])
 				ablk.BlockLen[0] = (i + 12) & 0xFF;
 				ablk.BlockLen[1] = ((i + 12) >> 8) & 0xFF;
 				ablk.BlockLen[2] = ((i + 12) >> 16) & 0xFF;
-				bblk.SamplesPerSec = speed;
+				bblk.SamplesPerSec = cpu_to_le32(speed);
 				bblk.BitsPerSample = bits;
 				bblk.Channels = stereo + 1;
-				bblk.Format = (bits == 8)? 0 : 4;
+				bblk.Format = cpu_to_le16((bits == 8)? 0 : 4);
 				write(thefd, &ablk, sizeof(ablk));
 				write(thefd, &bblk, sizeof(bblk));
 				shmrec(thefd, i, 1);
@@ -473,6 +500,17 @@ long bcount = 0, bjump = 0;
 
     memcpy((void*)&wavhd, (void*)hd_buf, 20);
     count = read(thefd, ((char*)&wavhd)+20, sizeof(wavhd) - 20);
+
+    wavhd.length = le32_to_cpu(wavhd.length);
+    wavhd.sc_len = le32_to_cpu(wavhd.sc_len);
+    wavhd.format = le16_to_cpu(wavhd.format);
+    wavhd.modus = le16_to_cpu(wavhd.modus);
+    wavhd.sample_fq = le32_to_cpu(wavhd.sample_fq);
+    wavhd.byte_p_sec = le32_to_cpu(wavhd.byte_p_sec);
+    wavhd.byte_p_spl = le16_to_cpu(wavhd.byte_p_spl);
+    wavhd.bit_p_spl = le16_to_cpu(wavhd.bit_p_spl);
+    wavhd.data_length = le32_to_cpu(wavhd.data_length);
+
     if(wavhd.format != 1) Die("Input is not a PCM WAV file");
 #ifndef LP2CD
     if (! (mods&MSPEED))
@@ -515,6 +553,11 @@ void playvoc(int thefd, char hd_buf[20])
     fprintf(stderr, "Playing Creative Labs Voice file ...\n");
     memcpy((void*)&vochd, (void*)hd_buf, 20);
     count = read(thefd, ((char*)&vochd)+20, sizeof(vochd) - 20);
+
+    vochd.BlockOffset = le16_to_cpu(vochd.BlockOffset);
+    vochd.Version = le16_to_cpu(vochd.Version);
+    vochd.IDCode = le16_to_cpu(vochd.IDCode);
+
     fprintf(stderr, "Format version %d.%d\n", vochd.Version>>8,
 	vochd.Version&0xFF);
     if (vochd.IDCode != (~vochd.Version+0x1234))
@@ -563,6 +606,9 @@ void playvoc(int thefd, char hd_buf[20])
 	{
 	blockT8 tblock;
 	read(thefd, (char*)&tblock, sizeof(tblock));
+
+	tblock.TimeConstant = le16_to_cpu(tblock.TimeConstant);
+
 	if(tblock.PackMethod != 0) Die("Non PCM VOC block");
 	speed = 256000000/(65536 - tblock.TimeConstant);
 	bits = 8;
@@ -575,6 +621,10 @@ void playvoc(int thefd, char hd_buf[20])
 	{
 	blockT9 tblock;
 	read(thefd, (char*)&tblock, sizeof(tblock));
+
+	tblock.SamplesPerSec = le32_to_cpu(tblock.SamplesPerSec);
+	tblock.Format = le16_to_cpu(tblock.Format);
+
 	if(tblock.Format != 0 && tblock.Format != 4)
 	    Die("Non PCM VOC block");
 	speed = tblock.SamplesPerSec;
Index: bplaysrc/fmtheaders.h
===================================================================
--- bplaysrc/fmtheaders.h.orig	1997-02-10 21:32:20.000000000 +0100
+++ bplaysrc/fmtheaders.h	2012-04-20 16:02:36.361164344 +0200
@@ -3,44 +3,50 @@
 
 #include <sys/types.h>
 
+#ifdef __GNUC__
+# define PACKED(x)      __attribute__((packed)) x
+#else
+# define PACKED(x)	x
+#endif
+
 /* Definitions for .VOC files */
 
 #define VOC_MAGIC	"Creative Voice File\032"
 
-#define DATALEN(bp)	((u_long)(bp.BlockLen[0]) | \
-                         ((u_long)(bp.BlockLen[1]) << 8) | \
-                         ((u_long)(bp.BlockLen[2]) << 16) )
+#define DATALEN(bp)	((u_int32_t)(bp.BlockLen[0]) | \
+                         ((u_int32_t)(bp.BlockLen[1]) << 8) | \
+                         ((u_int32_t)(bp.BlockLen[2]) << 16) )
 
 typedef struct vochead {
-  u_char  Magic[20];	/* must be VOC_MAGIC */
-  u_short BlockOffset;	/* Offset to first block from top of file */
-  u_short Version;	/* VOC-file version */
-  u_short IDCode;	/* complement of version + 0x1234 */
-} vochead;
+  u_int8_t  Magic[20];	/* must be VOC_MAGIC */
+  u_int16_t BlockOffset;	/* Offset to first block from top of file */
+  u_int16_t Version;	/* VOC-file version */
+  u_int16_t IDCode;	/* complement of version + 0x1234 */
+} PACKED(vochead);
 
 typedef struct blockTC {
-  u_char  BlockID;
-  u_char  BlockLen[3];	/* low, mid, high byte of length of rest of block */
-} blockTC;
+  u_int8_t  BlockID;
+  u_int8_t  BlockLen[3];	/* low, mid, high byte of length of rest of block */
+} PACKED(blockTC);
 
 typedef struct blockT1 {
-  u_char  TimeConstant;
-  u_char  PackMethod;
-} blockT1;
+  u_int8_t  TimeConstant;
+  u_int8_t  PackMethod;
+} PACKED(blockT1);
 
 typedef struct blockT8 {
-  u_short TimeConstant;
-  u_char  PackMethod;
-  u_char  VoiceMode;
-} blockT8;
+  u_int16_t TimeConstant;
+  u_int8_t  PackMethod;
+  u_int8_t  VoiceMode;
+} PACKED(blockT8);
 
 typedef struct blockT9 {
-  u_int   SamplesPerSec;
-  u_char  BitsPerSample;
-  u_char  Channels;
-  u_short Format;
-  u_char   reserved[4];
-} blockT9;
+  u_int32_t SamplesPerSec;
+  u_int8_t  BitsPerSample;
+  u_int8_t  Channels;
+  u_int16_t Format;
+  u_int8_t  reserved[4];
+} PACKED(blockT9);
   
 
 
@@ -51,21 +57,21 @@ typedef struct blockT9 {
    it works on all WAVE-file I have
 */
 typedef struct wavhead {
-  u_long	main_chunk;	/* 'RIFF' */
-  u_long	length;		/* Length of rest of file */
-  u_long	chunk_type;	/* 'WAVE' */
-
-  u_long	sub_chunk;	/* 'fmt ' */
-  u_long	sc_len;		/* length of sub_chunk, =16 (rest of chunk) */
-  u_short	format;		/* should be 1 for PCM-code */
-  u_short	modus;		/* 1 Mono, 2 Stereo */
-  u_long	sample_fq;	/* frequence of sample */
-  u_long	byte_p_sec;
-  u_short	byte_p_spl;	/* samplesize; 1 or 2 bytes */
-  u_short	bit_p_spl;	/* 8, 12 or 16 bit */ 
-
-  u_long	data_chunk;	/* 'data' */
-  u_long	data_length;	/* samplecount (lenth of rest of block?)*/
-} wavhead;
+  u_int32_t	main_chunk;	/* 'RIFF' */
+  u_int32_t	length;		/* Length of rest of file */
+  u_int32_t	chunk_type;	/* 'WAVE' */
+
+  u_int32_t	sub_chunk;	/* 'fmt ' */
+  u_int32_t	sc_len;		/* length of sub_chunk, =16 (rest of chunk) */
+  u_int16_t	format;		/* should be 1 for PCM-code */
+  u_int16_t	modus;		/* 1 Mono, 2 Stereo */
+  u_int32_t	sample_fq;	/* frequence of sample */
+  u_int32_t	byte_p_sec;
+  u_int16_t	byte_p_spl;	/* samplesize; 1 or 2 bytes */
+  u_int16_t	bit_p_spl;	/* 8, 12 or 16 bit */
+
+  u_int32_t	data_chunk;	/* 'data' */
+  u_int32_t	data_length;	/* samplecount (lenth of rest of block?)*/
+} PACKED(wavhead);
 
 #endif
Index: bplaysrc/sndfunc.c
===================================================================
--- bplaysrc/sndfunc.c.orig	2012-04-20 16:01:14.446139781 +0200
+++ bplaysrc/sndfunc.c	2012-04-20 16:01:14.494138625 +0200
@@ -66,6 +66,9 @@ void snd_parm(int speed, int bits, int s
 	sync_audio();
 
 	/* Set the sample speed, size and stereoness */
+	/* We only use values of 8 and 16 for bits. This implies
+	 * unsigned data for 8 bits, and little-endian signed for 16 bits.
+	 */
 	if (ioctl(audio, SNDCTL_DSP_SAMPLESIZE, &bits) < 0)
 	    ErrDie(AUDIO);
 	if (ioctl(audio, SNDCTL_DSP_STEREO, &stereo) < 0)
Index: endian.c
===================================================================
--- endian.c.orig	2000-03-28 23:07:25.000000000 +0200
+++ endian.c	2012-04-20 16:01:14.494138625 +0200
@@ -24,10 +24,10 @@ SwapTwo (short w)
   return (tmp);
 }
 
-u_long
-SwapFourBytes (u_long dw)
+u_int32_t
+SwapFourBytes (u_int32_t dw)
 {
-  register u_long tmp;
+  register u_int32_t tmp;
   tmp = (dw & 0x000000FF);
   tmp = ((dw & 0x0000FF00) >> 0x08) | (tmp << 0x08);
   tmp = ((dw & 0x00FF0000) >> 0x10) | (tmp << 0x08);
Index: endian.h
===================================================================
--- endian.h.orig	2012-04-20 16:01:14.469139227 +0200
+++ endian.h	2012-04-20 16:01:14.494138625 +0200
@@ -4,8 +4,10 @@
 #ifndef _GETBIG
 #define _GETBIG 1
 
+#include <sys/types.h>
+
 extern u_short SwapTwoBytes (u_short);
-extern u_long SwapFourBytes (u_long);
+extern u_int32_t SwapFourBytes (u_int32_t);
 extern sample_t SwapSample (sample_t);
 
 /* macro to swap endianness of values in a sample_t with */
Index: fmtheaders.h
===================================================================
--- fmtheaders.h.orig	2000-03-28 23:07:26.000000000 +0200
+++ fmtheaders.h	2012-04-20 16:02:18.449596395 +0200
@@ -3,54 +3,50 @@
 
 #include <sys/types.h>
 
+#ifdef __GNUC__
+# define PACKED(x)      __attribute__((packed)) x
+#else
+# define PACKED(x)	x
+#endif
+
 /* Definitions for .VOC files */
 
 #define VOC_MAGIC	"Creative Voice File\032"
 
-#define DATALEN(bp)	((u_long)(bp.BlockLen[0]) | \
-                         ((u_long)(bp.BlockLen[1]) << 8) | \
-                         ((u_long)(bp.BlockLen[2]) << 16) )
-
-typedef struct vochead
-  {
-    u_char Magic[20];		/* must be VOC_MAGIC */
-    u_short BlockOffset;	/* Offset to first block from top of file */
-    u_short Version;		/* VOC-file version */
-    u_short IDCode;		/* complement of version + 0x1234 */
-  }
-vochead;
-
-typedef struct blockTC
-  {
-    u_char BlockID;
-    u_char BlockLen[3];		/* low, mid, high byte of length of rest of block */
-  }
-blockTC;
-
-typedef struct blockT1
-  {
-    u_char TimeConstant;
-    u_char PackMethod;
-  }
-blockT1;
-
-typedef struct blockT8
-  {
-    u_short TimeConstant;
-    u_char PackMethod;
-    u_char VoiceMode;
-  }
-blockT8;
-
-typedef struct blockT9
-  {
-    u_int SamplesPerSec;
-    u_char BitsPerSample;
-    u_char Channels;
-    u_short Format;
-    u_char reserved[4];
-  }
-blockT9;
+#define DATALEN(bp)	((u_int32_t)(bp.BlockLen[0]) | \
+                         ((u_int32_t)(bp.BlockLen[1]) << 8) | \
+                         ((u_int32_t)(bp.BlockLen[2]) << 16) )
+
+typedef struct vochead {
+  u_int8_t  Magic[20];	/* must be VOC_MAGIC */
+  u_int16_t BlockOffset;	/* Offset to first block from top of file */
+  u_int16_t Version;	/* VOC-file version */
+  u_int16_t IDCode;	/* complement of version + 0x1234 */
+} PACKED(vochead);
+
+typedef struct blockTC {
+  u_int8_t  BlockID;
+  u_int8_t  BlockLen[3];	/* low, mid, high byte of length of rest of block */
+} PACKED(blockTC);
+
+typedef struct blockT1 {
+  u_int8_t  TimeConstant;
+  u_int8_t  PackMethod;
+} PACKED(blockT1);
+
+typedef struct blockT8 {
+  u_int16_t TimeConstant;
+  u_int8_t  PackMethod;
+  u_int8_t  VoiceMode;
+} PACKED(blockT8);
+
+typedef struct blockT9 {
+  u_int32_t SamplesPerSec;
+  u_int8_t  BitsPerSample;
+  u_int8_t  Channels;
+  u_int16_t Format;
+  u_int8_t  reserved[4];
+} PACKED(blockT9);
 
 
 
@@ -59,25 +55,23 @@ blockT9;
 /* it's in chunks like .voc and AMIGA iff, but my source say there
    are in only in this combination, so I combined them in one header;
    it works on all WAVE-file I have
- */
-typedef struct wavhead
-  {
-    u_long main_chunk;		/* 'RIFF' */
-    u_long length;		/* Length of rest of file */
-    u_long chunk_type;		/* 'WAVE' */
-
-    u_long sub_chunk;		/* 'fmt ' */
-    u_long sc_len;		/* length of sub_chunk, =16 (rest of chunk) */
-    u_short format;		/* should be 1 for PCM-code */
-    u_short modus;		/* 1 Mono, 2 Stereo */
-    u_long sample_fq;		/* frequence of sample */
-    u_long byte_p_sec;
-    u_short byte_p_spl;		/* samplesize; 1 or 2 bytes */
-    u_short bit_p_spl;		/* 8, 12 or 16 bit */
-
-    u_long data_chunk;		/* 'data' */
-    u_long data_length;		/* samplecount (lenth of rest of block?) */
-  }
-wavhead;
+*/
+typedef struct wavhead {
+  u_int32_t	main_chunk;	/* 'RIFF' */
+  u_int32_t	length;		/* Length of rest of file */
+  u_int32_t	chunk_type;	/* 'WAVE' */
+
+  u_int32_t	sub_chunk;	/* 'fmt ' */
+  u_int32_t	sc_len;		/* length of sub_chunk, =16 (rest of chunk) */
+  u_int16_t	format;		/* should be 1 for PCM-code */
+  u_int16_t	modus;		/* 1 Mono, 2 Stereo */
+  u_int32_t	sample_fq;	/* frequence of sample */
+  u_int32_t	byte_p_sec;
+  u_int16_t	byte_p_spl;	/* samplesize; 1 or 2 bytes */
+  u_int16_t	bit_p_spl;	/* 8, 12 or 16 bit */
+
+  u_int32_t	data_chunk;	/* 'data' */
+  u_int32_t	data_length;	/* samplecount (lenth of rest of block?)*/
+} PACKED(wavhead);
 
 #endif