[LIBMPG123] Update to v1.22.4.
[reactos.git] / reactos / lib / 3rdparty / libmpg123 / parse.c
index 0fd51c5..9d5c5dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
        parse: spawned from common; clustering around stream/frame parsing
 
-       copyright ?-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
+       copyright ?-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
        see COPYING and AUTHORS files in distribution or http://mpg123.org
        initially written by Michael Hipp & Thomas Orgis
 */
 #endif
 #define TRACK_MAX_FRAMES ULONG_MAX/4/1152
 
+#include "mpeghead.h"
+
 #include "debug.h"
 
 #define bsbufid(fr) (fr)->bsbuf==(fr)->bsspace[0] ? 0 : ((fr)->bsbuf==fr->bsspace[1] ? 1 : ( (fr)->bsbuf==(fr)->bsspace[0]+512 ? 2 : ((fr)->bsbuf==fr->bsspace[1]+512 ? 3 : -1) ) )
 
-/*
-       AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
-       A: sync
-       B: mpeg version
-       C: layer
-       D: CRC
-       E: bitrate
-       F:sampling rate
-       G: padding
-       H: private
-       I: channel mode
-       J: mode ext
-       K: copyright
-       L: original
-       M: emphasis
-
-       old compare mask 0xfffffd00:
-       11111111 11111111 11111101 00000000
-
-       means: everything must match excluding padding and channel mode, ext mode, ...
-       But a vbr stream's headers will differ in bitrate!
-       We are already strict in allowing only frames of same type in stream, we should at least watch out for VBR while being strict.
-
-       So a better mask is:
-       11111111 11111111 00001101 00000000
-
-       Even more, I'll allow varying crc bit.
-       11111111 11111110 00001101 00000000
-
-       (still unsure about this private bit)
-*/
-#define HDRCMPMASK 0xfffe0d00
-#define HDRSAMPMASK 0xc00 /* 1100 00000000, FF bits (sample rate) */
+/* PARSE_GOOD and PARSE_BAD have to be 1 and 0 (TRUE and FALSE), others can vary. */
+enum parse_codes
+{
+        PARSE_MORE = MPG123_NEED_MORE
+       ,PARSE_ERR  = MPG123_ERR
+       ,PARSE_END  = 10 /* No more audio data to find. */
+       ,PARSE_GOOD = 1 /* Everything's fine. */
+       ,PARSE_BAD  = 0 /* Not fine (invalid data). */
+       ,PARSE_RESYNC = 2 /* Header not good, go into resync. */
+       ,PARSE_AGAIN  = 3 /* Really start over, throw away and read a new header, again. */
+};
 
 /* bitrates for [mpeg1/2][layer] */
 static const int tabsel_123[2][3][16] =
@@ -81,11 +61,15 @@ static const int tabsel_123[2][3][16] =
        }
 };
 
-const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
+static const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
 
-static int decode_header(mpg123_handle *fr,unsigned long newhead);
+static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count);
+static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount);
+static int do_readahead(mpg123_handle *fr, unsigned long newhead);
+static int wetwork(mpg123_handle *fr, unsigned long *newheadp);
 
 /* These two are to be replaced by one function that gives all the frame parameters (for outsiders).*/
+/* Those functions are unsafe regarding bad arguments (inside the mpg123_handle), but just returning anything would also be unsafe, the caller code has to be trusted. */
 
 int frame_bitrate(mpg123_handle *fr)
 {
@@ -97,24 +81,21 @@ long frame_freq(mpg123_handle *fr)
        return freqs[fr->sampling_frequency];
 }
 
-#define free_format_header(head) ( ((head & 0xffe00000) == 0xffe00000) && ((head>>17)&3) && (((head>>12)&0xf) == 0x0) && (((head>>10)&0x3) != 0x3 ))
-
 /* compiler is smart enought to inline this one or should I really do it as macro...? */
-int head_check(unsigned long head)
+static int head_check(unsigned long head)
 {
        if
        (
-               /* first 11 bits are set to 1 for frame sync */
-               ((head & 0xffe00000) != 0xffe00000)
+               ((head & HDR_SYNC) != HDR_SYNC)
                ||
                /* layer: 01,10,11 is 1,2,3; 00 is reserved */
-               (!((head>>17)&3))
+               (!(HDR_LAYER_VAL(head)))
                ||
                /* 1111 means bad bitrate */
-               (((head>>12)&0xf) == 0xf)
+               (HDR_BITRATE_VAL(head) == 0xf)
                ||
                /* sampling freq: 11 is reserved */
-               (((head>>10)&0x3) == 0x3 )
+               (HDR_SAMPLERATE_VAL(head) == 0x3)
                /* here used to be a mpeg 2.5 check... re-enabled 2.5 decoding due to lack of evidence that it is really not good */
        )
        {
@@ -127,307 +108,348 @@ int head_check(unsigned long head)
        }
 }
 
+/* This is moderately sized buffers. Int offset is enough. */
+static unsigned long bit_read_long(unsigned char *buf, int *offset)
+{
+       unsigned long val =  /* 32 bit value */
+               (((unsigned long) buf[*offset])   << 24)
+       |       (((unsigned long) buf[*offset+1]) << 16)
+       |       (((unsigned long) buf[*offset+2]) << 8)
+       |        ((unsigned long) buf[*offset+3]);
+       *offset += 4;
+       return val;
+}
+
+static unsigned short bit_read_short(unsigned char *buf, int *offset)
+{
+       unsigned short val = /* 16 bit value */
+               (((unsigned short) buf[*offset]  ) << 8)
+       |        ((unsigned short) buf[*offset+1]);
+       *offset += 2;
+       return val;
+}
+
 static int check_lame_tag(mpg123_handle *fr)
 {
+       int i;
+       unsigned long xing_flags;
+       unsigned long long_tmp;
        /*
                going to look for Xing or Info at some position after the header
                                                   MPEG 1  MPEG 2/2.5 (LSF)
                Stereo, Joint Stereo, Dual Channel  32      17
                Mono                                17       9
+       */
+       int lame_offset = (fr->stereo == 2)
+       ? (fr->lsf ? 17 : 32)
+       : (fr->lsf ? 9  : 17);
 
-               Also, how to avoid false positives? I guess I should interpret more of the header to rule that out(?).
-               I hope that ensuring all zeros until tag start is enough.
+       if(fr->p.flags & MPG123_IGNORE_INFOFRAME) goto check_lame_tag_no;
+
+       debug("do we have lame tag?");
+       /*
+               Note: CRC or not, that does not matter here.
+               But, there is any combination of Xing flags in the wild. There are headers
+               without the search index table! I cannot assume a reasonable minimal size
+               for the actual data, have to check if each byte of information is present.
+               But: 4 B Info/Xing + 4 B flags is bare minimum.
        */
-       int lame_offset = (fr->stereo == 2) ? (fr->lsf ? 17 : 32 ) : (fr->lsf ? 9 : 17);
-       /* At least skip the decoder delay. */
-#ifdef GAPLESS
-       if(fr->p.flags & MPG123_GAPLESS)
+       if(fr->framesize < lame_offset+8) goto check_lame_tag_no;
+
+       /* only search for tag when all zero before it (apart from checksum) */
+       for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) goto check_lame_tag_no;
+
+       debug("possibly...");
+       if
+       (
+                  (fr->bsbuf[lame_offset]   == 'I')
+               && (fr->bsbuf[lame_offset+1] == 'n')
+               && (fr->bsbuf[lame_offset+2] == 'f')
+               && (fr->bsbuf[lame_offset+3] == 'o')
+       )
+       {
+               /* We still have to see what there is */
+       }
+       else if
+       (
+                  (fr->bsbuf[lame_offset]   == 'X')
+               && (fr->bsbuf[lame_offset+1] == 'i')
+               && (fr->bsbuf[lame_offset+2] == 'n')
+               && (fr->bsbuf[lame_offset+3] == 'g')
+       )
        {
-               if(fr->begin_s == 0) frame_gapless_init(fr, GAPLESS_DELAY, 0);
+               fr->vbr = MPG123_VBR; /* Xing header means always VBR */
        }
+       else goto check_lame_tag_no;
+
+       /* we have one of these headers... */
+       if(VERBOSE2) fprintf(stderr, "Note: Xing/Lame/Info header detected\n");
+       lame_offset += 4; 
+       xing_flags = bit_read_long(fr->bsbuf, &lame_offset);
+       debug1("Xing: flags 0x%08lx", xing_flags);
+
+       /* From now on, I have to carefully check if the announced data is actually
+          there! I'm always returning 'yes', though.  */
+       #define check_bytes_left(n) if(fr->framesize < lame_offset+n) \
+               goto check_lame_tag_yes
+       if(xing_flags & 1) /* total bitstream frames */
+       {
+               check_bytes_left(4); long_tmp = bit_read_long(fr->bsbuf, &lame_offset);
+               if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
+               {
+                       if(VERBOSE3) fprintf(stderr
+                       ,       "Note: Ignoring Xing frames because of MPG123_IGNORE_STREAMLENGTH\n");
+               }
+               else
+               {
+                       /* Check for endless stream, but: TRACK_MAX_FRAMES sensible at all? */
+                       fr->track_frames = long_tmp > TRACK_MAX_FRAMES ? 0 : (off_t) long_tmp;
+#ifdef GAPLESS
+                       /* All or nothing: Only if encoder delay/padding is known, we'll cut
+                          samples for gapless. */
+                       if(fr->p.flags & MPG123_GAPLESS)
+                       frame_gapless_init(fr, fr->track_frames, 0, 0);
 #endif
-
-       if(fr->framesize >= 120+lame_offset) /* traditional Xing header is 120 bytes */
+                       if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu frames\n", long_tmp);
+               }
+       }
+       if(xing_flags & 0x2) /* total bitstream bytes */
        {
-               int i;
-               int lame_type = 0;
-               debug("do we have lame tag?");
-               /* only search for tag when all zero before it (apart from checksum) */
-               for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) break;
-               if(i == lame_offset)
+               check_bytes_left(4); long_tmp = bit_read_long(fr->bsbuf, &lame_offset);
+               if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
                {
-                       debug("possibly...");
-                       if
-                       (
-                                          (fr->bsbuf[lame_offset] == 'I')
-                               && (fr->bsbuf[lame_offset+1] == 'n')
-                               && (fr->bsbuf[lame_offset+2] == 'f')
-                               && (fr->bsbuf[lame_offset+3] == 'o')
-                       )
-                       {
-                               lame_type = 1; /* We still have to see what there is */
-                       }
-                       else if
-                       (
-                                          (fr->bsbuf[lame_offset] == 'X')
-                               && (fr->bsbuf[lame_offset+1] == 'i')
-                               && (fr->bsbuf[lame_offset+2] == 'n')
-                               && (fr->bsbuf[lame_offset+3] == 'g')
-                       )
+                       if(VERBOSE3) fprintf(stderr
+                       ,       "Note: Ignoring Xing bytes because of MPG123_IGNORE_STREAMLENGTH\n");
+               }
+               else
+               {
+                       /* The Xing bitstream length, at least as interpreted by the Lame
+                          encoder, encompasses all data from the Xing header frame on,
+                          ignoring leading ID3v2 data. Trailing tags (ID3v1) seem to be 
+                          included, though. */
+                       if(fr->rdat.filelen < 1)
+                       fr->rdat.filelen = (off_t) long_tmp + fr->audio_start; /* Overflow? */
+                       else
                        {
-                               lame_type = 2;
-                               fr->vbr = MPG123_VBR; /* Xing header means always VBR */
+                               if((off_t)long_tmp != fr->rdat.filelen - fr->audio_start && NOQUIET)
+                               { /* 1/filelen instead of 1/(filelen-start), my decision */
+                                       double diff = 100.0/fr->rdat.filelen
+                                                   * ( fr->rdat.filelen - fr->audio_start
+                                                       - (off_t)long_tmp );
+                                       if(diff < 0.) diff = -diff;
+
+                                       if(VERBOSE3) fprintf(stderr
+                                       ,       "Note: Xing stream size %lu differs by %f%% from determined/given file size!\n"
+                                       ,       long_tmp, diff);
+
+                                       if(diff > 1. && NOQUIET) fprintf(stderr
+                                       ,       "Warning: Xing stream size off by more than 1%%, fuzzy seeking may be even more fuzzy than by design!\n");
+                               }
                        }
-                       if(lame_type)
+
+                       if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu bytes\n", long_tmp);
+               }
+       }
+       if(xing_flags & 0x4) /* TOC */
+       {
+               check_bytes_left(100);
+               frame_fill_toc(fr, fr->bsbuf+lame_offset);
+               lame_offset += 100;
+       }
+       if(xing_flags & 0x8) /* VBR quality */
+       {
+               check_bytes_left(4); long_tmp = bit_read_long(fr->bsbuf, &lame_offset);
+               if(VERBOSE3) fprintf(stderr, "Note: Xing: quality = %lu\n", long_tmp);
+       }
+       /*
+               Either zeros/nothing, or:
+                       0-8: LAME3.90a
+                       9: revision/VBR method
+                       10: lowpass
+                       11-18: ReplayGain
+                       19: encoder flags
+                       20: ABR 
+                       21-23: encoder delays
+       */
+       check_bytes_left(24); /* I'm interested in 24 B of extra info. */
+       if(fr->bsbuf[lame_offset] != 0)
+       {
+               unsigned char lame_vbr;
+               float replay_gain[2] = {0,0};
+               float peak = 0;
+               float gain_offset = 0; /* going to be +6 for old lame that used 83dB */
+               char nb[10];
+               off_t pad_in;
+               off_t pad_out;
+               memcpy(nb, fr->bsbuf+lame_offset, 9);
+               nb[9] = 0;
+               if(VERBOSE3) fprintf(stderr, "Note: Info: Encoder: %s\n", nb);
+               if(!strncmp("LAME", nb, 4))
+               {
+                       /* Lame versions before 3.95.1 used 83 dB reference level, later
+                          versions 89 dB. We stick with 89 dB as being "normal", adding
+                          6 dB. */
+                       unsigned int major, minor;
+                       char rest[6];
+                       rest[0] = 0;
+                       if(sscanf(nb+4, "%u.%u%s", &major, &minor, rest) >= 2)
                        {
-                               unsigned long xing_flags;
-
-                               /* we have one of these headers... */
-                               if(VERBOSE2) fprintf(stderr, "Note: Xing/Lame/Info header detected\n");
-                               /* now interpret the Xing part, I have 120 bytes total for sure */
-                               /* there are 4 bytes for flags, but only the last byte contains known ones */
-                               lame_offset += 4; /* now first byte after Xing/Name */
-                               /* 4 bytes dword for flags */
-                               #define make_long(a, o) ((((unsigned long) a[o]) << 24) | (((unsigned long) a[o+1]) << 16) | (((unsigned long) a[o+2]) << 8) | ((unsigned long) a[o+3]))
-                               /* 16 bit */
-                               #define make_short(a,o) ((((unsigned short) a[o]) << 8) | ((unsigned short) a[o+1]))
-                               xing_flags = make_long(fr->bsbuf, lame_offset);
-                               lame_offset += 4;
-                               debug1("Xing: flags 0x%08lx", xing_flags);
-                               if(xing_flags & 1) /* frames */
-                               {
-                                       if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
-                                       {
-                                               if(VERBOSE3)
-                                               fprintf(stderr, "Note: Ignoring Xing frames because of MPG123_IGNORE_STREAMLENGTH\n");
-                                       }
-                                       else
-                                       {
-                                               /*
-                                                       In theory, one should use that value for skipping...
-                                                       When I know the exact number of samples I could simply count in flush_output,
-                                                       but that's problematic with seeking and such.
-                                                       I still miss the real solution for detecting the end.
-                                               */
-                                               fr->track_frames = (off_t) make_long(fr->bsbuf, lame_offset);
-                                               if(fr->track_frames > TRACK_MAX_FRAMES) fr->track_frames = 0; /* endless stream? */
-                                               #ifdef GAPLESS
-                                               /* if no further info there, remove/add at least the decoder delay */
-                                               if(fr->p.flags & MPG123_GAPLESS)
-                                               {
-                                                       off_t length = fr->track_frames * spf(fr);
-                                                       if(length > 1)
-                                                       frame_gapless_init(fr, GAPLESS_DELAY, length+GAPLESS_DELAY);
-                                               }
-                                               #endif
-                                               if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu frames\n", (long unsigned)fr->track_frames);
-                                       }
-
-                                       lame_offset += 4;
-                               }
-                               if(xing_flags & 0x2) /* bytes */
+                               debug3("LAME: %u/%u/%s", major, minor, rest);
+                               /* We cannot detect LAME 3.95 reliably (same version string as
+                                  3.95.1), so this is a blind spot. Everything < 3.95 is safe,
+                                  though. */
+                               if(major < 3 || (major == 3 && minor < 95))
                                {
-                                       if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
-                                       {
-                                               if(VERBOSE3)
-                                               fprintf(stderr, "Note: Ignoring Xing bytes because of MPG123_IGNORE_STREAMLENGTH\n");
-                                       }
-                                       else
-                                       {
-                                               unsigned long xing_bytes = make_long(fr->bsbuf, lame_offset);                                   /* We assume that this is the _total_ size of the file, including Xing frame ... and ID3 frames...
-                                                  It's not that clearly documented... */
-                                               if(fr->rdat.filelen < 1)
-                                               fr->rdat.filelen = (off_t) xing_bytes; /* One could start caring for overflow here. */
-                                               else
-                                               {
-                                                       if((off_t) xing_bytes != fr->rdat.filelen && NOQUIET)
-                                                       {
-                                                               double diff = 1.0/fr->rdat.filelen * (fr->rdat.filelen - (off_t)xing_bytes);
-                                                               if(diff < 0.) diff = -diff;
-
-                                                               if(VERBOSE3)
-                                                               fprintf(stderr, "Note: Xing stream size %lu differs by %f%% from determined/given file size!\n", xing_bytes, diff);
-
-                                                               if(diff > 1.)
-                                                               fprintf(stderr, "Warning: Xing stream size off by more than 1%%, fuzzy seeking may be even more fuzzy than by design!\n");
-                                                       }
-                                               }
-
-                                               if(VERBOSE3)
-                                               fprintf(stderr, "Note: Xing: %lu bytes\n", (long unsigned)xing_bytes);
-                                       }
-
-                                       lame_offset += 4;
+                                       gain_offset = 6;
+                                       if(VERBOSE3) fprintf(stderr
+                                       ,       "Note: Info: Old LAME detected, using ReplayGain preamp of %f dB.\n"
+                                       ,       gain_offset);
                                }
-                               if(xing_flags & 0x4) /* TOC */
-                               {
-                                       frame_fill_toc(fr, fr->bsbuf+lame_offset);
-                                       lame_offset += 100; /* just skip */
-                               }
-                               if(xing_flags & 0x8) /* VBR quality */
-                               {
-                                       if(VERBOSE3)
-                                       {
-                                               unsigned long xing_quality = make_long(fr->bsbuf, lame_offset);
-                                               fprintf(stderr, "Note: Xing: quality = %lu\n", (long unsigned)xing_quality);
-                                       }
-                                       lame_offset += 4;
-                               }
-                               /* I guess that either 0 or LAME extra data follows */
-                               /* there may this crc16 be floating around... (?) */
-                               if(fr->bsbuf[lame_offset] != 0)
-                               {
-                                       unsigned char lame_vbr;
-                                       float replay_gain[2] = {0,0};
-                                       float peak = 0;
-                                       float gain_offset = 0; /* going to be +6 for old lame that used 83dB */
-                                       char nb[10];
-                                       memcpy(nb, fr->bsbuf+lame_offset, 9);
-                                       nb[9] = 0;
-                                       if(VERBOSE3) fprintf(stderr, "Note: Info: Encoder: %s\n", nb);
-                                       if(!strncmp("LAME", nb, 4))
-                                       {
-                                               gain_offset = 6;
-                                               debug("TODO: finish lame detetcion...");
-                                       }
-                                       lame_offset += 9;
-                                       /* the 4 big bits are tag revision, the small bits vbr method */
-                                       lame_vbr = fr->bsbuf[lame_offset] & 15;
-                                       if(VERBOSE3)
-                                       {
-                                               fprintf(stderr, "Note: Info: rev %u\n", fr->bsbuf[lame_offset] >> 4);
-                                               fprintf(stderr, "Note: Info: vbr mode %u\n", lame_vbr);
-                                       }
-                                       lame_offset += 1;
-                                       switch(lame_vbr)
-                                       {
-                                               /* from rev1 proposal... not sure if all good in practice */
-                                               case 1:
-                                               case 8: fr->vbr = MPG123_CBR; break;
-                                               case 2:
-                                               case 9: fr->vbr = MPG123_ABR; break;
-                                               default: fr->vbr = MPG123_VBR; /* 00==unknown is taken as VBR */
-                                       }
-                                       /* skipping: lowpass filter value */
-                                       lame_offset += 1;
-                                       /* replaygain */
-                                       /* 32bit float: peak amplitude -- why did I parse it as int before??*/
-                                       /* Ah, yes, lame seems to store it as int since some day in 2003; I've only seen zeros anyway until now, bah! */
-                                       if
-                                       (
-                                                        (fr->bsbuf[lame_offset] != 0)
-                                               || (fr->bsbuf[lame_offset+1] != 0)
-                                               || (fr->bsbuf[lame_offset+2] != 0)
-                                               || (fr->bsbuf[lame_offset+3] != 0)
-                                       )
-                                       {
-                                               debug("Wow! Is there _really_ a non-zero peak value? Now is it stored as float or int - how should I know?");
-                                               /* byte*peak_bytes = (byte*) &peak;
-                                               ... endianess ... just copy bytes to avoid floating point operation on unaligned memory?
-                                               peak_bytes[0] = ...
-                                               peak = *(float*) (fr->bsbuf+lame_offset); */
-                                       }
-                                       if(VERBOSE3) fprintf(stderr, "Note: Info: peak = %f (I won't use this)\n", peak);
-                                       peak = 0; /* until better times arrived */
-                                       lame_offset += 4;
-                                       /*
-                                               ReplayGain values - lame only writes radio mode gain...
-                                               16bit gain, 3 bits name, 3 bits originator, sign (1=-, 0=+), dB value*10 in 9 bits (fixed point)
-                                               ignore the setting if name or originator == 000!
-                                               radio 0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 1
-                                               audiophile 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0
-                                       */
-
-                                       for(i =0; i < 2; ++i)
-                                       {
-                                               unsigned char origin = (fr->bsbuf[lame_offset] >> 2) & 0x7; /* the 3 bits after that... */
-                                               if(origin != 0)
-                                               {
-                                                       unsigned char gt = fr->bsbuf[lame_offset] >> 5; /* only first 3 bits */
-                                                       if(gt == 1) gt = 0; /* radio */
-                                                       else if(gt == 2) gt = 1; /* audiophile */
-                                                       else continue;
-                                                       /* get the 9 bits into a number, divide by 10, multiply sign... happy bit banging */
-                                                       replay_gain[0] = (float) ((fr->bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1) * (make_short(fr->bsbuf, lame_offset) & 0x1f);
-                                               }
-                                               lame_offset += 2;
-                                       }
-                                       if(VERBOSE3) 
-                                       {
-                                               fprintf(stderr, "Note: Info: Radio Gain = %03.1fdB\n", replay_gain[0]);
-                                               fprintf(stderr, "Note: Info: Audiophile Gain = %03.1fdB\n", replay_gain[1]);
-                                       }
-                                       for(i=0; i < 2; ++i)
-                                       {
-                                               if(fr->rva.level[i] <= 0)
-                                               {
-                                                       fr->rva.peak[i] = 0; /* at some time the parsed peak should be used */
-                                                       fr->rva.gain[i] = replay_gain[i];
-                                                       fr->rva.level[i] = 0;
-                                               }
-                                       }
-                                       lame_offset += 1; /* skipping encoding flags byte */
-                                       if(fr->vbr == MPG123_ABR)
-                                       {
-                                               fr->abr_rate = fr->bsbuf[lame_offset];
-                                               if(VERBOSE3) fprintf(stderr, "Note: Info: ABR rate = %u\n", fr->abr_rate);
-                                       }
-                                       lame_offset += 1;
-                                       /* encoder delay and padding, two 12 bit values... lame does write them from int ...*/
-                                       if(VERBOSE3)
-                                       fprintf(stderr, "Note: Encoder delay = %i; padding = %i\n",
-                                               ((((int) fr->bsbuf[lame_offset]) << 4) | (((int) fr->bsbuf[lame_offset+1]) >> 4)),
-                                               (((((int) fr->bsbuf[lame_offset+1]) << 8) | (((int) fr->bsbuf[lame_offset+2]))) & 0xfff) );
-                                       #ifdef GAPLESS
-                                       if(fr->p.flags & MPG123_GAPLESS)
-                                       {
-                                               off_t length = fr->track_frames * spf(fr);
-                                               off_t skipbegin = GAPLESS_DELAY + ((((int) fr->bsbuf[lame_offset]) << 4) | (((int) fr->bsbuf[lame_offset+1]) >> 4));
-                                               off_t skipend = -GAPLESS_DELAY + (((((int) fr->bsbuf[lame_offset+1]) << 8) | (((int) fr->bsbuf[lame_offset+2]))) & 0xfff);
-                                               debug3("preparing gapless mode for layer3: length %lu, skipbegin %lu, skipend %lu", 
-                                                               (long unsigned)length, (long unsigned)skipbegin, (long unsigned)skipend);
-                                               if(length > 1)
-                                               frame_gapless_init(fr, skipbegin, (skipend < length) ? length-skipend : length);
-                                       }
-                                       #endif
-                               }
-                               /* switch buffer back ... */
-                               fr->bsbuf = fr->bsspace[fr->bsnum]+512;
-                               fr->bsnum = (fr->bsnum + 1) & 1;
-                               return 1; /* got it! */
+                       }
+                       else if(VERBOSE3) fprintf(stderr
+                       ,       "Note: Info: Cannot determine LAME version.\n");
+               }
+               lame_offset += 9; /* 9 in */ 
+
+               /* The 4 big bits are tag revision, the small bits vbr method. */
+               lame_vbr = fr->bsbuf[lame_offset] & 15;
+               lame_offset += 1; /* 10 in */
+               if(VERBOSE3)
+               {
+                       fprintf(stderr, "Note: Info: rev %u\n", fr->bsbuf[lame_offset] >> 4);
+                       fprintf(stderr, "Note: Info: vbr mode %u\n", lame_vbr);
+               }
+               switch(lame_vbr)
+               {
+                       /* from rev1 proposal... not sure if all good in practice */
+                       case 1:
+                       case 8: fr->vbr = MPG123_CBR; break;
+                       case 2:
+                       case 9: fr->vbr = MPG123_ABR; break;
+                       default: fr->vbr = MPG123_VBR; /* 00==unknown is taken as VBR */
+               }
+               lame_offset += 1; /* 11 in, skipping lowpass filter value */
+
+               /* ReplayGain peak ampitude, 32 bit float -- why did I parse it as int
+                  before??     Ah, yes, Lame seems to store it as int since some day in 2003;
+                  I've only seen zeros anyway until now, bah! */
+               if
+               (
+                          (fr->bsbuf[lame_offset]   != 0)
+                       || (fr->bsbuf[lame_offset+1] != 0)
+                       || (fr->bsbuf[lame_offset+2] != 0)
+                       || (fr->bsbuf[lame_offset+3] != 0)
+               )
+               {
+                       debug("Wow! Is there _really_ a non-zero peak value? Now is it stored as float or int - how should I know?");
+                       /* byte*peak_bytes = (byte*) &peak;
+                       ... endianess ... just copy bytes to avoid floating point operation on unaligned memory?
+                       peak_bytes[0] = ...
+                       peak = *(float*) (fr->bsbuf+lame_offset); */
+               }
+               if(VERBOSE3) fprintf(stderr
+               ,       "Note: Info: peak = %f (I won't use this)\n", peak);
+               peak = 0; /* until better times arrived */
+               lame_offset += 4; /* 15 in */
+
+               /* ReplayGain values - lame only writes radio mode gain...
+                  16bit gain, 3 bits name, 3 bits originator, sign (1=-, 0=+),
+                  dB value*10 in 9 bits (fixed point) ignore the setting if name or
+                  originator == 000!
+                  radio      0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 1
+                  audiophile 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 */
+               for(i =0; i < 2; ++i)
+               {
+                       unsigned char gt     =  fr->bsbuf[lame_offset] >> 5;
+                       unsigned char origin = (fr->bsbuf[lame_offset] >> 2) & 0x7;
+                       float factor         = (fr->bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1;
+                       unsigned short gain  = bit_read_short(fr->bsbuf, &lame_offset) & 0x1ff; /* 19 in (2 cycles) */
+                       if(origin == 0 || gt < 1 || gt > 2) continue;
+
+                       --gt;
+                       replay_gain[gt] = factor * (float) gain;
+                       /* Apply gain offset for automatic origin. */
+                       if(origin == 3) replay_gain[gt] += gain_offset;
+               }
+               if(VERBOSE3) 
+               {
+                       fprintf(stderr, "Note: Info: Radio Gain = %03.1fdB\n"
+                       ,       replay_gain[0]);
+                       fprintf(stderr, "Note: Info: Audiophile Gain = %03.1fdB\n"
+                       ,       replay_gain[1]);
+               }
+               for(i=0; i < 2; ++i)
+               {
+                       if(fr->rva.level[i] <= 0)
+                       {
+                               fr->rva.peak[i] = 0; /* TODO: use parsed peak? */
+                               fr->rva.gain[i] = replay_gain[i];
+                               fr->rva.level[i] = 0;
                        }
                }
+
+               lame_offset += 1; /* 20 in, skipping encoding flags byte */
+
+               /* ABR rate */
+               if(fr->vbr == MPG123_ABR)
+               {
+                       fr->abr_rate = fr->bsbuf[lame_offset];
+                       if(VERBOSE3) fprintf(stderr, "Note: Info: ABR rate = %u\n"
+                       ,       fr->abr_rate);
+               }
+               lame_offset += 1; /* 21 in */
+       
+               /* Encoder delay and padding, two 12 bit values
+                  ... lame does write them from int. */
+               pad_in  = ( (((int) fr->bsbuf[lame_offset])   << 4)
+                         | (((int) fr->bsbuf[lame_offset+1]) >> 4) );
+               pad_out = ( (((int) fr->bsbuf[lame_offset+1]) << 8)
+                         |  ((int) fr->bsbuf[lame_offset+2])       ) & 0xfff;
+               lame_offset += 3; /* 24 in */
+               if(VERBOSE3) fprintf(stderr, "Note: Encoder delay = %i; padding = %i\n"
+               ,       (int)pad_in, (int)pad_out);
+               #ifdef GAPLESS
+               if(fr->p.flags & MPG123_GAPLESS)
+               frame_gapless_init(fr, fr->track_frames, pad_in, pad_out);
+               #endif
+               /* final: 24 B LAME data */
        }
-       return 0; /* no lame tag */
+
+check_lame_tag_yes:
+       /* switch buffer back ... */
+       fr->bsbuf = fr->bsspace[fr->bsnum]+512;
+       fr->bsnum = (fr->bsnum + 1) & 1;
+       return 1;
+check_lame_tag_no:
+       return 0;
 }
 
 /* Just tell if the header is some mono. */
 static int header_mono(unsigned long newhead)
 {
-       return ((newhead>>6)&0x3) == MPG_MD_MONO ? TRUE : FALSE;
+       return HDR_CHANNEL_VAL(newhead) == MPG_MD_MONO ? TRUE : FALSE;
 }
 
-/*
-       That's a big one: read the next frame. 1 is success, <= 0 is some error
-       Special error READER_MORE means: Please feed more data and try again.
-*/
-int read_frame(mpg123_handle *fr)
+/* true if the two headers will work with the same decoding routines */
+static int head_compatible(unsigned long fred, unsigned long bret)
 {
-       /* TODO: rework this thing */
-       unsigned long newhead;
-       off_t framepos;
-       int ret;
-       /* stuff that needs resetting if complete frame reading fails */
-       int oldsize  = fr->framesize;
-       int oldphase = fr->halfphase;
-
-       /* The counter for the search-first-header loop.
-          It is persistent outside the loop to prevent seemingly endless loops
-          when repeatedly headers are found that do not have valid followup headers. */
-       int headcount = 0;
+       return ( (fred & HDR_CMPMASK) == (bret & HDR_CMPMASK)
+               &&       header_mono(fred) == header_mono(bret)    );
+}
 
-       fr->fsizeold=fr->framesize;       /* for Layer3 */
+static void halfspeed_prepare(mpg123_handle *fr)
+{
+       /* save for repetition */
+       if(fr->p.halfspeed && fr->lay == 3)
+       {
+               debug("halfspeed - reusing old bsbuf ");
+               memcpy (fr->ssave, fr->bsbuf, fr->ssize);
+       }
+}
 
+/* If this returns 1, the next frame is the repetition. */
+static int halfspeed_do(mpg123_handle *fr)
+{
        /* Speed-down hack: Play it again, Sam (the frame, I mean). */
        if (fr->p.halfspeed) 
        {
@@ -447,6 +469,45 @@ int read_frame(mpg123_handle *fr)
                        fr->halfphase = fr->p.halfspeed - 1;
                }
        }
+       return 0;
+}
+
+/* 
+       Temporary macro until we got this worked out.
+       Idea is to filter out special return values that shall trigger direct jumps to end / resync / read again. 
+       Particularily, the generic ret==PARSE_BAD==0 and ret==PARSE_GOOD==1 are not affected.
+*/
+#define JUMP_CONCLUSION(ret) \
+{ \
+if(ret < 0){ debug1("%s", ret == MPG123_NEED_MORE ? "need more" : "read error"); goto read_frame_bad; } \
+else if(ret == PARSE_AGAIN) goto read_again; \
+else if(ret == PARSE_RESYNC) goto init_resync; \
+else if(ret == PARSE_END){ ret=0; goto read_frame_bad; } \
+}
+
+/*
+       That's a big one: read the next frame. 1 is success, <= 0 is some error
+       Special error READER_MORE means: Please feed more data and try again.
+*/
+int read_frame(mpg123_handle *fr)
+{
+       /* TODO: rework this thing */
+       int freeformat_count = 0;
+       unsigned long newhead;
+       off_t framepos;
+       int ret;
+       /* stuff that needs resetting if complete frame reading fails */
+       int oldsize  = fr->framesize;
+       int oldphase = fr->halfphase;
+
+       /* The counter for the search-first-header loop.
+          It is persistent outside the loop to prevent seemingly endless loops
+          when repeatedly headers are found that do not have valid followup headers. */
+       long headcount = 0;
+
+       fr->fsizeold=fr->framesize;       /* for Layer3 */
+
+       if(halfspeed_do(fr) == 1) return 1;
 
 read_again:
        /* In case we are looping to find a valid frame, discard any buffered data before the current position.
@@ -454,269 +515,40 @@ read_again:
        if(fr->rd->forget != NULL) fr->rd->forget(fr);
 
        debug2("trying to get frame %"OFF_P" at %"OFF_P, (off_p)fr->num+1, (off_p)fr->rd->tell(fr));
-       if((ret = fr->rd->head_read(fr,&newhead)) <= 0){ debug("need more?"); goto read_frame_bad;}
+       if((ret = fr->rd->head_read(fr,&newhead)) <= 0){ debug1("need more? (%i)", ret); goto read_frame_bad;}
 
 init_resync:
 
-       fr->header_change = 2; /* output format change is possible... */
-       if(fr->oldhead)        /* check a following header for change */
-       {
-               if(fr->oldhead == newhead) fr->header_change = 0;
-               else
-               /* If they have the same sample rate. Note that only is _not_ the case for the first header, as we enforce sample rate match for following frames.
-                        So, during one stream, only change of stereoness is possible and indicated by header_change == 2. */
-               if((fr->oldhead & HDRSAMPMASK) == (newhead & HDRSAMPMASK))
-               {
-                       /* Now if both channel modes are mono or both stereo, it's no big deal. */
-                       if( header_mono(fr->oldhead) == header_mono(newhead))
-                       fr->header_change = 1;
-               }
-       }
-
 #ifdef SKIP_JUNK
-       /* watch out for junk/tags on beginning of stream by invalid header */
-       if(!fr->firsthead && !head_check(newhead)) {
-
-               /* check for id3v2; first three bytes (of 4) are "ID3" */
-               if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
-               {
-                       int id3ret = 0;
-                       id3ret = parse_new_id3(fr, newhead);
-                       if     (id3ret < 0){ debug("need more?"); ret = id3ret; goto read_frame_bad; }
-#ifndef NO_ID3V2
-                       else if(id3ret > 0){ debug("got ID3v2"); fr->metaflags  |= MPG123_NEW_ID3|MPG123_ID3; }
-                       else debug("no useful ID3v2");
-#endif
-
-                       fr->oldhead = 0;
-                       goto read_again; /* Also in case of invalid ID3 tag (ret==0), try to get on track again. */
-               }
-               else if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Junk at the beginning (0x%08lx)\n",newhead);
-
-               /* I even saw RIFF headers at the beginning of MPEG streams ;( */
-               if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') {
-                       if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr, "Note: Looks like a RIFF header.\n");
-
-                       if((ret=fr->rd->head_read(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
-
-                       while(newhead != ('d'<<24)+('a'<<16)+('t'<<8)+'a')
-                       {
-                               if((ret=fr->rd->head_shift(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
-                       }
-                       if((ret=fr->rd->head_read(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
-
-                       if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Skipped RIFF header!\n");
-
-                       fr->oldhead = 0;
-                       goto read_again;
-               }
-               /* unhandled junk... just continue search for a header */
-               /* step in byte steps through next 64K */
-               debug("searching for header...");
-
-               ret = 0; /* We will check the value after the loop. */
-               for(; headcount<65536; headcount++)
-               {
-                       if((ret=fr->rd->head_shift(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
-                       /* if(head_check(newhead)) */
-                       if(head_check(newhead) && (ret=decode_header(fr, newhead)))
-                               break;
-               }
-               if(ret<0){ debug("need more?"); goto read_frame_bad; }
-
-               if(headcount == 65536)
-               {
-                       if(NOQUIET) error("Giving up searching valid MPEG header after (over) 64K of junk.");
-                       return 0;
-               }
-               else debug1("hopefully found one at %"OFF_P, (off_p)fr->rd->tell(fr));
-               /* 
-                * should we additionaly check, whether a new frame starts at
-                * the next expected position? (some kind of read ahead)
-                * We could implement this easily, at least for files.
-                */
-       }
-#endif
-
-       /* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */
-       if(!fr->firsthead && fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED) && head_check(newhead) && (ret=decode_header(fr, newhead)))
+       if(!fr->firsthead && !head_check(newhead))
        {
-               unsigned long nexthead = 0;
-               int hd = 0;
-               off_t start = fr->rd->tell(fr);
-               if(ret<0){ debug("need more?"); goto read_frame_bad; }
-
-               debug2("doing ahead check with BPF %d at %"OFF_P, fr->framesize+4, (off_p)start);
-               /* step framesize bytes forward and read next possible header*/
-               if((ret=fr->rd->skip_bytes(fr, fr->framesize))<0)
-               {
-                       if(ret==READER_ERROR && NOQUIET) error("cannot seek!");
-                       goto read_frame_bad;
-               }
-               hd = fr->rd->head_read(fr,&nexthead);
-               if(hd==MPG123_NEED_MORE){ debug("need more?"); ret = hd; goto read_frame_bad; }
-               if((ret=fr->rd->back_bytes(fr, fr->rd->tell(fr)-start))<0)
-               {
-                       if(ret==READER_ERROR && NOQUIET) error("cannot seek!");
-                       else debug("need more?"); 
-                       goto read_frame_bad;
-               }
-               debug1("After fetching next header, at %"OFF_P, (off_p)fr->rd->tell(fr));
-               if(!hd)
-               {
-                       if(NOQUIET) warning("cannot read next header, a one-frame stream? Duh...");
-               }
-               else
-               {
-                       debug2("does next header 0x%08lx match first 0x%08lx?", nexthead, newhead);
-                       /* not allowing free format yet */
-                       if(!head_check(nexthead) || (nexthead & HDRCMPMASK) != (newhead & HDRCMPMASK))
-                       {
-                               debug("No, the header was not valid, start from beginning...");
-                               fr->oldhead = 0; /* start over */
-                               /* try next byte for valid header */
-                               if((ret=fr->rd->back_bytes(fr, 3))<0)
-                               {
-                                       if(NOQUIET) error("cannot seek!");
-                                       else debug("need more?"); 
-                                       goto read_frame_bad;
-                               }
-                               goto read_again;
-                       }
-               }
+               ret = skip_junk(fr, &newhead, &headcount);
+               JUMP_CONCLUSION(ret);
        }
+#endif
 
-       /* why has this head check been avoided here before? */
-       if(!head_check(newhead))
-       {
-               /* and those ugly ID3 tags */
-               if((newhead & 0xffffff00) == ('T'<<24)+('A'<<16)+('G'<<8))
-               {
-                       fr->id3buf[0] = (unsigned char) ((newhead >> 24) & 0xff);
-                       fr->id3buf[1] = (unsigned char) ((newhead >> 16) & 0xff);
-                       fr->id3buf[2] = (unsigned char) ((newhead >> 8)  & 0xff);
-                       fr->id3buf[3] = (unsigned char) ( newhead        & 0xff);
-                       if((ret=fr->rd->fullread(fr,fr->id3buf+4,124)) < 0){ debug("need more?"); goto read_frame_bad; }
-                       fr->metaflags  |= MPG123_NEW_ID3|MPG123_ID3;
-                       fr->rdat.flags |= READER_ID3TAG; /* that marks id3v1 */
-                       if (VERBOSE3) fprintf(stderr,"Note: Skipped ID3v1 tag.\n");
-                       goto read_again;
-               }
-               /* duplicated code from above! */
-               /* check for id3v2; first three bytes (of 4) are "ID3" */
-               if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
-               {
-                       int id3length = 0;
-                       id3length = parse_new_id3(fr, newhead);
-                       if(id3length < 0){ debug("need more?"); ret = id3length; goto read_frame_bad; }
-
-                       fr->metaflags  |= MPG123_NEW_ID3|MPG123_ID3;
-                       goto read_again;
-               }
-               else if(NOQUIET && fr->silent_resync == 0)
-               {
-                       fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset %"OFF_P".\n",
-                               newhead, (off_p)fr->rd->tell(fr)-4);
-               }
-
-               if(NOQUIET && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n");
-               /* Do resync if not forbidden by flag.
-               I used to have a check for not-icy-meta here, but concluded that the desync issues came from a reader bug, not the stream. */
-               if( !(fr->p.flags & MPG123_NO_RESYNC) )
-               {
-                       long try = 0;
-                       long limit = fr->p.resync_limit;
-                       
-                       /* If a resync is needed the bitreservoir of previous frames is no longer valid */
-                       fr->bitreservoir = 0;
-
-                       /* TODO: make this more robust, I'd like to cat two mp3 fragments together (in a dirty way) and still have mpg123 beign able to decode all it somehow. */
-                       if(NOQUIET && fr->silent_resync == 0) fprintf(stderr, "Note: Trying to resync...\n");
-                       /* Read more bytes until we find something that looks
-                        reasonably like a valid header.  This is not a
-                        perfect strategy, but it should get us back on the
-                        track within a short time (and hopefully without
-                        too much distortion in the audio output).  */
-                       do
-                       {
-                               ++try;
-                               if(limit >= 0 && try >= limit) break;                           
-
-                               if((ret=fr->rd->head_shift(fr,&newhead)) <= 0)
-                               {
-                                       debug("need more?");
-                                       if(NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n");
+       ret = head_check(newhead);
+       if(ret) ret = decode_header(fr, newhead, &freeformat_count);
 
-                                       goto read_frame_bad;
-                               }
-                               if(VERBOSE3) debug3("resync try %li at %"OFF_P", got newhead 0x%08lx", try, (off_p)fr->rd->tell(fr),  newhead);
-
-                               if(!fr->oldhead)
-                               {
-                                       debug("going to init_resync...");
-                                       goto init_resync;       /* "considered harmful", eh? */
-                               }
-                               /* we should perhaps collect a list of valid headers that occured in file... there can be more */
-                               /* Michael's new resync routine seems to work better with the one frame readahead (and some input buffering?) */
-                       } while
-                       (
-                               !head_check(newhead) /* Simply check for any valid header... we have the readahead to get it straight now(?) */
-                               /*   (newhead & HDRCMPMASK) != (fr->oldhead & HDRCMPMASK)
-                               && (newhead & HDRCMPMASK) != (fr->firsthead & HDRCMPMASK)*/
-                       );
-                       /* too many false positives 
-                       }while (!(head_check(newhead) && decode_header(fr, newhead))); */
-                       if(NOQUIET && fr->silent_resync == 0) fprintf (stderr, "Note: Skipped %li bytes in input.\n", try);
-
-                       if(limit >= 0 && try >= limit)
-                       {
-                               if(NOQUIET)
-                               error1("Giving up resync after %li bytes - your stream is not nice... (maybe increasing resync limit could help).", try);
-
-                               fr->err = MPG123_RESYNC_FAIL;
-                               return READER_ERROR;
-                       }
-                       else
-                       {
-                               debug1("Found valid header 0x%lx... unsetting firsthead to reinit stream.", newhead);
-                               fr->firsthead = 0;
-                               goto init_resync;
-                       }
-               }
-               else
-               {
-                       if(NOQUIET) error("not attempting to resync...");
-
-                       fr->err = MPG123_OUT_OF_SYNC;
-                       return READER_ERROR;
-               }
+       JUMP_CONCLUSION(ret); /* That only continues for ret == PARSE_BAD or PARSE_GOOD. */
+       if(ret == PARSE_BAD)
+       { /* Header was not good. */
+               ret = wetwork(fr, &newhead); /* Messy stuff, handle junk, resync ... */
+               JUMP_CONCLUSION(ret);
+               /* Normally, we jumped already. If for some reason everything's fine to continue, do continue. */
+               if(ret != PARSE_GOOD) goto read_frame_bad;
        }
 
-       /* Man, that code looks awfully redundant...
-          I need to untangle the spaghetti here in a future version. */
        if(!fr->firsthead)
        {
-               ret=decode_header(fr,newhead);
-               if(ret == 0)
-               {
-                       if(NOQUIET) error("decode header failed before first valid one, going to read again");
-
-                       goto read_again;
-               }
-               else if(ret < 0){ debug("need more?"); goto read_frame_bad; }
-       }
-       else
-       {
-               ret=decode_header(fr,newhead);
-               if(ret == 0)
-               {
-                       if(NOQUIET) error("decode header failed - goto resync");
-                       /* return 0; */
-                       goto init_resync;
-               }
-               else if(ret < 0){ debug("need more?"); goto read_frame_bad; }
+               ret = do_readahead(fr, newhead);
+               /* readahead can fail mit NEED_MORE, in which case we must also make the just read header available again for next go */
+               if(ret < 0) fr->rd->back_bytes(fr, 4);
+               JUMP_CONCLUSION(ret);
        }
 
+       /* Now we should have our valid header and proceed to reading the frame. */
+
        /* if filepos is invalid, so is framepos */
        framepos = fr->rd->tell(fr) - 4;
        /* flip/init buffer for Layer 3 */
@@ -770,19 +602,29 @@ init_resync:
        ++fr->num; /* 0 for first frame! */
        debug4("Frame %"OFF_P" %08lx %i, next filepos=%"OFF_P, 
        (off_p)fr->num, newhead, fr->framesize, (off_p)fr->rd->tell(fr));
-
-       /* save for repetition */
-       if(fr->p.halfspeed && fr->lay == 3)
+       if(!(fr->state_flags & FRAME_FRANKENSTEIN) && (
+               (fr->track_frames > 0 && fr->num >= fr->track_frames)
+#ifdef GAPLESS
+               || (fr->gapless_frames > 0 && fr->num >= fr->gapless_frames)
+#endif
+       ))
        {
-               debug("halfspeed - reusing old bsbuf ");
-               memcpy (fr->ssave, fr->bsbuf, fr->ssize);
+               fr->state_flags |= FRAME_FRANKENSTEIN;
+               if(NOQUIET) fprintf(stderr, "\nWarning: Encountered more data after announced end of track (frame %"OFF_P"/%"OFF_P"). Frankenstein!\n", (off_p)fr->num, 
+#ifdef GAPLESS
+               fr->gapless_frames > 0 ? (off_p)fr->gapless_frames : 
+#endif
+               (off_p)fr->track_frames);
        }
 
+       halfspeed_prepare(fr);
+
        /* index the position */
+       fr->input_offset = framepos;
 #ifdef FRAME_INDEX
        /* Keep track of true frame positions in our frame index.
           but only do so when we are sure that the frame number is accurate... */
-       if(fr->accurate && FI_NEXT(fr->index, fr->num))
+       if((fr->state_flags & FRAME_ACCURATE) && FI_NEXT(fr->index, fr->num))
        fi_add(&fr->index, framepos);
 #endif
 
@@ -793,9 +635,46 @@ init_resync:
        fr->to_decode = fr->to_ignore = TRUE;
        if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */
 
+       /*
+               Let's check for header change after deciding that the new one is good
+               and actually having read a frame.
+
+               header_change > 1: decoder structure has to be updated
+               Preserve header_change value from previous runs if it is serious.
+               If we still have a big change pending, it should be dealt with outside,
+               fr->header_change set to zero afterwards.
+       */
+       if(fr->header_change < 2)
+       {
+               fr->header_change = 2; /* output format change is possible... */
+               if(fr->oldhead)        /* check a following header for change */
+               {
+                       if(fr->oldhead == newhead) fr->header_change = 0;
+                       else
+                       /* Headers that match in this test behave the same for the outside world.
+                          namely: same decoding routines, same amount of decoded data. */
+                       if(head_compatible(fr->oldhead, newhead))
+                       fr->header_change = 1;
+                       else
+                       {
+                               fr->state_flags |= FRAME_FRANKENSTEIN;
+                               if(NOQUIET)
+                               fprintf(stderr, "\nWarning: Big change (MPEG version, layer, rate). Frankenstein stream?\n");
+                       }
+               }
+               else if(fr->firsthead && !head_compatible(fr->firsthead, newhead))
+               {
+                       fr->state_flags |= FRAME_FRANKENSTEIN;
+                       if(NOQUIET)
+                       fprintf(stderr, "\nWarning: Big change from first (MPEG version, layer, rate). Frankenstein stream?\n");
+               }
+       }
+
+       fr->oldhead = newhead;
+
        return 1;
 read_frame_bad:
-       /* Also if we searched for valid data in vain, we can forget skipped data.
+       /* Also if we searched for valid data in vein, we can forget skipped data.
           Otherwise, the feeder would hold every dead old byte in memory until the first valid frame! */
        if(fr->rd->forget != NULL) fr->rd->forget(fr);
 
@@ -811,11 +690,11 @@ read_frame_bad:
 /*
  * read ahead and find the next MPEG header, to guess framesize
  * return value: success code
- *  1: found a valid frame size (stored in the handle).
+ *  PARSE_GOOD: found a valid frame size (stored in the handle).
  * <0: error codes, possibly from feeder buffer (NEED_MORE)
- *  0: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...)
+ *  PARSE_BAD: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...)
  */
-static int guess_freeformat_framesize(mpg123_handle *fr)
+static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead)
 {
        long i;
        int ret;
@@ -824,48 +703,26 @@ static int guess_freeformat_framesize(mpg123_handle *fr)
        {
                if(NOQUIET) error("Cannot look for freeformat frame size with non-seekable and non-buffered stream!");
 
-               return 0;
+               return PARSE_BAD;
        }
        if((ret=fr->rd->head_read(fr,&head))<=0)
        return ret;
 
        /* We are already 4 bytes into it */
-/* fix that limit to be absolute for the first header search! */
-       for(i=4;i<65536;i++) {
-               if((ret=fr->rd->head_shift(fr,&head))<=0)
+       for(i=4;i<MAXFRAMESIZE+4;i++)
+       {
+               if((ret=fr->rd->head_shift(fr,&head))<=0) return ret;
+
+               /* No head_check needed, the mask contains all relevant bits. */
+               if((head & HDR_SAMEMASK) == (oldhead & HDR_SAMEMASK))
                {
-                       return ret;
-               }
-               if(head_check(head))
-               {
-                       int sampling_frequency,mpeg25,lsf;
-                       
-                       if(head & (1<<20))
-                       {
-                               lsf = (head & (1<<19)) ? 0x0 : 0x1;
-                               mpeg25 = 0;
-                       }
-                       else
-                       {
-                               lsf = 1;
-                               mpeg25 = 1;
-                       }
-                       
-                       if(mpeg25)
-                               sampling_frequency = 6 + ((head>>10)&0x3);
-                       else
-                               sampling_frequency = ((head>>10)&0x3) + (lsf*3);
-                       
-                       if((lsf==fr->lsf) && (mpeg25==fr->mpeg25) && (sampling_frequency == fr->sampling_frequency))
-                       {
-                               fr->rd->back_bytes(fr,i+1);
-                               fr->framesize = i-3;
-                               return 1; /* Success! */
-                       }
+                       fr->rd->back_bytes(fr,i+1);
+                       fr->framesize = i-3;
+                       return PARSE_GOOD; /* Success! */
                }
        }
        fr->rd->back_bytes(fr,i);
-       return 0;
+       return PARSE_BAD;
 }
 
 
@@ -876,64 +733,51 @@ static int guess_freeformat_framesize(mpg123_handle *fr)
  *  1: success
  *  0: no valid header
  * <0: some error
+ * You are required to do a head_check() before calling!
  */
-static int decode_header(mpg123_handle *fr,unsigned long newhead)
+static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count)
 {
+#ifdef DEBUG /* Do not waste cycles checking the header twice all the time. */
        if(!head_check(newhead))
        {
-               if(NOQUIET) error("tried to decode obviously invalid header");
-
-               return 0;
+               error1("trying to decode obviously invalid header 0x%08lx", newhead);
        }
-       if( newhead & (1<<20) )
+#endif
+       /* For some reason, the layer and sampling freq settings used to be wrapped
+          in a weird conditional including MPG123_NO_RESYNC. What was I thinking?
+          This information has to be consistent. */
+       fr->lay = 4 - HDR_LAYER_VAL(newhead);
+
+       if(HDR_VERSION_VAL(newhead) & 0x2)
        {
-               fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
+               fr->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1;
                fr->mpeg25 = 0;
+               fr->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fr->lsf*3);
        }
        else
        {
                fr->lsf = 1;
                fr->mpeg25 = 1;
-       }
-
-       if(   (fr->p.flags & MPG123_NO_RESYNC) || !fr->oldhead
-          || (((fr->oldhead>>19)&0x3) ^ ((newhead>>19)&0x3))  )
-       {
-               /* If "tryresync" is false, assume that certain
-               parameters do not change within the stream!
-               Force an update if lsf or mpeg25 settings
-               have changed. */
-               fr->lay = 4-((newhead>>17)&3);
-               if( ((newhead>>10)&0x3) == 0x3)
-               {
-                       if(NOQUIET) error("Stream error");
-
-                       return 0; /* exit() here really is too much, isn't it? */
-               }
-               if(fr->mpeg25)
-               fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
-               else
-               fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
+               fr->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead);
        }
 
        #ifdef DEBUG
-       if((((newhead>>16)&0x1)^0x1) != fr->error_protection) debug("changed crc bit!");
+       /* seen a file where this varies (old lame tag without crc, track with crc) */
+       if((HDR_CRC_VAL(newhead)^0x1) != fr->error_protection) debug("changed crc bit!");
        #endif
-       fr->error_protection = ((newhead>>16)&0x1)^0x1; /* seen a file where this varies (old lame tag without crc, track with crc) */
-       fr->bitrate_index = ((newhead>>12)&0xf);
-       fr->padding   = ((newhead>>9)&0x1);
-       fr->extension = ((newhead>>8)&0x1);
-       fr->mode      = ((newhead>>6)&0x3);
-       fr->mode_ext  = ((newhead>>4)&0x3);
-       fr->copyright = ((newhead>>3)&0x1);
-       fr->original  = ((newhead>>2)&0x1);
-       fr->emphasis  = newhead & 0x3;
-       fr->freeformat = free_format_header(newhead);
-
-       fr->stereo    = (fr->mode == MPG_MD_MONO) ? 1 : 2;
+       fr->error_protection = HDR_CRC_VAL(newhead)^0x1;
+       fr->bitrate_index    = HDR_BITRATE_VAL(newhead);
+       fr->padding          = HDR_PADDING_VAL(newhead);
+       fr->extension        = HDR_PRIVATE_VAL(newhead);
+       fr->mode             = HDR_CHANNEL_VAL(newhead);
+       fr->mode_ext         = HDR_CHANEX_VAL(newhead);
+       fr->copyright        = HDR_COPYRIGHT_VAL(newhead);
+       fr->original         = HDR_ORIGINAL_VAL(newhead);
+       fr->emphasis         = HDR_EMPHASIS_VAL(newhead);
+       fr->freeformat       = !(newhead & HDR_BITRATE);
+
+       fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
 
-       fr->oldhead = newhead;
-       
        /* we can't use tabsel_123 for freeformat, so trying to guess framesize... */
        if(fr->freeformat)
        {
@@ -941,8 +785,14 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead)
                if(fr->freeformat_framesize < 0)
                {
                        int ret;
-                       ret = guess_freeformat_framesize(fr);
-                       if(ret>0)
+                       *freeformat_count += 1;
+                       if(*freeformat_count > 5)
+                       {
+                               if(VERBOSE3) error("You fooled me too often. Refusing to guess free format frame size _again_.");
+                               return PARSE_BAD;
+                       }
+                       ret = guess_freeformat_framesize(fr, newhead);
+                       if(ret == PARSE_GOOD)
                        {
                                fr->freeformat_framesize = fr->framesize - fr->padding;
                                if(VERBOSE2)
@@ -952,8 +802,9 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead)
                        {
                                if(ret == MPG123_NEED_MORE)
                                debug("Need more data to guess free format frame size.");
-                               else
+                               else if(VERBOSE3)
                                error("Encountered free format header, but failed to guess frame size.");
+
                                return ret;
                        }
                }
@@ -968,6 +819,7 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead)
        {
 #ifndef NO_LAYER1
                case 1:
+                       fr->spf = 384;
                        fr->do_layer = do_layer1;
                        if(!fr->freeformat)
                        {
@@ -979,6 +831,7 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead)
 #endif
 #ifndef NO_LAYER2
                case 2:
+                       fr->spf = 1152;
                        fr->do_layer = do_layer2;
                        if(!fr->freeformat)
                        {
@@ -991,6 +844,7 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead)
 #endif
 #ifndef NO_LAYER3
                case 3:
+                       fr->spf = fr->lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/
                        fr->do_layer = do_layer3;
                        if(fr->lsf)
                        fr->ssize = (fr->stereo == 1) ? 9 : 17;
@@ -1011,15 +865,15 @@ static int decode_header(mpg123_handle *fr,unsigned long newhead)
                default:
                        if(NOQUIET) error1("Layer type %i not supported in this build!", fr->lay); 
 
-                       return 0;
+                       return PARSE_BAD;
        }
        if (fr->framesize > MAXFRAMESIZE)
        {
                if(NOQUIET) error1("Frame size too big: %d", fr->framesize+4-fr->padding);
 
-               return (0);
+               return PARSE_BAD;
        }
-       return 1;
+       return PARSE_GOOD;
 }
 
 void set_pointer(mpg123_handle *fr, long backstep)
@@ -1057,11 +911,18 @@ double compute_bpf(mpg123_handle *fr)
        return bpf;
 }
 
+int attribute_align_arg mpg123_spf(mpg123_handle *mh)
+{
+       if(mh == NULL) return MPG123_ERR;
+
+       return mh->firsthead ? mh->spf : MPG123_ERR;
+}
+
 double attribute_align_arg mpg123_tpf(mpg123_handle *fr)
 {
        static int bs[4] = { 0,384,1152,1152 };
        double tpf;
-       if(fr == NULL) return -1;
+       if(fr == NULL || !fr->firsthead) return MPG123_ERR;
 
        tpf = (double) bs[fr->lay];
        tpf /= freqs[fr->sampling_frequency] << (fr->lsf);
@@ -1077,11 +938,7 @@ int attribute_align_arg mpg123_position(mpg123_handle *fr, off_t no, off_t buffs
        off_t cur, left;
        double curs, lefts;
 
-       if(!fr || !fr->rd) /* Isn't this too paranoid? */
-       {
-               debug("reader troubles!");
-               return MPG123_ERR;
-       }
+       if(!fr || !fr->rd) return MPG123_ERR;
 
        no += fr->num; /* no starts out as offset */
        cur = no;
@@ -1150,3 +1007,263 @@ int get_songlen(mpg123_handle *fr,int no)
        tpf = mpg123_tpf(fr);
        return (int) (no*tpf);
 }
+
+/* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */
+static int do_readahead(mpg123_handle *fr, unsigned long newhead)
+{
+       unsigned long nexthead = 0;
+       int hd = 0;
+       off_t start, oret;
+       int ret;
+
+       if( ! (!fr->firsthead && fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED)) )
+       return PARSE_GOOD;
+
+       start = fr->rd->tell(fr);
+
+       debug2("doing ahead check with BPF %d at %"OFF_P, fr->framesize+4, (off_p)start);
+       /* step framesize bytes forward and read next possible header*/
+       if((oret=fr->rd->skip_bytes(fr, fr->framesize))<0)
+       {
+               if(oret==READER_ERROR && NOQUIET) error("cannot seek!");
+
+               return oret == MPG123_NEED_MORE ? PARSE_MORE : PARSE_ERR;
+       }
+
+       /* Read header, seek back. */
+       hd = fr->rd->head_read(fr,&nexthead);
+       if( fr->rd->back_bytes(fr, fr->rd->tell(fr)-start) < 0 )
+       {
+               if(NOQUIET) error("Cannot seek back!");
+
+               return PARSE_ERR;
+       }
+       if(hd == MPG123_NEED_MORE) return PARSE_MORE;
+
+       debug1("After fetching next header, at %"OFF_P, (off_p)fr->rd->tell(fr));
+       if(!hd)
+       {
+               if(NOQUIET) warning("Cannot read next header, a one-frame stream? Duh...");
+               return PARSE_END;
+       }
+
+       debug2("does next header 0x%08lx match first 0x%08lx?", nexthead, newhead);
+       if(!head_check(nexthead) || !head_compatible(newhead, nexthead))
+       {
+               debug("No, the header was not valid, start from beginning...");
+               fr->oldhead = 0; /* start over */
+               /* try next byte for valid header */
+               if((ret=fr->rd->back_bytes(fr, 3))<0)
+               {
+                       if(NOQUIET) error("Cannot seek 3 bytes back!");
+
+                       return PARSE_ERR;
+               }
+               return PARSE_AGAIN;
+       }
+       else return PARSE_GOOD;
+}
+
+static int handle_id3v2(mpg123_handle *fr, unsigned long newhead)
+{
+       int ret;
+       fr->oldhead = 0; /* Think about that. Used to be present only for skipping of junk, not resync-style wetwork. */
+       ret = parse_new_id3(fr, newhead);
+       if     (ret < 0) return ret;
+#ifndef NO_ID3V2
+       else if(ret > 0){ debug("got ID3v2"); fr->metaflags  |= MPG123_NEW_ID3|MPG123_ID3; }
+       else debug("no useful ID3v2");
+#endif
+       return PARSE_AGAIN;
+}
+
+/* Advance a byte in stream to get next possible header and forget 
+   buffered data if possible (for feed reader). */
+#define FORGET_INTERVAL 1024 /* Used by callers to set forget flag each <n> bytes. */
+static int forget_head_shift(mpg123_handle *fr, unsigned long *newheadp, int forget)
+{
+       int ret;
+       if((ret=fr->rd->head_shift(fr,newheadp))<=0) return ret;
+       /* Try to forget buffered data as early as possible to speed up parsing where
+          new data needs to be added for resync (and things would be re-parsed again
+          and again because of the start from beginning after hitting end). */
+       if(forget && fr->rd->forget != NULL)
+       {
+               /* Ensure that the last 4 bytes stay in buffers for reading the header
+                  anew. */
+               if(!fr->rd->back_bytes(fr, 4))
+               {
+                       fr->rd->forget(fr);
+                       fr->rd->back_bytes(fr, -4);
+               }
+       }
+       return ret; /* No surprise here, error already triggered early return. */
+}
+
+/* watch out for junk/tags on beginning of stream by invalid header */
+static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount)
+{
+       int ret;
+       int freeformat_count = 0;
+       long limit = 65536;
+       unsigned long newhead = *newheadp;
+       unsigned int forgetcount = 0;
+       /* check for id3v2; first three bytes (of 4) are "ID3" */
+       if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
+       {
+               return handle_id3v2(fr, newhead);
+       }
+       else if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Junk at the beginning (0x%08lx)\n",newhead);
+
+       /* I even saw RIFF headers at the beginning of MPEG streams ;( */
+       if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F')
+       {
+               if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr, "Note: Looks like a RIFF header.\n");
+
+               if((ret=fr->rd->head_read(fr,&newhead))<=0) return ret;
+
+               while(newhead != ('d'<<24)+('a'<<16)+('t'<<8)+'a')
+               {
+                       if(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
+                       if((ret=forget_head_shift(fr,&newhead,!forgetcount))<=0) return ret;
+               }
+               if((ret=fr->rd->head_read(fr,&newhead))<=0) return ret;
+
+               if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Skipped RIFF header!\n");
+
+               fr->oldhead = 0;
+               *newheadp = newhead;
+               return PARSE_AGAIN;
+       }
+
+       /*
+               Unhandled junk... just continue search for a header, stepping in single bytes through next 64K.
+               This is rather identical to the resync loop.
+       */
+       debug("searching for header...");
+       *newheadp = 0; /* Invalidate the external value. */
+       ret = 0; /* We will check the value after the loop. */
+
+       /* We prepare for at least the 64K bytes as usual, unless
+          user explicitly wanted more (even infinity). Never less. */
+       if(fr->p.resync_limit < 0 || fr->p.resync_limit > limit)
+       limit = fr->p.resync_limit;
+
+       do
+       {
+               ++(*headcount);
+               if(limit >= 0 && *headcount >= limit) break;                            
+
+               if(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
+               if((ret=forget_head_shift(fr, &newhead, !forgetcount))<=0) return ret;
+
+               if(head_check(newhead) && (ret=decode_header(fr, newhead, &freeformat_count))) break;
+       } while(1);
+       if(ret<0) return ret;
+
+       if(limit >= 0 && *headcount >= limit)
+       {
+               if(NOQUIET) error1("Giving up searching valid MPEG header after %li bytes of junk.", *headcount);
+               return PARSE_END;
+       }
+       else debug1("hopefully found one at %"OFF_P, (off_p)fr->rd->tell(fr));
+
+       /* If the new header ist good, it is already decoded. */
+       *newheadp = newhead;
+       return PARSE_GOOD;
+}
+
+/* The newhead is bad, so let's check if it is something special, otherwise just resync. */
+static int wetwork(mpg123_handle *fr, unsigned long *newheadp)
+{
+       int ret = PARSE_ERR;
+       unsigned long newhead = *newheadp;
+       *newheadp = 0;
+
+       /* Classic ID3 tags. Read, then start parsing again. */
+       if((newhead & 0xffffff00) == ('T'<<24)+('A'<<16)+('G'<<8))
+       {
+               fr->id3buf[0] = (unsigned char) ((newhead >> 24) & 0xff);
+               fr->id3buf[1] = (unsigned char) ((newhead >> 16) & 0xff);
+               fr->id3buf[2] = (unsigned char) ((newhead >> 8)  & 0xff);
+               fr->id3buf[3] = (unsigned char) ( newhead        & 0xff);
+
+               if((ret=fr->rd->fullread(fr,fr->id3buf+4,124)) < 0) return ret;
+
+               fr->metaflags  |= MPG123_NEW_ID3|MPG123_ID3;
+               fr->rdat.flags |= READER_ID3TAG; /* that marks id3v1 */
+               if(VERBOSE3) fprintf(stderr,"Note: Skipped ID3v1 tag.\n");
+
+               return PARSE_AGAIN;
+       }
+       /* This is similar to initial junk skipping code... */
+       /* Check for id3v2; first three bytes (of 4) are "ID3" */
+       if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
+       {
+               return handle_id3v2(fr, newhead);
+       }
+       else if(NOQUIET && fr->silent_resync == 0)
+       {
+               fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset %"OFF_P".\n",
+                       newhead, (off_p)fr->rd->tell(fr)-4);
+       }
+
+       /* Now we got something bad at hand, try to recover. */
+
+       if(NOQUIET && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n");
+
+       if( !(fr->p.flags & MPG123_NO_RESYNC) )
+       {
+               long try = 0;
+               long limit = fr->p.resync_limit;
+               unsigned int forgetcount = 0;
+
+               /* If a resync is needed the bitreservoir of previous frames is no longer valid */
+               fr->bitreservoir = 0;
+
+               if(NOQUIET && fr->silent_resync == 0) fprintf(stderr, "Note: Trying to resync...\n");
+
+               do /* ... shift the header with additional single bytes until be found something that could be a header. */
+               {
+                       ++try;
+                       if(limit >= 0 && try >= limit) break;                           
+
+                       if(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
+                       if((ret=forget_head_shift(fr,&newhead,!forgetcount)) <= 0)
+                       {
+                               *newheadp = newhead;
+                               if(NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n");
+
+                               return ret ? ret : PARSE_END;
+                       }
+                       if(VERBOSE3) debug3("resync try %li at %"OFF_P", got newhead 0x%08lx", try, (off_p)fr->rd->tell(fr),  newhead);
+               } while(!head_check(newhead));
+
+               *newheadp = newhead;
+               if(NOQUIET && fr->silent_resync == 0) fprintf (stderr, "Note: Skipped %li bytes in input.\n", try);
+
+               /* Now we either got something that could be a header, or we gave up. */
+               if(limit >= 0 && try >= limit)
+               {
+                       if(NOQUIET)
+                       error1("Giving up resync after %li bytes - your stream is not nice... (maybe increasing resync limit could help).", try);
+
+                       fr->err = MPG123_RESYNC_FAIL;
+                       return PARSE_ERR;
+               }
+               else
+               {
+                       debug1("Found possibly valid header 0x%lx... unsetting oldhead to reinit stream.", newhead);
+                       fr->oldhead = 0;
+                       return PARSE_RESYNC;
+               }
+       }
+       else
+       {
+               if(NOQUIET) error("not attempting to resync...");
+
+               fr->err = MPG123_OUT_OF_SYNC;
+               return PARSE_ERR;
+       }
+       /* Control never goes here... we return before that. */
+}