brasero r1570 - in trunk: . src
- From: philippr svn gnome org
- To: svn-commits-list gnome org
- Subject: brasero r1570 - in trunk: . src
- Date: Thu, 27 Nov 2008 17:23:26 +0000 (UTC)
Author: philippr
Date: Thu Nov 27 17:23:26 2008
New Revision: 1570
URL: http://svn.gnome.org/viewvc/brasero?rev=1570&view=rev
Log:
Take charset into account for CD-TEXT
* src/burn-medium.c (brasero_medium_get_CD_TEXT),
(_next_CD_TEXT_pack), (brasero_medium_read_CD_TEXT_block_info),
(brasero_medium_read_CD_TEXT):
* src/scsi-read-toc-pma-atip.h:
Modified:
trunk/ChangeLog
trunk/src/burn-medium.c
trunk/src/scsi-read-toc-pma-atip.h
Modified: trunk/src/burn-medium.c
==============================================================================
--- trunk/src/burn-medium.c (original)
+++ trunk/src/burn-medium.c Thu Nov 27 17:23:26 2008
@@ -2789,11 +2789,13 @@
brasero_medium_get_CD_TEXT (BraseroMedium *medium,
int type,
int track_num,
+ guint charset_CD_TEXT,
+ gboolean double_byte,
const char *string)
{
char *utf8_string;
- const char *charset = NULL;
BraseroMediumPrivate *priv;
+ const gchar *charset = NULL;
priv = BRASERO_MEDIUM_PRIVATE (medium);
@@ -2814,7 +2816,6 @@
case BRASERO_SCSI_CD_TEXT_DISC_ID_INFO:
case BRASERO_SCSI_CD_TEXT_GENRE_ID_INFO:
case BRASERO_SCSI_CD_TEXT_UPC_EAN_ISRC:
- case BRASERO_SCSI_CD_TEXT_BLOCK_SIZE:
default:
return FALSE;
}
@@ -2822,14 +2823,59 @@
g_get_charset (&charset);
/* it's ASCII so convert to locale */
- utf8_string = g_convert_with_fallback (string,
- -1,
- charset,
- "ASCII",
- NULL,
- NULL,
- NULL,
- NULL);
+ switch (charset_CD_TEXT) {
+ case BRASERO_CD_TEXT_8859_1:
+ utf8_string = g_convert_with_fallback (string,
+ -1,
+ charset,
+ "ISO-8859-1",
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ break;
+ case BRASERO_CD_TEXT_KANJI:
+ utf8_string = g_convert_with_fallback (string,
+ -1,
+ charset,
+ "EUC-JP",
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ break;
+ case BRASERO_CD_TEXT_KOREAN:
+ utf8_string = g_convert_with_fallback (string,
+ -1,
+ charset,
+ "EUC-KR",
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ break;
+ case BRASERO_CD_TEXT_CHINESE:
+ utf8_string = g_convert_with_fallback (string,
+ -1,
+ charset,
+ "GB2312",
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ break;
+ default:
+ case BRASERO_CD_TEXT_ASCII:
+ utf8_string = g_convert_with_fallback (string,
+ -1,
+ charset,
+ "ASCII",
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ }
+
if (priv->CD_TEXT_title)
g_free (priv->CD_TEXT_title);
@@ -2843,15 +2889,72 @@
return TRUE;
}
+static int
+_next_CD_TEXT_pack (BraseroScsiCDTextData *cd_text,
+ int current,
+ int max)
+{
+ current ++;
+ if (current >= max)
+ return -1;
+
+ /* Skip all packs we're not interested or are not valid */
+ while (cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_ALBUM_TITLE &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_PERFORMER_NAME &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_SONGWRITER_NAME &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_COMPOSER_NAME &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_ARRANGER_NAME &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_ARTIST_NAME &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_DISC_ID_INFO &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_GENRE_ID_INFO &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_UPC_EAN_ISRC &&
+ cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_BLOCK_SIZE) {
+ current ++;
+ if (current > max)
+ return -1;
+ }
+
+ return current;
+}
+
+static gboolean
+brasero_medium_read_CD_TEXT_block_info (BraseroScsiCDTextData *cd_text,
+ int current,
+ int max,
+ gchar *buffer)
+{
+ while ((current = _next_CD_TEXT_pack (cd_text, current, max)) != -1) {
+ off_t offset = 0;
+
+ if (cd_text->pack [current].type != BRASERO_SCSI_CD_TEXT_BLOCK_SIZE)
+ continue;
+
+ do {
+ memcpy (buffer + offset,
+ cd_text->pack [current].text,
+ sizeof (cd_text->pack [current].text));
+
+ offset += sizeof (cd_text->pack [current].text);
+ current = _next_CD_TEXT_pack (cd_text, current, max);
+ } while (current != -1 && cd_text->pack [current].type == BRASERO_SCSI_CD_TEXT_BLOCK_SIZE);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
brasero_medium_read_CD_TEXT (BraseroMedium *self,
BraseroDeviceHandle *handle,
BraseroScsiErrCode *code)
{
int off;
+ gint charset;
int track_num;
int num, size, i;
char buffer [256]; /* mmc specs advise no more than 160 */
+ gboolean find_block_info;
BraseroMediumPrivate *priv;
BraseroScsiCDTextData *cd_text;
@@ -2861,28 +2964,63 @@
return;
}
+ /* Get the number of CD-Text Data Packs */
num = (BRASERO_GET_16 (cd_text->hdr->len) -
(sizeof (BraseroScsiTocPmaAtipHdr) - sizeof (cd_text->hdr->len))) /
sizeof (BraseroScsiCDTextPackData);
- track_num = 0;
- off = 0;
-
priv = BRASERO_MEDIUM_PRIVATE (self);
- for (i = 0; i < num; i ++) {
+ off = 0;
+ track_num = 0;
+ charset = BRASERO_CD_TEXT_ASCII;
+
+ i = -1;
+ find_block_info = TRUE;
+ while ((i = _next_CD_TEXT_pack (cd_text, i, num)) != -1) {
int j;
+ gboolean is_double_byte;
+
+ /* skip these until the start of another language block or the end */
+ if (cd_text->pack [i].type == BRASERO_SCSI_CD_TEXT_BLOCK_SIZE) {
+ find_block_info = TRUE;
+ continue;
+ }
+
+ if (find_block_info) {
+ find_block_info = FALSE;
+
+ /* This pack is important since it holds the charset. */
+ /* NOTE: it's always the last in a block (max 255
+ * CD-TEXT pack data). So find it first. */
+ if (brasero_medium_read_CD_TEXT_block_info (cd_text, i, num, buffer)) {
+ BraseroScsiCDTextPackCharset *pack;
+
+ pack = (BraseroScsiCDTextPackCharset *) buffer;
+ charset = pack->charset;
+
+ BRASERO_BURN_LOG ("Found language pack. Charset = %d. Start %d. End %d",
+ charset, pack->first_track, pack->last_track);
+ }
+ }
track_num = cd_text->pack [i].track_num;
+ is_double_byte = cd_text->pack [i].double_byte;
for (j = 0; j < sizeof (cd_text->pack [i].text); j++) {
- if (!off && cd_text->pack [i].text [j] == '\t') {
+ if (!off
+ && cd_text->pack [i].text [j] == '\t'
+ && (!is_double_byte
+ || (j+1 < sizeof (cd_text->pack [i].text) && cd_text->pack [i].text [j + 1] == '\t'))) {
/* Specs say that tab character means that's the
- * same string as before */
+ * same string as before. So if buffer is not
+ * empty send the same string. */
if (buffer [0] != '\0')
brasero_medium_get_CD_TEXT (self,
cd_text->pack [i].type,
track_num,
+ charset,
+ cd_text->pack [i].double_byte,
buffer);
track_num ++;
continue;
@@ -2891,17 +3029,27 @@
buffer [off] = cd_text->pack [i].text [j];
off++;
- if (cd_text->pack [i].text [j] == '\0') {
+ if (cd_text->pack [i].text [j] == '\0'
+ && (!is_double_byte
+ || (j+1 < sizeof (cd_text->pack [i].text) && cd_text->pack [i].text [j + 1] == '\0'))) {
+ /* Make sure we actually wrote something to the
+ * buffer and that it's not empty. */
if (buffer [0] != '\0')
brasero_medium_get_CD_TEXT (self,
cd_text->pack [i].type,
track_num,
+ charset,
+ cd_text->pack [i].double_byte,
buffer);
+
+ /* End of encapsulated Text Pack. Skip to the next. */
track_num ++;
off = 0;
}
}
}
+
+ g_free (cd_text);
}
static void
Modified: trunk/src/scsi-read-toc-pma-atip.h
==============================================================================
--- trunk/src/scsi-read-toc-pma-atip.h (original)
+++ trunk/src/scsi-read-toc-pma-atip.h Thu Nov 27 17:23:26 2008
@@ -284,6 +284,7 @@
};
typedef struct _BraseroScsiMultisessionData BraseroScsiMultisessionData;
+/* Inside a language block, packs must be recorded in that order */
typedef enum {
BRASERO_SCSI_CD_TEXT_ALBUM_TITLE = 0x80,
BRASERO_SCSI_CD_TEXT_PERFORMER_NAME = 0x81,
@@ -303,12 +304,23 @@
BRASERO_SCSI_CD_TEXT_BLOCK_SIZE = 0x8F,
} BraseroScsiCDTextPackType;
+typedef enum {
+ BRASERO_CD_TEXT_8859_1 = 0x00,
+ BRASERO_CD_TEXT_ASCII = 0x01, /* (7 bit) */
+
+ /* Reserved */
+
+ BRASERO_CD_TEXT_KANJI = 0x80,
+ BRASERO_CD_TEXT_KOREAN = 0x81,
+ BRASERO_CD_TEXT_CHINESE = 0x82 /* Mandarin */
+} BraseroScsiCDTextCharset;
+
struct _BraseroScsiCDTextPackData {
uchar type;
uchar track_num;
uchar pack_num;
- uchar char_pos :4;
+ uchar char_pos :4; /* byte not used for type 0x8F */
uchar block_num :3;
uchar double_byte :1;
@@ -317,6 +329,18 @@
};
typedef struct _BraseroScsiCDTextPackData BraseroScsiCDTextPackData;
+/* Takes two BraseroScsiCDTextPackData (18 bytes) 3 x 12 = 36 bytes */
+struct _BraseroScsiCDTextPackCharset {
+ char charset;
+ char first_track;
+ char last_track;
+ char copyr_flags;
+ char pack_count [16];
+ char last_seqnum [8];
+ char language_code [8];
+};
+typedef struct _BraseroScsiCDTextPackCharset BraseroScsiCDTextPackCharset;
+
struct _BraseroScsiCDTextData {
BraseroScsiTocPmaAtipHdr hdr [1];
BraseroScsiCDTextPackData pack [0];
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]