ReactOS  0.4.15-dev-1389-g828d5fa
id3.c File Reference
#include "mpg123lib_intern.h"
#include "id3.h"
#include "debug.h"
Include dependency graph for id3.c:

Go to the source code of this file.

Macros

#define KNOWN_FRAMES   5
 
#define free_comment(mh)   free_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments))
 
#define free_text(mh)   free_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts))
 
#define free_extra(mh)   free_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras))
 
#define free_picture(mh)   free_id3_picture(&((mh)->id3v2.picture), &((mh)->id3v2.pictures))
 
#define add_comment(mh, l, d)   add_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments), NULL, l, d)
 
#define add_text(mh, id)   add_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts), id, NULL, NULL)
 
#define add_uslt(mh, l, d)   add_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts), id, l, d)
 
#define add_extra(mh, d)   add_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras), NULL, NULL, d)
 
#define add_picture(mh, t, d)   add_id3_picture(&((mh)->id3v2.picture), &((mh)->id3v2.pictures), t, d)
 
#define UNSYNC_FLAG   128
 
#define EXTHEAD_FLAG   64 /* ID3v2.3+ */
 
#define COMPRESS_FLAG   64 /* ID3v2.2 */
 
#define EXP_FLAG   32
 
#define FOOTER_FLAG   16
 
#define EXT_UPDATE_FLAG   64 /* ID3v2.4 only: extended header update flag */
 
#define UNKNOWN_FLAGS   15 /* 00001111*/
 
#define synchsafe_to_long(buf, res)
 
#define bytes_to_long(buf, res)
 
#define threebytes_to_long(buf, res)
 
#define BAD_FFLAGS   (unsigned long) 36784
 
#define PRES_TAG_FFLAG   16384
 
#define PRES_FILE_FFLAG   8192
 
#define READ_ONLY_FFLAG   4096
 
#define GROUP_FFLAG   64
 
#define COMPR_FFLAG   8
 
#define ENCR_FFLAG   4
 
#define UNSYNC_FFLAG   2
 
#define DATLEN_FFLAG   1
 
#define FULLPOINT(f, s)   ( (((f)&0x3ff)<<10) + ((s)&0x3ff) + 0x10000 )
 
#define UTF8LEN(x)   ( (x)<0x80 ? 1 : ((x)<0x800 ? 2 : ((x)<0x10000 ? 3 : 4)))
 

Typedefs

typedef void(* text_converter) (mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
 

Enumerations

enum  frame_types {
  unknown = -2, text = -1, comment, extra,
  rva2, uslt, picture
}
 

Functions

static void convert_latin1 (mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
 
static void convert_utf16bom (mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
 
static void convert_utf8 (mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
 
static void null_id3_links (mpg123_handle *fr)
 
void init_id3 (mpg123_handle *fr)
 
static void init_mpg123_text (mpg123_text *txt)
 
static void init_mpg123_picture (mpg123_picture *pic)
 
static void free_mpg123_text (mpg123_text *txt)
 
static void free_mpg123_picture (mpg123_picture *pic)
 
static void free_id3_text (mpg123_text **list, size_t *size)
 
static void free_id3_picture (mpg123_picture **list, size_t *size)
 
static mpg123_textadd_id3_text (mpg123_text **list, size_t *size, char id[4], char lang[3], mpg123_string *description)
 
static mpg123_pictureadd_id3_picture (mpg123_picture **list, size_t *size, char type, mpg123_string *description)
 
void exit_id3 (mpg123_handle *fr)
 
void reset_id3 (mpg123_handle *fr)
 
void id3_link (mpg123_handle *fr)
 
static void store_id3_text (mpg123_string *sb, unsigned char *source, size_t source_size, const int noquiet, const int notranslate)
 
void id3_to_utf8 (mpg123_string *sb, unsigned char encoding, const unsigned char *source, size_t source_size, int noquiet)
 
static unsigned charnext_text (unsigned char *prev, unsigned char encoding, size_t limit)
 
static const charenc_name (unsigned char enc)
 
static void process_text (mpg123_handle *fr, unsigned char *realdata, size_t realsize, char *id)
 
static void process_picture (mpg123_handle *fr, unsigned char *realdata, size_t realsize)
 
static void process_comment (mpg123_handle *fr, enum frame_types tt, unsigned char *realdata, size_t realsize, int rva_level, char *id)
 
static void process_extra (mpg123_handle *fr, unsigned char *realdata, size_t realsize, int rva_level, char *id)
 
static int promote_framename (mpg123_handle *fr, char *id)
 
int store_id3v2 (mpg123_handle *fr, unsigned long first4bytes, unsigned char buf[6], unsigned long length)
 
int parse_new_id3 (mpg123_handle *fr, unsigned long first4bytes)
 
static int check_bom (const unsigned char **source, size_t *len)
 

Variables

static const char frame_type [KNOWN_FRAMES][5] = { "COMM", "TXXX", "RVA2", "USLT", "APIC" }
 
static const text_converter text_converters [4]
 
static const unsigned int encoding_widths [4] = { 1, 2, 2, 1 }
 

Macro Definition Documentation

◆ add_comment

#define add_comment (   mh,
  l,
  d 
)    add_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments), NULL, l, d)

Definition at line 209 of file id3.c.

◆ add_extra

#define add_extra (   mh,
  d 
)    add_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras), NULL, NULL, d)

Definition at line 212 of file id3.c.

◆ add_picture

#define add_picture (   mh,
  t,
  d 
)    add_id3_picture(&((mh)->id3v2.picture), &((mh)->id3v2.pictures), t, d)

Definition at line 213 of file id3.c.

◆ add_text

#define add_text (   mh,
  id 
)    add_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts), id, NULL, NULL)

Definition at line 210 of file id3.c.

◆ add_uslt

#define add_uslt (   mh,
  l,
  d 
)    add_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts), id, l, d)

Definition at line 211 of file id3.c.

◆ BAD_FFLAGS

#define BAD_FFLAGS   (unsigned long) 36784

◆ bytes_to_long

#define bytes_to_long (   buf,
  res 
)
Value:
( \
major == 3 ? \
(res = (((unsigned long) (buf)[0]) << 24) \
| (((unsigned long) (buf)[1]) << 16) \
| (((unsigned long) (buf)[2]) << 8) \
| ((unsigned long) (buf)[3]) \
)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define long
Definition: qsort.c:33
GLuint res
Definition: glext.h:9613
#define synchsafe_to_long(buf, res)

◆ COMPR_FFLAG

#define COMPR_FFLAG   8

◆ COMPRESS_FLAG

#define COMPRESS_FLAG   64 /* ID3v2.2 */

◆ DATLEN_FFLAG

#define DATLEN_FFLAG   1

◆ ENCR_FFLAG

#define ENCR_FFLAG   4

◆ EXP_FLAG

#define EXP_FLAG   32

◆ EXT_UPDATE_FLAG

#define EXT_UPDATE_FLAG   64 /* ID3v2.4 only: extended header update flag */

◆ EXTHEAD_FLAG

#define EXTHEAD_FLAG   64 /* ID3v2.3+ */

◆ FOOTER_FLAG

#define FOOTER_FLAG   16

◆ free_comment

#define free_comment (   mh)    free_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments))

Definition at line 184 of file id3.c.

◆ free_extra

#define free_extra (   mh)    free_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras))

Definition at line 186 of file id3.c.

◆ free_picture

#define free_picture (   mh)    free_id3_picture(&((mh)->id3v2.picture), &((mh)->id3v2.pictures))

Definition at line 187 of file id3.c.

◆ free_text

#define free_text (   mh)    free_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts))

Definition at line 185 of file id3.c.

◆ FULLPOINT

#define FULLPOINT (   f,
  s 
)    ( (((f)&0x3ff)<<10) + ((s)&0x3ff) + 0x10000 )

Definition at line 1330 of file id3.c.

◆ GROUP_FFLAG

#define GROUP_FFLAG   64

◆ KNOWN_FRAMES

#define KNOWN_FRAMES   5

Definition at line 93 of file id3.c.

◆ PRES_FILE_FFLAG

#define PRES_FILE_FFLAG   8192

◆ PRES_TAG_FFLAG

#define PRES_TAG_FFLAG   16384

◆ READ_ONLY_FFLAG

#define READ_ONLY_FFLAG   4096

◆ synchsafe_to_long

#define synchsafe_to_long (   buf,
  res 
)
Value:
( \
(((buf)[0]|(buf)[1]|(buf)[2]|(buf)[3]) & 0x80) ? 0 : \
(res = (((unsigned long) (buf)[0]) << 21) \
| (((unsigned long) (buf)[1]) << 14) \
| (((unsigned long) (buf)[2]) << 7) \
| ((unsigned long) (buf)[3]) \
,1) \
)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define long
Definition: qsort.c:33
GLuint res
Definition: glext.h:9613

◆ threebytes_to_long

#define threebytes_to_long (   buf,
  res 
)
Value:
( \
res = (((unsigned long) (buf)[0]) << 16) \
| (((unsigned long) (buf)[1]) << 8) \
| ((unsigned long) (buf)[2]) \
)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define long
Definition: qsort.c:33

◆ UNKNOWN_FLAGS

#define UNKNOWN_FLAGS   15 /* 00001111*/

◆ UNSYNC_FFLAG

#define UNSYNC_FFLAG   2

◆ UNSYNC_FLAG

#define UNSYNC_FLAG   128

◆ UTF8LEN

#define UTF8LEN (   x)    ( (x)<0x80 ? 1 : ((x)<0x800 ? 2 : ((x)<0x10000 ? 3 : 4)))

Definition at line 1332 of file id3.c.

Typedef Documentation

◆ text_converter

typedef void(* text_converter) (mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)

Definition at line 99 of file id3.c.

Enumeration Type Documentation

◆ frame_types

Enumerator
unknown 
text 
comment 
extra 
rva2 
uslt 
picture 

Definition at line 95 of file id3.c.

95 { unknown = -2, text = -1, comment, extra, rva2, uslt, picture };
Definition: id3.c:95
Definition: id3.c:95
Definition: id3.c:95
Definition: id3.c:95
Definition: id3.c:95
Definition: id3.c:95
Definition: id3.c:95

Function Documentation

◆ add_id3_picture()

static mpg123_picture* add_id3_picture ( mpg123_picture **  list,
size_t size,
char  type,
mpg123_string description 
)
static

Definition at line 255 of file id3.c.

256 {
257  if(!description)
258  return NULL;
259 
260  // Return entry to overwrite, if appropriate.
261  for(size_t i=0; i<*size; ++i)
262  {
264  if( type == entry->type
265  && ( type == 1 || type == 2 ||
266  mpg123_same_string(&entry->description, description)
267  )
268  )
269  return entry;
270  }
271  // Append a new one.
273  if(x == NULL) return NULL; /* bad */
274 
275  *list = x;
276  *size += 1;
277  init_mpg123_picture(&((*list)[*size-1]));
278 
279  return &((*list)[*size-1]); /* Return pointer to the added picture. */
280 }
MPG123_EXPORT int mpg123_same_string(mpg123_string *a, mpg123_string *b)
Definition: stringbuf.c:241
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define safe_realloc
Definition: intsym.h:10
const char * description
Definition: directx.c:2497
static void init_mpg123_picture(mpg123_picture *pic)
Definition: id3.c:159
GLsizeiptr size
Definition: glext.h:5919
uint32_t entry
Definition: isohybrid.c:63
Definition: _list.h:228
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

◆ add_id3_text()

static mpg123_text* add_id3_text ( mpg123_text **  list,
size_t size,
char  id[4],
char  lang[3],
mpg123_string description 
)
static

Definition at line 214 of file id3.c.

216 {
217  mdebug( "add_id3_text id=%s lang=%s, desc=%s"
218  , id ? (char[5]) { id[0], id[1], id[2], id[3], 0 } : "(nil)"
219  , lang ? (char[4]) { lang[0], lang[1], lang[2], 0 } : "(nil)"
220  , description ? (description->fill ? description->p : "(empty)") : "(nil)" );
221  if(lang && !description)
222  return NULL; // no lone language intended
223  if(id || description)
224  {
225  // Look through list of existing texts and return an existing entry
226  // if it should be overwritten.
227  for(size_t i=0; i<*size; ++i)
228  {
229  mpg123_text *entry = *list+i;
230  if(description)
231  { // Overwrite entry with same description and same ID and language.
232  if( (!id || !memcmp(id, entry->id, 4))
233  && (!lang || !memcmp(entry->lang, lang, 3))
234  && mpg123_same_string(&(entry->description), description)
235  )
236  return entry;
237  } else if(id && !memcmp(id, entry->id, 4))
238  return entry; // Just ovewrite because of same ID.
239  mdebug("add_id3_text: entry %zu was no match", i);
240  }
241  }
242  mdebug("add_id3_text: append to list of %zu", *size);
243  // Nothing found, add new one.
244  mpg123_text *x = safe_realloc(*list, sizeof(mpg123_text)*(*size+1));
245  if(x == NULL) return NULL; /* bad */
246 
247  *list = x;
248  *size += 1;
249  init_mpg123_text(&((*list)[*size-1]));
250 
251  return &((*list)[*size-1]); /* Return pointer to the added text. */
252 }
MPG123_EXPORT int mpg123_same_string(mpg123_string *a, mpg123_string *b)
Definition: stringbuf.c:241
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define safe_realloc
Definition: intsym.h:10
const char * description
Definition: directx.c:2497
static const WCHAR lang[]
Definition: wbemdisp.c:287
GLsizeiptr size
Definition: glext.h:5919
#define mdebug(s,...)
Definition: debug.h:58
uint32_t entry
Definition: isohybrid.c:63
Definition: _list.h:228
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
static void init_mpg123_text(mpg123_text *txt)
Definition: id3.c:146

◆ check_bom()

static int check_bom ( const unsigned char **  source,
size_t len 
)
static

Definition at line 1304 of file id3.c.

1305 {
1306  int this_bom = 0;
1307  int further_bom = 0;
1308 
1309  if(*len < 2) return 0;
1310 
1311  if((*source)[0] == 0xff && (*source)[1] == 0xfe)
1312  this_bom = -1;
1313 
1314  if((*source)[0] == 0xfe && (*source)[1] == 0xff)
1315  this_bom = 1;
1316 
1317  /* Skip the detected BOM. */
1318  if(this_bom != 0)
1319  {
1320  *source += 2;
1321  *len -= 2;
1322  /* Check for following BOMs. The last one wins! */
1323  further_bom = check_bom(source, len);
1324  if(further_bom == 0) return this_bom; /* End of the recursion. */
1325  else return further_bom;
1326  }
1327  else return 0;
1328 }
GLenum GLsizei len
Definition: glext.h:6722
static int check_bom(const unsigned char **source, size_t *len)
Definition: id3.c:1304

Referenced by convert_utf16bom().

◆ convert_latin1()

static void convert_latin1 ( mpg123_string sb,
const unsigned char source,
size_t  len,
const int  noquiet 
)
static

Definition at line 1265 of file id3.c.

1266 {
1267  size_t length = l;
1268  size_t i;
1269  unsigned char *p;
1270  /* determine real length, a latin1 character can at most take 2 in UTF8 */
1271  for(i=0; i<l; ++i)
1272  if(s[i] >= 0x80) ++length;
1273 
1274  debug1("UTF-8 length: %lu", (unsigned long)length);
1275  /* one extra zero byte for paranoia */
1276  if(!mpg123_grow_string(sb, length+1))
1277  return;
1278 
1279  p = (unsigned char*) sb->p; /* Signedness doesn't matter but it shows I thought about the non-issue */
1280  for(i=0; i<l; ++i)
1281  if(s[i] < 0x80){ *p = s[i]; ++p; }
1282  else /* two-byte encoding */
1283  {
1284  *p = 0xc0 | (s[i]>>6);
1285  *(p+1) = 0x80 | (s[i] & 0x3f);
1286  p+=2;
1287  }
1288 
1289  sb->p[length] = 0;
1290  sb->fill = length+1;
1291 }
superblock * sb
Definition: btrfs.c:4220
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
r l[0]
Definition: byte_order.h:167
GLdouble s
Definition: gl.h:2039
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLfloat GLfloat p
Definition: glext.h:8902
#define debug1(s, a)
Definition: debug.h:61
MPG123_EXPORT int mpg123_grow_string(mpg123_string *sb, size_t news)
Definition: stringbuf.c:51

◆ convert_utf16bom()

static void convert_utf16bom ( mpg123_string sb,
const unsigned char source,
size_t  len,
const int  noquiet 
)
static

Definition at line 1333 of file id3.c.

1334 {
1335  size_t i;
1336  size_t n; /* number bytes that make up full pairs */
1337  unsigned char *p;
1338  size_t length = 0; /* the resulting UTF-8 length */
1339  /* Determine real length... extreme case can be more than utf-16 length. */
1340  size_t high = 0;
1341  size_t low = 1;
1342  int bom_endian;
1343 
1344  debug1("convert_utf16 with length %lu", (unsigned long)l);
1345 
1346  bom_endian = check_bom(&s, &l);
1347  debug1("UTF16 endianness check: %i", bom_endian);
1348 
1349  if(bom_endian == -1) /* little-endian */
1350  {
1351  high = 1; /* The second byte is the high byte. */
1352  low = 0; /* The first byte is the low byte. */
1353  }
1354 
1355  n = (l/2)*2; /* number bytes that make up full pairs */
1356 
1357  /* first: get length, check for errors -- stop at first one */
1358  for(i=0; i < n; i+=2)
1359  {
1360  unsigned long point = ((unsigned long) s[i+high]<<8) + s[i+low];
1361  if((point & 0xfc00) == 0xd800) /* lead surrogate */
1362  {
1363  unsigned short second = (i+3 < l) ? (s[i+2+high]<<8) + s[i+2+low] : 0;
1364  if((second & 0xfc00) == 0xdc00) /* good... */
1365  {
1366  point = FULLPOINT(point,second);
1367  length += UTF8LEN(point); /* possibly 4 bytes */
1368  i+=2; /* We overstepped one word. */
1369  }
1370  else /* if no valid pair, break here */
1371  {
1372  if(noquiet) error2("Invalid UTF16 surrogate pair at %li (0x%04lx).", (unsigned long)i, point);
1373  n = i; /* Forget the half pair, END! */
1374  break;
1375  }
1376  }
1377  else length += UTF8LEN(point); /* 1,2 or 3 bytes */
1378  }
1379 
1380  if(!mpg123_grow_string(sb, length+1))
1381  return;
1382 
1383  /* Now really convert, skip checks as these have been done just before. */
1384  p = (unsigned char*) sb->p; /* Signedness doesn't matter but it shows I thought about the non-issue */
1385  for(i=0; i < n; i+=2)
1386  {
1387  unsigned long codepoint = ((unsigned long) s[i+high]<<8) + s[i+low];
1388  if((codepoint & 0xfc00) == 0xd800) /* lead surrogate */
1389  {
1390  unsigned short second = (s[i+2+high]<<8) + s[i+2+low];
1391  codepoint = FULLPOINT(codepoint,second);
1392  i+=2; /* We overstepped one word. */
1393  }
1394  if(codepoint < 0x80) *p++ = (unsigned char) codepoint;
1395  else if(codepoint < 0x800)
1396  {
1397  *p++ = (unsigned char) (0xc0 | (codepoint>>6));
1398  *p++ = (unsigned char) (0x80 | (codepoint & 0x3f));
1399  }
1400  else if(codepoint < 0x10000)
1401  {
1402  *p++ = (unsigned char) (0xe0 | (codepoint>>12));
1403  *p++ = 0x80 | ((codepoint>>6) & 0x3f);
1404  *p++ = 0x80 | (codepoint & 0x3f);
1405  }
1406  else if (codepoint < 0x200000)
1407  {
1408  *p++ = (unsigned char) (0xf0 | codepoint>>18);
1409  *p++ = (unsigned char) (0x80 | ((codepoint>>12) & 0x3f));
1410  *p++ = (unsigned char) (0x80 | ((codepoint>>6) & 0x3f));
1411  *p++ = (unsigned char) (0x80 | (codepoint & 0x3f));
1412  } /* ignore bigger ones (that are not possible here anyway) */
1413  }
1414  sb->p[sb->size-1] = 0; /* paranoia... */
1415  sb->fill = sb->size;
1416 }
#define FULLPOINT(f, s)
Definition: id3.c:1330
superblock * sb
Definition: btrfs.c:4220
GLdouble n
Definition: glext.h:7729
POINTL point
Definition: edittest.c:50
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned char
Definition: typeof.h:29
#define error2(s, a, b)
Definition: debug.h:126
r l[0]
Definition: byte_order.h:167
GLdouble s
Definition: gl.h:2039
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define long
Definition: qsort.c:33
static int check_bom(const unsigned char **source, size_t *len)
Definition: id3.c:1304
#define UTF8LEN(x)
Definition: id3.c:1332
GLfloat GLfloat p
Definition: glext.h:8902
#define debug1(s, a)
Definition: debug.h:61
MPG123_EXPORT int mpg123_grow_string(mpg123_string *sb, size_t news)
Definition: stringbuf.c:51

◆ convert_utf8()

static void convert_utf8 ( mpg123_string sb,
const unsigned char source,
size_t  len,
const int  noquiet 
)
static

Definition at line 1420 of file id3.c.

1421 {
1422  if(mpg123_grow_string(sb, len+1))
1423  {
1424  memcpy(sb->p, source, len);
1425  sb->p[len] = 0;
1426  sb->fill = len+1;
1427  }
1428 }
superblock * sb
Definition: btrfs.c:4220
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
MPG123_EXPORT int mpg123_grow_string(mpg123_string *sb, size_t news)
Definition: stringbuf.c:51

◆ enc_name()

static const char* enc_name ( unsigned char  enc)
static

Definition at line 433 of file id3.c.

434 {
435  switch(enc)
436  {
437  case 0: return "Latin 1";
438  case 1: return "UTF-16 BOM";
439  case 2: return "UTF-16 BE";
440  case 3: return "UTF-8";
441  default: return "unknown!";
442  }
443 }

Referenced by process_comment(), process_extra(), and process_text().

◆ exit_id3()

void exit_id3 ( mpg123_handle fr)

Definition at line 284 of file id3.c.

285 {
286  free_picture(fr);
287  free_comment(fr);
288  free_extra(fr);
289  free_text(fr);
290 }
#define free_picture(mh)
Definition: id3.c:187
#define free_comment(mh)
Definition: id3.c:184
#define free_text(mh)
Definition: id3.c:185
#define free_extra(mh)
Definition: id3.c:186

Referenced by reset_id3().

◆ free_id3_picture()

static void free_id3_picture ( mpg123_picture **  list,
size_t size 
)
static

Definition at line 197 of file id3.c.

198 {
199  size_t i;
200  for(i=0; i<*size; ++i) free_mpg123_picture(&((*list)[i]));
201 
202  free(*list);
203  *list = NULL;
204  *size = 0;
205 }
#define free
Definition: debug_ros.c:5
GLsizeiptr size
Definition: glext.h:5919
Definition: _list.h:228
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
static void free_mpg123_picture(mpg123_picture *pic)
Definition: id3.c:175

◆ free_id3_text()

static void free_id3_text ( mpg123_text **  list,
size_t size 
)
static

Definition at line 188 of file id3.c.

189 {
190  size_t i;
191  for(i=0; i<*size; ++i) free_mpg123_text(&((*list)[i]));
192 
193  free(*list);
194  *list = NULL;
195  *size = 0;
196 }
static void free_mpg123_text(mpg123_text *txt)
Definition: id3.c:169
#define free
Definition: debug_ros.c:5
GLsizeiptr size
Definition: glext.h:5919
Definition: _list.h:228
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112

◆ free_mpg123_picture()

static void free_mpg123_picture ( mpg123_picture pic)
static

Definition at line 175 of file id3.c.

176 {
179  if (pic->data != NULL)
180  free(pic->data);
181 }
#define free
Definition: debug_ros.c:5
MPG123_EXPORT void mpg123_free_string(mpg123_string *sb)
Definition: stringbuf.c:43
mpg123_string mime_type
Definition: mpg123.h:1417
unsigned char * data
Definition: mpg123.h:1419
mpg123_string description
Definition: mpg123.h:1416
#define NULL
Definition: types.h:112

Referenced by free_id3_picture(), and process_picture().

◆ free_mpg123_text()

static void free_mpg123_text ( mpg123_text txt)
static

Definition at line 169 of file id3.c.

170 {
171  mpg123_free_string(&txt->text);
173 }
MPG123_EXPORT void mpg123_free_string(mpg123_string *sb)
Definition: stringbuf.c:43
mpg123_string text
Definition: mpg123.h:1380
mpg123_string description
Definition: mpg123.h:1379

Referenced by free_id3_text(), process_comment(), and process_extra().

◆ id3_link()

void id3_link ( mpg123_handle fr)

Definition at line 299 of file id3.c.

300 {
301  size_t i;
302  mpg123_id3v2 *v2 = &fr->id3v2;
303  debug("linking ID3v2");
304  null_id3_links(fr);
305  for(i=0; i<v2->texts; ++i)
306  {
307  mpg123_text *entry = &v2->text[i];
308  if (!strncmp("TIT2", entry->id, 4)) v2->title = &entry->text;
309  else if(!strncmp("TALB", entry->id, 4)) v2->album = &entry->text;
310  else if(!strncmp("TPE1", entry->id, 4)) v2->artist = &entry->text;
311  else if(!strncmp("TYER", entry->id, 4)) v2->year = &entry->text;
312  else if(!strncmp("TCON", entry->id, 4)) v2->genre = &entry->text;
313  }
314  for(i=0; i<v2->comments; ++i)
315  {
316  mpg123_text *entry = &v2->comment_list[i];
317  if(entry->description.fill == 0 || entry->description.p[0] == 0)
318  v2->comment = &entry->text;
319  }
320  /* When no generic comment found, use the last non-generic one. */
321  if(v2->comment == NULL && v2->comments > 0)
322  v2->comment = &v2->comment_list[v2->comments-1].text;
323 }
static void null_id3_links(mpg123_handle *fr)
Definition: id3.c:119
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
uint32_t entry
Definition: isohybrid.c:63
mpg123_id3v2 id3v2
Definition: frame.h:298
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
#define debug(msg)
Definition: key_call.c:71

◆ id3_to_utf8()

void id3_to_utf8 ( mpg123_string sb,
unsigned char  encoding,
const unsigned char source,
size_t  source_size,
int  noquiet 
)

Definition at line 374 of file id3.c.

375 {
376  unsigned int bwidth;
377  if(sb)
378  sb->fill = 0;
379  debug1("encoding: %u", encoding);
380  /* A note: ID3v2.3 uses UCS-2 non-variable 16bit encoding, v2.4 uses UTF16.
381  UTF-16 uses a reserved/private range in UCS-2 to add the magic, so we just always treat it as UTF. */
382  bwidth = encoding_widths[encoding];
383  /* Hack! I've seen a stray zero byte before BOM. Is that supposed to happen? */
384  if(encoding != mpg123_id3_utf16be) /* UTF16be _can_ beging with a null byte! */
385  while(source_size > bwidth && source[0] == 0)
386  {
387  --source_size;
388  ++source;
389  debug("skipped leading zero");
390  }
391  if(source_size % bwidth)
392  {
393  /* When we need two bytes for a character, it's strange to have an uneven bytestream length. */
394  if(noquiet) warning2("Weird tag size %d for encoding %u - I will probably trim too early or something but I think the MP3 is broken.", (int)source_size, encoding);
395  source_size -= source_size % bwidth;
396  }
397  text_converters[encoding](sb, source, source_size, noquiet);
398 }
superblock * sb
Definition: btrfs.c:4220
static const unsigned int encoding_widths[4]
Definition: id3.c:115
#define warning2(s, a, b)
Definition: debug.h:85
ed encoding
Definition: write.c:2825
static const text_converter text_converters[4]
Definition: id3.c:105
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
#define debug(msg)
Definition: key_call.c:71
#define debug1(s, a)
Definition: debug.h:61

Referenced by process_picture(), and store_id3_text().

◆ init_id3()

void init_id3 ( mpg123_handle fr)

Definition at line 129 of file id3.c.

130 {
131  fr->id3v2.version = 0; /* nothing there */
132  null_id3_links(fr);
133  fr->id3v2.comments = 0;
134  fr->id3v2.comment_list = NULL;
135  fr->id3v2.texts = 0;
136  fr->id3v2.text = NULL;
137  fr->id3v2.extras = 0;
138  fr->id3v2.extra = NULL;
139  fr->id3v2.pictures = 0;
140  fr->id3v2.picture = NULL;
141 }
mpg123_text * extra
Definition: mpg123.h:1442
mpg123_text * text
Definition: mpg123.h:1440
static void null_id3_links(mpg123_handle *fr)
Definition: id3.c:119
unsigned char version
Definition: mpg123.h:1429
size_t texts
Definition: mpg123.h:1441
mpg123_picture * picture
Definition: mpg123.h:1444
mpg123_id3v2 id3v2
Definition: frame.h:298
size_t extras
Definition: mpg123.h:1443
#define NULL
Definition: types.h:112
size_t pictures
Definition: mpg123.h:1446
size_t comments
Definition: mpg123.h:1439
mpg123_text * comment_list
Definition: mpg123.h:1438

Referenced by reset_id3().

◆ init_mpg123_picture()

static void init_mpg123_picture ( mpg123_picture pic)
static

Definition at line 159 of file id3.c.

160 {
163  pic->type = 0;
164  pic->size = 0;
165  pic->data = NULL;
166 }
size_t size
Definition: mpg123.h:1418
MPG123_EXPORT void mpg123_init_string(mpg123_string *sb)
Definition: stringbuf.c:35
mpg123_string mime_type
Definition: mpg123.h:1417
unsigned char * data
Definition: mpg123.h:1419
mpg123_string description
Definition: mpg123.h:1416
#define NULL
Definition: types.h:112

Referenced by add_id3_picture().

◆ init_mpg123_text()

static void init_mpg123_text ( mpg123_text txt)
static

Definition at line 146 of file id3.c.

147 {
148  mpg123_init_string(&txt->text);
150  txt->id[0] = 0;
151  txt->id[1] = 0;
152  txt->id[2] = 0;
153  txt->id[3] = 0;
154  txt->lang[0] = 0;
155  txt->lang[1] = 0;
156  txt->lang[2] = 0;
157 }
mpg123_string text
Definition: mpg123.h:1380
MPG123_EXPORT void mpg123_init_string(mpg123_string *sb)
Definition: stringbuf.c:35
char id[4]
Definition: mpg123.h:1378
char lang[3]
Definition: mpg123.h:1377
mpg123_string description
Definition: mpg123.h:1379

Referenced by add_id3_text(), process_comment(), and process_extra().

◆ next_text()

static unsigned char* next_text ( unsigned char prev,
unsigned char  encoding,
size_t  limit 
)
static

Definition at line 401 of file id3.c.

402 {
403  unsigned char *text = prev;
404  size_t width = encoding_widths[encoding];
405 
406  /* So I go lengths to find zero or double zero...
407  Remember bug 2834636: Only check for aligned NULLs! */
408  while(text-prev < (ssize_t)limit)
409  {
410  if(text[0] == 0)
411  {
412  if(width <= limit-(text-prev))
413  {
414  size_t i = 1;
415  for(; i<width; ++i) if(text[i] != 0) break;
416 
417  if(i == width) /* found a null wide enough! */
418  {
419  text += width;
420  break;
421  }
422  }
423  else return NULL; /* No full character left? This text is broken */
424  }
425 
426  text += width;
427  }
428  if((size_t)(text-prev) >= limit) text = NULL;
429 
430  return text;
431 }
GLint GLint GLsizei width
Definition: gl.h:1546
GLint limit
Definition: glext.h:10326
static const unsigned int encoding_widths[4]
Definition: id3.c:115
Definition: id3.c:95
int ssize_t
Definition: rosdhcp.h:48
ed encoding
Definition: write.c:2825
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112

Referenced by process_comment(), process_extra(), and process_picture().

◆ null_id3_links()

static void null_id3_links ( mpg123_handle fr)
static

Definition at line 119 of file id3.c.

120 {
121  fr->id3v2.title = NULL;
122  fr->id3v2.artist = NULL;
123  fr->id3v2.album = NULL;
124  fr->id3v2.year = NULL;
125  fr->id3v2.genre = NULL;
126  fr->id3v2.comment = NULL;
127 }
mpg123_string * comment
Definition: mpg123.h:1435
mpg123_string * year
Definition: mpg123.h:1433
mpg123_id3v2 id3v2
Definition: frame.h:298
#define NULL
Definition: types.h:112
mpg123_string * title
Definition: mpg123.h:1430
mpg123_string * album
Definition: mpg123.h:1432
mpg123_string * genre
Definition: mpg123.h:1434
mpg123_string * artist
Definition: mpg123.h:1431

Referenced by id3_link(), and init_id3().

◆ parse_new_id3()

int parse_new_id3 ( mpg123_handle fr,
unsigned long  first4bytes 
)

Definition at line 845 of file id3.c.

846 {
847  #define UNSYNC_FLAG 128
848  #define EXTHEAD_FLAG 64 /* ID3v2.3+ */
849  #define COMPRESS_FLAG 64 /* ID3v2.2 */
850  #define EXP_FLAG 32
851  #define FOOTER_FLAG 16
852  #define EXT_UPDATE_FLAG 64 /* ID3v2.4 only: extended header update flag */
853  #define UNKNOWN_FLAGS 15 /* 00001111*/
854  unsigned char buf[6];
855  unsigned long length=0;
856  unsigned char flags = 0;
857  int ret = 1;
858  off_t ret2;
859  int storetag = 0;
860  unsigned int footlen = 0;
861 #ifndef NO_ID3V2
862  int skiptag = 0;
863 #endif
864  unsigned char major = first4bytes & 0xff;
865  debug1("ID3v2: major tag version: %i", major);
866 
867  if(major == 0xff) return 0; /* Invalid... */
868  if((ret2 = fr->rd->read_frame_body(fr, buf, 6)) < 0) /* read more header information */
869  return ret2;
870 
871  if(buf[0] == 0xff) return 0; /* Revision, will never be 0xff. */
872 
873  if(fr->p.flags & MPG123_STORE_RAW_ID3)
874  storetag = 1;
875  /* second new byte are some nice flags, if these are invalid skip the whole thing */
876  flags = buf[1];
877  debug1("ID3v2: flags 0x%08x", flags);
878  /* use 4 bytes from buf to construct 28bit uint value and return 1; return 0 if bytes are not synchsafe */
879  #define synchsafe_to_long(buf,res) \
880  ( \
881  (((buf)[0]|(buf)[1]|(buf)[2]|(buf)[3]) & 0x80) ? 0 : \
882  (res = (((unsigned long) (buf)[0]) << 21) \
883  | (((unsigned long) (buf)[1]) << 14) \
884  | (((unsigned long) (buf)[2]) << 7) \
885  | ((unsigned long) (buf)[3]) \
886  ,1) \
887  )
888  /* id3v2.3 does not store synchsafe frame sizes, but synchsafe tag size - doh! */
889  /* Remember: bytes_to_long() can yield ULONG_MAX on 32 bit platforms! */
890  #define bytes_to_long(buf,res) \
891  ( \
892  major == 3 ? \
893  (res = (((unsigned long) (buf)[0]) << 24) \
894  | (((unsigned long) (buf)[1]) << 16) \
895  | (((unsigned long) (buf)[2]) << 8) \
896  | ((unsigned long) (buf)[3]) \
897  ,1) : synchsafe_to_long(buf,res) \
898  )
899  /* for id3v2.2 only */
900  #define threebytes_to_long(buf,res) \
901  ( \
902  res = (((unsigned long) (buf)[0]) << 16) \
903  | (((unsigned long) (buf)[1]) << 8) \
904  | ((unsigned long) (buf)[2]) \
905  )
906 
907  /* length-10 or length-20 (footer present); 4 synchsafe integers == 28 bit number */
908  /* we have already read 10 bytes, so left are length or length+10 bytes belonging to tag */
909  /* Note: This is an 28 bit value in 32 bit storage, plenty of space for */
910  /* length+x for reasonable x. */
912  {
913  if(NOQUIET) error4("Bad tag length (not synchsafe): 0x%02x%02x%02x%02x; You got a bad ID3 tag here.", buf[2],buf[3],buf[4],buf[5]);
914  return 0;
915  }
916  if(flags & FOOTER_FLAG)
917  footlen = 10;
918  debug1("ID3v2: tag data length %lu", length);
919 #ifndef NO_ID3V2
920  if(VERBOSE2) fprintf(stderr,"Note: ID3v2.%i rev %i tag of %lu bytes\n", major, buf[0], length);
921  /* skip if unknown version/scary flags, parse otherwise */
922  if(fr->p.flags & MPG123_SKIP_ID3V2)
923  {
924  if(VERBOSE3)
925  fprintf(stderr, "Note: Skipping ID3v2 tag per user request.\n");
926  skiptag = 1;
927  }
928  if((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2))
929  {
930  if(NOQUIET)
931  warning2( "ID3v2: Won't parse the ID3v2 tag with major version"
932  " %u and flags 0x%xu - some extra code may be needed"
933  , major, flags );
934  skiptag = 1;
935  }
936  // Standard says that compressed tags should be ignored as there isn't an agreed
937  // compressoion scheme.
938  if(major == 2 && flags & COMPRESS_FLAG)
939  {
940  if(NOQUIET)
941  warning("ID3v2: ignoring compressed ID3v2.2 tag");
942  skiptag = 1;
943  }
944  if(length < 10)
945  {
946  if(NOQUIET)
947  warning1("ID3v2: unrealistic small tag lengh %lu, skipping", length);
948  skiptag = 1;
949  }
950  if(!skiptag)
951  storetag = 1;
952 #endif
953  if(storetag)
954  {
955  /* Stores whole tag with footer and an additonal trailing zero. */
956  if((ret2 = store_id3v2(fr, first4bytes, buf, length+footlen)) <= 0)
957  return ret2;
958  }
959 #ifndef NO_ID3V2
960  if(skiptag)
961  {
962  if(VERBOSE3)
963  fprintf(stderr, "Note: skipped tag clearing possibly existing ID3v2 data");
964  reset_id3(fr); // Old data is invalid.
965 #endif
966  if(!storetag && (ret2=fr->rd->skip_bytes(fr,length+footlen))<0)
967  ret=ret2;
968 #ifndef NO_ID3V2
969  }
970  else
971  {
972  unsigned char* tagdata = fr->id3v2_raw+10;
973  /* try to interpret that beast */
974  debug("ID3v2: analysing frames...");
975  if(length > 0)
976  {
977  unsigned char extflags = 0;
978  unsigned long tagpos = 0;
979  /* bytes of frame title and of framesize value */
980  unsigned int head_part = major > 2 ? 4 : 3;
981  unsigned int flag_part = major > 2 ? 2 : 0;
982  /* The amount of bytes that are unconditionally read for each frame: */
983  /* ID, size, flags. */
984  unsigned int framebegin = head_part+head_part+flag_part;
985  debug1("ID3v2: have read at all %lu bytes for the tag now", (unsigned long)length+6);
986  if(flags & EXTHEAD_FLAG)
987  {
988  debug("ID3v2: extended header");
989  if(!bytes_to_long(tagdata, tagpos) || tagpos >= length)
990  {
991  ret = 0;
992  if(NOQUIET)
993  error4( "Bad (non-synchsafe/too large) tag offset from extended header:"
994  "0x%02x%02x%02x%02x"
995  , tagdata[0], tagdata[1], tagdata[2], tagdata[3] );
996  } else if(tagpos < 6)
997  {
998  ret = 0;
999  if(NOQUIET)
1000  merror("Extended header too small (%lu).", tagpos);
1001  }
1002  if(major == 3)
1003  {
1004  tagpos += 4; // The size itself is not included.
1005  if(tagpos >= length)
1006  {
1007  ret = 0;
1008  if(NOQUIET)
1009  error("Too much extended v2.3 header.");
1010  }
1011  } else if(ret) // v2.4 and at least got my 6 bytes of ext header
1012  {
1013  // Only v4 knows update frames, check for that.
1014  // Need to step back. Header is 4 bytes length, one byte flag size,
1015  // one byte flags. Flag size has to be 1!
1016  if(tagdata[4] == 1 && tagdata[5] & EXT_UPDATE_FLAG)
1017  {
1018  if(VERBOSE3)
1019  fprintf(stderr, "Note: ID3v2.4 update tag\n");
1020  extflags |= EXT_UPDATE_FLAG;
1021  }
1022  }
1023  }
1024  if(!(extflags & EXT_UPDATE_FLAG))
1025  {
1026  if(VERBOSE3)
1027  fprintf(stderr, "Note: non-update tag replacing existing ID3v2 data\n");
1028  reset_id3(fr);
1029  }
1030  if(ret > 0)
1031  {
1032  char id[5];
1033  unsigned long framesize;
1034  unsigned long fflags; /* need 16 bits, actually */
1035  id[4] = 0;
1036  fr->id3v2.version = major;
1037  /* Pos now advanced after ext head, now a frame has to follow. */
1038  /* Note: tagpos <= length, which is 28 bit integer, so both */
1039  /* far away from overflow for adding known small values. */
1040  /* I want to read at least one full header now. */
1041  while(length >= tagpos+framebegin)
1042  {
1043  int i = 0;
1044  unsigned long pos = tagpos;
1045  /* level 1,2,3 - 0 is info from lame/info tag! */
1046  /* rva tags with ascending significance, then general frames */
1047  enum frame_types tt = unknown;
1048  /* we may have entered the padding zone or any other strangeness: check if we have valid frame id characters */
1049  for(i=0; i< head_part; ++i)
1050  if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
1051  || ((tagdata[tagpos+i] > 64) && (tagdata[tagpos+i] < 91)) ) )
1052  {
1053  debug5("ID3v2: real tag data apparently ended after %lu bytes with 0x%02x%02x%02x%02x", tagpos, tagdata[tagpos], tagdata[tagpos+1], tagdata[tagpos+2], tagdata[tagpos+3]);
1054  /* This is no hard error... let's just hope that we got something meaningful already (ret==1 in that case). */
1055  goto tagparse_cleanup; /* Need to escape two loops here. */
1056  }
1057  if(ret > 0)
1058  {
1059  /* 4 or 3 bytes id */
1060  strncpy(id, (char*) tagdata+pos, head_part);
1061  id[head_part] = 0; /* terminate for 3 or 4 bytes */
1062  pos += head_part;
1063  tagpos += head_part;
1064  /* size as 32 bits or 28 bits */
1065  if(fr->id3v2.version == 2) threebytes_to_long(tagdata+pos, framesize);
1066  else
1067  if(!bytes_to_long(tagdata+pos, framesize))
1068  {
1069  /* Just assume that up to now there was some good data. */
1070  if(NOQUIET) error1("ID3v2: non-syncsafe size of %s frame, skipping the remainder of tag", id);
1071  break;
1072  }
1073  if(VERBOSE3) fprintf(stderr, "Note: ID3v2 %s frame of size %lu\n", id, framesize);
1074  tagpos += head_part;
1075  pos += head_part;
1076  if(fr->id3v2.version > 2)
1077  {
1078  fflags = (((unsigned long) tagdata[pos]) << 8) | ((unsigned long) tagdata[pos+1]);
1079  pos += 2;
1080  tagpos += 2;
1081  }
1082  else fflags = 0;
1083 
1084  if(length - tagpos < framesize)
1085  {
1086  if(NOQUIET) error("Whoa! ID3v2 frame claims to be larger than the whole rest of the tag.");
1087  break;
1088  }
1089  tagpos += framesize; /* the important advancement in whole tag */
1090  /* for sanity, after full parsing tagpos should be == pos */
1091  /* debug4("ID3v2: found %s frame, size %lu (as bytes: 0x%08lx), flags 0x%016lx", id, framesize, framesize, fflags); */
1092  /* %0abc0000 %0h00kmnp */
1093  #define BAD_FFLAGS (unsigned long) 36784
1094  #define PRES_TAG_FFLAG 16384
1095  #define PRES_FILE_FFLAG 8192
1096  #define READ_ONLY_FFLAG 4096
1097  #define GROUP_FFLAG 64
1098  #define COMPR_FFLAG 8
1099  #define ENCR_FFLAG 4
1100  #define UNSYNC_FFLAG 2
1101  #define DATLEN_FFLAG 1
1102  if(head_part < 4 && promote_framename(fr, id) != 0) continue;
1103 
1104  /* shall not or want not handle these */
1105  if(fflags & (BAD_FFLAGS | COMPR_FFLAG | ENCR_FFLAG))
1106  {
1107  if(NOQUIET) warning("ID3v2: skipping invalid/unsupported frame");
1108  continue;
1109  }
1110 
1111  for(i = 0; i < KNOWN_FRAMES; ++i)
1112  if(!strncmp(frame_type[i], id, 4)){ tt = i; break; }
1113 
1114  if(id[0] == 'T' && tt != extra) tt = text;
1115 
1116  if(tt != unknown)
1117  {
1118  int rva_mode = -1; /* mix / album */
1119  unsigned long realsize = framesize;
1120  unsigned char* realdata = tagdata+pos;
1121  unsigned char* unsyncbuffer = NULL;
1122  if(((flags & UNSYNC_FLAG) || (fflags & UNSYNC_FFLAG)) && framesize > 0)
1123  {
1124  unsigned long ipos = 0;
1125  unsigned long opos = 0;
1126  debug("Id3v2: going to de-unsync the frame data");
1127  /* de-unsync: FF00 -> FF; real FF00 is simply represented as FF0000 ... */
1128  /* damn, that means I have to delete bytes from withing the data block... thus need temporal storage */
1129  /* standard mandates that de-unsync should always be safe if flag is set */
1130  realdata = unsyncbuffer = malloc(framesize+1); /* will need <= bytes, plus a safety zero */
1131  if(realdata == NULL)
1132  {
1133  if(NOQUIET) error("ID3v2: unable to allocate working buffer for de-unsync");
1134  continue;
1135  }
1136  /* now going byte per byte through the data... */
1137  realdata[0] = tagdata[pos];
1138  opos = 1;
1139  for(ipos = pos+1; ipos < pos+framesize; ++ipos)
1140  {
1141  if(!((tagdata[ipos] == 0) && (tagdata[ipos-1] == 0xff)))
1142  {
1143  realdata[opos++] = tagdata[ipos];
1144  }
1145  }
1146  realsize = opos;
1147  /* Append a zero to keep strlen() safe. */
1148  realdata[realsize] = 0;
1149  debug2("ID3v2: de-unsync made %lu out of %lu bytes", realsize, framesize);
1150  }
1151  pos = 0; /* now at the beginning again... */
1152  /* Avoid reading over boundary, even if there is a */
1153  /* zero byte of padding for safety. */
1154  if(realsize) switch(tt)
1155  {
1156  case comment:
1157  case uslt:
1158  process_comment(fr, tt, realdata, realsize, comment+1, id);
1159  break;
1160  case extra: /* perhaps foobar2000's work */
1161  process_extra(fr, realdata, realsize, extra+1, id);
1162  break;
1163  case rva2: /* "the" RVA tag */
1164  {
1165  /* starts with null-terminated identification */
1166  if(VERBOSE3) fprintf(stderr, "Note: RVA2 identification \"%s\"\n", realdata);
1167  /* default: some individual value, mix mode */
1168  rva_mode = 0;
1169  if( !strncasecmp((char*)realdata, "album", 5)
1170  || !strncasecmp((char*)realdata, "audiophile", 10)
1171  || !strncasecmp((char*)realdata, "user", 4))
1172  rva_mode = 1;
1173  if(fr->rva.level[rva_mode] <= rva2+1)
1174  {
1175  pos += strlen((char*) realdata) + 1;
1176  debug2("got my pos: %zu - %zu", realsize, pos);
1177  // channel and two bytes for RVA value
1178  // pos possibly just past the safety zero, so one more than realsize
1179  if(pos > realsize || realsize-pos < 3)
1180  {
1181  if(NOQUIET)
1182  error("bad RVA2 tag (truncated?)");
1183  }
1184  else if(realdata[pos] == 1)
1185  {
1186  ++pos;
1187  /* only handle master channel */
1188  debug("ID3v2: it is for the master channel");
1189  /* two bytes adjustment, one byte for bits representing peak - n bytes, eh bits, for peak */
1190  /* 16 bit signed integer = dB * 512. Do not shift signed integers! Multiply instead.
1191  Also no implementation-defined casting. Reinterpret the pointer to signed char, then do
1192  proper casting. */
1193  fr->rva.gain[rva_mode] = (float) (
1194  ((short)((signed char*)realdata)[pos]) * 256 + (short)realdata[pos+1] ) / 512;
1195  pos += 2;
1196  if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
1197  /* heh, the peak value is represented by a number of bits - but in what manner? Skipping that part */
1198  fr->rva.peak[rva_mode] = 0;
1199  fr->rva.level[rva_mode] = rva2+1;
1200  }
1201  }
1202  }
1203  break;
1204  /* non-rva metainfo, simply store... */
1205  case text:
1206  process_text(fr, realdata, realsize, id);
1207  break;
1208  case picture:
1209  if (fr->p.flags & MPG123_PICTURE)
1210  process_picture(fr, realdata, realsize);
1211 
1212  break;
1213  default: if(NOQUIET) error1("ID3v2: unknown frame type %i", tt);
1214  }
1215  if(unsyncbuffer)
1216  free(unsyncbuffer);
1217  }
1218  #undef BAD_FFLAGS
1219  #undef PRES_TAG_FFLAG
1220  #undef PRES_FILE_FFLAG
1221  #undef READ_ONLY_FFLAG
1222  #undef GROUP_FFLAG
1223  #undef COMPR_FFLAG
1224  #undef ENCR_FFLAG
1225  #undef UNSYNC_FFLAG
1226  #undef DATLEN_FFLAG
1227  }
1228  else break;
1229  #undef KNOWN_FRAMES
1230  }
1231  } else
1232  {
1233  if(VERBOSE3)
1234  fprintf(stderr, "Note: faulty ID3v2 tag still clearing old data\n");
1235  reset_id3(fr);
1236  }
1237  } else // No new data, but still there was a tag that invalidates old data.
1238  {
1239  if(VERBOSE3)
1240  fprintf(stderr, "Note: empty ID3v2 clearing old data\n");
1241  reset_id3(fr);
1242  }
1243 tagparse_cleanup:
1244  /* Get rid of stored raw data that should not be kept. */
1245  if(!(fr->p.flags & MPG123_STORE_RAW_ID3))
1246  {
1247  free(fr->id3v2_raw);
1248  fr->id3v2_raw = NULL;
1249  fr->id3v2_size = 0;
1250  }
1251  }
1252 #endif /* NO_ID3V2 */
1253  return ret;
1254  #undef UNSYNC_FLAG
1255  #undef EXTHEAD_FLAG
1256  #undef COMPRESS_FLAG
1257  #undef EXP_FLAG
1258  #undef FOOTER_FLAG
1259  #undef EXT_UPDATE_FLAG
1260  #undef UNKOWN_FLAGS
1261 }
Definition: id3.c:95
struct mpg123_pars_struct p
Definition: frame.h:289
#define threebytes_to_long(buf, res)
#define error(str)
Definition: mkdosfs.c:1605
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define error1(s, a)
Definition: debug.h:125
size_t id3v2_size
Definition: frame.h:301
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define free
Definition: debug_ros.c:5
__kernel_off_t off_t
Definition: linux.h:201
unsigned char * id3v2_raw
Definition: frame.h:300
int store_id3v2(mpg123_handle *fr, unsigned long first4bytes, unsigned char buf[6], unsigned long length)
Definition: id3.c:794
#define bytes_to_long(buf, res)
#define debug2(s, a, b)
Definition: debug.h:62
#define FOOTER_FLAG
static void process_extra(mpg123_handle *fr, unsigned char *realdata, size_t realsize, int rva_level, char *id)
Definition: id3.c:655
Definition: id3.c:95
#define COMPR_FFLAG
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
Definition: id3.c:95
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define strncasecmp
Definition: fake.h:10
ULONG major
#define ENCR_FFLAG
#define VERBOSE2
static void process_text(mpg123_handle *fr, unsigned char *realdata, size_t realsize, char *id)
Definition: id3.c:445
static int promote_framename(mpg123_handle *fr, char *id)
Definition: id3.c:762
unsigned char version
Definition: mpg123.h:1429
#define warning2(s, a, b)
Definition: debug.h:85
#define error4(s, a, b, c, d)
Definition: debug.h:128
#define VERBOSE3
static void process_comment(mpg123_handle *fr, enum frame_types tt, unsigned char *realdata, size_t realsize, int rva_level, char *id)
Definition: id3.c:551
#define UNKNOWN_FLAGS
#define UNSYNC_FLAG
Definition: id3.c:95
Definition: id3.c:95
#define KNOWN_FRAMES
Definition: id3.c:93
#define BAD_FFLAGS
#define UNSYNC_FFLAG
void reset_id3(mpg123_handle *fr)
Definition: id3.c:292
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
struct mpg123_handle_struct::@3431 rva
Definition: id3.c:95
GLbitfield flags
Definition: glext.h:7161
#define NOQUIET
int ret
#define COMPRESS_FLAG
Definition: id3.c:95
mpg123_id3v2 id3v2
Definition: frame.h:298
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static float(__cdecl *square_half_float)(float x
#define EXTHEAD_FLAG
#define long
Definition: qsort.c:33
#define NULL
Definition: types.h:112
static void process_picture(mpg123_handle *fr, unsigned char *realdata, size_t realsize)
Definition: id3.c:465
static const char frame_type[KNOWN_FRAMES][5]
Definition: id3.c:94
FILE * stderr
#define debug(msg)
Definition: key_call.c:71
#define malloc
Definition: debug_ros.c:4
struct reader * rd
Definition: frame.h:287
#define debug5(s, a, b, c, d, e)
Definition: debug.h:65
#define debug1(s, a)
Definition: debug.h:61
#define EXT_UPDATE_FLAG
#define synchsafe_to_long(buf, res)
#define warning(s)
Definition: debug.h:83
frame_types
Definition: id3.c:95
#define merror(s,...)
Definition: debug.h:122
#define warning1(s, a)
Definition: debug.h:84

◆ process_comment()

static void process_comment ( mpg123_handle fr,
enum frame_types  tt,
unsigned char realdata,
size_t  realsize,
int  rva_level,
char id 
)
static

Definition at line 551 of file id3.c.

552 {
553  /* Text encoding $xx */
554  /* Language $xx xx xx */
555  /* Short description (encoded!) <text> $00 (00) */
556  /* Then the comment text (encoded) ... */
557  unsigned char encoding = realdata[0];
558  char lang[3]; // realdata + 1
559  unsigned char *descr = realdata+4;
560  unsigned char *text = NULL;
561  mpg123_text *xcom = NULL;
562  mpg123_text localcom; // UTF-8 variant for local processing, remember to clean up!
563  init_mpg123_text(&localcom);
564 
565  if(realsize < (size_t)(descr-realdata))
566  {
567  if(NOQUIET) error1("Invalid frame size of %"SIZE_P" (too small for anything).", (size_p)realsize);
568  return;
569  }
571  {
572  if(NOQUIET)
573  error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
574  return;
575  }
576  memcpy(lang, realdata+1, 3);
577  /* Now I can abuse a byte from lang for the encoding. */
578  descr[-1] = encoding;
579  /* Be careful with finding the end of description, I have to honor encoding here. */
580  text = next_text(descr, encoding, realsize-(descr-realdata));
581  if(text == NULL)
582  {
583  if(NOQUIET)
584  error("No comment text / valid description?");
585  return;
586  }
587  { // just vor variable scope
590  // Store the text, with desired encoding, but for comments always a local copy in UTF-8.
592  , NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT );
593  if(tt == comment)
594  store_id3_text( &localcom.description, descr-1, text-descr+1
595  , NOQUIET, 0 );
596  if(VERBOSE4)
597  fprintf( stderr, "Note: Storing comment from %s encoding\n"
598  , enc_name(realdata[0]) );
599  xcom = tt == uslt
600  ? add_uslt(fr, lang, &description)
601  : add_comment(fr, lang, &description);
602  if(xcom == NULL)
603  {
604  if(NOQUIET)
605  error("Unable to attach new comment!");
607  free_mpg123_text(&localcom);
608  return;
609  }
610  memcpy(xcom->id, id, 4);
611  memcpy(xcom->lang, lang, 3);
612  // That takes over the description allocation.
614  }
615 
616  text[-1] = encoding; /* Byte abusal for encoding... */
617  store_id3_text(&xcom->text, text-1, realsize+1-(text-realdata), NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
618  /* Remember: I will probably decode the above (again) for rva comment checking. So no messing around, please. */
619 
620  if(VERBOSE4) /* Do _not_ print the verbatim text: The encoding might be funny! */
621  {
622  fprintf(stderr, "Note: ID3 comm/uslt desc of length %"SIZE_P".\n", (size_p)xcom->description.fill);
623  fprintf(stderr, "Note: ID3 comm/uslt text of length %"SIZE_P".\n", (size_p)xcom->text.fill);
624  }
625  /* Look out for RVA info only when we really deal with a straight comment. */
626  if(tt == comment && localcom.description.fill > 0)
627  {
628  int rva_mode = -1; /* mix / album */
629  if( !strcasecmp(localcom.description.p, "rva")
630  || !strcasecmp(localcom.description.p, "rva_mix")
631  || !strcasecmp(localcom.description.p, "rva_track")
632  || !strcasecmp(localcom.description.p, "rva_radio") )
633  rva_mode = 0;
634  else if( !strcasecmp(localcom.description.p, "rva_album")
635  || !strcasecmp(localcom.description.p, "rva_audiophile")
636  || !strcasecmp(localcom.description.p, "rva_user") )
637  rva_mode = 1;
638  if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
639  {
640  /* Only translate the contents in here where we really need them. */
641  store_id3_text(&localcom.text, text-1, realsize+1-(text-realdata), NOQUIET, 0);
642  if(localcom.text.fill > 0)
643  {
644  fr->rva.gain[rva_mode] = (float) atof(localcom.text.p);
645  if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
646  fr->rva.peak[rva_mode] = 0;
647  fr->rva.level[rva_mode] = rva_level;
648  }
649  }
650  }
651  /* Make sure to free the local memory... */
652  free_mpg123_text(&localcom);
653 }
static void store_id3_text(mpg123_string *sb, unsigned char *source, size_t source_size, const int noquiet, const int notranslate)
Definition: id3.c:333
struct mpg123_pars_struct p
Definition: frame.h:289
#define error(str)
Definition: mkdosfs.c:1605
#define strcasecmp
Definition: fake.h:9
static void free_mpg123_text(mpg123_text *txt)
Definition: id3.c:169
#define error1(s, a)
Definition: debug.h:125
MPG123_EXPORT void mpg123_free_string(mpg123_string *sb)
Definition: stringbuf.c:43
MPG123_EXPORT int mpg123_move_string(mpg123_string *from, mpg123_string *to)
Definition: stringbuf.c:122
const char * description
Definition: directx.c:2497
_Check_return_ _CRTIMP double __cdecl atof(_In_z_ const char *str)
Definition: id3.c:95
static const char * enc_name(unsigned char enc)
Definition: id3.c:433
#define add_uslt(mh, l, d)
Definition: id3.c:211
mpg123_string text
Definition: mpg123.h:1380
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define VERBOSE4
MPG123_EXPORT void mpg123_init_string(mpg123_string *sb)
Definition: stringbuf.c:35
#define VERBOSE3
static unsigned char * next_text(unsigned char *prev, unsigned char encoding, size_t limit)
Definition: id3.c:401
static const WCHAR lang[]
Definition: wbemdisp.c:287
unsigned long size_p
Definition: compat.h:140
Definition: id3.c:95
const char * descr
Definition: boot.c:45
char id[4]
Definition: mpg123.h:1378
struct mpg123_handle_struct::@3431 rva
char lang[3]
Definition: mpg123.h:1377
#define NOQUIET
#define add_comment(mh, l, d)
Definition: id3.c:209
Definition: id3.c:95
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ed encoding
Definition: write.c:2825
static float(__cdecl *square_half_float)(float x
#define SIZE_P
Definition: compat.h:139
#define NULL
Definition: types.h:112
FILE * stderr
mpg123_string description
Definition: mpg123.h:1379
size_t fill
Definition: mpg123.h:1195
char * p
Definition: mpg123.h:1193
static void init_mpg123_text(mpg123_text *txt)
Definition: id3.c:146

Referenced by parse_new_id3().

◆ process_extra()

static void process_extra ( mpg123_handle fr,
unsigned char realdata,
size_t  realsize,
int  rva_level,
char id 
)
static

Definition at line 655 of file id3.c.

656 {
657  /* Text encoding $xx */
658  /* Description ... $00 (00) */
659  /* Text ... */
660  unsigned char encoding = realdata[0];
661  unsigned char *descr = realdata+1; /* remember, the encoding is descr[-1] */
662  unsigned char *text;
663  mpg123_text *xex;
664  mpg123_text localex;
665 
666  if((int)realsize < descr-realdata)
667  {
668  if(NOQUIET) error1("Invalid frame size of %lu (too small for anything).", (unsigned long)realsize);
669  return;
670  }
672  {
673  if(NOQUIET)
674  error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
675  return;
676  }
677  text = next_text(descr, encoding, realsize-(descr-realdata));
678  if(VERBOSE4) fprintf(stderr, "Note: Storing extra from %s encoding\n", enc_name(realdata[0]));
679  if(text == NULL)
680  {
681  if(NOQUIET) error("No extra frame text / valid description?");
682  return;
683  }
684  { // just vor variable scope
687  /* The outside storage gets reencoded to UTF-8 only if not requested otherwise.
688  Remember that we really need the -1 here to hand in the encoding byte!*/
690  , NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT );
691  xex = add_extra(fr, &description);
692  if(xex)
694  else
696  }
697  if(xex == NULL)
698  {
699  if(NOQUIET) error("Unable to attach new extra text!");
700  return;
701  }
702  memcpy(xex->id, id, 4);
703  init_mpg123_text(&localex); /* For our local copy. */
704 
705  /* Our local copy is always stored in UTF-8! */
706  store_id3_text(&localex.description, descr-1, text-descr+1, NOQUIET, 0);
707  /* At first, only store the outside copy of the payload. We may not need the local copy. */
708  text[-1] = encoding;
709  store_id3_text(&xex->text, text-1, realsize-(text-realdata)+1, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
710 
711  /* Now check if we would like to interpret this extra info for RVA. */
712  if(localex.description.fill > 0)
713  {
714  int is_peak = 0;
715  int rva_mode = -1; /* mix / album */
716 
717  if(!strncasecmp(localex.description.p, "replaygain_track_",17))
718  {
719  if(VERBOSE3) fprintf(stderr, "Note: RVA ReplayGain track gain/peak\n");
720 
721  rva_mode = 0;
722  if(!strcasecmp(localex.description.p, "replaygain_track_peak")) is_peak = 1;
723  else if(strcasecmp(localex.description.p, "replaygain_track_gain")) rva_mode = -1;
724  }
725  else
726  if(!strncasecmp(localex.description.p, "replaygain_album_",17))
727  {
728  if(VERBOSE3) fprintf(stderr, "Note: RVA ReplayGain album gain/peak\n");
729 
730  rva_mode = 1;
731  if(!strcasecmp(localex.description.p, "replaygain_album_peak")) is_peak = 1;
732  else if(strcasecmp(localex.description.p, "replaygain_album_gain")) rva_mode = -1;
733  }
734  if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
735  {
736  /* Now we need the translated copy of the data. */
737  store_id3_text(&localex.text, text-1, realsize-(text-realdata)+1, NOQUIET, 0);
738  if(localex.text.fill > 0)
739  {
740  if(is_peak)
741  {
742  fr->rva.peak[rva_mode] = (float) atof(localex.text.p);
743  if(VERBOSE3) fprintf(stderr, "Note: RVA peak %f\n", fr->rva.peak[rva_mode]);
744  }
745  else
746  {
747  fr->rva.gain[rva_mode] = (float) atof(localex.text.p);
748  if(VERBOSE3) fprintf(stderr, "Note: RVA gain %fdB\n", fr->rva.gain[rva_mode]);
749  }
750  fr->rva.level[rva_mode] = rva_level;
751  }
752  }
753  }
754 
755  free_mpg123_text(&localex);
756 }
static void store_id3_text(mpg123_string *sb, unsigned char *source, size_t source_size, const int noquiet, const int notranslate)
Definition: id3.c:333
struct mpg123_pars_struct p
Definition: frame.h:289
#define error(str)
Definition: mkdosfs.c:1605
#define strcasecmp
Definition: fake.h:9
static void free_mpg123_text(mpg123_text *txt)
Definition: id3.c:169
#define error1(s, a)
Definition: debug.h:125
MPG123_EXPORT void mpg123_free_string(mpg123_string *sb)
Definition: stringbuf.c:43
MPG123_EXPORT int mpg123_move_string(mpg123_string *from, mpg123_string *to)
Definition: stringbuf.c:122
const char * description
Definition: directx.c:2497
_Check_return_ _CRTIMP double __cdecl atof(_In_z_ const char *str)
static const char * enc_name(unsigned char enc)
Definition: id3.c:433
mpg123_string text
Definition: mpg123.h:1380
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define strncasecmp
Definition: fake.h:10
#define VERBOSE4
MPG123_EXPORT void mpg123_init_string(mpg123_string *sb)
Definition: stringbuf.c:35
#define VERBOSE3
static unsigned char * next_text(unsigned char *prev, unsigned char encoding, size_t limit)
Definition: id3.c:401
#define add_extra(mh, d)
Definition: id3.c:212
Definition: id3.c:95
const char * descr
Definition: boot.c:45
char id[4]
Definition: mpg123.h:1378
struct mpg123_handle_struct::@3431 rva
#define NOQUIET
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ed encoding
Definition: write.c:2825
static float(__cdecl *square_half_float)(float x
#define NULL
Definition: types.h:112
FILE * stderr
mpg123_string description
Definition: mpg123.h:1379
size_t fill
Definition: mpg123.h:1195
char * p
Definition: mpg123.h:1193
static void init_mpg123_text(mpg123_text *txt)
Definition: id3.c:146

Referenced by parse_new_id3().

◆ process_picture()

static void process_picture ( mpg123_handle fr,
unsigned char realdata,
size_t  realsize 
)
static

Definition at line 465 of file id3.c.

466 {
467  unsigned char encoding;
468  mpg123_picture *i = NULL;
469  unsigned char* workpoint = NULL;
471  unsigned char image_type = 0;
473  unsigned char *image_data = NULL;
474  if(realsize < 1)
475  {
476  debug("Empty id3 data!");
477  return;
478  }
479  encoding = realdata[0];
480  realdata++; realsize--;
482  {
483  if(NOQUIET)
484  error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
485  return;
486  }
487  if(VERBOSE4) fprintf(stderr, "Note: Storing picture from APIC frame.\n");
488 
489  /* get mime type (encoding is always latin-1) */
490  workpoint = next_text(realdata, 0, realsize);
491  if(!workpoint)
492  {
493  if(NOQUIET)
494  error("Unable to get mime type for picture; skipping picture.");
495  return;
496  }
497  id3_to_utf8(&mime, 0, realdata, workpoint - realdata, NOQUIET);
498  realsize -= workpoint - realdata;
499  realdata = workpoint;
500  /* get picture type */
501  image_type = realdata[0];
502  realdata++; realsize--;
503  /* get description (encoding is encoding) */
504  workpoint = next_text(realdata, encoding, realsize);
505  if(!workpoint)
506  {
507  if(NOQUIET)
508  error("Unable to get description for picture; skipping picture.");
510  return;
511  }
512  id3_to_utf8(&description, encoding, realdata, workpoint - realdata, NOQUIET);
513  realsize -= workpoint - realdata;
514  if(realsize)
515  image_data = (unsigned char*)malloc(realsize);
516  if(!realsize || !image_data) {
517  if(NOQUIET)
518  error("No picture data or malloc failure; skipping picture.");
521  return;
522  }
523  memcpy(image_data, workpoint, realsize);
524 
525  // All data ready now, append to/replace in list.
526  i = add_picture(fr, image_type, &description);
527  if(!i)
528  {
529  if(NOQUIET)
530  error("Unable to attach new picture!");
531  free(image_data);
534  return;
535  }
536 
537  // Either this is a fresh image, or one to be replaced.
538  // We hand over memory, so old storage needs to be freed.
540  i->type = image_type;
541  i->size = realsize;
542  i->data = image_data;
543  mpg123_move_string(&mime, &i->mime_type);
544  mpg123_move_string(&description, &i->description);
545  if(VERBOSE4)
546  fprintf(stderr, "Note: ID3v2 APIC picture frame of type: %d\n", i->type);
547 }
#define error(str)
Definition: mkdosfs.c:1605
const WCHAR * mime
Definition: mimefilter.c:512
#define error1(s, a)
Definition: debug.h:125
#define free
Definition: debug_ros.c:5
MPG123_EXPORT void mpg123_free_string(mpg123_string *sb)
Definition: stringbuf.c:43
MPG123_EXPORT int mpg123_move_string(mpg123_string *from, mpg123_string *to)
Definition: stringbuf.c:122
const char * description
Definition: directx.c:2497
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define VERBOSE4
MPG123_EXPORT void mpg123_init_string(mpg123_string *sb)
Definition: stringbuf.c:35
static unsigned char * next_text(unsigned char *prev, unsigned char encoding, size_t limit)
Definition: id3.c:401
void id3_to_utf8(mpg123_string *sb, unsigned char encoding, const unsigned char *source, size_t source_size, int noquiet)
Definition: id3.c:374
#define add_picture(mh, t, d)
Definition: id3.c:213
#define NOQUIET
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ed encoding
Definition: write.c:2825
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NULL
Definition: types.h:112
static void free_mpg123_picture(mpg123_picture *pic)
Definition: id3.c:175
FILE * stderr
#define debug(msg)
Definition: key_call.c:71
#define malloc
Definition: debug_ros.c:4

Referenced by parse_new_id3().

◆ process_text()

static void process_text ( mpg123_handle fr,
unsigned char realdata,
size_t  realsize,
char id 
)
static

Definition at line 445 of file id3.c.

446 {
447  /* Text encoding $xx */
448  /* The text (encoded) ... */
449  mpg123_text *t = add_text(fr, id);
450  if(VERBOSE4) fprintf(stderr, "Note: Storing text from %s encoding\n", enc_name(realdata[0]));
451  if(t == NULL)
452  {
453  if(NOQUIET) error("Unable to attach new text!");
454  return;
455  }
456  mdebug("process_text: (over)writing entry with ID %s", t->id
457  ? (char[5]) { t->id[0], t->id[1], t->id[2], t->id[3], 0 }
458  : "(nil)" );
459  memcpy(t->id, id, 4);
460  store_id3_text(&t->text, realdata, realsize, NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT);
461  if(VERBOSE4) // Do not print unsanitized text to terminals!
462  fprintf(stderr, "Note: ID3v2 %c%c%c%c text frame stored\n", id[0], id[1], id[2], id[3]);
463 }
static void store_id3_text(mpg123_string *sb, unsigned char *source, size_t source_size, const int noquiet, const int notranslate)
Definition: id3.c:333
struct mpg123_pars_struct p
Definition: frame.h:289
#define error(str)
Definition: mkdosfs.c:1605
GLdouble GLdouble t
Definition: gl.h:2047
static const char * enc_name(unsigned char enc)
Definition: id3.c:433
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define VERBOSE4
#define NOQUIET
#define mdebug(s,...)
Definition: debug.h:58
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define NULL
Definition: types.h:112
FILE * stderr
#define add_text(mh, id)
Definition: id3.c:210

Referenced by parse_new_id3().

◆ promote_framename()

static int promote_framename ( mpg123_handle fr,
char id 
)
static

Definition at line 762 of file id3.c.

763 {
764  size_t i;
765  char *old[] =
766  {
767  "COM", "TAL", "TBP", "TCM", "TCO", "TCR", "TDA", "TDY", "TEN", "TFT",
768  "TIM", "TKE", "TLA", "TLE", "TMT", "TOA", "TOF", "TOL", "TOR", "TOT",
769  "TP1", "TP2", "TP3", "TP4", "TPA", "TPB", "TRC", "TDA", "TRK", "TSI",
770  "TSS", "TT1", "TT2", "TT3", "TXT", "TXX", "TYE"
771  };
772  char *new[] =
773  {
774  "COMM", "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDAT", "TDLY", "TENC", "TFLT",
775  "TIME", "TKEY", "TLAN", "TLEN", "TMED", "TOPE", "TOFN", "TOLY", "TORY", "TOAL",
776  "TPE1", "TPE2", "TPE3", "TPE4", "TPOS", "TPUB", "TSRC", "TRDA", "TRCK", "TSIZ",
777  "TSSE", "TIT1", "TIT2", "TIT3", "TEXT", "TXXX", "TYER"
778  };
779  for(i=0; i<sizeof(old)/sizeof(char*); ++i)
780  {
781  if(!strncmp(id, old[i], 3))
782  {
783  memcpy(id, new[i], 4);
784  if(VERBOSE3) fprintf(stderr, "Translated ID3v2.2 frame %s to %s\n", old[i], new[i]);
785  return 0;
786  }
787  }
788  if(VERBOSE3) fprintf(stderr, "Ignoring untranslated ID3v2.2 frame %c%c%c\n", id[0], id[1], id[2]);
789  return -1;
790 }
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define VERBOSE3
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FILE * stderr

Referenced by parse_new_id3().

◆ reset_id3()

void reset_id3 ( mpg123_handle fr)

Definition at line 292 of file id3.c.

293 {
294  exit_id3(fr);
295  init_id3(fr);
296 }
void init_id3(mpg123_handle *fr)
Definition: id3.c:129
void exit_id3(mpg123_handle *fr)
Definition: id3.c:284

Referenced by parse_new_id3().

◆ store_id3_text()

static void store_id3_text ( mpg123_string sb,
unsigned char source,
size_t  source_size,
const int  noquiet,
const int  notranslate 
)
static

Definition at line 333 of file id3.c.

334 {
335  unsigned char encoding;
336  if(sb) // Always overwrite, even with nothing.
337  sb->fill = 0;
338  if(!source_size)
339  {
340  debug("Empty id3 data!");
341  return;
342  }
343 
344  /* We shall just copy the data. Client wants to decode itself. */
345  if(notranslate)
346  {
347  /* Future: Add a path for ID3 errors. */
348  if(!mpg123_grow_string(sb, source_size))
349  {
350  if(noquiet) error("Cannot resize target string, out of memory?");
351  return;
352  }
353  memcpy(sb->p, source, source_size);
354  sb->fill = source_size;
355  debug1("stored undecoded ID3 text of size %"SIZE_P, (size_p)source_size);
356  return;
357  }
358 
359  encoding = source[0];
361  {
362  if(noquiet)
363  error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
364  return;
365  }
366  id3_to_utf8(sb, encoding, source+1, source_size-1, noquiet);
367 
368  if(sb->fill) debug1("UTF-8 string (the first one): %s", sb->p);
369  else if(noquiet) error("unable to convert string to UTF-8 (out of memory, junk input?)!");
370 }
#define error(str)
Definition: mkdosfs.c:1605
superblock * sb
Definition: btrfs.c:4220
#define error1(s, a)
Definition: debug.h:125
void id3_to_utf8(mpg123_string *sb, unsigned char encoding, const unsigned char *source, size_t source_size, int noquiet)
Definition: id3.c:374
unsigned long size_p
Definition: compat.h:140
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ed encoding
Definition: write.c:2825
#define SIZE_P
Definition: compat.h:139
#define debug(msg)
Definition: key_call.c:71
#define debug1(s, a)
Definition: debug.h:61
MPG123_EXPORT int mpg123_grow_string(mpg123_string *sb, size_t news)
Definition: stringbuf.c:51

Referenced by process_comment(), process_extra(), and process_text().

◆ store_id3v2()

int store_id3v2 ( mpg123_handle fr,
unsigned long  first4bytes,
unsigned char  buf[6],
unsigned long  length 
)

Definition at line 794 of file id3.c.

796 {
797  int ret = 1;
798  off_t ret2;
799  unsigned long fullen = 10+length;
800  if(fr->id3v2_raw)
801  free(fr->id3v2_raw);
802  fr->id3v2_size = 0;
803  /* Allocate one byte more for a closing zero as safety catch for strlen(). */
804  fr->id3v2_raw = malloc(fullen+1);
805  if(!fr->id3v2_raw)
806  {
807  fr->err = MPG123_OUT_OF_MEM;
808  if(NOQUIET)
809  error1("ID3v2: Arrg! Unable to allocate %lu bytes"
810  " for ID3v2 data - trying to skip instead.", length+1);
811  if((ret2=fr->rd->skip_bytes(fr,length)) < 0)
812  ret = ret2;
813  else
814  ret = 0;
815  }
816  else
817  {
818  fr->id3v2_raw[0] = (first4bytes>>24) & 0xff;
819  fr->id3v2_raw[1] = (first4bytes>>16) & 0xff;
820  fr->id3v2_raw[2] = (first4bytes>>8) & 0xff;
821  fr->id3v2_raw[3] = first4bytes & 0xff;
822  memcpy(fr->id3v2_raw+4, buf, 6);
823  if((ret2=fr->rd->read_frame_body(fr, fr->id3v2_raw+10, length)) < 0)
824  {
825  ret=ret2;
826  free(fr->id3v2_raw);
827  fr->id3v2_raw = NULL;
828  }
829  else
830  { /* Closing with a zero for paranoia. */
831  fr->id3v2_raw[fullen] = 0;
832  fr->id3v2_size = fullen;
833  }
834  }
835  return ret;
836 }
#define error1(s, a)
Definition: debug.h:125
size_t id3v2_size
Definition: frame.h:301
#define free
Definition: debug_ros.c:5
__kernel_off_t off_t
Definition: linux.h:201
unsigned char * id3v2_raw
Definition: frame.h:300
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define NOQUIET
int ret
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define NULL
Definition: types.h:112
#define malloc
Definition: debug_ros.c:4
struct reader * rd
Definition: frame.h:287

Referenced by parse_new_id3().

Variable Documentation

◆ encoding_widths

const unsigned int encoding_widths[4] = { 1, 2, 2, 1 }
static

Definition at line 115 of file id3.c.

Referenced by id3_to_utf8(), and next_text().

◆ frame_type

const char frame_type[KNOWN_FRAMES][5] = { "COMM", "TXXX", "RVA2", "USLT", "APIC" }
static

Definition at line 94 of file id3.c.

Referenced by parse_new_id3().

◆ text_converters

const text_converter text_converters[4]
static
Initial value:
=
{
}
static void convert_latin1(mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
Definition: id3.c:1265
static void convert_utf8(mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
Definition: id3.c:1420
static void convert_utf16bom(mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
Definition: id3.c:1333

Definition at line 105 of file id3.c.

Referenced by id3_to_utf8().