예제 #1
0
파일: mplib.c 프로젝트: gitpan/MP3-Mplib
char*
mp_get_str_bitrate(const mpeg_header *h) 
{
	char *buf = (char *)xmallocd0(11, "mp_get_str_bitrate:buf");
	
	if(h->version == 1) /* MPEG 1 */
	{ 
		switch(h->layer) 
		{
			case 1:
				snprintf(buf, sizeof buf, "%d kBit/s", br_1_3[h->bitrate]);
				return buf;
			case 2:
				snprintf(buf, sizeof buf, "%d kBit/s", br_1_2[h->bitrate]);
				return buf;
			case 3:
				snprintf(buf, sizeof buf, "%d kBit/s", br_1_1[h->bitrate]);
				return buf;
			default:
				return "undefined";
		}
	} 
	else /* MPEG 2 */
	{ 
		switch(h->layer) 
		{
			case 1:
				snprintf(buf, sizeof buf, "%d kBit/s", br_2_3[h->bitrate]);
				return buf;
			case 2:
				snprintf(buf, sizeof buf, "%d kBit/s", br_2_2[h->bitrate]);
				return buf;
			case 3:
				snprintf(buf, sizeof buf, "%d kBit/s", br_2_1[h->bitrate]);
				return buf;
			default:
				return "undefined";
		}
	}
}
예제 #2
0
파일: mplib_s.c 프로젝트: berte/mediaplayer
static id3v2_tag*
id3v2_get_tag(int fd,int *cancle)
{
	if(1<=*cancle)
		return NULL;
	
	unsigned char *c;
	id3v2_header *header;
	id3v2_frame_list *frame_list;
	id3v2_frame *frame;
	id3v2_tag *tag = NULL;
	int i;
	
	if(lseek(fd, 0L, SEEK_SET) == -1) return NULL;
	
	c = (unsigned char*)xmallocd0(1024, "id3v2_get_tag:c");
	
	if(read(fd, c, 10) < 10) goto exit_on_error;

	c[10] = 0;
	
	if(strncmp(c, "ID3", 3)) goto exit_on_error;

	header = XMALLOCD0(id3v2_header, "id3v2_get_tag:header");
	header->version_minor = c[3];
	header->version_revision = c[4];
	header->flags = c[5];
	header->unsyncronization = (c[5] & 128) >> 7;

	//[email protected]
	if( 2!=header->version_minor )
	{
	     header->has_extended_header = (c[5] & 64) >> 6;
	     header->is_experimental = (c[5] & 32) >> 5;
	     header->has_footer = (c[5] & 16) >> 4;
	}
예제 #3
0
파일: mplib_s.c 프로젝트: gitpan/MP3-Mplib
static id3v2_tag*
id3v2_get_tag(int fd)
{
	unsigned char *c;
	id3v2_header *header;
	id3v2_frame_list *frame_list;
	id3v2_frame *frame;
	id3v2_tag *tag = NULL;
	int i;
	
	if(lseek(fd, 0L, SEEK_SET) == -1) return NULL;
	
	c = (unsigned char*)xmallocd0(1024, "id3v2_get_tag:c");
	
	if(read(fd, c, 10) < 10) goto exit_on_error;

	c[10] = 0;
	
	if(strncmp(c, "ID3", 3)) goto exit_on_error;

	header = XMALLOCD0(id3v2_header, "id3v2_get_tag:header");
	header->version_minor = c[3];
	header->version_revision = c[4];
	header->flags = c[5];
	header->unsyncronization = (c[5] & 128) >> 7;
	header->has_extended_header = (c[5] & 64) >> 6;
	header->is_experimental = (c[5] & 32) >> 5;
	header->has_footer = (c[5] & 16) >> 4;
	
	header->total_tag_size = id3_unsync32(c, 6) + 10;
	if(header->has_footer) header->total_tag_size += 10;
	
	tag = XMALLOCD0(id3v2_tag, "id3v2_get_tag:tag");
	
	/* check if version is supported */
	if(c[3] != 3 && c[3] != 4)
	{
		xfree(c);
		tag->header = header;
		tag->frame_list = NULL;
		return tag;
	}

	frame_list = XMALLOCD0(id3v2_frame_list, "id3v2_get_tag:frame_list");
	frame_list->start = frame_list;
	
	/* assigning header and frame list to tag */
	tag->header = header;
	tag->frame_list = frame_list;

	if(header->has_extended_header)
	{
		id3v2_extended_header *xt_header = XMALLOCD0(id3v2_extended_header,
						   "id3v2_get_tag:id3v2_extended_header");
		
		header->extended_header = xt_header;
		
		read(fd, c, 4); /* get length of extended header */
		xt_header->size = id3_unsync32(c, 0);
		
		read(fd, c, 1); /* get number of flags */
		xt_header->no_flag_bytes = (c[0] > 0) ? c[0] : 1;
		
		read(fd, c, xt_header->no_flag_bytes); /* get flag bytes */
		xt_header->is_update = (c[0] & 64) >> 6;
		xt_header->crc_data_present = (c[0] & 32) >> 5;
		xt_header->restrictions = (c[0] & 16) >> 4;
		
		/* Flag data */
		if(xt_header->is_update) read(fd, c, 1); /* Data length ind. is 0 -skip */
		if(xt_header->crc_data_present) {
			read(fd, c, 1); /* data length - shoud be 5 */
			if(*c != 5) goto exit_on_error; /*  else things might
			break badly */
			xt_header->crc_data_length = *c;
			xt_header->crc_data = xmallocd0(*c, "id3v2_get_tag:xt_header->crc_data");
			read(fd, xt_header->crc_data, *c);
		}
		if(xt_header->restrictions) {
			read(fd, c, 1); /* data length - shoud be 1 */
			if(*c != 1) goto exit_on_error;
			xt_header->restrictions_data_length = *c;
			xt_header->restrictions_data = xmallocd0(*c,
						       "id3v2_get_tag:xt_header->restrictions_data");
			read(fd, xt_header->restrictions_data, *c); 
		}
	}
예제 #4
0
파일: mplib_s.c 프로젝트: gitpan/MP3-Mplib
static int 
id3v2_add_tag(int fd, id3v2_tag *tag, id3v2_tag *old)
{
	unsigned char *btag, *btag_start;
	unsigned char flag = 0;
	int i, j;
	char *b_tag, *b_tag_start, *d;
	id3v2_frame_list *frame_list;
	id3v2_frame *frame;

	/* at first we are going to write the tags raw data into
	the btag byte array */
	btag = btag_start = xmallocd0(tag->header->total_tag_size,
			    "id3v2_add_tag:btag");
	strncpy(btag, "ID3", 3); btag += 3;
	*btag = (char)tag->header->version_minor; btag += 1;
	*btag = (char)tag->header->version_revision; btag += 1;
	flag |= ((tag->header->unsyncronization & 1) << 7);
	flag |= ((tag->header->has_extended_header & 1) << 6);
	flag |= ((tag->header->is_experimental & 1) << 5);
	flag |= ((tag->header->has_footer & 1) << 4);
	memcpy(btag, &flag, 1); btag += 1;
	
	if(old)
	{
		i = old->header->total_tag_size - 10;
		if(old->header->has_footer) i -= 10;
	}
	else
	{
		i = tag->header->total_tag_size - 10;
		if(tag->header->has_footer) i -= 10;
		/* add padding to total size we mean to store on disk */
		/* mplib does not use any kind of padding internaly */
		i += 1024;
	}
	
	d = id3_sync32(i); 
	btag[0] = d[0];
	btag[1] = d[1];
	btag[2] = d[2];
	btag[3] = d[3];
	xfree(d);
	btag += 4;
	
	if(tag->header->has_extended_header)
	{
		d = id3_sync32(tag->header->extended_header->size);
		btag[0] = d[0];
		btag[1] = d[1];
		btag[2] = d[2];
		btag[3] = d[3];
		xfree(d);
		btag += 4;
		
		*btag = (char)tag->header->extended_header->no_flag_bytes; btag += 1;
		flag = ((tag->header->extended_header->is_update & 1) << 6);
		flag |= ((tag->header->extended_header->crc_data_present & 1) << 5);
		flag |= ((tag->header->extended_header->restrictions & 1) << 4);
		memcpy(btag, &flag, 1); btag += 1;
		if(tag->header->extended_header->is_update) 
		{
			btag[0] = 0; btag += 1;
		}
		if(tag->header->extended_header->crc_data_present) 
		{
			int length = tag->header->extended_header->crc_data_length ? tag->header->extended_header->crc_data_length : 5;
			*btag = (char)length; btag += 1;
			memcpy(btag, tag->header->extended_header->crc_data, length); btag += 1;
		}
		if(tag->header->extended_header->restrictions) 
		{
			int length = tag->header->extended_header->restrictions_data_length ? tag->header->extended_header->restrictions_data_length : 5;
			*btag = (char)length; btag += 1;
			memcpy(btag, tag->header->extended_header->restrictions_data, length); btag += 1;
		}
	}
	
	frame_list = tag->frame_list;
	while(frame_list) {
		int j;
		frame = frame_list->data;
		
		strncpy(btag, frame->frame_id, 4); btag += 4;
		d = id3_sync32(frame->data_size);
		btag[0] = d[0];
		btag[1] = d[1];
		btag[2] = d[2];
		btag[3] = d[3];
		xfree(d);
		btag += 4;
		memcpy(btag, &frame->status_flag, 1); btag += 1;
		memcpy(btag, &frame->format_flag, 1); btag += 1;
		
		memcpy(btag, frame->data, frame->data_size); btag += frame->data_size;
		
		frame_list = frame_list->next;
	}
	
	/* XXX footer not supported yet */
	
	/* if an old tag was provided it is desired to overwrite it */
	/* else this is a brand new tag */
	if(old) {  
		FILE *file;
		void *ptr = xmallocd0(old->header->total_tag_size - tag->header->total_tag_size, "id3v2_add_tag:ptr");
		if(!(file = fdopen(fd, "r+b")))
		{
		    xfree(ptr);
		    goto exit_on_error;
		}
		
		fseek(file, 0, SEEK_SET);
		if(fwrite(btag_start, tag->header->total_tag_size, 1, file) < 1)
		{
		    xfree(ptr);
		    goto exit_on_error;
		}
		
		/* write padding till end of old tag */
		if(fwrite(ptr, old->header->total_tag_size - tag->header->total_tag_size, 1, file) < 1) {
		    xfree(ptr);
		    goto exit_on_error;
		}
		
		fflush(file);
		xfree(ptr);
				
	} else {
		FILE *file, *tmp;
		int read;
		void *ptr, *blank;
		unsigned char *c;

		ptr = xmallocd(4096, "id3v2_add_tag:ptr");
		blank = xmallocd0(1024, "id3v2_add_tag:blank");

		file = fdopen(fd, "r+b");
		tmp = tmpfile();
		if(!(file && tmp)) 
		{
		    fflush(file);
		    fclose(tmp);
		    xfree(ptr);
		    xfree(blank);
		    goto exit_on_error;
		}

		fseek(file, 0, SEEK_SET);
		fseek(tmp, 0, SEEK_SET);

		/* write tag in tmp file */
		fwrite(btag_start, tag->header->total_tag_size, 1, tmp);

		/* Write 1024b padding */
		fwrite(blank, 1024, 1, tmp);

		/* write rest of file */
		while(!feof(file))
		{
			read = fread(ptr, 1, 4096, file);
			if(fwrite(ptr, 1, read, tmp) != read && !feof(file))
			{
			    fflush(file);
			    fclose(tmp);
			    xfree(ptr);
			    xfree(blank);
			    goto exit_on_error;
			}
		}

		fflush(tmp);

		fseek(file, 0, SEEK_SET);
		fseek(tmp, 0, SEEK_SET);
		while(!feof(tmp))
		{
			read = fread(ptr, 1, 4096, tmp);
			if(fwrite(ptr, 1, read, file) != read && !feof(tmp))
			{
			    fflush(file);
			    fclose(tmp);
			    xfree(ptr);
			    xfree(blank);
			    goto exit_on_error;
			}
		}

		fflush(file);
		fclose(tmp);

		xfree(ptr);
		xfree(blank);
	    }

	xfree(btag_start);
	return 0;

 exit_on_error:
	xfree(btag_start);
	return MP_EERROR;
}
예제 #5
0
파일: mplib_s.c 프로젝트: gitpan/MP3-Mplib
static int 
id3v1_add_tag(int fd, id3v1_tag *tag) 
{
	int i, j;
	void *blank, *set;
	char *b_tag, *b_tag_start;
	
	blank = xmallocd0(30, "id3v1_add_tag:blank");
	set = xmallocd(30, "id3v1_add_tag:set");
	memset(set, 0xFF, 30);
	b_tag = b_tag_start = (char *)xmallocd0(128, "id3v1_add_tag:b_tag");
	
	strncpy(b_tag, "TAG", 3); b_tag += 3;
	
	if(tag->title) 
	{
		j = strlen(tag->title);
		strncpy(b_tag, tag->title, j); b_tag += j;
		i = 30 - j;
		if(i > 0) 
		{
			strncpy(b_tag, blank, i); b_tag += i;
		}
	}
	else 
	{
		strncpy(b_tag, blank, 30); b_tag += 30;
	}
	
	if(tag->artist) 
	{
		j = strlen(tag->artist);
		strncpy(b_tag, tag->artist, j); b_tag += j;
		i = 30 - j;
		if(i > 0) 
		{
			strncpy(b_tag, blank, i); b_tag += i;
		}
	} 
	else
	{
		strncpy(b_tag, blank, 30); b_tag += 30;
	}
	
	if(tag->album)
	{
		j = strlen(tag->album);
		strncpy(b_tag, tag->album, j); b_tag += j;
		i = 30 - j;
		if(i > 0)
		{
			strncpy(b_tag, blank, i); b_tag += i;
		}
	}
	else
	{
		strncpy(b_tag, blank, 30); b_tag += 30;
	}
	
	if(tag->year) 
	{
		j = strlen(tag->year);
		strncpy(b_tag, tag->year, j); b_tag += j;
		i = 4 - j;
		if(i > 0) 
		{
			strncpy(b_tag, blank, i); b_tag += i;
		}
	}
	else 
	{
		strncpy(b_tag, blank, 4); b_tag += 4;
	}
	
	if(tag->comment)
	{
		int hastrack = 0;
		j = strlen(tag->comment);
		if(tag->track > 0) hastrack = 1;
		if(hastrack && j > 28) 
		{
			strncpy(b_tag, tag->comment, 28); b_tag += 28;
		}
		else
		{
			strncpy(b_tag, tag->comment, j); b_tag += j;
			i = ((tag->track > 0) ? 28 : 30) - j;
		}
		if(i > 0)
		{
			strncpy(b_tag, blank, i); b_tag += i;
		}
	} 
	else 
	{ 
		strncpy(b_tag, blank, (tag->track > 0) ? 28 : 30); 
		b_tag += (tag->track > 0) ? 28 : 30;
	}
	
	if(tag->track > 0) 
	{
		strncpy(b_tag, blank, 1); b_tag += 1;
		strncpy(b_tag, &(tag->track), 1); b_tag += 1;
	}
	if(tag->genre != 0xFF) 
	{
		strncpy(b_tag, &(tag->genre), 1); b_tag += 1;
	}
	else 
	{
		strncpy(b_tag, set, 1); b_tag += 1;
	}
	
	j = 0;
	
	if(lseek(fd, 0L, SEEK_END) != -1)
	{
	    if(write(fd, b_tag - 128, 128) < 128) j = 1;
	}
	else j = 1;

	xfree(b_tag_start);
	xfree(blank);
	xfree(set);
	
	return j;
}
예제 #6
0
파일: mplib.c 프로젝트: gitpan/MP3-Mplib
 int
 mp_set_content(id3_tag* tag, const int field, id3_content* new_content)
 {
	 id3v1_tag *v1;
	 id3v2_tag *v2;
	 
	 
	 if(!tag) return MP_EERROR;
	 
	 if(tag->version == 2)
	 {
		 return mp_set_content_at_pos(tag, field, new_content, 0);
	 }
	 else if(tag->version == 1)
	 {
		unsigned char c;
		char *my_val;
		int len, j;
		 
		v1 = tag->tag;
		 
		 switch(field)
		 {

#define FLD(str1, str2, str3, str4) \
			case str1:\
				if(!new_content) v1->str2 = NULL;\
				else\
				{\
					id3_text_content *tc = str4(new_content);\
					if(strlen(tc->text) > str3 || tc->encoding != ISO_8859_1)\
					{\
						mp_convert_to_v2(tag);\
						mp_free_text_content(tc);\
						return mp_set_content(tag, field, new_content);\
					}\
					\
				 	v1->str2 = tc->text;\
					xfree(tc);\
				}\
				break;
			 
			 FLD(MP_ARTIST, artist, 30, mp_parse_artist);
			 FLD(MP_TITLE, title, 30, mp_parse_title);
			 FLD(MP_ALBUM, album, 30, mp_parse_album);
			 FLD(MP_YEAR, year, 4, mp_parse_year);
				 
			 case MP_COMMENT:
				 if(!new_content) v1->comment = NULL;
				 else
				 {
					 id3_comment_content *tc = mp_parse_comment(new_content);
					 if(strlen(tc->text) > 30 || tc->short_descr || tc->encoding != ISO_8859_1)
					 {
						 mp_convert_to_v2(tag);
						 mp_free_comment_content(tc);
						 return mp_set_content(tag, field, new_content);
					 }
					 v1->comment = xmallocd0(strlen(tc->text)+1,
						       "mp_set_content:v1->comment");
					 memcpy(v1->comment, tc->text, strlen(tc->text));
					 mp_free_comment_content(tc);
				 }
				 break;

			 case MP_TRACK:
				 if(!new_content) v1->track = 0;
				 else
				 {
					 id3_text_content *tc = mp_parse_track(new_content);
#ifdef HAVE_STRTOL
					 errno = 0;
					 j = strtol(tc->text, (char **)NULL, 10);
					 if(errno != ERANGE) v1->track = j;
					 else return MP_EERROR;
#else
					 v1->track = atoi(tc->text);
#endif
					 mp_free_text_content(tc);
				 }
				 break;

			 case MP_GENRE:
				 if(!new_content) v1->genre = 0xFF;
				 else
				 {
					 int b = 0, i;
					 id3_text_content *tc = mp_parse_genre(new_content);
					 /* i = strlen(tc->text); */
					 for(c = 0; c < GLL; c++) {
						 if(!strcmp(genre_list[c], tc->text))
						 {
							 v1->genre = c;
							 b = 1;
						 }
					 }
					 mp_free_text_content(tc);
					 if(!b)
					 {
						 mp_convert_to_v2(tag);
						 return mp_set_content(tag, field, new_content);
					 }
					 break;
				 }
			 }
	 }
	 else if(tag->version == -1) return MP_EVERSION;
	 else return MP_EFNF;
	 
	 return 0;
 }