Buffer 'gPi->TrackInfo' accessed by index 'sdTr' can overflow
[platform/core/multimedia/libmm-fileinfo.git] / formats / ffmpeg / mm_file_format_midi.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <string.h>     /*memcmp*/
23 #include <stdio.h>
24 #include <stdlib.h>     /*malloc*/
25
26 #include "mm_file_debug.h"
27 #include "mm_file_utils.h"
28 #include "mm_file_format_private.h"
29 #include "mm_file_format_midi.h"
30
31 /**
32  * internal defines
33  */
34 enum {
35         AV_DEC_AUDIO_MIDI,
36         AV_DEC_AUDIO_XMF,
37         AV_DEC_AUDIO_RMF,
38 };
39
40 #define MMFILE_XMF_100          "XMF_1.00"
41 #define MMFILE_XMF_101          "XMF_1.01"
42 #define MMFILE_MXMF_200         "XMF_2.00"
43 #define MMFILE_RMF                      "IREZ"
44
45 /*--------------------------------------------------------------------------*/
46 /*   Defines                                                                */
47 /*--------------------------------------------------------------------------*/
48 #define MAX_SMF_MESSAGES                        256                                                     /*                          */
49 #define MAX_SMF_TRACKS                          32                                                      /* Should be <= 32          */
50 #define SMF_MAX_GAIN                            76                                                      /* - 6[dB] : 90             */
51 /* -18[dB] : 45             */
52 #define MINIMUM_LENGTH                          (20)
53
54 #define MELODY_MAP                                      (0)
55 #define DRUM_MAP                                        (1)
56 #define NUM_OF_MAPS                                     (2)
57
58
59 /*--------------------------------------------------------------------------*/
60 /*   Types                                                                  */
61 /*--------------------------------------------------------------------------*/
62 typedef struct _tagMidChInfo {
63         unsigned long           dKeyCon;                                        /* 0:Melady, 1:OFF, 2:ON           */
64         unsigned long           dLedSync;                                       /* 0:OFF, 1:ON                     */
65         unsigned long           dVibSync;                                       /* 0:OFF, 1:ON                     */
66 } MIDCHINFO, *PMIDCHINFO;
67
68 typedef struct _tagTrack {
69         unsigned long           dSmfCmd;                                        /* CMD @ now                      */
70         unsigned long           dSize;                                          /* [byte] 0 measns nothing in it. */
71         unsigned char           *pbBase;                                                /* NULL measns nothing in it.     */
72         unsigned long           dOffset;                                        /* offset byte                    */
73         long                            sdTicks;                                        /*                                */
74 } TRACKINFO, *PTRACKINFO;
75
76 typedef struct _tagOrderList {
77         struct _tagOrderList    *pPrev;
78         struct _tagOrderList    *pNext;
79         unsigned long                   dTrack;
80         unsigned long                   dTicks;
81 } ORDERLIST, *PORDERLIST;
82
83 typedef struct _tagMidInfo {
84         unsigned long           dTimeResolution;                        /* 0..0x7fff                       */
85         unsigned char           *pbText;                                                /*                                 */
86         unsigned long           dSizeText;                                      /*                                 */
87         unsigned char           *pbTitle;                                       /*                                 */
88         unsigned long           dSizeTitle;                                     /*                                 */
89         unsigned char           *pbCopyright;                           /*                                 */
90         unsigned long           dSizeCopyright;                         /*                                 */
91         unsigned long           dNumOfTracks;                           /* 1..32                           */
92         unsigned long           dSmfFormat;                                     /* 0..1                            */
93         unsigned long           dSetupBar;                                      /* 0:No, 1:Yes                     */
94         unsigned long           dStart;                                         /* Index after SetupBar            */
95         unsigned long           dVibNoteVoice;                          /* 0:No, 1:Yes                     */
96
97         long            sdTotalTicks;                           /* Total ticks                     */
98         long            sdDataEndTime;                          /* (22.10)[ms]                     */
99
100         unsigned long           dEndFlag;                                       /*                                 */
101         TRACKINFO                       TrackInfo[MAX_SMF_TRACKS];
102
103         struct _tagOrderList    *pTopOrderList;
104         struct _tagOrderList    *pDoneOrderList;
105         struct _tagOrderList    *pBottomOrderList;
106         ORDERLIST                               OrderList[MAX_SMF_TRACKS + 3];
107
108         MIDCHINFO                               ChInfo[16];                                     /*                                 */
109         unsigned long                   dValid;                                         /* 0:none, 1:Valid                 */
110         unsigned char                   bVoiceMap[NUM_OF_MAPS][128];/* 0:Empty, 1:Valid                */
111 } MIDINFO, *PMIDINFO;
112
113 /*---------------------------------------------------------------------------*/
114 /*   Globals                                                                 */
115 /*---------------------------------------------------------------------------*/
116 static PMIDINFO gPi;
117
118 /**
119  * internal midi parsing functions
120  */
121 static bool __AvParseSkipXmf2Mid(unsigned char *pbFile, unsigned long dFSize, unsigned long *skipSize)
122 {
123         unsigned long skipVal;
124
125         for (skipVal = 0; skipVal < dFSize - 3; skipVal++) {
126                 if (pbFile[skipVal] == 'M' &&
127                         pbFile[skipVal + 1] == 'T' &&
128                         pbFile[skipVal + 2] == 'h' &&
129                         pbFile[skipVal + 3] == 'd') {
130                         debug_msg(RELEASE, "__AvParseSkipForXMF : MThd Header found!\n");
131                         *skipSize = skipVal;
132                         return true;
133                 }
134         }
135
136         debug_error(DEBUG, "MThd header not found\n");
137
138         return false;
139 }
140
141 static void __AvMidInitializeOrderList(void)
142 {
143         int idx;
144
145         for (idx = 1; idx <= MAX_SMF_TRACKS + 1; idx++) {
146                 gPi->OrderList[idx].pPrev = &gPi->OrderList[idx - 1];
147                 gPi->OrderList[idx].pNext = &gPi->OrderList[idx + 1];
148                 gPi->OrderList[idx].dTrack = 0xFF;
149                 gPi->OrderList[idx].dTicks = 0xFFFFFFFFL;
150         }
151         gPi->OrderList[0].pPrev = NULL;
152         gPi->OrderList[0].pNext = &gPi->OrderList[1];
153         gPi->OrderList[MAX_SMF_TRACKS + 2].pPrev = &gPi->OrderList[MAX_SMF_TRACKS + 1];
154         gPi->OrderList[MAX_SMF_TRACKS + 2].pNext = NULL;
155         gPi->pTopOrderList = &gPi->OrderList[0];
156         gPi->pDoneOrderList = &gPi->OrderList[1];
157         gPi->pBottomOrderList = &gPi->OrderList[MAX_SMF_TRACKS + 2];
158 }
159
160 static void __AvMidSortOrderList(void)
161 {
162         PORDERLIST pSlot;
163         PORDERLIST pTerget;
164
165         pSlot = (gPi->pTopOrderList)->pNext;
166         (pSlot->pPrev)->pNext = pSlot->pNext;
167         (pSlot->pNext)->pPrev = pSlot->pPrev;
168         pSlot->dTicks = ((unsigned long)gPi->TrackInfo[pSlot->dTrack].sdTicks << 5) + pSlot->dTrack;
169
170         pTerget = pSlot->pNext;
171         while (pTerget != gPi->pDoneOrderList) {
172                 if (pSlot->dTicks <= pTerget->dTicks)
173                         break;
174                 pTerget = pTerget->pNext;
175         }
176
177         (pTerget->pPrev)->pNext = pSlot;
178         pSlot->pPrev = pTerget->pPrev;
179         pTerget->pPrev = pSlot;
180         pSlot->pNext = pTerget;
181 }
182
183 static void __AvMidInsertOrderList(unsigned long dTrack, long sdTicks)
184 {
185         PORDERLIST pTerget;
186
187         if (gPi->dNumOfTracks == 1)
188                 return;
189
190         if (((gPi->dEndFlag >> dTrack) & 0x01) == 0)
191                 return;
192
193         pTerget = gPi->pDoneOrderList->pNext;
194         if (pTerget == gPi->pBottomOrderList)
195                 return;
196
197         gPi->pDoneOrderList->pNext = pTerget->pNext;
198         (pTerget->pNext)->pPrev = gPi->pDoneOrderList;
199
200         pTerget->dTrack = dTrack;
201         pTerget->dTicks = ((unsigned long)sdTicks << 5) + dTrack;
202         pTerget->pPrev = gPi->pTopOrderList;
203         pTerget->pNext = (gPi->pTopOrderList)->pNext;
204         ((gPi->pTopOrderList)->pNext)->pPrev = pTerget;
205         (gPi->pTopOrderList)->pNext = pTerget;
206
207         __AvMidSortOrderList();
208 }
209
210 static void __AvMidRemoveFromOrderList(void)
211 {
212         PORDERLIST pSlot;
213         PORDERLIST pTerget;
214
215         pSlot = (gPi->pTopOrderList)->pNext;
216         (pSlot->pPrev)->pNext = pSlot->pNext;
217         (pSlot->pNext)->pPrev = pSlot->pPrev;
218
219         pTerget = gPi->pBottomOrderList;
220         (pTerget->pPrev)->pNext = pSlot;
221         pSlot->pPrev = pTerget->pPrev;
222         pTerget->pPrev = pSlot;
223         pSlot->pNext = pTerget;
224 }
225
226 static void __AvMidGetTrackTime(unsigned long dTrack)
227 {
228         unsigned long dTemp;
229         long dTime;
230         PTRACKINFO pMt;
231
232         if (((gPi->dEndFlag >> dTrack) & 0x01) == 0)
233                 return;
234
235         pMt = &(gPi->TrackInfo[dTrack]);
236
237         dTime = 0;
238         do {
239                 if (pMt->dOffset >= pMt->dSize) {
240                         gPi->dEndFlag &= ~(1L << dTrack);
241                         return;
242                 }
243                 dTemp = (unsigned long)pMt->pbBase[pMt->dOffset++];
244                 dTime = (dTime << 7) + (dTemp & 0x7f);
245         } while (dTemp >= 0x80);
246
247         pMt->sdTicks += dTime;
248 }
249
250 static void __AvMidUpdateTrackTime(unsigned long dTrack)
251 {
252         unsigned long dTemp;
253         long dTime;
254         PTRACKINFO pMt;
255
256         if (gPi->dNumOfTracks == 1) {
257                 /* Single track */
258                 if (((gPi->dEndFlag >> dTrack) & 0x01) == 0)
259                         return;
260
261                 pMt = &(gPi->TrackInfo[dTrack]);
262
263                 dTime = 0;
264                 do {
265                         if (pMt->dOffset >= pMt->dSize) {
266                                 gPi->dEndFlag &= ~(1L << dTrack);
267                                 return;
268                         }
269                         dTemp = (unsigned long)pMt->pbBase[pMt->dOffset++];
270                         dTime = (dTime << 7) + (dTemp & 0x7f);
271                 } while (dTemp >= 0x80);
272
273                 pMt->sdTicks += dTime;
274         } else {
275                 /* Multi track */
276                 if (((gPi->dEndFlag >> dTrack) & 0x01) == 0) {
277                         __AvMidRemoveFromOrderList();
278                         return;
279                 }
280
281                 pMt = &(gPi->TrackInfo[dTrack]);
282
283                 dTime = 0;
284                 do {
285                         if (pMt->dOffset >= pMt->dSize) {
286                                 gPi->dEndFlag &= ~(1L << dTrack);
287                                 __AvMidRemoveFromOrderList();
288                                 return;
289                         }
290                         dTemp = (unsigned long)pMt->pbBase[pMt->dOffset++];
291                         dTime = (dTime << 7) + (dTemp & 0x7f);
292                 } while (dTemp >= 0x80);
293
294                 pMt->sdTicks += dTime;
295                 __AvMidSortOrderList();
296         }
297 }
298
299 static void __AvMidResetTimeInfo(void)
300 {
301         unsigned long sdTrack;
302         PTRACKINFO pMt;
303
304         gPi->dEndFlag = 0;
305
306         for (sdTrack = 0; sdTrack < gPi->dNumOfTracks; sdTrack++) {
307                 pMt = &(gPi->TrackInfo[sdTrack]);
308
309                 pMt->dSmfCmd = 0;
310                 pMt->dOffset = 0;
311                 pMt->sdTicks = 0;
312                 if (pMt->dSize > 0)
313                         gPi->dEndFlag |= (1L << sdTrack);
314         }
315
316         __AvMidInitializeOrderList();
317
318         if (gPi->dNumOfTracks > MAX_SMF_TRACKS) {
319                 debug_error(DEBUG, "__AvMidResetTimeInfo:  Num of tracks is over MAX track number. !!\n");
320                 return;
321         }
322
323         for (sdTrack = 0; sdTrack < gPi->dNumOfTracks; sdTrack++) {
324                 __AvMidGetTrackTime(sdTrack);
325                 pMt = &(gPi->TrackInfo[sdTrack]);
326                 __AvMidInsertOrderList(sdTrack, pMt->sdTicks);
327         }
328 }
329
330 static bool __AvMidGetLeastTimeTrack(unsigned long *leastTimeTrack)
331 {
332         PORDERLIST      pTerget;
333
334         pTerget = (gPi->pTopOrderList)->pNext;
335         if (pTerget == gPi->pBottomOrderList)
336                 return false;
337
338         *leastTimeTrack = pTerget->dTrack;
339         return true;
340 }
341
342 static long __AvGetSizeOfFileInfo(void)
343 {
344         unsigned long           dCmd;
345         unsigned long           dCmd2;
346         unsigned long           dSize;
347
348         unsigned long           dTemp;
349         unsigned long           dTime;
350         unsigned long           sdTotalTicks;
351         long            sdCurrentTime;
352         long            sdDelta;
353         PMIDCHINFO      pCh;
354         unsigned long           dCh;
355
356         unsigned long           dSetup;                 /* bit0:beat@0, bit1:tempo@0, bit2:GmOn@0, bit3:tempo@1 */
357         PTRACKINFO      pMt;
358         unsigned long           sdTr;
359
360         static unsigned long    dBank[16];
361         static unsigned long    dCurrBank[16];
362
363         long            sdNonConductorTime;
364         long            sdNonConductorTicks;
365         unsigned long           dConductorNote;
366         dSetup = 0;
367         sdTotalTicks = 0;
368         sdCurrentTime = 0;
369         sdNonConductorTime = 0x7FFFFFFF;
370         sdNonConductorTicks = 0;
371         dConductorNote = 0;
372         sdDelta = (unsigned long)(500 << 10) / gPi->dTimeResolution;    /* default=0.5sec */
373
374         gPi->pbText = NULL;
375         gPi->dSizeText = 0;
376         gPi->pbTitle = NULL;
377         gPi->dSizeTitle = 0;
378         gPi->pbCopyright = NULL;
379         gPi->dSizeCopyright = 0;
380         gPi->dStart = 0;
381         gPi->dSetupBar = 0;
382         gPi->dVibNoteVoice = 0;
383
384         for (dCh = 0; dCh < NUM_OF_MAPS; dCh++) {
385                 for (dTemp = 0; dTemp < 128; dTemp++) {
386                         gPi->bVoiceMap[dCh][dTemp] = 0;
387                 }
388         }
389         gPi->bVoiceMap[MELODY_MAP][0] = 1;                                              /* GM Default Piano */
390
391         for (dCh = 0; dCh < 16; dCh++) {
392                 dBank[dCh] = 0;
393                 dCurrBank[dCh] = 0;
394                 pCh = &gPi->ChInfo[dCh];
395                 pCh->dKeyCon = 0;
396                 pCh->dVibSync = 0;
397                 pCh->dLedSync = 0;
398         }
399
400         __AvMidResetTimeInfo();
401
402         if (gPi->dSmfFormat != 0)
403                 dSetup |= 0x20;
404
405         while (gPi->dEndFlag != 0) {
406                 if ((gPi->dEndFlag == 1) && (sdNonConductorTime == 0x7FFFFFFF)) {
407                         sdNonConductorTime = sdCurrentTime;
408                         sdNonConductorTicks = sdTotalTicks;
409                         dConductorNote |= 2;
410                 }
411
412                 if (gPi->dNumOfTracks == 1) {
413                         sdTr = 0;
414                 } else {
415                         if (!__AvMidGetLeastTimeTrack(&sdTr))
416                                 break;
417                 }
418
419                 if (sdTr >= MAX_SMF_TRACKS) {
420                         debug_error(DEBUG, "__AvGetSizeOfFileInfo:  Num of tracks is over MAX track number. !!\n");
421                         return -1;
422                 }
423
424                 pMt = &(gPi->TrackInfo[sdTr]);
425
426                 dTime = pMt->sdTicks - sdTotalTicks;
427                 sdCurrentTime += dTime * sdDelta;
428                 sdTotalTicks = pMt->sdTicks;
429                 if ((sdCurrentTime < 0) || (sdTotalTicks > 0x07FFFFFFL))
430                         return -1;
431
432                 dCmd = (unsigned long)pMt->pbBase[pMt->dOffset++];
433
434                 if (dCmd < 0xf0) {
435                         /*--- MidiMsg ---*/
436                         if (dCmd < 0x80) {
437                                 dCmd = pMt->dSmfCmd;
438                                 if (dCmd < 0x80)
439                                         return -1;
440                                 pMt->dOffset--;
441                         } else {
442                                 pMt->dSmfCmd = dCmd;
443                         }
444
445                         dCh = dCmd & 0x0f;
446
447                         switch (dCmd & 0xf0) {
448                         case 0x90:      /* NoteOn */
449                                 /* Conductor Track Note Check */
450                                 if (sdTr == 0)
451                                         dConductorNote |= 1;
452                                 switch (dCurrBank[dCh] >> 8) {
453                                 case 0x79:
454                                         /* Melody */
455                                         break;
456
457                                 case 0x78:
458                                         /* Drum */
459                                         gPi->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
460                                         break;
461
462                                 default:
463                                         if (dCh == 9) {
464                                                 /* Unknown: default GM Drum */
465                                                 gPi->bVoiceMap[DRUM_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
466                                         }
467                                 }
468                                 pMt->dOffset += 2;
469                                 break;
470
471                         case 0xC0:      /* Program change */
472                                 switch (dBank[dCh] >> 8) {
473                                 case 0x79:
474                                         if (dBank[dCh] != 0x7906) {
475                                                 /* Melody */
476                                                 gPi->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
477                                         } else {
478                                                 /* Vibration Note */
479                                                 gPi->dVibNoteVoice = 1;
480                                         }
481                                         break;
482
483                                 case 0x78:
484                                         /* Drum */
485                                         break;
486
487                                 default:
488                                         /* default GM Melody */
489                                         if (dCh != 9) {
490                                                 gPi->bVoiceMap[MELODY_MAP][pMt->pbBase[pMt->dOffset] & 0x7F] = 1;
491                                         }
492                                 }
493
494                                 dCurrBank[dCh] = dBank[dCh];
495                                 pMt->dOffset++;
496                                 break;
497
498                         case 0xD0:      /* Channel pressure */
499                                 pMt->dOffset++;
500                                 break;
501
502                         case 0xB0:      /* Control Change */
503                                 switch (pMt->pbBase[pMt->dOffset]) {
504                                 case 0x00:      /* Bank select(MSB) */
505                                         dBank[dCh] = (dBank[dCh] & 0x00FF) | (pMt->pbBase[pMt->dOffset + 1] << 8);
506                                         break;
507
508                                 case 0x20:      /* Bank select (LSB) */
509                                         dBank[dCh] = (dBank[dCh] & 0xFF00) | pMt->pbBase[pMt->dOffset + 1];
510                                         break;
511                                 default:
512                                         break;
513                                 }
514                                 pMt->dOffset += 2;
515                                 break;
516
517                         default:
518                                 pMt->dOffset += 2;
519                                 break;
520                         }
521                 } else {
522                         switch (dCmd) {
523                         case 0xF0:                      /* SysEx */
524                         case 0xF7:                      /* SysEx */
525                                 pMt->dSmfCmd = 0;
526                                 dSize = 0;
527                                 do {
528                                         dTemp = (unsigned long)pMt->pbBase[pMt->dOffset++];
529                                         dSize = (dSize << 7) + (dTemp & 0x7f);
530                                 } while (dTemp >= 0x80);
531
532                                 if ((dSize == 5) &&
533                                         (pMt->pbBase[pMt->dOffset] == 0x7e) &&
534                                         (pMt->pbBase[pMt->dOffset + 1] == 0x7f) &&
535                                         (pMt->pbBase[pMt->dOffset + 2] == 0x09) &&
536                                         (pMt->pbBase[pMt->dOffset + 3] == 0x01)) {
537                                         /* System On */
538                                         if (sdTotalTicks == 0) {
539                                                 dSetup |= 0x04;
540                                         }
541                                 } else {
542                                         if (gPi->dSetupBar == 0) {
543                                                 if ((dSize == 22) &&
544                                                         (pMt->pbBase[pMt->dOffset] == 0x43) &&
545                                                         (pMt->pbBase[pMt->dOffset + 1] == 0x79) &&
546                                                         (pMt->pbBase[pMt->dOffset + 2] == 0x06) &&
547                                                         (pMt->pbBase[pMt->dOffset + 3] == 0x7C) &&
548                                                         (pMt->pbBase[pMt->dOffset + 4] == 0x02)) {
549                                                         /* Channel status */
550                                                         for (dCh = 0; dCh < 16; dCh++) {
551                                                                 pCh = &gPi->ChInfo[dCh];
552                                                                 dTemp = pMt->pbBase[pMt->dOffset + 5 + dCh];
553                                                                 pCh->dKeyCon = (dTemp >> 2) & 0x03;
554                                                                 pCh->dVibSync = (dTemp >> 1) & 0x01;
555                                                                 pCh->dLedSync = dTemp & 0x01;
556                                                         }
557                                                 }
558                                         }
559                                 }
560
561                                 pMt->dOffset += dSize;
562                                 break;
563
564                         case 0xF1:                      /* System Msg */
565                         case 0xF3:                      /* System Msg */
566                                 pMt->dOffset++;
567                                 break;
568
569                         case 0xF2:                      /* System Msg */
570                                 pMt->dOffset += 2;
571                                 break;
572
573                         case 0xFF:                                                                                      /* Meta          */
574                                 dCmd2 = (unsigned long)pMt->pbBase[pMt->dOffset++];     /* Meta Command  */
575                                 dSize = 0;                                                                              /* Size          */
576                                 do {
577                                         dTemp = (unsigned long)pMt->pbBase[pMt->dOffset++];
578                                         dSize = (dSize << 7) + (dTemp & 0x7f);
579                                 } while (dTemp >= 0x80);
580
581                                 switch (dCmd2) {
582                                 case 0x01:      /* Text */
583                                         if (gPi->pbText == NULL) {
584                                                 gPi->pbText = &pMt->pbBase[pMt->dOffset];
585                                                 gPi->dSizeText = dSize;
586                                         }
587                                         break;
588
589                                 case 0x02:      /* Copyright */
590                                         if (gPi->pbCopyright == NULL) {
591                                                 gPi->pbCopyright = &pMt->pbBase[pMt->dOffset];
592                                                 gPi->dSizeCopyright = dSize;
593                                         }
594                                         break;
595
596                                 case 0x06:      /* Title */
597                                         if (gPi->pbTitle == NULL) {
598                                                 gPi->pbTitle = &pMt->pbBase[pMt->dOffset];
599                                                 gPi->dSizeTitle = dSize;
600                                         }
601                                         break;
602
603                                 case 0x2f:              /* End */
604                                         gPi->dEndFlag &= ~(1L << sdTr);
605                                         break;
606
607                                 case 0x51:              /* Set Tempo */
608                                         switch (dSize) {
609                                         case 3:
610                                         case 4:
611                                                 dTime = ((unsigned long)pMt->pbBase[pMt->dOffset] << 16) +
612                                                                 ((unsigned long)pMt->pbBase[pMt->dOffset + 1] << 8) +
613                                                                 (unsigned long)pMt->pbBase[pMt->dOffset + 2];
614                                                 if ((sdTotalTicks == 0) && (dTime == 250000)) dSetup |= 0x02;
615                                                 if (sdTotalTicks == (unsigned long)gPi->dTimeResolution) dSetup |= 0x08;
616
617                                                 sdDelta = (unsigned long)(dTime / (gPi->dTimeResolution > 0 ? gPi->dTimeResolution : 1));
618                                                 break;
619
620                                         default:
621                                                 break;
622                                         }
623                                         break;
624
625                                 case 0x58:              /* Set TimeSignature */
626                                         if ((sdTotalTicks == 0) &&
627                                                 (pMt->pbBase[pMt->dOffset] == 1) &&
628                                                 (pMt->pbBase[pMt->dOffset + 1] == 2)) dSetup |= 0x01;
629                                         break;
630                                 default:
631                                         break;
632                                 }
633                                 pMt->dOffset += dSize;
634                                 break;
635                         default:
636                                 break;
637                         }
638                 }
639
640                 __AvMidUpdateTrackTime(sdTr);
641
642                 if (dSetup == 0x0F) {
643                         dSetup |= 0x10;
644                         sdCurrentTime = 0;
645                         gPi->dSetupBar = 1;
646                         gPi->dStart = gPi->TrackInfo[0].dOffset;
647                 }
648         }
649
650         if ((dConductorNote != 2) || (gPi->dSmfFormat == 0)) {
651                 gPi->sdTotalTicks = sdTotalTicks;
652                 gPi->sdDataEndTime = sdCurrentTime;
653         } else {
654                 gPi->sdTotalTicks = sdNonConductorTicks;
655                 gPi->sdDataEndTime = sdNonConductorTime;
656         }
657
658         if (gPi->dSetupBar == 0) {
659                 for (dCh = 0; dCh < 16; dCh++) {
660                         pCh = &gPi->ChInfo[dCh];
661                         pCh->dKeyCon = 0;
662                         pCh->dVibSync = 0;
663                         pCh->dLedSync = 0;
664                 }
665         }
666         if ((gPi->sdDataEndTime >> 10) <= MINIMUM_LENGTH)
667                 return -1;
668
669         return gPi->sdDataEndTime;
670 }
671
672 static long __AvCheckSizeOfMidFile(unsigned char *src_fp, unsigned long dFsize)
673 {
674         unsigned long   dTemp;
675         unsigned long   dSize;
676         unsigned long   dFormat;
677         unsigned long   dNumOfTracks;
678         unsigned long   i;
679         unsigned char *fp = src_fp;
680
681         while (dFsize >= 22) {
682                 dTemp = ((unsigned long)fp[0] << 24) + ((unsigned long)fp[1] << 16) + ((unsigned long)fp[2] << 8) + (unsigned long)fp[3];
683                 if (dTemp == 0x4D546864)
684                         break;          /* 'MThd' */
685                 fp++;
686                 dFsize--;
687         }
688
689         mm_file_retvm_if_fails(DEBUG, dFsize >= 22, -1);
690
691         fp += 4;
692         dFsize -= 4;
693
694         dTemp = ((unsigned long)fp[0] << 24) + ((unsigned long)fp[1] << 16) + ((unsigned long)fp[2] << 8) + (unsigned long)fp[3];
695         mm_file_retvm_if_fails(DEBUG, dTemp == 6, -1);
696
697         fp += 4;
698         dFsize -= 4;
699
700         gPi = g_new0(MIDINFO, 1);
701
702         /*--- Check format -------------------------------------------------*/
703         dFormat = ((unsigned long)fp[0] << 8) + (unsigned long)fp[1];
704         mm_file_retvm_if_fails(DEBUG, dFormat <= 1, -1);
705
706         /*--- Check number of tracks ---------------------------------------*/
707         dNumOfTracks = ((unsigned long)fp[2] << 8) + (unsigned long)fp[3];
708         mm_file_retvm_if_fails(DEBUG, dNumOfTracks > 0, -1);
709         mm_file_retvm_if_fails(DEBUG, dFormat != 0 || dNumOfTracks == 1, -1);
710
711         gPi->dNumOfTracks = (dNumOfTracks > MAX_SMF_TRACKS) ? MAX_SMF_TRACKS : dNumOfTracks;
712
713         /*--- Check Time unit --------------------------------------------*/
714         dTemp = ((unsigned long)fp[4] << 8) + (unsigned long)fp[5];
715         gPi->dTimeResolution = dTemp & 0x7fff;
716         if (((dTemp & 0x8000) != 0) || (gPi->dTimeResolution == 0)) {
717                 debug_error(DEBUG, "__AvCheckSizeOfMidFile Error/ Unknown TimeUnit\n");
718                 return -1;
719         }
720         fp += 6;
721         dFsize -= 6;
722
723         for (i = 0; i < dNumOfTracks; i++) {
724                 /*--- Check chunk name --------------------------------------------*/
725                 while (dFsize >= 8) {
726                         dTemp = ((unsigned long)fp[0] << 24) + ((unsigned long)fp[1] << 16) + ((unsigned long)fp[2] << 8) + (unsigned long)fp[3];
727                         if (dTemp == 0x4D54726B)
728                                 break;  /* 'MTrk' */
729                         fp++;
730                         dFsize--;
731                 }
732
733                 mm_file_retvm_if_fails(DEBUG, dFsize >= 8, -1);
734
735                 /*--- Check size ----------------------------------------------------*/
736                 dSize = ((unsigned long)fp[4] << 24) + ((unsigned long)fp[5] << 16) + ((unsigned long)fp[6] << 8) + (unsigned long)fp[7];
737
738                 if (dFsize < (dSize + 8)) {
739                         debug_error(DEBUG, "__AvCheckSizeOfMidFile Error/ Bad size [%ld] vs [%ld]\n", dFsize, dSize + 22);
740                         return -1;
741                 }
742                 gPi->TrackInfo[i].pbBase = &fp[8];
743                 gPi->TrackInfo[i].dSize = dSize;
744                 fp += (dSize + 8);
745                 dFsize -= (dSize + 8);
746         }
747         gPi->dSmfFormat = dFormat;
748
749         return __AvGetSizeOfFileInfo();
750 }
751
752 static void __AvGetMidiDuration(char *szFileName, MIDI_INFO_SIMPLE *info)
753 {
754         unsigned long xmfheaderSkip = 0;
755         MMFileIOHandle *hFile = NULL;
756         unsigned char *pbFile = NULL;
757         unsigned char *pIMYbuf = NULL;
758         long dFileSize;
759         int     sdCurrentTime = 0;
760         int readed = 0;
761         int codecType = AV_DEC_AUDIO_MIDI;
762         int is_xmf = 0;
763
764         if (!szFileName || !info)
765                 return;
766
767         /*open*/
768         if (mmfile_open(&hFile, szFileName, MMFILE_RDONLY) != MMFILE_UTIL_SUCCESS) {
769                 debug_error(DEBUG, "failed to open\n");
770                 return;
771         }
772
773         /*get file size*/
774         dFileSize = mmfile_get_size(hFile);
775         if (dFileSize <= 0) {
776                 debug_error(DEBUG, "failed to get file size.\n");
777                 goto _RELEASE_RESOURCE;
778         }
779
780         /*alloc read buffer*/
781         pbFile = g_malloc0(dFileSize + 1);
782
783         /*read data*/
784         if ((readed = mmfile_read(hFile, pbFile, dFileSize)) != dFileSize) {
785                 debug_error(DEBUG, "read error. size = %d\n", readed);
786                 goto _RELEASE_RESOURCE;
787         }
788
789         /*check format*/
790         if (!(memcmp(pbFile, MMFILE_XMF_100, 8)) ||
791                 !(memcmp(pbFile, MMFILE_XMF_101, 8)) ||
792                 !(memcmp(pbFile, MMFILE_MXMF_200, 8))) {
793
794                 is_xmf = 1;
795                 codecType = AV_DEC_AUDIO_XMF;
796         } else if (!(memcmp(pbFile, MMFILE_RMF, 4))) {
797                 is_xmf = 0;
798                 codecType = AV_DEC_AUDIO_RMF;
799         } else {
800                 is_xmf = 0;
801                 codecType = AV_DEC_AUDIO_MIDI;
802         }
803
804         /*set output param*/
805         if (codecType == AV_DEC_AUDIO_RMF) {
806                 info->duration = sdCurrentTime = 0;             /*not yet implemented.*/
807                 info->track_num = 1;                                    /*not yet implemented.*/
808                 info->is_xmf = is_xmf;
809         } else {
810                 /*get duration. XMF/MIDI*/
811                 if (codecType ==  AV_DEC_AUDIO_XMF) {
812                         if (!__AvParseSkipXmf2Mid(pbFile, dFileSize, &xmfheaderSkip))
813                                 goto _RELEASE_RESOURCE;
814
815                         sdCurrentTime = __AvCheckSizeOfMidFile(pbFile + xmfheaderSkip, dFileSize);
816                 } else {
817                         sdCurrentTime = __AvCheckSizeOfMidFile(pbFile, dFileSize);
818                 }
819
820                 if (sdCurrentTime < 0) {
821                         debug_error(DEBUG, "__AvGetMidiDuration: sdResult's error Code!(%d)\n", sdCurrentTime);
822                         goto _RELEASE_RESOURCE;
823                 }
824
825                 if (sdCurrentTime > 0)
826                         sdCurrentTime /= 1000;
827
828                 info->duration = sdCurrentTime;
829                 info->track_num = gPi->dNumOfTracks;
830                 info->is_xmf = is_xmf;
831
832                 info->title = g_strndup((const char *)gPi->pbTitle, gPi->dSizeTitle);
833                 info->copyright = g_strndup((const char *)gPi->pbCopyright, gPi->dSizeCopyright);
834                 info->comment = g_strndup((const char *)gPi->pbText, gPi->dSizeText);
835         }
836
837 _RELEASE_RESOURCE:
838         /*resource release*/
839         mmfile_free(gPi);
840         mmfile_close(hFile);
841         mmfile_free(pbFile);
842         mmfile_free(pIMYbuf);
843 }
844
845 /* mm plugin interface */
846 int mmfile_format_read_stream_mid(MMFileFormatContext *formatContext);
847 int mmfile_format_read_frame_mid(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame);
848 int mmfile_format_read_tag_mid(MMFileFormatContext *formatContext);
849 int mmfile_format_close_mid(MMFileFormatContext *formatContext);
850
851
852 int mmfile_format_open_mid(MMFileFormatContext *formatContext)
853 {
854         mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
855         mm_file_retvm_if_fails(DEBUG, formatContext->uriFileName, MMFILE_FORMAT_FAIL);
856         mm_file_retvm_if_fails(DEBUG, MMFileFormatIsValidMID(NULL, formatContext->uriFileName, 0), MMFILE_FORMAT_FAIL);
857
858         formatContext->ReadStream   = mmfile_format_read_stream_mid;
859         formatContext->ReadFrame    = mmfile_format_read_frame_mid;
860         formatContext->ReadTag      = mmfile_format_read_tag_mid;
861         formatContext->Close        = mmfile_format_close_mid;
862
863         formatContext->videoTotalTrackNum = 0;
864         formatContext->audioTotalTrackNum = 1;
865
866         formatContext->privateFormatData = NULL;
867
868         return MMFILE_FORMAT_SUCCESS;
869 }
870
871 int mmfile_format_read_stream_mid(MMFileFormatContext *formatContext)
872 {
873         MMFileFormatStream *audioStream = NULL;
874         MIDI_INFO_SIMPLE *info = NULL;
875
876         mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
877
878         /*get infomation*/
879         info = mmfile_format_get_midi_infomation(formatContext->uriFileName);
880
881         formatContext->duration = info->duration;
882         formatContext->videoStreamId = -1;
883         formatContext->videoTotalTrackNum = 0;
884         formatContext->audioTotalTrackNum = info->track_num;
885         formatContext->nbStreams = 1;
886
887         audioStream = g_new0(MMFileFormatStream, 1);
888
889         audioStream->streamType = MMFILE_AUDIO_STREAM;
890         audioStream->codecId = (info->is_xmf == 1) ? MM_AUDIO_CODEC_MXMF : MM_AUDIO_CODEC_MIDI;
891         audioStream->bitRate = 0;
892         audioStream->framePerSec = 0;
893         audioStream->width = 0;
894         audioStream->height = 0;
895         audioStream->nbChannel = 1;
896         audioStream->samplePerSec = 0;
897         formatContext->streams[MMFILE_AUDIO_STREAM] = audioStream;
898
899 #ifdef  __MMFILE_TEST_MODE__
900         mmfile_format_print_contents(formatContext);
901 #endif
902
903         mmfile_format_free_midi_infomation(info);
904         return MMFILE_FORMAT_SUCCESS;
905 }
906
907
908 int mmfile_format_read_tag_mid(MMFileFormatContext *formatContext)
909 {
910         MIDI_INFO_SIMPLE *info = NULL;
911         const char *locale = MMFileUtilGetLocale();
912
913         mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
914
915         /*get infomation*/
916         info = mmfile_format_get_midi_infomation(formatContext->uriFileName);
917
918         /**
919          * UTF8 converting.
920          */
921         if (info->title) {
922                 formatContext->title = mmfile_convert_to_utf8((const char *)info->title, -1, locale);
923                 if (formatContext->title == NULL) {
924                         debug_warning(DEBUG, "failed to UTF8 convert.\n");
925                         formatContext->title = g_strdup(info->title);
926                 }
927         }
928
929         if (info->copyright) {
930                 formatContext->copyright = mmfile_convert_to_utf8((const char *)info->copyright, -1, locale);
931                 if (formatContext->copyright == NULL) {
932                         debug_warning(DEBUG, "failed to UTF8 convert.\n");
933                         formatContext->copyright = g_strdup(info->copyright);
934                 }
935         }
936
937         if (info->comment) {
938                 formatContext->comment = mmfile_convert_to_utf8((const char *)info->comment, -1, locale);
939                 if (formatContext->comment == NULL) {
940                         debug_warning(DEBUG, "failed to UTF8 convert.\n");
941                         formatContext->comment = g_strdup(info->comment);
942                 }
943         }
944
945 #ifdef  __MMFILE_TEST_MODE__
946         mmfile_format_print_contents(formatContext);
947 #endif
948
949         mmfile_format_free_midi_infomation(info);
950         return MMFILE_FORMAT_SUCCESS;
951 }
952
953
954 int mmfile_format_read_frame_mid(MMFileFormatContext *formatContext, unsigned int timestamp, MMFileFormatFrame *frame)
955 {
956         debug_error(DEBUG, "error: mmfile_format_read_frame_midi, no handling\n");
957
958         return MMFILE_FORMAT_FAIL;
959 }
960
961
962 int mmfile_format_close_mid(MMFileFormatContext *formatContext)
963 {
964         mm_file_retvm_if_fails(DEBUG, formatContext, MMFILE_FORMAT_FAIL);
965         mmfile_free(formatContext->streams[MMFILE_AUDIO_STREAM]);
966
967         formatContext->ReadStream   = NULL;
968         formatContext->ReadFrame    = NULL;
969         formatContext->ReadTag      = NULL;
970         formatContext->Close        = NULL;
971
972         return MMFILE_FORMAT_SUCCESS;
973 }
974
975 MIDI_INFO_SIMPLE * mmfile_format_get_midi_infomation(char *szFileName)
976 {
977         MIDI_INFO_SIMPLE *info = g_new0(MIDI_INFO_SIMPLE, 1);
978
979         __AvGetMidiDuration(szFileName, info);
980
981         return info;
982 }
983
984 void mmfile_format_free_midi_infomation(MIDI_INFO_SIMPLE *info)
985 {
986         if (info) {
987                 mmfile_free(info->title);
988                 mmfile_free(info->copyright);
989                 mmfile_free(info->comment);
990                 mmfile_free(info);
991         }
992 }