⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tag.c

📁 linux下mp3编解码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
      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;}/* * NAME:	tag->parse() * DESCRIPTION:	parse a complete ID3 tag */struct id3_tag *id3_tag_parse(id3_byte_t const *data, id3_length_t length){  id3_byte_t const *ptr;  unsigned int version;  int flags;  id3_length_t size;  assert(data);  switch (tagtype(data, length)) {  case TAGTYPE_ID3V1:    return (length < 128) ? 0 : v1_parse(data);  case TAGTYPE_ID3V2:    break;  case TAGTYPE_ID3V2_FOOTER:  case TAGTYPE_NONE:    return 0;  }  /* ID3v2.x */  ptr = data;  parse_header(&ptr, &version, &flags, &size);  switch (ID3_TAG_VERSION_MAJOR(version)) {  case 4:    if (flags & ID3_TAG_FLAG_FOOTERPRESENT)      size += 10;  case 2:  case 3:    return (length < 10 + size) ? 0 : v2_parse(data);  }  return 0;}staticvoid v1_renderstr(struct id3_tag const *tag, char const *frameid,		  id3_byte_t **buffer, id3_length_t length){  struct id3_frame *frame;  id3_ucs4_t const *string;  frame = id3_tag_findframe(tag, frameid, 0);  if (frame == 0)    string = id3_ucs4_empty;  else {    if (strcmp(frameid, ID3_FRAME_COMMENT) == 0)      string = id3_field_getfullstring(&frame->fields[3]);    else      string = id3_field_getstrings(&frame->fields[1], 0);  }  id3_render_paddedstring(buffer, string, length);}/* * NAME:	v1->render() * DESCRIPTION:	render an ID3v1 (or ID3v1.1) tag */staticid3_length_t v1_render(struct id3_tag const *tag, id3_byte_t *buffer){  id3_byte_t data[128], *ptr;  struct id3_frame *frame;  unsigned int i;  int genre = -1;  ptr = data;  id3_render_immediate(&ptr, "TAG", 3);  v1_renderstr(tag, ID3_FRAME_TITLE,   &ptr, 30);  v1_renderstr(tag, ID3_FRAME_ARTIST,  &ptr, 30);  v1_renderstr(tag, ID3_FRAME_ALBUM,   &ptr, 30);  v1_renderstr(tag, ID3_FRAME_YEAR,    &ptr,  4);  v1_renderstr(tag, ID3_FRAME_COMMENT, &ptr, 30);  /* ID3v1.1 track number */  frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0);  if (frame) {    unsigned int track;    track = id3_ucs4_getnumber(id3_field_getstrings(&frame->fields[1], 0));    if (track > 0 && track <= 0xff) {      ptr[-2] = 0;      ptr[-1] = track;    }  }  /* ID3v1 genre number */  frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0);  if (frame) {    unsigned int nstrings;    nstrings = id3_field_getnstrings(&frame->fields[1]);    for (i = 0; i < nstrings; ++i) {      genre = id3_genre_number(id3_field_getstrings(&frame->fields[1], i));      if (genre != -1)	break;    }    if (i == nstrings && nstrings > 0)      genre = ID3_GENRE_OTHER;  }  id3_render_int(&ptr, genre, 1);  /* make sure the tag is not empty */  if (genre == -1) {    for (i = 3; i < 127; ++i) {      if (data[i] != ' ')	break;    }    if (i == 127)      return 0;  }  if (buffer)    memcpy(buffer, data, 128);  return 128;}/* * NAME:	tag->render() * DESCRIPTION:	render a complete ID3 tag */id3_length_t id3_tag_render(struct id3_tag const *tag, id3_byte_t *buffer){  id3_length_t size = 0;  id3_byte_t **ptr,    *header_ptr = 0, *tagsize_ptr = 0, *crc_ptr = 0, *frames_ptr = 0;  int flags, extendedflags;  unsigned int i;  assert(tag);  if (tag->options & ID3_TAG_OPTION_ID3V1)    return v1_render(tag, buffer);  /* a tag must contain at least one (renderable) frame */  for (i = 0; i < tag->nframes; ++i) {    if (id3_frame_render(tag->frames[i], 0, 0) > 0)      break;  }  if (i == tag->nframes)    return 0;  ptr = buffer ? &buffer : 0;  /* get flags */  flags         = tag->flags         & ID3_TAG_FLAG_KNOWNFLAGS;  extendedflags = tag->extendedflags & ID3_TAG_EXTENDEDFLAG_KNOWNFLAGS;  extendedflags &= ~ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT;  if (tag->options & ID3_TAG_OPTION_CRC)    extendedflags |= ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT;  extendedflags &= ~ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS;  if (tag->restrictions)    extendedflags |= ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS;  flags &= ~ID3_TAG_FLAG_UNSYNCHRONISATION;  if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION)    flags |= ID3_TAG_FLAG_UNSYNCHRONISATION;  flags &= ~ID3_TAG_FLAG_EXTENDEDHEADER;  if (extendedflags)    flags |= ID3_TAG_FLAG_EXTENDEDHEADER;  flags &= ~ID3_TAG_FLAG_FOOTERPRESENT;  if (tag->options & ID3_TAG_OPTION_APPENDEDTAG)    flags |= ID3_TAG_FLAG_FOOTERPRESENT;  /* header */  if (ptr)    header_ptr = *ptr;  size += id3_render_immediate(ptr, "ID3", 3);  size += id3_render_int(ptr, ID3_TAG_VERSION, 2);  size += id3_render_int(ptr, flags, 1);  if (ptr)    tagsize_ptr = *ptr;  size += id3_render_syncsafe(ptr, 0, 4);  /* extended header */  if (flags & ID3_TAG_FLAG_EXTENDEDHEADER) {    id3_length_t ehsize = 0;    id3_byte_t *ehsize_ptr = 0;    if (ptr)      ehsize_ptr = *ptr;    ehsize += id3_render_syncsafe(ptr, 0, 4);    ehsize += id3_render_int(ptr, 1, 1);    ehsize += id3_render_int(ptr, extendedflags, 1);    if (extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE)      ehsize += id3_render_int(ptr, 0, 1);    if (extendedflags & ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT) {      ehsize += id3_render_int(ptr, 5, 1);      if (ptr)	crc_ptr = *ptr;      ehsize += id3_render_syncsafe(ptr, 0, 5);    }    if (extendedflags & ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS) {      ehsize += id3_render_int(ptr, 1, 1);      ehsize += id3_render_int(ptr, tag->restrictions, 1);    }    if (ehsize_ptr)      id3_render_syncsafe(&ehsize_ptr, ehsize, 4);    size += ehsize;  }  /* frames */  if (ptr)    frames_ptr = *ptr;  for (i = 0; i < tag->nframes; ++i)    size += id3_frame_render(tag->frames[i], ptr, tag->options);  /* padding */  if (!(flags & ID3_TAG_FLAG_FOOTERPRESENT)) {    if (size < tag->paddedsize)      size += id3_render_padding(ptr, 0, tag->paddedsize - size);    else if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION) {      if (ptr == 0)	size += 1;      else {	if ((*ptr)[-1] == 0xff)	  size += id3_render_padding(ptr, 0, 1);      }    }  }  /* patch tag size and CRC */  if (tagsize_ptr)    id3_render_syncsafe(&tagsize_ptr, size - 10, 4);  if (crc_ptr) {    id3_render_syncsafe(&crc_ptr,			id3_crc_compute(frames_ptr, *ptr - frames_ptr), 5);  }  /* footer */  if (flags & ID3_TAG_FLAG_FOOTERPRESENT) {    size += id3_render_immediate(ptr, "3DI", 3);    size += id3_render_binary(ptr, header_ptr + 3, 7);  }  return size;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -