comparison src/libid3tag/util.c @ 2503:10692383c103 trunk

[svn] first try for libid3tag integration. this improved libid3tag supports vfs operations and is capable of adding id3v2 tag to files which doesn't have id3v2 tag ever.
author yaz
date Sun, 11 Feb 2007 05:19:07 -0800
parents
children
comparison
equal deleted inserted replaced
2502:b7be0af74307 2503:10692383c103
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 */
38 id3_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 */
73 id3_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 */
96 id3_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 */
128 id3_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 }