Example #1
0
/* This will try to convert a string to utf-8,
 */
static id3_utf8_t *
import_id3_string(bool is_id3v1, const id3_ucs4_t *ucs4)
{
    id3_utf8_t *utf8, *utf8_stripped = NULL;
    id3_latin1_t *isostr;
    const char *encoding;
    bool is_utf8;

    encoding = config_get_string(CONF_ID3V1_ENCODING, NULL);
    isostr = id3_ucs4_latin1duplicate(ucs4);
    if (G_UNLIKELY(!isostr)) {
        return NULL;
    }
    is_utf8 = check_utf8((const unsigned char *)isostr,
        strlen((const char *)isostr));

    if(is_utf8) {
        utf8 = id3_ucs4_utf8duplicate(ucs4);
        goto done;
    }

    /* use encoding field here? */
    if (is_id3v1 && encoding) {
        utf8 = import_8bit_string(isostr, encoding);
    } else {
        utf8 = id3_ucs4_utf8duplicate(ucs4);
        if(!check_utf8((unsigned char *)utf8, strlen((const char *)utf8))
            && encoding)
        {
            id3_utf8_t *tmp = import_8bit_string(isostr, encoding);
            if(tmp)
            {
                g_free(utf8);
                utf8 = tmp;
            }
        }
    }

done:
    if(isostr)
        g_free(isostr);
    if(utf8) {
        utf8_stripped = (id3_utf8_t *)g_strdup(g_strstrip((gchar *)utf8));
        g_free(utf8);
        return utf8_stripped;
    }
    return NULL;

}
Example #2
0
char * getTagString(struct id3_tag *tag, const char *frameName) {
	struct id3_frame *frame;
	union id3_field *field;
	int i;
	const id3_ucs4_t *unicode;
	char *ret;
	
	frame = id3_tag_findframe(tag,frameName,0);
	if(!frame) {
		fprintf(stdout,"No frame\n");
		return NULL;
	}
	for(i=0;;i++) {
		field = id3_frame_field(frame,i);
		if(!field) {
			break;
		}
		if(id3_field_type(field) == ID3_FIELD_TYPE_STRINGLIST) {
			unicode = id3_field_getstrings(field,0);
			if(unicode) {
				id3_utf8_t *str;
				str = id3_ucs4_utf8duplicate(unicode);
				ret = (char *) str;
			}
			
		}
	}
	
	return ret;
}
Example #3
0
wxString GetGenreNum(int i)
{
#ifdef USE_LIBID3TAG
  id3_latin1_t      i_latin1[50];
  id3_ucs4_t       *i_ucs4;
  const id3_ucs4_t *genre_ucs4;

  sprintf((char *)i_latin1, "%d", i);
  i_ucs4 =
     (id3_ucs4_t *)malloc((id3_latin1_length(i_latin1) + 1) *
                          sizeof(*i_ucs4));
  if (i_ucs4) {
    id3_latin1_decode(i_latin1, i_ucs4);
    genre_ucs4 = id3_genre_name(i_ucs4);
    char *genre_char = (char *)id3_ucs4_utf8duplicate(genre_ucs4);
    wxString genreStr = UTF8CTOWX(genre_char);
    free(genre_char);
    free(i_ucs4);
    return genreStr;    
  }   

#endif // ifdef USE_LIBID3TAG 

  return wxT("");
}
Example #4
0
wchar_t* GetMP3Text(id3_field_textencoding encoding, const id3_field* field, const id3_ucs4_t* ucs4)
{
	if (ucs4 == NULL)
		return NULL;

	wchar_t* content = NULL;
	switch(encoding)
	{
	case ID3_FIELD_TEXTENCODING_ISO_8859_1:
		{
			char* p = (char*)id3_ucs4_latin1duplicate(ucs4);
			content = CharToWideChar(p, strlen(p));
			free(p);
		}		
		break;

	case ID3_FIELD_TEXTENCODING_UTF_8:
		{
			char* p = (char*)id3_ucs4_utf8duplicate(ucs4);
			if (p != NULL)
			{
				content = UTF8toWideChar(p, strlen(p));				
				free(p);
			}
		}		
		break;

	case ID3_FIELD_TEXTENCODING_UTF_16:
		{
			char* p = (char*)id3_ucs4_utf8duplicate(ucs4);
			if (p != NULL)
			{
				content = UTF8toWideChar(p, strlen(p));
				free(p);
			}			
		}		
		break;

	default:
		break;
	}

	return content;
}
Example #5
0
File: tag_id3.c Project: azuwis/mpd
/* This will try to convert a string to utf-8,
 */
static id3_utf8_t * processID3FieldString (int is_id3v1, const id3_ucs4_t *ucs4, int type, enum id3_field_textencoding id3_encoding)
{
	id3_utf8_t *utf8, *utf8_stripped;
	id3_utf8_t *isostr;
	const char *encoding;

	if (type == TAG_ITEM_GENRE)
		ucs4 = id3_genre_name(ucs4);
	/* use encoding field here? */
	if ((encoding = config_get_string(CONF_ID3V1_ENCODING, NULL)) != NULL) {
		if(!is_id3v1 && (id3_encoding == ID3_FIELD_TEXTENCODING_UTF_16 || id3_encoding == ID3_FIELD_TEXTENCODING_UTF_8))
			isostr = id3_ucs4_utf8duplicate(ucs4);
		else
			isostr = (id3_utf8_t*)id3_ucs4_latin1duplicate(ucs4);
		if (G_UNLIKELY(!isostr)) {
			return NULL;
		}

                if(id3_encoding == 0xff || id3_encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1) {
                utf8 = (id3_utf8_t *)
			g_convert_with_fallback((const char*)isostr, -1,
						"utf-8", encoding,
						NULL, NULL, NULL, NULL);
                } else
                        utf8 = (id3_utf8_t *) g_strdup((const char*)isostr);
		if (utf8 == NULL) {
			g_debug("Unable to convert %s string to UTF-8: '%s'",
				encoding, isostr);
			g_free(isostr);
			return NULL;
		}
		g_free(isostr);
	} else {
		utf8 = id3_ucs4_utf8duplicate(ucs4);
		if (G_UNLIKELY(!utf8)) {
			return NULL;
		}
	}

	utf8_stripped = (id3_utf8_t *)g_strdup(g_strstrip((gchar *)utf8));
	g_free(utf8);

	return utf8_stripped;
}
Example #6
0
QString mpgDecoder::getID3String( id3_tag* idtag, const char* field_frame )
{
    QString str;
    id3_frame* frame = id3_tag_findframe( idtag, field_frame, 0 );
    if(frame)
    {
        id3_field* field = id3_frame_field(frame, 1);
        if(field)
        {
            const id3_ucs4_t* id3_string = id3_field_getstrings(field, 0);
            if(id3_string)
                str = (char*)id3_ucs4_utf8duplicate(id3_string);
        }
    }
    return str;
}
Example #7
0
static char *get_tag (struct id3_tag *tag, const char *what)
{
	struct id3_frame *frame;
	union id3_field *field;
	const id3_ucs4_t *ucs4;
	char *comm = NULL;

	frame = id3_tag_findframe (tag, what, 0);
	if (frame && (field = &frame->fields[1])) {
		ucs4 = id3_field_getstrings (field, 0);
		if (ucs4)
			comm = (char *)id3_ucs4_utf8duplicate (ucs4);
	}

	return comm;
}
Example #8
0
static id3_utf8_t *
tag_id3_getstring(const struct id3_frame *frame, unsigned i)
{
	union id3_field *field;
	const id3_ucs4_t *ucs4;

	field = id3_frame_field(frame, i);
	if (field == NULL)
		return NULL;

	ucs4 = id3_field_getstring(field);
	if (ucs4 == NULL)
		return NULL;

	return id3_ucs4_utf8duplicate(ucs4);
}
Example #9
0
static char *get_tag (struct id3_tag *tag, const char *what)
{
	struct id3_frame *frame;
	union id3_field *field;
	const id3_ucs4_t *ucs4;
	char *comm = NULL;

	frame = id3_tag_findframe (tag, what, 0);
	if (frame && (field = &frame->fields[1])) {
		ucs4 = id3_field_getstrings (field, 0);
		if (ucs4) {
			/* Workaround for ID3 tags v1/v1.1 where the encoding
			 * is latin1. */
            union id3_field *encoding_field = &frame->fields[0];
			if ((id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1) 
                    || ((options_get_int ("EnforceTagsEncoding") && 
                            (id3_field_gettextencoding((encoding_field)) 
                             == ID3_FIELD_TEXTENCODING_ISO_8859_1))))
            {
				char *t;

				comm = (char *)id3_ucs4_latin1duplicate (ucs4);

#ifdef HAVE_RCC
				if (options_get_int("UseRCC"))
					comm = do_rcc (comm);
				else {
#endif /* HAVE_RCC */
					t = comm;
					comm = id3v1_fix (comm);
					free (t);
#ifdef HAVE_RCC
				}
#endif /* HAVE_RCC */
			}
			else
				comm = (char *)id3_ucs4_utf8duplicate (ucs4);
		}
	}

	return comm;
}
Example #10
0
File: tag_id3.c Project: ion1/mpd
/* This will try to convert a string to utf-8,
 */
static id3_utf8_t *
import_id3_string(bool is_id3v1, const id3_ucs4_t *ucs4)
{
	id3_utf8_t *utf8, *utf8_stripped;
	id3_latin1_t *isostr;
	const char *encoding;

	/* use encoding field here? */
	if (is_id3v1 &&
	    (encoding = config_get_string(CONF_ID3V1_ENCODING, NULL)) != NULL) {
		isostr = id3_ucs4_latin1duplicate(ucs4);
		if (G_UNLIKELY(!isostr)) {
			return NULL;
		}

		utf8 = (id3_utf8_t *)
			g_convert_with_fallback((const char*)isostr, -1,
						"utf-8", encoding,
						NULL, NULL, NULL, NULL);
		if (utf8 == NULL) {
			g_debug("Unable to convert %s string to UTF-8: '%s'",
				encoding, isostr);
			g_free(isostr);
			return NULL;
		}
		g_free(isostr);
	} else {
		utf8 = id3_ucs4_utf8duplicate(ucs4);
		if (G_UNLIKELY(!utf8)) {
			return NULL;
		}
	}

	utf8_stripped = (id3_utf8_t *)g_strdup(g_strstrip((gchar *)utf8));
	g_free(utf8);

	return utf8_stripped;
}
Example #11
0
wxString GetID3FieldStr(struct id3_tag *tp, const char *name)
{
   struct id3_frame *frame;

   frame = id3_tag_findframe(tp, name, 0);
   if (frame) {
      const id3_ucs4_t *ustr;

      if (strcmp(name, ID3_FRAME_COMMENT) == 0)
	 ustr = id3_field_getfullstring(&frame->fields[3]);
      else
	 ustr = id3_field_getstrings(&frame->fields[1], 0);

      if (ustr) {
	 char *str = (char *)id3_ucs4_utf8duplicate(ustr);
	 wxString s = UTF8CTOWX(str);
	 free(str);
	 return s;
      }
   }

   return wxT("");
}
Example #12
0
int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
    struct id3_file *pid3file;
    struct id3_tag *pid3tag;
    struct id3_frame *pid3frame;
    int err;
    int index;
    int used;
    char *utf8_text;
    int genre=WINAMP_GENRE_UNKNOWN;
    int have_utf8;
    int have_text;
    id3_ucs4_t const *native_text;
    char *tmp;
    int got_numeric_genre;
    int rating;
    char *conversion_codepage;

    pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY);
    if(!pid3file) {
        DPRINTF(E_WARN,L_SCAN,"Cannot open %s\n",file);
        return FALSE;
    }

    pid3tag=id3_file_tag(pid3file);

    if(!pid3tag) {
        err=errno;
        id3_file_close(pid3file);
        errno=err;
        DPRINTF(E_WARN,L_SCAN,"Cannot get ID3 tag for %s\n",file);
        return FALSE;
    }

    DPRINTF(E_SPAM,L_SCAN,"Starting mp3 tag scan\n");

    conversion_codepage = conf_alloc_string("scanning","mp3_tag_codepage",
                                            "ISO-8859-1");

    index=0;
    while((pid3frame=id3_tag_findframe(pid3tag,"",index))) {
        used=0;
        utf8_text=NULL;
        native_text=NULL;
        have_utf8=0;
        have_text=0;

        DPRINTF(E_SPAM,L_SCAN,"Found tag %s\n",pid3frame->id);

        if(!strcmp(pid3frame->id,"YTCP")) { /* for id3v2.2 */
            pmp3->compilation = 1;
            DPRINTF(E_DBG,L_SCAN,"Compilation: %d\n", pmp3->compilation);
        }

        if(((pid3frame->id[0] == 'T')||(strcmp(pid3frame->id,"COMM")==0)) &&
           (id3_field_getnstrings(&pid3frame->fields[1])))
            have_text=1;

        if(have_text) {
            native_text=id3_field_getstrings(&pid3frame->fields[1],0);

            if(native_text) {
                have_utf8=1;


                utf8_text = (char*)id3_ucs4_utf8duplicate(native_text);
                if(utf8_text)
                    mem_register(utf8_text,0);

                if(id3_field_gettextencoding(&pid3frame->fields[1]) ==
                   ID3_FIELD_TEXTENCODING_ISO_8859_1) {
#ifdef HAVE_ICONV
                    /* this is kinda cheesy, but ucs4* == char* for 8859-1 */
                    free(utf8_text);
                    utf8_text =
                        (char*)util_xtoutf8_alloc((unsigned char*)native_text,
                                                  strlen((char*)native_text),
                                                  conversion_codepage);
#endif
                }



                if(!strcmp(pid3frame->id,"TIT2")) { /* Title */
                    used=1;
                    pmp3->title = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Title: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TPE1")) {
                    used=1;
                    pmp3->artist = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Artist: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TALB")) {
                    used=1;
                    pmp3->album = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Album: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TCOM")) {
                    used=1;
                    pmp3->composer = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Composer: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TIT1")) {
                    used=1;
                    pmp3->grouping = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Grouping: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TPE2")) {
                    used=1;
                    pmp3->orchestra = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Orchestra: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TPE3")) {
                    used=1;
                    pmp3->conductor = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Conductor: %s\n",utf8_text);
                } else if(!strcmp(pid3frame->id,"TCON")) {
                    used=1;
                    pmp3->genre = utf8_text;
                    got_numeric_genre=0;
                    DPRINTF(E_DBG,L_SCAN," Genre: %s\n",utf8_text);
                    if(pmp3->genre) {
                        if(!strlen(pmp3->genre)) {
                            genre=WINAMP_GENRE_UNKNOWN;
                            got_numeric_genre=1;
                        } else if (scan_mp3_is_numeric(pmp3->genre)) {
                            genre=atoi(pmp3->genre);
                            got_numeric_genre=1;
                        } else if ((pmp3->genre[0] == '(') && (isdigit(pmp3->genre[1]))) {
                            genre=atoi((char*)&pmp3->genre[1]);
                            got_numeric_genre=1;
                        }

                        if(got_numeric_genre) {
                            if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
                                genre=WINAMP_GENRE_UNKNOWN;
                            free(pmp3->genre);
                            pmp3->genre=strdup(scan_winamp_genre[genre]);
                        }
                    }
                } else if(!strcmp(pid3frame->id,"COMM")) {
                    used=1;
                    pmp3->comment = utf8_text;
                    DPRINTF(E_DBG,L_SCAN," Comment: %s\n",pmp3->comment);
                } else if(!strcmp(pid3frame->id,"TPOS")) {
                    tmp=utf8_text;
                    strsep(&tmp,"/");
                    if(tmp) {
                        pmp3->total_discs=atoi(tmp);
                    }
                    pmp3->disc=atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN," Disc %d of %d\n",pmp3->disc,pmp3->total_discs);
                } else if(!strcmp(pid3frame->id,"TRCK")) {
                    tmp=utf8_text;
                    strsep(&tmp,"/");
                    if(tmp) {
                        pmp3->total_tracks=atoi(tmp);
                    }
                    pmp3->track=atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN," Track %d of %d\n",pmp3->track,pmp3->total_tracks);
                } else if(!strcmp(pid3frame->id,"TDRC")) {
                    pmp3->year = atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN," Year: %d\n",pmp3->year);
                } else if(!strcmp(pid3frame->id,"TLEN")) {
                    pmp3->song_length = atoi(utf8_text); /* now in ms */
                    DPRINTF(E_DBG,L_SCAN," Length: %d\n", pmp3->song_length);
                } else if(!strcmp(pid3frame->id,"TBPM")) {
                    pmp3->bpm = atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN,"BPM: %d\n", pmp3->bpm);
                } else if(!strcmp(pid3frame->id,"TCMP")) { /* for id3v2.3 */
                    pmp3->compilation = (char)atoi(utf8_text);
                    DPRINTF(E_DBG,L_SCAN,"Compilation: %d\n", pmp3->compilation);
                }
            }
        }

        /* can check for non-text tags here */
        if((!used) && (have_utf8) && (utf8_text))
            free(utf8_text);

        if((!strcmp(pid3frame->id,"POPM")) && (pid3frame->nfields == 3)) {
            rating = id3_field_getint(&pid3frame->fields[1]);
            if(rating >= 0x01)
                pmp3->rating = 20;
            if(rating >= 0x40)
                pmp3->rating = 40;
            if(rating >= 0x80)
                pmp3->rating = 60;
            if(rating >= 0xC4)
                pmp3->rating = 80;
            if(rating >= 0xFF)
                pmp3->rating = 100;
        }


        /* v2 COMM tags are a bit different than v1 */
        if((!strcmp(pid3frame->id,"COMM")) && (pid3frame->nfields == 4)) {
            /* Make sure it isn't a application-specific comment...
             * This currently includes the following:
             *
             * iTunes_CDDB_IDs
             * iTunNORM
             *
             * If other apps stuff crap into comment fields, then we'll ignore them
             * here.
             */
            native_text=id3_field_getstring(&pid3frame->fields[2]);
            if(native_text) {
                utf8_text=(char*)id3_ucs4_utf8duplicate(native_text);
                if(utf8_text)
                    mem_register(utf8_text,0);

                if((utf8_text) && (strncasecmp(utf8_text,"iTun",4) != 0)) {
                    /* it's a real comment */
                    if(utf8_text)
                        free(utf8_text);

                    native_text=id3_field_getfullstring(&pid3frame->fields[3]);
                    if(native_text) {
                        if(pmp3->comment)
                            free(pmp3->comment);
                        utf8_text=(char*)id3_ucs4_utf8duplicate(native_text);
                        if(utf8_text) {
                            mem_register(utf8_text,0);
                            pmp3->comment=utf8_text;
                        }
                    }
                } else {
                    if(utf8_text)
                        free(utf8_text);
                }
            }
        }

        index++;
    }

    free(conversion_codepage);
    id3_file_close(pid3file);
    DPRINTF(E_DBG,L_SCAN,"Got id3 tag successfully\n");
    return TRUE;
}
Example #13
0
File: id3read.c Project: cjd/mtpfs
static gchar *
getFrameText (struct id3_tag *tag, char *frame_name)
{
  const id3_ucs4_t *string;
  struct id3_frame *frame;
  union id3_field *field;
  gchar *utf8 = NULL;
  enum id3_field_textencoding encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1;

  frame = id3_tag_findframe (tag, frame_name, 0);
  if (!frame)
    return NULL;

  /* Find the encoding used for the field */
  field = id3_frame_field (frame, 0);
  //printf ("field: %p\n", field);
  if (field && (id3_field_type (field) == ID3_FIELD_TYPE_TEXTENCODING))
    {
      encoding = field->number.value;
      //printf ("encoding: %d\n", encoding);
    }

  if (strcmp (frame_name, ID3_FRAME_COMMENT) == 0)
    field = id3_frame_field (frame, 3);
  else
    field = id3_frame_field (frame, 1);

  //printf ("field: %p\n", field);

  if (!field)
    return NULL;

  if (strcmp (frame_name, ID3_FRAME_COMMENT) == 0)
    string = id3_field_getfullstring (field);
  else
    string = id3_field_getstrings (field, 0);

  // g_debug("string: %s\n", string);

  if (!string)
    return NULL;

  if (strcmp (frame_name, ID3_FRAME_GENRE) == 0)
    string = id3_genre_name (string);

  if (encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1)
    {
      /* ISO_8859_1 is just a "marker" -- most people just drop
         whatever coding system they are using into it, so we use
         charset_to_utf8() to convert to utf8 */
      id3_latin1_t *raw = id3_ucs4_latin1duplicate (string);
      utf8 = (gchar *) charset_to_utf8 (raw);
      g_free (raw);
    }
  else
    {
      /* Standard unicode is being used -- we won't have to worry
         about charsets then. */
      // g_debug("This frame is a Unicode frame!\n");
      utf8 = (gchar *) id3_ucs4_utf8duplicate (string);
    }
  // g_debug("Found tag: %s, value: %s\n", frame_name, utf8);
  return utf8;
}
Example #14
0
JNIEXPORT jstring JNICALL Java_com_ssb_droidsound_utils_ID3Tag_getStringInfo(JNIEnv *env, jobject obj, jint what)
{
	struct id3_file *id3file = (struct id3_file*)env->GetLongField(obj, refField);
	struct id3_tag *tag = (struct id3_tag*)env->GetLongField(obj, tagRefField);

	__android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "Get String Info %p %p", id3file, tag);


	if(!tag && id3file)
		tag = id3_file_tag(id3file);

	if(!tag) return 0;

	const id3_ucs4_t *title = NULL;
	struct id3_frame *frame = NULL;

	__android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "id3tag %p", tag);

	switch(what) {
	case INFO_TITLE:
		frame = id3_tag_findframe(tag, ID3_FRAME_TITLE, 0);
		break;
	case INFO_AUTHOR:
		frame = id3_tag_findframe(tag, ID3_FRAME_ARTIST, 0);
		break;
	case INFO_COPYRIGHT:
		frame = id3_tag_findframe(tag, ID3_FRAME_YEAR, 0);
		break;
	case ID3INFO_GENRE:
		frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0);
		if(frame) {
			title = id3_field_getstrings(&frame->fields[1], 0);
			title = id3_genre_name(title);
		}
		break;
	case ID3INFO_ALBUM:
		frame = id3_tag_findframe(tag, ID3_FRAME_ALBUM, 0);
		break;
	case ID3INFO_TRACK:
		frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0);
		break;
	case ID3INFO_COMMENT:
		frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, 0);
		if(frame) {
			__android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "COMMENT %d fields", frame->nfields);
			if(frame->nfields >= 4)
				title = id3_field_getfullstring(&frame->fields[3]);
		}
		break;
	}

	if(frame) {

		__android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "frame %p %d", frame, what);

		if(title == NULL)
			title = id3_field_getstrings(&frame->fields[1], 0);
		if(title) {
			__android_log_print(ANDROID_LOG_VERBOSE, "ID3Tag", "title %p", title);
			id3_utf8_t *titleu8 = id3_ucs4_utf8duplicate(title);
			jstring j = env->NewStringUTF((const char *)titleu8);
			return j;
		}
	}

	return NULL;

}
Example #15
0
static int
_get_dsftags(char *file, struct song_metadata *psong)
{
	struct id3_tag *pid3tag;
	struct id3_frame *pid3frame;
	int err;
	int index;
	int used;
	unsigned char *utf8_text;
	int genre = WINAMP_GENRE_UNKNOWN;
	int have_utf8;
	int have_text;
	id3_ucs4_t const *native_text;
	char *tmp;
	int got_numeric_genre;
	id3_byte_t const *image;
	id3_length_t image_size = 0;
	
	FILE *fp;
	struct id3header *pid3;
	uint32_t len;
	unsigned char hdr[28] = {0};
	uint64_t total_size = 0;
	uint64_t pointer_to_metadata_chunk = 0;
	uint64_t metadata_chunk_size = 0;
	unsigned char *id3tagbuf = NULL;

	//DEBUG DPRINTF(E_DEBUG,L_SCANNER,"Getting DSF file info\n");

	if((fp = fopen(file, "rb")) == NULL)
	{
		DPRINTF(E_WARN, L_SCANNER, "Could not create file handle\n");
		return -1;
	}

	len = 28;
	if(!(len = fread(hdr, len, 1,fp)))
	{
		DPRINTF(E_WARN, L_SCANNER, "Could not read DSD Chunk from %s\n", file);
		fclose(fp);
		return -1;
	}

	if(strncmp((char*)hdr, "DSD ", 4))
	{
		DPRINTF(E_WARN, L_SCANNER, "Invalid DSD Chunk header in %s\n", file);
		fclose(fp);
		return -1;
	}

	total_size = GET_DSF_INT64(hdr + 12);
	pointer_to_metadata_chunk = GET_DSF_INT64(hdr + 20);
	
	//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "%llu\n", total_size);
	//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "%llu\n", pointer_to_metadata_chunk);
	//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "%llu\n", metadata_chunk_size);

	//check invalid metadata
	if(total_size == 0)
	{
		fclose(fp);
		DPRINTF(E_INFO, L_SCANNER, "Invalid TotalDataSize in %s\n", file);
		return 0;
	}

	if(pointer_to_metadata_chunk == 0)
	{
		fclose(fp);
		DPRINTF(E_INFO, L_SCANNER, "Metadata doesn't exist %s\n", file);
		return 0;
	}

	if(total_size > pointer_to_metadata_chunk)
	{
		metadata_chunk_size = total_size - pointer_to_metadata_chunk;
	}
	else
	{
		fclose(fp);
		DPRINTF(E_INFO, L_SCANNER, "Invalid PointerToMetadata in %s\n", file);
		return 0;
	}

	fseeko(fp, pointer_to_metadata_chunk,SEEK_SET);

	id3tagbuf = (unsigned char *)malloc(sizeof(unsigned char)*metadata_chunk_size);
	if(id3tagbuf == NULL)
	{
		fclose(fp);
		DPRINTF(E_WARN, L_SCANNER, "Out of memory.Big MetadataSize in %s\n",file);
		return -1;
	}
	memset(id3tagbuf, 0,sizeof(unsigned char)*metadata_chunk_size);
	
	if(!(len = fread(id3tagbuf,metadata_chunk_size,1,fp)))
	{
		fclose(fp);
		free(id3tagbuf);
		DPRINTF(E_WARN, L_SCANNER, "Could not read Metadata Chunk from %s\n", file);
		return -1;
	}
	
	pid3tag = id3_tag_parse(id3tagbuf,metadata_chunk_size);
	
	if(!pid3tag)
	{
		free(id3tagbuf);
		err = errno;
		errno = err;
		DPRINTF(E_WARN, L_SCANNER, "Cannot get ID3 tag for %s\n", file);
		return -1;
	}

	pid3 = (struct id3header*)id3tagbuf;

	if(strncmp((char*)pid3->id, "ID3", 3) == 0)
	{
		char tagversion[16];

		/* found an ID3 header... */
		snprintf(tagversion, sizeof(tagversion), "ID3v2.%d.%d",
			 pid3->version[0], pid3->version[1]);
		psong->tagversion = strdup(tagversion);
	}
	pid3 = NULL;
	
	index = 0;
	while((pid3frame = id3_tag_findframe(pid3tag, "", index)))
	{
		used = 0;
		utf8_text = NULL;
		native_text = NULL;
		have_utf8 = 0;
		have_text = 0;

		if(!strcmp(pid3frame->id, "YTCP"))   /* for id3v2.2 */
		{
			psong->compilation = 1;
			DPRINTF(E_DEBUG, L_SCANNER, "Compilation: %d [%s]\n", psong->compilation, basename(file));
		}
		else if(!strcmp(pid3frame->id, "APIC") && !image_size)
		{
			if( (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpeg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "jpeg") == 0) )
			{
				image = id3_field_getbinarydata(&pid3frame->fields[4], &image_size);
				if( image_size )
				{
					psong->image = malloc(image_size);
					memcpy(psong->image, image, image_size);
					psong->image_size = image_size;
					//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "Found thumbnail: %d\n", psong->image_size);
				}
			}
		}

		if(((pid3frame->id[0] == 'T') || (strcmp(pid3frame->id, "COMM") == 0)) &&
		   (id3_field_getnstrings(&pid3frame->fields[1])))
			have_text = 1;

		if(have_text)
		{
			native_text = id3_field_getstrings(&pid3frame->fields[1], 0);

			if(native_text)
			{
				have_utf8 = 1;
				if(lang_index >= 0)
					utf8_text = _get_utf8_text(native_text); // through iconv
				else
					utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);

				if(!strcmp(pid3frame->id, "TIT2"))
				{
					used = 1;
					psong->title = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE1"))
				{
					used = 1;
					psong->contributor[ROLE_ARTIST] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TALB"))
				{
					used = 1;
					psong->album = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCOM"))
				{
					used = 1;
					psong->contributor[ROLE_COMPOSER] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TIT1"))
				{
					used = 1;
					psong->grouping = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE2"))
				{
					used = 1;
					psong->contributor[ROLE_BAND] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE3"))
				{
					used = 1;
					psong->contributor[ROLE_CONDUCTOR] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCON"))
				{
					used = 1;
					psong->genre = (char*)utf8_text;
					got_numeric_genre = 0;
					if(psong->genre)
					{
						if(!strlen(psong->genre))
						{
							genre = WINAMP_GENRE_UNKNOWN;
							got_numeric_genre = 1;
						}
						else if(isdigit(psong->genre[0]))
						{
							genre = atoi(psong->genre);
							got_numeric_genre = 1;
						}
						else if((psong->genre[0] == '(') && (isdigit(psong->genre[1])))
						{
							genre = atoi((char*)&psong->genre[1]);
							got_numeric_genre = 1;
						}

						if(got_numeric_genre)
						{
							if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
								genre = WINAMP_GENRE_UNKNOWN;
							free(psong->genre);
							psong->genre = strdup(winamp_genre[genre]);
						}
					}
				}
				else if(!strcmp(pid3frame->id, "COMM"))
				{
					used = 1;
					psong->comment = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPOS"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_discs = atoi(tmp);
					}
					psong->disc = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TRCK"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_tracks = atoi(tmp);
					}
					psong->track = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TDRC"))
				{
					psong->year = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TLEN"))
				{
					psong->song_length = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TBPM"))
				{
					psong->bpm = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TCMP"))
				{
					psong->compilation = (char)atoi((char*)utf8_text);
				}
			}
		}

		// check if text tag
		if((!used) && (have_utf8) && (utf8_text))
			free(utf8_text);

		// v2 COMM
		if((!strcmp(pid3frame->id, "COMM")) && (pid3frame->nfields == 4))
		{
			native_text = id3_field_getstring(&pid3frame->fields[2]);
			if(native_text)
			{
				utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
				if((utf8_text) && (strncasecmp((char*)utf8_text, "iTun", 4) != 0))
				{
					// read comment
					free(utf8_text);

					native_text = id3_field_getfullstring(&pid3frame->fields[3]);
					if(native_text)
					{
						utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
						if(utf8_text)
						{
							free(psong->comment);
							psong->comment = (char*)utf8_text;
						}
					}
				}
				else
				{
					free(utf8_text);
				}
			}
		}

		index++;
	}

	id3_tag_delete(pid3tag);
	free(id3tagbuf);
	fclose(fp);
	//DPRINTF(E_DEBUG, L_SCANNER, "Got id3tag successfully for file=%s\n", file);
	return 0;
}
Example #16
0
static unsigned char*
_get_utf8_text(const id3_ucs4_t* native_text)
{
	unsigned char *utf8_text = NULL;
	char *in, *in8, *iconv_buf;
	iconv_result rc;
	int i, n;

	in = (char*)id3_ucs4_latin1duplicate(native_text);
	if(!in)
	{
		goto out;
	}

	in8 = (char*)id3_ucs4_utf8duplicate(native_text);
	if(!in8)
	{
		free(in);
		goto out;
	}

	iconv_buf = (char*)calloc(MAX_ICONV_BUF, sizeof(char));
	if(!iconv_buf)
	{
		free(in); free(in8);
		goto out;
	}

	i = lang_index;
	// (1) try utf8 -> default
	rc = do_iconv(iconv_map[i].cpnames[0], "UTF-8", in8, strlen(in8), iconv_buf, MAX_ICONV_BUF);
	if(rc == ICONV_OK)
	{
		utf8_text = (unsigned char*)in8;
		free(iconv_buf);
	}
	else if(rc == ICONV_TRYNEXT)
	{
		// (2) try default -> utf8
		rc = do_iconv("UTF-8", iconv_map[i].cpnames[0], in, strlen(in), iconv_buf, MAX_ICONV_BUF);
		if(rc == ICONV_OK)
		{
			utf8_text = (unsigned char*)iconv_buf;
		}
		else if(rc == ICONV_TRYNEXT)
		{
			// (3) try other encodes
			for(n = 1; n < N_LANG_ALT && iconv_map[i].cpnames[n]; n++)
			{
				rc = do_iconv("UTF-8", iconv_map[i].cpnames[n], in, strlen(in), iconv_buf, MAX_ICONV_BUF);
				if(rc == ICONV_OK)
				{
					utf8_text = (unsigned char*)iconv_buf;
					break;
				}
			}
			if(!utf8_text)
			{
				// cannot iconv
				utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
				free(iconv_buf);
			}
		}
		free(in8);
	}
	free(in);

 out:
	if(!utf8_text)
	{
		utf8_text = (unsigned char*)strdup("UNKNOWN");
	}

	return utf8_text;
}
Example #17
0
void MP3ImportFileHandle::ImportID3(Tags *tags)
{
#ifdef USE_LIBID3TAG 
   struct id3_file *fp = id3_file_open(OSFILENAME(mFilename), ID3_FILE_MODE_READONLY);
   if (!fp) {
      return;
   }

   struct id3_tag *tp = id3_file_tag(fp);
   if (!tp) {
      id3_file_close(fp);
      return;
   }

   tags->Clear();
   tags->SetID3V2( tp->options & ID3_TAG_OPTION_ID3V1 ? false : true );

   // Loop through all frames
   for (int i = 0; i < (int) tp->nframes; i++) {
      struct id3_frame *frame = tp->frames[i];

      // printf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
      // printf("Desc: %s\n", frame->description);
      // printf("Num fields: %d\n", frame->nfields);

      // for (int j = 0; j < (int) frame->nfields; j++) {
      //    printf("field %d type %d\n", j, frame->fields[j].type );
      //    if (frame->fields[j].type == ID3_FIELD_TYPE_STRINGLIST) {
      //       printf("num strings %d\n", frame->fields[j].stringlist.nstrings);
      //    }
      // }

      wxString n, v;

      // Determine the tag name
      if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
         n = TAG_TITLE;
      }
      else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
         n = TAG_ARTIST;
      }
      else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
         n = TAG_ALBUM;
      }
      else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
         n = TAG_TRACK;
      }
      else if (strcmp(frame->id, "TYER") == 0) {
         n = TAG_YEAR;
      }
      else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
         n = TAG_YEAR;
      }
      else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
         n = TAG_COMMENTS;
      }
      else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
         n = TAG_GENRE;
      }
   else {
         // Use frame description as default tag name.  The descriptions
         // may include several "meanings" separated by "/" characters, so
         // we just use the first meaning
         n = UTF8CTOWX(frame->description).BeforeFirst(wxT('/'));
      }

      const id3_ucs4_t *ustr = NULL;

      if (n == TAG_COMMENTS) {
         ustr = id3_field_getfullstring(&frame->fields[3]);
      }
      else if (frame->nfields == 3) {
         ustr = id3_field_getstring(&frame->fields[1]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            n = UTF8CTOWX(str);
            free(str);
         }

         ustr = id3_field_getstring(&frame->fields[2]);
      }
      else if (frame->nfields >= 2) {
         ustr = id3_field_getstrings(&frame->fields[1], 0);
      }

      if (ustr) {
         char *str = (char *)id3_ucs4_utf8duplicate(ustr);
         v = UTF8CTOWX(str);
         free(str);
      }

      if (!n.IsEmpty() && !v.IsEmpty()) {
         tags->SetTag(n, v);
   }
}

   // Convert v1 genre to name
   if (tags->HasTag(TAG_GENRE)) {
      long g = -1;
      if (tags->GetTag(TAG_GENRE).ToLong(&g)) {
         tags->SetTag(TAG_GENRE, tags->GetGenre(g));
   }
}

   id3_file_close(fp);
#endif // ifdef USE_LIBID3TAG 
}
Example #18
0
/*****************************************************************************
 * ParseID3Tag : parse an id3tag into the info structures
 *****************************************************************************/
static void ParseID3Tag( demux_meta_t *p_demux_meta, const uint8_t *p_data, int i_size )
{
    struct id3_tag   *p_id3_tag;
    struct id3_frame *p_frame;
    vlc_meta_t       *p_meta;
    int i;

    p_id3_tag = id3_tag_parse( p_data, i_size );
    if( !p_id3_tag )
        return;

    if( !p_demux_meta->p_meta )
        p_demux_meta->p_meta = vlc_meta_New();
    p_meta = p_demux_meta->p_meta;

#define ID_IS( a ) (!strcmp(  p_frame->id, a ))
#define DESCR_IS( a) strstr( (char*)p_frame->description, a )
#define GET_STRING(frame,fidx) id3_ucs4_latin1duplicate( id3_field_getstring( &(frame)->fields[fidx] ) )

    /* */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "UFID", i )) != NULL; i++ )
    {
        const char *psz_owner = id3_field_getlatin1( &p_frame->fields[0] );

        if( !strncmp( psz_owner, "http://musicbrainz.org", 22 ) )
        {
            id3_byte_t const * p_ufid;
            id3_length_t i_ufidlen;

            p_ufid = id3_field_getbinarydata( &p_frame->fields[1], &i_ufidlen );
            char *psz_ufid = strndup( p_ufid, i_ufidlen );

            vlc_meta_SetTrackID( p_meta, psz_ufid );
            free( psz_ufid );
        }
    }

    /* User defined text (TXXX) */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "TXXX", i )) != NULL; i++ )
    {
        /* 3 fields: 'encoding', 'description', 'value' */
        char *psz_name = GET_STRING( p_frame, 1 );
        char *psz_value = GET_STRING( p_frame, 2 );

        vlc_meta_AddExtra( p_meta, psz_name, psz_value );
#if 0
        if( !strncmp( psz_name, "MusicBrainz Artist Id", 21 ) )
            vlc_meta_SetArtistID( p_meta, psz_value );
        if( !strncmp( psz_desc, "MusicBrainz Album Id", 20 ) )
            vlc_meta_SetAlbumID( p_meta, psz_value );
#endif
        free( psz_name );
        free( psz_value );
    }

    /* Relative volume adjustment */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "RVA2", i )) != NULL; i++ )
    {
        /* 2 fields: 'latin1', 'binary' */
        const char *psz_type = id3_field_getlatin1( &p_frame->fields[0] );
        if( !strcasecmp( psz_type, "track" ) || !strcasecmp( psz_type, "album" ) ||
            !strcasecmp( psz_type, "normalize" ) )
        {
            id3_byte_t const * p_data;
            id3_length_t i_data;

            p_data = id3_field_getbinarydata( &p_frame->fields[1], &i_data );
            while( i_data >= 4 )
            {
                const unsigned int i_peak_size = p_data[3];
                const float f_temp = GetWBE( &p_data[1] );
                const float f_gain = f_temp / 512.0;
                char psz_value[32];

                if( i_data < i_peak_size + 4 )
                    break;
                /* only master volume */
                if( p_data[0] == 0x01 )
                {
                    snprintf( psz_value, sizeof(psz_value), "%f", f_gain );
                    if( !strcasecmp( psz_type, "album" ) )
                        vlc_meta_AddExtra( p_meta, "REPLAYGAIN_ALBUM_GAIN", psz_value );
                    else
                        vlc_meta_AddExtra( p_meta, "REPLAYGAIN_TRACK_GAIN", psz_value );
                    /* XXX I have no idea what peak unit is ... */
                }
                i_data -= 4+i_peak_size;
            }
        }
    }

    /* TODO 'RGAD' if it is used somewhere */

    /* T--- Text informations */
    for( i = 0; (p_frame = id3_tag_findframe( p_id3_tag, "T", i )) != NULL; i++ )
    {
        unsigned i_strings;
 
        /* Special case TXXX is not the same beast */
        if( ID_IS( "TXXX" ) )
            continue;

        i_strings = id3_field_getnstrings( &p_frame->fields[1] );
        while( i_strings > 0 )
        {
            char *psz_temp = id3_ucs4_utf8duplicate(
                id3_field_getstrings( &p_frame->fields[1], --i_strings ) );

            if( ID_IS( ID3_FRAME_GENRE ) )
            {
                char *psz_endptr;
                int i_genre = strtol( psz_temp, &psz_endptr, 10 );

                if( psz_temp != psz_endptr &&
                    i_genre >= 0 && i_genre < NUM_GENRES )
                {
                    vlc_meta_SetGenre( p_meta, ppsz_genres[atoi(psz_temp)]);
                }
                else
                {
                    /* Unknown genre */
                    vlc_meta_SetGenre( p_meta,psz_temp );
                }
            }
            else if( ID_IS( ID3_FRAME_TITLE ) )
            {
                vlc_meta_SetTitle( p_meta, psz_temp );
            }
            else if( ID_IS( ID3_FRAME_ARTIST ) )
            {
                vlc_meta_SetArtist( p_meta, psz_temp );
            }
            else if( ID_IS( ID3_FRAME_YEAR ) )
            {
                vlc_meta_SetDate( p_meta, psz_temp );
            }
            else if( ID_IS( ID3_FRAME_COMMENT ) )
            {
                vlc_meta_SetDescription( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Copyright" ) )
            {
                vlc_meta_SetCopyright( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Publisher" ) )
            {
                vlc_meta_SetPublisher( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Track number/position in set" ) )
            {
                vlc_meta_SetTrackNum( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Album/movie/show title" ) )
            {
                vlc_meta_SetAlbum( p_meta, psz_temp );
            }
            else if( DESCR_IS( "Encoded by" ) )
            {
                vlc_meta_SetEncodedBy( p_meta, psz_temp );
            }
            else if( ID_IS ( "APIC" ) )
            {
                msg_Dbg( p_demux_meta, "** Has APIC **" );
            }
            else if( p_frame->description )
            {
                /* Unhandled meta */
                vlc_meta_AddExtra( p_meta, (char*)p_frame->description, psz_temp );
            }
            free( psz_temp );
        }
    }
    id3_tag_delete( p_id3_tag );
#undef GET_STRING
#undef DESCR_IS
#undef ID_IS
}
Example #19
0
void MP3ImportFileHandle::ImportID3(Tags *tags)
{
#ifdef USE_LIBID3TAG
   wxFile f;   // will be closed when it goes out of scope
   struct id3_file *fp = NULL;

   if (f.Open(mFilename)) {
      // Use id3_file_fdopen() instead of id3_file_open since wxWidgets can open a
      // file with a Unicode name and id3_file_open() can't (under Windows).
      fp = id3_file_fdopen(f.fd(), ID3_FILE_MODE_READONLY);
   }

   if (!fp) {
      return;
   }

   // The file descriptor is now owned by "fp", so we must tell "f" to forget
   // about it.
   f.Detach();

   struct id3_tag *tp = id3_file_tag(fp);
   if (!tp) {
      id3_file_close(fp);
      return;
   }

   tags->Clear();

   // Loop through all frames
   bool have_year = false;
   for (int i = 0; i < (int) tp->nframes; i++) {
      struct id3_frame *frame = tp->frames[i];

      // printf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
      // printf("Desc: %s\n", frame->description);
      // printf("Num fields: %d\n", frame->nfields);

      // for (int j = 0; j < (int) frame->nfields; j++) {
      //    printf("field %d type %d\n", j, frame->fields[j].type );
      //    if (frame->fields[j].type == ID3_FIELD_TYPE_STRINGLIST) {
      //       printf("num strings %d\n", frame->fields[j].stringlist.nstrings);
      //    }
      // }

      wxString n, v;

      // Determine the tag name
      if (strcmp(frame->id, ID3_FRAME_TITLE) == 0) {
         n = TAG_TITLE;
      }
      else if (strcmp(frame->id, ID3_FRAME_ARTIST) == 0) {
         n = TAG_ARTIST;
      }
      else if (strcmp(frame->id, ID3_FRAME_ALBUM) == 0) {
         n = TAG_ALBUM;
      }
      else if (strcmp(frame->id, ID3_FRAME_TRACK) == 0) {
         n = TAG_TRACK;
      }
      else if (strcmp(frame->id, ID3_FRAME_YEAR) == 0) {
         // LLL:  When libid3tag encounters the "TYER" tag, it converts it to a
         //       "ZOBS" (obsolete) tag and adds a "TDRC" tag at the end of the
         //       list of tags using the first 4 characters of the "TYER" tag.
         //       Since we write both the "TDRC" and "TYER" tags, the "TDRC" tag
         //       will always be encountered first in the list.  We want use it
         //       since the converted "TYER" tag may have been truncated.
         if (have_year) {
            continue;
         }
         n = TAG_YEAR;
         have_year = true;
      }
      else if (strcmp(frame->id, ID3_FRAME_COMMENT) == 0) {
         n = TAG_COMMENTS;
      }
      else if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) {
         n = TAG_GENRE;
      }
   else {
         // Use frame description as default tag name.  The descriptions
         // may include several "meanings" separated by "/" characters, so
         // we just use the first meaning
         n = UTF8CTOWX(frame->description).BeforeFirst(wxT('/'));
      }

      const id3_ucs4_t *ustr = NULL;

      if (n == TAG_COMMENTS) {
         ustr = id3_field_getfullstring(&frame->fields[3]);
      }
      else if (frame->nfields == 3) {
         ustr = id3_field_getstring(&frame->fields[1]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            n = UTF8CTOWX(str);
            free(str);
         }

         ustr = id3_field_getstring(&frame->fields[2]);
      }
      else if (frame->nfields >= 2) {
         ustr = id3_field_getstrings(&frame->fields[1], 0);
      }

      if (ustr) {
         char *str = (char *)id3_ucs4_utf8duplicate(ustr);
         v = UTF8CTOWX(str);
         free(str);
      }

      if (!n.IsEmpty() && !v.IsEmpty()) {
         tags->SetTag(n, v);
   }
}

   // Convert v1 genre to name
   if (tags->HasTag(TAG_GENRE)) {
      long g = -1;
      if (tags->GetTag(TAG_GENRE).ToLong(&g)) {
         tags->SetTag(TAG_GENRE, tags->GetGenre(g));
   }
}

   id3_file_close(fp);
#endif // ifdef USE_LIBID3TAG
}
Example #20
0
void Tags::ImportID3(wxString fileName)
{
#ifdef USE_LIBID3TAG 

   struct id3_file *fp = id3_file_open(OSFILENAME(fileName),
                                          ID3_FILE_MODE_READONLY);
   if (!fp) return;

   struct id3_tag *tp = id3_file_tag(fp);
   if (!tp) return;

   mTitle = GetID3FieldStr(tp, ID3_FRAME_TITLE);
   mArtist = GetID3FieldStr(tp, ID3_FRAME_ARTIST);
   mAlbum = GetID3FieldStr(tp, ID3_FRAME_ALBUM);   
   mYear = GetID3FieldStr(tp, ID3_FRAME_YEAR);
   mComments = GetID3FieldStr(tp, ID3_FRAME_COMMENT);

   long l;
   wxString s;
   if ((s = GetID3FieldStr(tp, ID3_FRAME_TRACK)).ToLong(&l))
      mTrackNum = l;

   mID3V2 = ( tp->options & ID3_TAG_OPTION_ID3V1 ) ? false : true;
   
   s = GetID3FieldStr(tp, ID3_FRAME_GENRE);

   if( mID3V2 ) {
      int numGenres = GetNumGenres();
      for(int i=0; i<numGenres; i++)
         if (0 == s.CmpNoCase(GetGenreNum(i)))
            mGenre = i;
   }
   else {
      if( s.ToLong( &l ) )
         mGenre = l;
   }

   // Loop through all remaining frames
   int i;
   for(i=0; i<(int)tp->nframes; i++) {
      struct id3_frame *frame = tp->frames[i];

      //printf("ID: %08x '%4s'\n", (int) *(int *)frame->id, frame->id);
      //printf("Desc: %s\n", frame->description);
      //printf("Num fields: %d\n", frame->nfields);
      
      if (!strcmp(frame->id, ID3_FRAME_TITLE) ||
          !strcmp(frame->id, ID3_FRAME_ARTIST) ||
          !strcmp(frame->id, ID3_FRAME_ALBUM) ||
          !strcmp(frame->id, ID3_FRAME_YEAR) ||
          !strcmp(frame->id, ID3_FRAME_COMMENT) ||
          !strcmp(frame->id, ID3_FRAME_GENRE) ||
          !strcmp(frame->id, ID3_FRAME_TRACK)) {
         continue;
      }

      const id3_ucs4_t *ustr;

      if (frame->nfields>=2) {
         ustr = id3_field_getstrings(&frame->fields[1], 0);
         if (ustr) {
            wxString name = UTF8CTOWX(frame->description);
            
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            wxString value = UTF8CTOWX(str);
            free(str);
            
            mExtraNames.Add(name);
            mExtraValues.Add(value);
         }
      }

      if (frame->nfields==3) {
         wxString name, value;

         ustr = id3_field_getstring(&frame->fields[2]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            value = UTF8CTOWX(str);
            free(str);
         }

         ustr = id3_field_getstring(&frame->fields[1]);
         if (ustr) {
            char *str = (char *)id3_ucs4_utf8duplicate(ustr);
            name = UTF8CTOWX(str);
            free(str);
         }

         mExtraNames.Add(name);
         mExtraValues.Add(value);
      }

   }

   id3_file_close(fp);
#endif // ifdef USE_LIBID3TAG 
}
Example #21
0
static int
_get_mp3tags(char *file, struct song_metadata *psong)
{
	struct id3_file *pid3file;
	struct id3_tag *pid3tag;
	struct id3_frame *pid3frame;
	int err;
	int index;
	int used;
	unsigned char *utf8_text;
	int genre = WINAMP_GENRE_UNKNOWN;
	int have_utf8;
	int have_text;
	id3_ucs4_t const *native_text;
	char *tmp;
	int got_numeric_genre;
	id3_byte_t const *image;
	id3_length_t image_size = 0;

	pid3file = id3_file_open(file, ID3_FILE_MODE_READONLY);
	if(!pid3file)
	{
		DPRINTF(E_ERROR, L_SCANNER, "Cannot open %s\n", file);
		return -1;
	}

	pid3tag = id3_file_tag(pid3file);

	if(!pid3tag)
	{
		err = errno;
		id3_file_close(pid3file);
		errno = err;
		DPRINTF(E_WARN, L_SCANNER, "Cannot get ID3 tag for %s\n", file);
		return -1;
	}

	index = 0;
	while((pid3frame = id3_tag_findframe(pid3tag, "", index)))
	{
		used = 0;
		utf8_text = NULL;
		native_text = NULL;
		have_utf8 = 0;
		have_text = 0;

		if(!strcmp(pid3frame->id, "YTCP"))   /* for id3v2.2 */
		{
			psong->compilation = 1;
			DPRINTF(E_DEBUG, L_SCANNER, "Compilation: %d [%s]\n", psong->compilation, basename(file));
		}
		else if(!strcmp(pid3frame->id, "APIC") && !image_size)
		{
			if( (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpeg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/jpg") == 0) ||
			    (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "jpeg") == 0)
#if HAVE_LIBPNG
			    || (strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "image/png") == 0) ||
				(strcmp((char*)id3_field_getlatin1(&pid3frame->fields[1]), "png") == 0)
#endif
			)
			{
				image = id3_field_getbinarydata(&pid3frame->fields[4], &image_size);
				if( image_size )
				{
					psong->image = malloc(image_size);
					memcpy(psong->image, image, image_size);
					psong->image_size = image_size;
					//DEBUG DPRINTF(E_DEBUG, L_SCANNER, "Found thumbnail: %d\n", psong->image_size);
				}
			}
		}

		if(((pid3frame->id[0] == 'T') || (strcmp(pid3frame->id, "COMM") == 0)) &&
		   (id3_field_getnstrings(&pid3frame->fields[1])))
			have_text = 1;

		if(have_text)
		{
			native_text = id3_field_getstrings(&pid3frame->fields[1], 0);

			if(native_text)
			{
				have_utf8 = 1;
				if(lang_index >= 0)
					utf8_text = _get_utf8_text(native_text); // through iconv
				else
					utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);

				if(!strcmp(pid3frame->id, "TIT2"))
				{
					used = 1;
					psong->title = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE1"))
				{
					used = 1;
					psong->contributor[ROLE_ARTIST] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TALB"))
				{
					used = 1;
					psong->album = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCOM"))
				{
					used = 1;
					psong->contributor[ROLE_COMPOSER] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TIT1"))
				{
					used = 1;
					psong->grouping = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE2"))
				{
					used = 1;
					psong->contributor[ROLE_BAND] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPE3"))
				{
					used = 1;
					psong->contributor[ROLE_CONDUCTOR] = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TCON"))
				{
					used = 1;
					psong->genre = (char*)utf8_text;
					got_numeric_genre = 0;
					if(psong->genre)
					{
						if(!strlen(psong->genre))
						{
							genre = WINAMP_GENRE_UNKNOWN;
							got_numeric_genre = 1;
						}
						else if(isdigit(psong->genre[0]))
						{
							genre = atoi(psong->genre);
							got_numeric_genre = 1;
						}
						else if((psong->genre[0] == '(') && (isdigit(psong->genre[1])))
						{
							genre = atoi((char*)&psong->genre[1]);
							got_numeric_genre = 1;
						}

						if(got_numeric_genre)
						{
							if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
								genre = WINAMP_GENRE_UNKNOWN;
							free(psong->genre);
							psong->genre = strdup(winamp_genre[genre]);
						}
					}
				}
				else if(!strcmp(pid3frame->id, "COMM"))
				{
					used = 1;
					psong->comment = (char*)utf8_text;
				}
				else if(!strcmp(pid3frame->id, "TPOS"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_discs = atoi(tmp);
					}
					psong->disc = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TRCK"))
				{
					tmp = (char*)utf8_text;
					strsep(&tmp, "/");
					if(tmp)
					{
						psong->total_tracks = atoi(tmp);
					}
					psong->track = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TDRC"))
				{
					psong->year = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TLEN"))
				{
					psong->song_length = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TBPM"))
				{
					psong->bpm = atoi((char*)utf8_text);
				}
				else if(!strcmp(pid3frame->id, "TCMP"))
				{
					psong->compilation = (char)atoi((char*)utf8_text);
				}
			}
		}

		// check if text tag
		if((!used) && (have_utf8) && (utf8_text))
			free(utf8_text);

		// v2 COMM
		if((!strcmp(pid3frame->id, "COMM")) && (pid3frame->nfields == 4))
		{
			native_text = id3_field_getstring(&pid3frame->fields[2]);
			if(native_text)
			{
				utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
				if((utf8_text) && (strncasecmp((char*)utf8_text, "iTun", 4) != 0))
				{
					// read comment
					free(utf8_text);

					native_text = id3_field_getfullstring(&pid3frame->fields[3]);
					if(native_text)
					{
						utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text);
						if(utf8_text)
						{
							free(psong->comment);
							psong->comment = (char*)utf8_text;
						}
					}
				}
				else
				{
					free(utf8_text);
				}
			}
		}

		index++;
	}

	id3_file_close(pid3file);
	//DEBUG DPRINTF(E_INFO, L_SCANNER, "Got id3 tag successfully for file=%s\n", file);
	return 0;
}