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