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