PageRenderTime 322ms CodeModel.GetById 70ms app.highlight 127ms RepoModel.GetById 115ms app.codeStats 1ms

/thirdparty/liblastfm2/src/types/mbid_mp3.c

http://github.com/tomahawk-player/tomahawk
C | 181 lines | 108 code | 24 blank | 49 comment | 35 complexity | 902a728888d2eb10a8464a6ee3f76301 MD5 | raw file
  1/*
  2*  LICENSE
  3*  
  4*  Copyright (c) 2006, David Nicolson
  5*  All rights reserved.
  6*  
  7*  Redistribution and use in source and binary forms, with or without
  8*  modification, are permitted provided that the following conditions
  9*  are met:
 10*  
 11*    1. Redistributions of source code must retain the above copyright
 12*       notice, this list of conditions and the following disclaimer.
 13*    2. Redistributions in binary form must reproduce the above copyright
 14*       notice, this list of conditions and the following disclaimer in the
 15*       documentation and/or other materials provided with the distribution.
 16*    3. Neither the name of the author nor the names of its contributors
 17*       may be used to endorse or promote products derived from this software
 18*       without specific prior written permission.
 19*  
 20*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT UNLESS REQUIRED BY
 24*  LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER OR CONTRIBUTOR
 25*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 26*  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 27*  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, PROFITS; OR
 28*  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 29*  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 30*  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 31*  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32*/
 33
 34#ifndef __MBID_MP3_H
 35#define __MBID_MP3_H
 36
 37#define MBID_BUFFER_SIZE 37
 38
 39// -----------------------------------------------------------------------------
 40
 41void mfile(size_t length, char ret[], FILE *fp, int *s) {
 42   size_t bytes = fread(ret,1,length,fp);
 43
 44   if (bytes != length) {
 45      *s = 0;
 46   }
 47}
 48
 49// -----------------------------------------------------------------------------
 50
 51int to_synch_safe(char bytes[]) {
 52   return ((int)bytes[0] << 21) + ((int)bytes[1] << 14) + ((int)bytes[2] << 7) + (int)bytes[3];
 53}
 54
 55int to_integer(char bytes[]) {
 56   size_t size = 0;
 57   uint i;
 58   for (i=0; i < sizeof(bytes); i++) {
 59      size = size * 256 + ((int)bytes[i] & 0x000000FF);
 60   }
 61   return static_cast<int>(size);
 62}
 63
 64// -----------------------------------------------------------------------------
 65
 66int getMP3_MBID(const char *path, char mbid[MBID_BUFFER_SIZE]) 
 67{
 68   FILE *fp;
 69   static int s = 1;
 70   char head[3];
 71   char version[2];
 72   char flag[1];
 73   char size[4];
 74   char size_extended[4];
 75   int tag_size = 0;
 76   int extended_size = 0;
 77   char frame[4];
 78   char frame_header[4];
 79   int frame_size;
 80   int version_major, version_minor;
 81
 82   if (path == NULL) {
 83      //debug("Received null path\n");
 84      return -1;
 85   }
 86
 87   fp = fopen(path,"rb");
 88   if (fp == NULL) {
 89      //debug("Failed to open music file: %s\n",path);
 90      return -1;
 91   }
 92
 93   while (s) {
 94      mfile(3,head,fp,&s);
 95      if (!strncmp(head,"ID3",3) == 0) {
 96         //debug("No ID3v2 tag found: %s\n",path);
 97         break;
 98      }
 99
100      mfile(2,version,fp,&s);
101      version_major = (int)version[0];
102      version_minor = (int)version[1];
103      if (version_major == 2) {
104         //debug("ID3v2.2.0 does not support MBIDs: %s\n",path);
105         break;
106      }
107      if (version_major != 3 && version_major != 4) {
108         //debug("Unsupported ID3 version: v2.%d.%d\n",version_major,version_minor);
109         break;
110      }
111
112      mfile(1,flag,fp,&s);
113      if ((unsigned int)flag[0] & 0x00000040) {
114         //debug("Extended header found\n");
115         if (version[0] == 4) {
116            mfile(4,size_extended,fp,&s);
117            extended_size = to_synch_safe(size_extended);
118         } else {
119            mfile(4,size_extended,fp,&s);
120            extended_size = to_integer(size_extended);
121         }
122         //debug("Extended header size: %d\n",extended_size);
123         fseek(fp,extended_size,SEEK_CUR);
124      }
125
126      mfile(4,size,fp,&s);
127      tag_size = to_synch_safe(size);
128      //debug("Tag size: %d\n",tag_size);
129
130      while (s) {
131         if (ftell(fp) > tag_size || ftell(fp) > 1048576) {
132            break;
133         }
134
135         mfile(4,frame,fp,&s);
136         if (frame[0] == 0x00) {
137            break;
138         }
139         if (version_major == 4) {
140            mfile(4,frame_header,fp,&s);
141            frame_size = to_synch_safe(frame_header);
142         } else {
143            mfile(4,frame_header,fp,&s);
144            frame_size = to_integer(frame_header);
145         }
146
147         fseek(fp,2,SEEK_CUR);
148         //debug("Reading %d bytes from frame %s\n",frame_size,frame);
149
150         if (strncmp(frame,"UFID",4) == 0) {
151            //char frame_data[frame_size];
152            char frame_data[59];
153            mfile(59,frame_data,fp,&s);
154            if (frame_size >= 59 && strncmp(frame_data,"http://musicbrainz.org",22) == 0) {
155               char *tmbid = frame_data;
156               tmbid = frame_data + 23;
157               strncpy(mbid,tmbid,MBID_BUFFER_SIZE-1);
158               mbid[MBID_BUFFER_SIZE-1] = 0x00;
159               fclose(fp);
160               return 0;
161            }
162         } else {
163            fseek(fp,frame_size,SEEK_CUR);
164         }
165      }
166      break;
167   }
168
169   if (fp) {
170      fclose(fp);
171   }
172   //if (!s) {
173   //   debug("Failed to read music file: %s\n",path);
174   //}                
175   return -1;
176
177}
178
179#endif
180
181// -----------------------------------------------------------------------------