Browse Source

added an endianness check in VorbisDecoder.cpp

bill@Ixion 16 years ago
parent
commit
b8677cebd0
3 changed files with 144 additions and 127 deletions
  1. 26 18
      src/common/config.h
  2. 105 97
      src/modules/sound/lullaby/VorbisDecoder.cpp
  3. 13 12
      src/modules/sound/lullaby/VorbisDecoder.h

+ 26 - 18
src/common/config.h

@@ -1,21 +1,21 @@
-/**
-* Copyright (c) 2006-2009 LOVE Development Team
-* 
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* 
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 
-* 1. The origin of this software must not be misrepresented; you must not
-*    claim that you wrote the original software. If you use this software
-*    in a product, an acknowledgment in the product documentation would be
-*    appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-*    misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
 **/
 
 #ifndef LOVE_CONFIG_H
@@ -35,6 +35,14 @@
 #	define LOVE_MACOS 1
 #endif
 
+// Endianness.
+#if defined(__i386__) || defined(__i386)
+#	define LOVE_LITTLE_ENDIAN 1
+#endif
+#if defined(__ppc__) || defined(__ppc)
+#	define LOVE_BIG_ENDIAN 1
+#endif
+
 // Warnings.
 #ifndef _CRT_SECURE_NO_WARNINGS
 #	define _CRT_SECURE_NO_WARNINGS

+ 105 - 97
src/modules/sound/lullaby/VorbisDecoder.cpp

@@ -21,6 +21,7 @@
 #include "VorbisDecoder.h"
 
 #include <string.h>
+#include <common/config.h>
 #include <common/Exception.h>
 
 namespace love
@@ -32,41 +33,41 @@ namespace lullaby
 	/**
 	* CALLBACK FUNCTIONS
 	**/
-	int vorbisClose(void * datasource	/* ptr to the data that the vorbis files need*/)
-	{
-		// Does nothing (handled elsewhere)
-		return 1;
+	int vorbisClose(void * datasource	/* ptr to the data that the vorbis files need*/)
+	{
+		// Does nothing (handled elsewhere)
+		return 1;
 	}
 
-	size_t vorbisRead(void * ptr		/* ptr to the data that the vorbis files need*/, 
-					  size_t byteSize	/* how big a byte is*/, 
-					  size_t sizeToRead	/* How much we can read*/, 
+	size_t vorbisRead(void * ptr		/* ptr to the data that the vorbis files need*/, 
+					  size_t byteSize	/* how big a byte is*/, 
+					  size_t sizeToRead	/* How much we can read*/, 
 					  void * datasource	/* this is a pointer to the data we passed into ov_open_callbacks (our SOggFile struct*/)
 	{
-		size_t				spaceToEOF;			// How much more we can read till we hit the EOF marker
-		size_t				actualSizeToRead;	// How much data we are actually going to read from memory
-		SOggFile*			vorbisData;			// Our vorbis data, for the typecast
-
-		// Get the data in the right format
-		vorbisData = (SOggFile*)datasource;
-
-		// Calculate how much we need to read.  This can be sizeToRead*byteSize or less depending on how near the EOF marker we are
-		spaceToEOF = vorbisData->dataSize - vorbisData->dataRead;
-		if ((sizeToRead*byteSize) < spaceToEOF)
-			actualSizeToRead = (sizeToRead*byteSize);
-		else
-			actualSizeToRead = spaceToEOF;	
-		
-		// A simple copy of the data from memory to the datastruct that the vorbis libs will use
-		if (actualSizeToRead)
-		{
-			// Copy the data from the start of the file PLUS how much we have already read in
-			memcpy(ptr, (char*)vorbisData->dataPtr + vorbisData->dataRead, actualSizeToRead);
-			// Increase by how much we have read by
-			vorbisData->dataRead += (actualSizeToRead);
-		}
-
-		// Return how much we read (in the same way fread would)
+		size_t				spaceToEOF;			// How much more we can read till we hit the EOF marker
+		size_t				actualSizeToRead;	// How much data we are actually going to read from memory
+		SOggFile*			vorbisData;			// Our vorbis data, for the typecast
+
+		// Get the data in the right format
+		vorbisData = (SOggFile*)datasource;
+
+		// Calculate how much we need to read.  This can be sizeToRead*byteSize or less depending on how near the EOF marker we are
+		spaceToEOF = vorbisData->dataSize - vorbisData->dataRead;
+		if ((sizeToRead*byteSize) < spaceToEOF)
+			actualSizeToRead = (sizeToRead*byteSize);
+		else
+			actualSizeToRead = spaceToEOF;	
+		
+		// A simple copy of the data from memory to the datastruct that the vorbis libs will use
+		if (actualSizeToRead)
+		{
+			// Copy the data from the start of the file PLUS how much we have already read in
+			memcpy(ptr, (char*)vorbisData->dataPtr + vorbisData->dataRead, actualSizeToRead);
+			// Increase by how much we have read by
+			vorbisData->dataRead += (actualSizeToRead);
+		}
+
+		// Return how much we read (in the same way fread would)
 		return actualSizeToRead;
 	}
 
@@ -74,43 +75,43 @@ namespace lullaby
 				   ogg_int64_t offset	/*offset from the point we wish to seek to*/,
 				   int whence			/*where we want to seek to*/)
 	{
-		size_t				spaceToEOF;		// How much more we can read till we hit the EOF marker
-		ogg_int64_t			actualOffset;	// How much we can actually offset it by
-		SOggFile*			vorbisData;		// The data we passed in (for the typecast)
-
-		// Get the data in the right format
-		vorbisData = (SOggFile*) datasource;
-
-		// Goto where we wish to seek to
-		switch (whence)
-		{
-		case SEEK_SET: // Seek to the start of the data file
-			// Make sure we are not going to the end of the file
-			if (vorbisData->dataSize >= offset)
-				actualOffset = offset;
-			else
-				actualOffset = vorbisData->dataSize;
-			// Set where we now are
-			vorbisData->dataRead = (int)actualOffset;
-			break;
-		case SEEK_CUR: // Seek from where we are
-			// Make sure we dont go past the end
-			spaceToEOF = vorbisData->dataSize - vorbisData->dataRead;
-			if (offset < spaceToEOF)
-				actualOffset = (offset);
-			else
-				actualOffset = spaceToEOF;	
-			// Seek from our currrent location
-			vorbisData->dataRead += (int)actualOffset;
-			break;
-		case SEEK_END: // Seek from the end of the file
-			vorbisData->dataRead = vorbisData->dataSize+1;
-			break;
-		default:
-			throw love::Exception("Unknown seek command in vorbisSeek\n");
-			break;
-		};
-
+		size_t				spaceToEOF;		// How much more we can read till we hit the EOF marker
+		ogg_int64_t			actualOffset;	// How much we can actually offset it by
+		SOggFile*			vorbisData;		// The data we passed in (for the typecast)
+
+		// Get the data in the right format
+		vorbisData = (SOggFile*) datasource;
+
+		// Goto where we wish to seek to
+		switch (whence)
+		{
+		case SEEK_SET: // Seek to the start of the data file
+			// Make sure we are not going to the end of the file
+			if (vorbisData->dataSize >= offset)
+				actualOffset = offset;
+			else
+				actualOffset = vorbisData->dataSize;
+			// Set where we now are
+			vorbisData->dataRead = (int)actualOffset;
+			break;
+		case SEEK_CUR: // Seek from where we are
+			// Make sure we dont go past the end
+			spaceToEOF = vorbisData->dataSize - vorbisData->dataRead;
+			if (offset < spaceToEOF)
+				actualOffset = (offset);
+			else
+				actualOffset = spaceToEOF;	
+			// Seek from our currrent location
+			vorbisData->dataRead += (int)actualOffset;
+			break;
+		case SEEK_END: // Seek from the end of the file
+			vorbisData->dataRead = vorbisData->dataSize+1;
+			break;
+		default:
+			throw love::Exception("Unknown seek command in vorbisSeek\n");
+			break;
+		};
+
 		return 0;
 	}
 
@@ -127,11 +128,18 @@ namespace lullaby
 	VorbisDecoder::VorbisDecoder(Data * data, const std::string & ext, int bufferSize, int sampleRate)
 		: Decoder(data, ext, bufferSize, sampleRate)
 	{
-		// Initialize callbacks
-		vorbisCallbacks.close_func = vorbisClose;
-		vorbisCallbacks.seek_func  = vorbisSeek;
-		vorbisCallbacks.read_func  = vorbisRead;
+		// Initialize callbacks
+		vorbisCallbacks.close_func = vorbisClose;
+		vorbisCallbacks.seek_func  = vorbisSeek;
+		vorbisCallbacks.read_func  = vorbisRead;
 		vorbisCallbacks.tell_func  = vorbisTell;
+		
+		// Check endianness
+#ifdef LOVE_BIG_ENDIAN
+		endian = 1;
+#else
+		endian = 0;
+#endif
 
 		// Initialize OGG file
 		oggFile.dataPtr = (char *) data->getData();
@@ -143,7 +151,7 @@ namespace lullaby
 			throw love::Exception("Could not read Ogg bitstream");
 		
 		// Get info and comments
-		vorbisInfo = ov_info(&handle, -1);
+		vorbisInfo = ov_info(&handle, -1);
 		vorbisComment = ov_comment(&handle, -1);
 	}
 
@@ -176,7 +184,7 @@ namespace lullaby
 	{
 		int bits = this->getBits();
 		int size = 0;
-		int section;
+		int section;
 		int result;
 
 		if(bits == 16)
@@ -186,7 +194,7 @@ namespace lullaby
 
 		while(size < bufferSize)
 		{
-			result = ov_read(&handle, (char*) buffer + size, bufferSize - size, 0, bits, 1, &section);
+			result = ov_read(&handle, (char*) buffer + size, bufferSize - size, endian, bits, 1, &section);
 
 			if(result > 0)
 				size += result;
@@ -194,17 +202,17 @@ namespace lullaby
 			{
 				switch(result)
 				{
-				case OV_EREAD:
-					throw love::Exception("Vorbis read: Read from media");
-				case OV_ENOTVORBIS:
-					throw love::Exception("Vorbis read: Not Vorbis data");
-				case OV_EVERSION:
-					throw love::Exception("Vorbis read: Vorbis version mismatch");
-				case OV_EBADHEADER:
-					throw love::Exception("Vorbis read: Invalid Vorbis header");
-				case OV_EFAULT:
-					throw love::Exception("Vorbis read: Internal logic fault (bug or heap/stack corruption)");
-				default:
+				case OV_EREAD:
+					throw love::Exception("Vorbis read: Read from media");
+				case OV_ENOTVORBIS:
+					throw love::Exception("Vorbis read: Not Vorbis data");
+				case OV_EVERSION:
+					throw love::Exception("Vorbis read: Vorbis version mismatch");
+				case OV_EBADHEADER:
+					throw love::Exception("Vorbis read: Invalid Vorbis header");
+				case OV_EFAULT:
+					throw love::Exception("Vorbis read: Internal logic fault (bug or heap/stack corruption)");
+				default:
 					throw love::Exception("Vorbis read: Unknown error");
 				}
 			}
@@ -257,20 +265,20 @@ namespace lullaby
 		return (result != 0);
 	}
 
-	int VorbisDecoder::getChannels() const
-	{
-		return vorbisInfo->channels;
-	}
-
-	int VorbisDecoder::getBits() const
-	{
+	int VorbisDecoder::getChannels() const
+	{
+		return vorbisInfo->channels;
+	}
+
+	int VorbisDecoder::getBits() const
+	{
 		//return vorbisInfo->bitrate_nominal / 10000;
-		return 16;
+		return 16;
 	}
 
-	int VorbisDecoder::getSampleRate() const
-	{
-		return vorbisInfo->rate;
+	int VorbisDecoder::getSampleRate() const
+	{
+		return vorbisInfo->rate;
 	}
 
 } // lullaby

+ 13 - 12
src/modules/sound/lullaby/VorbisDecoder.h

@@ -35,22 +35,23 @@ namespace sound
 {
 namespace lullaby
 {
-	// Struct for handling data
-	struct SOggFile
-	{
-		char * dataPtr;	// Pointer to the data in memory
-		int dataSize;	// Size of the data
-		int dataRead;	// How much we've read so far
+	// Struct for handling data
+	struct SOggFile
+	{
+		char * dataPtr;	// Pointer to the data in memory
+		int dataSize;	// Size of the data
+		int dataRead;	// How much we've read so far
 	};
 
 	class VorbisDecoder : public Decoder
 	{
-	private:
-		SOggFile oggFile;				// (see struct)
-		ov_callbacks vorbisCallbacks;	// Callbacks used to read the file from mem
-		OggVorbis_File handle;			// Handle to the file
-		vorbis_info * vorbisInfo;		// Info
+	private:
+		SOggFile oggFile;				// (see struct)
+		ov_callbacks vorbisCallbacks;	// Callbacks used to read the file from mem
+		OggVorbis_File handle;			// Handle to the file
+		vorbis_info * vorbisInfo;		// Info
         vorbis_comment * vorbisComment;	// Comments
+		int endian;						// Endianness
 
 	public:
 
@@ -64,7 +65,7 @@ namespace lullaby
 		bool seek(float s);
 		bool rewind();
 		bool isSeekable();
-		int getChannels() const;
+		int getChannels() const;
 		int getBits() const;
 		int getSampleRate() const;