aboutsummaryrefslogtreecommitdiff
path: root/libmpio/mplib/mplib_s.c
diff options
context:
space:
mode:
authorLars-Dominik Braun <PromyLOPh@lavabit.com>2009-05-09 13:30:25 +0200
committerLars-Dominik Braun <PromyLOPh@lavabit.com>2009-05-09 13:30:25 +0200
commit2d49dfdd370852d5033b848fd69b6112368b7d20 (patch)
treee83bbefd73bc643df14b9e0728df1ff5eea11d6a /libmpio/mplib/mplib_s.c
parent5c2e36136f0c6801ef73ddeaff7f7d4ac412681f (diff)
downloadmpiosh-2d49dfdd370852d5033b848fd69b6112368b7d20.tar.gz
mpiosh-2d49dfdd370852d5033b848fd69b6112368b7d20.tar.bz2
mpiosh-2d49dfdd370852d5033b848fd69b6112368b7d20.zip
Drop id3 rewriting
Diffstat (limited to 'libmpio/mplib/mplib_s.c')
-rw-r--r--libmpio/mplib/mplib_s.c1177
1 files changed, 0 insertions, 1177 deletions
diff --git a/libmpio/mplib/mplib_s.c b/libmpio/mplib/mplib_s.c
deleted file mode 100644
index 2c336b4..0000000
--- a/libmpio/mplib/mplib_s.c
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- * mplib - a library that enables you to edit ID3 tags
- * Copyright (C) 2001,2002 Stefan Podkowinski
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; version 2.1.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
-
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#if STDC_HEADERS
-# include <stdlib.h>
-# include <string.h>
-#elif HAVE_STRINGS_H
-# include <strings.h>
-#endif /*STDC_HEADERS*/
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-# include <sys/types.h>
-#endif
-
-
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <sys/stat.h>
-
-#include "mplib_s.h"
-#include "xmalloc.h"
-
-
-
-/******************************/
-/* Static functions */
-/******************************/
-
-static id3v1_tag*
-id3v1_get_tag(int fd)
-{
- id3v1_tag *tag;
- char *c;
-
- tag = XMALLOCD0(id3v1_tag, "id3v1_get_tag:tag");
-
- c = (char *)xmallocd(3, "id3v1_get_tag:c");
-
- if(lseek(fd, -128L, SEEK_END) == -1) goto exit_on_error;
- if(read(fd, c, 3) < 3) goto exit_on_error;
- if(strncmp(c, "TAG", 3) != 0) goto exit_on_error;
-
- tag->title = (char *)xmallocd(31, "id3v1_get_tag:tag->title");
- if(read(fd, tag->title, 30) < 30) goto exit_on_error;
- if(tag->title[0] == 0 || id3_is_only_space(tag->title, 30)) {
- xfree(tag->title);
- tag->title = NULL;
- } else tag->title[30] = 0;
-
- tag->artist = (char*)xmallocd(31, "id3v1_get_tag:tag->artist");
- if(read(fd, tag->artist, 30) < 30) goto exit_on_error;
- if(tag->artist[0] == 0 || id3_is_only_space(tag->artist, 30)) {
- xfree(tag->artist);
- tag->artist = NULL;
- } else tag->artist[30] = 0;
-
- tag->album = (char*)xmallocd(31, "id3v1_get_tag:tag->album");
- if(read(fd, tag->album, 30) < 30) goto exit_on_error;
- if(tag->album[0] == 0 || id3_is_only_space(tag->album, 30)) {
- xfree(tag->album);
- tag->album = NULL;
- } else tag->album[30] = 0;
-
- tag->year = (char*)xmallocd(5, "id3v1_get_tag:tag->year");
- if(read(fd, tag->year, 4) < 4) goto exit_on_error;
- if(tag->year[0] == 0 || id3_is_only_space(tag->year, 4)) {
- xfree(tag->year);
- tag->year = NULL;
- } else tag->year[4] = 0;
-
- tag->comment = (char*)xmallocd(31, "id3v1_get_tag:tag->comment");
- if(read(fd, tag->comment, 30) < 30) goto exit_on_error;
- tag->comment[30] = 0;
-
- if(read(fd, &(tag->genre), 1) < 1) goto exit_on_error;
-
- /* Looking for v1.1 track info */
- if(tag->comment && tag->comment[28] == 0 && tag->comment[29] != 0)
- {
- tag->track = tag->comment[29];
- tag->comment[29] = 0;
- }
- else
- {
- tag->track = 0;
- }
-
- /* Set comment to NULL if not set - this happens at this point because */
- /* there maybe a track info anyway */
- if(tag->comment[0] == 0 || id3_is_only_space(tag->comment, 28)) {
- xfree(tag->comment);
- tag->comment = NULL;
- }
-
- xfree(c);
- return tag;
-
- exit_on_error:
-
- xfree(c);
- id3v1_free_tag(tag);
- return NULL;
-}
-
-static int
-id3v1_add_tag(int fd, id3v1_tag *tag)
-{
- int i, j;
- void *blank, *set;
- char *b_tag, *b_tag_start;
-
- blank = xmallocd0(30, "id3v1_add_tag:blank");
- set = xmallocd(30, "id3v1_add_tag:set");
- memset(set, 0xFF, 30);
- b_tag = b_tag_start = (char *)xmallocd0(128, "id3v1_add_tag:b_tag");
-
- strncpy(b_tag, "TAG", 3); b_tag += 3;
-
- if(tag->title)
- {
- j = strlen(tag->title);
- strncpy(b_tag, tag->title, j); b_tag += j;
- i = 30 - j;
- if(i > 0)
- {
- strncpy(b_tag, blank, i); b_tag += i;
- }
- }
- else
- {
- strncpy(b_tag, blank, 30); b_tag += 30;
- }
-
- if(tag->artist)
- {
- j = strlen(tag->artist);
- strncpy(b_tag, tag->artist, j); b_tag += j;
- i = 30 - j;
- if(i > 0)
- {
- strncpy(b_tag, blank, i); b_tag += i;
- }
- }
- else
- {
- strncpy(b_tag, blank, 30); b_tag += 30;
- }
-
- if(tag->album)
- {
- j = strlen(tag->album);
- strncpy(b_tag, tag->album, j); b_tag += j;
- i = 30 - j;
- if(i > 0)
- {
- strncpy(b_tag, blank, i); b_tag += i;
- }
- }
- else
- {
- strncpy(b_tag, blank, 30); b_tag += 30;
- }
-
- if(tag->year)
- {
- j = strlen(tag->year);
- strncpy(b_tag, tag->year, j); b_tag += j;
- i = 4 - j;
- if(i > 0)
- {
- strncpy(b_tag, blank, i); b_tag += i;
- }
- }
- else
- {
- strncpy(b_tag, blank, 4); b_tag += 4;
- }
-
- if(tag->comment)
- {
- int hastrack = 0;
- j = strlen(tag->comment);
- if(tag->track > 0) hastrack = 1;
- if(hastrack && j > 28)
- {
- strncpy(b_tag, tag->comment, 28); b_tag += 28;
- }
- else
- {
- strncpy(b_tag, tag->comment, j); b_tag += j;
- i = ((tag->track > 0) ? 28 : 30) - j;
- }
- if(i > 0)
- {
- strncpy(b_tag, blank, i); b_tag += i;
- }
- }
- else
- {
- strncpy(b_tag, blank, (tag->track > 0) ? 28 : 30);
- b_tag += (tag->track > 0) ? 28 : 30;
- }
-
- if(tag->track > 0)
- {
- strncpy(b_tag, blank, 1); b_tag += 1;
- strncpy(b_tag, &(tag->track), 1); b_tag += 1;
- }
- if(tag->genre != 0xFF)
- {
- strncpy(b_tag, &(tag->genre), 1); b_tag += 1;
- }
- else
- {
- strncpy(b_tag, set, 1); b_tag += 1;
- }
-
- j = 0;
-
- if(lseek(fd, 0L, SEEK_END) != -1)
- {
- if(write(fd, b_tag - 128, 128) < 128) j = 1;
- }
- else j = 1;
-
- xfree(b_tag_start);
- xfree(blank);
- xfree(set);
-
- return j;
-}
-
-static int
-id3v2_add_tag(int fd, id3v2_tag *tag, id3v2_tag *old)
-{
- unsigned char *btag, *btag_start;
- unsigned char flag = 0;
- int i, j;
- char *b_tag, *b_tag_start, *d;
- id3v2_frame_list *frame_list;
- id3v2_frame *frame;
-
- /* at first we are going to write the tags raw data into
- the btag byte array */
- btag = btag_start = xmallocd0(tag->header->total_tag_size,
- "id3v2_add_tag:btag");
- strncpy(btag, "ID3", 3); btag += 3;
- *btag = (char)tag->header->version_minor; btag += 1;
- *btag = (char)tag->header->version_revision; btag += 1;
- flag |= ((tag->header->unsyncronization & 1) << 7);
- flag |= ((tag->header->has_extended_header & 1) << 6);
- flag |= ((tag->header->is_experimental & 1) << 5);
- flag |= ((tag->header->has_footer & 1) << 4);
- memcpy(btag, &flag, 1); btag += 1;
-
- if(old)
- {
- i = old->header->total_tag_size - 10;
- if(old->header->has_footer) i -= 10;
- }
- else
- {
- i = tag->header->total_tag_size - 10;
- if(tag->header->has_footer) i -= 10;
- /* add padding to total size we mean to store on disk */
- /* mplib does not use any kind of padding internaly */
-/* i += 1024; */ /* no padding needed for MPIO use */
- }
-
- d = id3_sync32(i);
- btag[0] = d[0];
- btag[1] = d[1];
- btag[2] = d[2];
- btag[3] = d[3];
- xfree(d);
- btag += 4;
-
- if(tag->header->has_extended_header)
- {
- d = id3_sync32(tag->header->extended_header->size);
- btag[0] = d[0];
- btag[1] = d[1];
- btag[2] = d[2];
- btag[3] = d[3];
- xfree(d);
- btag += 4;
-
- *btag = (char)tag->header->extended_header->no_flag_bytes; btag += 1;
- flag = ((tag->header->extended_header->is_update & 1) << 6);
- flag |= ((tag->header->extended_header->crc_data_present & 1) << 5);
- flag |= ((tag->header->extended_header->restrictions & 1) << 4);
- memcpy(btag, &flag, 1); btag += 1;
- if(tag->header->extended_header->is_update)
- {
- btag[0] = 0; btag += 1;
- }
- if(tag->header->extended_header->crc_data_present)
- {
- int length = tag->header->extended_header->crc_data_length ? tag->header->extended_header->crc_data_length : 5;
- *btag = (char)length; btag += 1;
- memcpy(btag, tag->header->extended_header->crc_data, length); btag += 1;
- }
- if(tag->header->extended_header->restrictions)
- {
- int length = tag->header->extended_header->restrictions_data_length ? tag->header->extended_header->restrictions_data_length : 5;
- *btag = (char)length; btag += 1;
- memcpy(btag, tag->header->extended_header->restrictions_data, length); btag += 1;
- }
- }
-
- frame_list = tag->frame_list;
- while(frame_list) {
- int j;
- frame = frame_list->data;
-
- strncpy(btag, frame->frame_id, 4); btag += 4;
- d = id3_sync32(frame->data_size);
- btag[0] = d[0];
- btag[1] = d[1];
- btag[2] = d[2];
- btag[3] = d[3];
- xfree(d);
- btag += 4;
- memcpy(btag, &frame->status_flag, 1); btag += 1;
- memcpy(btag, &frame->format_flag, 1); btag += 1;
-
- memcpy(btag, frame->data, frame->data_size); btag += frame->data_size;
-
- frame_list = frame_list->next;
- }
-
- /* XXX footer not supported yet */
-
- /* if an old tag was provided it is desired to overwrite it */
- /* else this is a brand new tag */
- if(old) {
- FILE *file;
- void *ptr = xmallocd0(old->header->total_tag_size - tag->header->total_tag_size, "id3v2_add_tag:ptr");
- if(!(file = fdopen(fd, "r+b")))
- {
- xfree(ptr);
- goto exit_on_error;
- }
-
- fseek(file, 0, SEEK_SET);
- if(fwrite(btag_start, tag->header->total_tag_size, 1, file) < 1)
- {
- xfree(ptr);
- goto exit_on_error;
- }
-
- /* write padding till end of old tag */
- if(fwrite(ptr, old->header->total_tag_size - tag->header->total_tag_size, 1, file) < 1) {
- xfree(ptr);
- goto exit_on_error;
- }
-
- fflush(file);
- xfree(ptr);
-
- } else {
- FILE *file, *tmp;
- int read;
- void *ptr, *blank;
- unsigned char *c;
-
- ptr = xmallocd(4096, "id3v2_add_tag:ptr");
- blank = xmallocd0(1024, "id3v2_add_tag:blank");
-
- file = fdopen(fd, "r+b");
- tmp = tmpfile();
- if(!(file && tmp))
- {
- fflush(file);
- fclose(tmp);
- xfree(ptr);
- xfree(blank);
- goto exit_on_error;
- }
-
- fseek(file, 0, SEEK_SET);
- fseek(tmp, 0, SEEK_SET);
-
- /* write tag in tmp file */
- fwrite(btag_start, tag->header->total_tag_size, 1, tmp);
-
- /* Write 1024b padding */
- /* no padding needed for MPIO use */
-/* fwrite(blank, 1024, 1, tmp); */
-
- /* write rest of file */
- while(!feof(file))
- {
- read = fread(ptr, 1, 4096, file);
- if(fwrite(ptr, 1, read, tmp) != read && !feof(file))
- {
- fflush(file);
- fclose(tmp);
- xfree(ptr);
- xfree(blank);
- goto exit_on_error;
- }
- }
-
- fflush(tmp);
-
- fseek(file, 0, SEEK_SET);
- fseek(tmp, 0, SEEK_SET);
- while(!feof(tmp))
- {
- read = fread(ptr, 1, 4096, tmp);
- if(fwrite(ptr, 1, read, file) != read && !feof(tmp))
- {
- fflush(file);
- fclose(tmp);
- xfree(ptr);
- xfree(blank);
- goto exit_on_error;
- }
- }
-
- fflush(file);
- fclose(tmp);
-
- xfree(ptr);
- xfree(blank);
- }
-
- xfree(btag_start);
- return 0;
-
- exit_on_error:
- xfree(btag_start);
- return MP_EERROR;
-}
-
-static int
-id3v1_del_tag(int fd)
-{
- int nlength;
- unsigned char *c;
- struct stat fs;
-
- if(fstat(fd, &fs)) return 1;
-
- if(fs.st_size < 128) return 1; /* Hardly a valid mpeg file.. */
-
- c = (char *)xmallocd(3, "id3v1_del_tag:c");
- if(lseek(fd, -128L, SEEK_END) == -1) goto exit_on_error;
- if(read(fd, c, 3) < 3) goto exit_on_error;
- if(strncmp(c, "TAG", 3)) goto exit_on_error;
- xfree(c);
-
- nlength = fs.st_size - 128;
-
- if(ftruncate(fd, nlength)) return 1;
-
- return 0;
-
- exit_on_error:
- xfree(c);
- return 1;
-}
-
-
-static int
-id3v2_del_tag(int fd, id3v2_tag *t)
-{
- unsigned char *c;
- long tag_len, file_len;
- FILE *file, *tmp;
- int read;
- void *ptr;
- id3v2_tag *tfound = NULL;;
-
- if(!t)
- {
- t = id3v2_get_tag(fd);
- if(!t) return 0;
- else tfound = t;
- }
-
- ptr = xmallocd(4096, "id3v2_del_tag:ptr");
-
- tag_len = t->header->total_tag_size;
- file_len = lseek(fd, 0, SEEK_END);
- if(file_len < 1 || tag_len < 1) goto exit_on_error;
-
- /* use os system buffering */
- file = fdopen(fd, "r+b");
- tmp = tmpfile();
- if(!(file && tmp)) goto exit_on_error;
-
- fseek(file, tag_len, SEEK_SET);
- fseek(tmp, 0, SEEK_SET);
- while(!feof(file))
- {
- read = fread(ptr, 1, 4096, file);
- if(fwrite(ptr, 1, read, tmp) != read && !feof(file))
- goto exit_on_error;
- }
-
- fflush(tmp);
-
- fseek(file, 0, SEEK_SET);
- fseek(tmp, 0, SEEK_SET);
- while(!feof(tmp))
- {
- read = fread(ptr, 1, 4096, tmp);
- if(fwrite(ptr, 1, read, file) != read && !feof(tmp))
- goto exit_on_error;
- }
-
- fclose(tmp);
- xfree(ptr);
- if(tfound) id3v2_free_tag(tfound);
- return 0;
-
- exit_on_error:
- fclose(tmp);
- xfree(ptr);
- if(tfound) id3v2_free_tag(tfound);
- return 1;
-}
-
-
-static int
-id3v1_truncate_tag(id3v1_tag *tag)
-{
- int notrunc = 0;
- int len = 0;
- void *ptr;
-
- if(tag->title && (len = strlen(tag->title)) > 30)
- {
- realloc(tag->title, 31);
- tag->title[30] = 0;
- }
-
- if(tag->artist && (len = strlen(tag->artist)) > 30)
- {
- realloc(tag->artist, 31);
- tag->artist[30] = 0;
- }
-
- if(tag->album && (len = strlen(tag->album)) > 30)
- {
- realloc(tag->album, 31);
- tag->album[30] = 0;
- }
-
- if(tag->year && (len = strlen(tag->year)) > 4)
- {
- realloc(tag->title, 5);
- tag->title[4] = 0;
- }
-
- if(tag->comment)
- {
- int max = (tag->track > 0) ? 28 : 30;
- if((len = strlen(tag->comment)) > max)
- {
- realloc(tag->comment, max + 1);
- tag->comment[max] = 0;
- }
- }
-
- return notrunc;
-}
-
-static int
-id3_is_only_space(char *str, int strlen)
-{
- int i = 0;
-
- while(i < strlen)
- {
- if(str[i] != 0x20) return 0;
- i++;
- }
-
- return 1;
-}
-
-static id3v2_tag*
-id3v2_get_tag(int fd)
-{
- unsigned char *c;
- id3v2_header *header;
- id3v2_frame_list *frame_list;
- id3v2_frame *frame;
- id3v2_tag *tag = NULL;
- int i;
-
- if(lseek(fd, 0L, SEEK_SET) == -1) return NULL;
-
- c = (unsigned char*)xmallocd0(1024, "id3v2_get_tag:c");
-
- if(read(fd, c, 10) < 10) goto exit_on_error;
-
- c[10] = 0;
-
- if(strncmp(c, "ID3", 3)) goto exit_on_error;
-
- header = XMALLOCD0(id3v2_header, "id3v2_get_tag:header");
- header->version_minor = c[3];
- header->version_revision = c[4];
- header->flags = c[5];
- header->unsyncronization = (c[5] & 128) >> 7;
- header->has_extended_header = (c[5] & 64) >> 6;
- header->is_experimental = (c[5] & 32) >> 5;
- header->has_footer = (c[5] & 16) >> 4;
-
- header->total_tag_size = id3_unsync32(c, 6) + 10;
- if(header->has_footer) header->total_tag_size += 10;
-
- tag = XMALLOCD0(id3v2_tag, "id3v2_get_tag:tag");
-
- /* check if version is supported */
- if(c[3] != 3 && c[3] != 4)
- {
- xfree(c);
- tag->header = header;
- tag->frame_list = NULL;
- return tag;
- }
-
- frame_list = XMALLOCD0(id3v2_frame_list, "id3v2_get_tag:frame_list");
- frame_list->start = frame_list;
-
- /* assigning header and frame list to tag */
- tag->header = header;
- tag->frame_list = frame_list;
-
- if(header->has_extended_header)
- {
- id3v2_extended_header *xt_header = XMALLOCD0(id3v2_extended_header,
- "id3v2_get_tag:id3v2_extended_header");
-
- header->extended_header = xt_header;
-
- read(fd, c, 4); /* get length of extended header */
- xt_header->size = id3_unsync32(c, 0);
-
- read(fd, c, 1); /* get number of flags */
- xt_header->no_flag_bytes = (c[0] > 0) ? c[0] : 1;
-
- read(fd, c, xt_header->no_flag_bytes); /* get flag bytes */
- xt_header->is_update = (c[0] & 64) >> 6;
- xt_header->crc_data_present = (c[0] & 32) >> 5;
- xt_header->restrictions = (c[0] & 16) >> 4;
-
- /* Flag data */
- if(xt_header->is_update) read(fd, c, 1); /* Data length ind. is 0 -skip */
- if(xt_header->crc_data_present) {
- read(fd, c, 1); /* data length - shoud be 5 */
- if(*c != 5) goto exit_on_error; /* else things might
- break badly */
- xt_header->crc_data_length = *c;
- xt_header->crc_data = xmallocd0(*c, "id3v2_get_tag:xt_header->crc_data");
- read(fd, xt_header->crc_data, *c);
- }
- if(xt_header->restrictions) {
- read(fd, c, 1); /* data length - shoud be 1 */
- if(*c != 1) goto exit_on_error;
- xt_header->restrictions_data_length = *c;
- xt_header->restrictions_data = xmallocd0(*c,
- "id3v2_get_tag:xt_header->restrictions_data");
- read(fd, xt_header->restrictions_data, *c);
- }
- }
-
- /* Read frames */
- while(lseek(fd, 0L, SEEK_CUR) < header->total_tag_size)
- {
- int hasEnc = 0, hasLang = 0, d;
-
- read(fd, c, 10); /* Read header */
-
- /* break if padding is reached - this should never happen here.. */
- if(c[0] == 0 && c[1] == 0 && c[2] == 0 && c[3] == 0) break;
-
- /* Check if possible id is alpha numeric */
- if(!isalnum(c[0]) || !isalnum(c[1]) || !isalnum(c[2]) || !isalnum(c[3])) break;
-
- frame = XMALLOCD(id3v2_frame, "id3v2_get_tag:frame");
- frame->frame_id = xmallocd(4, "id3v2_get_tag:frame->frame_id");
- strncpy(frame->frame_id, c, 4);
- frame->data_size = id3_unsync32(c, 4);
- frame->status_flag = c[8];
- frame->format_flag = c[9];
-
- /* Getting frame content */
- frame->data = xmallocd(frame->data_size, "id3v2_get_tag:frame->data_size");
- read(fd, frame->data, frame->data_size);
-
- /* Add frame to list */
- if(frame_list->data)
- {
- frame_list->next = XMALLOCD(id3v2_frame_list, "id3v2_get_tag:frame_list->next");
- frame_list->next->start = frame_list->start;
- frame_list = frame_list->next;
- frame_list->next = NULL;
- }
- frame_list->data = frame;
- }
-
- xfree(c);
- return tag;
-
- exit_on_error:
-
- xfree(c);
- id3v2_free_tag(tag);
- return NULL;
-}
-
-static char **
-id3v2_get_names(id3v2_tag *tag)
-{
- id3v2_frame *frame;
- id3v2_frame_list *frame_list;
- char **clist;
- int i;
-
- if(!tag->frame_list) return NULL;
-
- frame_list = tag->frame_list;
-
- i = id3_get_no_frames(tag);
- clist = xmallocd(sizeof(char*) * i+1, "id3v2_get_names:clist");
- clist[i] = 0;
-
- for(i = 0; frame_list; i++)
- {
- if(!frame_list->data) continue;
- frame = frame_list->data;
-
- if(!frame->frame_id) continue;
- clist[i] = xmallocd(5, "id3v2_get_names:clist[i]");
- strncpy(clist[i], frame->frame_id, 4);
- clist[i][4] = 0;
- frame_list = frame_list->next;
- }
- return clist;
-}
-
-
-static id3_content*
-id3v1_get_content(id3v1_tag *tag, int field)
-{
- int i;
- char *c;
- id3_content *ret;
-
- switch(field)
- {
- case MP_ARTIST:
- if(!tag->artist)
- {
- errno = MP_EFNF;
- return NULL;
- }
- return mp_assemble_text_content(tag->artist, ISO_8859_1);
-
- case MP_TITLE:
- if(!tag->title)
- {
- errno = MP_EFNF;
- return NULL;
- }
- return mp_assemble_text_content(tag->title, ISO_8859_1);
-
- case MP_ALBUM:
- if(!tag->album)
- {
- errno = MP_EFNF;
- return NULL;
- }
- return mp_assemble_text_content(tag->album, ISO_8859_1);
-
- case MP_YEAR:
- if(!tag->year)
- {
- errno = MP_EFNF;
- return NULL;
- }
- return mp_assemble_text_content(tag->year, ISO_8859_1);
-
- case MP_COMMENT:
- if(!tag->comment)
- {
- errno = MP_EFNF;
- return NULL;
- }
- return mp_assemble_comment_content(tag->comment, NULL, ISO_8859_1, NULL);
-
- case MP_GENRE:
- if(tag->genre < GLL)
- {
- return mp_assemble_text_content(genre_list[tag->genre], ISO_8859_1);
- }
- else
- {
- errno = MP_EFNF;
- return NULL;
- }
-
- case MP_TRACK:
- if(!tag->track)
- {
- errno = MP_EFNF;
- return NULL;
- }
-
- if(tag->track < 10) i = 2;
- else if(tag->track < 100) i = 3;
- else i = 4;
- c = xmallocd(i, "id3v1_get_content:c");
- snprintf(c, i, "%d", tag->track);
- ret = mp_assemble_text_content(c, ISO_8859_1);
- xfree(c);
- return ret;
-
- default:
- errno = MP_EFNF;
- return NULL;
- }
-}
-
-static id3_content*
-id3v2_get_content_at_pos(id3v2_tag *tag, const char *field, int pos)
-{
- id3v2_frame_list *frame_list;
- id3v2_frame *frame;
- int i, found, j;
-
- if(!tag->frame_list || !field)
- {
- errno = MP_EERROR;
- return NULL;
- }
-
- frame_list = tag->frame_list;
-
- for(i = 0, found = 0; frame_list; i++, frame_list = frame_list->next)
- {
- if(!frame_list->data) continue;
- frame = frame_list->data;
-
- if(!frame->frame_id || !frame->data) continue;
- if(strncmp(frame->frame_id, field, 4)) continue;
-
- if(found == pos)
- {
- id3_content *ret = XMALLOCD0(id3_content,
- "id3v2_get_content_at_pos:ret");
- if(frame_is_compressed(frame)) ret->compressed = 1;
- else ret->compressed = 0;
-
- if(frame_is_encrypted(frame)) ret->encrypted = 1;
- else ret->encrypted = 0;
-
- ret->length = frame->data_size;
- ret->data = xmallocd(frame->data_size, "id3v2_get_content_at_pos:ret->data");
- ret->data = memcpy(ret->data, frame->data, frame->data_size);
-
- return ret;
- }
-
- found++;
- }
-
- errno = MP_EFNF;
- return NULL;
-}
-
-static long
-id3_sync(unsigned char* data, long length)
-{
- int i;
-
- for(i = 0; i < length - 1; i++)
- {
- if(((data[i] & 0xFF) == 0xFF && (data[i+1] & 0xE0) == 0xE0) ||
- (i+2 < length && (data[i] & 0xFF) == 0xFF && data[i+1] == 0 && data[i+2] != 0))
- {
-
- realloc(data, length + 1); length++;
- memmove(data + i+2, data + i+1, length - i - 2);
- memset(data + i+1, 0, 1);
- }
- }
-
- return length;
-}
-
-static long
-id3_unsync(unsigned char* data, long length)
-{
- /* TODO */
- /* this function is supposed to make syncsafe values normal again */
- /* we don't need this yet, because there are no fields supported that will */
- /* have the unsynchronization scheme applied */
-
-
-}
-
-static unsigned int
-id3_unsync32(unsigned char* c, int start)
-{
- return c[start+3] + (c[start+2] << 7) + (c[start+1] << 14) + (c[start] << 21);
-}
-
-int
-id3_get_no_frames(id3v2_tag *tag)
-{
- int i;
- id3v2_frame_list *frame_list = tag->frame_list;
-
- for(i = 0; frame_list; i++)
- frame_list = frame_list->next;
-
- return i;
-}
-
-static unsigned char *
-id3_sync32(unsigned int i)
-{
- unsigned char *c = (unsigned char *)xmallocd0(4, "id3_sync32:c");
-
- c[3] = (i & 0x7f);
- c[2] = ((i & 0x80) >> 7) | (((i & 0x7f00) >> 8) << 1);
- c[1] = ((i & 0x8000) >> 15) | (((i & 0x7f0000) >> 16) << 1);
- c[0] = ((i & 0x800000) >> 23) | (((i & 0x7f000000) >> 24) << 1);
-
- return c;
-}
-
-id3v2_frame*
-id3_lookup_frame(id3v2_frame_list *list, const char *field, const int pos)
-{
- int cur = 0;
-
- if(!list || !field) return NULL;
-
- do
- {
- if(!strcmp(list->data->frame_id, field))
- {
- if(cur == pos) return list->data;
- cur++;
- }
- } while((list = list->next));
-
- return NULL;
-}
-
-int
-id3_remove_frame(id3v2_frame_list *list, id3v2_frame *frame)
-{
- if(!list || !frame) return MP_EERROR;
-
- /* Frame is first element in list */
- if(list->data == frame)
- {
- xfree(list->data);
- list->next->start = list->next;
- xfree(list);
- return 0;
- }
-
- /* Iterate through others */
- do
- {
- if(list->next->data == frame)
- {
- list->next = list->next->next;
- xfree(frame);
- return 0;
- }
- } while((list = list->next));
-
- return 1;
-}
-
-
-int
-id3_add_frame(id3v2_frame_list *list, char *field, char *new_value, int len)
-{
- id3v2_frame *frame;
- char *new_valuecp;
- long len_sync;
-
- if(!list || !new_value || !field || strlen(field) != 4) return MP_EERROR;
-
- // make a copy of the given value to include it in the frame
- new_valuecp = xmallocd(len,
- "id3_add_frame:new_valuecp");
- memcpy(new_valuecp, new_value, len);
- new_value = new_valuecp;
-
- /* make sync safe */
-/* len_sync = id3_sync(new_value, len); */
- len_sync = len; /* disabled sync for MPIO use */
-
- frame = XMALLOCD(id3v2_frame, "id3_add_frame:frame");
- frame->frame_id = xmallocd(4, "id3_add_frame:frame->frame_id");
- strncpy(frame->frame_id, field, 4);
- frame->data = new_value;
- frame->status_flag = 0;
-
- if(len != len_sync) frame->format_flag = 64;
- else frame->format_flag = 0;
- frame->data_size = len_sync;
-
- /* Empty list */
- if(!list->data)
- {
- list->data = frame;
- return 0;
- }
-
- /* iterate to last element */
- while(list->next) list = list->next;
-
- list->next = XMALLOCD(id3v2_frame_list, "id3_add_frame:list->next");
- list->next->start = list->start;
- list = list->next;
- list->next = NULL;
- list->data = frame;
-
- return 0;
-}
-
-
-#define BUF_SIZE 4096
-
-static int
-id3_lseek_syncword(int fd)
-{
- unsigned char *data = (unsigned char*) xmallocd(BUF_SIZE, "id3_lseek_syncword:data");
- int ret;
-
- // Reset the reading offset of the fd
- lseek(fd, SEEK_SET, 0);
-
- if(read(fd, data, BUF_SIZE) < 1)
- {
- xfree(data);
- return 0; /* return false on EOF */
- }
-
- ret = id3_lseek_syncword_r(fd, data, 0);
- xfree(data);
- return ret;
-}
-
-static int
-id3_lseek_syncword_r(int fd, unsigned char *data, int checked)
-{
- unsigned char lastchar;
- int i;
-
- for(i = 0; i + 1 < BUF_SIZE; i++)
- {
- if(((data[i] & 0xFF)== 0xFF) && ((data[i+1] & 0xE0)== 0xE0))
- {
- lseek(fd, checked + i, SEEK_SET);
- return 0;
- }
- }
-
- lastchar = data[BUF_SIZE - 1];
-
- if(read(fd, data, BUF_SIZE) < 1) return 0; /* return false on EOF */
-
- if(((lastchar & 0xFF)== 0xFF) && ((data[0] & 0xE0)== 0xE0))
- {
- lseek(fd, checked + BUF_SIZE - 1, SEEK_SET);
- return 0;
- }
-
- return id3_lseek_syncword_r(fd, data, checked + BUF_SIZE);
-}
-
-static id3_tag*
-id3v1_alloc_tag(void)
-{
- id3_tag *tag = XMALLOCD(id3_tag, "id3v1_alloc_tag:tag");
- id3v1_tag *v1 = XMALLOCD0(id3v1_tag, "id3v1_alloc_tag:v1");
-
- tag->tag = v1;
- tag->version = 1;
-
- v1->genre = 0xFF;
-
- return tag;
-}
-
-static id3_tag*
-id3v2_alloc_tag(void)
-{
- id3_tag *tag = XMALLOCD(id3_tag, "id3v2_alloc_tag:tag");
- id3v2_tag *v2 = XMALLOCD0(id3v2_tag, "id3v2_alloc_tag:v2");
-
- tag->tag = v2;
- tag->version = 2;
-
- return tag;
-}
-
-static void
-id3v1_free_tag(id3v1_tag* v1)
-{
- xfree(v1->artist);
- xfree(v1->album);
- xfree(v1->title);
- xfree(v1->year);
- xfree(v1->comment);
- xfree(v1);
-}
-
-static void
-id3v2_free_tag(id3v2_tag* v2)
-{
- id3v2_frame_list* doomed;
- id3v2_frame *frame;
-
- if(!v2) return;
-
- xfree(v2->header->extended_header);
- xfree(v2->header);
-
- if(!v2->frame_list)
- {
- xfree(v2);
- return;
- }
-
- /* Freeing frames */
- do
- {
- frame = (id3v2_frame*)v2->frame_list->data;
- if(frame->frame_id) xfree(frame->frame_id);
- if(frame->data) xfree(frame->data);
- xfree(v2->frame_list->data);
-
- doomed = v2->frame_list->next;
- xfree(v2->frame_list);
-
- } while((v2->frame_list = doomed));
-
- xfree(v2);
-}