コード例 #1
0
ファイル: tag.c プロジェクト: Jsoucek/q3ce
static
int v1_attachstr(struct id3_tag *tag, char const *id,
		 char *text, unsigned long number)
{
  struct id3_frame *frame;
  id3_ucs4_t ucs4[31];

  if (text) {
    trim(text);
    if (*text == 0)
      return 0;
  }

  frame = id3_frame_new(id);
  if (frame == 0)
    return -1;

  if (id3_field_settextencoding(&frame->fields[0],
				ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1)
    goto fail;

  if (text)
    id3_latin1_decode(text, ucs4);
  else
    id3_ucs4_putnumber(ucs4, number);

  if (strcmp(id, ID3_FRAME_COMMENT) == 0) {
    if (id3_field_setlanguage(&frame->fields[1], "XXX") == -1 ||
	id3_field_setstring(&frame->fields[2], id3_ucs4_empty) == -1 ||
	id3_field_setfullstring(&frame->fields[3], ucs4) == -1)
      goto fail;
  }
  else {
    id3_ucs4_t *ptr = ucs4;

    if (id3_field_setstrings(&frame->fields[1], 1, &ptr) == -1)
      goto fail;
  }

  if (id3_tag_attachframe(tag, frame) == -1)
    goto fail;

  return 0;

 fail:
  id3_frame_delete(frame);
  return -1;
}
コード例 #2
0
ファイル: metadata.c プロジェクト: sd-eblana/bawx
int id3_metadata_setcomment(struct id3_tag* tag, id3_ucs4_t* value)
{
  union id3_field *field;
  struct id3_frame *frame;

  frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, 0);
  if (frame == 0)
  {
	  frame = id3_frame_new(ID3_FRAME_COMMENT);
    id3_tag_attachframe(tag, frame);
  }

  id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);

  field = id3_frame_field(frame, 3);
  if (field == 0)
    return 0;

  return id3_field_setfullstring(field, value);
}
コード例 #3
0
ファイル: metadata.c プロジェクト: sd-eblana/bawx
int metadata_setstring(struct id3_tag* tag, const char* id, id3_ucs4_t* value)
{
  union id3_field *field;
  struct id3_frame *frame;

  frame = id3_tag_findframe(tag, id, 0);
  if (frame == 0)
  {
	  frame = id3_frame_new(id);
    id3_tag_attachframe(tag, frame);
  }

  id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);

  field = id3_frame_field(frame, 1);
  if (field == 0)
    return 0;

  return (id3_field_setstrings(field, 1, &value)==0);
}
コード例 #4
0
ファイル: ExportMP2.cpp プロジェクト: Avi2011class/audacity
void ExportMP2::AddFrame(struct id3_tag *tp, const wxString & n, const wxString & v, const char *name)
{
   struct id3_frame *frame = id3_frame_new(name);

   if (!n.IsAscii() || !v.IsAscii()) {
      id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
   }
   else {
      id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
   }

   id3_ucs4_t *ucs4 =
      id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) v.mb_str(wxConvUTF8));

   if (strcmp(name, ID3_FRAME_COMMENT) == 0) {
      // A hack to get around iTunes not recognizing the comment.  The
      // language defaults to XXX and, since it's not a valid language,
      // iTunes just ignores the tag.  So, either set it to a valid language
      // (which one???) or just clear it.  Unfortunately, there's no supported
      // way of clearing the field, so do it directly.
      id3_field *f = id3_frame_field(frame, 1);
      memset(f->immediate.value, 0, sizeof(f->immediate.value));
      id3_field_setfullstring(id3_frame_field(frame, 3), ucs4);
   }
   else if (strcmp(name, "TXXX") == 0) {
      id3_field_setstring(id3_frame_field(frame, 2), ucs4);
      free(ucs4);

      ucs4 = id3_utf8_ucs4duplicate((id3_utf8_t *) (const char *) n.mb_str(wxConvUTF8));

      id3_field_setstring(id3_frame_field(frame, 1), ucs4);
   }
   else {
      id3_field_setstrings(id3_frame_field(frame, 1), 1, &ucs4);
   }

   free(ucs4);

   id3_tag_attachframe(tp, frame);
}
コード例 #5
0
ファイル: metadata.c プロジェクト: sd-eblana/bawx
int id3_metadata_setrating(struct id3_tag* tag, char value)
{
  union id3_field *field;
  struct id3_frame *frame;
  char popm[] = { 3, 53, 104, 154, 205, 255 };

  if (value < '0' || value > '5')
    return -1;

  frame = id3_tag_findframe(tag, "POPM", 0);
  if (frame == 0)
  {
	  frame = id3_frame_new("POPM");
    id3_tag_attachframe(tag, frame);
  }

  field = id3_frame_field(frame, 1);
  if (field == 0)
    return 0;

  return id3_field_setint(field, popm[value - '0']);
}
コード例 #6
0
ファイル: tag.c プロジェクト: Jsoucek/q3ce
static
struct id3_tag *v2_parse(id3_byte_t const *ptr)
{
  struct id3_tag *tag;
  id3_byte_t *mem = 0;

  tag = id3_tag_new();
  if (tag) {
    id3_byte_t const *end;
    id3_length_t size;

    parse_header(&ptr, &tag->version, &tag->flags, &size);

    tag->paddedsize = 10 + size;

    if ((tag->flags & ID3_TAG_FLAG_UNSYNCHRONISATION) &&
	ID3_TAG_VERSION_MAJOR(tag->version) < 4) {
      mem = malloc(size);
      if (mem == 0)
	goto fail;

      memcpy(mem, ptr, size);

      size = id3_util_deunsynchronise(mem, size);
      ptr  = mem;
    }

    end = ptr + size;

    if (tag->flags & ID3_TAG_FLAG_EXTENDEDHEADER) {
      switch (ID3_TAG_VERSION_MAJOR(tag->version)) {
      case 2:
	goto fail;

      case 3:
	{
	  id3_byte_t const *ehptr, *ehend;
	  id3_length_t ehsize;

	  enum {
	    EH_FLAG_CRC = 0x8000  /* CRC data present */
	  };

	  if (end - ptr < 4)
	    goto fail;

	  ehsize = id3_parse_uint(&ptr, 4);

	  if (ehsize > end - ptr)
	    goto fail;

	  ehptr = ptr;
	  ehend = ptr + ehsize;

	  ptr = ehend;

	  if (ehend - ehptr >= 6) {
	    int ehflags;
	    id3_length_t padsize;

	    ehflags = id3_parse_uint(&ehptr, 2);
	    padsize = id3_parse_uint(&ehptr, 4);

	    if (padsize > end - ptr)
	      goto fail;

	    end -= padsize;

	    if (ehflags & EH_FLAG_CRC) {
	      unsigned long crc;

	      if (ehend - ehptr < 4)
		goto fail;

	      crc = id3_parse_uint(&ehptr, 4);

	      if (crc != id3_crc_compute(ptr, end - ptr))
		goto fail;

	      tag->extendedflags |= ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT;
	    }
	  }
	}
	break;

      case 4:
	{
	  id3_byte_t const *ehptr, *ehend;
	  id3_length_t ehsize;
	  unsigned int bytes;

	  if (end - ptr < 4)
	    goto fail;

	  ehptr  = ptr;
	  ehsize = id3_parse_syncsafe(&ptr, 4);

	  if (ehsize < 6 || ehsize > end - ehptr)
	    goto fail;

	  ehend = ehptr + ehsize;

	  bytes = id3_parse_uint(&ptr, 1);

	  if (bytes < 1 || bytes > ehend - ptr)
	    goto fail;

	  ehptr = ptr + bytes;

	  /* verify extended header size */
	  {
	    id3_byte_t const *flagsptr = ptr, *dataptr = ehptr;
	    unsigned int datalen;
	    int ehflags;

	    while (bytes--) {
	      for (ehflags = id3_parse_uint(&flagsptr, 1); ehflags;
		   ehflags = (ehflags << 1) & 0xff) {
		if (ehflags & 0x80) {
		  if (dataptr == ehend)
		    goto fail;
		  datalen = id3_parse_uint(&dataptr, 1);
		  if (datalen > 0x7f || datalen > ehend - dataptr)
		    goto fail;
		  dataptr += datalen;
		}
	      }
	    }
	  }

	  tag->extendedflags = id3_parse_uint(&ptr, 1);

	  ptr = ehend;

	  if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE) {
	    bytes  = id3_parse_uint(&ehptr, 1);
	    ehptr += bytes;
	  }

	  if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT) {
	    unsigned long crc;

	    bytes = id3_parse_uint(&ehptr, 1);
	    if (bytes < 5)
	      goto fail;

	    crc = id3_parse_syncsafe(&ehptr, 5);
	    ehptr += bytes - 5;

	    if (crc != id3_crc_compute(ptr, end - ptr))
	      goto fail;
	  }

	  if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS) {
	    bytes = id3_parse_uint(&ehptr, 1);
	    if (bytes < 1)
	      goto fail;

	    tag->restrictions = id3_parse_uint(&ehptr, 1);
	    ehptr += bytes - 1;
	  }
	}
	break;
      }
    }

    /* frames */

    while (ptr < end) {
      struct id3_frame *frame;

      if (*ptr == 0)
	break;  /* padding */

      frame = id3_frame_parse(&ptr, end - ptr, tag->version);
      if (frame == 0 || id3_tag_attachframe(tag, frame) == -1)
	goto fail;
    }

    if (ID3_TAG_VERSION_MAJOR(tag->version) < 4 &&
	id3_compat_fixup(tag) == -1)
      goto fail;
  }

  if (0) {
  fail:
    id3_tag_delete(tag);
    tag = 0;
  }

  if (mem)
    free(mem);

  return tag;
}
コード例 #7
0
ファイル: fly_id3.c プロジェクト: gravityrail/pianobarfly
int BarFlyID3AddCover(struct id3_tag* tag, uint8_t const* cover_art,
		size_t cover_size, BarSettings_t const* settings)
{
	/*
	 * http://flac.sourceforge.net/api/group__flac__format.html#ga113
	 */
	int const PICTURE_TYPE_FRONT_COVER = 3;

	char const BAR_FLY_ID3_FRAME_PICTURE[] = "APIC";

	int exit_status = 0;
	int status;
	struct id3_frame* frame = NULL;
	union id3_field* field;
	int index;
	char* mime_type;

	assert(tag != NULL);
	assert(cover_art != NULL);
	assert(settings != NULL);

	/*
	 * Get a new picture frame.
	 */
	frame = id3_frame_new(BAR_FLY_ID3_FRAME_PICTURE);
	if (frame == NULL) {
		BarUiMsg(settings, MSG_ERR, "Failed to create new frame (type = %s).\n", 
				BAR_FLY_ID3_FRAME_PICTURE);
		goto error;
	}
	
	/*
	 * Go through all the frame fields setting the mime type, image type, and
	 * the image data.
	 */
	index = 0;
	field = id3_frame_field(frame, index);
	while (field != NULL) {
		switch (id3_field_type(field)) {
			/*
			 * Set the cover art mime type.
			 */
			case (ID3_FIELD_TYPE_LATIN1):
				if ((cover_art[0] == 0xFF) && (cover_art[1] == 0xD8)) {
					mime_type = "image/jpeg";
				} else if ((cover_art[0] == 0x89) &&
				           (cover_art[1] == 0x50) &&
				           (cover_art[2] == 0x4E) &&
				           (cover_art[3] == 0x47) &&
				           (cover_art[4] == 0x0D) &&
				           (cover_art[5] == 0x0A) &&
				           (cover_art[6] == 0x1A) &&
				           (cover_art[7] == 0x0A)) {
					mime_type = "image/png";
				} else {
					mime_type = NULL;
				}

				id3_field_setlatin1(field, (id3_latin1_t const*)mime_type);
				break;

			/*
			 * Designate this as the front cover.
			 */
			case (ID3_FIELD_TYPE_INT8):
				id3_field_setint(field, PICTURE_TYPE_FRONT_COVER);
				break;

			/*
			 * Set the image data.
			 */
			case (ID3_FIELD_TYPE_BINARYDATA):
				id3_field_setbinarydata(field, cover_art, cover_size);
				break;

			default:
				break;
		}

		index++;
		field = id3_frame_field(frame, index);
	}

	/*
	 * Attach the frame to the tag.
	 */
	status = id3_tag_attachframe(tag, frame);
	if (status != 0) {
		BarUiMsg(settings, MSG_ERR, "Failed to attach cover art frame.\n");
		goto error;
	}

	goto end;

error:
	if (frame != NULL) {
		id3_frame_delete(frame);
	}

	exit_status = -1;

end:
	return exit_status;
}
コード例 #8
0
ファイル: fly_id3.c プロジェクト: gravityrail/pianobarfly
int BarFlyID3AddFrame(struct id3_tag* tag, char const* type,
		char const* value, BarSettings_t const* settings)
{
	int exit_status = 0;
	int status;
	struct id3_frame* frame = NULL;
	union id3_field* field;
	id3_ucs4_t* ucs4 = NULL;
	int index;

	assert(tag != NULL);
	assert(type != NULL);
	assert(value != NULL);
	assert(settings != NULL);

	/*
	 * Create the frame.
	 */
	frame = id3_frame_new(type);
	if (frame == NULL) {
		BarUiMsg(settings, MSG_ERR, "Failed to create new frame (type = %s).\n",
				type);
		goto error;
	}

	frame->flags &= ~ID3_FRAME_FLAG_FORMATFLAGS;

	/*
	 * Get the string list field of the frame.
	 */
	index = 0;
	do {
		field = id3_frame_field(frame, index);
		index++;
	} while (id3_field_type(field) != ID3_FIELD_TYPE_STRINGLIST);
	assert(id3_field_type(field) == ID3_FIELD_TYPE_STRINGLIST);

	/*
	 * Add the value as a string to the field.
	 */
	ucs4 = id3_latin1_ucs4duplicate((id3_latin1_t*)value);
	if (ucs4 == NULL) {
		BarUiMsg(settings, MSG_ERR, "Could not allocate memory.\n");
		goto error;
	}

	status = id3_field_addstring(field, ucs4);
	if (status != 0) {
		BarUiMsg(settings, MSG_ERR, "Failed to set field value (value = %s).\n",
				value);
		goto error;
	}

	/*
	 * Attach the frame to the tag.
	 */
	status = id3_tag_attachframe(tag, frame);
	if (status != 0) {
		BarUiMsg(settings, MSG_ERR, "Failed to attach frame (type = %s).\n",
				type);
		goto error;
	}

	goto end;
	
error:
	if (frame != NULL) {
		id3_frame_delete(frame);
	}

	exit_status = -1;

end:
	if (ucs4 != NULL) {
		free(ucs4);
	}

	return exit_status;
}
コード例 #9
0
ファイル: loader_id3.c プロジェクト: Limsik/e17
static context     *
context_create(const char *filename)
{
   context            *node = (context *) malloc(sizeof(context));
   context            *ptr, *last;
   int                 last_id = INT_MAX;

   node->refcount = 1;
   {
      struct id3_file    *file;
      struct id3_tag     *tag;
      unsigned int        i;

      file = id3_file_open(filename, ID3_FILE_MODE_READONLY);
      if (!file)
        {
           fprintf(stderr, "Unable to open tagged file %s: %s\n",
                   filename, strerror(errno));
           goto fail_free;
        }
      tag = id3_file_tag(file);
      if (!tag)
        {
           fprintf(stderr, "Unable to find ID3v2 tags in file %s\n", filename);
           id3_file_close(file);
           goto fail_free;
        }
      node->tag = id3_tag_new();
      for (i = 0; i < id3_tag_get_numframes(tag); i++)
         if (!strcmp(id3_frame_id(id3_tag_get_frame(tag, i)), "APIC"))
            id3_tag_attachframe(node->tag, id3_tag_get_frame(tag, i));
      id3_file_close(file);
   }
   node->filename = strdup(filename);
   if (!id3_ctxs)
     {
        node->id = 1;
        node->next = NULL;
        id3_ctxs = node;
        return node;
     }
   ptr = id3_ctxs;
   last = NULL;
   while (UNLIKELY(ptr && (ptr->id + 1) >= last_id))
     {
        last_id = ptr->id;
        last = ptr;
        ptr = ptr->next;
     }
   /* Paranoid! this can occur only if there are INT_MAX contexts :) */
   if (UNLIKELY(!ptr))
     {
        fprintf(stderr, "Too many open ID3 contexts\n");
        goto fail_close;
     }
   node->id = ptr->id + 1;
   if (UNLIKELY(! !last))
     {
        node->next = last->next;
        last->next = node;
     }
   else
     {
        node->next = id3_ctxs;
        id3_ctxs = node;
     }
   return node;

 fail_close:
   free(node->filename);
   id3_tag_delete(node->tag);
 fail_free:
   free(node);
   return NULL;
}
コード例 #10
0
ファイル: Tags.cpp プロジェクト: Kirushanr/audacity
// returns buffer len; caller frees
int Tags::ExportID3(char **buffer, bool *endOfFile)
{
#ifdef USE_LIBID3TAG 
   struct id3_tag *tp = id3_tag_new();
   
   if (mTitle != wxT(""))
      id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_TITLE, mTitle.mb_str()));

   if (mArtist != wxT(""))
      id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_ARTIST, mArtist.mb_str()));

   if (mAlbum != wxT(""))
      id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_ALBUM, mAlbum.mb_str()));

   if (mYear != wxT(""))
      id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_YEAR, mYear.mb_str()));

   if (mComments != wxT(""))
      id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_COMMENT, mComments.mb_str()));

   if (mTrackNum >= 0) {
      wxString trackNumStr;
      trackNumStr.Printf(wxT("%d"), mTrackNum);
      id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_TRACK, trackNumStr.mb_str()));
   }

   if (mGenre >= 0) {
      if (mID3V2) {
         wxString genreStr = GetGenreNum(mGenre);
         id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_GENRE, genreStr.mb_str()));
      }
      else {
         wxString genreStr;
         genreStr.Printf(wxT("%d"), mGenre);
         id3_tag_attachframe(tp, MakeID3Frame(ID3_FRAME_GENRE, genreStr.mb_str()));
      }
   }

   if (mID3V2) {
      tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression

      // If this version of libid3tag supports it, use v2.3 ID3
      // tags instead of the newer, but less well supported, v2.4
      // that libid3tag uses by default.
      #ifdef ID3_TAG_OPTION_ID3V2_3
      tp->options |= ID3_TAG_OPTION_ID3V2_3;
      #endif

      *endOfFile = false;
   }
   else {
      tp->options |= ID3_TAG_OPTION_ID3V1;
      *endOfFile = true;
   }

   id3_length_t len;
   
   len = id3_tag_render(tp, 0);
   *buffer = (char *)malloc(len);
   len = id3_tag_render(tp, (id3_byte_t *)*buffer);

   id3_tag_delete(tp);

   return len;
#else //ifdef USE_LIBID3TAG 
   return 0;
#endif
}
コード例 #11
0
ファイル: compat.c プロジェクト: jpmac26/PGE-Project
/*
 * NAME:    compat->fixup()
 * DESCRIPTION: finish compatibility translations
 */
int id3_compat_fixup(struct id3_tag *tag)
{
    struct id3_frame *frame;
    unsigned int index;
    id3_ucs4_t timestamp[17] = { 0 };
    int result = 0;

    /* create a TDRC frame from obsolete TYER/TDAT/TIME frames */

    /*
     * TYE/TYER: YYYY
     * TDA/TDAT: DDMM
     * TIM/TIME: HHMM
     *
     * TDRC: yyyy-MM-ddTHH:mm
     */

    index = 0;
    while((frame = id3_tag_findframe(tag, ID3_FRAME_OBSOLETE, index++)))
    {
        char const *id;
        id3_byte_t const *data, *end;
        id3_length_t length;
        enum id3_field_textencoding encoding;
        id3_ucs4_t *string;

        id = id3_field_getframeid(&frame->fields[0]);
        assert(id);

        if(strcmp(id, "TYER") != 0 && strcmp(id, "YTYE") != 0 &&
           strcmp(id, "TDAT") != 0 && strcmp(id, "YTDA") != 0 &&
           strcmp(id, "TIME") != 0 && strcmp(id, "YTIM") != 0)
            continue;

        data = id3_field_getbinarydata(&frame->fields[1], &length);
        assert(data);

        if(length < 1)
            continue;

        end = data + length;

        encoding = (enum id3_field_textencoding)id3_parse_uint(&data, 1);
        string   = id3_parse_string(&data, end - data, encoding, 0);

        if(id3_ucs4_length(string) < 4)
        {
            free(string);
            continue;
        }

        if(strcmp(id, "TYER") == 0 ||
           strcmp(id, "YTYE") == 0)
        {
            timestamp[0] = string[0];
            timestamp[1] = string[1];
            timestamp[2] = string[2];
            timestamp[3] = string[3];
        }
        else if(strcmp(id, "TDAT") == 0 ||
                strcmp(id, "YTDA") == 0)
        {
            timestamp[4] = '-';
            timestamp[5] = string[2];
            timestamp[6] = string[3];
            timestamp[7] = '-';
            timestamp[8] = string[0];
            timestamp[9] = string[1];
        }
        else    /* TIME or YTIM */
        {
            timestamp[10] = 'T';
            timestamp[11] = string[0];
            timestamp[12] = string[1];
            timestamp[13] = ':';
            timestamp[14] = string[2];
            timestamp[15] = string[3];
        }

        free(string);
    }

    if(timestamp[0])
    {
        id3_ucs4_t *strings;

        frame = id3_frame_new("TDRC");
        if(frame == 0)
            goto fail;

        strings = timestamp;

        if(id3_field_settextencoding(&frame->fields[0],
                                     ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1 ||
           id3_field_setstrings(&frame->fields[1], 1, &strings) == -1 ||
           id3_tag_attachframe(tag, frame) == -1)
        {
            id3_frame_delete(frame);
            goto fail;
        }
    }

    if(0)
    {
fail:
        result = -1;
    }

    return result;
}