Chris@0: /* Chris@0: * libid3tag - ID3 tag manipulation library Chris@0: * Copyright (C) 2000-2004 Underbit Technologies, Inc. Chris@0: * Chris@0: * This program is free software; you can redistribute it and/or modify Chris@0: * it under the terms of the GNU General Public License as published by Chris@0: * the Free Software Foundation; either version 2 of the License, or Chris@0: * (at your option) any later version. Chris@0: * Chris@0: * This program is distributed in the hope that it will be useful, Chris@0: * but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@0: * GNU General Public License for more details. Chris@0: * Chris@0: * You should have received a copy of the GNU General Public License Chris@0: * along with this program; if not, write to the Free Software Chris@0: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Chris@0: * Chris@0: * $Id: util.c,v 1.9 2004/01/23 09:41:32 rob Exp $ Chris@0: */ Chris@0: Chris@0: # ifdef HAVE_CONFIG_H Chris@0: # include "config.h" Chris@0: # endif Chris@0: Chris@0: # include "global.h" Chris@0: Chris@0: # include Chris@0: # include Chris@0: Chris@0: # include "id3tag.h" Chris@0: # include "util.h" Chris@0: Chris@0: /* Chris@0: * NAME: util->unsynchronise() Chris@0: * DESCRIPTION: perform (in-place) unsynchronisation Chris@0: */ Chris@0: id3_length_t id3_util_unsynchronise(id3_byte_t *data, id3_length_t length) Chris@0: { Chris@0: id3_length_t bytes = 0, count; Chris@0: id3_byte_t *end = data + length; Chris@0: id3_byte_t const *ptr; Chris@0: Chris@0: if (length == 0) Chris@0: return 0; Chris@0: Chris@0: for (ptr = data; ptr < end - 1; ++ptr) { Chris@0: if (ptr[0] == 0xff && (ptr[1] == 0x00 || (ptr[1] & 0xe0) == 0xe0)) Chris@0: ++bytes; Chris@0: } Chris@0: Chris@0: if (bytes) { Chris@0: ptr = end; Chris@0: end += bytes; Chris@0: Chris@0: *--end = *--ptr; Chris@0: Chris@0: for (count = bytes; count; *--end = *--ptr) { Chris@0: if (ptr[-1] == 0xff && (ptr[0] == 0x00 || (ptr[0] & 0xe0) == 0xe0)) { Chris@0: *--end = 0x00; Chris@0: --count; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: return length + bytes; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: util->deunsynchronise() Chris@0: * DESCRIPTION: undo unsynchronisation (in-place) Chris@0: */ Chris@0: id3_length_t id3_util_deunsynchronise(id3_byte_t *data, id3_length_t length) Chris@0: { Chris@0: id3_byte_t const *old, *end = data + length; Chris@0: id3_byte_t *new; Chris@0: Chris@0: if (length == 0) Chris@0: return 0; Chris@0: Chris@0: for (old = new = data; old < end - 1; ++old) { Chris@0: *new++ = *old; Chris@0: if (old[0] == 0xff && old[1] == 0x00) Chris@0: ++old; Chris@0: } Chris@0: Chris@0: *new++ = *old; Chris@0: Chris@0: return new - data; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: util->compress() Chris@0: * DESCRIPTION: perform zlib deflate method compression Chris@0: */ Chris@0: id3_byte_t *id3_util_compress(id3_byte_t const *data, id3_length_t length, Chris@0: id3_length_t *newlength) Chris@0: { Chris@0: id3_byte_t *compressed; Chris@0: Chris@0: *newlength = length + 12; Chris@0: *newlength += *newlength / 1000; Chris@0: Chris@0: compressed = malloc(*newlength); Chris@0: if (compressed) { Chris@0: if (compress2(compressed, newlength, data, length, Chris@0: Z_BEST_COMPRESSION) != Z_OK || Chris@0: *newlength >= length) { Chris@0: free(compressed); Chris@0: compressed = 0; Chris@0: } Chris@0: else { Chris@0: id3_byte_t *resized; Chris@0: Chris@0: resized = realloc(compressed, *newlength ? *newlength : 1); Chris@0: if (resized) Chris@0: compressed = resized; Chris@0: } Chris@0: } Chris@0: Chris@0: return compressed; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: util->decompress() Chris@0: * DESCRIPTION: undo zlib deflate method compression Chris@0: */ Chris@0: id3_byte_t *id3_util_decompress(id3_byte_t const *data, id3_length_t length, Chris@0: id3_length_t newlength) Chris@0: { Chris@0: id3_byte_t *decompressed; Chris@0: Chris@0: decompressed = malloc(newlength ? newlength : 1); Chris@0: if (decompressed) { Chris@0: id3_length_t size; Chris@0: Chris@0: size = newlength; Chris@0: Chris@0: if (uncompress(decompressed, &size, data, length) != Z_OK || Chris@0: size != newlength) { Chris@0: free(decompressed); Chris@0: decompressed = 0; Chris@0: } Chris@0: } Chris@0: Chris@0: return decompressed; Chris@0: }