libcdio  2.1.0
About: GNU libcdio is a library for CD-ROM and CD image access.
  Fossies Dox: libcdio-2.1.0.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

cdtext.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 2018 Thomas Schmitt
3  Copyright (C) 2004-2005, 2008, 2011, 2012, 2013 Rocky Bernstein <rocky@gnu.org>
4  toc reading routine adapted from cuetools
5  Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
6 
7  This program is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 # define __CDIO_CONFIG_H__ 1
24 #endif
25 
26 #include <cdio/cdtext.h>
27 #include <cdio/logging.h>
28 #include "cdtext_private.h"
29 #include <cdio/utf8.h>
30 
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif
38 
39 #define _CDTEXT_DBCC
40 #define MAX_CDTEXT_GENRE_CODE 28
41 #define MAX_CDTEXT_LANGUAGE_CODE 127
42 
44 {
45  "TITLE",
46  "PERFORMER",
47  "SONGWRITER",
48  "COMPOSER",
49  "MESSAGE",
50  "ARRANGER",
51  "ISRC",
52  "UPC_EAN",
53  "GENRE",
54  "DISC_ID",
55 };
56 
58 {
59  "Not Used",
60  "Not Defined",
61  "Adult Contemporary",
62  "Alternative Rock",
63  "Childrens Music",
64  "Classical",
65  "Contemporary Christian",
66  "Country",
67  "Dance",
68  "Easy Listening",
69  "Erotic",
70  "Folk",
71  "Gospel",
72  "Hip Hop",
73  "Jazz",
74  "Latin",
75  "Musical",
76  "New Age",
77  "Opera",
78  "Operetta",
79  "Pop Music",
80  "Rap",
81  "Reggae",
82  "Rock Music",
83  "Rhythm & Blues",
84  "Sound Effects",
85  "Spoken Word",
86  "World Music"
87 };
88 
90 {
91  "Unknown",
92  "Albanian",
93  "Breton",
94  "Catalan",
95  "Croatian",
96  "Welsh",
97  "Czech",
98  "Danish",
99  "German",
100  "English",
101  "Spanish",
102  "Esperanto",
103  "Estonian",
104  "Basque",
105  "Faroese",
106  "French",
107  "Frisian",
108  "Irish",
109  "Gaelic",
110  "Galician",
111  "Icelandic",
112  "Italian",
113  "Lappish",
114  "Latin",
115  "Latvian",
116  "Luxembourgian",
117  "Lithuanian",
118  "Hungarian",
119  "Maltese",
120  "Dutch",
121  "Norwegian",
122  "Occitan",
123  "Polish",
124  "Portuguese",
125  "Romanian",
126  "Romansh",
127  "Serbian",
128  "Slovak",
129  "Slovenian",
130  "Finnish",
131  "Swedish",
132  "Turkish",
133  "Flemish",
134  "Wallon",
135  "", "", "", "", "", "", "", "", "", "",
136  "", "", "", "", "", "", "", "", "", "",
137  "", "", "", "", "",
138  "Zulu",
139  "Vietnamese",
140  "Uzbek",
141  "Urdu",
142  "Ukrainian",
143  "Thai",
144  "Telugu",
145  "Tatar",
146  "Tamil",
147  "Tadzhik",
148  "Swahili",
149  "SrananTongo",
150  "Somali",
151  "Sinhalese",
152  "Shona",
153  "Serbo-croat",
154  "Ruthenian",
155  "Russian",
156  "Quechua",
157  "Pushtu",
158  "Punjabi",
159  "Persian",
160  "Papamiento",
161  "Oriya",
162  "Nepali",
163  "Ndebele",
164  "Marathi",
165  "Moldavian",
166  "Malaysian",
167  "Malagasay",
168  "Macedonian",
169  "Laotian",
170  "Korean",
171  "Khmer",
172  "Kazakh",
173  "Kannada",
174  "Japanese",
175  "Indonesian",
176  "Hindi",
177  "Hebrew",
178  "Hausa",
179  "Gurani",
180  "Gujurati",
181  "Greek",
182  "Georgian",
183  "Fulani",
184  "Dari",
185  "Churash",
186  "Chinese",
187  "Burmese",
188  "Bulgarian",
189  "Bengali",
190  "Bielorussian",
191  "Bambora",
192  "Azerbaijani",
193  "Assamese",
194  "Armenian",
195  "Arabic",
196  "Amharic"
197 };
198 
202 const char *
204 {
205  if (i >= MAX_CDTEXT_FIELDS)
206  return "INVALID";
207  else
208  return cdtext_field[i];
209 }
210 
214 const char *
216 {
217  if (i >= MAX_CDTEXT_GENRE_CODE)
218  return "INVALID";
219  else
220  return cdtext_genre[i];
221 }
222 
226 const char *
228 {
229  if (i <= CDTEXT_LANGUAGE_WALLON)
230  return cdtext_language[i];
232  return cdtext_language[i];
233  return "INVALID";
234 }
235 
241 void
243 {
244  cdtext_field_t k;
245  track_t j;
246  int i;
247 
248  if (!p_cdtext) return;
249  for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++) {
250  for (j=0; j<CDTEXT_NUM_TRACKS_MAX; j++) {
251  for (k=0; k < MAX_CDTEXT_FIELDS; k++) {
252  if (p_cdtext->block[i].track[j].field[k]) {
253  free(p_cdtext->block[i].track[j].field[k]);
254  p_cdtext->block[i].track[j].field[k] = NULL;
255  }
256  }
257  }
258  }
259  free(p_cdtext);
260 }
261 
268 char *
269 cdtext_get(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track)
270 {
271  const char *ret = cdtext_get_const(p_cdtext, field, track);
272  if (NULL == ret)
273  return NULL;
274  else
275  return strdup(ret);
276 }
277 
288 const char *
289 cdtext_get_const(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track)
290 {
291  if (CDTEXT_FIELD_INVALID == field
292  || NULL == p_cdtext
293  || CDIO_CD_MAX_TRACKS < track)
294  return NULL;
295 
296  return p_cdtext->block[p_cdtext->block_i].track[track].field[field];
297 }
298 
305 cdtext_get_genre(const cdtext_t *p_cdtext)
306 {
307  if (NULL == p_cdtext)
308  return CDTEXT_GENRE_UNUSED;
309  return p_cdtext->block[p_cdtext->block_i].genre_code;
310 }
311 
319 {
320  if (NULL == p_cdtext)
322  return p_cdtext->block[p_cdtext->block_i].language_code;
323 }
324 
330 track_t
332 {
333  if (NULL == p_cdtext)
334  return 0;
335  return p_cdtext->block[p_cdtext->block_i].first_track;
336 }
337 
343 track_t
345 {
346  if (NULL == p_cdtext)
347  return 0;
348  return p_cdtext->block[p_cdtext->block_i].last_track;
349 }
350 
370 {
371  static cdtext_lang_t avail[CDTEXT_NUM_BLOCKS_MAX];
372  int i, j=0;
373 
374  if (NULL == p_cdtext)
375  return NULL;
376 
377  for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++)
378  {
379  avail[i] = CDTEXT_LANGUAGE_UNKNOWN;
380  if (CDTEXT_LANGUAGE_UNKNOWN != p_cdtext->block[i].language_code &&
383  avail[j++] = p_cdtext->block[i].language_code;
384  }
385 
386  return avail;
387 }
388 
412 {
413  int i;
414 
415  if (NULL == p_cdtext)
416  return NULL;
417  for (i = 0; i < CDTEXT_NUM_BLOCKS_MAX; i++)
418  {
419  p_cdtext->languages[i] = p_cdtext->block[i].language_code;
420  }
421  return p_cdtext->languages;
422 }
423 
434 bool
436 {
437  if (NULL == p_cdtext)
438  return false;
439  p_cdtext->block_i = 0;
440  if (idx < 0 || idx > 7)
441  return false;
442  if (p_cdtext->block[idx].language_code == CDTEXT_LANGUAGE_BLOCK_UNUSED)
443  return false;
444  p_cdtext->block_i = idx;
445  return true;
446 }
447 
458 bool
460 {
461  if(NULL == p_cdtext)
462  return false;
463 
464  if (CDTEXT_LANGUAGE_BLOCK_UNUSED != language)
465  {
466  int i;
467  for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++) {
468  if (language == p_cdtext->block[i].language_code) {
469  p_cdtext->block_i = i;
470  return true;
471  }
472  }
473  }
474  p_cdtext->block_i = 0;
475  return false;
476 }
477 
485 cdtext_t
487 {
488  cdtext_field_t k;
489  track_t j;
490  int i;
491  cdtext_t *p_cdtext;
492 
493  p_cdtext = (cdtext_t *) malloc(sizeof(struct cdtext_s));
494 
495  for (i=0; i<CDTEXT_NUM_BLOCKS_MAX; i++) {
496  for (j=0; j<CDTEXT_NUM_TRACKS_MAX; j++) {
497  for (k=0; k < MAX_CDTEXT_FIELDS; k++) {
498  p_cdtext->block[i].track[j].field[k] = NULL;
499  }
500  }
501  p_cdtext->block[i].genre_code = CDTEXT_GENRE_UNUSED;
503  }
504 
505  p_cdtext->block_i = 0;
506 
507  return p_cdtext;
508 }
509 
520 cdtext_is_field (const char *key)
521 {
522  unsigned int i;
523 
524  for (i = 0; i < MAX_CDTEXT_FIELDS ; i++)
525  if (0 == strcmp(cdtext_field[i], key)) {
526  return i;
527  }
528  return CDTEXT_FIELD_INVALID;
529 }
530 
542 cdtext_str2lang (const char *lang)
543 {
544  unsigned int i;
545 
546  if(0 == lang[0]) /* The empty texts in cdtext_language[] are invalid */
548 
549  for (i = 0; i <= MAX_CDTEXT_LANGUAGE_CODE; i++)
550  if (0 == strcmp(cdtext_language[i], lang)) {
551  return i;
552  }
554 }
555 
567 void
568 cdtext_set(cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value,
569  track_t track, const char *charset)
570 {
571  if (NULL == value || key == CDTEXT_FIELD_INVALID
572  || CDIO_CD_MAX_TRACKS < track)
573  return;
574 
575  /* free old memory */
576  if (p_cdtext->block[p_cdtext->block_i].track[track].field[key])
577  free(p_cdtext->block[p_cdtext->block_i].track[track].field[key]);
578 
579  /* recode to UTF-8 */
580  if (NULL != charset) {
581  cdio_utf8_t *utf8_str = NULL;
582  cdio_charset_to_utf8((const char*) value, strlen((const char*)value),
583  &utf8_str, charset);
584  p_cdtext->block[p_cdtext->block_i].track[track].field[key] = (char *)utf8_str;
585  } else
586  p_cdtext->block[p_cdtext->block_i].track[track].field[key] = strdup((const char *)value);
587 }
588 
589 #define CDTEXT_COMPARE_CHAR(buf, c, db) ((buf)[0] == c && (! db || (buf)[1] == c) )
590 
600 int
601 cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data)
602 {
603  uint8_t *p_data;
604  int j;
605  uint8_t buffer[256];
606  uint8_t tab_buffer[256];
607  int i_buf = 0;
608  int i_block;
609  int i_seq = 0;
610  int i;
611  cdtext_blocksize_t blocksize;
612  char *charset = NULL;
613  uint8_t cur_track;
614 
615  memset( buffer, 0, sizeof(buffer) );
616  memset( tab_buffer, 0, sizeof(buffer) );
617 
618  p_data = wdata;
619  if (i_data < CDTEXT_LEN_PACK || 0 != i_data % CDTEXT_LEN_PACK) {
620  cdio_warn("CD-Text size is too small or not a multiple of pack size");
621  return -1;
622  }
623 
624 #if 0
625  for(i=0; i < i_data; i++)
626  printf("%0x%c", wdata[i], ((i+1) % 18 == 0 ? '\n' : ' '));
627 #endif
628 
629 
630  /* Iterate over blocks */
631  i_block = -1;
632  while(i_data > 0) {
633  cdtext_pack_t pack;
634  cdtext_read_pack(&pack, p_data);
635 
636  if (i_block != pack.block || i_seq != pack.seq) {
637  cdtext_pack_t tpack;
638  i_block = pack.block;
639  if (i_block >= CDTEXT_NUM_BLOCKS_MAX) {
640  cdio_warn("CD-TEXT: Invalid blocknumber %d.\n", i_block);
641  return -1;
642  }
643  p_cdtext->block_i = i_block;
644  i_seq = 0;
645  memset( &blocksize, 0, CDTEXT_LEN_BLOCKSIZE);
646 
647  /* first read block size information for sanity checks and encoding */
648  for(i=0; i <= i_data-CDTEXT_LEN_PACK; i+=CDTEXT_LEN_PACK) {
649 
650  if (p_data[i+0] == CDTEXT_PACK_BLOCKSIZE) {
651  cdtext_read_pack(&tpack, p_data+i);
652  switch (tpack.i_track) {
653  case 0:
654  blocksize.charcode = tpack.text[0];
655  blocksize.i_first_track = tpack.text[1];
656  blocksize.i_last_track = tpack.text[2];
657  blocksize.copyright = tpack.text[3];
658  blocksize.i_packs[0] = tpack.text[4];
659  blocksize.i_packs[1] = tpack.text[5];
660  blocksize.i_packs[2] = tpack.text[6];
661  blocksize.i_packs[3] = tpack.text[7];
662  blocksize.i_packs[4] = tpack.text[8];
663  blocksize.i_packs[5] = tpack.text[9];
664  blocksize.i_packs[6] = tpack.text[10];
665  blocksize.i_packs[7] = tpack.text[11];
666  break;
667  case 1:
668  blocksize.i_packs[8] = tpack.text[0];
669  blocksize.i_packs[9] = tpack.text[1];
670  blocksize.i_packs[10] = tpack.text[2];
671  blocksize.i_packs[11] = tpack.text[3];
672  blocksize.i_packs[12] = tpack.text[4];
673  blocksize.i_packs[13] = tpack.text[5];
674  blocksize.i_packs[14] = tpack.text[6];
675  blocksize.i_packs[15] = tpack.text[7];
676  blocksize.lastseq[0] = tpack.text[8];
677  blocksize.lastseq[1] = tpack.text[9];
678  blocksize.lastseq[2] = tpack.text[10];
679  blocksize.lastseq[3] = tpack.text[11];
680  break;
681  case 2:
682  blocksize.lastseq[4] = tpack.text[0];
683  blocksize.lastseq[5] = tpack.text[1];
684  blocksize.lastseq[6] = tpack.text[2];
685  blocksize.lastseq[7] = tpack.text[3];
686  blocksize.langcode[0] = tpack.text[4];
687  blocksize.langcode[1] = tpack.text[5];
688  blocksize.langcode[2] = tpack.text[6];
689  blocksize.langcode[3] = tpack.text[7];
690  blocksize.langcode[4] = tpack.text[8];
691  blocksize.langcode[5] = tpack.text[9];
692  blocksize.langcode[6] = tpack.text[10];
693  blocksize.langcode[7] = tpack.text[11];
694  break;
695  }
696  }
697  }
698 
699  if(blocksize.i_packs[15] == 3) {
700  cdtext_lang_t lcode;
701  /* if there were 3 BLOCKSIZE packs */
702  /* set copyright */
703  p_cdtext->block[i_block].copyright = (0x03 == (blocksize.copyright & 0x03));
704 
705  /* set Language */
706  lcode = blocksize.langcode[i_block];
707  if(lcode <= CDTEXT_LANGUAGE_WALLON ||
708  (lcode >= CDTEXT_LANGUAGE_ZULU && lcode <= CDTEXT_LANGUAGE_AMHARIC) )
709  p_cdtext->block[i_block].language_code = lcode;
710  else
711  p_cdtext->block[i_block].language_code = CDTEXT_LANGUAGE_INVALID;
712 
713  /* determine encoding */
714  switch (blocksize.charcode){
716  /* default */
717  charset = (char *) "ISO-8859-1";
718  break;
720  charset = (char *) "ASCII";
721  break;
723  charset = (char *) "SHIFT_JIS";
724  break;
725  }
726 
727  /* set track numbers */
728  p_cdtext->block[i_block].first_track = blocksize.i_first_track;
729  p_cdtext->block[i_block].last_track = blocksize.i_last_track;
730 
731  } else {
732  cdio_warn("CD-TEXT: No blocksize information available for block %d.\n", i_block);
733  return -1;
734  }
735 
736  }
737 
738  cdtext_read_pack(&pack, p_data);
739 
740 #ifndef _CDTEXT_DBCC
741  if ( pack.db_chars ) {
742  cdio_warn("CD-TEXT: Double-byte characters not supported");
743  return -1;
744  }
745 #endif
746 
747  cur_track = pack.i_track;
748 
749  /* read text packs first */
750  j = 0;
751  switch (pack.type) {
752  case CDTEXT_PACK_GENRE:
753  /* If pack.text starts with an unprintable character, it is likely to be the genre_code.
754  * While the specification requires the first GENRE pack to start with the 2 byte genre code,
755  * it is not specific about the following ones. */
756  if (pack.text[0] <= 31) {
757  j = 2;
758  if (CDTEXT_GENRE_UNUSED == p_cdtext->block[i_block].genre_code)
759  p_cdtext->block[i_block].genre_code = CDTEXT_GET_LEN16(pack.text);
760  }
761  case CDTEXT_PACK_TITLE:
766  case CDTEXT_PACK_MESSAGE:
767  case CDTEXT_PACK_DISCID:
768  case CDTEXT_PACK_UPC:
769  while (j < CDTEXT_LEN_TEXTDATA) {
770  /* not terminated */
771 
772  if ( i_buf+2 >= sizeof(buffer)) {
773  cdio_warn("CD-TEXT: Field too long.");
774  return -1;
775  }
776 
777  /* if the first character is a TAB, copy the buffer */
778  if ( i_buf == 0 && CDTEXT_COMPARE_CHAR(&pack.text[j], '\t', pack.db_chars)) {
779  memcpy(tab_buffer, buffer, sizeof(tab_buffer));
780  }
781 
782  if ( ! CDTEXT_COMPARE_CHAR(&pack.text[j], '\0', pack.db_chars)) {
783  buffer[i_buf++] = pack.text[j];
784  if(pack.db_chars)
785  buffer[i_buf++] = pack.text[j+1];
786  } else if(i_buf > 0) {
787  /* if end of string */
788 
789  /* check if the buffer contains only the Tab Indicator */
790  if ( CDTEXT_COMPARE_CHAR(buffer, '\t', pack.db_chars) ) {
791  if ( cur_track <= blocksize.i_first_track ) {
792  cdio_warn("CD-TEXT: Invalid use of Tab Indicator.");
793  return -1;
794  }
795  memcpy(buffer, tab_buffer, sizeof(buffer));
796  } else {
797  buffer[i_buf++] = 0;
798  if(pack.db_chars)
799  buffer[i_buf++] = 0;
800  }
801 
802  switch (pack.type) {
803  case CDTEXT_PACK_TITLE:
804  cdtext_set(p_cdtext, CDTEXT_FIELD_TITLE, buffer, cur_track, charset);
805  break;
807  cdtext_set(p_cdtext, CDTEXT_FIELD_PERFORMER, buffer, cur_track, charset);
808  break;
810  cdtext_set(p_cdtext, CDTEXT_FIELD_SONGWRITER, buffer, cur_track, charset);
811  break;
813  cdtext_set(p_cdtext, CDTEXT_FIELD_COMPOSER, buffer, cur_track, charset);
814  break;
816  cdtext_set(p_cdtext, CDTEXT_FIELD_ARRANGER, buffer, cur_track, charset);
817  break;
818  case CDTEXT_PACK_MESSAGE:
819  cdtext_set(p_cdtext, CDTEXT_FIELD_MESSAGE, buffer, cur_track, charset);
820  break;
821  case CDTEXT_PACK_DISCID:
822  if (cur_track == 0)
823  cdtext_set(p_cdtext, CDTEXT_FIELD_DISCID, buffer, cur_track, NULL);
824  break;
825  case CDTEXT_PACK_GENRE:
826  cdtext_set(p_cdtext, CDTEXT_FIELD_GENRE, buffer, cur_track, "ASCII");
827  break;
828  case CDTEXT_PACK_UPC:
829  if (cur_track == 0)
830  cdtext_set(p_cdtext, CDTEXT_FIELD_UPC_EAN, buffer, cur_track, "ASCII");
831  else
832  cdtext_set(p_cdtext, CDTEXT_FIELD_ISRC, buffer, cur_track, "ISO-8859-1");
833  break;
834  }
835  i_buf = 0;
836  ++cur_track;
837 
838  }
839  if (pack.db_chars)
840  j+=2;
841  else
842  j+=1;
843  }
844  break;
845  }
846  /* This would be the right place to parse TOC and TOC2 fields. */
847 
848  i_seq++;
850  p_data+=CDTEXT_LEN_PACK;
851  } /* end of while loop */
852 
853  p_cdtext->block_i = 0;
854  return 0;
855 }
856 
857 
864 int
865 cdtext_read_pack(cdtext_pack_t *p_pack, const uint8_t *p_data) {
866  p_pack->type = p_data[0];
867  p_pack->i_track = p_data[1];
868  p_pack->seq = p_data[2];
869  p_pack->char_pos = p_data[3] & 0x0F;
870  p_pack->block = (p_data[3] >> 4) & 0x07;
871  p_pack->db_chars = (p_data[3] >> 7) & 0x01;
872  p_pack->text[0] = p_data[4];
873  p_pack->text[1] = p_data[5];
874  p_pack->text[2] = p_data[6];
875  p_pack->text[3] = p_data[7];
876  p_pack->text[4] = p_data[8];
877  p_pack->text[5] = p_data[9];
878  p_pack->text[6] = p_data[10];
879  p_pack->text[7] = p_data[11];
880  p_pack->text[8] = p_data[12];
881  p_pack->text[9] = p_data[13];
882  p_pack->text[10] = p_data[14];
883  p_pack->text[11] = p_data[15];
884  p_pack->crc[0] = p_data[16];
885  p_pack->crc[1] = p_data[17];
886 
887  return 0;
888 }
cdtext_str2lang
cdtext_lang_t cdtext_str2lang(const char *lang)
Definition: cdtext.c:542
CDTEXT_PACK_ARRANGER
Definition: cdtext_private.h:50
cdtext_genre
const char * cdtext_genre[28]
Definition: cdtext.c:57
CDTEXT_FIELD_GENRE
Definition: cdtext.h:53
cdtext_block_s::language_code
cdtext_lang_t language_code
Definition: cdtext_private.h:117
cdtext_block_s::last_track
track_t last_track
Definition: cdtext_private.h:120
CDTEXT_PACK_UPC
Definition: cdtext_private.h:56
cdtext_block_s::copyright
bool copyright
Definition: cdtext_private.h:118
CDTEXT_FIELD_UPC_EAN
Definition: cdtext.h:52
CDTEXT_PACK_DISCID
Definition: cdtext_private.h:52
cdio_warn
void void void void cdio_warn(const char format[],...) GNUC_PRINTF(1
MAX_CDTEXT_LANGUAGE_CODE
#define MAX_CDTEXT_LANGUAGE_CODE
Definition: cdtext.c:41
cdtext_list_languages_v2
cdtext_lang_t * cdtext_list_languages_v2(cdtext_t *p_cdtext)
Definition: cdtext.c:411
CDTEXT_FIELD_INVALID
Definition: cdtext.h:55
cdtext_track_s::field
char * field[MAX_CDTEXT_FIELDS]
Definition: cdtext_private.h:110
CDTEXT_PACK_COMPOSER
Definition: cdtext_private.h:49
CDTEXT_LEN_BLOCKSIZE
Definition: cdtext_private.h:35
CDTEXT_FIELD_COMPOSER
Definition: cdtext.h:48
CDTEXT_NUM_BLOCKS_MAX
Definition: cdtext_private.h:36
cdtext_s::block
struct cdtext_block_s block[CDTEXT_NUM_BLOCKS_MAX]
Definition: cdtext_private.h:128
cdtext_genre_t
cdtext_genre_t
Enumeration of possible genre codes.
Definition: cdtext.h:62
cdtext_pack_s::db_chars
uint8_t db_chars
Definition: cdtext_private.h:83
cdtext_pack_s::crc
uint8_t crc[2]
Definition: cdtext_private.h:85
MAX_CDTEXT_FIELDS
#define MAX_CDTEXT_FIELDS
Definition: cdtext.h:38
cdtext_pack_s::type
uint8_t type
Definition: cdtext_private.h:78
track_t
uint8_t track_t
Definition: types.h:276
i_data
static int i_data
Definition: cdda-player.c:106
CDTEXT_PACK_MESSAGE
Definition: cdtext_private.h:51
cdtext_is_field
cdtext_field_t cdtext_is_field(const char *key)
Definition: cdtext.c:520
cdtext_pack_s::text
uint8_t text[CDTEXT_LEN_TEXTDATA]
Definition: cdtext_private.h:84
CDTEXT_FIELD_TITLE
Definition: cdtext.h:45
CDTEXT_CHARCODE_ASCII
Definition: cdtext_private.h:64
cdtext_get_last_track
track_t cdtext_get_last_track(const cdtext_t *p_cdtext)
Definition: cdtext.c:344
cdtext_blocksize_s::lastseq
uint8_t lastseq[8]
Definition: cdtext_private.h:101
cdtext_block_s::genre_code
cdtext_genre_t genre_code
Definition: cdtext_private.h:116
CDTEXT_PACK_TITLE
Definition: cdtext_private.h:46
CDTEXT_PACK_GENRE
Definition: cdtext_private.h:53
CDTEXT_LANGUAGE_BLOCK_UNUSED
Definition: cdtext.h:209
CDTEXT_CHARCODE_ISO_8859_1
Definition: cdtext_private.h:63
cdtext_get_first_track
track_t cdtext_get_first_track(const cdtext_t *p_cdtext)
Definition: cdtext.c:331
cdtext_data_init
int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data)
Definition: cdtext.c:601
i
int i
Definition: cdinfo-linux.c:194
cdtext_read_pack
int cdtext_read_pack(cdtext_pack_t *p_pack, const uint8_t *p_data)
Definition: cdtext.c:865
CDTEXT_PACK_PERFORMER
Definition: cdtext_private.h:47
CDTEXT_LANGUAGE_ZULU
Definition: cdtext.h:146
cdtext_block_s::first_track
track_t first_track
Definition: cdtext_private.h:119
cdtext_pack_s::block
uint8_t block
Definition: cdtext_private.h:82
cdtext_pack_s::i_track
uint8_t i_track
Definition: cdtext_private.h:79
cdio_charset_to_utf8
bool cdio_charset_to_utf8(const char *src, size_t src_len, cdio_utf8_t **dst, const char *src_charset)
Convert a string from another charset to UTF-8.
NULL
#define NULL
Definition: types.h:184
CDTEXT_LANGUAGE_WALLON
Definition: cdtext.h:145
cdtext_s::block_i
uint8_t block_i
Definition: cdtext_private.h:130
cdtext_set_language_index
bool cdtext_set_language_index(cdtext_t *p_cdtext, int idx)
Definition: cdtext.c:435
cdtext_blocksize_s::i_packs
uint8_t i_packs[16]
Definition: cdtext_private.h:96
cdtext_get
char * cdtext_get(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track)
Definition: cdtext.c:269
cdtext_destroy
void cdtext_destroy(cdtext_t *p_cdtext)
Definition: cdtext.c:242
CDTEXT_PACK_SONGWRITER
Definition: cdtext_private.h:48
CDTEXT_PACK_BLOCKSIZE
Definition: cdtext_private.h:57
CDTEXT_LANGUAGE_UNKNOWN
Definition: cdtext.h:102
cdtext_blocksize_s::copyright
uint8_t copyright
Definition: cdtext_private.h:95
j
int j
Definition: cdinfo-linux.c:194
CDTEXT_GET_LEN16
#define CDTEXT_GET_LEN16(p)
Definition: cdtext_private.h:28
cdtext_get_genre
cdtext_genre_t cdtext_get_genre(const cdtext_t *p_cdtext)
Definition: cdtext.c:305
CDTEXT_NUM_TRACKS_MAX
Definition: cdtext_private.h:37
cdtext_blocksize_s
Definition: cdtext_private.h:90
cdtext_blocksize_s::charcode
uint8_t charcode
Definition: cdtext_private.h:92
cdtext_blocksize_s::i_last_track
uint8_t i_last_track
Definition: cdtext_private.h:94
cdtext_get_const
const char * cdtext_get_const(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track)
Definition: cdtext.c:289
cdtext.h
The top-level header for CD-Text information. Applications include this for CD-Text access.
cdtext_field2str
const char * cdtext_field2str(cdtext_field_t i)
Definition: cdtext.c:203
cdtext_pack_s
Definition: cdtext_private.h:76
cdtext_pack_s::char_pos
uint8_t char_pos
Definition: cdtext_private.h:81
cdtext_private.h
CDIO_CD_MAX_TRACKS
Definition: track.h:77
cdtext_language
const char * cdtext_language[127+1]
Definition: cdtext.c:89
cdtext_pack_s::seq
uint8_t seq
Definition: cdtext_private.h:80
MAX_CDTEXT_GENRE_CODE
#define MAX_CDTEXT_GENRE_CODE
Definition: cdtext.c:40
buffer
char buffer[6][CDIO_CD_FRAMESIZE_RAW]
Definition: cdinfo-linux.c:201
utf8.h
UTF-8 support.
CDTEXT_FIELD_ARRANGER
Definition: cdtext.h:50
cdtext_init
cdtext_t * cdtext_init(void)
Definition: cdtext.c:486
cdtext_blocksize_s::i_first_track
uint8_t i_first_track
Definition: cdtext_private.h:93
cdtext_field
const char * cdtext_field[MAX_CDTEXT_FIELDS]
Definition: cdtext.c:43
logging.h
Header to control logging and level of detail of output.
cdtext_lang2str
const char * cdtext_lang2str(cdtext_lang_t i)
Definition: cdtext.c:227
CDTEXT_FIELD_ISRC
Definition: cdtext.h:51
cdtext_block_s::track
struct cdtext_track_s track[CDTEXT_NUM_TRACKS_MAX]
Definition: cdtext_private.h:115
CDTEXT_FIELD_PERFORMER
Definition: cdtext.h:46
cdtext_lang_t
cdtext_lang_t
Enumeration of possible CD-TEXT languages.
Definition: cdtext.h:101
cdtext_list_languages
cdtext_lang_t * cdtext_list_languages(const cdtext_t *p_cdtext)
Definition: cdtext.c:369
config.h
CDTEXT_LANGUAGE_AMHARIC
Definition: cdtext.h:204
CDTEXT_COMPARE_CHAR
#define CDTEXT_COMPARE_CHAR(buf, c, db)
Definition: cdtext.c:589
CDTEXT_LANGUAGE_INVALID
Definition: cdtext.h:208
cdtext_s::languages
cdtext_lang_t languages[CDTEXT_NUM_BLOCKS_MAX]
Definition: cdtext_private.h:129
cdtext_select_language
bool cdtext_select_language(cdtext_t *p_cdtext, cdtext_lang_t language)
Definition: cdtext.c:459
CDTEXT_GENRE_UNUSED
Definition: cdtext.h:63
CDTEXT_FIELD_DISCID
Definition: cdtext.h:54
CDTEXT_FIELD_MESSAGE
Definition: cdtext.h:49
cdtext_s
Definition: cdtext_private.h:127
cdtext_genre2str
const char * cdtext_genre2str(cdtext_genre_t i)
Definition: cdtext.c:215
cdtext_field_t
cdtext_field_t
Enumeration of CD-TEXT text fields.
Definition: cdtext.h:44
cdtext_get_language
cdtext_lang_t cdtext_get_language(const cdtext_t *p_cdtext)
Definition: cdtext.c:318
CDTEXT_LEN_TEXTDATA
Definition: cdtext_private.h:33
CDTEXT_LEN_PACK
Definition: cdtext_private.h:34
CDTEXT_CHARCODE_SHIFT_JIS
Definition: cdtext_private.h:65
cdtext_blocksize_s::langcode
uint8_t langcode[8]
Definition: cdtext_private.h:102
CDTEXT_FIELD_SONGWRITER
Definition: cdtext.h:47
cdtext_set
void cdtext_set(cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, track_t track, const char *charset)
Definition: cdtext.c:568
cdio_utf8_t
char cdio_utf8_t
UTF-8 char definition.
Definition: types.h:234