Subversion Repositories Kolibri OS

Rev

Rev 1905 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1905 Rev 3960
Line 33... Line 33...
33
	convert_utf16bom,
33
	convert_utf16bom,
34
	convert_utf16bom,
34
	convert_utf16bom,
35
	convert_utf8
35
	convert_utf8
36
};
36
};
Line 37... Line 37...
37
 
37
 
Line 38... Line 38...
38
const unsigned int encoding_widths[4] = { 1, 2, 2, 1 };
38
static const unsigned int encoding_widths[4] = { 1, 2, 2, 1 };
Line 39... Line 39...
39
 
39
 
40
/* the code starts here... */
40
/* the code starts here... */
Line 184... Line 184...
184
	Preserve the zero string separator (I don't need strlen for the total size).
184
	Preserve the zero string separator (I don't need strlen for the total size).
Line 185... Line 185...
185
 
185
 
186
	ID3v2 standard says that there should be one text frame of specific type per tag, and subsequent tags overwrite old values.
186
	ID3v2 standard says that there should be one text frame of specific type per tag, and subsequent tags overwrite old values.
187
	So, I always replace the text that may be stored already (perhaps with a list of zero-separated strings, though).
187
	So, I always replace the text that may be stored already (perhaps with a list of zero-separated strings, though).
188
*/
188
*/
189
void store_id3_text(mpg123_string *sb, char *source, size_t source_size, const int noquiet, const int notranslate)
189
static void store_id3_text(mpg123_string *sb, char *source, size_t source_size, const int noquiet, const int notranslate)
190
{
190
{
191
	if(!source_size)
191
	if(!source_size)
192
	{
192
	{
193
		debug("Empty id3 data!");
193
		debug("Empty id3 data!");
Line 245... Line 245...
245
		source_size -= source_size % bwidth;
245
		source_size -= source_size % bwidth;
246
	}
246
	}
247
	text_converters[encoding](sb, source, source_size, noquiet);
247
	text_converters[encoding](sb, source, source_size, noquiet);
248
}
248
}
Line 249... Line 249...
249
 
249
 
250
char *next_text(char* prev, int encoding, size_t limit)
250
static char *next_text(char* prev, int encoding, size_t limit)
251
{
251
{
252
	char *text = prev;
252
	char *text = prev;
Line 253... Line 253...
253
	size_t width = encoding_widths[encoding];
253
	size_t width = encoding_widths[encoding];
Line 272... Line 272...
272
			else return NULL; /* No full character left? This text is broken */
272
			else return NULL; /* No full character left? This text is broken */
273
		}
273
		}
Line 274... Line 274...
274
 
274
 
275
		text += width;
275
		text += width;
276
	}
276
	}
Line 277... Line 277...
277
	if(text-prev >= limit) text = NULL;
277
	if((size_t)(text-prev) >= limit) text = NULL;
278
 
278
 
Line 279... Line 279...
279
	return text;
279
	return text;
Line 350... Line 350...
350
	init_mpg123_text(&localcom);
350
	init_mpg123_text(&localcom);
351
	/* Store the text, without translation to UTF-8, but for comments always a local copy in UTF-8.
351
	/* Store the text, without translation to UTF-8, but for comments always a local copy in UTF-8.
352
	   Reminder: No bailing out from here on without freeing the local comment data! */
352
	   Reminder: No bailing out from here on without freeing the local comment data! */
353
	store_id3_text(&xcom->description, descr-1, text-descr+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
353
	store_id3_text(&xcom->description, descr-1, text-descr+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
354
	if(tt == comment)
354
	if(tt == comment)
355
	store_id3_text(&localcom.description, descr-1, text-descr+1, NOQUIET, 1);
355
	store_id3_text(&localcom.description, descr-1, text-descr+1, NOQUIET, 0);
Line 356... Line 356...
356
 
356
 
357
	text[-1] = encoding; /* Byte abusal for encoding... */
357
	text[-1] = encoding; /* Byte abusal for encoding... */
358
	store_id3_text(&xcom->text, text-1, realsize+1-(text-realdata), NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
358
	store_id3_text(&xcom->text, text-1, realsize+1-(text-realdata), NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
Line 377... Line 377...
377
		         || !strcasecmp(localcom.description.p, "rva_user") )
377
		         || !strcasecmp(localcom.description.p, "rva_user") )
378
		rva_mode = 1;
378
		rva_mode = 1;
379
		if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
379
		if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
380
		{
380
		{
381
			/* Only translate the contents in here where we really need them. */
381
			/* Only translate the contents in here where we really need them. */
382
			store_id3_text(&localcom.text, text-1, realsize+1-(text-realdata), NOQUIET, 1);
382
			store_id3_text(&localcom.text, text-1, realsize+1-(text-realdata), NOQUIET, 0);
383
			if(localcom.text.fill > 0)
383
			if(localcom.text.fill > 0)
384
			{
384
			{
385
				fr->rva.gain[rva_mode] = (float) atof(localcom.text.p);
385
				fr->rva.gain[rva_mode] = (float) atof(localcom.text.p);
386
				if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
386
				if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
387
				fr->rva.peak[rva_mode] = 0;
387
				fr->rva.peak[rva_mode] = 0;
Line 391... Line 391...
391
	}
391
	}
392
	/* Make sure to free the local memory... */
392
	/* Make sure to free the local memory... */
393
	free_mpg123_text(&localcom);
393
	free_mpg123_text(&localcom);
394
}
394
}
Line 395... Line 395...
395
 
395
 
396
void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_level, char *id)
396
static void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_level, char *id)
397
{
397
{
398
	/* Text encoding          $xx */
398
	/* Text encoding          $xx */
399
	/* Description        ... $00 (00) */
399
	/* Description        ... $00 (00) */
400
	/* Text ... */
400
	/* Text ... */
Line 422... Line 422...
422
		if(NOQUIET) error("Unable to attach new extra text!");
422
		if(NOQUIET) error("Unable to attach new extra text!");
423
		return;
423
		return;
424
	}
424
	}
425
	memcpy(xex->id, id, 4);
425
	memcpy(xex->id, id, 4);
426
	init_mpg123_text(&localex); /* For our local copy. */
426
	init_mpg123_text(&localex); /* For our local copy. */
-
 
427
 
-
 
428
	/* The outside storage gets reencoded to UTF-8 only if not requested otherwise.
-
 
429
	   Remember that we really need the -1 here to hand in the encoding byte!*/
427
	store_id3_text(&xex->description, descr-1, text-descr+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
430
	store_id3_text(&xex->description, descr-1, text-descr+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
-
 
431
	/* Our local copy is always stored in UTF-8! */
428
	store_id3_text(&localex.description, descr-1, text-descr+1, NOQUIET, 1);
432
	store_id3_text(&localex.description, descr-1, text-descr+1, NOQUIET, 0);
-
 
433
	/* At first, only store the outside copy of the payload. We may not need the local copy. */
429
	text[-1] = encoding;
434
	text[-1] = encoding;
430
	store_id3_text(&xex->text, text-1, realsize-(text-realdata)+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
435
	store_id3_text(&xex->text, text-1, realsize-(text-realdata)+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
-
 
436
 
431
	/* Now check if we would like to interpret this extra info for RVA. */
437
	/* Now check if we would like to interpret this extra info for RVA. */
432
	if(localex.description.fill > 0)
438
	if(localex.description.fill > 0)
433
	{
439
	{
434
		int is_peak = 0;
440
		int is_peak = 0;
435
		int rva_mode = -1; /* mix / album */
441
		int rva_mode = -1; /* mix / album */
Line 452... Line 458...
452
			else if(strcasecmp(localex.description.p, "replaygain_album_gain")) rva_mode = -1;
458
			else if(strcasecmp(localex.description.p, "replaygain_album_gain")) rva_mode = -1;
453
		}
459
		}
454
		if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
460
		if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
455
		{
461
		{
456
			/* Now we need the translated copy of the data. */
462
			/* Now we need the translated copy of the data. */
457
			store_id3_text(&localex.text, text-1, realsize-(text-realdata)+1, NOQUIET, 1);
463
			store_id3_text(&localex.text, text-1, realsize-(text-realdata)+1, NOQUIET, 0);
458
			if(localex.text.fill > 0)
464
			if(localex.text.fill > 0)
459
			{
465
			{
460
				if(is_peak)
466
				if(is_peak)
461
				{
467
				{
462
					fr->rva.peak[rva_mode] = (float) atof(localex.text.p);
468
					fr->rva.peak[rva_mode] = (float) atof(localex.text.p);
Line 477... Line 483...
477
 
483
 
478
/* Make a ID3v2.3+ 4-byte ID from a ID3v2.2 3-byte ID
484
/* Make a ID3v2.3+ 4-byte ID from a ID3v2.2 3-byte ID
479
   Note that not all frames survived to 2.4; the mapping goes to 2.3 .
485
   Note that not all frames survived to 2.4; the mapping goes to 2.3 .
480
   A notable miss is the old RVA frame, which is very unspecific anyway.
486
   A notable miss is the old RVA frame, which is very unspecific anyway.
481
   This function returns -1 when a not known 3 char ID was encountered, 0 otherwise. */
487
   This function returns -1 when a not known 3 char ID was encountered, 0 otherwise. */
482
int promote_framename(mpg123_handle *fr, char *id) /* fr because of VERBOSE macros */
488
static int promote_framename(mpg123_handle *fr, char *id) /* fr because of VERBOSE macros */
483
{
489
{
484
	size_t i;
490
	size_t i;
485
	char *old[] =
491
	char *old[] =
486
	{
492
	{
Line 528... Line 534...
528
	unsigned char buf[6];
534
	unsigned char buf[6];
529
	unsigned long length=0;
535
	unsigned long length=0;
530
	unsigned char flags = 0;
536
	unsigned char flags = 0;
531
	int ret = 1;
537
	int ret = 1;
532
	int ret2;
538
	int ret2;
533
	unsigned char* tagdata = NULL;
-
 
534
	unsigned char major = first4bytes & 0xff;
539
	unsigned char major = first4bytes & 0xff;
535
	debug1("ID3v2: major tag version: %i", major);
540
	debug1("ID3v2: major tag version: %i", major);
536
	if(major == 0xff) return 0; /* Invalid... */
541
	if(major == 0xff) return 0; /* Invalid... */
537
	if((ret2 = fr->rd->read_frame_body(fr, buf, 6)) < 0) /* read more header information */
542
	if((ret2 = fr->rd->read_frame_body(fr, buf, 6)) < 0) /* read more header information */
538
	return ret2;
543
	return ret2;
Line 580... Line 585...
580
	}
585
	}
581
	debug1("ID3v2: tag data length %lu", length);
586
	debug1("ID3v2: tag data length %lu", length);
582
#ifndef NO_ID3V2
587
#ifndef NO_ID3V2
583
	if(VERBOSE2) fprintf(stderr,"Note: ID3v2.%i rev %i tag of %lu bytes\n", major, buf[0], length);
588
	if(VERBOSE2) fprintf(stderr,"Note: ID3v2.%i rev %i tag of %lu bytes\n", major, buf[0], length);
584
	/* skip if unknown version/scary flags, parse otherwise */
589
	/* skip if unknown version/scary flags, parse otherwise */
585
	if((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2))
590
	if(fr->p.flags & MPG123_SKIP_ID3V2 || ((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2)))
-
 
591
	{
-
 
592
		if(NOQUIET)
586
	{
593
		{
-
 
594
			if(fr->p.flags & MPG123_SKIP_ID3V2)
-
 
595
			{
-
 
596
				if(VERBOSE3) fprintf(stderr, "Note: Skipping ID3v2 tag per user request.\n");
-
 
597
			}
587
		/* going to skip because there are unknown flags set */
598
			else /* Must be because of scary Tag properties. */
588
		if(NOQUIET) warning2("ID3v2: Won't parse the ID3v2 tag with major version %u and flags 0x%xu - some extra code may be needed", major, flags);
599
			warning2("ID3v2: Won't parse the ID3v2 tag with major version %u and flags 0x%xu - some extra code may be needed", major, flags);
-
 
600
		}
589
#endif
601
#endif
590
		if((ret2 = fr->rd->skip_bytes(fr,length)) < 0) /* will not store data in backbuff! */
602
		if((ret2 = fr->rd->skip_bytes(fr,length)) < 0) /* will not store data in backbuff! */
591
		ret = ret2;
603
		ret = ret2;
592
#ifndef NO_ID3V2
604
#ifndef NO_ID3V2
593
	}
605
	}
594
	else
606
	else
595
	{
607
	{
-
 
608
		unsigned char* tagdata = NULL;
596
		fr->id3v2.version = major;
609
		fr->id3v2.version = major;
597
		/* try to interpret that beast */
610
		/* try to interpret that beast */
598
		if((tagdata = (unsigned char*) malloc(length+1)) != NULL)
611
		if((tagdata = (unsigned char*) malloc(length+1)) != NULL)
599
		{
612
		{
600
			debug("ID3v2: analysing frames...");
613
			debug("ID3v2: analysing frames...");
Line 639... Line 652...
639
						}
652
						}
640
						if(ret > 0)
653
						if(ret > 0)
641
						{
654
						{
642
							/* 4 or 3 bytes id */
655
							/* 4 or 3 bytes id */
643
							strncpy(id, (char*) tagdata+pos, head_part);
656
							strncpy(id, (char*) tagdata+pos, head_part);
-
 
657
							id[head_part] = 0; /* terminate for 3 or 4 bytes */
644
							pos += head_part;
658
							pos += head_part;
645
							tagpos += head_part;
659
							tagpos += head_part;
646
							/* size as 32 bits or 28 bits */
660
							/* size as 32 bits or 28 bits */
647
							if(fr->id3v2.version == 2) threebytes_to_long(tagdata+pos, framesize);
661
							if(fr->id3v2.version == 2) threebytes_to_long(tagdata+pos, framesize);
648
							else
662
							else
Line 788... Line 802...
788
					}
802
					}
789
				}
803
				}
790
			}
804
			}
791
			else
805
			else
792
			{
806
			{
-
 
807
				/* There are tags with zero length. Strictly not an error, then. */
793
				if(NOQUIET) error("ID3v2: Duh, not able to read ID3v2 tag data.");
808
				if(length > 0 && NOQUIET && ret2 != MPG123_NEED_MORE) error("ID3v2: Duh, not able to read ID3v2 tag data.");
794
				ret = ret2;
809
				ret = ret2;
795
			}
810
			}
796
tagparse_cleanup:
811
tagparse_cleanup:
797
			free(tagdata);
812
			free(tagdata);
798
		}
813
		}
Line 849... Line 864...
849
	-1: little endian
864
	-1: little endian
850
	 0: no BOM
865
	 0: no BOM
851
	 1: big endian
866
	 1: big endian
Line 852... Line 867...
852
 
867
 
853
	This modifies source and len to indicate the data _after_ the BOM(s).
868
	This modifies source and len to indicate the data _after_ the BOM(s).
854
	Note on nasty data: The last encountered BOM determines the endianess.
869
	Note on nasty data: The last encountered BOM determines the endianness.
855
	I have seen data with multiple BOMS, namely from "the" id3v2 program.
870
	I have seen data with multiple BOMS, namely from "the" id3v2 program.
856
	Not nice, but what should I do?
871
	Not nice, but what should I do?
857
*/
872
*/
858
static int check_bom(const unsigned char** source, size_t *len)
873
static int check_bom(const unsigned char** source, size_t *len)
Line 896... Line 911...
896
	int bom_endian;
911
	int bom_endian;
Line 897... Line 912...
897
 
912
 
Line 898... Line 913...
898
	debug1("convert_utf16 with length %lu", (unsigned long)l);
913
	debug1("convert_utf16 with length %lu", (unsigned long)l);
899
 
914
 
Line 900... Line 915...
900
	bom_endian = check_bom(&s, &l);
915
	bom_endian = check_bom(&s, &l);
901
	debug1("UTF16 endianess check: %i", bom_endian);
916
	debug1("UTF16 endianness check: %i", bom_endian);
902
 
917
 
903
	if(bom_endian == -1) /* little-endian */
918
	if(bom_endian == -1) /* little-endian */