aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/frametab.gperf7
-rw-r--r--src/idest.h3
-rw-r--r--src/idop.c59
3 files changed, 44 insertions, 25 deletions
diff --git a/src/frametab.gperf b/src/frametab.gperf
index 7863d08..c02b771 100644
--- a/src/frametab.gperf
+++ b/src/frametab.gperf
@@ -39,13 +39,13 @@ decode_qv(struct ed_item *item, struct id3_frame const *frame,
39 item->qc = count; 39 item->qc = count;
40 item->qv = xcalloc(item->qc, sizeof(item->qv[0])); 40 item->qv = xcalloc(item->qc, sizeof(item->qv[0]));
41 for (i = 0; i < count; i++) { 41 for (i = 0; i < count; i++) {
42 field = id3_frame_field(frame, n + i); 42 field = id3_frame_field(frame, n + i);
43 if (!field) 43 if (!field)
44 break; 44 break;
45 item->qv[i] = field_to_string(field, 0); 45 item->qv[i] = field_to_string(field, frame);
46 } 46 }
47 return 0; 47 return 0;
48} 48}
49 49
50char *_idest_errstr[] = { 50char *_idest_errstr[] = {
51 "no error", 51 "no error",
@@ -343,21 +343,20 @@ text_encode(struct id3_frame *frame, struct ed_item const *item)
343 return 0; 343 return 0;
344} 344}
345 345
346static int 346static int
347text_decode(struct ed_item *item, struct id3_frame const *frame) 347text_decode(struct ed_item *item, struct id3_frame const *frame)
348{ 348{
349 int isgenre = strcmp(frame->id, ID3_FRAME_GENRE) == 0;
350 union id3_field *field; 349 union id3_field *field;
351 char *str; 350 char *str;
352 int rc; 351 int rc;
353 352
354 field = id3_frame_field(frame, 1); 353 field = id3_frame_field(frame, 1);
355 if (!field) 354 if (!field)
356 return IDEST_ERR_NOFIELD; 355 return IDEST_ERR_NOFIELD;
357 str = field_to_string(field, isgenre); 356 str = field_to_string(field, frame);
358 rc = utf8_convert(idest_conv_decode, str, &item->value); 357 rc = utf8_convert(idest_conv_decode, str, &item->value);
359 free(str); 358 free(str);
360 if (rc) 359 if (rc)
361 return IDEST_ERR_BADCONV; 360 return IDEST_ERR_BADCONV;
362 return 0; 361 return 0;
363} 362}
diff --git a/src/idest.h b/src/idest.h
index 2c10077..787cdad 100644
--- a/src/idest.h
+++ b/src/idest.h
@@ -89,17 +89,16 @@ extern int fixup_option;
89 89
90/* idop.c */ 90/* idop.c */
91int guess_file_tag_options(struct id3_file *file, int *modified); 91int guess_file_tag_options(struct id3_file *file, int *modified);
92int set_frame_value(struct id3_frame *frame, const struct ed_item *item); 92int set_frame_value(struct id3_frame *frame, const struct ed_item *item);
93void set_tags(const char *name); 93void set_tags(const char *name);
94void del_tags(const char *name); 94void del_tags(const char *name);
95char *idest_ucs4_cvt(id3_ucs4_t const *ucs4);
96void query_tags(const char *name); 95void query_tags(const char *name);
97void info_id3(const char *name); 96void info_id3(const char *name);
98 97
99char *field_to_string(union id3_field *field, int isgenre); 98char *field_to_string(union id3_field *field, struct id3_frame const *frame);
100int field_binary_from_string(union id3_field *field, const char *str); 99int field_binary_from_string(union id3_field *field, const char *str);
101char *field_binary_to_string(union id3_field *field); 100char *field_binary_to_string(union id3_field *field);
102 101
103int frame_field_from_rawdata(struct id3_frame *frame, int n, 102int frame_field_from_rawdata(struct id3_frame *frame, int n,
104 enum id3_field_type type, 103 enum id3_field_type type,
105 const char *value); 104 const char *value);
diff --git a/src/idop.c b/src/idop.c
index 063ff78..c3a3ce2 100644
--- a/src/idop.c
+++ b/src/idop.c
@@ -185,16 +185,37 @@ safe_id3_file_update_and_close(struct id3_file *file)
185 sigprocmask(SIG_BLOCK, &set, &oldset); 185 sigprocmask(SIG_BLOCK, &set, &oldset);
186 id3_file_update(file); 186 id3_file_update(file);
187 id3_file_close(file); 187 id3_file_close(file);
188 sigprocmask(SIG_SETMASK, &oldset, NULL); 188 sigprocmask(SIG_SETMASK, &oldset, NULL);
189} 189}
190 190
191static int
192frame_encoding_is_8bit(struct id3_frame const *frame)
193{
194 union id3_field const *field;
195
196 if (!frame)
197 return 0;
198 field = id3_frame_field(frame, 0);
199 if (!field)
200 return 0;
201 return id3_field_gettextencoding(field) == ID3_FIELD_TEXTENCODING_ISO_8859_1;
202}
203
204static int
205frame_is_genre(struct id3_frame const *frame)
206{
207 if (!frame)
208 return 0;
209 return strcmp(frame->id, ID3_FRAME_GENRE) == 0;
210}
211
191char * 212char *
192idest_ucs4_cvt(id3_ucs4_t const *ucs4) 213idest_ucs4_cvt(id3_ucs4_t const *ucs4, struct id3_frame const *frame)
193{ 214{
194 if (broken_8bit_charset) { 215 if (broken_8bit_charset && frame_encoding_is_8bit(frame)) {
195 char *tempval = (char*)id3_ucs4_latin1duplicate(ucs4); 216 char *tempval = (char*)id3_ucs4_latin1duplicate(ucs4);
196 char *output; 217 char *output;
197 int rc = utf8_convert(idest_conv_recode, tempval, &output); 218 int rc = utf8_convert(idest_conv_recode, tempval, &output);
198 free(tempval); 219 free(tempval);
199 if (rc == 0) 220 if (rc == 0)
200 return output; 221 return output;
@@ -202,28 +223,29 @@ idest_ucs4_cvt(id3_ucs4_t const *ucs4)
202 broken_8bit_charset, "utf-8"); 223 broken_8bit_charset, "utf-8");
203 } 224 }
204 return (char*) id3_ucs4_utf8duplicate(ucs4); 225 return (char*) id3_ucs4_utf8duplicate(ucs4);
205} 226}
206 227
207static void 228static void
208add_stringlist(gl_list_t list, union id3_field *field, int isgenre, 229add_stringlist(gl_list_t list, union id3_field *field,
230 struct id3_frame const *frame,
209 size_t *psize) 231 size_t *psize)
210{ 232{
211 unsigned i, nstrings = id3_field_getnstrings(field); 233 unsigned i, nstrings = id3_field_getnstrings(field);
212 size_t size = 0; 234 size_t size = 0;
213 235
214 for (i = 0; i < nstrings; i++) { 236 for (i = 0; i < nstrings; i++) {
215 id3_ucs4_t const *ucs4; 237 id3_ucs4_t const *ucs4;
216 char *str; 238 char *str;
217 239
218 ucs4 = id3_field_getstrings(field, i); 240 ucs4 = id3_field_getstrings(field, i);
219 if (!ucs4) 241 if (!ucs4)
220 continue; 242 continue;
221 if (isgenre) 243 if (frame_is_genre(frame))
222 ucs4 = id3_genre_name(ucs4); 244 ucs4 = id3_genre_name(ucs4);
223 str = idest_ucs4_cvt(ucs4); 245 str = idest_ucs4_cvt(ucs4, frame);
224 size += strlen(str); 246 size += strlen(str);
225 gl_list_add_last(list, str); 247 gl_list_add_last(list, str);
226 } 248 }
227 if (psize) 249 if (psize)
228 *psize = size; 250 *psize = size;
229} 251}
@@ -281,13 +303,13 @@ field_binary_from_string(union id3_field *field, const char *str)
281 field->binary.data[i] = b; 303 field->binary.data[i] = b;
282 } 304 }
283 return IDEST_OK; 305 return IDEST_OK;
284} 306}
285 307
286char * 308char *
287field_to_string(union id3_field *field, int isgenre) 309field_to_string(union id3_field *field, struct id3_frame const *frame)
288{ 310{
289 id3_ucs4_t const *ucs4; 311 id3_ucs4_t const *ucs4;
290 char *ret = NULL; 312 char *ret = NULL;
291 char buf[128]; 313 char buf[128];
292 314
293 switch (id3_field_type(field)) { 315 switch (id3_field_type(field)) {
@@ -309,29 +331,29 @@ field_to_string(union id3_field *field, int isgenre)
309 case ID3_FIELD_TYPE_LATIN1LIST: 331 case ID3_FIELD_TYPE_LATIN1LIST:
310 /* FIXME */ 332 /* FIXME */
311 break; 333 break;
312 334
313 case ID3_FIELD_TYPE_STRING: 335 case ID3_FIELD_TYPE_STRING:
314 ucs4 = id3_field_getstring(field);; 336 ucs4 = id3_field_getstring(field);;
315 if (ucs4) 337 if (ucs4)
316 ret = idest_ucs4_cvt(ucs4); 338 ret = idest_ucs4_cvt(ucs4, frame);
317 break; 339 break;
318 340
319 case ID3_FIELD_TYPE_STRINGFULL: 341 case ID3_FIELD_TYPE_STRINGFULL:
320 ucs4 = id3_field_getfullstring(field); 342 ucs4 = id3_field_getfullstring(field);
321 ret = idest_ucs4_cvt(ucs4); 343 ret = idest_ucs4_cvt(ucs4, frame);
322 break; 344 break;
323 345
324 case ID3_FIELD_TYPE_STRINGLIST: { 346 case ID3_FIELD_TYPE_STRINGLIST: {
325 gl_list_t list; 347 gl_list_t list;
326 size_t sz; 348 size_t sz;
327 gl_list_iterator_t itr; 349 gl_list_iterator_t itr;
328 const void *p; 350 const void *p;
329 351
330 list = new_string_list(true); 352 list = new_string_list(true);
331 add_stringlist(list, field, isgenre, &sz); 353 add_stringlist(list, field, frame, &sz);
332 ret = xmalloc(sz + 1); 354 ret = xmalloc(sz + 1);
333 ret[0] = 0; 355 ret[0] = 0;
334 itr = gl_list_iterator(list); 356 itr = gl_list_iterator(list);
335 while (gl_list_iterator_next(&itr, &p, NULL)) 357 while (gl_list_iterator_next(&itr, &p, NULL))
336 strcat(ret, p); 358 strcat(ret, p);
337 gl_list_iterator_free(&itr); 359 gl_list_iterator_free(&itr);
@@ -525,29 +547,36 @@ update_frames(struct id3_tag *tag)
525 } 547 }
526 gl_list_iterator_free(&itr); 548 gl_list_iterator_free(&itr);
527 return modified; 549 ret