"finalize" Ogg FLAC mapping version 1.0 by prepending "FLAC" magic and a 2 byte mappi...
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 3 Sep 2004 01:03:23 +0000 (01:03 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 3 Sep 2004 01:03:23 +0000 (01:03 +0000)
src/libOggFLAC/include/private/ogg_decoder_aspect.h
src/libOggFLAC/ogg_decoder_aspect.c
src/libOggFLAC/ogg_encoder_aspect.c
src/libOggFLAC/stream_decoder.c

index c387109..77e02e9 100644 (file)
@@ -45,6 +45,7 @@ typedef struct OggFLAC__OggDecoderAspect {
        /* these are for internal state related to Ogg decoding */
        ogg_stream_state stream_state;
        ogg_sync_state sync_state;
+       unsigned version_major, version_minor;
        FLAC__bool need_serial_number;
        FLAC__bool end_of_stream;
        FLAC__bool have_working_page; /* only if true will the following vars be valid */
@@ -64,6 +65,8 @@ typedef enum {
        OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_OK = 0,
        OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM,
        OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC,
+       OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC,
+       OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION,
        OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT,
        OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR,
        OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR
index a0f34a6..0627478 100644 (file)
@@ -32,6 +32,7 @@
 #include <string.h> /* for memcpy() */
 #include "FLAC/assert.h"
 #include "private/ogg_decoder_aspect.h"
+#include "private/ogg_mapping.h"
 
 #ifdef max
 #undef max
@@ -53,6 +54,9 @@ FLAC__bool OggFLAC__ogg_decoder_aspect_init(OggFLAC__OggDecoderAspect *aspect)
        if(ogg_sync_init(&aspect->sync_state) != 0)
                return false;
 
+       aspect->version_major = ~(0u);
+       aspect->version_minor = ~(0u);
+
        aspect->need_serial_number = aspect->use_first_serial_number;
 
        aspect->end_of_stream = false;
@@ -149,6 +153,20 @@ OggFLAC__OggDecoderAspectReadStatus OggFLAC__ogg_decoder_aspect_read_callback_wr
                                const int ret = ogg_stream_packetout(&aspect->stream_state, &aspect->working_packet);
                                if (ret > 0) {
                                        aspect->have_working_packet = true;
+                                       /* if it is packet 0, check for magic and a supported Ogg FLAC mapping version */
+                                       if (aspect->working_packet.packetno == 0) {
+                                               const unsigned header_length = OggFLAC__MAPPING_MAGIC_LENGTH + OggFLAC__MAPPING_VERSION_MAJOR_LENGTH + OggFLAC__MAPPING_VERSION_MINOR_LENGTH;
+                                               if (aspect->working_packet.bytes < (long)header_length)
+                                                       return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC;
+                                               if (memcmp(aspect->working_packet.packet, OggFLAC__MAPPING_MAGIC, OggFLAC__MAPPING_MAGIC_LENGTH))
+                                                       return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC;
+                                               aspect->version_major = (unsigned)aspect->working_packet.packet[OggFLAC__MAPPING_MAGIC_LENGTH];
+                                               aspect->version_minor = (unsigned)aspect->working_packet.packet[OggFLAC__MAPPING_MAGIC_LENGTH+OggFLAC__MAPPING_VERSION_MAJOR_LENGTH];
+                                               if (aspect->version_major != 1)
+                                                       return OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION;
+                                               aspect->working_packet.packet += header_length;
+                                               aspect->working_packet.bytes -= header_length;
+                                       }
                                }
                                else if (ret == 0) {
                                        aspect->have_working_page = false;
index 38efc1e..9c9ef7d 100644 (file)
 #include <string.h> /* for memset() */
 #include "FLAC/assert.h"
 #include "private/ogg_encoder_aspect.h"
+#include "private/ogg_mapping.h"
+
+static const FLAC__byte OggFLAC__MAPPING_VERSION_MAJOR = 1;
+static const FLAC__byte OggFLAC__MAPPING_VERSION_MINOR = 0;
 
 /***********************************************************************
  *
@@ -72,13 +76,14 @@ void OggFLAC__ogg_encoder_aspect_set_defaults(OggFLAC__OggEncoderAspect *aspect)
  * The basic FLAC -> Ogg mapping goes like this:
  *
  * - 'fLaC' magic and STREAMINFO block get combined into the first
- *   packet
- * - the first packet is flushed to the first page
- * - each subsequent metadata block goes into its own packet
- * - each metadata packet is flushed to page (this is not required,
+ *   packet.  The packet is prefixed with 'FLAC' magic and the 2
+ *   byte Ogg FLAC mapping version number.
+ * - The first packet is flushed to the first page.
+ * - Each subsequent metadata block goes into its own packet.
+ * - Each metadata packet is flushed to page (this is not required,
  *   the mapping only requires that a flush must occur after all
- *   metadata is written)
- * - each subsequent FLAC audio frame goes into its own packet.
+ *   metadata is written).
+ * - Each subsequent FLAC audio frame goes into its own packet.
  *
  * WATCHOUT:
  * This depends on the behavior of FLAC__StreamEncoder that we get a
@@ -104,7 +109,15 @@ FLAC__StreamEncoderWriteStatus OggFLAC__ogg_encoder_aspect_write_callback_wrappe
                packet.granulepos = aspect->samples_written + samples;
 
                if(aspect->is_first_packet) {
-                       FLAC__byte newbuffer[FLAC__STREAM_SYNC_LENGTH + FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH];
+                       FLAC__byte newbuffer[
+                               OggFLAC__MAPPING_MAGIC_LENGTH +
+                               OggFLAC__MAPPING_VERSION_MAJOR_LENGTH +
+                               OggFLAC__MAPPING_VERSION_MINOR_LENGTH +
+                               FLAC__STREAM_SYNC_LENGTH +
+                               FLAC__STREAM_METADATA_HEADER_LENGTH +
+                               FLAC__STREAM_METADATA_STREAMINFO_LENGTH
+                       ];
+                       FLAC__byte *b = newbuffer;
                        if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) {
                                /*
                                 * If we get here, our assumption about the way write callbacks happen
@@ -113,8 +126,21 @@ FLAC__StreamEncoderWriteStatus OggFLAC__ogg_encoder_aspect_write_callback_wrappe
                                FLAC__ASSERT(0);
                                return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
                        }
-                       memcpy(newbuffer, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH);
-                       memcpy(newbuffer + FLAC__STREAM_SYNC_LENGTH, buffer, bytes);
+                       /* add 'FLAC' mapping magic */
+                       memcpy(b, OggFLAC__MAPPING_MAGIC, OggFLAC__MAPPING_MAGIC_LENGTH);
+                       b += OggFLAC__MAPPING_MAGIC_LENGTH;
+                       /* add Ogg FLAC mapping major version number */
+                       memcpy(b, &OggFLAC__MAPPING_VERSION_MAJOR, OggFLAC__MAPPING_VERSION_MAJOR_LENGTH);
+                       b += OggFLAC__MAPPING_VERSION_MAJOR_LENGTH;
+                       /* add Ogg FLAC mapping minor version number */
+                       memcpy(b, &OggFLAC__MAPPING_VERSION_MINOR, OggFLAC__MAPPING_VERSION_MINOR_LENGTH);
+                       b += OggFLAC__MAPPING_VERSION_MINOR_LENGTH;
+                       /* add native FLAC 'fLaC' magic */
+                       memcpy(b, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH);
+                       b += FLAC__STREAM_SYNC_LENGTH;
+                       /* add STREAMINFO */
+                       memcpy(b, buffer, bytes);
+                       FLAC__ASSERT(b + bytes - newbuffer == sizeof(newbuffer));
                        packet.packet = (unsigned char *)newbuffer;
                        packet.bytes = sizeof(newbuffer);
 
index 73f56ef..be7c5d6 100644 (file)
@@ -506,6 +506,8 @@ FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused,
                        return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
                        return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+               case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC:
+               case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION:
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
                case OggFLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR:
                        decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;