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