~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to kscd/libwm/cdtext.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          cdtext.c  -  description
 
3
                             -------------------
 
4
    begin                : Mon Feb 12 2001
 
5
    copyright            : (C) 2001 by Alex Kern
 
6
    email                : alex.kern@gmx.de
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include <errno.h>
 
19
#include <stdio.h>
 
20
#include <unistd.h>
 
21
#include <stdlib.h>
 
22
#include <string.h>
 
23
#include <sys/types.h>
 
24
#ifdef libunicode
 
25
  #include <unicode.h>
 
26
#endif
 
27
/* #include <sys/time.h> */
 
28
 
 
29
#include "include/wm_config.h"
 
30
#include "include/wm_struct.h"
 
31
/*#include "include/wm_cdrom.h"*/
 
32
#include "include/wm_database.h"
 
33
#include "include/wm_platform.h"
 
34
#include "include/wm_helpers.h"
 
35
#include "include/wm_cdinfo.h"
 
36
#include "include/wm_cdtext.h"
 
37
 
 
38
struct cdtext_info wm_cdtext_info;
 
39
static int first_initialise = 1;
 
40
 
 
41
int free_cdtext_info_block(struct cdtext_info_block* cdtextinfoblock)
 
42
{
 
43
  if(cdtextinfoblock)
 
44
  {
 
45
    if(cdtextinfoblock->name)
 
46
      free(cdtextinfoblock->name);
 
47
    if(cdtextinfoblock->performer)
 
48
      free(cdtextinfoblock->performer);
 
49
    if(cdtextinfoblock->songwriter)
 
50
      free(cdtextinfoblock->songwriter);
 
51
    if(cdtextinfoblock->composer)
 
52
      free(cdtextinfoblock->composer);
 
53
    if(cdtextinfoblock->arranger)
 
54
      free(cdtextinfoblock->arranger);
 
55
    if(cdtextinfoblock->message)
 
56
      free(cdtextinfoblock->message);
 
57
    if(cdtextinfoblock->UPC_EAN_ISRC_code)
 
58
      free(cdtextinfoblock->UPC_EAN_ISRC_code);
 
59
 
 
60
    if(cdtextinfoblock->block_encoding_text)
 
61
      free(cdtextinfoblock->block_encoding_text);
 
62
  }
 
63
 
 
64
  return 0;
 
65
}
 
66
 
 
67
int free_cdtext_info(struct cdtext_info* cdtextinfo)
 
68
{
 
69
  int i;
 
70
  printf("CDTEXT INFO: free_cdtext_info() called\n");
 
71
  if(cdtextinfo)
 
72
  {
 
73
    for(i = 0; i < 8; i++)
 
74
    {
 
75
      if(cdtextinfo->blocks[i])
 
76
      {
 
77
        free_cdtext_info_block(cdtextinfo->blocks[i]);
 
78
      }
 
79
    }
 
80
  }
 
81
 
 
82
  return 0;
 
83
}
 
84
 
 
85
struct cdtext_info_block* malloc_cdtext_info_block(int count_of_tracks)
 
86
{
 
87
  int memamount;
 
88
  struct cdtext_info_block* lp_block;
 
89
 
 
90
  lp_block = malloc(sizeof(struct cdtext_info_block));
 
91
  if(!lp_block)
 
92
  {
 
93
    return (struct cdtext_info_block*)0;
 
94
  }
 
95
  memset(lp_block, 0, sizeof(struct cdtext_info_block));
 
96
 
 
97
  memamount = count_of_tracks * sizeof(cdtext_string);
 
98
 
 
99
  lp_block->name = malloc(memamount);
 
100
  if(!lp_block->name)
 
101
    return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
 
102
  memset(lp_block->name, 0, memamount);
 
103
 
 
104
  lp_block->performer = malloc(memamount);
 
105
  if(!lp_block->performer)
 
106
    return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
 
107
  memset(lp_block->performer, 0, memamount);
 
108
 
 
109
  lp_block->songwriter = malloc(memamount);
 
110
  if(!lp_block->songwriter)
 
111
    return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
 
112
  memset(lp_block->songwriter, 0, memamount);
 
113
 
 
114
  lp_block->composer = malloc(memamount);
 
115
  if(!lp_block->composer)
 
116
    return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
 
117
  memset(lp_block->composer, 0, memamount);
 
118
 
 
119
  lp_block->arranger = malloc(memamount);
 
120
  if(!lp_block->arranger)
 
121
    return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
 
122
  memset(lp_block->arranger, 0, memamount);
 
123
 
 
124
  lp_block->message = malloc(memamount);
 
125
  if(!lp_block->message)
 
126
    return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
 
127
  memset(lp_block->message, 0, memamount);
 
128
                
 
129
  lp_block->UPC_EAN_ISRC_code = malloc(memamount);
 
130
  if(!lp_block->UPC_EAN_ISRC_code)
 
131
    return (struct cdtext_info_block*)free_cdtext_info_block(lp_block);
 
132
  memset(lp_block->UPC_EAN_ISRC_code, 0, memamount);
 
133
 
 
134
  return lp_block;
 
135
}
 
136
 
 
137
void get_data_from_cdtext_pack(
 
138
  const struct cdtext_pack_data_header *pack,
 
139
  const struct cdtext_pack_data_header *pack_previous,
 
140
  cdtext_string *p_componente)
 
141
{
 
142
 
 
143
  int arr = pack->header_field_id2_tracknumber;
 
144
  int i;
 
145
  int language_block;
 
146
  int unicode;
 
147
 
 
148
  language_block = (pack->header_field_id4_block_no >> 4) & 0x07;
 
149
  unicode = pack->header_field_id4_block_no & 0x80;
 
150
 
 
151
  if(!unicode)
 
152
  {
 
153
    for(i = 0; i < DATAFIELD_LENGHT_IN_PACK; i++)
 
154
    {
 
155
      if(pack->text_data_field[i] == 0x00) /* end marker */
 
156
      {
 
157
        arr++;
 
158
      }
 
159
      else if(pack->text_data_field[i] == 0x09) /* repeat last marker */
 
160
      {
 
161
        /* ASSERT(arr > 0) */
 
162
        strcat((char*)(p_componente[arr]), (char*)(p_componente[arr-1]));
 
163
        arr++;
 
164
      }
 
165
      else
 
166
      {
 
167
        strncat((char*)(p_componente[arr]), (char*)(&(pack->text_data_field[i])), 1);
 
168
      }
 
169
    }
 
170
  }
 
171
#ifdef libunicode
 
172
  else /* doublebytes ;-) */
 
173
  {
 
174
    for(i = 0; i < DATAFIELD_LENGHT_IN_PACK; i += 2)
 
175
    {
 
176
      if((Uchar)(pack->text_data_field[i]) == 0x0000) /* end marker */
 
177
      {
 
178
        arr++;
 
179
      }
 
180
      else if((Uchar)(pack->text_data_field[i]) == 0x0909) /* repeat last marker */
 
181
      {
 
182
        /* ASSERT(arr > 0) */
 
183
        strcat((char*)(p_componente[arr]), (char*)(p_componente[arr-1]));
 
184
        arr++;
 
185
      }
 
186
      else
 
187
      {
 
188
        strncat((char*)(p_componente[arr]), u_uc_to_utf8((Uchar*)(&(pack->text_data_field[i]))), 1);
 
189
      }
 
190
    }
 
191
  }
 
192
#else
 
193
  else {
 
194
     fprintf( stderr, "can't handle unicode"); 
 
195
  }
 
196
#endif
 
197
}
 
198
 
 
199
int wm_get_cdtext(struct wm_drive *d)
 
200
{
 
201
  /* alloc cdtext_info */
 
202
 
 
203
  unsigned char *buffer;
 
204
  int buffer_lenght;
 
205
  int ret;
 
206
  int i;
 
207
  struct cdtext_pack_data_header *pack, *pack_previous;
 
208
  cdtext_string *p_componente;
 
209
  struct cdtext_info_block *lp_block;
 
210
 
 
211
  if(1 == first_initialise)
 
212
  {
 
213
    memset(&wm_cdtext_info, 0, sizeof(struct cdtext_info));
 
214
    first_initialise = 0;
 
215
  }
 
216
 
 
217
  lp_block = 0;
 
218
  p_componente = 0;
 
219
  buffer = 0;
 
220
  buffer_lenght = 0;
 
221
 
 
222
  ret = (d->get_cdtext)(d, &buffer, &buffer_lenght);
 
223
 
 
224
  free_cdtext_info(&wm_cdtext_info);
 
225
  memset(&wm_cdtext_info, 0, sizeof(struct cdtext_info));
 
226
  if(!ret)
 
227
  {
 
228
    (d->get_trackcount)(d, &(wm_cdtext_info.count_of_entries));
 
229
    if( wm_cdtext_info.count_of_entries < 0 )
 
230
      wm_cdtext_info.count_of_entries = 1;
 
231
    else
 
232
      wm_cdtext_info.count_of_entries++;
 
233
 
 
234
    i = 0;
 
235
 
 
236
    pack = 0; /* NULL pointer*/
 
237
    while(i < buffer_lenght)
 
238
    {
 
239
      pack_previous = pack;
 
240
      pack = (struct cdtext_pack_data_header*)(buffer+i);
 
241
      /* to implement: check_crc(pack); */
 
242
 
 
243
      /* only for valid packs */
 
244
      if(pack->header_field_id1_typ_of_pack >= 0x80 && pack->header_field_id1_typ_of_pack < 0x90)
 
245
      {
 
246
        int code, j;
 
247
          printf("CDTEXT DEBUG: valid packet at 0x%08X: 0x %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
 
248
            i,
 
249
            pack->header_field_id1_typ_of_pack,
 
250
            pack->header_field_id2_tracknumber,
 
251
            pack->header_field_id3_sequence,
 
252
            pack->header_field_id4_block_no,
 
253
            pack->text_data_field[0],
 
254
            pack->text_data_field[1],
 
255
            pack->text_data_field[2],
 
256
            pack->text_data_field[3],
 
257
            pack->text_data_field[4],
 
258
            pack->text_data_field[5],
 
259
            pack->text_data_field[6],
 
260
            pack->text_data_field[7],
 
261
            pack->text_data_field[8],
 
262
            pack->text_data_field[9],
 
263
            pack->text_data_field[10],
 
264
            pack->text_data_field[11],
 
265
            pack->crc_byte1,
 
266
            pack->crc_byte2);
 
267
        wm_cdtext_info.count_of_valid_packs++;
 
268
 
 
269
        code = (pack->header_field_id4_block_no >> 4) & 0x07;
 
270
        if(0 == lp_block || lp_block->block_code != code) /* find or create one new block */
 
271
        {
 
272
          lp_block = 0;
 
273
          for(j = 0; j < MAX_LANGUAGE_BLOCKS && wm_cdtext_info.blocks[j] != 0 && 0 == lp_block; i++)
 
274
          {
 
275
            if(wm_cdtext_info.blocks[j]->block_code == code)
 
276
            {
 
277
              lp_block = wm_cdtext_info.blocks[j];
 
278
            }
 
279
          }
 
280
 
 
281
          if(MAX_LANGUAGE_BLOCKS <= j)
 
282
          {
 
283
            free_cdtext_info(&wm_cdtext_info);
 
284
            printf("CDTEXT ERROR: more as 8 languageblocks defined\n");
 
285
            return -1;
 
286
          }
 
287
 
 
288
          if(0 == lp_block)
 
289
          {
 
290
            /* make next new block */
 
291
            lp_block = malloc_cdtext_info_block(wm_cdtext_info.count_of_entries);
 
292
            if(0 == lp_block)
 
293
            {
 
294
              printf("CDTEXT ERROR: out of memory, can't create a new language block\n");
 
295
              free_cdtext_info(&wm_cdtext_info);
 
296
              return ENOMEM;
 
297
            }
 
298
            else
 
299
            {
 
300
              wm_cdtext_info.blocks[j] = lp_block;
 
301
              wm_cdtext_info.blocks[j]->block_code = code;
 
302
              wm_cdtext_info.blocks[j]->block_unicode = pack->header_field_id4_block_no & 0x80;
 
303
              printf("CDTEXT INFO: created a new language block; code %i, %s characters\n", code, lp_block->block_unicode?"doublebyte":"singlebyte");
 
304
/*
 
305
  unsigned char block_encoding; not jet!
 
306
  cdtext_string* block_encoding_text;
 
307
*/
 
308
            }
 
309
          }
 
310
        }
 
311
      }
 
312
 
 
313
      switch(pack->header_field_id1_typ_of_pack)
 
314
      {
 
315
        case 0x80:
 
316
          p_componente = (lp_block->name);
 
317
          get_data_from_cdtext_pack(pack, pack_previous, p_componente);
 
318
          break;
 
319
        case 0x81:
 
320
          p_componente = (lp_block->performer);
 
321
          get_data_from_cdtext_pack(pack, pack_previous, p_componente);
 
322
          break;
 
323
        case 0x82:
 
324
          p_componente = (lp_block->songwriter);
 
325
          get_data_from_cdtext_pack(pack, pack_previous, p_componente);
 
326
          break;
 
327
        case 0x83:
 
328
          p_componente = (lp_block->composer);
 
329
          get_data_from_cdtext_pack(pack, pack_previous, p_componente);
 
330
          break;
 
331
        case 0x84:
 
332
          p_componente = (lp_block->arranger);
 
333
          get_data_from_cdtext_pack(pack, pack_previous, p_componente);
 
334
          break;
 
335
        case 0x85:
 
336
          p_componente = (lp_block->message);
 
337
          get_data_from_cdtext_pack(pack, pack_previous, p_componente);
 
338
          break;
 
339
        case 0x86:
 
340
          memcpy((char*)(lp_block->binary_disc_identification_info),
 
341
          (char*)(pack->text_data_field),  DATAFIELD_LENGHT_IN_PACK);
 
342
          break;
 
343
        case 0x87:
 
344
          memcpy((char*)(lp_block->binary_genreidentification_info),
 
345
          (char*)(pack->text_data_field),  DATAFIELD_LENGHT_IN_PACK);
 
346
          break;
 
347
        case 0x88:
 
348
         printf("CDTEXT INFO: PACK with code 0x88 (TOC)\n");
 
349
          break;
 
350
        case 0x89:
 
351
         printf("CDTEXT INFO: PACK with code 0x89 (second TOC)\n");
 
352
          break;
 
353
        case 0x8A:
 
354
        case 0x8B:
 
355
        case 0x8C:
 
356
          printf("CDTEXT INFO: PACK with code 0x%02X (reserved)\n", pack->header_field_id1_typ_of_pack);
 
357
          break;
 
358
        case 0x8D:
 
359
          printf("CDTEXT INFO: PACK with code 0x8D (for content provider only)\n");
 
360
          break;
 
361
        case 0x8E:
 
362
          p_componente = (lp_block->UPC_EAN_ISRC_code);
 
363
          get_data_from_cdtext_pack(pack, pack_previous, p_componente);
 
364
          break;
 
365
        case 0x8F:
 
366
          memcpy((char*)(lp_block->binary_size_information),
 
367
          (char*)(pack->text_data_field), DATAFIELD_LENGHT_IN_PACK);
 
368
          break;
 
369
        default:
 
370
          printf("CDTEXT ERROR: invalid packet at 0x%08X: 0x %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
 
371
            i,
 
372
            pack->header_field_id1_typ_of_pack,
 
373
            pack->header_field_id2_tracknumber,
 
374
            pack->header_field_id3_sequence,
 
375
            pack->header_field_id4_block_no,
 
376
            pack->text_data_field[0],
 
377
            pack->text_data_field[1],
 
378
            pack->text_data_field[2],
 
379
            pack->text_data_field[3],
 
380
            pack->text_data_field[4],
 
381
            pack->text_data_field[5],
 
382
            pack->text_data_field[6],
 
383
            pack->text_data_field[7],
 
384
            pack->text_data_field[8],
 
385
            pack->text_data_field[9],
 
386
            pack->text_data_field[10],
 
387
            pack->text_data_field[11],
 
388
            pack->crc_byte1,
 
389
            pack->crc_byte2);
 
390
          wm_cdtext_info.count_of_invalid_packs++;
 
391
      }
 
392
      i += sizeof(struct cdtext_pack_data_header);
 
393
    } /* while */
 
394
  }
 
395
 
 
396
  if(0 == ret && wm_cdtext_info.count_of_valid_packs > 0)
 
397
    wm_cdtext_info.valid = 1;
 
398
 
 
399
  return ret;
 
400
}
 
401
 
 
402
void wm_free_cdtext(void)
 
403
{
 
404
  printf("CDTEXT INFO: wm_free_cdtext() called, this function will be called at the end from USERSPACE(KSCD etc.)\n");
 
405
  if (0 == first_initialise)
 
406
    free_cdtext_info(&wm_cdtext_info);
 
407
 
 
408
  first_initialise = 1; 
 
409
}