1/* 2 * libid3tag - ID3 tag manipulation library 3 * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 19 * $Id: util.c,v 1.9 2004/01/23 09:41:32 rob Exp $ 20 */ 21 22# ifdef HAVE_CONFIG_H 23# include "config.h" 24# endif 25 26# include "global.h" 27 28# include <stdlib.h> 29# include <zlib.h> 30 31# include "id3tag.h" 32# include "util.h" 33 34/* 35 * NAME: util->unsynchronise() 36 * DESCRIPTION: perform (in-place) unsynchronisation 37 */ 38id3_length_t id3_util_unsynchronise(id3_byte_t *data, id3_length_t length) 39{ 40 id3_length_t bytes = 0, count; 41 id3_byte_t *end = data + length; 42 id3_byte_t const *ptr; 43 44 if (length == 0) 45 return 0; 46 47 for (ptr = data; ptr < end - 1; ++ptr) { 48 if (ptr[0] == 0xff && (ptr[1] == 0x00 || (ptr[1] & 0xe0) == 0xe0)) 49 ++bytes; 50 } 51 52 if (bytes) { 53 ptr = end; 54 end += bytes; 55 56 *--end = *--ptr; 57 58 for (count = bytes; count; *--end = *--ptr) { 59 if (ptr[-1] == 0xff && (ptr[0] == 0x00 || (ptr[0] & 0xe0) == 0xe0)) { 60 *--end = 0x00; 61 --count; 62 } 63 } 64 } 65 66 return length + bytes; 67} 68 69/* 70 * NAME: util->deunsynchronise() 71 * DESCRIPTION: undo unsynchronisation (in-place) 72 */ 73id3_length_t id3_util_deunsynchronise(id3_byte_t *data, id3_length_t length) 74{ 75 id3_byte_t const *old, *end = data + length; 76 id3_byte_t *new; 77 78 if (length == 0) 79 return 0; 80 81 for (old = new = data; old < end - 1; ++old) { 82 *new++ = *old; 83 if (old[0] == 0xff && old[1] == 0x00) 84 ++old; 85 } 86 87 *new++ = *old; 88 89 return new - data; 90} 91 92/* 93 * NAME: util->compress() 94 * DESCRIPTION: perform zlib deflate method compression 95 */ 96id3_byte_t *id3_util_compress(id3_byte_t const *data, id3_length_t length, 97 id3_length_t *newlength) 98{ 99 id3_byte_t *compressed; 100 101 *newlength = length + 12; 102 *newlength += *newlength / 1000; 103 104 compressed = malloc(*newlength); 105 if (compressed) { 106 if (compress2(compressed, newlength, data, length, 107 Z_BEST_COMPRESSION) != Z_OK || 108 *newlength >= length) { 109 free(compressed); 110 compressed = 0; 111 } 112 else { 113 id3_byte_t *resized; 114 115 resized = realloc(compressed, *newlength ? *newlength : 1); 116 if (resized) 117 compressed = resized; 118 } 119 } 120 121 return compressed; 122} 123 124/* 125 * NAME: util->decompress() 126 * DESCRIPTION: undo zlib deflate method compression 127 */ 128id3_byte_t *id3_util_decompress(id3_byte_t const *data, id3_length_t length, 129 id3_length_t newlength) 130{ 131 id3_byte_t *decompressed; 132 133 decompressed = malloc(newlength ? newlength : 1); 134 if (decompressed) { 135 id3_length_t size; 136 137 size = newlength; 138 139 if (uncompress(decompressed, &size, data, length) != Z_OK || 140 size != newlength) { 141 free(decompressed); 142 decompressed = 0; 143 } 144 } 145 146 return decompressed; 147} 148