Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/openal-0.0.8/src/audioconvert/ac_misc.c @ 17

Last change on this file since 17 was 17, checked in by landauf, 16 years ago

added openal

File size: 16.6 KB
Line 
1/*
2 * -*- mode: C; tab-width:8; c-basic-offset:8 -*-
3 * vi:set ts=8:
4 *
5 * ac_misc.c
6 *
7 * misc. audioconvert funcs.
8 *
9 * ripped straight from the SDL
10 *
11 * FIXME: consolidate ac_adpcm for MS_ADPCM stuff (ie, remove
12 *        _FULL sillyness
13 *        attach SDL and Sam copyright.
14 */
15
16#include "al_siteconfig.h"
17
18#include <AL/al.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include "audioconvert/audioconvert.h"
24#include "audioconvert/ac_endian.h"
25#include "audioconvert/ac_wave.h"
26
27#define PCM_CODE        0x0001
28#define MS_ADPCM_CODE   0x0002
29#define IMA_ADPCM_CODE  0x0011
30
31#define MS_ADPCM_max ((1<<(16-1))-1)
32#define MS_ADPCM_min -(1<<(16-1))
33
34struct MS_ADPCM_decodestate_FULL {
35        ALubyte hPredictor;
36        ALushort iDelta;
37        ALshort iSamp1;
38        ALshort iSamp2;
39}
40#ifdef __GNUC__
41 __attribute__ ((packed));
42#else
43 __attribute__;
44#endif /* __GNUC__ JIV */
45
46static struct MS_ADPCM_decoder_FULL {
47        alWaveFMT_LOKI wavefmt;
48        ALushort wSamplesPerBlock;
49        ALushort wNumCoef;
50        ALshort aCoeff[7][2];
51        /* * * */
52        struct MS_ADPCM_decodestate_FULL state[2];
53} MS_ADPCM_state_FULL;
54
55typedef struct Chunk {
56        ALuint magic;
57        ALuint length;
58        void *data;
59} Chunk;
60
61
62/* decode of MS stuff in full (as opposed to ac_adpcm) */
63static ALint MS_ADPCM_nibble_FULL(struct MS_ADPCM_decodestate_FULL *state,
64                                        ALubyte nybble, ALshort *coeff);
65static int MS_ADPCM_decode_FULL(ALubyte **audio_buf, ALuint *audio_len);
66static int InitMS_ADPCM(alWaveFMT_LOKI *format);
67
68static int ac_isWAVEadpcm(void *data, ALuint size, int encoding);
69
70/* read riff chunk */
71static void ReadChunk(const void *srcp, int *offset, Chunk *chunk) {
72        ALuint reader;
73        const ALubyte *src = srcp;
74
75        src += *offset;
76
77        memcpy((void *) &reader, (void *) src, 4);
78        chunk->magic    = swap32le(reader);
79
80        memcpy((void *) &reader, (void *) (src+4), 4);
81        chunk->length   = swap32le(reader);
82        *offset += chunk->length + 8;
83
84        chunk->data     = (void *) (src+8);
85}
86
87void *ac_guess_info(void *data, ALuint *size,
88                ALushort *fmt, ALushort *chan, ALushort *freq){
89        if(ac_is_wave(data)) {
90                return ac_guess_wave_info(data, size, fmt, chan, freq);
91        }
92#ifdef DEBUG_CONVERT
93        fprintf(stderr,
94                "ac_guess_info: can only guess WAVE files right now.\n");
95#endif
96
97        return NULL;
98}
99
100/* 0 if not wave
101 * 1 if is wave
102 *
103 * FIXME:
104 *   potential endian issues;
105 */
106int ac_is_wave(void *data) {
107        ALuint comparator;
108
109        memcpy((void *) &comparator, data, 4);
110        if(swap32le(comparator) != RIFF) {
111#ifdef DEBUG_CONVERT
112                fprintf(stderr, "Not a RIFF file: magic = 0x%x\n",
113                        comparator);
114#endif
115                return 0;
116        }
117
118        memcpy((void *) &comparator, (void *) ((char *)data+8), 4);
119        if(swap32le(comparator) != WAVE) {
120#ifdef DEBUG_CONVERT
121                fprintf(stderr, "Not a WAVE file: magic = 0x%x\n",
122                        comparator);
123#endif
124                return 0;
125        }
126
127        return 1;
128}
129
130void *acLoadWAV(const void *data, ALuint *size, void **udata,
131                ALushort *fmt, ALushort *chan, ALushort *freq) {
132        acAudioCVT endianConverter;
133
134        if((data == NULL) || (udata == NULL) || (size == NULL) ||
135           (fmt  == NULL) || (chan  == NULL) || (freq == NULL)) {
136                return NULL;
137        }
138
139        *udata = ac_wave_to_pcm(data, size, fmt, chan, freq);
140        if(*udata == NULL) {
141#ifdef DEBUG_CONVERT
142                /* bad mojo */
143                fprintf(stderr,
144                "[%s:%d] acLoadWAV: Could not load WAV\n", __FILE__, __LINE__);
145#endif
146
147                return NULL;
148        }
149
150        if((*fmt == AUDIO_S8) || (*fmt == AUDIO_U8) || (*fmt == AUDIO_S16)) {
151                return *udata;
152        }
153
154        if(acBuildAudioCVT(&endianConverter,
155                /* from */
156                *fmt,
157                *chan,
158                *freq,
159
160                /* to */
161                AUDIO_S16,
162                *chan,
163                *freq) < 0) {
164                fprintf(stderr,
165                        "[%s:%d] Couldn't build audio convertion data structure.",
166                        __FILE__, __LINE__);
167
168                free(udata);
169
170                return NULL;
171        }
172
173        endianConverter.buf = *udata;
174        endianConverter.len = *size;
175
176        acConvertAudio(&endianConverter);
177
178        return endianConverter.buf;
179}
180
181/*
182 * convert wave to pcm data, setting size, fmt, chan, and freq.
183 *
184 * usually just a memcpy, but for MS_ADPCM does that too.
185 */
186void *ac_wave_to_pcm(const void *data, ALuint *size,
187                ALushort *fmt, ALushort *chan, ALushort *freq) {
188        ALubyte *retval;
189        alWaveFMT_LOKI *format;
190        Chunk riffchunk = { 0, 0, 0 };
191        int offset = 12;
192        alIMAADPCM_state_LOKI ima_decoder;
193        ALuint tempfreq;
194
195        do {
196                ReadChunk(data, &offset, &riffchunk);
197        } while ((riffchunk.magic == WAVE) ||
198                 (riffchunk.magic == RIFF));
199
200        if(riffchunk.magic != FMT) {
201                fprintf(stderr,
202                        "ouch II magic|FMT [0x%x|0x%x]\n",
203                                riffchunk.magic, FMT);
204                return NULL;
205        }
206
207        format = (alWaveFMT_LOKI *) riffchunk.data;
208
209        /* channels */
210        *chan = swap16le(format->channels);
211
212        /* freq */
213        tempfreq = swap32le(format->frequency);
214        *freq = (ALushort) tempfreq;
215
216        switch(swap16le(format->encoding)) {
217                case PCM_CODE:
218                  switch(swap16le(format->bitspersample)) {
219                          case 8:
220                            *fmt = AUDIO_U8;
221                            break;
222                          case 16:
223                            *fmt = AUDIO_S16LSB;
224                            break;
225                          default:
226                            fprintf(stderr,
227                                "Unknown bits %d\n",
228                                swap16le(format->bitspersample));
229                            break;
230                  }
231
232                  do {
233                        ReadChunk(data, &offset, &riffchunk);
234                  } while(riffchunk.magic != DATA);
235
236                  retval = malloc(riffchunk.length);
237                  if(retval == NULL) {
238                          return NULL;
239                  }
240
241                  /* FIXME: Need to convert to native format? */
242#if defined(WORDS_BIGENDIAN) && DEBUG_CONVERT
243                  fprintf(stderr,
244                        "[%s:%d] do we need to convert to host native format here?\n",
245                        __FILE__, __LINE__);
246#endif
247                  memcpy(retval, riffchunk.data, riffchunk.length);
248
249                  *size = riffchunk.length;
250                  return retval;
251                  break;
252                case MS_ADPCM_CODE:
253                  /* not possible to do an inplace conversion */
254                  *fmt = AUDIO_S16LSB;
255
256                  if(InitMS_ADPCM(format) < 0) {
257#ifdef DEBUG
258                          fprintf(stderr, "Couldn't init MSADPCM\n");
259#endif
260                          return NULL;
261                  }
262
263                  do {
264                        ReadChunk(data, &offset, &riffchunk);
265                        retval = riffchunk.data;
266                  } while (riffchunk.magic != DATA);
267
268                  if(MS_ADPCM_decode_FULL(&retval, &riffchunk.length) < 0) {
269#ifdef DEBUG
270                          fprintf(stderr, "Couldn't decode MS_ADPCM\n");
271#endif
272                          return NULL;
273                  }
274
275                  *size = riffchunk.length;
276                  return retval;
277                  break;
278                case IMA_ADPCM_CODE:
279                  /* not possible to do an inplace conversion */
280                  *fmt = AUDIO_S16LSB;
281
282                  if(InitIMA_ADPCM(&ima_decoder, format) < 0) {
283#ifdef DEBUG_CONVERT
284                          fprintf(stderr, "Couldn't init IMA ADPCM\n");
285#endif
286                          return NULL;
287                  }
288
289                  do {
290                        ReadChunk(data, &offset, &riffchunk);
291                        retval = riffchunk.data;
292                  } while (riffchunk.magic != DATA);
293
294                  if(IMA_ADPCM_decode_FULL(&ima_decoder, &retval, &riffchunk.length) < 0) {
295#ifdef DEBUG_CONVERT
296                          fprintf(stderr, "Couldn't decode IMA_ADPCM\n");
297#endif
298                          return NULL;
299                  }
300
301                  *size = riffchunk.length;
302                  return retval;
303                  break;
304                default:
305#ifdef DEBUG_CONVERT
306                  fprintf(stderr,
307                        "[%s:%d] unknown WAVE format 0x%x\n",
308                        __FILE__, __LINE__, *fmt);
309#endif
310                  break;
311        }
312
313        return NULL;
314}
315
316void *ac_guess_wave_info(void *data, ALuint *size,
317                ALushort *fmt, ALushort *chan, ALushort *freq) {
318        alWaveFMT_LOKI *format;
319        Chunk riffchunk = { 0, 0, 0 };
320        int offset = 12;
321
322        do {
323                ReadChunk(data, &offset, &riffchunk);
324        } while ((riffchunk.magic == WAVE) ||
325                 (riffchunk.magic == RIFF));
326
327
328        if(riffchunk.magic != FMT) {
329                fprintf(stderr, "ouch II magic|FMT"
330                                "[0x%x|0x%x]\n",
331                                riffchunk.magic, FMT);
332                return NULL;
333        }
334
335        format = (alWaveFMT_LOKI *) riffchunk.data;
336
337        /* channels */
338        *chan = swap16le(format->channels);
339
340        /* freq */
341        *freq = swap16le(format->frequency);
342
343        switch(swap16le(format->encoding)) {
344                case PCM_CODE:
345                  switch(swap16le(format->bitspersample)) {
346                          case 8:
347                            *fmt = AUDIO_U8;
348                            break;
349                          case 16:
350                            *fmt = AUDIO_S16LSB;
351                            break;
352                          default:
353                            fprintf(stderr, "Unknown bits %d\n",
354                                    swap16le(format->bitspersample));
355                            break;
356                  }
357
358                  do {
359                        ReadChunk(data, &offset, &riffchunk);
360                  } while ((riffchunk.magic == FACT) ||
361                           (riffchunk.magic == FMT)  ||
362                           (riffchunk.magic == LIST) ||
363                           (riffchunk.magic == WAVE) ||
364                           (riffchunk.magic == RIFF));
365
366                  *size = riffchunk.length;
367
368                  return riffchunk.data;
369                  break;
370                case MS_ADPCM_CODE:
371                  break;
372                default:
373#ifdef DEBUG
374                  fprintf(stderr,
375                        "[%s:%d] unknown WAVE format 0x%x\n",
376                        __FILE__, __LINE__, *fmt);
377#endif
378                  break;
379        }
380
381        return NULL;
382}
383
384static int InitMS_ADPCM(alWaveFMT_LOKI *format) {
385        ALubyte *rogue_feel;
386        ALushort extra_info;
387        int i;
388
389        /* Set the rogue pointer to the MS_ADPCM specific data */
390        MS_ADPCM_state_FULL.wavefmt.encoding = swap16le(format->encoding);
391        MS_ADPCM_state_FULL.wavefmt.channels = swap16le(format->channels);
392        MS_ADPCM_state_FULL.wavefmt.frequency = swap32le(format->frequency);
393        MS_ADPCM_state_FULL.wavefmt.byterate = swap32le(format->byterate);
394        MS_ADPCM_state_FULL.wavefmt.blockalign = swap16le(format->blockalign);
395        MS_ADPCM_state_FULL.wavefmt.bitspersample =
396                                         swap16le(format->bitspersample);
397        rogue_feel = (ALubyte *)format+sizeof(*format);
398        if(sizeof(*format) == 16) {
399                extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);
400                rogue_feel += sizeof(ALushort);
401        }
402
403        MS_ADPCM_state_FULL.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
404        rogue_feel += sizeof(ALushort);
405        MS_ADPCM_state_FULL.wNumCoef = ((rogue_feel[1]<<8)|rogue_feel[0]);
406        rogue_feel += sizeof(ALushort);
407        if ( MS_ADPCM_state_FULL.wNumCoef != 7 ) {
408                fprintf(stderr, "Unknown set of MS_ADPCM coefficients\n");
409                return -1;
410        }
411
412        for(i = 0; i < MS_ADPCM_state_FULL.wNumCoef; i++) {
413                MS_ADPCM_state_FULL.aCoeff[i][0] =((rogue_feel[1]<<8)|rogue_feel[0]);
414                rogue_feel += sizeof(ALushort);
415                MS_ADPCM_state_FULL.aCoeff[i][1] =((rogue_feel[1]<<8)|rogue_feel[0]);
416                rogue_feel += sizeof(ALushort);
417        }
418
419        return 0;
420}
421
422static int MS_ADPCM_decode_FULL(ALubyte **audio_buf, ALuint *audio_len) {
423        struct MS_ADPCM_decodestate_FULL *state[2];
424        ALubyte *freeable, *encoded, *decoded;
425        ALint encoded_len, samplesleft;
426        ALbyte nybble, stereo;
427        ALshort *coeff[2];
428        ALint new_sample;
429
430        /* Allocate the proper sized output buffer */
431        encoded_len = *audio_len;
432        encoded = *audio_buf;
433        freeable = *audio_buf;
434        *audio_len = (encoded_len/MS_ADPCM_state_FULL.wavefmt.blockalign) *
435                                MS_ADPCM_state_FULL.wSamplesPerBlock*
436                                MS_ADPCM_state_FULL.wavefmt.channels*sizeof(ALshort);
437        *audio_buf = malloc(*audio_len);
438        if(*audio_buf == NULL) {
439                perror("malloc");
440                return -1;
441        }
442        decoded = *audio_buf;
443
444        /* Get ready... Go! */
445        stereo = (MS_ADPCM_state_FULL.wavefmt.channels == 2);
446        state[0] = &MS_ADPCM_state_FULL.state[0];
447        state[1] = &MS_ADPCM_state_FULL.state[(int) stereo];
448        while ( encoded_len >= MS_ADPCM_state_FULL.wavefmt.blockalign ) {
449                /* Grab the initial information for this block */
450                state[0]->hPredictor = *encoded++;
451                if ( stereo ) {
452                        state[1]->hPredictor = *encoded++;
453                }
454                state[0]->iDelta = ((encoded[1]<<8)|encoded[0]);
455                encoded += sizeof(ALshort);
456                if ( stereo ) {
457                        state[1]->iDelta = ((encoded[1]<<8)|encoded[0]);
458                        encoded += sizeof(ALshort);
459                }
460                state[0]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
461                encoded += sizeof(ALshort);
462                if ( stereo ) {
463                        state[1]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
464                        encoded += sizeof(ALshort);
465                }
466                state[0]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
467                encoded += sizeof(ALshort);
468                if ( stereo ) {
469                        state[1]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
470                        encoded += sizeof(ALshort);
471                }
472                coeff[0] = MS_ADPCM_state_FULL.aCoeff[state[0]->hPredictor];
473                coeff[1] = MS_ADPCM_state_FULL.aCoeff[state[1]->hPredictor];
474
475                /* Store the two initial samples we start with */
476                decoded[0] = state[0]->iSamp2&0xFF;
477                decoded[1] = state[0]->iSamp2>>8;
478                decoded += 2;
479                if ( stereo ) {
480                        decoded[0] = state[1]->iSamp2&0xFF;
481                        decoded[1] = state[1]->iSamp2>>8;
482                        decoded += 2;
483                }
484                decoded[0] = state[0]->iSamp1&0xFF;
485                decoded[1] = state[0]->iSamp1>>8;
486                decoded += 2;
487                if ( stereo ) {
488                        decoded[0] = state[1]->iSamp1&0xFF;
489                        decoded[1] = state[1]->iSamp1>>8;
490                        decoded += 2;
491                }
492
493                /* Decode and store the other samples in this block */
494                samplesleft = (MS_ADPCM_state_FULL.wSamplesPerBlock-2)*
495                                        MS_ADPCM_state_FULL.wavefmt.channels;
496                while ( samplesleft > 0 ) {
497                        nybble = (*encoded)>>4;
498                        new_sample = MS_ADPCM_nibble_FULL(state[0],nybble,coeff[0]);
499                        decoded[0] = new_sample&0xFF;
500                        new_sample >>= 8;
501                        decoded[1] = new_sample&0xFF;
502                        decoded += 2;
503
504                        nybble = (*encoded)&0x0F;
505                        new_sample = MS_ADPCM_nibble_FULL(state[1],nybble,coeff[1]);
506                        decoded[0] = new_sample&0xFF;
507                        new_sample >>= 8;
508                        decoded[1] = new_sample&0xFF;
509                        decoded += 2;
510
511                        ++encoded;
512                        samplesleft -= 2;
513                }
514                encoded_len -= MS_ADPCM_state_FULL.wavefmt.blockalign;
515        }
516
517        /* free(freeable); */
518        return 0;
519}
520
521static ALint MS_ADPCM_nibble_FULL(struct MS_ADPCM_decodestate_FULL *state,
522                                        ALubyte nybble, ALshort *coeff) {
523        const ALint adaptive[] = {
524                230, 230, 230, 230, 307, 409, 512, 614,
525                768, 614, 512, 409, 307, 230, 230, 230
526        };
527        ALint new_sample, delta;
528
529        new_sample = ((state->iSamp1 * coeff[0]) +
530                      (state->iSamp2 * coeff[1]))/256;
531
532        if(nybble & 0x08) {
533                new_sample += state->iDelta * (nybble-0x10);
534        } else {
535                new_sample += state->iDelta * nybble;
536        }
537
538        if(new_sample < MS_ADPCM_min) {
539                new_sample = MS_ADPCM_min;
540        } else if(new_sample > MS_ADPCM_max) {
541                new_sample = MS_ADPCM_max;
542        }
543
544        delta = ((ALint) state->iDelta * adaptive[nybble]);
545        if(delta < 4096) {
546                delta = 16;
547        } else {
548                delta /= 256;
549        }
550
551        state->iDelta = delta;
552        state->iSamp2 = state->iSamp1;
553        state->iSamp1 = new_sample;
554
555        return new_sample;
556}
557
558/* 0 if adpcm, -1 otherwise */
559static int ac_isWAVEadpcm(void *data, UNUSED(ALuint size), int encoding) {
560        alWaveFMT_LOKI *format;
561        Chunk riffchunk = { 0, 0, 0 };
562        int offset = 12;
563
564        do {
565                ReadChunk(data, &offset, &riffchunk);
566        } while ((riffchunk.magic == WAVE) ||
567                 (riffchunk.magic == RIFF));
568
569        if(riffchunk.magic != FMT) {
570                return -1;
571        }
572
573        format = (alWaveFMT_LOKI *) riffchunk.data;
574
575        if(swap16le(format->encoding) == encoding) {
576                  return 0;
577        }
578
579#ifdef DEBUG_CONVERT
580        fprintf(stderr, "encoding | format->enc %d|%d\n",
581                format->encoding, encoding);
582#endif
583
584        return -1;
585}
586
587void *ac_getWAVEadpcm_info(void *data, ALuint *size, void *spec) {
588        void *retval;
589        alWaveFMT_LOKI        *format;
590        alMSADPCM_state_LOKI  *mss;
591        alIMAADPCM_state_LOKI *ias;
592        Chunk riffchunk = { 0, 0, 0 };
593        int offset = 12;
594        ALubyte *ext_format_reader;
595        ALushort reader16;
596        int i;
597
598        do {
599                ReadChunk(data, &offset, &riffchunk);
600        } while ((riffchunk.magic == WAVE) ||
601                 (riffchunk.magic == RIFF));
602
603        if(riffchunk.magic != FMT) {
604                fprintf(stderr, "returning NULL\n");
605                return NULL;
606        }
607
608        format = (alWaveFMT_LOKI *) riffchunk.data;
609
610        do {
611                ReadChunk(data, &offset, &riffchunk);
612                retval = riffchunk.data;
613        } while (riffchunk.magic != DATA);
614
615        *size = riffchunk.length;
616
617        switch(swap16le(format->encoding)) {
618                case MS_ADPCM_CODE:
619                  ext_format_reader = (ALubyte *) format + 18;
620                  mss = (alMSADPCM_state_LOKI *) spec;
621
622                  mss->wavefmt.encoding      = swap16le(format->encoding);
623                  mss->wavefmt.channels      = swap16le(format->channels);
624                  mss->wavefmt.frequency     = swap32le(format->frequency);
625                  mss->wavefmt.byterate      = swap32le(format->byterate);
626                  mss->wavefmt.blockalign    = swap16le(format->blockalign);
627                  mss->wavefmt.bitspersample = swap16le(format->bitspersample);
628
629                  ext_format_reader = cp16le(ext_format_reader, &reader16);
630                  mss->wSamplesPerBlock = reader16;
631
632                  ext_format_reader = cp16le(ext_format_reader, &reader16);
633                  mss->wNumCoef = reader16;
634
635                  if(mss->wNumCoef != 7) {
636                          fprintf(stderr, "wNumCoeff != 7\n");
637                  }
638
639                  for(i = 0; i < mss->wNumCoef; i++) {
640                        ext_format_reader = cp16le(ext_format_reader,&reader16);
641                        mss->aCoeff[i][0] = reader16;
642
643                        ext_format_reader = cp16le(ext_format_reader,&reader16);
644                        mss->aCoeff[i][1] = reader16;
645                  }
646                  return retval;
647                case IMA_ADPCM_CODE:
648                  ias = (alIMAADPCM_state_LOKI *) spec;
649                  InitIMA_ADPCM(ias, format);
650
651                  return retval;
652                case PCM_CODE:
653                default:
654                  fprintf(stderr, "returning NULL\n");
655                  return NULL;
656        }
657}
658
659int ac_isWAVE_IMA_adpcm(void *data, ALuint size) {
660        return ac_isWAVEadpcm(data, size, IMA_ADPCM_CODE);
661}
662
663int ac_isWAVE_MS_adpcm(void *data, ALuint size) {
664        return ac_isWAVEadpcm(data, size, MS_ADPCM_CODE);
665}
666
667int ac_isWAVE_ANY_adpcm(void *data, ALuint size) {
668        int retval;
669
670        retval = ac_isWAVEadpcm(data, size, MS_ADPCM_CODE);
671        if(retval) {
672                retval = ac_isWAVEadpcm(data, size, IMA_ADPCM_CODE);
673        }
674
675        return retval;
676}
677
678
679/* read riff chunk */
680int RiffOffset(ALubyte *rawdata, ALint magic) {
681        unsigned char *rawp;
682        struct {
683                ALint magic;
684                ALint len;
685        } chunk;
686        int retval;
687
688        rawp = rawdata + 12;
689
690        do {
691                memcpy(&chunk.magic, rawp, sizeof chunk.magic);
692                rawp += sizeof chunk.magic;
693
694                memcpy(&chunk.len,   rawp, sizeof chunk.len);
695                rawp += sizeof chunk.magic;
696
697                chunk.magic = swap32le(chunk.magic);
698                chunk.len   = swap32le(chunk.len);
699
700#ifdef DEBUG_CONVERT
701                fprintf(stderr,
702                        "chunk.magic = %c%c%c%c\n",
703                        ((char *) &chunk.magic)[0],
704                        ((char *) &chunk.magic)[1],
705                        ((char *) &chunk.magic)[2],
706                        ((char *) &chunk.magic)[3]);
707
708                fprintf(stderr,
709                        "chunk.len   = %d\n", chunk.len);
710#endif
711
712                if(chunk.magic == magic) {
713                        retval = rawp - rawdata;
714                        break;
715                }
716
717                rawp += chunk.len;
718        } while(1);
719
720        return retval;
721}
Note: See TracBrowser for help on using the repository browser.