1 /*---------------------------------------------------------------------------*
2   Project:  Revolution THP Converting tool
3   File:     THPConv.c
4 
5   Copyright (C)2002-2006 Nintendo  All Rights Reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: THPConv.c,v $
14   Revision 1.2  2006/12/21 07:07:22  aka
15   Removed resampling code.
16 
17   Revision 1.1  2006/02/08 02:55:34  aka
18   Imported from Dolphin Tree.
19 
20 
21     22    2003/12/24 4:20p Akagi
22     Revised frame rate check.
23 
24     21    2003/12/24 1:36p Akagi
25     Removed a function copyFile().
26     Changed calling from copyFile() to THPUtyCopyTHPFile().
27     Added frame rate check.
28 
29     20    2003/12/08 2:27p Akagi
30     Revised 2 error messages.
31 
32     19    2003/09/21 6:48p Akagi
33     Added several file checks.
34 
35     18    2003/09/18 10:07a Akagi
36     Added option check.
37 
38     17    2003/09/17 9:59p Akagi
39     Fixed some bugs.
40 
41     16    2003/07/03 2:58p Akagi
42     Fixed 2 trivial bugs.
43 
44     15    2003/07/03 11:09a Akagi
45     Renamed some functions.
46 
47     14    2003/07/02 4:20p Akagi
48     Renamed from THPConv_main.c to THPConv.c.
49 
50     13    2003/07/02 4:13p Akagi
51     Rewrote with DolphinSDK coding style.
52 
53     12    2003/07/02 1:02p Akagi
54     Modified appendAudioData().
55 
56     11    2003/07/01 2:55p Akagi
57     Modified to divide old THPConv.exe into 2 DLLs and 1 EXE by
58     Ohki-san@NTSC.
59 
60     10    2003/07/01 9:54a Akagi
61     Moved from securebuild/tools.
62 
63     9     2002/10/16 11:28a Akagi
64     JPEG & WAV file Name bug fixed. (by iRD  tsuji)
65 
66     8    2002/05/30 2:21p Akagi
67     Stopped supporting QuickTime MJPEG By Tsuji (IRD)
68 
69     7    2002/05/27 9:45a Akagi
70     Modified output error messages in English, by Tsuji (IRD)
71 
72     6    2002/05/08 2:31p Akagi
73     Modified [-trk] option By Tsuji (IRD)
74 
75     5    2002/05/01 3:09p Akagi
76     Added JPEG files sort program. By Tsuji (IRD)
77 
78     4    2002/03/28 11:15a Akagi
79     Modified by Tsuji (IRD)
80 
81     2    2002/01/22 10:10a Akagi
82     Added error message, when can't load "dsptools.dll" by Tsuji.
83 
84     1    2002/01/16 4:58p Akagi
85     Initial revision made by Tsuji-san (IRD).
86 
87   $NoKeywords: $
88 
89  *---------------------------------------------------------------------------*/
90 
91 #include <windows.h>
92 #include <CRTDBG.h>
93 #include <stdlib.h>
94 #include <stdio.h>
95 #include <sys/types.h>
96 #include <sys/stat.h>
97 #include <assert.h>
98 #include <string.h>
99 
100 #include <revolution/types.h>
101 #include <revolution/thpfile.h>
102 #include <win32/thpcommon.h>
103 #include <win32/thpcore.h>
104 #include <win32/thputilities.h>
105 #include <win32/thpaudio.h>
106 
107 //-----------------------------------------------------------------------------
108 // <The THP library functions being used>
109 //
110 // #include <win32/thputilities.h>
111 //
112 //    THPUtyConvertToUnixFmt()
113 //    THPUtyHeaderInit()
114 //    THPUtyCreateTHP()
115 //    THPUtyChangeAudioTrack()
116 //    THPUtyReadTHPFileHeader()
117 //    THPUtyCopyTHPFile()
118 //
119 // #include <win32/thpaudio.h>
120 //
121 //    THPAudioInit()
122 //    THPAudioCreateHandle()
123 //    THPAudioGetInfo()
124 //    THPAudioGetMaxFrameSamples()
125 //    THPAudioGetTotalSamples()
126 //    THPAudioQuit()
127 //    THPAudioFreeHandle()
128 //
129 //-----------------------------------------------------------------------------
130 
131 //-----------------------------------------------------------------------------
132 //      Define
133 //-----------------------------------------------------------------------------
134 #define TMP_FILENAME "__tmp_VD"
135 
136 //-----------------------------------------------------------------------------
137 //      Static Value
138 //-----------------------------------------------------------------------------
139 static char** jpegFilesPtr = NULL;                 // JPEG File name string array pointer
140 static u32    num_JPGfiles = 0;                    // Number of JPEG files
141 
142 static char** waveFilesPtr = NULL;                 // WAV File name string array pointer
143 static u32    num_WAVfiles = 0;                    // Number of WAV files
144 
145 static char*  inFile  = NULL;                      // Input filename
146 static char*  outFile = NULL;                      // Output filename
147 
148 static u32    pack_jpegs       = 0;                // Convert jpegs files to THP flag (-j)
149 static u32    change_snd_data  = 0;                // Change sound data flag (-c)
150 static u32    change_alltrack  = 0;                // Change all track data flag (-s)
151 static u32    change_onetrack  = 0;                // Change one track data flag (-trk)
152 static u8     change_framerate = 0;                // Change framerate (-r)
153 static u8     change_videotype = 0;                // Change videotype (-non/odd/even)
154 static u32    offset_mode      = 0;                // Offset flag (-o)
155 
156 static f32    frame_rate = 29.97F;                 // Frame rate
157 static u32    videotype  = THP_VIDEO_NON_INTERLACE;// Video Type
158 
159 static u8     trackNo = 0;                         // Track # (-trk)
160 
161 static u32    Convert_Verbose = 0;
162 
163 //-----------------------------------------------------------------------------
164 //      Function
165 //-----------------------------------------------------------------------------
166 static void Usage                   ( const char* progName );
167 static s32  verifyWriteOverInputData( const char* fileName );
168 static u32  getFileNameList         ( const char *sWildcardPattern, THPFileName* filename );
169 static int  compare                 ( const void *arg1, const void *arg2 );
170 static s32  checkArguments          ( u32 argument_count, char *argv[] );
171 static s32  convertJPEGtoTHP        ( void );
172 static s32  changeAudioTrack        ( THPFileHeader* fileHeader );
173 static s32  appendAudioData         ( THPFileHeader* fileHeader );
174 static s32  changeAudioData         ( void );
175 static void logPrintFunc            ( const char* format, va_list argptr );
176 
177 /*---------------------------------------------------------------------------*
178   Name:         Usage
179 
180   Description:  Command usage display
181 
182   Arguments:    progName    Pointer to the program name
183 
184   Returns:      None.
185  *---------------------------------------------------------------------------*/
Usage(const char * progName)186 static void Usage(const char* progName)
187 {
188     fprintf(stderr, "usage: %s [-OPTIONS]\n", progName);
189     fprintf(stderr, "\n");
190     fprintf(stderr, "  <<JPEGs -> THP>>\n");
191     fprintf(stderr, "  -j   [*.jpg]               # some JPEGs are packed into one file\n");
192     fprintf(stderr, "  -d   [file.thp]            # output THP file name\n");
193     fprintf(stderr, "\n");
194     fprintf(stderr, "  <SubOptions>\n");
195     fprintf(stderr, "  -s   [file.wav] [file.wav] [file.wav] ...\n");
196     fprintf(stderr, "                             # input WAV file names\n");
197     fprintf(stderr, "  -o                         # put offset data in THP\n");
198     fprintf(stderr, "  -r   [f32 number]          # set FrameRate (default is 29.97)\n");
199     fprintf(stderr, "\n");
200     fprintf(stderr, "  (THP Video Type)\n");
201     fprintf(stderr, "  -non                       # default Video Type NON  Interlace\n");
202     fprintf(stderr, "  -odd                       # set     Video Type ODD  Interlace\n");
203     fprintf(stderr, "  -even                      # set     Video Type EVEN Interlace\n");
204     fprintf(stderr, "\n");
205     fprintf(stderr, "  -v                         # verbose mode\n");
206     fprintf(stderr, "  -h                         # show this usage\n");
207     fprintf(stderr, "\n");
208     fprintf(stderr, "  ------------------------------------------------------------------\n");
209     fprintf(stderr, "\n");
210     fprintf(stderr, "  <<Change THP sound file Data>>\n");
211     fprintf(stderr, "  -c   [file.thp]            # input THP file name\n");
212     fprintf(stderr, "  -s   [file.wav] [file.wav] [file.wav] ...\n");
213     fprintf(stderr, "                             # input WAV file names\n");
214     fprintf(stderr, "  -trk [u8 track No.] [file.wav] \n");
215     fprintf(stderr, "                             # change Track No.[0... ] & input WAV file name\n");
216     fprintf(stderr, "\n");
217     fprintf(stderr, "  <SubOptions>\n");
218     fprintf(stderr, "  -d   [file.thp]            # output THP file name\n");
219     fprintf(stderr, "  -o                         # put offset data in THP\n");
220     fprintf(stderr, "  -r   [f32 number]          # set FrameRate (default is 29.97)\n");
221     fprintf(stderr, "\n");
222     fprintf(stderr, "  (THP Video Type)\n");
223     fprintf(stderr, "  -non                       # default Video Type NON  Interlace \n");
224     fprintf(stderr, "  -odd                       # set     Video Type ODD  Interlace \n");
225     fprintf(stderr, "  -even                      # set     Video Type EVEN Interlace \n");
226     fprintf(stderr, "\n");
227     fprintf(stderr, "  -v                         # verbose mode\n");
228     fprintf(stderr, "  -h                         # show this usage\n");
229     fprintf(stderr, "\n");
230 }
231 
232 /*---------------------------------------------------------------------------*
233   Name:         verifyWriteOverInputData
234 
235   Description:  Confirms overwriting of input file
236 
237   Arguments:    fileName    Pointer to the file name
238 
239   Returns:      TRUE        Overwrite permitted
240                 FALSE       Overwrite denied
241  *---------------------------------------------------------------------------*/
verifyWriteOverInputData(const char * fileName)242 static s32 verifyWriteOverInputData(const char* fileName)
243 {
244     char  answer    = 0;
245     u8    loop_flag = 1;
246 
247     while (loop_flag)
248     {
249         printf("\a>Overwrite the inputfile[%s] by OutputData ? [Y/N] ", fileName);
250         answer = toupper(getchar());
251 
252         if (answer == 'Y')
253         {
254             loop_flag = 0;
255         }
256         else if (answer == 'N')
257         {
258             printf("\a\n Please try using [-d] option.\n");
259             return FALSE;
260         }
261         else
262         {
263             // Loop //
264         }
265     }
266 
267     return TRUE;
268 }
269 
270 /*---------------------------------------------------------------------------*
271   Name:         getFileNameList
272 
273   Description:  Searches for file names matching sWildcardPattern and stores them all in filename.
274                 The filename buffer must be allocated in advance.
275 
276   Arguments:    sWildcardPattern  File name including the wildcard
277                 filename          Buffer storing the file names
278 
279   Returns:      Number of files
280  *---------------------------------------------------------------------------*/
getFileNameList(const char * sWildcardPattern,THPFileName * filename)281 static u32 getFileNameList(const char *sWildcardPattern, THPFileName* filename)
282 {
283     u32              f_count = 0;
284     WIN32_FIND_DATA  wfd;
285     HANDLE           hFind;
286     struct           stat;
287 
288     if ((hFind = FindFirstFile(sWildcardPattern, &wfd)) == INVALID_HANDLE_VALUE)
289     {
290         return f_count;
291     }
292 
293     do
294     {
295         if (filename != NULL)
296         {
297             strcpy(filename[f_count].name, wfd.cFileName);
298             strlwr(filename[f_count].name);
299             filename[f_count].fileSize = wfd.nFileSizeLow;
300         }
301         f_count++;
302 
303     } while (FindNextFile(hFind, &wfd));
304 
305     FindClose(hFind);
306 
307     if (filename != NULL)
308     {
309         u32   i;
310         char  drive[_MAX_DRIVE];
311         char  dir[_MAX_DIR];
312         char  pathCopy[_MAX_PATH];
313         char  path[_MAX_PATH];
314 
315         qsort(filename, f_count, sizeof(THPFileName), compare);
316 
317         _splitpath(sWildcardPattern, drive, dir, NULL, NULL);
318         _makepath(path, drive, dir, NULL, NULL);
319 
320         for (i = 0; i < f_count; i++)
321         {
322             strcpy(pathCopy, path);
323             strcat(pathCopy, filename[i].name);
324             strcpy(filename[i].name, pathCopy);
325         }
326     }
327 
328     return f_count++;
329 }
330 
331 /*---------------------------------------------------------------------------*
332   Name:         compare
333 
334   Description:  The comparison function specified in qsort()
335 
336   Arguments:    arg1, arg2  The elements to be compared
337 
338   Returns:      negative   arg1 is less than arg2
339                 0           arg1 = arg2
340                 positive   arg1 is greater than arg2
341  *---------------------------------------------------------------------------*/
compare(const void * arg1,const void * arg2)342 static int compare(const void *arg1, const void *arg2)
343 {
344     // Compares two strings until their ends
345     return strcmp(((THPFileName *)arg1)->name, ((THPFileName *)arg2)->name);
346 }
347 
348 /*---------------------------------------------------------------------------*
349   Name:         checkArguments
350 
351   Description:  Argument checker
352 
353   Arguments:    argument_count  Number of arguments
354                 argv            Array of argument strings
355 
356   Returns:      TRUE        Ended successfully
357                 FALSE       Ended in an error
358                 (when the argument is '-h', immediately use exit(0))
359  *---------------------------------------------------------------------------*/
360 /*---------------------------------------------------------------------------*
361   [Flags]
362 
363   <Required>
364 
365   -j option: Create THP files from serial JPEG file (group)
366     Flag specifying serial JPEG files   pack_jpegs           : 0    -> 1
367     Serial JPEG file's file name jpegFilesPtr         : NULL -> XXXX
368     Number of serial JPEG files         num_JPGfiles         :0    -> XX
369 
370   -c option: Replace audio data in existing THP file
371     Flag specifying the input THP file    change_snd_data      : 0    -> 1
372     Input THP file's file name  inFile               : NULL -> XXXX
373 
374   *** -j and -c are exclusive ***
375 
376   <Recommended>
377 
378   -d option
379     Output THP file name            outFile              : NULL -> XXXX
380 
381   *** Required when using -j/optional when using -c ***
382 
383   -s option
384     Flag specifying the input WAV file    change_alltrack      : 0    -> 1
385     Input WAV file's file name  waveFilesPtr         : NULL -> XXXX
386     Number of input WAV files          num_WAVfiles         :0    -> XX
387 
388   *** Not required when using -j ***
389 
390   -trk option
391     Audio track file exchange flag   change_onetrack      : 0    -> 1
392     Exchange WAV file name        waveFilesPtr         : NULL -> XXXX
393     Exchange track number           trackNo              :0    -> XX
394 
395   *** Invalid when using -j/when using -c, although -s and -trk are exclusive, one of the two must be included ***
396 
397   <Other>
398 
399   -r option
400     Flag specifying frame rate       change_framerate     : 0    -> 1
401     Frame rate                 frame_rate           : 29.97f -> XXXXXX
402 
403   -o option
404     Flag for creating offset table   offset_mode          : 0    -> 1
405 
406   -non/odd/even option
407     Flag specifying display start field   change_videotype     : 0    -> 1
408     Specified field                 videotype            : THP_VIDEO_NON_INTERLACE -> XXXXX
409 
410   *** Invalid when using -trk ***
411 
412   -v option
413     Verbose mode flag               Convert_Verbose      : 0    -> 1
414 
415  *---------------------------------------------------------------------------*/
416 
checkArguments(u32 argument_count,char * argv[])417 static s32 checkArguments(u32 argument_count, char *argv[])
418 {
419     u32  i;
420 
421     if (argument_count < 2)
422     {
423         Usage(argv[0]);
424         exit(0);
425     }
426 
427     // Check Options //
428     for (i = 1; i < argument_count; i++)
429     {
430         if (argv[i][0] == '-')
431         {
432             u8* option = argv[i];
433 
434             //
435             // -j : Specify input JPEG file(s)
436             //
437             if (strcmp(option, "-j") == 0)
438             {
439                 // -j (pack_jpegs = 1) and -c (change_snd_data) are mutually exclusive
440                 if (change_snd_data)
441                 {
442                     printf("\aERROR : Can't use both [-j] and [-c] at the same time.\n");
443                     return FALSE;
444                 }
445 
446                 // -j can only be specified once
447                 if (pack_jpegs)
448                 {
449                     printf("\aERROR : [-j] is specified twice.\n");
450                     return FALSE;
451                 }
452 
453                 // Check to see if there are subsequent file names
454                 i++;
455                 if (i >= argument_count)
456                 {
457                     printf("\aERROR : Must specify input filename after [-j].\n");
458                     return FALSE;
459                 }
460 
461                 jpegFilesPtr = &argv[i];
462 
463                 // Check the number of specified JPEG files
464                 while (i < argument_count && argv[i][0] != '-')
465                 {
466                     num_JPGfiles++;
467                     i++;
468                 }
469 
470                 if (num_JPGfiles == 0)
471                 {
472                     printf("\aERROR : There is no jpeg file after [-j].\n");
473                     return FALSE;
474                 }
475 
476                 i--;
477                 pack_jpegs = 1;
478             }
479 
480             //
481             // -c : Specify input THP file
482             //
483             else if (strcmp(option, "-c") == 0)
484             {
485                 // -j (pack_jpegs = 1) and -c (change_snd_data) are mutually exclusive
486                 if (pack_jpegs)
487                 {
488                     printf("\aERROR : Can't use both [-j] and [-c] at the same time.\n");
489                     return FALSE;
490                 }
491 
492                 // -c can only be specified once
493                 if (change_snd_data)
494                 {
495                     printf("\aERROR : [-c] is specified twice.\n");
496                     return FALSE;
497                 }
498 
499                 // Check to see if there are subsequent file names
500                 i++;
501                 if (i >= argument_count || argv[i][0] == '-')
502                 {
503                     printf("\aERROR : Must specify input filename after [-c].\n");
504                     return FALSE;
505                 }
506 
507                 // Acquire input THP file name
508                 inFile = argv[i];
509                 THPUtyConvertToUnixFmt(inFile);
510 
511                 change_snd_data = 1;
512             }
513 
514             //
515             // -d : Specify output THP file name
516             //
517             else if (strcmp(option, "-d") == 0)
518             {
519                 // -d can only be specified once
520                 if (outFile)
521                 {
522                     printf("\aERROR : [-d] is specified twice.\n");
523                     return FALSE;
524                 }
525 
526                 // Check to see if there are subsequent file names
527                 i++;
528                 if (i >= argument_count || argv[i][0] == '-')
529                 {
530                     printf("\aERROR : Must specify output THP filename after [-d].\n");
531                     return FALSE;
532                 }
533 
534                 // Get output THP file name
535                 outFile = argv[i];
536                 THPUtyConvertToUnixFmt(outFile);
537             }
538 
539             //
540             // -s : Specify input WAV file(s)
541             //
542             else if (strcmp(option, "-s") == 0)
543             {
544                 // -s (change_alltrack = 1) and -trk (change_onetrack) are mutually exclusive
545                 if (change_onetrack)
546                 {
547                     printf("\aERROR : Can't use both [-s] and [-trk] at the same time.\n");
548                     return FALSE;
549                 }
550 
551                 // -s can only be specified once
552                 if (change_alltrack)
553                 {
554                     printf("\aERROR : [-s] is specified twice.\n");
555                     return FALSE;
556                 }
557 
558                 // Check to see if there are subsequent file names
559                 i++;
560                 if (i >= argument_count)
561                 {
562                     printf("\aERROR : Must specify input filename after [-s].\n");
563                     return FALSE;
564                 }
565 
566                 waveFilesPtr = &argv[i];
567 
568                 // Check the number of specified WAV files
569                 while ((i < argument_count) && argv[i][0] != '-')
570                 {
571                     num_WAVfiles++;
572                     i++;
573                 }
574 
575                 if (num_WAVfiles == 0)
576                 {
577                     printf("\aERROR : There is no WAV file after [-s].\n");
578                     return FALSE;
579                 }
580 
581                 i--;
582                 change_alltrack = 1;
583             }
584 
585             //
586             // -trk : Specify track number and input WAV file
587             //
588             else if (strcmp(option, "-trk") == 0)
589             {
590                 // -s (change_alltrack = 1) and -trk (change_onetrack) are mutually exclusive
591                 if (change_alltrack)
592                 {
593                     printf("\aERROR : Can't use both [-s] and [-trk] at the same time.\n");
594                     return FALSE;
595                 }
596 
597                 // -trk can only be specified once
598                 if (change_onetrack)
599                 {
600                     printf("\aERROR : [-trk] is specified twice.\n");
601                     return FALSE;
602                 }
603 
604                 // Check to see if there are subsequent track numbers and file names
605                 i++;
606                 if (i + 1 >= argument_count)
607                 {
608                     printf("\aERROR : Must specify trackNo and input filename after [-trk].\n");
609                     return FALSE;
610                 }
611 
612                 // Get the track number
613                 if (argv[i][0] < '0' || argv[i][0] > '9')
614                 {
615                     printf("\aERROR : Invalid trackNo.\n");
616                     return FALSE;
617                 }
618 
619                 trackNo = atoi(argv[i]);
620 
621                 // Get the input WAV file name
622                 i++;
623                 if (i >= argument_count || argv[i][0] == '-')
624                 {
625                     printf("\aERROR : Must specify trackNo and input filename after [-trk].\n");
626                     return FALSE;
627                 }
628                 waveFilesPtr = &argv[i];
629                 THPUtyConvertToUnixFmt(waveFilesPtr[0]);
630 
631                 change_onetrack = 1;
632             }
633 
634             //
635             // -r : Specify frame rate
636             //
637             else if (strcmp(option, "-r") == 0)
638             {
639                 // Check to see if there are subsequent specified frame rates
640                 i++;
641                 if (i >= argument_count)
642                 {
643                     printf("\aERROR : Must specify output framerate after [-r].\n");
644                     return FALSE;
645                 }
646 
647                 // Get the frame rate
648                 frame_rate = (f32)atof(argv[i]);
649                 if (frame_rate > 59.94 ||  frame_rate < 1.0)
650                 {
651                     printf("\aERROR : Framarate should be between 1.0 to 59.94.\n");
652                     return FALSE;
653                 }
654 
655                 change_framerate = 1;
656             }
657 
658             //
659             // -o : Specify making an offset table
660             //
661             else if (strcmp(option, "-o") == 0)
662             {
663                 offset_mode = 1;
664             }
665 
666             //
667             // -non : Specify video type non-interlace
668             //
669             else if (strcmp(option, "-non") == 0)
670             {
671                 if (change_videotype)
672                 {
673                     printf("\aERROR : Already used -non/odd/even.\n");
674                     return FALSE;
675                 }
676 
677                 videotype = THP_VIDEO_NON_INTERLACE;
678                 change_videotype = 1;
679             }
680 
681             //
682             // -odd : Specify video type interlace beginning from odd field
683             //
684             else if (strcmp(option, "-odd") == 0)
685             {
686                 if (change_videotype)
687                 {
688                     printf("\aERROR : Already used -non/odd/even.\n");
689                     return FALSE;
690                 }
691 
692                 videotype = THP_VIDEO_ODD_INTERLACE;
693                 change_videotype = 1;
694             }
695 
696             //
697             // -even : Specify video type interlace beginning from even field
698             //
699             else if (strcmp(option, "-even") == 0)
700             {
701                 if (change_videotype)
702                 {
703                     printf("\aERROR : Already used -non/odd/even.\n");
704                     return FALSE;
705                 }
706 
707                 videotype = THP_VIDEO_EVEN_INTERLACE;
708                 change_videotype = 1;
709             }
710 
711             //
712             // -v : Specify setting verbose mode
713             //
714             else if (strcmp(option, "-v") == 0)
715             {
716                 Convert_Verbose = 1;
717             }
718 
719             //
720             // -on : old option
721             //
722             else if (strcmp(option, "-on") == 0)
723             {
724                 ;
725             }
726 
727             //
728             // -h : Specify displaying usage
729             //
730             else if (strcmp(option, "-h") == 0)
731             {
732                 Usage(argv[0]);
733                 exit(0);
734             }
735 
736             //
737             // etc.
738             //
739             else
740             {
741                 printf("\aERROR : Unknown option <%s>.\n", option);
742                 return FALSE;
743             }
744 
745         } // if (argv[i][0] == '-')
746 
747         // Invalid argument
748         else
749         {
750             printf("\aERROR : Invalid arguments!\n");
751             return FALSE;
752 
753         } // if (argv[i][0] == '-')
754 
755     } // for (i = 1; i < argument_count; i++)
756 
757 
758     // Check if either conversion (-j : pack_jpegs = 1) or audio replacement (-c : change_snd_data = 1) has been specified.
759     //
760     if (!pack_jpegs && !change_snd_data)
761     {
762         printf("\aERROR : Must input either [-j] or [-c].\n");
763         return FALSE;
764     }
765 
766     // When converting from JPEG to THP (-j : pack_jpegs = 1), check that the output THP files have been specified (-d : outFile != NULL).
767     //
768     if (pack_jpegs)
769     {
770         if (outFile == NULL)
771         {
772             printf("\aERROR : Must specify output THP filename [-d] [file.thp].\n");
773             return FALSE;
774         }
775     }
776 
777     // When replacing THP audio data (-c :change_snd_data = 1), check that input WAV file is specified (-s : change_alltrack = 1 or -trk : change_one_track = 1).
778     //
779     if (change_snd_data)
780     {
781         if (!change_alltrack && !change_onetrack)
782         {
783             printf("\aERROR : Must input [-s] [file.wav] or [-trk] [track No.] [file.wav].\n");
784             return FALSE;
785         }
786     }
787 
788     return TRUE;
789 }
790 
791 /*---------------------------------------------------------------------------*
792   Name:         convertJPEGtoTHP
793 
794   Description:  Converts serial JPEG files to THP data
795 
796   Arguments:    None.
797 
798   Returns:      TRUE        Ended successfully
799                 FALSE       Ended in an error
800  *---------------------------------------------------------------------------*/
convertJPEGtoTHP(void)801 static s32 convertJPEGtoTHP(void)
802 {
803     s32               rtn;
804     s32               error = TRUE;
805     u32               cnt;
806     FILE*             thpFp = NULL;
807     THPFileName*      jpegFileList = NULL;
808     THPAudioHandle**  audioHandle = NULL;
809     THPFileHeader     fileHeader;
810 
811     //
812     // Create a JPEG file list
813     //
814     if (num_JPGfiles == 1)
815     {
816         // When a single JPEG file or wildcard is specified
817 
818         THPUtyConvertToUnixFmt(jpegFilesPtr[0]);
819 
820         // Confirm the number of JPEG files
821         num_JPGfiles = getFileNameList(jpegFilesPtr[0], NULL);
822         if (num_JPGfiles == 0)
823         {
824             printf("\aERROR : There is no jpeg files. Input right argument.\n");
825             error = FALSE;
826             goto ERROR_END;
827         }
828 
829         jpegFileList = (THPFileName*)malloc(sizeof(THPFileName) * num_JPGfiles);
830         if (jpegFileList == NULL)
831         {
832             printf("\aERROR : Can't alloc memory.\n");
833             error = FALSE;
834             goto ERROR_END;
835         }
836 
837         // Save the JPEG file name
838         getFileNameList(jpegFilesPtr[0], jpegFileList);
839     }
840 
841     else
842     {
843         // When multiple JPEG files are specified
844 
845         jpegFileList = (THPFileName*)malloc(sizeof(THPFileName) * num_JPGfiles);
846         if (jpegFileList == NULL)
847         {
848             printf("\aERROR : Can't alloc memory.\n");
849             error = FALSE;
850             goto ERROR_END;
851         }
852 
853         for (cnt = 0; cnt < num_JPGfiles; cnt++)
854         {
855             struct stat  statBuf;
856             char         ext[_MAX_EXT];
857 
858             // Save the JPEG file name
859             strcpy(jpegFileList[cnt].name, jpegFilesPtr[cnt]);
860             THPUtyConvertToUnixFmt(jpegFileList[cnt].name);
861 
862             // Confirm the extension
863             _splitpath(jpegFileList[cnt].name, NULL, NULL, NULL, ext);
864             if ((stricmp(ext, ".jpg") != 0) && (stricmp(ext, ".jpeg") != 0))
865             {
866                 printf("\aERROR : Please input filename is [***.jpg] or [***.jpeg].\n");
867                 error = FALSE;
868                 goto ERROR_END;
869             }
870 
871             // Get the JPEG file size
872             rtn = stat(jpegFileList[cnt].name, &statBuf);
873             if (rtn != 0)
874             {
875                 printf("\aERROR : Can't get JPEG file status!\n");
876                 error = FALSE;
877                 goto ERROR_END;
878             }
879 
880             jpegFileList[cnt].fileSize = statBuf.st_size;
881         }
882     }
883 
884     if (Convert_Verbose)
885     {
886         printf("Total Frames = %ld\n", num_JPGfiles);
887         printf("Frame Rate   = %f\n",  frame_rate);
888     }
889 
890     // Set THPHeader
891     THPUtyHeaderInit(&fileHeader.header);
892     fileHeader.header.frameRate           = frame_rate;
893     fileHeader.header.numFrames           = num_JPGfiles;
894     fileHeader.header.compInfoDataOffsets = sizeof(THPHeader);
895     fileHeader.header.offsetDataOffsets   = offset_mode;
896 
897     // Set THPFrameCompInfo
898     fileHeader.frameCompInfo.frameComp[0] = THP_VIDEO_COMP;
899     fileHeader.frameCompInfo.numComponents = 1;
900     for (cnt = 1; cnt < THP_COMP_MAX; cnt++)
901     {
902         fileHeader.frameCompInfo.frameComp[cnt] = THP_NOCOMP_COMP;
903     }
904 
905     // Set THPVideoInfo
906     fileHeader.videoInfo.videoType = videotype;
907 
908     // Audio data encoding settings
909     if (change_alltrack)
910     {
911         if (Convert_Verbose)
912         {
913             printf("START: Audio Initializing.\n");
914         }
915 
916         if (THPAudioInit() == FALSE)
917         {
918             printf("\aERROR : Fail to execute THPAudioInit().\n");
919             error = FALSE;
920             goto ERROR_END;
921         }
922 
923         audioHandle = (THPAudioHandle**)malloc(sizeof(THPAudioHandle*) * num_WAVfiles);
924         if (audioHandle == NULL)
925         {
926             printf("\aERROR : Can't alloc memory.\n");
927             error = FALSE;
928             goto ERROR_END;
929         }
930 
931         // Create the WAV file list
932         for (cnt = 0; cnt < num_WAVfiles; cnt++)
933         {
934             THPUtyConvertToUnixFmt(waveFilesPtr[cnt]);
935 
936             audioHandle[cnt] = THPAudioCreateHandle(waveFilesPtr[cnt], frame_rate);
937             if (audioHandle[cnt] == NULL)
938             {
939                 printf("\aERROR : Fail to execute THPAudioCreateHandle().\n");
940                 error = FALSE;
941                 goto ERROR_END;
942             }
943         }
944 
945         // Main Sound
946         rtn = THPAudioGetInfo(audioHandle[0], &fileHeader.audioInfo);
947         if (rtn == FALSE)
948         {
949             printf("\aERROR : Fail to execute THPAudioGetInfo().\n");
950             error = FALSE;
951             goto ERROR_END;
952         }
953 
954         if (Convert_Verbose)
955         {
956             printf("    [AudioData]:(%2ld Tracks)\n", num_WAVfiles);
957             printf("     >> Channels  = %ld\n", fileHeader.audioInfo.sndChannels);
958             printf("     >> Frequency = %ld\n", fileHeader.audioInfo.sndFrequency);
959             printf("    <+> Track%02d <= [%s]\n", 0, waveFilesPtr[0]);
960         }
961 
962         // Sub Sound
963         for (cnt = 1; cnt < num_WAVfiles; cnt++)
964         {
965             THPAudioInfo  subAudioInfo;
966 
967             rtn = THPAudioGetInfo(audioHandle[cnt], &subAudioInfo);
968             if (rtn == FALSE)
969             {
970                 printf("\aERROR : Fail to execute THPAudioGetInfo().\n");
971                 error = FALSE;
972                 goto ERROR_END;
973             }
974 
975             // Check the number of channels in a WAV file
976             if (audioHandle[0]->audioInfo.channel != subAudioInfo.sndChannels)
977             {
978                 printf("\aERROR : Channels of [%s] is %d (!= %d).\n",
979                        waveFilesPtr[cnt],
980                        subAudioInfo.sndChannels,
981                        audioHandle[0]->audioInfo.channel);
982                 error = FALSE;
983                 goto ERROR_END;
984             }
985 
986             // Check the playback frequency in a WAV file
987             if (audioHandle[0]->audioInfo.frequency != subAudioInfo.sndFrequency)
988             {
989                 printf("\aERROR : Frequency of [%s] is %d (!= %d).\n",
990                        waveFilesPtr[cnt],
991                        subAudioInfo.sndFrequency,
992                        audioHandle[0]->audioInfo.frequency);
993                 error = FALSE;
994                 goto ERROR_END;
995             }
996 
997             if (Convert_Verbose)
998             {
999                 printf("    <+> Track%02d <= [%s]\n", cnt, waveFilesPtr[cnt]);
1000             }
1001         }
1002 
1003         if (Convert_Verbose)
1004         {
1005             printf("END  : Audio Initializing.\n");
1006         }
1007 
1008         // Update THPHeader
1009         fileHeader.header.audioMaxSamples
1010             = THPAudioGetMaxFrameSamples(audioHandle[0], num_JPGfiles);
1011 
1012         // Update THPAudioInfo
1013         fileHeader.audioInfo.sndNumTracks  = num_WAVfiles;
1014         fileHeader.audioInfo.sndNumSamples = THPAudioGetTotalSamples(audioHandle[0],
1015                                                                      num_JPGfiles);
1016 
1017         // Update THPFrameCompInfo
1018         fileHeader.frameCompInfo.frameComp[1] = THP_AUDIO_COMP;
1019         fileHeader.frameCompInfo.numComponents++;
1020     }
1021 
1022     // Open Output File
1023     thpFp = fopen(outFile, "wb");
1024     if (thpFp == NULL)
1025     {
1026         THPPrintError("\aERROR : Can't output [%s].\n", outFile);
1027         THPPrintError("          Please input valid directory & file name.\n");
1028         error = FALSE;
1029         goto ERROR_END;
1030     }
1031 
1032     // Convert serial JPEGs to THP
1033     rtn = THPUtyCreateTHP(thpFp, THP_CREATETHP_FILEFLAG_JPEGS,
1034                                  (void*)jpegFileList,
1035                                  &fileHeader,
1036                                  audioHandle);
1037     if (rtn != THP_ERROR_NOERROR)
1038     {
1039         printf("\aERROR : Fail to execute THPUtyCreateTHP().\n");
1040         error = FALSE;
1041         goto ERROR_END;
1042     }
1043 
1044 ERROR_END:
1045 
1046     if (audioHandle)
1047     {
1048         THPAudioQuit();
1049         for (cnt = 0; cnt < num_WAVfiles; cnt++)
1050         {
1051             if (audioHandle[cnt] != NULL)
1052             {
1053                 THPAudioFreeHandle(audioHandle[cnt]);
1054             }
1055         }
1056         free(audioHandle);
1057     }
1058 
1059     if (jpegFileList != NULL)
1060     {
1061         free(jpegFileList);
1062     }
1063 
1064     if (thpFp != NULL)
1065     {
1066         fclose(thpFp);
1067     }
1068 
1069     return error;
1070 }
1071 
1072 /*---------------------------------------------------------------------------*
1073   Name:         changeAudioTrack
1074 
1075   Description:  Replaces the existing audio tracks within THP file
1076 
1077   Arguments:    fileHeader  Pointer to the THP file header
1078 
1079   Returns:      TRUE        Ended successfully
1080                 FALSE       Ended in an error
1081  *---------------------------------------------------------------------------*/
changeAudioTrack(THPFileHeader * fileHeader)1082 static s32 changeAudioTrack(THPFileHeader* fileHeader)
1083 {
1084     s32              rtn;
1085     s32              error = TRUE;
1086     u32              cnt;
1087     u32              adjustFrequency;
1088     char             tmpFilename[_MAX_PATH];
1089     char*            fileName = NULL;
1090     FILE*            outTHPFp = NULL;
1091     FILE*            inTHPFp = NULL;
1092     THPAudioHandle** audioHandle = NULL;
1093     THPAudioInfo     audioInfo;
1094 
1095     // Check whether the THP file has an audio track
1096     for (cnt = 0; cnt < fileHeader->frameCompInfo.numComponents; cnt++)
1097     {
1098         if (fileHeader->frameCompInfo.frameComp[cnt] == THP_AUDIO_COMP)
1099         {
1100             break;
1101         }
1102     }
1103 
1104     if (cnt >= fileHeader->frameCompInfo.numComponents)
1105     {
1106         printf("\aERROR : [%s] doesn't have a Sound Data!\n", inFile);
1107         error = FALSE;
1108         goto ERROR_END;
1109     }
1110 
1111     // Check the THP file's number of channels and playback frequency
1112     if (fileHeader->audioInfo.sndChannels == 0 || fileHeader->audioInfo.sndFrequency == 0)
1113     {
1114         printf("\aERROR : [%s] doesn't have a Sound Data!\n", inFile);
1115         error = FALSE;
1116         goto ERROR_END;
1117     }
1118 
1119     // Check the number of THP file tracks
1120     if (trackNo >= fileHeader->audioInfo.sndNumTracks)
1121     {
1122         printf("\aERROR : Must input [u8 track No.] < %d.\n",
1123                fileHeader->audioInfo.sndNumTracks);
1124         error = FALSE;
1125         goto ERROR_END;
1126     }
1127 
1128     if (Convert_Verbose)
1129     {
1130         printf("START: Audio Initializing.\n");
1131     }
1132 
1133     // Set THPAudioHandle
1134     audioHandle = (THPAudioHandle**)malloc(sizeof(THPAudioHandle*)
1135                                            * fileHeader->audioInfo.sndNumTracks);
1136     if (audioHandle == NULL)
1137     {
1138         printf("\aERROR : Can't alloc memory.\n");
1139         error = FALSE;
1140         goto ERROR_END;
1141     }
1142 
1143     for (cnt = 0; cnt < fileHeader->audioInfo.sndNumTracks; cnt++)
1144     {
1145         audioHandle[cnt] = NULL;
1146     }
1147 
1148     THPUtyConvertToUnixFmt(waveFilesPtr[0]);
1149 
1150     audioHandle[trackNo] = THPAudioCreateHandle(waveFilesPtr[0],
1151                                                 fileHeader->header.frameRate);
1152     if (audioHandle[trackNo] == NULL)
1153     {
1154         printf("\aERROR : Fail to execute THPAudioCreateHandle().\n");
1155         error = FALSE;
1156         goto ERROR_END;
1157     }
1158 
1159     // Get additional audio data information
1160     rtn = THPAudioGetInfo(audioHandle[trackNo], &audioInfo);
1161     if (rtn == FALSE)
1162     {
1163         printf("\aERROR : Fail to execute THPAudioGetInfo().\n");
1164         error = FALSE;
1165         goto ERROR_END;
1166     }
1167 
1168     // Check the number of channels
1169     if (fileHeader->audioInfo.sndChannels != audioInfo.sndChannels )
1170     {
1171         printf("\aERROR : Channels of [%s] is %d (!= %d).\n",
1172                waveFilesPtr[0],
1173                audioInfo.sndChannels,
1174                fileHeader->audioInfo.sndChannels);
1175         error = FALSE;
1176         goto ERROR_END;
1177     }
1178 
1179     // Check the playback frequency
1180     if (fileHeader->audioInfo.sndFrequency != audioInfo.sndFrequency)
1181     {
1182         printf("\aERROR : Frequency of [%s] is %d (!= %d).\n",
1183                waveFilesPtr[0],
1184                audioInfo.sndFrequency,
1185                fileHeader->audioInfo.sndFrequency);
1186         error = FALSE;
1187         goto ERROR_END;
1188     }
1189 
1190     if (Convert_Verbose)
1191     {
1192         printf("    [AudioData]:(%2ld Tracks)\n", fileHeader->audioInfo.sndNumTracks);
1193         printf("     >> Channels  = %ld\n", fileHeader->audioInfo.sndChannels);
1194         printf("     >> Frequency = %ld\n", fileHeader->audioInfo.sndFrequency);
1195         printf("    <+> Track%02d <= [%s]\n", trackNo, waveFilesPtr[0]);
1196 
1197         printf("END  : Audio Initializing.\n");
1198     }
1199 
1200     // Open the input THP file
1201     inTHPFp = fopen(inFile, "rb");
1202     if (inTHPFp == NULL)
1203     {
1204         printf("\aERROR : Can't open [%s].\n", inFile);
1205         error = FALSE;
1206         goto ERROR_END;
1207     }
1208 
1209     // Open the output THP file
1210     if (outFile != NULL)
1211     {
1212         fileName = outFile;
1213     }
1214     else
1215     {
1216         char drive[_MAX_DRIVE];
1217         char dir[_MAX_DIR];
1218         _splitpath(inFile, drive, dir, NULL, NULL);
1219         _makepath(tmpFilename, drive, dir, TMP_FILENAME, NULL);
1220         fileName = tmpFilename;
1221     }
1222 
1223     outTHPFp = fopen(fileName, "w+b");
1224     if (outTHPFp == NULL)
1225     {
1226         printf("\aERROR : Can't open [%s].\n", fileName);
1227         error = FALSE;
1228         goto ERROR_END;
1229     }
1230 
1231     // Copy the input THP file to the output THP file
1232     rtn = THPUtyCopyTHPFile(inTHPFp, fileHeader, outTHPFp);
1233     if (rtn != THP_ERROR_NOERROR)
1234     {
1235         printf("\aERROR : Fail to execute THPUtyCopyTHPFile().\n");
1236         error = FALSE;
1237         goto ERROR_END;
1238     }
1239 
1240     rtn = fseek(outTHPFp, 0, SEEK_SET);
1241     if (rtn != 0)
1242     {
1243         THPPrintError("\aERROR : Can't rewind output THP file.\n");
1244         error = FALSE;
1245         goto ERROR_END;
1246     }
1247 
1248     // Exchange the audio track
1249     rtn = THPUtyChangeAudioTrack(outTHPFp, fileHeader, audioHandle);
1250     if (rtn != THP_ERROR_NOERROR)
1251     {
1252         printf("\aERROR : Fail to execute THPUtyChangeAudioTrack().\n");
1253         error = FALSE;
1254         goto ERROR_END;
1255     }
1256 
1257 ERROR_END:
1258 
1259     if (audioHandle)
1260     {
1261         for (cnt = 0; cnt < fileHeader->audioInfo.sndNumTracks; cnt++)
1262         {
1263             if (audioHandle[cnt] != NULL)
1264             {
1265                 THPAudioFreeHandle(audioHandle[cnt]);
1266             }
1267         }
1268         free(audioHandle);
1269     }
1270 
1271     if (inTHPFp != NULL)
1272     {
1273         fclose(inTHPFp);
1274     }
1275 
1276     if (outTHPFp != NULL)
1277     {
1278         fclose(outTHPFp);
1279     }
1280 
1281     // Temporarily rename the file during an overwrite
1282     if (outFile == NULL)
1283     {
1284         if (error == TRUE)
1285         {
1286             if (remove(inFile) == -1)
1287             {
1288                 printf("\aERROR : Can't remove old THP file[%s].\n", inFile);
1289             }
1290 
1291             if (rename(fileName, inFile))
1292             {
1293                 printf("\aERROR : Can't rename THP file[%s -> %s].\n", fileName, inFile);
1294             }
1295         }
1296         else
1297         {
1298             if (fileName)
1299             {
1300                 if (remove(fileName) == -1)
1301                 {
1302                     printf("\aERROR : Can't remove temporary THP file[%s].\n", fileName);
1303                 }
1304             }
1305         }
1306     }
1307 
1308     return error;
1309 }
1310 
1311 /*---------------------------------------------------------------------------*
1312   Name:         appendAudioData
1313 
1314   Description:  Adds audio data when none exists.
1315                 If it does exist, replace it.
1316                 (with the -s option)
1317 
1318   Arguments:    fileHeader  Pointer to the file header
1319 
1320   Returns:      TRUE        Ended successfully
1321                 FALSE       Ended in an error
1322  *---------------------------------------------------------------------------*/
appendAudioData(THPFileHeader * fileHeader)1323 static s32 appendAudioData(THPFileHeader* fileHeader)
1324 {
1325     s32              rtn;
1326     s32              error = TRUE;
1327     u32              cnt;
1328     char             tmpFilename[_MAX_PATH];
1329     char*            fileName = NULL;
1330     FILE*            outTHPFp = NULL;
1331     FILE*            inTHPFp = NULL;
1332     THPAudioHandle** audioHandle = NULL;
1333 
1334     // Open the input THP file
1335     inTHPFp = fopen(inFile, "rb");
1336     if (inTHPFp == NULL)
1337     {
1338         printf("\aERROR : Can't open [%s].\n", inFile);
1339         error = FALSE;
1340         goto ERROR_END;
1341     }
1342 
1343     // Open the output THP file
1344     if (outFile != NULL)
1345     {
1346         fileName = outFile;
1347     }
1348     else
1349     {
1350         char drive[_MAX_DRIVE];
1351         char dir[_MAX_DIR];
1352         _splitpath(inFile, drive, dir, NULL, NULL);
1353         _makepath(tmpFilename, drive, dir, TMP_FILENAME, NULL);
1354         fileName = tmpFilename;
1355     }
1356 
1357     outTHPFp = fopen(fileName, "wb");
1358     if (outTHPFp == NULL)
1359     {
1360         printf("\aERROR : Can't open [%s].\n", fileName);
1361         error = FALSE;
1362         goto ERROR_END;
1363     }
1364 
1365     if (Convert_Verbose)
1366     {
1367         printf("START: Audio Initializing.\n");
1368     }
1369 
1370     // Update THPAudioInfo (number of tracks: sndNumTracks)
1371     fileHeader->audioInfo.sndNumTracks = num_WAVfiles;
1372 
1373     audioHandle = (THPAudioHandle**)malloc(sizeof(THPAudioHandle*) * num_WAVfiles);
1374     if (audioHandle == NULL)
1375     {
1376         printf("\aERROR : Can't alloc memory.\n");
1377         error = FALSE;
1378         goto ERROR_END;
1379     }
1380 
1381     // Create the WAV file list
1382     for (cnt = 0; cnt < num_WAVfiles; cnt++)
1383     {
1384         THPUtyConvertToUnixFmt(waveFilesPtr[cnt]);
1385 
1386         audioHandle[cnt] = THPAudioCreateHandle(waveFilesPtr[cnt],
1387                                                 fileHeader->header.frameRate);
1388         if (audioHandle[cnt] == NULL)
1389         {
1390             printf("\aERROR : Fail to execute THPAudioCreateHandle().\n");
1391             error = FALSE;
1392             goto ERROR_END;
1393         }
1394     }
1395 
1396     // Main Sound
1397     rtn = THPAudioGetInfo(audioHandle[0], &fileHeader->audioInfo);
1398     if (rtn == FALSE)
1399     {
1400         printf("\aERROR : Fail to execute THPAudioGetInfo().\n");
1401         error = FALSE;
1402         goto ERROR_END;
1403     }
1404 
1405     if (Convert_Verbose)
1406     {
1407         printf("    [AudioData]:(%2ld Tracks)\n", num_WAVfiles);
1408         printf("     >> Channels  = %ld\n", fileHeader->audioInfo.sndChannels);
1409         printf("     >> Frequency = %ld\n", fileHeader->audioInfo.sndFrequency);
1410         printf("    <+> Track%02d <= [%s]\n", 0, waveFilesPtr[0]);
1411     }
1412 
1413     // Sub Sound
1414     for (cnt = 1; cnt < num_WAVfiles; cnt++)
1415     {
1416         THPAudioInfo subAudioInfo;
1417 
1418         rtn = THPAudioGetInfo(audioHandle[cnt], &subAudioInfo);
1419         if (rtn == FALSE)
1420         {
1421             printf("\aERROR : Fail to execute THPAudioGetInfo().\n");
1422             error = FALSE;
1423             goto ERROR_END;
1424         }
1425 
1426         // Check the number of channels in a WAV file
1427         if (audioHandle[0]->audioInfo.channel != subAudioInfo.sndChannels)
1428         {
1429             printf("\aERROR : Channels of [%s] is %d (!= %d).\n",
1430                    waveFilesPtr[cnt],
1431                    subAudioInfo.sndChannels,
1432                    audioHandle[0]->audioInfo.channel);
1433             error = FALSE;
1434             goto ERROR_END;
1435         }
1436 
1437         // Check the playback frequency in a WAV file
1438         if (audioHandle[0]->audioInfo.frequency != subAudioInfo.sndFrequency)
1439         {
1440             printf("\aERROR : Frequency of [%s] is %d (!= %d).\n",
1441                    waveFilesPtr[cnt],
1442                    subAudioInfo.sndFrequency,
1443                    audioHandle[0]->audioInfo.frequency);
1444             error = FALSE;
1445             goto ERROR_END;
1446         }
1447 
1448         if (Convert_Verbose)
1449         {
1450             printf("    <+> Track%02d <= [%s]\n", cnt, waveFilesPtr[cnt]);
1451         }
1452     }
1453 
1454     if (Convert_Verbose)
1455     {
1456         printf("END  : Audio Initializing.\n");
1457     }
1458 
1459     // Update THPHeader
1460     fileHeader->header.audioMaxSamples
1461         = THPAudioGetMaxFrameSamples(audioHandle[0], fileHeader->header.numFrames);
1462 
1463     // Update THPAudioInfo
1464     fileHeader->audioInfo.sndNumTracks = num_WAVfiles;
1465     fileHeader->audioInfo.sndNumSamples
1466         = THPAudioGetTotalSamples(audioHandle[0], fileHeader->header.numFrames);
1467 
1468     // Update THPFrameCompInfo
1469     if (fileHeader->frameCompInfo.frameComp[1] == THP_NOCOMP_COMP)
1470     {
1471         fileHeader->frameCompInfo.numComponents++;
1472         fileHeader->frameCompInfo.frameComp[1] = THP_AUDIO_COMP;
1473     }
1474 
1475     // Add/exchange audio data in THP data
1476     rtn = THPUtyCreateTHP(outTHPFp, THP_CREATETHP_FILEFLAG_THP,
1477                                     (void*)inTHPFp,
1478                                     fileHeader,
1479                                     audioHandle);
1480     if (rtn != THP_ERROR_NOERROR)
1481     {
1482         printf("\aERROR : Fail to execute THPUtyCreateTHP().\n");
1483         error = FALSE;
1484         goto ERROR_END;
1485     }
1486 
1487 ERROR_END:
1488 
1489     if (audioHandle)
1490     {
1491         for (cnt = 0; cnt < num_WAVfiles; cnt++)
1492         {
1493             if (audioHandle[cnt] != NULL)
1494             {
1495                 THPAudioFreeHandle(audioHandle[cnt]);
1496             }
1497         }
1498         free(audioHandle);
1499     }
1500 
1501     if (inTHPFp != NULL)
1502     {
1503         fclose(inTHPFp);
1504     }
1505 
1506     if (outTHPFp != NULL)
1507     {
1508         fclose(outTHPFp);
1509     }
1510 
1511     // Temporarily rename the file during an overwrite
1512     if (outFile == NULL)
1513     {
1514         if (error == TRUE)
1515         {
1516             if (remove(inFile) == -1)
1517             {
1518                 printf("\aERROR : Can't remove old THP file[%s].\n", inFile);
1519             }
1520 
1521             if (rename(fileName, inFile))
1522             {
1523                 printf("\aERROR : Can't rename THP file[%s -> %s].\n", fileName, inFile);
1524             }
1525         }
1526         else
1527         {
1528             if (fileName)
1529             {
1530                 if (remove(fileName) == -1)
1531                 {
1532                     printf("\aERROR : Can't remove temporary THP file[%s].\n", fileName);
1533                 }
1534             }
1535         }
1536     }
1537 
1538     return error;
1539 }
1540 
1541 /*---------------------------------------------------------------------------*
1542   Name:         changeAudioData
1543 
1544   Description:  Adds or replaces audio data
1545 
1546   Arguments:    None.
1547 
1548   Returns:      TRUE        Ended successfully
1549                 FALSE       Ended in an error
1550  *---------------------------------------------------------------------------*/
changeAudioData(void)1551 static s32 changeAudioData(void)
1552 {
1553     THPFileHeader fileHeader;
1554     FILE*         inTHPFp = NULL;
1555     s32           rtn;
1556     s32           error = TRUE;
1557 
1558     if (THPAudioInit() == FALSE)
1559     {
1560         printf("\aERROR : Fail to execute THPAudioInit().\n");
1561         error = FALSE;
1562         goto ERROR_END;
1563     }
1564 
1565     // Open the input THP file
1566     inTHPFp = fopen(inFile, "rb");
1567     if (inTHPFp == NULL)
1568     {
1569         printf("\aERROR : Can't open [%s].\n", inFile);
1570         error = FALSE;
1571         goto ERROR_END;
1572     }
1573 
1574     // Read the input THP file's THPFileHeader
1575     rtn = THPUtyReadTHPFileHeader(inTHPFp, &fileHeader);
1576     if (rtn != THP_ERROR_NOERROR)
1577     {
1578         printf("\aERROR : Can't read THPHeader of [%s].\n", inFile);
1579         fclose(inTHPFp);
1580         error = FALSE;
1581         goto ERROR_END;
1582     }
1583 
1584     fclose(inTHPFp);
1585 
1586     // Add or replace audio data
1587     if (change_onetrack)
1588     {
1589         // When replacing audio data for a specific track (-trk)
1590 
1591         if (Convert_Verbose)
1592         {
1593             printf("Replace audio data of one track.\n");
1594         }
1595 
1596         // -o/-r/-non/-odd/-even are ignored
1597 
1598         error = changeAudioTrack(&fileHeader);
1599 
1600     }
1601     else
1602     {
1603         // When replacing audio data for all tracks (-s)
1604 
1605         if (Convert_Verbose)
1606         {
1607             printf("Append/Replace audio data of all tracks.\n");
1608         }
1609 
1610         // Frame rate update (-r)
1611         if (change_framerate)
1612         {
1613             fileHeader.header.frameRate = frame_rate;
1614         }
1615 
1616         // Update existence of offset table (-o)
1617         if (offset_mode)
1618         {
1619             fileHeader.header.offsetDataOffsets = offset_mode;
1620         }
1621 
1622         // Update the specification of the display start field (-non/odd/even)
1623         if (change_videotype)
1624         {
1625             fileHeader.videoInfo.videoType = videotype;
1626         }
1627 
1628         error = appendAudioData(&fileHeader);
1629     }
1630 
1631 ERROR_END:
1632 
1633     THPAudioQuit();
1634 
1635     return error;
1636 }
1637 
1638 /*---------------------------------------------------------------------------*
1639   Name:         logPrintFunc
1640 
1641   Description:  Outputs messages, logs and errors
1642 
1643   Arguments:    ...
1644 
1645   Returns:      None.
1646  *---------------------------------------------------------------------------*/
logPrintFunc(const char * format,va_list argptr)1647 static void logPrintFunc(const char* format, va_list argptr)
1648 {
1649     vfprintf(stdout, format, argptr);
1650 }
1651 
1652 /*---------------------------------------------------------------------------*
1653   Name:         main
1654 
1655   Description:  THPConv main
1656 
1657   Arguments:    (references Usage())
1658 
1659   Returns:      0           Ended normally
1660                 1           Ends in an error
1661  *---------------------------------------------------------------------------*/
main(int argc,char * argv[])1662 int main(int argc, char *argv[])
1663 {
1664     s32  error = 0;
1665 
1666     // Hook the function for output of messages by the THP Library
1667     THPPrintFunc      = logPrintFunc;
1668     THPPrintLogFunc   = logPrintFunc;
1669     THPPrintErrorFunc = logPrintFunc;
1670 
1671     // Argument checker
1672     error = checkArguments(argc, argv);
1673 
1674     // Set the verbose mode flag for the THP Library
1675     THPVerboseFlag = Convert_Verbose;
1676 
1677     if (Convert_Verbose)
1678     {
1679         printf("Dolphin Jpegs to THP converter. Copyright 2002-2003 Nintendo.\n");
1680         printf("Built : %s %s\n\n", __DATE__, __TIME__);
1681     }
1682 
1683     if ((error == FALSE) || (argc == 1))
1684     {
1685         exit(1);
1686     }
1687 
1688     printf("THP file Version is %X.%X\n", THP_VERSION >> 16, THP_VERSION & 0xFFFF);
1689 
1690     // Create THP
1691     if (pack_jpegs)
1692     {
1693         // Convert from JPEG to THP (-j)
1694 
1695         if (Convert_Verbose)
1696         {
1697             printf("Convert from JPEGs to THP...\n");
1698         }
1699 
1700         error = convertJPEGtoTHP();
1701     }
1702 
1703     else if (change_snd_data)
1704     {
1705         // Add/replace audio data in existing THP (-c)
1706 
1707         if (Convert_Verbose)
1708         {
1709             printf("Append/Replace audio data...\n");
1710         }
1711 
1712         // Overwrite confirmation
1713         if (outFile == NULL)
1714         {
1715             if (verifyWriteOverInputData(inFile) == FALSE)
1716             {
1717                 exit(0);
1718             }
1719         }
1720 
1721         error = changeAudioData();
1722     }
1723 
1724     if (error == FALSE)
1725     {
1726         printf("WARNING : Errors occurred while converting to THP.\n");
1727         printf("          Please check for error messages above!\n");
1728 
1729         exit(1);
1730     }
1731     else
1732     {
1733         if (outFile)
1734         {
1735             printf("Successfully generated [%s].\n", outFile);
1736         }
1737         else
1738         {
1739             printf("Successfully overwrote [%s].\n", inFile);
1740         }
1741     }
1742 
1743     exit(0);
1744 }
1745