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