MatroskaParser.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:81k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Copyright (c) 2004-2005 Mike Matsnev.  All Rights Reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice immediately at the beginning of the file, without modification,
  10.  *    this list of conditions, and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. Absolutely no warranty of function or purpose is made by the author
  15.  *    Mike Matsnev.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  * 
  28.  * $Id: MatroskaParser.c,v 1.47 2005/07/06 18:44:40 mike Exp $
  29.  * 
  30.  */
  31. /* modified for TCPMP by Picard 14/08/2005 */
  32. #include <stdlib.h>
  33. #include <stdarg.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. //Picard
  37. #if !defined(__palmos__) || !defined(ARM) 
  38. #include <setjmp.h>
  39. #else
  40. #ifndef EOF
  41. #define EOF -1
  42. #endif
  43. typedef int jmp_buf[16];
  44. int setjmp(jmp_buf jp);
  45. int longjmp(jmp_buf jp, int ret);
  46. #define alloca(size) __builtin_alloca(size)
  47. #endif
  48. #ifdef _WIN32
  49. // MS names some functions differently
  50. #define alloca   _alloca
  51. #define inline   __inline
  52. #include <tchar.h>
  53. #endif
  54. #ifndef EVCBUG
  55. #define EVCBUG
  56. #endif
  57. #include "MatroskaParser.h"
  58. #ifdef MATROSKA_COMPRESSION_SUPPORT
  59. #include "../../common/zlib/zlib.h" //Picard
  60. //#include <zlib.h>
  61. #endif
  62. #define EBML_VERSION       1
  63. #define EBML_MAX_ID_LENGTH    4
  64. #define EBML_MAX_SIZE_LENGTH  8
  65. #define MATROSKA_VERSION      1
  66. #define MATROSKA_DOCTYPE      "matroska"
  67. #define MAX_STRING_LEN       1023
  68. #define QSEGSIZE       512
  69. #define MAX_TRACKS       32
  70. #define MAX_READAHEAD       (512*1024)
  71. #define MAXCLUSTER       (64*1048576)
  72. #define MAXFRAME       (4*1048576)
  73. #ifdef WIN32
  74. #define LL(x) x##i64
  75. #define ULL(x) x##ui64
  76. #else
  77. #define LL(x) x##ll
  78. #define ULL(x) x##ull
  79. #endif
  80. #define MAXU64       ULL(0xffffffffffffffff)
  81. #define ONE       ULL(1)
  82. // compatibility
  83. static char  *mystrdup(struct InputStream *is,const char *src) {
  84.   size_t  len;
  85.   char   *dst;
  86.   if (src==NULL)
  87.     return NULL;
  88.   len = strlen(src);
  89.   dst = is->memalloc(is,len+1);
  90.   if (dst==NULL)
  91.     return NULL;
  92.   memcpy(dst,src,len+1);
  93.   return dst;
  94. }
  95. #if defined(_WIN32) || defined(__palmos__) //Picard
  96. static void  strlcpy(char *dst,const char *src,unsigned size) {
  97.   unsigned  i;
  98.   for (i=0;i+1<size && src[i];++i)
  99.     dst[i] = src[i];
  100.   if (i<size)
  101.     dst[i] = 0;
  102. }
  103. #endif
  104. struct Cue {
  105.   ulonglong Time;
  106.   ulonglong Position;
  107.   ulonglong Block;
  108.   unsigned char Track;
  109. };
  110. struct QueueEntry {
  111.   struct QueueEntry *next;
  112.   unsigned int     Length;
  113.   ulonglong     Start;
  114.   ulonglong     End;
  115.   ulonglong     Position;
  116.   void *Ref; //Picard
  117.   unsigned int     flags;
  118. };
  119. struct Queue {
  120.   struct QueueEntry *head;
  121.   struct QueueEntry *tail;
  122. };
  123. #define MPF_ERROR 0x10000
  124. #define IBSZ   1024
  125. #define RBRESYNC  1
  126. struct MatroskaFile {
  127.   // parser config
  128.   unsigned    flags;
  129.   // input
  130.   InputStream *cache;
  131.   // internal buffering
  132.   char       inbuf[IBSZ];
  133.   ulonglong   bufbase; // file offset of the first byte in buffer
  134.   int       bufpos; // current read position in buffer
  135.   int       buflen; // valid bytes in buffer
  136.   // error reporting
  137.   char       errmsg[128];
  138.   jmp_buf     jb;
  139.   // pointers to key elements
  140.   ulonglong   pSegment;
  141.   ulonglong   pSeekHead;
  142.   ulonglong   pSegmentInfo;
  143.   ulonglong   pCluster;
  144.   ulonglong   pTracks;
  145.   ulonglong   pCues;
  146.   ulonglong   pAttachments;
  147.   ulonglong   pChapters;
  148.   ulonglong   pTags;
  149.   // flags for key elements
  150.   struct {
  151.     unsigned int  SegmentInfo:1;
  152.     unsigned int  Cluster:1;
  153.     unsigned int  Tracks:1;
  154.     unsigned int  Cues:1;
  155.     unsigned int  Attachments:1;
  156.     unsigned int  Chapters:1;
  157.     unsigned int  Tags:1;
  158.   } seen;
  159.   // file info
  160.   ulonglong   firstTimecode;
  161.   // SegmentInfo
  162.   struct SegmentInfo  Seg;
  163.   // Tracks
  164.   unsigned int     nTracks,nTracksSize;
  165.   struct TrackInfo  **Tracks;
  166.   // Queues
  167.   struct QueueEntry *QFreeList;
  168.   unsigned int     nQBlocks,nQBlocksSize;
  169.   struct QueueEntry **QBlocks;
  170.   struct Queue     *Queues;
  171.   ulonglong     readPosition;
  172.   unsigned int     trackMask;
  173.   ulonglong     pSegmentTop;  // offset of next byte after the segment
  174.   ulonglong     tcCluster;    // current cluster timecode
  175.   // Cues
  176.   unsigned int     nCues,nCuesSize;
  177.   struct Cue     *Cues;
  178.   // Attachments
  179.   unsigned int     nAttachments,nAttachmentsSize;
  180.   struct Attachment *Attachments;
  181.   // Chapters
  182.   unsigned int     nChapters,nChaptersSize;
  183.   struct Chapter    *Chapters;
  184.   // Tags
  185.   unsigned int     nTags,nTagsSize;
  186.   struct Tag     *Tags;
  187. };
  188. ///////////////////////////////////////////////////////////////////////////
  189. // error reporting
  190. static void   myvsnprintf_string(char **pdest,char *de,const char *str) {
  191.   char *dest = *pdest;
  192.   while (dest < de && *str)
  193.     *dest++ = *str++;
  194.   *pdest = dest;
  195. }
  196. static void   myvsnprintf_uint_impl(char **pdest,char *de,int width,int zero,
  197.     int neg,unsigned base,int letter,
  198.     int ms,ulonglong val)
  199. {
  200.   char *dest = *pdest;
  201.   char tmp[21]; /* enough for 64 bit ints */
  202.   char *np = tmp + sizeof(tmp);
  203.   int rw,pad,trail;
  204.   char pc = zero ? '0' : ' ';
  205.   *--np = '';
  206.   while (val != 0) {
  207.     int   rem = (int)(val % base);
  208.     val = val / base;
  209.     *--np = rem < 10 ? rem + '0' : rem - 10 + letter;
  210.   }
  211.   rw = (int)(tmp - np + sizeof(tmp) - 1);
  212.   if (ms)
  213.     ++rw;
  214.   pad = trail = 0;
  215.   if (rw < width)
  216.     pad = width - rw;
  217.   if (neg)
  218.     trail = pad, pad = 0;
  219.   if (dest < de && ms)
  220.     *dest++ = '-';
  221.   while (dest < de && pad--)
  222.     *dest++ = pc;
  223.   while (dest < de && *np)
  224.     *dest++ = *np++;
  225.   while (dest < de && trail--)
  226.     *dest++ = ' ';
  227.   *pdest = dest;
  228. }
  229. static void   myvsnprintf_uint(char **pdest,char *de,int width,int zero,
  230.        int neg,unsigned base,int letter,
  231.        ulonglong val)
  232. {
  233.   myvsnprintf_uint_impl(pdest,de,width,zero,neg,base,letter,0,val);
  234. }
  235. static void   myvsnprintf_int(char **pdest,char *de,int width,int zero,
  236.       int neg,unsigned base,int letter,
  237.       longlong val)
  238. {
  239.   if (val < 0)
  240.     myvsnprintf_uint_impl(pdest,de,width,zero,neg,base,letter,1,-val);
  241.   else
  242.     myvsnprintf_uint_impl(pdest,de,width,zero,neg,base,letter,0,val);
  243. }
  244. static void   myvsnprintf(char *dest,unsigned dsize,const char *fmt,va_list ap) {
  245.   // s,d,x,u,ll
  246.   char     *de = dest + dsize - 1;
  247.   int     state = 0, width=0, zero=0, neg=0, ll=0; //Picard
  248.   if (dsize <= 1) {
  249.     if (dsize > 0)
  250.       *dest = '';
  251.     return;
  252.   }
  253.   while (*fmt && dest < de)
  254.     switch (state) {
  255.       case 0:
  256. if (*fmt == '%') {
  257.   ++fmt;
  258.   state = 1;
  259.   width = zero = neg = ll = 0;
  260. } else
  261.   *dest++ = *fmt++;
  262. break;
  263.       case 1:
  264. if (*fmt == '-') {
  265.   neg = 1;
  266.   ++fmt;
  267.   state = 2;
  268.   break;
  269. }
  270. state = 2;
  271.       case 2:
  272. if (*fmt >= '0' && *fmt <= '9') {
  273.   width = width * 10 + *fmt++ - '0';
  274.   break;
  275. }
  276. state = 3;
  277.       case 3:
  278. if (*fmt == 'l') {
  279.   ++ll;
  280.   ++fmt;
  281.   break;
  282. }
  283. state = 4;
  284.       case 4:
  285. switch (*fmt) {
  286.   case 's':
  287.     myvsnprintf_string(&dest,de,va_arg(ap,const char *));
  288.     break;
  289.   case 'd':
  290.     switch (ll) {
  291.       case 0:
  292. myvsnprintf_int(&dest,de,width,zero,neg,10,'a',va_arg(ap,int));
  293. break;
  294.       case 1:
  295. myvsnprintf_int(&dest,de,width,zero,neg,10,'a',va_arg(ap,long));
  296. break;
  297.       case 2:
  298. myvsnprintf_int(&dest,de,width,zero,neg,10,'a',va_arg(ap,longlong));
  299. break;
  300.     }
  301.     break;
  302.   case 'u':
  303.     switch (ll) {
  304.       case 0:
  305. myvsnprintf_uint(&dest,de,width,zero,neg,10,'a',va_arg(ap,unsigned int));
  306. break;
  307.       case 1:
  308. myvsnprintf_uint(&dest,de,width,zero,neg,10,'a',va_arg(ap,unsigned long));
  309. break;
  310.       case 2:
  311. myvsnprintf_uint(&dest,de,width,zero,neg,10,'a',va_arg(ap,ulonglong));
  312. break;
  313.     }
  314.     break;
  315.   case 'x':
  316.     switch (ll) {
  317.       case 0:
  318. myvsnprintf_uint(&dest,de,width,zero,neg,16,'a',va_arg(ap,unsigned int));
  319. break;
  320.       case 1:
  321. myvsnprintf_uint(&dest,de,width,zero,neg,16,'a',va_arg(ap,unsigned long));
  322. break;
  323.       case 2:
  324. myvsnprintf_uint(&dest,de,width,zero,neg,16,'a',va_arg(ap,ulonglong));
  325. break;
  326.     }
  327.     break;
  328.   case 'X':
  329.     switch (ll) {
  330.       case 0:
  331. myvsnprintf_uint(&dest,de,width,zero,neg,16,'A',va_arg(ap,unsigned int));
  332. break;
  333.       case 1:
  334. myvsnprintf_uint(&dest,de,width,zero,neg,16,'A',va_arg(ap,unsigned long));
  335. break;
  336.       case 2:
  337. myvsnprintf_uint(&dest,de,width,zero,neg,16,'A',va_arg(ap,ulonglong));
  338. break;
  339.     }
  340.     break;
  341.   default:
  342.     break;
  343. }
  344. ++fmt;
  345. state = 0;
  346. break;
  347.       default:
  348. state = 0;
  349. break;
  350.     }
  351.   *dest = '';
  352. }
  353. static void   errorjmp(MatroskaFile *mf,const char *fmt, ...) {
  354.   va_list   ap;
  355.   va_start(ap, fmt);
  356.   myvsnprintf(mf->errmsg,sizeof(mf->errmsg),fmt,ap);
  357.   va_end(ap);
  358.   mf->flags |= MPF_ERROR;
  359.   longjmp(mf->jb,1);
  360. }
  361. ///////////////////////////////////////////////////////////////////////////
  362. // arrays
  363. static void *ArrayAlloc(MatroskaFile *mf,void **base,
  364. unsigned *cur,unsigned *max,unsigned elem_size)
  365. {
  366.   if (*cur>=*max) {
  367.     void      *np;
  368.     unsigned  newsize = *max * 2;
  369.     if (newsize==0)
  370.       newsize = 1;
  371.     np = mf->cache->memrealloc(mf->cache,*base,newsize*elem_size);
  372.     if (np==NULL)
  373.       errorjmp(mf,"Out of memory in ArrayAlloc");
  374.     *base = np;
  375.     *max = newsize;
  376.   }
  377.   return (char*)*base + elem_size * (*cur)++;
  378. }
  379. static void ArrayReleaseMemory(MatroskaFile *mf,void **base,
  380.        unsigned cur,unsigned *max,unsigned elem_size)
  381. {
  382.   if (cur<*max) {
  383.     void  *np = mf->cache->memrealloc(mf->cache,*base,cur*elem_size);
  384.     *base = np;
  385.     *max = cur;
  386.   }
  387. }
  388. #define ASGET(f,s,name)   ArrayAlloc((f),(void**)&(s)->name,&(s)->n##name,&(s)->n##name##Size,sizeof(*((s)->name)))
  389. #define AGET(f,name)   ArrayAlloc((f),(void**)&(f)->name,&(f)->n##name,&(f)->n##name##Size,sizeof(*((f)->name)))
  390. #define ARELEASE(f,s,name)  ArrayReleaseMemory((f),(void**)&(s)->name,(s)->n##name,&(s)->n##name##Size,sizeof(*((s)->name)))
  391. ///////////////////////////////////////////////////////////////////////////
  392. // queues
  393. static struct QueueEntry *QPut(struct Queue *q,struct QueueEntry *qe) {
  394.   if (q->tail)
  395.     q->tail->next = qe;
  396.   qe->next = NULL;
  397.   q->tail = qe;
  398.   if (q->head==NULL)
  399.     q->head = qe;
  400.   return qe;
  401. }
  402. static struct QueueEntry  *QGet(struct Queue *q) {
  403.   struct QueueEntry   *qe = q->head;
  404.   if (qe == NULL)
  405.     return NULL;
  406.   q->head = qe->next;
  407.   if (q->tail == qe)
  408.     q->tail = NULL;
  409.   return qe;
  410. }
  411. static struct QueueEntry  *QAlloc(MatroskaFile *mf) {
  412.   struct QueueEntry   *qe,**qep;
  413.   if (mf->QFreeList == NULL) {
  414.     unsigned       i;
  415.     qep = AGET(mf,QBlocks);
  416.     *qep = mf->cache->memalloc(mf->cache,QSEGSIZE * sizeof(*qe));
  417.     if (*qep == NULL)
  418.       errorjmp(mf,"Ouf of memory");
  419.     qe = *qep;
  420.     for (i=0;i<QSEGSIZE-1;++i)
  421.       qe[i].next = qe+i+1;
  422.     qe[QSEGSIZE-1].next = NULL;
  423.     mf->QFreeList = qe;
  424.   }
  425.   qe = mf->QFreeList;
  426.   mf->QFreeList = qe->next;
  427.   return qe;
  428. }
  429. static inline void QFree(MatroskaFile *mf,struct QueueEntry *qe) {
  430.   if (qe->Ref) mf->cache->releaseref(mf->cache,qe->Ref); //Picard
  431.   qe->next = mf->QFreeList;
  432.   mf->QFreeList = qe;
  433. }
  434. //Picard
  435. /*
  436. // fill the buffer at current position
  437. static void fillbuf(MatroskaFile *mf) {
  438.   int     rd;
  439.   // advance buffer pointers
  440.   mf->bufbase += mf->buflen;
  441.   mf->buflen = mf->bufpos = 0;
  442.   // get the relevant page
  443.   rd = mf->cache->read(mf->cache, mf->bufbase, mf->inbuf, IBSZ);
  444.   if (rd<0)
  445.     errorjmp(mf,"I/O Error: %s",mf->cache->geterror(mf->cache));
  446.   mf->buflen = rd;
  447. }
  448. // fill the buffer and return next char
  449. static int  nextbuf(MatroskaFile *mf) {
  450.   fillbuf(mf);
  451.   if (mf->bufpos < mf->buflen)
  452.     return (unsigned char)(mf->inbuf[mf->bufpos++]);
  453.   return EOF;
  454. }
  455. */
  456. static inline int readch(MatroskaFile *mf) {
  457.   return mf->cache->ioreadch(mf->cache); //Picard
  458.   //return mf->bufpos < mf->buflen ? (unsigned char)(mf->inbuf[mf->bufpos++]) : nextbuf(mf);
  459. }
  460. static inline ulonglong filepos(MatroskaFile *mf) {
  461.   return mf->cache->iotell(mf->cache); //Picard
  462.   //return mf->bufbase + mf->bufpos;
  463. }
  464. static void   readbytes(MatroskaFile *mf,void *buffer,int len) {
  465.   mf->cache->ioread(mf->cache,buffer,len); //Picard
  466. /*  
  467.   char *cp = buffer;
  468.   int nb = mf->buflen - mf->bufpos;
  469.   if (nb > len)
  470.     nb = len;
  471.   memcpy(cp, mf->inbuf + mf->bufpos, nb);
  472.   mf->bufpos += nb;
  473.   len -= nb;
  474.   cp += nb;
  475.   if (len>0) {
  476.     mf->bufbase += mf->buflen;
  477.     mf->bufpos = mf->buflen = 0;
  478.     nb = mf->cache->read(mf->cache, mf->bufbase, cp, len);
  479.     if (nb<0)
  480.       errorjmp(mf,"I/O Error: %s",mf->cache->geterror(mf->cache));
  481.     if (nb != len)
  482.       errorjmp(mf,"Short read: got %d bytes of %d",nb,len);
  483.     mf->bufbase += len;
  484.   }
  485. */
  486. }
  487. static void   skipbytes(MatroskaFile *mf,ulonglong len) {
  488.   mf->cache->ioseek(mf->cache,len,1);//Picard
  489. /*
  490.   int     nb = mf->buflen - mf->bufpos;
  491.   if (nb > len)
  492.     nb = (int)len;
  493.   mf->bufpos += nb;
  494.   len -= nb;
  495.   if (len>0) {
  496.     mf->bufbase += mf->buflen;
  497.     mf->bufpos = mf->buflen = 0;
  498.     mf->bufbase += len;
  499.   }
  500. */
  501. }
  502. static void seek(MatroskaFile *mf,ulonglong pos) {
  503.   mf->cache->ioseek(mf->cache,pos,0);//Picard
  504. /*
  505.   // see if pos is inside buffer
  506.   if (pos>=mf->bufbase && pos<mf->bufbase+mf->buflen)
  507.     mf->bufpos = (unsigned)(pos - mf->bufbase);
  508.   else {
  509.     // invalidate buffer and set pointer
  510.     mf->bufbase = pos;
  511.     mf->buflen = mf->bufpos = 0;
  512.   }
  513. */
  514. }
  515. ///////////////////////////////////////////////////////////////////////////
  516. // floating point
  517. static inline MKFLOAT mkfi(int i) {
  518. #ifdef MATROSKA_INTEGER_ONLY
  519.   MKFLOAT  f;
  520.   f.v = (longlong)i << 32;
  521.   return f;
  522. #else
  523.   return i;
  524. #endif
  525. }
  526. static inline longlong mul3(MKFLOAT scale,longlong tc) {
  527. #ifdef MATROSKA_INTEGER_ONLY
  528.   //             x1 x0
  529.   //             y1 y0
  530.   //    --------------
  531.   //             x0*y0
  532.   //          x1*y0
  533.   //          x0*y1
  534.   //       x1*y1
  535.   //    --------------
  536.   //       .. r1 r0 ..
  537.   //
  538.   //    r = ((x0*y0) >> 32) + (x1*y0) + (x0*y1) + ((x1*y1) << 32)
  539.   unsigned    x0,x1,y0,y1;
  540.   ulonglong   p;
  541.   char       sign = 0;
  542.   if (scale.v < 0)
  543.     sign = !sign, scale.v = -scale.v;
  544.   if (tc < 0)
  545.     sign = !sign, tc = -tc;
  546.   x0 = (unsigned)scale.v;
  547.   x1 = (unsigned)((ulonglong)scale.v >> 32);
  548.   y0 = (unsigned)tc;
  549.   y1 = (unsigned)((ulonglong)tc >> 32);
  550.   p = (ulonglong)x0*y0 >> 32;
  551.   p += (ulonglong)x0*y1;
  552.   p += (ulonglong)x1*y0;
  553.   p += (ulonglong)(x1*y1) << 32;
  554.   return p;
  555. #else
  556.   return (longlong)(scale * tc);
  557. #endif
  558. }
  559. ///////////////////////////////////////////////////////////////////////////
  560. // EBML support
  561. static int   readID(MatroskaFile *mf) {
  562.   int c1,c2,c3,c4;
  563.   c1 = readch(mf);
  564.   if (c1 == EOF)
  565.     return EOF;
  566.   if (c1 & 0x80)
  567.     return c1;
  568.   if ((c1 & 0xf0) == 0)
  569.     errorjmp(mf,"Invalid first byte of EBML ID: %02X",c1);
  570.   c2 = readch(mf);
  571.   if (c2 == EOF)
  572. fail:
  573.     errorjmp(mf,"Got EOF while reading EBML ID");
  574.   if ((c1 & 0xc0) == 0x40)
  575.     return (c1<<8) | c2;
  576.   c3 = readch(mf);
  577.   if (c3 == EOF)
  578.     goto fail;
  579.   if ((c1 & 0xe0) == 0x20)
  580.     return (c1<<16) | (c2<<8) | c3;
  581.   c4 = readch(mf);
  582.   if (c4 == EOF)
  583.     goto fail;
  584.   if ((c1 & 0xf0) == 0x10)
  585.     return (c1<<24) | (c2<<16) | (c3<<8) | c4;
  586.   return 0; // NOT REACHED
  587. }
  588. static ulonglong readVLUIntImp(MatroskaFile *mf,int *mask) {
  589.   int c,d,m;
  590.   ulonglong v = 0;
  591.   c = readch(mf);
  592.   if (c == EOF)
  593.     return EOF;
  594.   if (c == 0)
  595.     errorjmp(mf,"Invalid first byte of EBML integer: 0");
  596.   for (m=0;;++m) {
  597.     if (c & (0x80 >> m)) {
  598.       c &= 0x7f >> m;
  599.       if (mask)
  600. *mask = m;
  601.       return v | ((ulonglong)c << m*8);
  602.     }
  603.     d = readch(mf);
  604.     if (d == EOF)
  605.       errorjmp(mf,"Got EOF while reading EBML unsigned integer");
  606.     v = (v<<8) | d;
  607.   }
  608.   // NOT REACHED
  609. }
  610. static inline ulonglong readVLUInt(MatroskaFile *mf) {
  611.   return readVLUIntImp(mf,NULL);
  612. }
  613. static ulonglong readSize(MatroskaFile *mf) {
  614.   int     m;
  615.   ulonglong v = readVLUIntImp(mf,&m);
  616.   // see if it's unspecified
  617.   if (v == (MAXU64 >> (57-m*7)))
  618.     errorjmp(mf,"Unspecified element size is not supported here.");
  619.   return v;
  620. }
  621. static inline longlong readVLSInt(MatroskaFile *mf) {
  622.   static longlong bias[8] = { (ONE<<6)-1, (ONE<<13)-1, (ONE<<20)-1, (ONE<<27)-1,
  623.       (ONE<<34)-1, (ONE<<41)-1, (ONE<<48)-1, (ONE<<55)-1 };
  624.   int     m;
  625.   longlong  v = readVLUIntImp(mf,&m);
  626.   return v - bias[m];
  627. }
  628. static ulonglong  readUInt(MatroskaFile *mf,unsigned int len) {
  629.   int c;
  630.   unsigned int m = len;
  631.   ulonglong v = 0;
  632.   if (len==0)
  633.     return v;
  634.   if (len>8)
  635.     errorjmp(mf,"Unsupported integer size in readUInt: %u",len);
  636.   do {
  637.     c = readch(mf);
  638.     if (c == EOF)
  639.       errorjmp(mf,"Got EOF while reading EBML unsigned integer");
  640.     v = (v<<8) | c;
  641.   } while (--m);
  642.   return v;
  643. }
  644. static inline longlong readSInt(MatroskaFile *mf,unsigned int len) {
  645.   longlong v = readUInt(mf,(unsigned)len);
  646.   int s = 64 - (len<<3);
  647.   return (v << s) >> s;
  648. }
  649. static MKFLOAT readFloat(MatroskaFile *mf,unsigned int len) {
  650. #ifdef MATROSKA_INTEGER_ONLY
  651.   MKFLOAT   f;
  652.   int   shift;
  653. #else
  654.   union {
  655.     unsigned int  ui;
  656.     ulonglong   ull;
  657.     float   f;
  658.     double   d;
  659.   } u;
  660. #endif
  661.   if (len!=4 && len!=8)
  662.     errorjmp(mf,"Invalid float size in readFloat: %u",len);
  663. #ifdef MATROSKA_INTEGER_ONLY
  664.   if (len == 4) {
  665.     unsigned  ui = (unsigned)readUInt(mf,(unsigned)len);
  666.     f.v = (ui & 0x7fffff) | 0x800000;
  667.     if (ui & 0x80000000)
  668.       f.v = -f.v;
  669.     shift = (ui >> 23) & 0xff;
  670.     if (shift == 0) // assume 0
  671. zero:
  672.       shift = 0, f.v = 0;
  673.     else if (shift == 255)
  674. inf:
  675.       if (ui & 0x80000000)
  676. f.v = LL(0x8000000000000000);
  677.       else
  678. f.v = LL(0x7fffffffffffffff);
  679.     else {
  680.       shift += -127 + 9;
  681.       if (shift > 39)
  682. goto inf;
  683. shift:
  684.       if (shift < 0)
  685. f.v = f.v >> -shift;
  686.       else if (shift > 0)
  687. f.v = f.v << shift;
  688.     }
  689.   } else if (len == 8) {
  690.     ulonglong  ui = readUInt(mf,(unsigned)len);
  691.     f.v = (ui & LL(0xfffffffffffff)) | LL(0x10000000000000);
  692.     if (ui & 0x80000000)
  693.       f.v = -f.v;
  694.     shift = (int)((ui >> 52) & 0x7ff);
  695.     if (shift == 0) // assume 0
  696.       goto zero;
  697.     else if (shift == 2047)
  698.       goto inf;
  699.     else {
  700.       shift += -1023 - 20;
  701.       if (shift > 10)
  702. goto inf;
  703.       goto shift;
  704.     }
  705.   }
  706.   return f;
  707. #else
  708.   if (len==4) {
  709.     u.ui = (unsigned int)readUInt(mf,(unsigned)len);
  710.     return u.f;
  711.   }
  712.   if (len==8) {
  713.     u.ull = readUInt(mf,(unsigned)len);
  714.     return u.d;
  715.   }
  716.   return 0;
  717. #endif
  718. }
  719. static void readString(MatroskaFile *mf,ulonglong len,char *buffer,int buflen) {
  720.   int   nread;
  721.   if (buflen<1)
  722.     errorjmp(mf,"Invalid buffer size in readString: %d",buflen);
  723.   nread = buflen - 1;
  724.   if (nread > len)
  725.     nread = (int)len;
  726.   readbytes(mf,buffer,nread);
  727.   len -= nread;
  728.   if (len>0)
  729.     skipbytes(mf,len);
  730.   buffer[nread] = '';
  731. }
  732. ///////////////////////////////////////////////////////////////////////////
  733. // file parser
  734. #define FOREACH(f,tl) 
  735.   { 
  736.     ulonglong tmplen = (tl); 
  737.     { 
  738.       ulonglong   start = filepos(f); 
  739.       ulonglong   cur,len; 
  740.       int       id; 
  741.       for (;;) { 
  742. cur = filepos(mf); 
  743. if (cur == start + tmplen) 
  744.   break; 
  745. id = readID(f); 
  746. if (id==EOF) 
  747.   errorjmp(mf,"Unexpected EOF while reading EBML container"); 
  748. len = readSize(mf); 
  749. switch (id) {
  750. #define ENDFOR1(f) 
  751. default: 
  752.   skipbytes(f,len); 
  753.   break; 
  754. }
  755. #define ENDFOR2() 
  756.       } 
  757.     } 
  758.   }
  759. #define ENDFOR(f) ENDFOR1(f) ENDFOR2()
  760. #define myalloca(f,c) alloca(c)
  761. #define STRGETF(f,v,len,func) 
  762.   { 
  763.     char *TmpVal; 
  764.     unsigned TmpLen = (len)>MAX_STRING_LEN ? MAX_STRING_LEN : (unsigned)(len); 
  765.     TmpVal = func(f->cache,TmpLen+1); 
  766.     if (TmpVal == NULL) 
  767.       errorjmp(mf,"Out of memory"); 
  768.     readString(f,len,TmpVal,TmpLen+1); 
  769.     (v) = TmpVal; 
  770.   }
  771. #define STRGETA(f,v,len)  STRGETF(f,v,len,myalloca)
  772. #define STRGETM(f,v,len)  STRGETF(f,v,len,f->cache->memalloc)
  773. #if 0
  774. static int  IsWritingApp(MatroskaFile *mf,const char *str) {
  775.   const char  *cp = mf->Seg.WritingApp;
  776.   if (!cp)
  777.     return 0;
  778.   while (*str && *str++==*cp++) ;
  779.   return !*str;
  780. }
  781. #endif
  782. static void parseEBML(MatroskaFile *mf,ulonglong toplen) {
  783.   ulonglong v;
  784.   char     buf[32];
  785.   FOREACH(mf,toplen)
  786.     case 0x4286: // Version
  787.       v = readUInt(mf,(unsigned)len);
  788.       break;
  789.     case 0x42f7: // ReadVersion
  790.       v = readUInt(mf,(unsigned)len);
  791.       if (v > EBML_VERSION)
  792. errorjmp(mf,"File requires version %d EBML parser",(int)v);
  793.       break;
  794.     case 0x42f2: // MaxIDLength
  795.       v = readUInt(mf,(unsigned)len);
  796.       if (v > EBML_MAX_ID_LENGTH)
  797. errorjmp(mf,"File has identifiers longer than %d",(int)v);
  798.       break;
  799.     case 0x42f3: // MaxSizeLength
  800.       v = readUInt(mf,(unsigned)len);
  801.       if (v > EBML_MAX_SIZE_LENGTH)
  802. errorjmp(mf,"File has integers longer than %d",(int)v);
  803.       break;
  804.     case 0x4282: // DocType
  805.       readString(mf,len,buf,sizeof(buf));
  806.       if (strcmp(buf,MATROSKA_DOCTYPE))
  807. errorjmp(mf,"Unsupported DocType: %s",buf);
  808.       break;
  809.     case 0x4287: // DocTypeVersion
  810.       v = readUInt(mf,(unsigned)len);
  811.       break;
  812.     case 0x4285: // DocTypeReadVersion
  813.       v = readUInt(mf,(unsigned)len);
  814.       if (v > MATROSKA_VERSION)
  815. errorjmp(mf,"File requires version %d Matroska parser",(int)v);
  816.       break;
  817.   ENDFOR(mf);
  818. }
  819. static void parseSeekEntry(MatroskaFile *mf,ulonglong toplen) {
  820.   int     seekid = 0;
  821.   ulonglong pos = (ulonglong)-1;
  822.   FOREACH(mf,toplen)
  823.     case 0x53ab: // SeekID
  824.       if (len>EBML_MAX_ID_LENGTH)
  825. errorjmp(mf,"Invalid ID size in parseSeekEntry: %dn",(int)len);
  826.       seekid = (int)readUInt(mf,(unsigned)len);
  827.       break;
  828.     case 0x53ac: // SeekPos
  829.       pos = readUInt(mf,(unsigned)len);
  830.       break;
  831.   ENDFOR(mf);
  832.   if (pos == (ulonglong)-1)
  833.     errorjmp(mf,"Invalid element position in parseSeekEntry");
  834.   pos += mf->pSegment;
  835.   switch (seekid) {
  836.     case 0x114d9b74: // next SeekHead
  837.       if (mf->pSeekHead)
  838. errorjmp(mf,"SeekHead contains more than one SeekHead pointer");
  839.       mf->pSeekHead = pos;
  840.       break;
  841.     case 0x1549a966: // SegmentInfo
  842.       mf->pSegmentInfo = pos;
  843.       break;
  844.     case 0x1f43b675: // Cluster
  845.       if (!mf->pCluster)
  846. mf->pCluster = pos;
  847.       break;
  848.     case 0x1654ae6b: // Tracks
  849.       mf->pTracks = pos;
  850.       break;
  851.     case 0x1c53bb6b: // Cues
  852.       mf->pCues = pos;
  853.       break;
  854.     case 0x1941a469: // Attachments
  855.       mf->pAttachments = pos;
  856.       break;
  857.     case 0x1043a770: // Chapters
  858.       mf->pChapters = pos;
  859.       break;
  860.     case 0x1254c367: // tags
  861.       mf->pTags = pos;
  862.       break;
  863.   }
  864. }
  865. static void parseSeekHead(MatroskaFile *mf,ulonglong toplen) {
  866.   FOREACH(mf,toplen)
  867.     case 0x4dbb:
  868.       parseSeekEntry(mf,len);
  869.       break;
  870.   ENDFOR(mf);
  871. }
  872. static void parseSegmentInfo(MatroskaFile *mf,ulonglong toplen) {
  873.   MKFLOAT     duration = mkfi(0);
  874.   if (mf->seen.SegmentInfo) {
  875.     skipbytes(mf,toplen);
  876.     return;
  877.   }
  878.   mf->seen.SegmentInfo = 1;
  879.   mf->Seg.TimecodeScale = 1000000; // Default value
  880.   FOREACH(mf,toplen)
  881.     case 0x73a4: // SegmentUID
  882.       if (len!=sizeof(mf->Seg.UID))
  883. errorjmp(mf,"SegmentUID size is not %d bytes",mf->Seg.UID);
  884.       readbytes(mf,mf->Seg.UID,sizeof(mf->Seg.UID));
  885.       break;
  886.     case 0x7384: // SegmentFilename
  887.       STRGETM(mf,mf->Seg.Filename,len);
  888.       break;
  889.     case 0x3cb923: // PrevUID
  890.       if (len!=sizeof(mf->Seg.PrevUID))
  891. errorjmp(mf,"PrevUID size is not %d bytes",mf->Seg.PrevUID);
  892.       readbytes(mf,mf->Seg.PrevUID,sizeof(mf->Seg.PrevUID));
  893.       break;
  894.     case 0x3c83ab: // PrevFilename
  895.       STRGETM(mf,mf->Seg.PrevFilename,len);
  896.       break;
  897.     case 0x3eb923: // NextUID
  898.       if (len!=sizeof(mf->Seg.NextUID))
  899. errorjmp(mf,"NextUID size is not %d bytes",mf->Seg.NextUID);
  900.       readbytes(mf,mf->Seg.NextUID,sizeof(mf->Seg.NextUID));
  901.       break;
  902.     case 0x3e83bb: // NextFilename
  903.       STRGETM(mf,mf->Seg.NextFilename,len);
  904.       break;
  905.     case 0x2ad7b1: // TimecodeScale
  906.       mf->Seg.TimecodeScale = readUInt(mf,(unsigned)len);
  907.       if (mf->Seg.TimecodeScale == 0)
  908. errorjmp(mf,"Segment timecode scale is zero");
  909.       break;
  910.     case 0x4489: // Duration
  911.       duration = readFloat(mf,(unsigned)len);
  912.       break;
  913.     case 0x4461: // DateUTC
  914.       mf->Seg.DateUTC = readUInt(mf,(unsigned)len);
  915.       break;
  916.     case 0x7ba9: // Title
  917.       STRGETM(mf,mf->Seg.Title,len);
  918.       break;
  919.     case 0x4d80: // MuxingApp
  920.       STRGETM(mf,mf->Seg.MuxingApp,len);
  921.       break;
  922.     case 0x5741: // WritingApp
  923.       STRGETM(mf,mf->Seg.WritingApp,len);
  924.       break;
  925.   ENDFOR(mf);
  926.   mf->Seg.Duration = mul3(duration,mf->Seg.TimecodeScale);
  927. }
  928. static void parseFirstCluster(MatroskaFile *mf,ulonglong toplen) {
  929.   mf->seen.Cluster = 1;
  930.   mf->firstTimecode = 0;
  931.   FOREACH(mf,toplen)
  932.     case 0xe7: // Timecode
  933.       mf->firstTimecode += readUInt(mf,(unsigned)len);
  934.       break;
  935.     case 0xa0: // BlockGroup
  936.       FOREACH(mf,len)
  937. case 0xa1: // Block
  938.   readVLUInt(mf); // track number
  939.   mf->firstTimecode += readSInt(mf,2); 
  940.   skipbytes(mf,start + toplen - filepos(mf));
  941.   return;
  942.       ENDFOR(mf);
  943.       break;
  944.   ENDFOR(mf);
  945. }
  946. static void parseVideoInfo(MatroskaFile *mf,ulonglong toplen,struct TrackInfo *ti) {
  947.   ulonglong v;
  948.   char     dW = 0, dH = 0;
  949.   FOREACH(mf,toplen)
  950.     case 0x9a: // FlagInterlaced
  951.       ti->Video.Interlaced = readUInt(mf,(unsigned)len)!=0;
  952.       break;
  953.     case 0x53b8: // StereoMode
  954.       v = readUInt(mf,(unsigned)len);
  955.       if (v>3)
  956. errorjmp(mf,"Invalid stereo mode");
  957.       ti->Video.StereoMode = (unsigned char)v;
  958.       break;
  959.     case 0xb0: // PixelWidth
  960.       v = readUInt(mf,(unsigned)len);
  961.       if (v>0xffffffff)
  962. errorjmp(mf,"PixelWidth is too large");
  963.       ti->Video.PixelWidth = (unsigned)v;
  964.       if (!dW)
  965. ti->Video.DisplayWidth = ti->Video.PixelWidth;
  966.       break;
  967.     case 0xba: // PixelHeight
  968.       v = readUInt(mf,(unsigned)len);
  969.       if (v>0xffffffff)
  970. errorjmp(mf,"PixelHeight is too large");
  971.       ti->Video.PixelHeight = (unsigned)v;
  972.       if (!dH)
  973. ti->Video.DisplayHeight = ti->Video.PixelHeight;
  974.       break;
  975.     case 0x54b0: // DisplayWidth
  976.       v = readUInt(mf,(unsigned)len);
  977.       if (v>0xffffffff)
  978. errorjmp(mf,"DisplayWidth is too large");
  979.       ti->Video.DisplayWidth = (unsigned)v;
  980.       dW = 1;
  981.       break;
  982.     case 0x54ba: // DisplayHeight
  983.       v = readUInt(mf,(unsigned)len);
  984.       if (v>0xffffffff)
  985. errorjmp(mf,"DisplayHeight is too large");
  986.       ti->Video.DisplayHeight = (unsigned)v;
  987.       dH = 1;
  988.       break;
  989.     case 0x54b2: // DisplayUnit
  990.       v = readUInt(mf,(unsigned)len);
  991.       if (v>2)
  992. errorjmp(mf,"Invalid DisplayUnit: %d",(int)v);
  993.       ti->Video.DisplayUnit = (unsigned char)v;
  994.       break;
  995.     case 0x54b3: // AspectRatioType
  996.       v = readUInt(mf,(unsigned)len);
  997.       if (v>2)
  998. errorjmp(mf,"Invalid AspectRatioType: %d",(int)v);
  999.       ti->Video.AspectRatioType = (unsigned char)v;
  1000.       break;
  1001.     case 0x54aa: // PixelCropBottom
  1002.       v = readUInt(mf,(unsigned)len);
  1003.       if (v>0xffffffff)
  1004. errorjmp(mf,"PixelCropBottom is too large");
  1005.       ti->Video.CropB = (unsigned)v;
  1006.       break;
  1007.     case 0x54bb: // PixelCropTop
  1008.       v = readUInt(mf,(unsigned)len);
  1009.       if (v>0xffffffff)
  1010. errorjmp(mf,"PixelCropTop is too large");
  1011.       ti->Video.CropT = (unsigned)v;
  1012.       break;
  1013.     case 0x54cc: // PixelCropLeft
  1014.       v = readUInt(mf,(unsigned)len);
  1015.       if (v>0xffffffff)
  1016. errorjmp(mf,"PixelCropLeft is too large");
  1017.       ti->Video.CropL = (unsigned)v;
  1018.       break;
  1019.     case 0x54dd: // PixelCropRight
  1020.       v = readUInt(mf,(unsigned)len);
  1021.       if (v>0xffffffff)
  1022. errorjmp(mf,"PixelCropRight is too large");
  1023.       ti->Video.CropR = (unsigned)v;
  1024.       break;
  1025.     case 0x2eb524: // ColourSpace
  1026.       ti->Video.ColourSpace = (unsigned)readUInt(mf,4);
  1027.       break;
  1028.     case 0x2fb523: // GammaValue
  1029.       ti->Video.GammaValue = readFloat(mf,(unsigned)len);
  1030.       break;
  1031.   ENDFOR(mf);
  1032. }
  1033. static void parseAudioInfo(MatroskaFile *mf,ulonglong toplen,struct TrackInfo *ti) {
  1034.   ulonglong   v;
  1035.   FOREACH(mf,toplen)
  1036.     case 0xb5: // SamplingFrequency
  1037.       ti->Audio.SamplingFreq = readFloat(mf,(unsigned)len);
  1038.       break;
  1039.     case 0x78b5: // OutputSamplingFrequency
  1040.       ti->Audio.OutputSamplingFreq = readFloat(mf,(unsigned)len);
  1041.       break;
  1042.     case 0x9f: // Channels
  1043.       v = readUInt(mf,(unsigned)len);
  1044.       if (v<1 || v>255)
  1045. errorjmp(mf,"Invalid Channels value");
  1046.       ti->Audio.Channels = (unsigned char)v;
  1047.       break;
  1048.     case 0x7d7b: // ChannelPositions
  1049.       skipbytes(mf,len);
  1050.       break;
  1051.     case 0x6264: // BitDepth
  1052.       v = readUInt(mf,(unsigned)len);
  1053. #if 0
  1054.       if ((v<1 || v>255) && !IsWritingApp(mf,"AVI-Mux GUI"))
  1055. errorjmp(mf,"Invalid BitDepth: %d",(int)v);
  1056. #endif
  1057.       ti->Audio.BitDepth = (unsigned char)v;
  1058.       break;
  1059.   ENDFOR(mf);
  1060.   if (ti->Audio.Channels == 0)
  1061.     ti->Audio.Channels = 1;
  1062.   if (mkv_TruncFloat(ti->Audio.SamplingFreq) == 0)
  1063.     ti->Audio.SamplingFreq = mkfi(8000);
  1064.   if (mkv_TruncFloat(ti->Audio.OutputSamplingFreq)==0)
  1065.     ti->Audio.OutputSamplingFreq = ti->Audio.SamplingFreq;
  1066. }
  1067. static void CopyStr(char **src,char **dst) {
  1068.   size_t l;
  1069.   if (!*src)
  1070.     return;
  1071.   l = strlen(*src)+1;
  1072.   memcpy(*dst,*src,l);
  1073.   *src = *dst;
  1074.   *dst += l;
  1075. }
  1076. static void parseTrackEntry(MatroskaFile *mf,ulonglong toplen) {
  1077.   struct TrackInfo  t,*tp,**tpp;
  1078.   ulonglong     v;
  1079.   char     *cp = NULL;
  1080.   size_t     cplen = 0, cpadd = 0;
  1081.   unsigned     CompScope = 1;
  1082.   if (mf->nTracks >= MAX_TRACKS)
  1083.     errorjmp(mf,"Too many tracks.");
  1084.   // clear track info
  1085.   memset(&t,0,sizeof(t));
  1086.   // fill default values
  1087.   t.Enabled = 1;
  1088.   t.Default = 1;
  1089.   t.Lacing = 1;
  1090.   t.TimecodeScale = mkfi(1);
  1091.   t.DecodeAll = 1;
  1092.   FOREACH(mf,toplen)
  1093.     case 0xd7: // TrackNumber
  1094.       v = readUInt(mf,(unsigned)len);
  1095.       if (v>255)
  1096. errorjmp(mf,"Track number is >255 (%d)",(int)v);
  1097.       t.Number = (unsigned char)v;
  1098.       break;
  1099.     case 0x73c5: // TrackUID
  1100.       t.UID = readUInt(mf,(unsigned)len);
  1101.       break;
  1102.     case 0x83: // TrackType
  1103.       v = readUInt(mf,(unsigned)len);
  1104.       if (v<1 || v>254)
  1105. errorjmp(mf,"Invalid track type: %d",(int)v);
  1106.       t.Type = (unsigned char)v;
  1107.       break;
  1108.     case 0xb9: // Enabled
  1109.       t.Enabled = readUInt(mf,(unsigned)len)!=0;
  1110.       break;
  1111.     case 0x88: // Default
  1112.       t.Default = readUInt(mf,(unsigned)len)!=0;
  1113.       break;
  1114.     case 0x9c: // Lacing
  1115.       t.Lacing = readUInt(mf,(unsigned)len)!=0;
  1116.       break;
  1117.     case 0x6de7: // MinCache
  1118.       v = readUInt(mf,(unsigned)len);
  1119.       if (v > 0xffffffff)
  1120. errorjmp(mf,"MinCache is too large");
  1121.       t.MinCache = (unsigned)v;
  1122.       break;
  1123.     case 0x6df8: // MaxCache
  1124.       v = readUInt(mf,(unsigned)len);
  1125.       if (v > 0xffffffff)
  1126. errorjmp(mf,"MaxCache is too large");
  1127.       t.MaxCache = (unsigned)v;
  1128.       break;
  1129.     case 0x23e383: // DefaultDuration
  1130.       t.DefaultDuration = readUInt(mf,(unsigned)len);
  1131.       break;
  1132.     case 0x23314f: // TrackTimecodeScale
  1133.       t.TimecodeScale = readFloat(mf,(unsigned)len);
  1134.       break;
  1135.     case 0x55ee: // MaxBlockAdditionID
  1136.       t.MaxBlockAdditionID = (unsigned)readUInt(mf,(unsigned)len);
  1137.       break;
  1138.     case 0x536e: // Name
  1139.       if (t.Name)
  1140. errorjmp(mf,"Duplicate Track Name");
  1141.       STRGETA(mf,t.Name,len);
  1142.       break;
  1143.     case 0x22b59c: // Language
  1144.       if (t.Language)
  1145. errorjmp(mf,"Duplicate Track Language");
  1146.       STRGETA(mf,t.Language,len);
  1147.       break;
  1148.     case 0x86: // CodecID
  1149.       if (t.CodecID)
  1150. errorjmp(mf,"Duplicate CodecID");
  1151.       STRGETA(mf,t.CodecID,len);
  1152.       break;
  1153.     case 0x63a2: // CodecPrivate
  1154.       if (cp)
  1155. errorjmp(mf,"Duplicate CodecPrivate");
  1156.       if (len>262144) // 256KB
  1157. errorjmp(mf,"CodecPrivate is too large: %d",(int)len);
  1158.       cplen = (unsigned)len;
  1159.       cp = alloca(cplen);
  1160.       readbytes(mf,cp,(int)cplen);
  1161.       break;
  1162.     case 0x258688: // CodecName
  1163.       skipbytes(mf,len);
  1164.       break;
  1165.     case 0x3a9697: // CodecSettings
  1166.       skipbytes(mf,len);
  1167.       break;
  1168.     case 0x3b4040: // CodecInfoURL
  1169.       skipbytes(mf,len);
  1170.       break;
  1171.     case 0x26b240: // CodecDownloadURL
  1172.       skipbytes(mf,len);
  1173.       break;
  1174.     case 0xaa: // CodecDecodeAll
  1175.       t.DecodeAll = readUInt(mf,(unsigned)len)!=0;
  1176.       break;
  1177.     case 0x6fab: // TrackOverlay
  1178.       v = readUInt(mf,(unsigned)len);
  1179.       if (v>255)
  1180. errorjmp(mf,"Track number in TrackOverlay is too large: %d",(int)v);
  1181.       t.TrackOverlay = (unsigned char)v;
  1182.       break;
  1183.     case 0xe0: // VideoInfo
  1184.       parseVideoInfo(mf,len,&t);
  1185.       break;
  1186.     case 0xe1: // AudioInfo
  1187.       parseAudioInfo(mf,len,&t);
  1188.       break;
  1189.     case 0x6d80: // ContentEncodings
  1190.       FOREACH(mf,len)
  1191. case 0x6240: // ContentEncoding
  1192.   FOREACH(mf,len)
  1193.     case 0x5031: // ContentEncodingOrder
  1194.       readUInt(mf,(unsigned)len);
  1195.       break;
  1196.     case 0x5032: // ContentEncodingScope
  1197.       CompScope = (unsigned)readUInt(mf,(unsigned)len);
  1198.       break;
  1199.     case 0x5033: // ContentEncodingType
  1200.       readUInt(mf,(unsigned)len);
  1201.       break;
  1202.     case 0x5034: // ContentCompression
  1203.       // fill in defaults
  1204.       t.CompEnabled = 1;
  1205.       t.CompMethod = COMP_ZLIB;
  1206.       FOREACH(mf,len)
  1207. case 0x4254: // ContentCompAlgo
  1208.   v = readUInt(mf,(unsigned)len);
  1209.   if (v != 0)
  1210.     errorjmp(mf,"Unsupported compression algorithm: %d",(int)v);
  1211.   t.CompEnabled = 1;
  1212.   t.CompMethod = COMP_ZLIB;
  1213.   break;
  1214. case 0x4255: // ContentCompSettings
  1215.   skipbytes(mf,len);
  1216.   break;
  1217.       ENDFOR(mf);
  1218.       break;
  1219.       // TODO Implement Encryption/Signatures
  1220.   ENDFOR(mf);
  1221.   break;
  1222.       ENDFOR(mf);
  1223.       break;
  1224.   ENDFOR(mf);
  1225.   // validate track info
  1226.   if (!t.CodecID)
  1227.     errorjmp(mf,"Track has no Codec ID");
  1228.   if (t.UID != 0) {
  1229.     unsigned  i;
  1230.     for (i = 0; i < mf->nTracks; ++i)
  1231.       if (mf->Tracks[i]->UID == t.UID) // duplicate track entry
  1232. return;
  1233.   }
  1234. #ifdef MATROSKA_COMPRESSION_SUPPORT
  1235.   // handle compressed CodecPrivate
  1236.   if (t.CompEnabled && (CompScope & 2) && cplen > 0) {
  1237.     z_stream  zs;
  1238.     char      tmp[64], *ncp;
  1239.     int       code;
  1240.     uLong     ncplen;
  1241.     memset(&zs,0,sizeof(zs));
  1242.     if (inflateInit(&zs) != Z_OK)
  1243.       errorjmp(mf, "inflateInit failed");
  1244.     zs.next_in = cp;
  1245.     zs.avail_in = cplen;
  1246.     do {
  1247.       zs.next_out = tmp;
  1248.       zs.avail_out = sizeof(tmp);
  1249.       code = inflate(&zs, Z_NO_FLUSH);
  1250.     } while (code == Z_OK);
  1251.     if (code != Z_STREAM_END)
  1252.       errorjmp(mf, "invalid compressed data in CodecPrivate");
  1253.     ncplen = zs.total_out;
  1254.     ncp = alloca(ncplen);
  1255.     inflateReset(&zs);
  1256.     zs.next_in = cp;
  1257.     zs.avail_in = cplen;
  1258.     zs.next_out = ncp;
  1259.     zs.avail_out = ncplen;
  1260.     if (inflate(&zs, Z_FINISH) != Z_STREAM_END)
  1261.       errorjmp(mf, "inflate failed");
  1262.     inflateEnd(&zs);
  1263.     cp = ncp;
  1264.     cplen = ncplen;
  1265.   }
  1266. #endif
  1267.   if (!(CompScope & 1))
  1268.     t.CompEnabled = 0;
  1269.   // allocate new track
  1270.   tpp = AGET(mf,Tracks);
  1271.   // copy strings
  1272.   if (t.Name)
  1273.     cpadd += strlen(t.Name)+1;
  1274.   if (t.Language)
  1275.     cpadd += strlen(t.Language)+1;
  1276.   if (t.CodecID)
  1277.     cpadd += strlen(t.CodecID)+1;
  1278.   tp = mf->cache->memalloc(mf->cache,sizeof(*tp) + cplen + cpadd);
  1279.   if (tp == NULL)
  1280.     errorjmp(mf,"Out of memory");
  1281.   memcpy(tp,&t,sizeof(*tp));
  1282.   memcpy(tp+1,cp,cplen);
  1283.   if (cplen) {
  1284.     tp->CodecPrivate = tp+1;
  1285.     tp->CodecPrivateSize = (unsigned)cplen;
  1286.   }
  1287.   cp = (char*)(tp+1) + cplen;
  1288.   CopyStr(&tp->Name,&cp);
  1289.   CopyStr(&tp->Language,&cp);
  1290.   CopyStr(&tp->CodecID,&cp);
  1291.   // set default language
  1292.   if (!tp->Language)
  1293.     tp->Language="eng";
  1294.   *tpp = tp;
  1295. }
  1296. static void parseTracks(MatroskaFile *mf,ulonglong toplen) {
  1297.   mf->seen.Tracks = 1;
  1298.   FOREACH(mf,toplen)
  1299.     case 0xae: // TrackEntry
  1300.       parseTrackEntry(mf,len);
  1301.       break;
  1302.   ENDFOR(mf);
  1303. }
  1304. static void addCue(MatroskaFile *mf,ulonglong pos,ulonglong timecode) {
  1305.   struct Cue  *cc = AGET(mf,Cues);
  1306.   cc->Time = timecode;
  1307.   cc->Position = pos;
  1308.   cc->Track = 0;
  1309.   cc->Block = 0;
  1310. }
  1311. static void fixupCues(MatroskaFile *mf) {
  1312.   // adjust cues, shift cues if file does not start at 0
  1313.   unsigned  i;
  1314.   longlong  adjust = mf->firstTimecode * mf->Seg.TimecodeScale;
  1315.   for (i=0;i<mf->nCues;++i) {
  1316.     mf->Cues[i].Time *= mf->Seg.TimecodeScale;
  1317.     mf->Cues[i].Time -= adjust;
  1318.   }
  1319. }
  1320. static void parseCues(MatroskaFile *mf,ulonglong toplen) {
  1321.   jmp_buf     jb;
  1322.   ulonglong   v;
  1323.   struct Cue  cc;
  1324.   unsigned    i,j,k;
  1325.   mf->seen.Cues = 1;
  1326.   mf->nCues = 0;
  1327.   cc.Block = 0;
  1328.   memcpy(&jb,&mf->jb,sizeof(jb));
  1329.   if (setjmp(mf->jb)) {
  1330.     memcpy(&mf->jb,&jb,sizeof(jb));
  1331.     mf->nCues = 0;
  1332.     mf->seen.Cues = 0;
  1333.     return;
  1334.   }
  1335.   FOREACH(mf,toplen)
  1336.     case 0xbb: // CuePoint
  1337.       FOREACH(mf,len)
  1338. case 0xb3: // CueTime
  1339.   cc.Time = readUInt(mf,(unsigned)len);
  1340.   break;
  1341. case 0xb7: // CueTrackPositions
  1342.   FOREACH(mf,len)
  1343.     case 0xf7: // CueTrack
  1344.       v = readUInt(mf,(unsigned)len);
  1345.       if (v>255)
  1346. errorjmp(mf,"CueTrack points to an invalid track: %d",(int)v);
  1347.       cc.Track = (unsigned char)v;
  1348.       break;
  1349.     case 0xf1: // CueClusterPosition
  1350.       cc.Position = readUInt(mf,(unsigned)len);
  1351.       break;
  1352.     case 0x5378: // CueBlockNumber
  1353.       cc.Block = readUInt(mf,(unsigned)len);
  1354.       break;
  1355.     case 0xea: // CodecState
  1356.       readUInt(mf,(unsigned)len);
  1357.       break;
  1358.     case 0xdb: // CueReference
  1359.       FOREACH(mf,len)
  1360. case 0x96: // CueRefTime
  1361.   readUInt(mf,(unsigned)len);
  1362.   break;
  1363. case 0x97: // CueRefCluster
  1364.   readUInt(mf,(unsigned)len);
  1365.   break;
  1366. case 0x535f: // CueRefNumber
  1367.   readUInt(mf,(unsigned)len);
  1368.   break;
  1369. case 0xeb: // CueRefCodecState
  1370.   readUInt(mf,(unsigned)len);
  1371.   break;
  1372.       ENDFOR(mf);
  1373.       break;
  1374.   ENDFOR(mf);
  1375.   break;
  1376.       ENDFOR(mf);
  1377.       if (mf->nCues == 0 && mf->pCluster - mf->pSegment != cc.Position)
  1378. addCue(mf,mf->pCluster - mf->pSegment,mf->firstTimecode);
  1379.       memcpy(AGET(mf,Cues),&cc,sizeof(cc));
  1380.       break;
  1381.   ENDFOR(mf);
  1382.   memcpy(&mf->jb,&jb,sizeof(jb));
  1383.   ARELEASE(mf,mf,Cues);
  1384.   // bubble sort the cues and fuck the losers that write unordered cues
  1385.   if (mf->nCues > 0)
  1386.     for (i = mf->nCues - 1, k = 1; i > 0 && k > 0; --i)
  1387.       for (j = k = 0; j < i; ++j)
  1388. if (mf->Cues[j].Time > mf->Cues[j+1].Time) {
  1389.   struct Cue tmp = mf->Cues[j+1];
  1390.   mf->Cues[j+1] = mf->Cues[j];
  1391.   mf->Cues[j] = tmp;
  1392.   ++k;
  1393. }
  1394.   fixupCues(mf);
  1395. }
  1396. static void parseAttachment(MatroskaFile *mf,ulonglong toplen) {
  1397.   struct Attachment a,*pa;
  1398.   memset(&a,0,sizeof(a));
  1399.   FOREACH(mf,toplen)
  1400.     case 0x467e: // Description
  1401.       STRGETA(mf,a.Description,len);
  1402.       break;
  1403.     case 0x466e: // Name
  1404.       STRGETA(mf,a.Name,len);
  1405.       break;
  1406.     case 0x4660: // MimeType
  1407.       STRGETA(mf,a.MimeType,len);
  1408.       break;
  1409.     case 0x46ae: // UID
  1410.       a.UID = readUInt(mf,(unsigned)len);
  1411.       break;
  1412.     case 0x465c: // Data
  1413.       a.Position = filepos(mf);
  1414.       a.Length = len;
  1415.       skipbytes(mf,len);
  1416.       break;
  1417.   ENDFOR(mf);
  1418.   if (!a.Position)
  1419.     return;
  1420.   pa = AGET(mf,Attachments);
  1421.   memcpy(pa,&a,sizeof(a));
  1422.   if (a.Description)
  1423.     pa->Description = mystrdup(mf->cache,a.Description);
  1424.   if (a.Name)
  1425.     pa->Name = mystrdup(mf->cache,a.Name);
  1426.   if (a.MimeType)
  1427.     pa->MimeType = mystrdup(mf->cache,a.MimeType);
  1428. }
  1429. static void parseAttachments(MatroskaFile *mf,ulonglong toplen) {
  1430.   mf->seen.Attachments = 1;
  1431.   FOREACH(mf,toplen)
  1432.     case 0x61a7: // AttachedFile
  1433.       parseAttachment(mf,len);
  1434.       break;
  1435.   ENDFOR(mf);
  1436. }
  1437. static void parseChapter(MatroskaFile *mf,ulonglong toplen,struct Chapter *parent) {
  1438.   struct ChapterDisplay *disp;
  1439.   struct ChapterProcess *proc;
  1440.   struct ChapterCommand *cmd;
  1441.   struct Chapter *ch = ASGET(mf,parent,Children);
  1442.   memset(ch,0,sizeof(*ch));
  1443.   ch->Enabled = 1;
  1444.   FOREACH(mf,toplen)
  1445.     case 0x73c4: // ChapterUID
  1446.       ch->UID = readUInt(mf,(unsigned)len);
  1447.       break;
  1448.     case 0x6e67: // ChapterSegmentUID
  1449.       if (len != sizeof(ch->SegmentUID))
  1450. skipbytes(mf, len);
  1451.       else
  1452. readbytes(mf, ch->SegmentUID, sizeof(ch->SegmentUID));
  1453.       break;
  1454.     case 0x91: // ChapterTimeStart
  1455.       ch->Start = readUInt(mf,(unsigned)len);
  1456.       break;
  1457.     case 0x92: // ChapterTimeEnd
  1458.       ch->End = readUInt(mf,(unsigned)len);
  1459.       break;
  1460.     case 0x98: // ChapterFlagHidden
  1461.       ch->Hidden = readUInt(mf,(unsigned)len)!=0;
  1462.       break;
  1463.     case 0x4598: // ChapterFlagEnabled
  1464.       ch->Enabled = readUInt(mf,(unsigned)len)!=0;
  1465.       break;
  1466.     case 0x8f: // ChapterTrack
  1467.       FOREACH(mf,len)
  1468. case 0x89: // ChapterTrackNumber
  1469.   *(ulonglong*)(ASGET(mf,ch,Tracks)) = readUInt(mf,(unsigned)len);
  1470.   break;
  1471.       ENDFOR(mf);
  1472.       break;
  1473.     case 0x80: // ChapterDisplay
  1474.       disp = NULL;
  1475.       FOREACH(mf,len)
  1476. case 0x85: // ChapterString
  1477.   if (disp==NULL) {
  1478.     disp = ASGET(mf,ch,Display);
  1479.     memset(disp, 0, sizeof(*disp));
  1480.   }
  1481.   if (disp->String)
  1482.     skipbytes(mf,len); // Ignore duplicate string
  1483.   else
  1484.     STRGETM(mf,disp->String,len);
  1485.   break;
  1486. case 0x437c: // ChapterLanguage
  1487.   if (disp==NULL) {
  1488.     disp = ASGET(mf,ch,Display);
  1489.     memset(disp, 0, sizeof(*disp));
  1490.   }
  1491.   if (disp->Language)
  1492.     skipbytes(mf,len);
  1493.   else
  1494.     STRGETM(mf,disp->Language,len);
  1495.   break;
  1496. case 0x437e: // ChapterCountry
  1497.   if (disp==NULL) {
  1498.     disp = ASGET(mf,ch,Display);
  1499.     memset(disp, 0, sizeof(*disp));
  1500.   }
  1501.   if (disp->Country)
  1502.     skipbytes(mf,len);
  1503.   else
  1504.     STRGETM(mf,disp->Country,len);
  1505.   break;
  1506.       ENDFOR(mf);
  1507.       if (disp && !disp->String) {
  1508. mf->cache->memfree(mf->cache,disp->Language);
  1509. mf->cache->memfree(mf->cache,disp->Country);
  1510. --ch->nDisplay;
  1511.       }
  1512.       break;
  1513.     case 0x6944: // ChapProcess
  1514.       proc = NULL;
  1515.       FOREACH(mf,len)
  1516. case 0x6955: // ChapProcessCodecID
  1517.   if (proc == NULL) {
  1518.     proc = ASGET(mf, ch, Process);
  1519.     memset(proc, 0, sizeof(*proc));
  1520.   }
  1521.   proc->CodecID = (unsigned)readUInt(mf,(unsigned)len);
  1522.   break;
  1523. case 0x450d: // ChapProcessPrivate
  1524.   if (proc == NULL) {
  1525.     proc = ASGET(mf, ch, Process);
  1526.     memset(proc, 0, sizeof(*proc));
  1527.   }
  1528.   if (proc->CodecPrivate)
  1529.     skipbytes(mf, len);
  1530.   else {
  1531.     proc->CodecPrivateLength = (unsigned)len;
  1532.     STRGETM(mf,proc->CodecPrivate,len);
  1533.   }
  1534.   break;
  1535. case 0x6911: // ChapProcessCommand
  1536.   if (proc == NULL) {
  1537.     proc = ASGET(mf, ch, Process);
  1538.     memset(proc, 0, sizeof(*proc));
  1539.   }
  1540.   cmd = NULL;
  1541.   FOREACH(mf,len)
  1542.     case 0x6922: // ChapterCommandTime
  1543.       if (cmd == NULL) {
  1544. cmd = ASGET(mf,proc,Commands);
  1545. memset(cmd, 0, sizeof(*cmd));
  1546.       }
  1547.       cmd->Time = (unsigned)readUInt(mf,(unsigned)len);
  1548.       break;
  1549.     case 0x6933: // ChapterCommandString
  1550.       if (cmd == NULL) {
  1551. cmd = ASGET(mf,proc,Commands);
  1552. memset(cmd, 0, sizeof(*cmd));
  1553.       }
  1554.       if (cmd->Command)
  1555. skipbytes(mf,len);
  1556.       else {
  1557. cmd->CommandLength = (unsigned)len;
  1558. STRGETM(mf,cmd->Command,len);
  1559.       }
  1560.       break;
  1561.   ENDFOR(mf);
  1562.   if (cmd && !cmd->Command)
  1563.     --proc->nCommands;
  1564.   break;
  1565.       ENDFOR(mf);
  1566.       if (proc && !proc->nCommands)
  1567. --ch->nProcess;
  1568.       break;
  1569.     case 0xb6: // Nested ChapterAtom
  1570.       parseChapter(mf,len,ch);
  1571.       break;
  1572.   ENDFOR(mf);
  1573.   ARELEASE(mf,ch,Tracks);
  1574.   ARELEASE(mf,ch,Display);
  1575.   ARELEASE(mf,ch,Children);
  1576. }
  1577. static void parseChapters(MatroskaFile *mf,ulonglong toplen) {
  1578.   struct Chapter  *ch;
  1579.   mf->seen.Chapters = 1;
  1580.   FOREACH(mf,toplen)
  1581.     case 0x45b9: // EditionEntry
  1582. ch = AGET(mf,Chapters);
  1583. memset(ch, 0, sizeof(*ch));
  1584.   FOREACH(mf,len)
  1585.   case 0x45bc: // EditionUID
  1586.     ch->UID = readUInt(mf,(unsigned)len);
  1587.     break;
  1588.   case 0x45bd: // EditionFlagHidden
  1589.     ch->Hidden = readUInt(mf,(unsigned)len)!=0;
  1590.     break;
  1591.   case 0x45db: // EditionFlagDefault
  1592.     ch->Default = readUInt(mf,(unsigned)len)!=0;
  1593.     break;
  1594.   case 0x45dd: // EditionFlagOrdered
  1595.     ch->Ordered = readUInt(mf,(unsigned)len)!=0;
  1596.     break;
  1597.   case 0xb6: // ChapterAtom
  1598.     parseChapter(mf,len,ch);
  1599.     break;
  1600. ENDFOR(mf);
  1601.       break;
  1602.   ENDFOR(mf);
  1603. }
  1604. static void parseTags(MatroskaFile *mf,ulonglong toplen) {
  1605.   struct Tag  *tag;
  1606.   struct Target *target;
  1607.   struct SimpleTag *st;
  1608.   mf->seen.Tags = 1;
  1609.   FOREACH(mf,toplen)
  1610.     case 0x7373: // Tag
  1611.       tag = AGET(mf,Tags);
  1612.       memset(tag,0,sizeof(*tag));
  1613.       FOREACH(mf,len)
  1614. case 0x63c0: // Targets
  1615.   FOREACH(mf,len)
  1616.     case 0x63c5: // TrackUID
  1617.       target = ASGET(mf,tag,Targets);
  1618.       target->UID = readUInt(mf,(unsigned)len);
  1619.       target->Type = TARGET_TRACK;
  1620.       break;
  1621.     case 0x63c4: // ChapterUID
  1622.       target = ASGET(mf,tag,Targets);
  1623.       target->UID = readUInt(mf,(unsigned)len);
  1624.       target->Type = TARGET_CHAPTER;
  1625.       break;
  1626.     case 0x63c6: // AttachmentUID
  1627.       target = ASGET(mf,tag,Targets);
  1628.       target->UID = readUInt(mf,(unsigned)len);
  1629.       target->Type = TARGET_ATTACHMENT;
  1630.       break;
  1631.     case 0x63c9: // EditionUID
  1632.       target = ASGET(mf,tag,Targets);
  1633.       target->UID = readUInt(mf,(unsigned)len);
  1634.       target->Type = TARGET_EDITION;
  1635.       break;
  1636.   ENDFOR(mf);
  1637.   break;
  1638. case 0x67c8: // SimpleTag
  1639.   st = ASGET(mf,tag,SimpleTags);
  1640.   memset(st,0,sizeof(*st));
  1641.   FOREACH(mf,len)
  1642.     case 0x45a3: // TagName
  1643.       if (st->Name)
  1644. skipbytes(mf,len);
  1645.       else
  1646. STRGETM(mf,st->Name,len);
  1647.       break;
  1648.     case 0x4487: // TagString
  1649.       if (st->Value)
  1650. skipbytes(mf,len);
  1651.       else
  1652. STRGETM(mf,st->Value,len);
  1653.       break;
  1654.     case 0x447a: // TagLanguage
  1655.       if (st->Language)
  1656. skipbytes(mf,len);
  1657.       else
  1658. STRGETM(mf,st->Language,len);
  1659.       break;
  1660.     case 0x4484: // TagDefault
  1661.       st->Default = readUInt(mf,(unsigned)len)!=0;
  1662.       break;
  1663.   ENDFOR(mf);
  1664.   if (!st->Name || !st->Value) {
  1665.     mf->cache->memfree(mf->cache,st->Name);
  1666.     mf->cache->memfree(mf->cache,st->Value);
  1667.     mf->cache->memfree(mf->cache,st->Language); //Picard
  1668.     --tag->nSimpleTags;
  1669.   }
  1670.   break;
  1671.       ENDFOR(mf);
  1672.       break;
  1673.   ENDFOR(mf);
  1674. }
  1675. static void parseContainer(MatroskaFile *mf) {
  1676.   ulonglong len;
  1677.   int     id = readID(mf);
  1678.   if (id==EOF)
  1679.     errorjmp(mf,"Unexpected EOF in parseContainer");
  1680.   len = readSize(mf);
  1681.   switch (id) {
  1682.     case 0x1549a966: // SegmentInfo
  1683.       parseSegmentInfo(mf,len);
  1684.       break;
  1685.     case 0x1f43b675: // Cluster
  1686.       parseFirstCluster(mf,len);
  1687.       break;
  1688.     case 0x1654ae6b: // Tracks
  1689.       parseTracks(mf,len);
  1690.       break;
  1691.     case 0x1c53bb6b: // Cues
  1692.       parseCues(mf,len);
  1693.       break;
  1694.     case 0x1941a469: // Attachments
  1695.       parseAttachments(mf,len);
  1696.       break;
  1697.     case 0x1043a770: // Chapters
  1698.       parseChapters(mf,len);
  1699.       break;
  1700.     case 0x1254c367: // Tags
  1701.       parseTags(mf,len);
  1702.       break;
  1703.   }
  1704. }
  1705. static void parseContainerPos(MatroskaFile *mf,ulonglong pos) {
  1706.   seek(mf,pos);
  1707.   parseContainer(mf);
  1708. }
  1709. static void parsePointers(MatroskaFile *mf) {
  1710.   jmp_buf jb;
  1711.   if (mf->pSegmentInfo && !mf->seen.SegmentInfo)
  1712.     parseContainerPos(mf,mf->pSegmentInfo);
  1713.   if (mf->pCluster && !mf->seen.Cluster)
  1714.     parseContainerPos(mf,mf->pCluster);
  1715.   if (mf->pTracks && !mf->seen.Tracks)
  1716.     parseContainerPos(mf,mf->pTracks);
  1717.   memcpy(&jb,&mf->jb,sizeof(jb));
  1718.   if (setjmp(mf->jb)) 
  1719.     mf->flags &= ~MPF_ERROR; // ignore errors
  1720.   else {
  1721.     if (mf->pCues && !mf->seen.Cues)
  1722. parseContainerPos(mf,mf->pCues);
  1723.     if (mf->pAttachments && !mf->seen.Attachments)
  1724.       parseContainerPos(mf,mf->pAttachments);
  1725.     if (mf->pChapters && !mf->seen.Chapters)
  1726.       parseContainerPos(mf,mf->pChapters);
  1727.     if (mf->pTags && !mf->seen.Tags)
  1728.       parseContainerPos(mf,mf->pTags);
  1729.   }
  1730.   memcpy(&mf->jb,&jb,sizeof(jb));
  1731. }
  1732. static void parseSegment(MatroskaFile *mf,ulonglong toplen) {
  1733.   ulonglong   nextpos;
  1734.   unsigned    nSeekHeads = 0, dontstop = 0;
  1735.   // we want to read data until we find a seekhead or a trackinfo
  1736.   FOREACH(mf,toplen)
  1737.     case 0x114d9b74: // SeekHead
  1738.       if (mf->flags & MKVF_AVOID_SEEKS) {
  1739. skipbytes(mf,len);
  1740. break;
  1741.       }
  1742.       nextpos = filepos(mf) + len;
  1743.       do {
  1744. mf->pSeekHead = 0;
  1745. parseSeekHead(mf,len);
  1746. ++nSeekHeads;
  1747. if (mf->pSeekHead) { // this is possibly a chained SeekHead
  1748.   seek(mf,mf->pSeekHead);
  1749.   id = readID(mf);
  1750.   if (id==EOF) // chained SeekHead points to EOF?
  1751.     break;
  1752.   if (id != 0x114d9b74) // chained SeekHead doesnt point to a SeekHead?
  1753.     break;
  1754.   len = readSize(mf);
  1755. } else if (mf->pSegmentInfo && mf->pTracks && mf->pCues && mf->pCluster) { // we have pointers to all key elements
  1756.   // XXX EVIL HACK
  1757.   // Some software doesnt index tags via SeekHead, so we continue
  1758.   // reading the segment after the second SeekHead
  1759.   if (mf->pTags || nSeekHeads<2 || filepos(mf)>=start+toplen) {
  1760.     parsePointers(mf);
  1761.     return;
  1762.   }
  1763.   // reset nextpos pointer to current position
  1764.   nextpos = filepos(mf);
  1765.   dontstop = 1;
  1766. }
  1767.       } while (mf->pSeekHead);
  1768.       seek(mf,nextpos); // resume reading segment
  1769.       break;
  1770.     case 0x1549a966: // SegmentInfo
  1771.       mf->pSegmentInfo = cur;
  1772.       parseSegmentInfo(mf,len);
  1773.       break;
  1774.     case 0x1f43b675: // Cluster
  1775.       if (!mf->pCluster)
  1776. mf->pCluster = cur;
  1777.       if (mf->seen.Cluster)
  1778. skipbytes(mf,len);
  1779.       else
  1780. parseFirstCluster(mf,len);
  1781.       break;
  1782.     case 0x1654ae6b: // Tracks
  1783.       mf->pTracks = cur;
  1784.       parseTracks(mf,len);
  1785.       break;
  1786.     case 0x1c53bb6b: // Cues
  1787.       mf->pCues = cur;
  1788.       parseCues(mf,len);
  1789.       break;
  1790.     case 0x1941a469: // Attachments
  1791.       mf->pAttachments = cur;
  1792.       parseAttachments(mf,len);
  1793.       break;
  1794.     case 0x1043a770: // Chapters
  1795.       mf->pChapters = cur;
  1796.       parseChapters(mf,len);
  1797.       break;
  1798.     case 0x1254c367: // Tags
  1799.       mf->pTags = cur;
  1800.       parseTags(mf,len);
  1801.       break;
  1802.   ENDFOR1(mf);
  1803.     // if we have pointers to all key elements
  1804.     if (!dontstop && mf->pSegmentInfo && mf->pTracks && mf->pCluster)
  1805.       break;
  1806.   ENDFOR2();
  1807.   parsePointers(mf);
  1808. }
  1809. static void parseBlockAdditions(MatroskaFile *mf, ulonglong toplen, ulonglong timecode, unsigned track) {
  1810.   ulonglong add_id = 1, add_pos=0, add_len=0; //Picard
  1811.   unsigned char have_add;
  1812.   void* add_ref = NULL;
  1813.   FOREACH(mf, toplen)
  1814.     case 0xa6: // BlockMore
  1815.       have_add = 0;
  1816.       FOREACH(mf, len)
  1817. case 0xee: // BlockAddId
  1818.   add_id = readUInt(mf, (unsigned)len);
  1819.   break;
  1820. case 0xa5: // BlockAddition
  1821.   add_pos = filepos(mf);
  1822.   add_len = len;
  1823.   if (!have_add) add_ref = mf->cache->makeref(mf->cache,(int)len); else //Picard
  1824.   skipbytes(mf, len);
  1825.   ++have_add;
  1826.   break;
  1827.       ENDFOR(mf);
  1828.       if (have_add == 1 && id > 0 && id < 255) {
  1829. struct QueueEntry *qe = QAlloc(mf);
  1830. qe->Start = qe->End = timecode;
  1831. qe->Position = add_pos;
  1832. qe->Length = (unsigned)add_len;
  1833. qe->Ref = add_ref; //Picard
  1834. add_ref = NULL;
  1835. qe->flags = FRAME_UNKNOWN_START | FRAME_UNKNOWN_END |
  1836.   (((unsigned)add_id << FRAME_STREAM_SHIFT) & FRAME_STREAM_MASK);
  1837. QPut(&mf->Queues[track],qe);
  1838.       }
  1839.   if (add_ref) { mf->cache->releaseref(mf->cache,add_ref); add_ref = NULL; } //Picard
  1840.       break;
  1841.   ENDFOR(mf);
  1842. }
  1843. static void parseBlockGroup(MatroskaFile *mf,ulonglong toplen,ulonglong timecode) {
  1844.   ulonglong v;
  1845.   ulonglong duration = 0;
  1846.   ulonglong dpos;
  1847.   //unsigned add_id = 0; //Picard
  1848.   struct QueueEntry *qe,*qf = NULL;
  1849.   unsigned char have_duration = 0, have_block = 0;
  1850.   unsigned char gap = 0;
  1851.   unsigned char lacing = 0;
  1852.   unsigned char ref = 0;
  1853.   unsigned char trackid;
  1854.   unsigned tracknum = 0;
  1855.   int c;
  1856.   unsigned nframes = 0,i;
  1857.   unsigned *sizes;
  1858.   signed short block_timecode;
  1859.   FOREACH(mf,toplen)
  1860.     case 0xfb: // ReferenceBlock
  1861.       readSInt(mf,(unsigned)len);
  1862.       ref = 1;
  1863.       break;
  1864.     case 0xa1: // Block
  1865.       have_block = 1;
  1866.       dpos = filepos(mf);
  1867.       v = readVLUInt(mf);
  1868.       if (v>255)
  1869. errorjmp(mf,"Invalid track number in Block: %d",(int)v);
  1870.       trackid = (unsigned char)v;
  1871.       for (tracknum=0;tracknum<mf->nTracks;++tracknum)
  1872. if (mf->Tracks[tracknum]->Number == trackid)
  1873.   goto found;
  1874.       errorjmp(mf,"Invalid track number in Block: %u",trackid);
  1875. found:
  1876.       if (mf->trackMask & (1<<tracknum)) { // ignore this block
  1877. skipbytes(mf,start + tmplen - filepos(mf)); // shortcut
  1878. return;
  1879.       }
  1880.       block_timecode = (signed short)readSInt(mf,2);
  1881.       // recalculate this block's timecode to final timecode in ns
  1882.       timecode = mul3(mf->Tracks[tracknum]->TimecodeScale,
  1883. (timecode - mf->firstTimecode + block_timecode) * mf->Seg.TimecodeScale);
  1884.       c = readch(mf);
  1885.       if (c==EOF)
  1886. errorjmp(mf,"Unexpected EOF while reading Block flags");
  1887.       gap = c & 0x1;
  1888.       lacing = (c >> 1) & 3;
  1889.       if (lacing) {
  1890. c = readch(mf);
  1891. if (c == EOF)
  1892.   errorjmp(mf,"Unexpected EOF while reading lacing data");
  1893. nframes = c+1;
  1894.       } else
  1895. nframes = 1;
  1896.       sizes = alloca(nframes*sizeof(*sizes));
  1897.  
  1898.       switch (lacing) {
  1899. case 0: // No lacing
  1900.   sizes[0] = (unsigned)(len - filepos(mf) + dpos);
  1901.   break;
  1902. case 1: // Xiph lacing
  1903.   sizes[nframes-1] = 0;
  1904.   for (i=0;i<nframes-1;++i) {
  1905.     sizes[i] = 0;
  1906.     do {
  1907.       c = readch(mf);
  1908.       if (c==EOF)
  1909. errorjmp(mf,"Unexpected EOF while reading lacing data");
  1910.       sizes[i] += c;
  1911.     } while (c==255);
  1912.     sizes[nframes-1] += sizes[i];
  1913.   }
  1914.   sizes[nframes-1] = (unsigned)(len - filepos(mf) + dpos) - sizes[nframes-1];
  1915.   break;
  1916. case 3: // EBML lacing
  1917.   sizes[nframes-1] = 0;
  1918.   sizes[0] = (unsigned)readVLUInt(mf);
  1919.   for (i=1;i<nframes-1;++i) {
  1920.     sizes[i] = sizes[i-1] + (int)readVLSInt(mf);
  1921.     sizes[nframes-1] += sizes[i];
  1922.   }
  1923.   if (nframes>1)
  1924.     sizes[nframes-1] = (unsigned)(len - filepos(mf) + dpos) - sizes[0] - sizes[nframes-1];
  1925.   break;
  1926. case 2: // Fixed lacing
  1927.   sizes[0] = (unsigned)(len - filepos(mf) + dpos)/nframes;
  1928.   for (i=1;i<nframes;++i)
  1929.     sizes[i] = sizes[0];
  1930.   break;
  1931.       }
  1932.       v = filepos(mf);
  1933.       qf = NULL;
  1934.       for (i=0;i<nframes;++i) {
  1935. qe = QAlloc(mf);
  1936. if (!qf)
  1937.   qf = qe;
  1938. qe->Start = timecode;
  1939. qe->End = timecode;
  1940. qe->Position = v;
  1941. qe->Length = sizes[i];
  1942. qe->Ref = mf->cache->makeref(mf->cache,sizes[i]); //Picard
  1943. qe->flags = FRAME_UNKNOWN_END | FRAME_KF;
  1944. if (i == nframes-1 && gap)
  1945.   qe->flags |= FRAME_GAP;
  1946. if (i > 0)
  1947.   qe->flags |= FRAME_UNKNOWN_START;
  1948. QPut(&mf->Queues[tracknum],qe);
  1949. v += sizes[i];
  1950.       }
  1951.       // we want to still load these bytes into cache
  1952.   //Picard, not needed for TCPMP 
  1953.   /*
  1954.       for (v = filepos(mf) & ~0x3fff; v < len + dpos; v += 0x4000)
  1955. mf->cache->read(mf->cache,v,NULL,0); // touch page
  1956.   */
  1957.       skipbytes(mf,len - filepos(mf) + dpos);
  1958.       break;
  1959.     case 0x9b: // BlockDuration
  1960.       duration = readUInt(mf,(unsigned)len);
  1961.       have_duration = 1;
  1962.       break;
  1963.     case 0x75a1: // BlockAdditions
  1964.       if (nframes > 0) // have some frames
  1965. parseBlockAdditions(mf, len, timecode, tracknum);
  1966.       else
  1967. skipbytes(mf, len);
  1968.       break;
  1969.   ENDFOR(mf);
  1970.   if (!have_block)
  1971.     errorjmp(mf,"Found a BlockGroup without Block");
  1972.   if (nframes > 1) {
  1973.     if (have_duration) {
  1974.       duration = mul3(mf->Tracks[tracknum]->TimecodeScale,
  1975. duration * mf->Seg.TimecodeScale);
  1976.       dpos = duration / nframes;
  1977.       v = qf->Start;
  1978.       for (qe = qf; nframes > 1; --nframes, qe = qe->next) {
  1979. qe->Start = v;
  1980. v += dpos;
  1981. duration -= dpos;
  1982. qe->End = v;
  1983. qe->flags &= ~(FRAME_UNKNOWN_START|FRAME_UNKNOWN_END);
  1984.       }
  1985.       qe->Start = v;
  1986.       qe->End = v + duration;
  1987.       qe->flags &= ~(FRAME_UNKNOWN_START|FRAME_UNKNOWN_END);
  1988.     } else if (mf->Tracks[tracknum]->DefaultDuration) {
  1989.       dpos = mf->Tracks[tracknum]->DefaultDuration;
  1990.       v = qf->Start;
  1991.       for (qe = qf; nframes > 0; --nframes, qe = qe->next) {
  1992. qe->Start = v;
  1993. v += dpos;
  1994. qe->End = v;
  1995. qe->flags &= ~(FRAME_UNKNOWN_START|FRAME_UNKNOWN_END);
  1996.       }
  1997.     }
  1998.   } else if (nframes == 1) {
  1999.     if (have_duration) {
  2000.       qf->End = qf->Start + mul3(mf->Tracks[tracknum]->TimecodeScale,
  2001. duration * mf->Seg.TimecodeScale);
  2002.       qf->flags &= ~FRAME_UNKNOWN_END;
  2003.     } else if (mf->Tracks[tracknum]->DefaultDuration) {
  2004.       qf->End = qf->Start + mf->Tracks[tracknum]->DefaultDuration;
  2005.       qf->flags &= ~FRAME_UNKNOWN_END;
  2006.     }
  2007.   }
  2008.   if (ref)
  2009.     while (qf) {
  2010.       qf->flags &= ~FRAME_KF;
  2011.       qf = qf->next;
  2012.     }
  2013. }
  2014. static void ClearQueue(MatroskaFile *mf,struct Queue *q) {
  2015.   struct QueueEntry *qe,*qn;
  2016.   for (qe=q->head;qe;qe=qn) {
  2017.     qn = qe->next;
  2018. QFree(mf,qe); //Picard
  2019.     /*
  2020. qe->next = mf->QFreeList;
  2021.     mf->QFreeList = qe;
  2022. */
  2023.   }
  2024.   q->head = NULL;
  2025.   q->tail = NULL;
  2026. }
  2027. static void EmptyQueues(MatroskaFile *mf) {
  2028.   unsigned     i;
  2029.   for (i=0;i<mf->nTracks;++i)
  2030.     ClearQueue(mf,&mf->Queues[i]);
  2031. }
  2032. static int  readMoreBlocks(MatroskaFile *mf) {
  2033.   ulonglong toplen, cstop;
  2034.   longlong cp;
  2035.   int cid, ret = 0;
  2036.   jmp_buf jb;
  2037.   volatile unsigned retries = 0;
  2038.   if (mf->readPosition >= mf->pSegmentTop)
  2039.     return EOF;
  2040.   memcpy(&jb,&mf->jb,sizeof(jb));
  2041.   if (setjmp(mf->jb)) { // something evil happened here, try to resync
  2042.     // always advance read position no matter what so
  2043.     // we don't get caught in an endless loop
  2044.     mf->readPosition = filepos(mf);
  2045.     ret = EOF;
  2046.     if (++retries > 3) // don't try too hard
  2047.       goto ex;
  2048.     for (;;) {
  2049.       if (filepos(mf) >= mf->pSegmentTop)
  2050. goto ex;
  2051.       cp = mf->cache->scan(mf->cache,filepos(mf),0x1f43b675); // cluster
  2052.       if (cp < 0 || (ulonglong)cp >= mf->pSegmentTop)
  2053. goto ex;
  2054.       seek(mf,cp);
  2055.       cid = readID(mf);
  2056.       if (cid == EOF)
  2057. goto ex;
  2058.       if (cid == 0x1f43b675) {
  2059. toplen = readSize(mf);
  2060. if (toplen < MAXCLUSTER) {
  2061.   // reset error flags
  2062.   mf->flags &= ~MPF_ERROR;
  2063.   ret = RBRESYNC;
  2064.   break;
  2065. }
  2066.       }
  2067.     }
  2068.     mf->readPosition = cp;
  2069.   }
  2070.   cstop = mf->cache->getsize(mf->cache)>>1;
  2071.   if (cstop > MAX_READAHEAD)
  2072.     cstop = MAX_READAHEAD;
  2073.   cstop += mf->readPosition;
  2074.   seek(mf,mf->readPosition);
  2075.   while (filepos(mf) < mf->pSegmentTop) {
  2076.     cid = readID(mf);
  2077.     if (cid == EOF) {
  2078.       ret = EOF;
  2079.       break;
  2080.     }
  2081.     toplen = readSize(mf);
  2082.     if (cid == 0x1f43b675) { // Cluster
  2083.       unsigned char have_timecode = 0;
  2084.       FOREACH(mf,toplen)
  2085. case 0xe7: // Timecode
  2086.   mf->tcCluster = readUInt(mf,(unsigned)len);
  2087.   have_timecode = 1;
  2088.   break;
  2089. case 0xa7: // Position
  2090.   readUInt(mf,(unsigned)len);
  2091.   break;
  2092. case 0xab: // PrevSize
  2093.   readUInt(mf,(unsigned)len);
  2094.   break;
  2095. case 0x5854: { // SilentTracks
  2096.   unsigned  stmask = 0, i, trk;
  2097.   FOREACH(mf, len)
  2098.     case 0x58d7: // SilentTrackNumber
  2099.       trk = (unsigned)readUInt(mf, (unsigned)len);
  2100.       for (i = 0; i < mf->nTracks; ++i)
  2101. if (mf->Tracks[i]->Number == trk) {
  2102.   stmask |= 1 << i;
  2103.   break;
  2104. }
  2105.       break;
  2106.   ENDFOR(mf);
  2107.   // TODO pass stmask to reading app
  2108.   break; }
  2109. case 0xa0: // BlockGroup
  2110.   if (!have_timecode)
  2111.     errorjmp(mf,"Found BlockGroup before cluster TimeCode");
  2112.   parseBlockGroup(mf,len,mf->tcCluster);
  2113.   goto out;
  2114.       ENDFOR(mf);
  2115. out:;
  2116.     } else {
  2117.       if (toplen > MAXFRAME)
  2118. errorjmp(mf,"Element in a cluster is too large around %llu, %X [%u]",filepos(mf),cid,(unsigned)toplen);
  2119.       if (cid == 0xa0) // BlockGroup
  2120. parseBlockGroup(mf,toplen,mf->tcCluster);
  2121.       else
  2122. skipbytes(mf,toplen);
  2123.     }
  2124.     if ((mf->readPosition = filepos(mf)) > cstop)
  2125.       break;
  2126.   }
  2127.   mf->readPosition = filepos(mf);
  2128. ex:
  2129.   memcpy(&mf->jb,&jb,sizeof(jb));
  2130.   return ret;
  2131. }
  2132. // this is almost the same as readMoreBlocks, except it ensures
  2133. // there are no partial frames queued, however empty queues are ok
  2134. static int  fillQueues(MatroskaFile *mf,unsigned int mask) {
  2135.   unsigned    i,j;
  2136.   int       ret = 0;
  2137.   for (;;) {
  2138.     j = 0;
  2139.     for (i=0;i<mf->nTracks;++i)
  2140.       if (mf->Queues[i].head && !(mask & (1<<i)))
  2141. ++j;
  2142.     if (j>0) // have at least some frames
  2143.       return ret;
  2144.     if ((ret = readMoreBlocks(mf)) < 0) {
  2145.       j = 0;
  2146.       for (i=0;i<mf->nTracks;++i)
  2147. if (mf->Queues[i].head && !(mask & (1<<i)))
  2148.   ++j;
  2149.       if (j) // we adjusted some blocks
  2150. return 0;
  2151.       return EOF;
  2152.     }
  2153.   }
  2154. }
  2155. static void reindex(MatroskaFile *mf) {
  2156.   jmp_buf     jb;
  2157.   ulonglong   pos = mf->pCluster;
  2158.   ulonglong   step = 10*1024*1024;
  2159.   ulonglong   size, tc=0, isize; //Picard
  2160.   longlong    next_cluster;
  2161.   int       id, have_tc, bad;
  2162.   struct Cue  *cue;
  2163.   if (pos >= mf->pSegmentTop)
  2164.     return;
  2165.   if (pos + step * 10 > mf->pSegmentTop)
  2166.     step = (mf->pSegmentTop - pos) / 10;
  2167.   if (step == 0)
  2168.     step = 1;
  2169.   memcpy(&jb,&mf->jb,sizeof(jb));
  2170.   // remove all cues
  2171.   mf->nCues = 0;
  2172.   bad = 0;
  2173.   while (pos < mf->pSegmentTop) {
  2174.     if (!mf->cache->progress(mf->cache,pos,mf->pSegmentTop))
  2175.       break;
  2176.     if (++bad > 50) {
  2177.       pos += step;
  2178.       bad = 0;
  2179.       continue;
  2180.     }
  2181.     // find next cluster header
  2182.     next_cluster = mf->cache->scan(mf->cache,pos,0x1f43b675); // cluster
  2183.     if (next_cluster < 0 || (ulonglong)next_cluster >= mf->pSegmentTop)
  2184.       break;
  2185.     pos = next_cluster + 4; // prevent endless loops
  2186.     if (setjmp(mf->jb)) // something evil happened while reindexing
  2187.       continue;
  2188.     seek(mf,next_cluster);
  2189.     id = readID(mf);
  2190.     if (id == EOF)
  2191.       break;
  2192.     if (id != 0x1f43b675) // shouldn't happen
  2193.       continue;
  2194.     size = readVLUInt(mf);
  2195.     if (size >= MAXCLUSTER || size < 1024)
  2196.       continue;
  2197.     have_tc = 0;
  2198.     size += filepos(mf);
  2199.     while (filepos(mf) < (ulonglong)next_cluster + 1024) {
  2200.       id = readID(mf);
  2201.       if (id == EOF)
  2202. break;
  2203.       isize = readVLUInt(mf);
  2204.       if (id == 0xe7) { // cluster timecode
  2205. tc = readUInt(mf,(unsigned)isize);
  2206. have_tc = 1;
  2207. break;
  2208.       }
  2209.       skipbytes(mf,isize);
  2210.     }
  2211.     if (!have_tc)
  2212.       continue;
  2213.     seek(mf,size);
  2214.     id = readID(mf);
  2215.     if (id == EOF)
  2216.       break;
  2217.     if (id != 0x1f43b675) // cluster
  2218.       continue;
  2219.     // good cluster, remember it
  2220.     cue = AGET(mf,Cues);
  2221.     cue->Time = tc;
  2222.     cue->Position = next_cluster - mf->pSegment;
  2223.     cue->Block = 0;
  2224.     cue->Track = 0;
  2225.     // advance to the next point
  2226.     pos = next_cluster + step;
  2227.     if (pos < size)
  2228.       pos = size;
  2229.     bad = 0;
  2230.   }
  2231.   fixupCues(mf);
  2232.   if (mf->nCues == 0) {
  2233.     cue = AGET(mf,Cues);
  2234.     cue->Time = mf->firstTimecode;
  2235.     cue->Position = mf->pCluster - mf->pSegment;
  2236.     cue->Block = 0;
  2237.     cue->Track = 0;
  2238.   }
  2239.   mf->cache->progress(mf->cache,0,0);
  2240.   memcpy(&mf->jb,&jb,sizeof(jb));
  2241. }
  2242. static void fixupChapter(ulonglong adj, struct Chapter *ch) {
  2243.   unsigned i;
  2244.   if (ch->Start != 0)
  2245.     ch->Start -= adj;
  2246.   if (ch->End != 0)
  2247.     ch->End -= adj;
  2248.   for (i=0;i<ch->nChildren;++i)
  2249.     fixupChapter(adj,&ch->Children[i]);
  2250. }
  2251. static longlong findLastTimecode(MatroskaFile *mf) {
  2252.   ulonglong   nd = 0;
  2253.   unsigned    n,vtrack;
  2254.   if (mf->nCues == 0 || mf->nTracks == 0)
  2255.     return -1;
  2256.   for (n=vtrack=0;n<mf->nTracks;++n)
  2257.     if (mf->Tracks[n]->Type == TT_VIDEO) {
  2258.       vtrack = n;
  2259.       goto ok;
  2260.     }
  2261.   return -1;
  2262. ok:
  2263.   EmptyQueues(mf);
  2264.   mf->trackMask = ~(1 << vtrack);
  2265.   mf->readPosition = mf->Cues[mf->nCues - 1].Position + mf->pSegment;
  2266.   mf->tcCluster = mf->Cues[mf->nCues - 1].Time / mf->Seg.TimecodeScale;
  2267.   do
  2268.     while (mf->Queues[vtrack].head)
  2269.     {
  2270.       ulonglong   tc = mf->Queues[vtrack].head->flags & FRAME_UNKNOWN_END ?
  2271.   mf->Queues[vtrack].head->Start : mf->Queues[vtrack].head->End;
  2272.       if (nd < tc)
  2273. nd = tc;
  2274.       QFree(mf,QGet(&mf->Queues[vtrack]));
  2275.     }
  2276.   while (fillQueues(mf,0) != EOF);
  2277.   mf->trackMask = 0;
  2278.   EmptyQueues(mf);
  2279.   return nd;
  2280. }
  2281. static void parseFile(MatroskaFile *mf) {
  2282.   ulonglong len = filepos(mf), adjust;
  2283.   unsigned  i;
  2284.   int     id = readID(mf);
  2285.   int     m;
  2286.   if (id==EOF)
  2287.     errorjmp(mf,"Unexpected EOF at start of file");
  2288.   // files with multiple concatenated segments can have only
  2289.   // one EBML prolog
  2290.   if (len > 0 && id == 0x18538067)
  2291.     goto segment;
  2292.   if (id!=0x1a45dfa3)
  2293.     errorjmp(mf,"First element in file is not EBML");
  2294.   parseEBML(mf,readSize(mf));
  2295.   // next we need to find the first segment
  2296.   for (;;) {
  2297.     id = readID(mf);
  2298.     if (id==EOF)
  2299.       errorjmp(mf,"No segments found in the file");
  2300. segment:
  2301.     len = readVLUIntImp(mf,&m);
  2302.     // see if it's unspecified
  2303.     if (len == (MAXU64 >> (57-m*7)))
  2304.       len = MAXU64;
  2305.     if (id == 0x18538067) // Segment
  2306.       break;
  2307.     skipbytes(mf,len);
  2308.   }
  2309.   // found it
  2310.   mf->pSegment = filepos(mf);
  2311.   mf->pSegmentTop = len == MAXU64 ? MAXU64 : mf->pSegment + len;
  2312.   parseSegment(mf,len);
  2313.   // check if we got all data
  2314.   if (!mf->seen.SegmentInfo)
  2315.     errorjmp(mf,"Couldn't find SegmentInfo");
  2316.   if (!mf->seen.Cluster)
  2317.     mf->pCluster = mf->pSegmentTop;
  2318.   adjust = mf->firstTimecode * mf->Seg.TimecodeScale;
  2319.   for (i=0;i<mf->nChapters;++i)
  2320.     fixupChapter(adjust, &mf->Chapters[i]);
  2321.   // release extra memory
  2322.   ARELEASE(mf,mf,Tracks);
  2323.   // initialize reader
  2324.   mf->Queues = mf->cache->memalloc(mf->cache,mf->nTracks * sizeof(*mf->Queues));
  2325.   if (mf->Queues == NULL)
  2326.     errorjmp(mf, "Ouf of memory");
  2327.   memset(mf->Queues, 0, mf->nTracks * sizeof(*mf->Queues));
  2328.   // try to detect real duration
  2329.   if (!(mf->flags & MKVF_AVOID_SEEKS)) {
  2330.     longlong nd = findLastTimecode(mf);
  2331.     if (nd > 0)
  2332.       mf->Seg.Duration = nd;
  2333.   }
  2334.   // move to first frame
  2335.   mf->readPosition = mf->pCluster;
  2336.   mf->tcCluster = mf->firstTimecode;
  2337.   seek(mf,mf->readPosition); //Picard
  2338. }
  2339. static void DeleteChapter(MatroskaFile *mf,struct Chapter *ch) {
  2340.   unsigned i,j;
  2341.   for (i=0;i<ch->nDisplay;++i) {
  2342.     mf->cache->memfree(mf->cache,ch->Display[i].String);
  2343.     mf->cache->memfree(mf->cache,ch->Display[i].Language);
  2344.     mf->cache->memfree(mf->cache,ch->Display[i].Country);
  2345.   }
  2346.   mf->cache->memfree(mf->cache,ch->Display);
  2347.   mf->cache->memfree(mf->cache,ch->Tracks);
  2348.   for (i=0;i<ch->nProcess;++i) {
  2349.     for (j=0;j<ch->Process[i].nCommands;++j)
  2350.       mf->cache->memfree(mf->cache,ch->Process[i].Commands[j].Command);
  2351.     mf->cache->memfree(mf->cache,ch->Process[i].Commands);
  2352.     mf->cache->memfree(mf->cache,ch->Process[i].CodecPrivate);
  2353.   }
  2354.   mf->cache->memfree(mf->cache,ch->Process);
  2355.   for (i=0;i<ch->nChildren;++i)
  2356.     DeleteChapter(mf,&ch->Children[i]);
  2357.   mf->cache->memfree(mf->cache,ch->Children);
  2358. }
  2359. ///////////////////////////////////////////////////////////////////////////
  2360. // public interface
  2361. MatroskaFile  *mkv_OpenEx(InputStream *io,
  2362.   ulonglong base,
  2363.   unsigned flags,
  2364.   char *err_msg,unsigned msgsize)
  2365. {
  2366.   MatroskaFile *mf = io->memalloc(io,sizeof(*mf));
  2367.   if (mf == NULL) {
  2368.     strlcpy(err_msg,"Out of memory",msgsize);
  2369.     return NULL;
  2370.   }
  2371.   memset(mf,0,sizeof(*mf));
  2372.   mf->cache = io;
  2373.   mf->flags = flags;
  2374.   io->progress(io,0,0);
  2375.   if (setjmp(mf->jb)==0) {
  2376.     seek(mf,base);
  2377.     parseFile(mf);
  2378.   } else { // parser error
  2379.     strlcpy(err_msg,mf->errmsg,msgsize);
  2380.     mkv_Close(mf);
  2381.     return NULL;
  2382.   }
  2383.   return mf;
  2384. }
  2385. MatroskaFile  *mkv_Open(InputStream *io,
  2386. char *err_msg,unsigned msgsize)
  2387. {
  2388.   return mkv_OpenEx(io,0,0,err_msg,msgsize);
  2389. }
  2390. void       mkv_Close(MatroskaFile *mf) {
  2391.   unsigned  i,j;
  2392.   if (mf==NULL)
  2393.     return;
  2394.   if (mf->Queues) EmptyQueues(mf); //Picard
  2395.   for (i=0;i<mf->nTracks;++i)
  2396.     mf->cache->memfree(mf->cache,mf->Tracks[i]);
  2397.   mf->cache->memfree(mf->cache,mf->Tracks);
  2398.   for (i=0;i<mf->nQBlocks;++i)
  2399.     mf->cache->memfree(mf->cache,mf->QBlocks[i]);
  2400.   mf->cache->memfree(mf->cache,mf->QBlocks);
  2401.   mf->cache->memfree(mf->cache,mf->Queues);
  2402.   mf->cache->memfree(mf->cache,mf->Seg.Title);
  2403.   mf->cache->memfree(mf->cache,mf->Seg.MuxingApp);
  2404.   mf->cache->memfree(mf->cache,mf->Seg.WritingApp);
  2405.   mf->cache->memfree(mf->cache,mf->Seg.Filename);
  2406.   mf->cache->memfree(mf->cache,mf->Seg.NextFilename);
  2407.   mf->cache->memfree(mf->cache,mf->Seg.PrevFilename);
  2408.   mf->cache->memfree(mf->cache,mf->Cues);
  2409.   for (i=0;i<mf->nAttachments;++i) {
  2410.     mf->cache->memfree(mf->cache,mf->Attachments[i].Description);
  2411.     mf->cache->memfree(mf->cache,mf->Attachments[i].Name);
  2412.     mf->cache->memfree(mf->cache,mf->Attachments[i].MimeType);
  2413.   }
  2414.   mf->cache->memfree(mf->cache,mf->Attachments);
  2415.   for (i=0;i<mf->nChapters;++i)
  2416.     DeleteChapter(mf,&mf->Chapters[i]);
  2417.   mf->cache->memfree(mf->cache,mf->Chapters);
  2418.   for (i=0;i<mf->nTags;++i) {
  2419.     for (j=0;j<mf->Tags[i].nSimpleTags;++j) {
  2420.       mf->cache->memfree(mf->cache,mf->Tags[i].SimpleTags[j].Name);
  2421.       mf->cache->memfree(mf->cache,mf->Tags[i].SimpleTags[j].Value);
  2422.       mf->cache->memfree(mf->cache,mf->Tags[i].SimpleTags[j].Language); //Picard
  2423.     }
  2424.     mf->cache->memfree(mf->cache,mf->Tags[i].Targets);
  2425.     mf->cache->memfree(mf->cache,mf->Tags[i].SimpleTags);
  2426.   }
  2427.   mf->cache->memfree(mf->cache,mf->Tags);
  2428.   mf->cache->memfree(mf->cache,mf);
  2429. }
  2430. const char    *mkv_GetLastError(MatroskaFile *mf) {
  2431.   return mf->errmsg[0] ? mf->errmsg : NULL;
  2432. }
  2433. SegmentInfo   *mkv_GetFileInfo(MatroskaFile *mf) {
  2434.   return &mf->Seg;
  2435. }
  2436. unsigned int  mkv_GetNumTracks(MatroskaFile *mf) {
  2437.   return mf->nTracks;
  2438. }
  2439. TrackInfo     *mkv_GetTrackInfo(MatroskaFile *mf,unsigned track) {
  2440.   if (track>mf->nTracks)
  2441.     return NULL;
  2442.   return mf->Tracks[track];
  2443. }
  2444. void       mkv_GetAttachments(MatroskaFile *mf,Attachment **at,unsigned *count) {
  2445.   *at = mf->Attachments;
  2446.   *count = mf->nAttachments;
  2447. }
  2448. void       mkv_GetChapters(MatroskaFile *mf,Chapter **ch,unsigned *count) {
  2449.   *ch = mf->Chapters;
  2450.   *count = mf->nChapters;
  2451. }
  2452. void       mkv_GetTags(MatroskaFile *mf,Tag **tag,unsigned *count) {
  2453.   *tag = mf->Tags;
  2454.   *count = mf->nTags;
  2455. }
  2456. ulonglong     mkv_GetSegmentTop(MatroskaFile *mf) {
  2457.   return mf->pSegmentTop;
  2458. }
  2459. #define IS_DELTA(f) (!((f)->flags & FRAME_KF) || ((f)->flags & FRAME_UNKNOWN_START))
  2460. void  mkv_Seek(MatroskaFile *mf,ulonglong timecode,unsigned flags) {
  2461.   int i,j,m,ret;
  2462.   unsigned n,z,mask;
  2463.   ulonglong m_kftime[MAX_TRACKS];
  2464.   unsigned char m_seendf[MAX_TRACKS];
  2465.   if (mf->flags & MKVF_AVOID_SEEKS)
  2466.     return;
  2467.   if (timecode == 0) {
  2468.     EmptyQueues(mf);
  2469.     mf->readPosition = mf->pCluster;
  2470.     mf->tcCluster = mf->firstTimecode;
  2471.     mf->flags &= ~MPF_ERROR;
  2472. seek(mf,mf->readPosition); //Picard, we need to be able to start filling buffer
  2473.     return;
  2474.   }
  2475.   if (mf->nCues==0)
  2476.     reindex(mf);
  2477.   if (mf->nCues==0)
  2478.     return;
  2479.   mf->flags &= ~MPF_ERROR;
  2480.   i = 0;
  2481.   j = mf->nCues - 1;
  2482.   for (;;) {
  2483.     if (i>j) {
  2484.       j = j>=0 ? j : 0;
  2485.       if (setjmp(mf->jb)!=0)
  2486. return;
  2487.       mkv_SetTrackMask(mf,mf->trackMask);
  2488.       if (flags & MKVF_SEEK_TO_PREV_KEYFRAME) {
  2489. // we do this in two stages
  2490. // a. find the last keyframes before the require position
  2491. // b. seek to them
  2492. // pass 1
  2493. for (;;) {
  2494.   for (n=0;n<mf->nTracks;++n) {
  2495.     m_kftime[n] = MAXU64;
  2496.     m_seendf[n] = 0;
  2497.   }
  2498.   EmptyQueues(mf);
  2499.   mf->readPosition = mf->Cues[j].Position + mf->pSegment;
  2500.   mf->tcCluster = mf->Cues[j].Time / mf->Seg.TimecodeScale;
  2501.   for (;;) {
  2502.     if ((ret = fillQueues(mf,0)) < 0 || ret == RBRESYNC)
  2503.       return;
  2504.     // drain queues until we get to the required timecode
  2505.     for (n=0;n<mf->nTracks;++n) {
  2506.       if (mf->Queues[n].head && mf->Queues[n].head->Start<timecode) {
  2507. if (IS_DELTA(mf->Queues[n].head))
  2508.   m_seendf[n] = 1;
  2509. else
  2510.   m_kftime[n] = mf->Queues[n].head->Start;
  2511.       }
  2512.       while (mf->Queues[n].head && mf->Queues[n].head->Start<timecode)
  2513.       {
  2514. if (IS_DELTA(mf->Queues[n].head))
  2515.   m_seendf[n] = 1;
  2516. else
  2517.   m_kftime[n] = mf->Queues[n].head->Start;
  2518. QFree(mf,QGet(&mf->Queues[n]));
  2519.       }
  2520.       if (mf->Queues[n].head && (mf->Tracks[n]->Type != TT_AUDIO || mf->Queues[n].head->Start<=timecode))
  2521. if (!IS_DELTA(mf->Queues[n].head))
  2522.   m_kftime[n] = mf->Queues[n].head->Start;
  2523.     }
  2524.     for (n=0;n<mf->nTracks;++n)
  2525.       if (mf->Queues[n].head && mf->Queues[n].head->Start>=timecode)
  2526. goto found;
  2527.   }
  2528. found:
  2529.   
  2530.   for (n=0;n<mf->nTracks;++n)
  2531.     if (!(mf->trackMask & (1<<n)) && m_kftime[n]==MAXU64 &&
  2532. m_seendf[n] && j>0)
  2533.     {
  2534.       // we need to restart the search from prev cue
  2535.       --j;
  2536.       goto again;
  2537.     }
  2538.   break;
  2539. again:;
  2540. }
  2541.       } else
  2542. for (n=0;n<mf->nTracks;++n)
  2543.   m_kftime[n] = timecode;
  2544.       // now seek to this timecode
  2545.       EmptyQueues(mf);
  2546.       mf->readPosition = mf->Cues[j].Position + mf->pSegment;
  2547.       mf->tcCluster = mf->Cues[j].Time / mf->Seg.TimecodeScale;
  2548.       for (mask=0;;) {
  2549. if ((ret = fillQueues(mf,mask)) < 0 || ret == RBRESYNC)
  2550.   return;
  2551. // drain queues until we get to the required timecode
  2552. for (n=0;n<mf->nTracks;++n) {
  2553.   struct QueueEntry *qe;
  2554.   for (qe = mf->Queues[n].head;qe && qe->Start<m_kftime[n];qe = mf->Queues[n].head)
  2555.     QFree(mf,QGet(&mf->Queues[n]));
  2556. }
  2557. for (n=z=0;n<mf->nTracks;++n)
  2558.   if (m_kftime[n]==MAXU64 || (mf->Queues[n].head && mf->Queues[n].head->Start>=m_kftime[n])) {
  2559.     ++z;
  2560.     mask |= 1<<n;
  2561.     if (m_kftime[n]!=MAXU64) return; //Picard (buffer could get full if we would want to find all packets, like with subtitles)
  2562.   }
  2563. if (z==mf->nTracks)
  2564.   return;
  2565.       }
  2566.     }
  2567.     m = (i+j)>>1;
  2568.     if (timecode < mf->Cues[m].Time)
  2569.       j = m-1;
  2570.     else
  2571.       i = m+1;
  2572.   }
  2573. }
  2574. void  mkv_SkipToKeyframe(MatroskaFile *mf) {
  2575.   unsigned  n,wait;
  2576.   ulonglong ht;
  2577.   if (setjmp(mf->jb)!=0)
  2578.     return;
  2579.   // remove delta frames from queues
  2580.   do {
  2581.     wait = 0;
  2582.     if (fillQueues(mf,0)<0)
  2583.       return;
  2584.     for (n=0;n<mf->nTracks;++n)
  2585.       if (mf->Queues[n].head && !(mf->Queues[n].head->flags & FRAME_KF)) {
  2586. ++wait;
  2587. QFree(mf,QGet(&mf->Queues[n]));
  2588.       }
  2589.   } while (wait);
  2590.   // find highest queued time
  2591.   for (n=0,ht=0;n<mf->nTracks;++n)
  2592.     if (mf->Queues[n].head && ht<mf->Queues[n].head->Start)
  2593.       ht = mf->Queues[n].head->Start;
  2594.   // ensure the time difference is less than 100ms
  2595.   do {
  2596.     wait = 0;
  2597.     if (fillQueues(mf,0)<0)
  2598.       return;
  2599.     for (n=0;n<mf->nTracks;++n)
  2600.       while (mf->Queues[n].head && mf->Queues[n].head->next &&
  2601.   (mf->Queues[n].head->next->flags & FRAME_KF) &&
  2602.   ht - mf->Queues[n].head->Start > 100000000)
  2603.       {
  2604. ++wait;
  2605. QFree(mf,QGet(&mf->Queues[n]));
  2606.       }
  2607.   } while (wait);
  2608. }
  2609. ulonglong mkv_GetLowestQTimecode(MatroskaFile *mf) {
  2610.   unsigned  n,seen;
  2611.   ulonglong t;
  2612.   // find the lowest queued timecode
  2613.   for (n=seen=0,t=0;n<mf->nTracks;++n)
  2614.     if (mf->Queues[n].head && (!seen || t > mf->Queues[n].head->Start))
  2615.       t = mf->Queues[n].head->Start, seen=1;
  2616.   return seen ? t : (ulonglong)LL(-1);
  2617. }
  2618. int       mkv_TruncFloat(MKFLOAT f) {
  2619. #ifdef MATROSKA_INTEGER_ONLY
  2620.   return (int)(f.v >> 32);
  2621. #else
  2622.   return (int)f;
  2623. #endif
  2624. }
  2625. #define FTRACK 0xffffffff
  2626. void       mkv_SetTrackMask(MatroskaFile *mf,unsigned int mask) {
  2627.   unsigned int   i;
  2628.   if (mf->flags & MPF_ERROR)
  2629.     return;
  2630.   mf->trackMask = mask;
  2631.   for (i=0;i<mf->nTracks;++i)
  2632.     if (mask & (1<<i))
  2633.       ClearQueue(mf,&mf->Queues[i]);
  2634. }
  2635. int       mkv_ReadFrame(MatroskaFile *mf,
  2636.     unsigned int mask,unsigned int *track,
  2637.     ulonglong *StartTime,ulonglong *EndTime,
  2638.     ulonglong *FilePos,unsigned int *FrameSize,
  2639. void** FrameRef, //Picard
  2640.     unsigned int *FrameFlags)
  2641. {
  2642.   unsigned int     i,j;
  2643.   struct QueueEntry *qe;
  2644.   if (setjmp(mf->jb)!=0)
  2645.     return -1;
  2646.   do {
  2647.     // extract required frame, use block with the lowest timecode
  2648.     for (j=FTRACK,i=0;i<mf->nTracks;++i)
  2649.       if (!(mask & (1<<i)) && mf->Queues[i].head) {
  2650. j = i;
  2651. ++i;
  2652. break;
  2653.       }
  2654.     for (;i<mf->nTracks;++i)
  2655.       if (!(mask & (1<<i)) && mf->Queues[i].head &&
  2656.   mf->Queues[j].head->Start > mf->Queues[i].head->Start)
  2657. j = i;
  2658.     if (j != FTRACK) {
  2659.       qe = QGet(&mf->Queues[j]);
  2660.       *track = j;
  2661.       *StartTime = qe->Start;
  2662.       *EndTime = qe->End;
  2663.       *FilePos = qe->Position;
  2664.       *FrameSize = qe->Length;
  2665.       *FrameFlags = qe->flags;
  2666.   *FrameRef = qe->Ref; //Picard
  2667.   qe->Ref = NULL; //Picard
  2668.       QFree(mf,qe);
  2669.       return 0;
  2670.     }
  2671.     if (mf->flags & MPF_ERROR)
  2672.       return -1;
  2673.   } while (fillQueues(mf,mask)>=0);
  2674.   return EOF;
  2675. }
  2676. #ifdef MATROSKA_COMPRESSION_SUPPORT
  2677. /*************************************************************************
  2678.  * Compressed streams support
  2679.  ************************************************************************/
  2680. struct CompressedStream {
  2681.   MatroskaFile   *mf;
  2682.   z_stream   zs;
  2683.   /* current compressed frame */
  2684.   ulonglong   frame_pos;
  2685.   unsigned   frame_size;
  2686.   char   frame_buffer[2048];
  2687.   /* decoded data buffer */
  2688.   char   decoded_buffer[2048];
  2689.   unsigned   decoded_ptr;
  2690.   unsigned   decoded_size;
  2691.   /* error handling */
  2692.   char   errmsg[128];
  2693. };
  2694. CompressedStream  *cs_Create(/* in */ MatroskaFile *mf,
  2695.      /* in */ unsigned tracknum,
  2696.      /* out */ char *errormsg,
  2697.      /* in */ unsigned msgsize)
  2698. {
  2699.   CompressedStream  *cs;
  2700.   TrackInfo     *ti;
  2701.   int     code;
  2702.   ti = mkv_GetTrackInfo(mf, tracknum);
  2703.   if (ti == NULL) {
  2704.     strlcpy(errormsg, "No such track.", msgsize);
  2705.     return NULL;
  2706.   }
  2707.   if (!ti->CompEnabled) {
  2708.     strlcpy(errormsg, "Track is not compressed.", msgsize);
  2709.     return NULL;
  2710.   }
  2711.   if (ti->CompMethod != COMP_ZLIB) {
  2712.     strlcpy(errormsg, "Unsupported compression method.", msgsize);
  2713.     return NULL;
  2714.   }
  2715.   cs = mf->cache->memalloc(mf->cache,sizeof(*cs));
  2716.   if (cs == NULL) {
  2717.     strlcpy(errormsg, "Ouf of memory.", msgsize);
  2718.     return NULL;
  2719.   }
  2720.   memset(&cs->zs,0,sizeof(cs->zs));
  2721.   code = inflateInit(&cs->zs);
  2722.   if (code != Z_OK) {
  2723.     strlcpy(errormsg, "ZLib error.", msgsize);
  2724.     mf->cache->memfree(mf->cache,cs);
  2725.     return NULL;
  2726.   }
  2727.   cs->frame_size = 0;
  2728.   cs->decoded_ptr = cs->decoded_size = 0;
  2729.   cs->mf = mf;
  2730.   return cs;
  2731. }
  2732. void   cs_Destroy(/* in */ CompressedStream *cs) {
  2733.   if (cs == NULL)
  2734.     return;
  2735.   inflateEnd(&cs->zs);
  2736.   cs->mf->cache->memfree(cs->mf->cache,cs);
  2737. }
  2738. /* advance to the next frame in matroska stream, you need to pass values returned
  2739.  * by mkv_ReadFrame */
  2740. void   cs_NextFrame(/* in */ CompressedStream *cs,
  2741.        /* in */ ulonglong pos,
  2742.        /* in */ unsigned size)
  2743. {
  2744.   cs->zs.avail_in = 0;
  2745.   inflateReset(&cs->zs);
  2746.   cs->frame_pos = pos;
  2747.   cs->frame_size = size;
  2748.   cs->decoded_ptr = cs->decoded_size = 0;
  2749. }
  2750. /* read and decode more data from current frame, return number of bytes decoded,
  2751.  * 0 on end of frame, or -1 on error */
  2752. int   cs_ReadData(CompressedStream *cs,char *buffer,unsigned bufsize)
  2753. {
  2754.   char     *cp = buffer;
  2755.   unsigned  rd = 0;
  2756.   unsigned  todo;
  2757.   int     code;
  2758.   
  2759.   do {
  2760.     /* try to copy data from decoded buffer */
  2761.     if (cs->decoded_ptr < cs->decoded_size) {
  2762.       todo = cs->decoded_size - cs->decoded_ptr;;
  2763.       if (todo > bufsize - rd)
  2764. todo = bufsize - rd;
  2765.       memcpy(cp, cs->decoded_buffer + cs->decoded_ptr, todo);
  2766.       rd += todo;
  2767.       cp += todo;
  2768.       cs->decoded_ptr += todo;
  2769.     } else {
  2770.       /* setup output buffer */
  2771.       cs->zs.next_out = cs->decoded_buffer;
  2772.       cs->zs.avail_out = sizeof(cs->decoded_buffer);
  2773.       /* try to read more data */
  2774.       if (cs->zs.avail_in == 0 && cs->frame_size > 0) {
  2775. todo = cs->frame_size;
  2776. if (todo > sizeof(cs->frame_buffer))
  2777.   todo = sizeof(cs->frame_buffer);
  2778. if (cs->mf->cache->read(cs->mf->cache, cs->frame_pos, cs->frame_buffer, todo) != (int)todo) {
  2779.   strlcpy(cs->errmsg, "File read failed", sizeof(cs->errmsg));
  2780.   return -1;
  2781. }
  2782. cs->zs.next_in = cs->frame_buffer;
  2783. cs->zs.avail_in = todo;
  2784. cs->frame_pos += todo;
  2785. cs->frame_size -= todo;
  2786.       }
  2787.       /* try to decode more data */
  2788.       code = inflate(&cs->zs,Z_NO_FLUSH);
  2789.       if (code != Z_OK && code != Z_STREAM_END) {
  2790. strlcpy(cs->errmsg, "ZLib error.", sizeof(cs->errmsg));
  2791. return -1;
  2792.       }
  2793.       /* handle decoded data */
  2794.       if (cs->zs.avail_out == sizeof(cs->decoded_buffer)) /* EOF */
  2795. break;
  2796.       cs->decoded_ptr = 0;
  2797.       cs->decoded_size = sizeof(cs->decoded_buffer) - cs->zs.avail_out;
  2798.     }
  2799.   } while (rd < bufsize);
  2800.   return rd;
  2801. }
  2802. /* return error message for the last error */
  2803. const char   *cs_GetLastError(CompressedStream *cs)
  2804. {
  2805.   if (!cs->errmsg[0])
  2806.     return NULL;
  2807.   return cs->errmsg;
  2808. }
  2809. #endif