[easytag/wip/core-refactoring: 12/13] Port Monkey's Audio header reading to GFile
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag/wip/core-refactoring: 12/13] Port Monkey's Audio header reading to GFile
- Date: Fri, 5 Feb 2016 21:39:02 +0000 (UTC)
commit 9fe083aa74281f341b1bd3889abf9d88c747df33
Author: David King <amigadave amigadave com>
Date: Thu Jan 28 21:30:17 2016 +0100
Port Monkey's Audio header reading to GFile
src/tags/libapetag/info_mac.c | 171 ++++++++++++++++++++++++++++-------------
src/tags/libapetag/info_mac.h | 14 +---
src/tags/monkeyaudio_header.c | 10 +--
3 files changed, 121 insertions(+), 74 deletions(-)
---
diff --git a/src/tags/libapetag/info_mac.c b/src/tags/libapetag/info_mac.c
index 00b7f47..bae5891 100644
--- a/src/tags/libapetag/info_mac.c
+++ b/src/tags/libapetag/info_mac.c
@@ -17,6 +17,7 @@
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <errno.h>
#include <glib/gstdio.h>
#include <stdio.h>
#include <stdlib.h>
@@ -31,6 +32,8 @@
#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // number of seek elements after the peak level
#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // wave header not stored
+#define MAC_FORMAT_HEADER_LENGTH 16
+
struct macHeader {
char id[4]; // should equal 'MAC '
unsigned short ver; // version number * 1000 (3.81 = 3810)
@@ -81,73 +84,133 @@ monkey_samples_per_frame(unsigned int versionid, unsigned int compressionlevel)
}
/*
- return 0; Info has all info
- return 1; File not found
- return 2; no MAC file
+ * info_mac_read:
+ * @file: file from which to read a header
+ * @stream_info: stream information to fill
+ * @error: a #GError, or NULL
+ *
+ * Read the header information from a Monkey's Audio file.
+ *
+ * Returns: %TRUE on success, or %FALSE and with @error set on failure
*/
-int
-info_mac_read(const char *fn, StreamInfoMac * Info)
+gboolean
+info_mac_read (GFile *file,
+ StreamInfoMac *stream_info,
+ GError **error)
{
- unsigned int HeaderData[32];
- FILE *tmpFile = NULL;
- long SkipSizeID3;
- struct macHeader * header;
-
- // load file
- tmpFile = g_fopen (fn, "rb");
-
- if (tmpFile == NULL)
- return 1; // file not found or read-protected
+ GFileInfo *info;
+ GFileInputStream *istream;
+ guint8 header_buffer[MAC_FORMAT_HEADER_LENGTH];
+ gsize bytes_read;
+ gsize size_id3;
+ struct macHeader *header;
- // skip id3v2
- SkipSizeID3 = is_id3v2(tmpFile);
- fseek(tmpFile, SkipSizeID3, SEEK_SET);
- if (fread ((void *) HeaderData, sizeof (int), 16, tmpFile) != 16)
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
+ G_FILE_QUERY_INFO_NONE, NULL, error);
+
+ if (!info)
{
- fclose (tmpFile);
- return 1;
+ return FALSE;
+ }
+
+ stream_info->FileSize = g_file_info_get_size (info);
+ g_object_unref (info);
+
+ istream = g_file_read (file, NULL, error);
+
+ if (!istream)
+ {
+ return FALSE;
+ }
+
+ /* FIXME: is_id3v2() should accept an istream or a GFile. */
+ {
+ gchar *path;
+ FILE *fp;
+
+ path = g_file_get_path (file);
+ fp = g_fopen (path, "rb");
+
+ if (!fp)
+ {
+ /* TODO: Add specific error domain and message. */
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s",
+ g_strerror (EINVAL));
+ g_free (path);
+ return FALSE;
+ }
+
+ size_id3 = is_id3v2 (fp);
+ fclose (fp);
+ g_free (path);
+ }
+
+ if (!g_seekable_seek (G_SEEKABLE (istream), size_id3, G_SEEK_SET, NULL,
+ error))
+ {
+ return FALSE;
+ }
+
+ if (!g_input_stream_read_all (G_INPUT_STREAM (istream), header_buffer,
+ MAC_FORMAT_HEADER_LENGTH, &bytes_read, NULL,
+ error))
+ {
+ g_debug ("Only %" G_GSIZE_FORMAT " bytes out of 16 bytes of data were "
+ "read", bytes_read);
+ return FALSE;
+ }
+
+ if (memcmp (header_buffer, "MAC", 3) != 0)
+ {
+ /* TODO: Add specific error domain and message. */
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s",
+ g_strerror (EINVAL));
+ return FALSE; // no monkeyAudio file
}
- fseek(tmpFile, 0, SEEK_END);
- Info->FileSize = ftell(tmpFile);
- fclose(tmpFile);
-
- if (0 != memcmp(HeaderData, "MAC", 3))
- return 2; // no monkeyAudio file
- header= (struct macHeader *) HeaderData;
+ header = (struct macHeader *) header_buffer;
- Info->Version = Info->EncoderVersion = header->ver;
- Info->Channels = header->channels;
- Info->SampleFreq = header->sampleRate;
- Info->Flags = header->formatFlags;
- Info->SamplesPerFrame = monkey_samples_per_frame(header->ver, header->compLevel);
- Info->BitsPerSample = (header->formatFlags & MAC_FORMAT_FLAG_8_BIT)
- ? 8 : ((header->formatFlags & MAC_FORMAT_FLAG_24_BIT) ? 24 : 16);
+ stream_info->Version = stream_info->EncoderVersion = header->ver;
+ stream_info->Channels = header->channels;
+ stream_info->SampleFreq = header->sampleRate;
+ stream_info->Flags = header->formatFlags;
+ stream_info->SamplesPerFrame = monkey_samples_per_frame(header->ver, header->compLevel);
+ stream_info->BitsPerSample = (header->formatFlags & MAC_FORMAT_FLAG_8_BIT)
+ ? 8 : ((header->formatFlags & MAC_FORMAT_FLAG_24_BIT) ? 24 : 16);
- Info->PeakLevel = header->peakLevel;
+ stream_info->PeakLevel = header->peakLevel;
// Info->PeakRatio = Info->PakLevel / pow(2, Info->bitsPerSample - 1);
- Info->Frames = header->totalFrames;
- Info->Samples = (Info->Frames - 1) * Info->SamplesPerFrame +
- header->finalFrameBlocks;
+ stream_info->Frames = header->totalFrames;
+ stream_info->Samples = (stream_info->Frames - 1)
+ * stream_info->SamplesPerFrame
+ + header->finalFrameBlocks;
- Info->Duration = Info->SampleFreq > 0 ?
- ((float)Info->Samples / Info->SampleFreq)*1000 : 0;
+ stream_info->Duration = stream_info -> SampleFreq > 0 ?
+ ((float)stream_info->Samples
+ / stream_info->SampleFreq) * 1000 : 0;
- Info->Compresion = header->compLevel;
- Info->CompresionName = monkey_stringify(Info->Compresion);
+ stream_info->Compresion = header->compLevel;
+ stream_info->CompresionName = monkey_stringify (stream_info->Compresion);
- Info->UncompresedSize = Info->Samples * Info->Channels *
- (Info->BitsPerSample / 8);
+ stream_info->UncompresedSize = stream_info->Samples
+ * stream_info->Channels
+ * (stream_info->BitsPerSample / 8);
- Info->CompresionRatio =
- (Info->UncompresedSize + header->headerBytesWAV) > 0 ?
- Info->FileSize / (float) (Info->UncompresedSize +
- header->headerBytesWAV) : 0. ;
+ stream_info->CompresionRatio = (stream_info->UncompresedSize
+ + header->headerBytesWAV) > 0
+ ? stream_info->FileSize
+ / (float) (stream_info->UncompresedSize
+ + header->headerBytesWAV) : 0.;
- Info->Bitrate = Info->Duration > 0 ? (((Info->Samples *
- Info->Channels * Info->BitsPerSample) / (float) Info->Duration) *
- Info->CompresionRatio) * 1000 : 0;
+ stream_info->Bitrate = stream_info->Duration > 0
+ ? (((stream_info->Samples * stream_info->Channels
+ * stream_info->BitsPerSample)
+ / (float) stream_info->Duration)
+ * stream_info->CompresionRatio) * 1000 : 0;
- Info->PeakRatio=Info->ByteLength=0;
- return 0;
+ stream_info->PeakRatio = stream_info->ByteLength = 0;
+
+ return TRUE;
}
diff --git a/src/tags/libapetag/info_mac.h b/src/tags/libapetag/info_mac.h
index f588f97..4b8181b 100644
--- a/src/tags/libapetag/info_mac.h
+++ b/src/tags/libapetag/info_mac.h
@@ -20,6 +20,8 @@
#ifndef INFO_MAC_H
#define INFO_MAC_H
+#include <gio/gio.h>
+
/** \file info_mac.h
\brief Get information from MonkeyAudio file.
@@ -77,16 +79,6 @@ typedef struct
unsigned int EncoderVersion; /**< version of encoder used */
} StreamInfoMac;
-/**
- Read all mac info from filename
-
- \param fn File name
- \param Info StreamInfoMac Structure for all information
- \retval 0 ok
- \retval 1 file not found or write protected
- \retval 2 not monkey's audio file
-*/
-int
-info_mac_read(const char *fn, StreamInfoMac * Info);
+gboolean info_mac_read (GFile *file, StreamInfoMac *stream_info, GError **error);
#endif /* INFO_MAC_H */
diff --git a/src/tags/monkeyaudio_header.c b/src/tags/monkeyaudio_header.c
index e7671e1..5649a52 100644
--- a/src/tags/monkeyaudio_header.c
+++ b/src/tags/monkeyaudio_header.c
@@ -32,24 +32,16 @@ et_mac_header_read_file_info (GFile *file,
ET_File_Info *ETFileInfo,
GError **error)
{
- gchar *filename;
StreamInfoMac Info;
g_return_val_if_fail (file != NULL && ETFileInfo != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- filename = g_file_get_path (file);
-
- if (info_mac_read (filename, &Info))
+ if (!info_mac_read (file, &Info, error))
{
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
- _("Error opening Monkey’s Audio file"));
- g_free (filename);
return FALSE;
}
- g_free (filename);
-
ETFileInfo->mpc_profile = g_strdup(Info.CompresionName);
ETFileInfo->version = Info.Version;
ETFileInfo->bitrate = Info.Bitrate/1000.0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]