Mercurial > sdl-ios-xcode
annotate src/audio/SDL_audiocvt.c @ 261:1c5f68da5fc2
*** empty log message ***
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 04 Jan 2002 20:48:51 +0000 |
parents | e8157fcb3114 |
children | f6ffac90895c |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library 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 GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Functions for audio drivers to perform runtime conversion of audio format */ | |
29 | |
30 #include <stdio.h> | |
31 | |
32 #include "SDL_error.h" | |
33 #include "SDL_audio.h" | |
34 | |
35 | |
36 /* Effectively mix right and left channels into a single channel */ | |
37 void SDL_ConvertMono(SDL_AudioCVT *cvt, Uint16 format) | |
38 { | |
39 int i; | |
40 Sint32 sample; | |
41 | |
42 #ifdef DEBUG_CONVERT | |
43 fprintf(stderr, "Converting to mono\n"); | |
44 #endif | |
45 switch (format&0x8018) { | |
46 | |
47 case AUDIO_U8: { | |
48 Uint8 *src, *dst; | |
49 | |
50 src = cvt->buf; | |
51 dst = cvt->buf; | |
52 for ( i=cvt->len_cvt/2; i; --i ) { | |
53 sample = src[0] + src[1]; | |
54 if ( sample > 255 ) { | |
55 *dst = 255; | |
56 } else { | |
57 *dst = sample; | |
58 } | |
59 src += 2; | |
60 dst += 1; | |
61 } | |
62 } | |
63 break; | |
64 | |
65 case AUDIO_S8: { | |
66 Sint8 *src, *dst; | |
67 | |
68 src = (Sint8 *)cvt->buf; | |
69 dst = (Sint8 *)cvt->buf; | |
70 for ( i=cvt->len_cvt/2; i; --i ) { | |
71 sample = src[0] + src[1]; | |
72 if ( sample > 127 ) { | |
73 *dst = 127; | |
74 } else | |
75 if ( sample < -128 ) { | |
76 *dst = -128; | |
77 } else { | |
78 *dst = sample; | |
79 } | |
80 src += 2; | |
81 dst += 1; | |
82 } | |
83 } | |
84 break; | |
85 | |
86 case AUDIO_U16: { | |
87 Uint8 *src, *dst; | |
88 | |
89 src = cvt->buf; | |
90 dst = cvt->buf; | |
91 if ( (format & 0x1000) == 0x1000 ) { | |
92 for ( i=cvt->len_cvt/4; i; --i ) { | |
93 sample = (Uint16)((src[0]<<8)|src[1])+ | |
94 (Uint16)((src[2]<<8)|src[3]); | |
95 if ( sample > 65535 ) { | |
96 dst[0] = 0xFF; | |
97 dst[1] = 0xFF; | |
98 } else { | |
99 dst[1] = (sample&0xFF); | |
100 sample >>= 8; | |
101 dst[0] = (sample&0xFF); | |
102 } | |
103 src += 4; | |
104 dst += 2; | |
105 } | |
106 } else { | |
107 for ( i=cvt->len_cvt/4; i; --i ) { | |
108 sample = (Uint16)((src[1]<<8)|src[0])+ | |
109 (Uint16)((src[3]<<8)|src[2]); | |
110 if ( sample > 65535 ) { | |
111 dst[0] = 0xFF; | |
112 dst[1] = 0xFF; | |
113 } else { | |
114 dst[0] = (sample&0xFF); | |
115 sample >>= 8; | |
116 dst[1] = (sample&0xFF); | |
117 } | |
118 src += 4; | |
119 dst += 2; | |
120 } | |
121 } | |
122 } | |
123 break; | |
124 | |
125 case AUDIO_S16: { | |
126 Uint8 *src, *dst; | |
127 | |
128 src = cvt->buf; | |
129 dst = cvt->buf; | |
130 if ( (format & 0x1000) == 0x1000 ) { | |
131 for ( i=cvt->len_cvt/4; i; --i ) { | |
132 sample = (Sint16)((src[0]<<8)|src[1])+ | |
133 (Sint16)((src[2]<<8)|src[3]); | |
134 if ( sample > 32767 ) { | |
135 dst[0] = 0x7F; | |
136 dst[1] = 0xFF; | |
137 } else | |
138 if ( sample < -32768 ) { | |
139 dst[0] = 0x80; | |
140 dst[1] = 0x00; | |
141 } else { | |
142 dst[1] = (sample&0xFF); | |
143 sample >>= 8; | |
144 dst[0] = (sample&0xFF); | |
145 } | |
146 src += 4; | |
147 dst += 2; | |
148 } | |
149 } else { | |
150 for ( i=cvt->len_cvt/4; i; --i ) { | |
151 sample = (Sint16)((src[1]<<8)|src[0])+ | |
152 (Sint16)((src[3]<<8)|src[2]); | |
153 if ( sample > 32767 ) { | |
154 dst[1] = 0x7F; | |
155 dst[0] = 0xFF; | |
156 } else | |
157 if ( sample < -32768 ) { | |
158 dst[1] = 0x80; | |
159 dst[0] = 0x00; | |
160 } else { | |
161 dst[0] = (sample&0xFF); | |
162 sample >>= 8; | |
163 dst[1] = (sample&0xFF); | |
164 } | |
165 src += 4; | |
166 dst += 2; | |
167 } | |
168 } | |
169 } | |
170 break; | |
171 } | |
172 cvt->len_cvt /= 2; | |
173 if ( cvt->filters[++cvt->filter_index] ) { | |
174 cvt->filters[cvt->filter_index](cvt, format); | |
175 } | |
176 } | |
177 | |
178 | |
179 /* Duplicate a mono channel to both stereo channels */ | |
180 void SDL_ConvertStereo(SDL_AudioCVT *cvt, Uint16 format) | |
181 { | |
182 int i; | |
183 | |
184 #ifdef DEBUG_CONVERT | |
185 fprintf(stderr, "Converting to stereo\n"); | |
186 #endif | |
187 if ( (format & 0xFF) == 16 ) { | |
188 Uint16 *src, *dst; | |
189 | |
190 src = (Uint16 *)(cvt->buf+cvt->len_cvt); | |
191 dst = (Uint16 *)(cvt->buf+cvt->len_cvt*2); | |
192 for ( i=cvt->len_cvt/2; i; --i ) { | |
193 dst -= 2; | |
194 src -= 1; | |
195 dst[0] = src[0]; | |
196 dst[1] = src[0]; | |
197 } | |
198 } else { | |
199 Uint8 *src, *dst; | |
200 | |
201 src = cvt->buf+cvt->len_cvt; | |
202 dst = cvt->buf+cvt->len_cvt*2; | |
203 for ( i=cvt->len_cvt; i; --i ) { | |
204 dst -= 2; | |
205 src -= 1; | |
206 dst[0] = src[0]; | |
207 dst[1] = src[0]; | |
208 } | |
209 } | |
210 cvt->len_cvt *= 2; | |
211 if ( cvt->filters[++cvt->filter_index] ) { | |
212 cvt->filters[cvt->filter_index](cvt, format); | |
213 } | |
214 } | |
215 | |
216 /* Convert 8-bit to 16-bit - LSB */ | |
217 void SDL_Convert16LSB(SDL_AudioCVT *cvt, Uint16 format) | |
218 { | |
219 int i; | |
220 Uint8 *src, *dst; | |
221 | |
222 #ifdef DEBUG_CONVERT | |
223 fprintf(stderr, "Converting to 16-bit LSB\n"); | |
224 #endif | |
225 src = cvt->buf+cvt->len_cvt; | |
226 dst = cvt->buf+cvt->len_cvt*2; | |
227 for ( i=cvt->len_cvt; i; --i ) { | |
228 src -= 1; | |
229 dst -= 2; | |
230 dst[1] = *src; | |
231 dst[0] = 0; | |
232 } | |
233 format = ((format & ~0x0008) | AUDIO_U16LSB); | |
234 cvt->len_cvt *= 2; | |
235 if ( cvt->filters[++cvt->filter_index] ) { | |
236 cvt->filters[cvt->filter_index](cvt, format); | |
237 } | |
238 } | |
239 /* Convert 8-bit to 16-bit - MSB */ | |
240 void SDL_Convert16MSB(SDL_AudioCVT *cvt, Uint16 format) | |
241 { | |
242 int i; | |
243 Uint8 *src, *dst; | |
244 | |
245 #ifdef DEBUG_CONVERT | |
246 fprintf(stderr, "Converting to 16-bit MSB\n"); | |
247 #endif | |
248 src = cvt->buf+cvt->len_cvt; | |
249 dst = cvt->buf+cvt->len_cvt*2; | |
250 for ( i=cvt->len_cvt; i; --i ) { | |
251 src -= 1; | |
252 dst -= 2; | |
253 dst[0] = *src; | |
254 dst[1] = 0; | |
255 } | |
256 format = ((format & ~0x0008) | AUDIO_U16MSB); | |
257 cvt->len_cvt *= 2; | |
258 if ( cvt->filters[++cvt->filter_index] ) { | |
259 cvt->filters[cvt->filter_index](cvt, format); | |
260 } | |
261 } | |
262 | |
263 /* Convert 16-bit to 8-bit */ | |
264 void SDL_Convert8(SDL_AudioCVT *cvt, Uint16 format) | |
265 { | |
266 int i; | |
267 Uint8 *src, *dst; | |
268 | |
269 #ifdef DEBUG_CONVERT | |
270 fprintf(stderr, "Converting to 8-bit\n"); | |
271 #endif | |
272 src = cvt->buf; | |
273 dst = cvt->buf; | |
274 if ( (format & 0x1000) != 0x1000 ) { /* Little endian */ | |
275 ++src; | |
276 } | |
277 for ( i=cvt->len_cvt/2; i; --i ) { | |
278 *dst = *src; | |
279 src += 2; | |
280 dst += 1; | |
281 } | |
282 format = ((format & ~0x9010) | AUDIO_U8); | |
283 cvt->len_cvt /= 2; | |
284 if ( cvt->filters[++cvt->filter_index] ) { | |
285 cvt->filters[cvt->filter_index](cvt, format); | |
286 } | |
287 } | |
288 | |
289 /* Toggle signed/unsigned */ | |
290 void SDL_ConvertSign(SDL_AudioCVT *cvt, Uint16 format) | |
291 { | |
292 int i; | |
293 Uint8 *data; | |
294 | |
295 #ifdef DEBUG_CONVERT | |
296 fprintf(stderr, "Converting audio signedness\n"); | |
297 #endif | |
298 data = cvt->buf; | |
299 if ( (format & 0xFF) == 16 ) { | |
300 if ( (format & 0x1000) != 0x1000 ) { /* Little endian */ | |
301 ++data; | |
302 } | |
303 for ( i=cvt->len_cvt/2; i; --i ) { | |
304 *data ^= 0x80; | |
305 data += 2; | |
306 } | |
307 } else { | |
308 for ( i=cvt->len_cvt; i; --i ) { | |
309 *data++ ^= 0x80; | |
310 } | |
311 } | |
312 format = (format ^ 0x8000); | |
313 if ( cvt->filters[++cvt->filter_index] ) { | |
314 cvt->filters[cvt->filter_index](cvt, format); | |
315 } | |
316 } | |
317 | |
318 /* Toggle endianness */ | |
319 void SDL_ConvertEndian(SDL_AudioCVT *cvt, Uint16 format) | |
320 { | |
321 int i; | |
322 Uint8 *data, tmp; | |
323 | |
324 #ifdef DEBUG_CONVERT | |
325 fprintf(stderr, "Converting audio endianness\n"); | |
326 #endif | |
327 data = cvt->buf; | |
328 for ( i=cvt->len_cvt/2; i; --i ) { | |
329 tmp = data[0]; | |
330 data[0] = data[1]; | |
331 data[1] = tmp; | |
332 data += 2; | |
333 } | |
334 format = (format ^ 0x1000); | |
335 if ( cvt->filters[++cvt->filter_index] ) { | |
336 cvt->filters[cvt->filter_index](cvt, format); | |
337 } | |
338 } | |
339 | |
340 /* Convert rate up by multiple of 2 */ | |
341 void SDL_RateMUL2(SDL_AudioCVT *cvt, Uint16 format) | |
342 { | |
343 int i; | |
344 Uint8 *src, *dst; | |
345 | |
346 #ifdef DEBUG_CONVERT | |
347 fprintf(stderr, "Converting audio rate * 2\n"); | |
348 #endif | |
349 src = cvt->buf+cvt->len_cvt; | |
350 dst = cvt->buf+cvt->len_cvt*2; | |
351 switch (format & 0xFF) { | |
352 case 8: | |
353 for ( i=cvt->len_cvt; i; --i ) { | |
354 src -= 1; | |
355 dst -= 2; | |
356 dst[0] = src[0]; | |
357 dst[1] = src[0]; | |
358 } | |
359 break; | |
360 case 16: | |
361 for ( i=cvt->len_cvt/2; i; --i ) { | |
362 src -= 2; | |
363 dst -= 4; | |
364 dst[0] = src[0]; | |
365 dst[1] = src[1]; | |
366 dst[2] = src[0]; | |
367 dst[3] = src[1]; | |
368 } | |
369 break; | |
370 } | |
371 cvt->len_cvt *= 2; | |
372 if ( cvt->filters[++cvt->filter_index] ) { | |
373 cvt->filters[cvt->filter_index](cvt, format); | |
374 } | |
375 } | |
376 | |
377 /* Convert rate down by multiple of 2 */ | |
378 void SDL_RateDIV2(SDL_AudioCVT *cvt, Uint16 format) | |
379 { | |
380 int i; | |
381 Uint8 *src, *dst; | |
382 | |
383 #ifdef DEBUG_CONVERT | |
384 fprintf(stderr, "Converting audio rate / 2\n"); | |
385 #endif | |
386 src = cvt->buf; | |
387 dst = cvt->buf; | |
388 switch (format & 0xFF) { | |
389 case 8: | |
390 for ( i=cvt->len_cvt/2; i; --i ) { | |
391 dst[0] = src[0]; | |
392 src += 2; | |
393 dst += 1; | |
394 } | |
395 break; | |
396 case 16: | |
397 for ( i=cvt->len_cvt/4; i; --i ) { | |
398 dst[0] = src[0]; | |
399 dst[1] = src[1]; | |
400 src += 4; | |
401 dst += 2; | |
402 } | |
403 break; | |
404 } | |
405 cvt->len_cvt /= 2; | |
406 if ( cvt->filters[++cvt->filter_index] ) { | |
407 cvt->filters[cvt->filter_index](cvt, format); | |
408 } | |
409 } | |
410 | |
411 /* Very slow rate conversion routine */ | |
412 void SDL_RateSLOW(SDL_AudioCVT *cvt, Uint16 format) | |
413 { | |
414 double ipos; | |
415 int i, clen; | |
416 | |
417 #ifdef DEBUG_CONVERT | |
418 fprintf(stderr, "Converting audio rate * %4.4f\n", 1.0/cvt->rate_incr); | |
419 #endif | |
420 clen = (int)((double)cvt->len_cvt / cvt->rate_incr); | |
421 if ( cvt->rate_incr > 1.0 ) { | |
422 switch (format & 0xFF) { | |
423 case 8: { | |
424 Uint8 *output; | |
425 | |
426 output = cvt->buf; | |
427 ipos = 0.0; | |
428 for ( i=clen; i; --i ) { | |
429 *output = cvt->buf[(int)ipos]; | |
430 ipos += cvt->rate_incr; | |
431 output += 1; | |
432 } | |
433 } | |
434 break; | |
435 | |
436 case 16: { | |
437 Uint16 *output; | |
438 | |
439 clen &= ~1; | |
440 output = (Uint16 *)cvt->buf; | |
441 ipos = 0.0; | |
442 for ( i=clen/2; i; --i ) { | |
443 *output=((Uint16 *)cvt->buf)[(int)ipos]; | |
444 ipos += cvt->rate_incr; | |
445 output += 1; | |
446 } | |
447 } | |
448 break; | |
449 } | |
450 } else { | |
451 switch (format & 0xFF) { | |
452 case 8: { | |
453 Uint8 *output; | |
454 | |
455 output = cvt->buf+clen; | |
456 ipos = (double)cvt->len_cvt; | |
457 for ( i=clen; i; --i ) { | |
458 ipos -= cvt->rate_incr; | |
459 output -= 1; | |
460 *output = cvt->buf[(int)ipos]; | |
461 } | |
462 } | |
463 break; | |
464 | |
465 case 16: { | |
466 Uint16 *output; | |
467 | |
468 clen &= ~1; | |
469 output = (Uint16 *)(cvt->buf+clen); | |
470 ipos = (double)cvt->len_cvt/2; | |
471 for ( i=clen/2; i; --i ) { | |
472 ipos -= cvt->rate_incr; | |
473 output -= 1; | |
474 *output=((Uint16 *)cvt->buf)[(int)ipos]; | |
475 } | |
476 } | |
477 break; | |
478 } | |
479 } | |
480 cvt->len_cvt = clen; | |
481 if ( cvt->filters[++cvt->filter_index] ) { | |
482 cvt->filters[cvt->filter_index](cvt, format); | |
483 } | |
484 } | |
485 | |
486 int SDL_ConvertAudio(SDL_AudioCVT *cvt) | |
487 { | |
488 /* Make sure there's data to convert */ | |
489 if ( cvt->buf == NULL ) { | |
490 SDL_SetError("No buffer allocated for conversion"); | |
491 return(-1); | |
492 } | |
493 /* Return okay if no conversion is necessary */ | |
494 cvt->len_cvt = cvt->len; | |
495 if ( cvt->filters[0] == NULL ) { | |
496 return(0); | |
497 } | |
498 | |
499 /* Set up the conversion and go! */ | |
500 cvt->filter_index = 0; | |
501 cvt->filters[0](cvt, cvt->src_format); | |
502 return(0); | |
503 } | |
504 | |
505 /* Creates a set of audio filters to convert from one format to another. | |
506 Returns -1 if the format conversion is not supported, or 1 if the | |
507 audio filter is set up. | |
508 */ | |
509 | |
510 int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, | |
511 Uint16 src_format, Uint8 src_channels, int src_rate, | |
512 Uint16 dst_format, Uint8 dst_channels, int dst_rate) | |
513 { | |
514 /* Start off with no conversion necessary */ | |
515 cvt->needed = 0; | |
516 cvt->filter_index = 0; | |
517 cvt->filters[0] = NULL; | |
518 cvt->len_mult = 1; | |
519 cvt->len_ratio = 1.0; | |
520 | |
521 /* First filter: Endian conversion from src to dst */ | |
522 if ( (src_format & 0x1000) != (dst_format & 0x1000) | |
523 && ((src_format & 0xff) != 8) ) { | |
524 cvt->filters[cvt->filter_index++] = SDL_ConvertEndian; | |
525 } | |
526 | |
527 /* Second filter: Sign conversion -- signed/unsigned */ | |
528 if ( (src_format & 0x8000) != (dst_format & 0x8000) ) { | |
529 cvt->filters[cvt->filter_index++] = SDL_ConvertSign; | |
530 } | |
531 | |
532 /* Next filter: Convert 16 bit <--> 8 bit PCM */ | |
533 if ( (src_format & 0xFF) != (dst_format & 0xFF) ) { | |
534 switch (dst_format&0x10FF) { | |
535 case AUDIO_U8: | |
536 cvt->filters[cvt->filter_index++] = | |
537 SDL_Convert8; | |
538 cvt->len_ratio /= 2; | |
539 break; | |
540 case AUDIO_U16LSB: | |
541 cvt->filters[cvt->filter_index++] = | |
542 SDL_Convert16LSB; | |
543 cvt->len_mult *= 2; | |
544 cvt->len_ratio *= 2; | |
545 break; | |
546 case AUDIO_U16MSB: | |
547 cvt->filters[cvt->filter_index++] = | |
548 SDL_Convert16MSB; | |
549 cvt->len_mult *= 2; | |
550 cvt->len_ratio *= 2; | |
551 break; | |
552 } | |
553 } | |
554 | |
555 /* Last filter: Mono/Stereo conversion */ | |
556 if ( src_channels != dst_channels ) { | |
557 while ( (src_channels*2) <= dst_channels ) { | |
558 cvt->filters[cvt->filter_index++] = | |
559 SDL_ConvertStereo; | |
560 cvt->len_mult *= 2; | |
561 src_channels *= 2; | |
562 cvt->len_ratio *= 2; | |
563 } | |
564 /* This assumes that 4 channel audio is in the format: | |
565 Left {front/back} + Right {front/back} | |
566 so converting to L/R stereo works properly. | |
567 */ | |
568 while ( ((src_channels%2) == 0) && | |
569 ((src_channels/2) >= dst_channels) ) { | |
570 cvt->filters[cvt->filter_index++] = | |
571 SDL_ConvertMono; | |
572 src_channels /= 2; | |
573 cvt->len_ratio /= 2; | |
574 } | |
575 if ( src_channels != dst_channels ) { | |
576 /* Uh oh.. */; | |
577 } | |
578 } | |
579 | |
580 /* Do rate conversion */ | |
581 cvt->rate_incr = 0.0; | |
582 if ( (src_rate/100) != (dst_rate/100) ) { | |
583 Uint32 hi_rate, lo_rate; | |
584 int len_mult; | |
585 double len_ratio; | |
586 void (*rate_cvt)(SDL_AudioCVT *cvt, Uint16 format); | |
587 | |
588 if ( src_rate > dst_rate ) { | |
589 hi_rate = src_rate; | |
590 lo_rate = dst_rate; | |
591 rate_cvt = SDL_RateDIV2; | |
592 len_mult = 1; | |
593 len_ratio = 0.5; | |
594 } else { | |
595 hi_rate = dst_rate; | |
596 lo_rate = src_rate; | |
597 rate_cvt = SDL_RateMUL2; | |
598 len_mult = 2; | |
599 len_ratio = 2.0; | |
600 } | |
601 /* If hi_rate = lo_rate*2^x then conversion is easy */ | |
602 while ( ((lo_rate*2)/100) <= (hi_rate/100) ) { | |
603 cvt->filters[cvt->filter_index++] = rate_cvt; | |
604 cvt->len_mult *= len_mult; | |
605 lo_rate *= 2; | |
606 cvt->len_ratio *= len_ratio; | |
607 } | |
608 /* We may need a slow conversion here to finish up */ | |
609 if ( (lo_rate/100) != (hi_rate/100) ) { | |
610 #if 1 | |
611 /* The problem with this is that if the input buffer is | |
612 say 1K, and the conversion rate is say 1.1, then the | |
613 output buffer is 1.1K, which may not be an acceptable | |
614 buffer size for the audio driver (not a power of 2) | |
615 */ | |
616 /* For now, punt and hope the rate distortion isn't great. | |
617 */ | |
618 #else | |
619 if ( src_rate < dst_rate ) { | |
620 cvt->rate_incr = (double)lo_rate/hi_rate; | |
621 cvt->len_mult *= 2; | |
622 cvt->len_ratio /= cvt->rate_incr; | |
623 } else { | |
624 cvt->rate_incr = (double)hi_rate/lo_rate; | |
625 cvt->len_ratio *= cvt->rate_incr; | |
626 } | |
627 cvt->filters[cvt->filter_index++] = SDL_RateSLOW; | |
628 #endif | |
629 } | |
630 } | |
631 | |
632 /* Set up the filter information */ | |
633 if ( cvt->filter_index != 0 ) { | |
634 cvt->needed = 1; | |
635 cvt->src_format = src_format; | |
636 cvt->dst_format = dst_format; | |
637 cvt->len = 0; | |
638 cvt->buf = NULL; | |
639 cvt->filters[cvt->filter_index] = NULL; | |
640 } | |
641 return(cvt->needed); | |
642 } |