1 /*---------------------------------------------------------------------------*
2 Project: Revolution THP Utilities Library
3 File: thputilities.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: thputilities.c,v $
14 Revision 1.1 02/08/2006 02:57:09 aka
15 Imported from Dolphin Tree.
16
17
18 15 03/12/24 3:00p Akagi
19 Revised a comment.
20
21 14 03/12/24 1:58p Akagi
22 Added THPUtyCopyTHPFile().
23
24 13 03/12/10 10:17a Akagi
25 Revised THP version in THPUtyReadTHPFileHeader().
26
27 12 03/09/21 6:44p Akagi
28 Added THP file check during reading THPHeader.
29
30 11 03/09/15 5:56p Akagi
31 Renamed all functions from THPCONVXXXX to THPUtyXXXX.
32 Added some comments.
33
34 10 03/07/03 11:04a Akagi
35 Renamed some functions.
36
37 9 03/07/01 2:34p Akagi
38 Modified to divide old THPConv.exe into 2 LIBs and 1 EXE by
39 Ohki-san@NTSC.
40
41 8 03/07/01 2:26p Akagi
42 Moved from build/tools/THPConv/src.
43
44 7 03/07/01 9:54a Akagi
45 Moved from securebuild/tools.
46
47 6 02/10/16 11:28a Akagi
48 JPEG & WAV file Name bug fixed. (by iRD tsuji)
49
50 5 02/05/08 2:31p Akagi
51 modified [-trk] option By Tsuji (IRD)
52
53 1 02/01/16 4:59p Akagi
54 Initial revision made by Tsuji-san (IRD).
55
56 $NoKeywords: $
57
58 *---------------------------------------------------------------------------*/
59
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <assert.h>
63 #include <string.h>
64
65 #include <revolution/types.h>
66 #include <revolution/thpfile.h>
67 #include <win32/thpcommon.h>
68 #include <win32/thpcore.h>
69 #include <win32/thputilities.h>
70 #include <win32/thpaudio.h>
71
72 //-----------------------------------------------------------------------------
73 // Local Functions
74 //-----------------------------------------------------------------------------
75 static s32 THPUtyWriteVideoOneFrame( FILE* thpFp, THPFileName* fileName,
76 THPImageStatus* imageStatus );
77 static s32 THPUtyWriteAudioOneFrame( FILE* thpFp, THPFileHeader* fileHeader,
78 THPAudioHandle** audioHandleList,
79 u32 frameSize,
80 u32 frameNum );
81 static s32 THPUtyCopyVideoFrame ( FILE* thpFp, FILE* videoTHPFp,
82 THPFileHeader* videoFileHeader,
83 u32* videoCompSize );
84
85 /*---------------------------------------------------------------------------*
86 *---------------------------------------------------------------------------*
87 * Utility Functions *
88 *---------------------------------------------------------------------------*
89 *---------------------------------------------------------------------------*/
90 /*---------------------------------------------------------------------------*
91 Name: THPUtyConvertToUnixFmt
92
93 Description: Converts the Unix-format path specified in fmt to DOS format.
94 Be aware that the buffer specified by fmt is overwritten.
95
96 Arguments: fmt a pointer to the string to be converted
97
98 Returns: None.
99 *---------------------------------------------------------------------------*/
THPUtyConvertToUnixFmt(char * fmt)100 void THPUtyConvertToUnixFmt(char* fmt)
101 {
102 char* fmt_start = fmt;
103 char temp[256];
104 char* temp_ptr = temp;
105
106 strcpy(temp_ptr, fmt);
107
108 if (temp_ptr == NULL)
109 {
110 return;
111 }
112
113 while (*temp_ptr != '\0')
114 {
115 if ((*temp_ptr == '/') && (*(temp_ptr + 1) == '/'))
116 {
117 *fmt = *(temp_ptr + 2);
118 *(fmt + 1) = ':';
119 *(fmt + 2) = '\\';
120 fmt += 3;
121 temp_ptr += 3;
122 }
123 else if ((*temp_ptr == '.') && (*(temp_ptr + 1) == '.') && (*(temp_ptr + 2) == '/'))
124 {
125 *fmt = '.';
126 *(fmt + 1) = '.';
127 *(fmt + 2) = '\\';
128 fmt += 3;
129 temp_ptr += 3;
130 }
131 else if (*temp_ptr == '/')
132 {
133 *(fmt) = '\\';
134 fmt++;
135 temp_ptr++;
136 }
137 else
138 {
139 *fmt = *temp_ptr;
140 fmt++;
141 temp_ptr++;
142 }
143 }
144 }
145
146 /*---------------------------------------------------------------------------*
147 Name: THPUtyReverseEndianU16
148
149 Description: Converts a 16-bit value's endian.
150
151 Arguments: data a 16-bit value endian to be converted
152
153 Returns: an endian-converted value
154 *---------------------------------------------------------------------------*/
THPUtyReverseEndianU16(u16 data)155 u16 THPUtyReverseEndianU16(u16 data)
156 {
157 #if 1
158 __asm {
159 mov ax, data;
160 rol ax, 8;
161 mov data, ax;
162 }
163 return data;
164 #else
165 return (u16)(((data & 0x00FF) << 8) | ((data & 0xFF00) >> 8));
166 #endif
167 }
168
169 /*---------------------------------------------------------------------------*
170 Name: THPUtyReverseEndianU32
171
172 Description: Converts a 32-bit value's endian.
173
174 Arguments: data a 32-bit value endian to be converted
175
176 Returns: an endian-converted value
177 *---------------------------------------------------------------------------*/
THPUtyReverseEndianU32(u32 data)178 u32 THPUtyReverseEndianU32(u32 data)
179 {
180 #if 1
181 __asm {
182 mov eax, data;
183 bswap eax;
184 mov data, eax;
185 }
186 return data;
187
188 #else
189 return(((data >> 24) & 0x000000ff) |
190 ((data >> 8) & 0x0000ff00) |
191 ((data << 8) & 0x00ff0000) |
192 ((data << 24) & 0xff000000) );
193 #endif
194 }
195
196 /*---------------------------------------------------------------------------*
197 Name: THPUtyReverseEndianF32
198
199 Description: Converts a 32-bit floating value's endian.
200
201 Arguments: data a floating value endian to be converted
202
203 Returns: an endian-converted floating value
204 *---------------------------------------------------------------------------*/
THPUtyReverseEndianF32(f32 data)205 f32 THPUtyReverseEndianF32(f32 data)
206 {
207 u8* src = (u8 *)&data;
208 f32 result;
209 u8* r = (u8*)&result;
210
211 r[3] = src[0];
212 r[2] = src[1];
213 r[1] = src[2];
214 r[0] = src[3];
215
216 return(result);
217 }
218
219 /*---------------------------------------------------------------------------*
220 Name: THPUtyWritePad32
221
222 Description: Outputs NULLs to the file to make it 32-byte aligned.
223
224 Arguments: op a pointer to the output file
225 bytes the size of the data just output
226
227 Returns: THP_ERROR_NOERROR -- normal completion
228 THP_ERROR_FILEIO -- file output failed
229 *---------------------------------------------------------------------------*/
THPUtyWritePad32(FILE * op,u32 bytes)230 s32 THPUtyWritePad32(FILE* op, u32 bytes)
231 {
232 u32 remainder = 32 - (bytes & ((u32)31));
233 u8 val = 0;
234 u8 buffer[32];
235 size_t ret;
236
237 // no real remainder
238 if (remainder == 32)
239 {
240 return THP_ERROR_NOERROR;
241 }
242
243 THPPrintLog("Adding %ld pad bytes\n", remainder);
244
245 memset(buffer, 0, sizeof(buffer));
246
247 ret = fwrite(buffer, remainder, 1, op);
248 if (ret != 1)
249 {
250 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
251 return THP_ERROR_FILEIO;
252 }
253
254 return THP_ERROR_NOERROR;
255 }
256
257 /*---------------------------------------------------------------------------*
258 Name: THPUtyPutU32
259
260 Description: Converts the endian for u32-type data and outputs to a file specified by op.
261
262 Arguments: op a pointer to the output file
263 data the u32-type value to be output
264
265 Returns: THP_ERROR_NOERROR -- normal completion
266 THP_ERROR_FILEIO -- file output failed
267 *---------------------------------------------------------------------------*/
THPUtyPutU32(FILE * op,u32 data)268 s32 THPUtyPutU32(FILE *op, u32 data)
269 {
270 s32 rtn;
271 u8 buffer[4];
272
273 buffer[0] = (u8)(data >> 24);
274 buffer[1] = (u8)(data >> 16);
275 buffer[2] = (u8)(data >> 8);
276 buffer[3] = (u8)(data >> 0);
277 rtn = fwrite(buffer, 4, 1, op);
278 if (rtn != 1)
279 {
280 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
281 return THP_ERROR_FILEIO;
282 }
283
284 return THP_ERROR_NOERROR;
285 }
286
287 /*---------------------------------------------------------------------------*
288 Name: THPUtyPutF32
289
290 Description: Converts the endian for f32-type data and outputs to a file specified by op.
291
292 Arguments: op a pointer to the output file
293 data the f32-type value to be output
294
295 Returns: THP_ERROR_NOERROR -- normal completion
296 THP_ERROR_FILEIO -- file output failed
297 *---------------------------------------------------------------------------*/
THPUtyPutF32(FILE * op,f32 data)298 s32 THPUtyPutF32(FILE *op, f32 data)
299 {
300 u32 data_u32;
301
302 memcpy(&data_u32, &data, 4);
303
304 return THPUtyPutU32(op, data_u32);
305 }
306
307 /*---------------------------------------------------------------------------*
308 *---------------------------------------------------------------------------*
309 * THP File Write Functions *
310 *---------------------------------------------------------------------------*
311 *---------------------------------------------------------------------------*/
312 /*---------------------------------------------------------------------------*
313 Name: THPUtyHeaderInit
314
315 Description: Initializes the THPHeader structure.
316
317 Arguments: header a pointer to the THPHeader structure
318
319 Returns: None.
320 *---------------------------------------------------------------------------*/
THPUtyHeaderInit(THPHeader * header)321 void THPUtyHeaderInit(THPHeader* header)
322 {
323 header->magic[0] = 'T';
324 header->magic[1] = 'H';
325 header->magic[2] = 'P';
326 header->magic[3] = '\0';
327 header->version = THP_VERSION;
328 header->bufSize = 0;
329 header->audioMaxSamples = 0;
330 header->frameRate = 0.0F;
331 header->numFrames = 0; // frames total
332 header->firstFrameSize = 0;
333 header->movieDataSize = 0;
334 header->compInfoDataOffsets = 0;
335 header->offsetDataOffsets = 0;
336 header->movieDataOffsets = 0;
337 header->finalFrameDataOffsets = 0;
338 }
339
340 /*---------------------------------------------------------------------------*
341 Name: THPUtyWriteTHPHeader
342
343 Description: Outputs the THPHeader structure to a file specified by op.
344
345 Arguments: op a pointer to the output file
346 header a pointer to the THPHeader structure to be output
347
348 Returns: THP_ERROR_NOERROR -- normal completion
349 THP_ERROR_FILEIO -- file output failed
350 *---------------------------------------------------------------------------*/
THPUtyWriteTHPHeader(FILE * op,THPHeader * header)351 s32 THPUtyWriteTHPHeader(FILE *op, THPHeader *header)
352 {
353 s32 rtn;
354
355 rtn = fwrite(header->magic, 4, 1, op);
356 if (rtn != 1)
357 {
358 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
359 return THP_ERROR_FILEIO;
360 }
361
362 if ((rtn = THPUtyPutU32(op, header->version)) != THP_ERROR_NOERROR)
363 {
364 return rtn;
365 }
366 if ((rtn = THPUtyPutU32(op, header->bufSize)) != THP_ERROR_NOERROR)
367 {
368 return rtn;
369 }
370 if ((rtn = THPUtyPutU32(op, header->audioMaxSamples)) != THP_ERROR_NOERROR)
371 {
372 return rtn;
373 }
374 if ((rtn = THPUtyPutF32(op, header->frameRate)) != THP_ERROR_NOERROR)
375 {
376 return rtn;
377 }
378 if ((rtn = THPUtyPutU32(op, header->numFrames)) != THP_ERROR_NOERROR)
379 {
380 return rtn;
381 }
382 if ((rtn = THPUtyPutU32(op, header->firstFrameSize)) != THP_ERROR_NOERROR)
383 {
384 return rtn;
385 }
386 if ((rtn = THPUtyPutU32(op, header->movieDataSize)) != THP_ERROR_NOERROR)
387 {
388 return rtn;
389 }
390 if ((rtn = THPUtyPutU32(op, header->compInfoDataOffsets)) != THP_ERROR_NOERROR)
391 {
392 return rtn;
393 }
394 if ((rtn = THPUtyPutU32(op, header->offsetDataOffsets)) != THP_ERROR_NOERROR)
395 {
396 return rtn;
397 }
398 if ((rtn = THPUtyPutU32(op, header->movieDataOffsets)) != THP_ERROR_NOERROR)
399 {
400 return rtn;
401 }
402 if ((rtn = THPUtyPutU32(op, header->finalFrameDataOffsets)) != THP_ERROR_NOERROR)
403 {
404 return rtn;
405 }
406
407 return THP_ERROR_NOERROR;
408 }
409
410 /*---------------------------------------------------------------------------*
411 Name: THPUtyWriteTHPFrameCompInfo
412
413 Description: Outputs the THPFrameCompInfo structure to a file specified by op.
414
415 Arguments: op a pointer to the output file
416 header a pointer to the THPFrameCompInfo structure to be output
417
418 Returns: THP_ERROR_NOERROR -- normal completion
419 THP_ERROR_FILEIO -- file output failed
420 *---------------------------------------------------------------------------*/
THPUtyWriteTHPFrameCompInfo(FILE * op,THPFrameCompInfo * compinfo)421 s32 THPUtyWriteTHPFrameCompInfo(FILE *op, THPFrameCompInfo *compinfo)
422 {
423 s32 rtn;
424
425 if ((rtn = THPUtyPutU32(op, compinfo->numComponents)) != THP_ERROR_NOERROR)
426 {
427 return rtn;
428 }
429
430 rtn = fwrite(compinfo->frameComp, THP_COMP_MAX, 1, op);
431 if (rtn != 1)
432 {
433 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
434 return THP_ERROR_FILEIO;
435 }
436
437 return THP_ERROR_NOERROR;
438 }
439
440 /*---------------------------------------------------------------------------*
441 Name: THPUtyWriteTHPVideoInfo
442
443 Description: Outputs the THPVideoInfo structure to a file specified by op.
444
445 Arguments: op a pointer to the output file
446 header a pointer to the THPVideoInfo structure to be output
447
448 Returns: THP_ERROR_NOERROR -- normal completion
449 THP_ERROR_FILEIO -- file output failed
450 *---------------------------------------------------------------------------*/
THPUtyWriteTHPVideoInfo(FILE * op,THPVideoInfo * videoinfo)451 s32 THPUtyWriteTHPVideoInfo(FILE *op, THPVideoInfo *videoinfo)
452 {
453 s32 rtn;
454
455 if ((rtn = THPUtyPutU32(op, videoinfo->xSize)) != THP_ERROR_NOERROR)
456 {
457 return rtn;
458 }
459 if ((rtn = THPUtyPutU32(op, videoinfo->ySize)) != THP_ERROR_NOERROR)
460 {
461 return rtn;
462 }
463 if ((rtn = THPUtyPutU32(op, videoinfo->videoType)) != THP_ERROR_NOERROR)
464 {
465 return rtn;
466 }
467
468 return THP_ERROR_NOERROR;
469 }
470
471 /*---------------------------------------------------------------------------*
472 Name: THPUtyWriteTHPAudioInfo
473
474 Description: Outputs the THPAudioInfo structure to a file specified by op.
475
476 Arguments: op a pointer to the output file
477 header a pointer to the THPAudioInfo structure to be output
478
479 Returns: THP_ERROR_NOERROR -- normal completion
480 THP_ERROR_FILEIO -- file output failed
481 *---------------------------------------------------------------------------*/
THPUtyWriteTHPAudioInfo(FILE * op,THPAudioInfo * audioinfo)482 s32 THPUtyWriteTHPAudioInfo(FILE *op, THPAudioInfo *audioinfo)
483 {
484 s32 rtn;
485
486 if ((rtn = THPUtyPutU32(op, audioinfo->sndChannels)) != THP_ERROR_NOERROR)
487 {
488 return rtn;
489 }
490 if ((rtn = THPUtyPutU32(op, audioinfo->sndFrequency)) != THP_ERROR_NOERROR)
491 {
492 return rtn;
493 }
494 if ((rtn = THPUtyPutU32(op, audioinfo->sndNumSamples)) != THP_ERROR_NOERROR)
495 {
496 return rtn;
497 }
498 if ((rtn = THPUtyPutU32(op, audioinfo->sndNumTracks)) != THP_ERROR_NOERROR)
499 {
500 return rtn;
501 }
502
503 return THP_ERROR_NOERROR;
504 }
505
506 /*---------------------------------------------------------------------------*
507 Name: THPUtyWriteTHPFrameHeader
508
509 Description: Outputs the THPFrameHeader structure to a file specified by op.
510
511 Arguments: op a pointer to the output file
512 frameCompInfo a pointer to the THPFrameCompInfo structure
513 frameHeader a pointer to the THPFrameHeader structure to be output
514
515 Returns: THP_ERROR_NOERROR -- normal completion
516 THP_ERROR_FILEIO -- file output failed
517 *---------------------------------------------------------------------------*/
THPUtyWriteTHPFrameHeader(FILE * op,THPFrameCompInfo * frameCompInfo,THPFrameHeader * frameHeader)518 s32 THPUtyWriteTHPFrameHeader(FILE* op, THPFrameCompInfo* frameCompInfo,
519 THPFrameHeader* frameHeader)
520 {
521 u32 i;
522 s32 rtn;
523
524 if ((rtn = THPUtyPutU32(op, frameHeader->frameSizeNext)) != THP_ERROR_NOERROR)
525 {
526 return rtn;
527 }
528 if ((rtn = THPUtyPutU32(op, frameHeader->frameSizePrevious)) != THP_ERROR_NOERROR)
529 {
530 return rtn;
531 }
532 for (i = 0; i < frameCompInfo->numComponents; i++)
533 {
534 if ((rtn = THPUtyPutU32(op, frameHeader->comp[i])) != THP_ERROR_NOERROR)
535 {
536 return rtn;
537 }
538 }
539
540 return THP_ERROR_NOERROR;
541 }
542
543 /*---------------------------------------------------------------------------*
544 Name: THPUtyWriteTHPComponentsInfo
545
546 Description: Outputs the THPVideoInfo and THPAudioInfo structures to a file specified by op.
547
548 Arguments: op a pointer to the output file
549 compinfo a pointer to the THPFrameCompInfo structure
550 header a pointer to the THPVideoInfo structure to be output
551 header a pointer to the THPAudioInfo structure to be output
552 compinfosize a pointer to the storage of the component size
553
554 Returns: THP_ERROR_NOERROR -- normal completion
555 THP_ERROR_FILEIO -- file output failed
556 THP_ERROR_DATA data error
557 *---------------------------------------------------------------------------*/
THPUtyWriteTHPComponentsInfo(FILE * op,THPFrameCompInfo * compinfo,THPVideoInfo * videoinfo,THPAudioInfo * audioinfo,s32 * compinfosize)558 s32 THPUtyWriteTHPComponentsInfo(FILE* op, THPFrameCompInfo* compinfo,
559 THPVideoInfo* videoinfo,
560 THPAudioInfo* audioinfo,
561 s32* compinfosize)
562 {
563 u32 i;
564 s32 size = 0;
565 s32 rtn;
566
567 for (i = 0; i < compinfo->numComponents; i++)
568 {
569 switch (compinfo->frameComp[i])
570 {
571 case THP_VIDEO_COMP:
572 rtn = THPUtyWriteTHPVideoInfo(op, videoinfo);
573 if (rtn != THP_ERROR_NOERROR)
574 {
575 return rtn;
576 }
577 size += sizeof(THPVideoInfo);
578 break;
579
580 case THP_AUDIO_COMP:
581 rtn = THPUtyWriteTHPAudioInfo(op, audioinfo);
582 if (rtn != THP_ERROR_NOERROR)
583 {
584 return rtn;
585 }
586 size += sizeof(THPAudioInfo);
587 break;
588
589 case THP_NOCOMP_COMP:
590 THPPrintError("\aERROR : Strange numComponents (%ld)\n", __LINE__);
591 return THP_ERROR_DATA;
592 break;
593
594 default:
595 THPPrintError("\aERROR : Unsupported Components (%ld)\n", __LINE__);
596 return THP_ERROR_DATA;
597 break;
598 }
599 }
600
601 if (compinfosize != NULL)
602 {
603 *compinfosize = size;
604 }
605
606 return THP_ERROR_NOERROR;
607 }
608
609 /*---------------------------------------------------------------------------*
610 Name: THPUtyWriteTHPFileHeader
611
612 Description: Outputs the THPFileHeader structure to a file specified by op.
613
614 Arguments: op a pointer to the output file
615 fileHeader a pointer to the THPFileHeader structure to be output
616 compInfoSize a pointer to the storage of the component size
617
618 Returns: THP_ERROR_NOERROR -- normal completion
619 THP_ERROR_FILEIO -- file output failed
620 THP_ERROR_DATA data error
621 *---------------------------------------------------------------------------*/
THPUtyWriteTHPFileHeader(FILE * op,THPFileHeader * fileHeader,s32 * compInfoSize)622 s32 THPUtyWriteTHPFileHeader(FILE* op, THPFileHeader* fileHeader, s32* compInfoSize)
623 {
624 s32 rtn;
625
626 rtn = fseek(op, 0, SEEK_SET);
627 if (rtn != 0)
628 {
629 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
630 return THP_ERROR_FILEIO;
631 }
632
633 // Write THPHeader, THPFrameCompInfo, THPVideoInfo, THPAudioInfo(Update after Convert)
634
635 rtn = THPUtyWriteTHPHeader(op, &fileHeader->header);
636 if (rtn != THP_ERROR_NOERROR)
637 {
638 return rtn;;
639 }
640
641 rtn = fseek(op, fileHeader->header.compInfoDataOffsets, SEEK_SET);
642 if (rtn != 0)
643 {
644 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
645 return THP_ERROR_FILEIO;
646 }
647
648 rtn = THPUtyWriteTHPFrameCompInfo(op, &fileHeader->frameCompInfo);
649 if (rtn != THP_ERROR_NOERROR)
650 {
651 return rtn;
652 }
653
654 rtn = THPUtyWriteTHPComponentsInfo(op,
655 &fileHeader->frameCompInfo,
656 &fileHeader->videoInfo,
657 &fileHeader->audioInfo,
658 compInfoSize);
659 if (rtn != THP_ERROR_NOERROR)
660 {
661 return rtn;
662 }
663
664 return THP_ERROR_NOERROR;
665 }
666
667 /*---------------------------------------------------------------------------*
668 *---------------------------------------------------------------------------*
669 * THP File Read Functions *
670 *---------------------------------------------------------------------------*
671 *---------------------------------------------------------------------------*/
672 /*---------------------------------------------------------------------------*
673 Name: THPUtyReadTHPHeader
674
675 Description: Reads the THPHeader structure from a THP file specified by ip.
676 The read position needs to be set to the THPHeader position in advance.
677
678 Arguments: ip a file pointer to the THP file
679 header a pointer to the THPHeader structure
680
681 Returns: THP_ERROR_NOERROR -- normal completion
682 THP_ERROR_FILEIO file read error
683 THP_ERROR_THPFILE THP file error
684 *---------------------------------------------------------------------------*/
THPUtyReadTHPHeader(FILE * ip,THPHeader * header)685 s32 THPUtyReadTHPHeader(FILE *ip, THPHeader *header)
686 {
687 s32 rtn;
688
689 rtn = fread(header, sizeof(THPHeader), 1, ip);
690 if (rtn != 1)
691 {
692 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
693 return THP_ERROR_FILEIO;
694 }
695
696 // magic check
697 if (memcmp(header->magic, "THP\0", 4))
698 {
699 THPPrintError("\aERROR : this will not be a THP file (%ld)\n", __LINE__);
700 return THP_ERROR_THPFILE;
701 }
702
703 // Reverse Endian
704 header->version = THPUtyReverseEndianU32(header->version);
705 header->bufSize = THPUtyReverseEndianU32(header->bufSize);
706 header->audioMaxSamples = THPUtyReverseEndianU32(header->audioMaxSamples);
707 header->frameRate = THPUtyReverseEndianF32(header->frameRate);
708 header->numFrames = THPUtyReverseEndianU32(header->numFrames);
709 header->firstFrameSize = THPUtyReverseEndianU32(header->firstFrameSize);
710 header->movieDataSize = THPUtyReverseEndianU32(header->movieDataSize);
711 header->compInfoDataOffsets = THPUtyReverseEndianU32(header->compInfoDataOffsets);
712 header->offsetDataOffsets = THPUtyReverseEndianU32(header->offsetDataOffsets);
713 header->movieDataOffsets = THPUtyReverseEndianU32(header->movieDataOffsets);
714 header->finalFrameDataOffsets = THPUtyReverseEndianU32(header->finalFrameDataOffsets);
715
716 return THP_ERROR_NOERROR;
717 }
718
719 /*---------------------------------------------------------------------------*
720 Name: THPUtyReadTHPFrameCompInfo
721
722 Description: Reads the THPFrameCompInfo structure from a THP file specified by ip.
723 The read position needs to be set to the THPFrameCompInfo position in advance.
724
725 Arguments: ip a file pointer to the THP file
726 compinfo a pointer to the THPFrameCompInfo structure
727
728 Returns: THP_ERROR_NOERROR -- normal completion
729 THP_ERROR_FILEIO file read error
730 *---------------------------------------------------------------------------*/
THPUtyReadTHPFrameCompInfo(FILE * ip,THPFrameCompInfo * compinfo)731 s32 THPUtyReadTHPFrameCompInfo(FILE *ip, THPFrameCompInfo *compinfo)
732 {
733 s32 rtn;
734
735 rtn = fread(compinfo, sizeof(THPFrameCompInfo), 1, ip);
736 if (rtn != 1)
737 {
738 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
739 return THP_ERROR_FILEIO;
740 }
741
742 // Reverse Endian
743 compinfo->numComponents = THPUtyReverseEndianU32(compinfo->numComponents);
744
745 return THP_ERROR_NOERROR;
746 }
747
748 /*---------------------------------------------------------------------------*
749 Name: THPUtyReadTHPVideoInfo
750
751 Description: Reads the THPVideoInfo structure from a THP file specified by ip.
752 The read position needs to be set to the THPVideoInfo position in advance.
753
754 Arguments: ip a file pointer to the THP file
755 videoinfo a pointer to the THPVideoInfo structure
756
757 Returns: THP_ERROR_NOERROR -- normal completion
758 THP_ERROR_FILEIO file read error
759 *---------------------------------------------------------------------------*/
THPUtyReadTHPVideoInfo(FILE * ip,THPVideoInfo * videoinfo)760 s32 THPUtyReadTHPVideoInfo(FILE *ip, THPVideoInfo *videoinfo)
761 {
762 s32 rtn;
763
764 rtn = fread(videoinfo, sizeof(THPVideoInfo), 1, ip);
765 if (rtn != 1)
766 {
767 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
768 return THP_ERROR_FILEIO;
769 }
770
771 // Reverse Endian
772 videoinfo->xSize = THPUtyReverseEndianU32(videoinfo->xSize);
773 videoinfo->ySize = THPUtyReverseEndianU32(videoinfo->ySize);
774 videoinfo->videoType = THPUtyReverseEndianU32(videoinfo->videoType);
775
776 return THP_ERROR_NOERROR;
777 }
778
779 /*---------------------------------------------------------------------------*
780 Name: THPUtyReadTHPVideoInfoOld
781
782 Description: Reads the THPVideoInfo structure from a version 1.0 or older THP file specified by ip.
783 The read position needs to be set to the THPVideoInfo position in advance.
784
785 Arguments: ip a file pointer to a version 1.0 or older THP file
786 videoinfo a pointer to the THPVideoInfo structure
787
788 Returns: THP_ERROR_NOERROR -- normal completion
789 THP_ERROR_FILEIO file read error
790 *---------------------------------------------------------------------------*/
THPUtyReadTHPVideoInfoOld(FILE * ip,THPVideoInfo * videoinfo)791 s32 THPUtyReadTHPVideoInfoOld(FILE *ip, THPVideoInfo *videoinfo)
792 {
793 s32 rtn;
794 THPVideoInfoOld videoinfoOld;
795
796 rtn = fread(&videoinfoOld, sizeof(THPVideoInfoOld), 1, ip);
797 if (rtn != 1)
798 {
799 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
800 return THP_ERROR_FILEIO;
801 }
802
803 // Reverse Endian
804 videoinfo->xSize = THPUtyReverseEndianU32(videoinfoOld.xSize);
805 videoinfo->ySize = THPUtyReverseEndianU32(videoinfoOld.ySize);
806 videoinfo->videoType = THP_VIDEO_NON_INTERLACE;
807
808 return THP_ERROR_NOERROR;
809 }
810
811 /*---------------------------------------------------------------------------*
812 Name: THPUtyReadTHPAudioInfo
813
814 Description: Reads the THPAudioInfo structure from a THP file specified by ip.
815 The read position needs to be set to the THPAudioInfo position in advance.
816
817 Arguments: ip a file pointer to the THP file
818 audioinfo a pointer to the THPAudioInfo structure
819
820 Returns: THP_ERROR_NOERROR -- normal completion
821 THP_ERROR_FILEIO file read error
822 *---------------------------------------------------------------------------*/
THPUtyReadTHPAudioInfo(FILE * ip,THPAudioInfo * audioinfo)823 s32 THPUtyReadTHPAudioInfo(FILE *ip, THPAudioInfo *audioinfo)
824 {
825 s32 rtn;
826
827 rtn = fread(audioinfo, sizeof(THPAudioInfo), 1, ip);
828 if (rtn != 1)
829 {
830 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
831 return THP_ERROR_FILEIO;
832 }
833
834 // Reverse Endian
835 audioinfo->sndChannels = THPUtyReverseEndianU32(audioinfo->sndChannels);
836 audioinfo->sndFrequency = THPUtyReverseEndianU32(audioinfo->sndFrequency);
837 audioinfo->sndNumSamples = THPUtyReverseEndianU32(audioinfo->sndNumSamples);
838 audioinfo->sndNumTracks = THPUtyReverseEndianU32(audioinfo->sndNumTracks);
839
840 return THP_ERROR_NOERROR;
841 }
842
843 /*---------------------------------------------------------------------------*
844 Name: THPUtyReadTHPAudioInfoOld
845
846 Description: Reads the THPAudioInfo structure from a version 1.0 or older THP file specified by ip.
847 The read position needs to be set to the THPAudioInfo position in advance.
848
849 Arguments: ip a file pointer to a version 1.0 or older THP file
850 audioinfo a pointer to the THPAudioInfo structure
851
852 Returns: THP_ERROR_NOERROR -- normal completion
853 THP_ERROR_FILEIO file read error
854 *---------------------------------------------------------------------------*/
THPUtyReadTHPAudioInfoOld(FILE * ip,THPAudioInfo * audioinfo)855 s32 THPUtyReadTHPAudioInfoOld(FILE *ip, THPAudioInfo *audioinfo)
856 {
857 s32 rtn;
858 THPAudioInfoOld audioinfoOld;
859
860 rtn = fread(&audioinfoOld, sizeof(THPAudioInfoOld), 1, ip);
861 if (rtn != 1)
862 {
863 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
864 return THP_ERROR_FILEIO;
865 }
866
867 // Reverse Endian
868 audioinfo->sndChannels = THPUtyReverseEndianU32(audioinfoOld.sndChannels);
869 audioinfo->sndFrequency = THPUtyReverseEndianU32(audioinfoOld.sndFrequency);
870 audioinfo->sndNumSamples = THPUtyReverseEndianU32(audioinfoOld.sndNumSamples);
871 audioinfo->sndNumTracks = 1;
872
873 return THP_ERROR_NOERROR;
874 }
875
876 /*---------------------------------------------------------------------------*
877 Name: THPUtyReadTHPFrameHeader
878
879 Description: Reads the THPFrameHeader structure from a THP file specified by ip.
880 The read position needs to be set to the THPFrameHeader position in advance.
881
882 Arguments: ip a file pointer to the THP file
883 frameHeader a pointer to the THPFrameHeader
884 componentNum the number of components included in the THP file
885
886 Returns: THP_ERROR_NOERROR -- normal completion
887 THP_ERROR_FILEIO file read error
888 *---------------------------------------------------------------------------*/
THPUtyReadTHPFrameHeader(FILE * ip,THPFrameHeader * frameHeader,s32 componentNum)889 s32 THPUtyReadTHPFrameHeader(FILE* ip, THPFrameHeader* frameHeader, s32 componentNum)
890 {
891 s32 rtn;
892 size_t readSize;
893
894 readSize = componentNum * sizeof(u32) + sizeof(u32) * 2;
895 rtn = fread(frameHeader, readSize, 1,ip);
896 if (rtn != 1)
897 {
898 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
899 return THP_ERROR_FILEIO;
900 }
901
902 // Reverse Endian
903 frameHeader->frameSizeNext = THPUtyReverseEndianU32(frameHeader->frameSizeNext);
904 frameHeader->frameSizePrevious = THPUtyReverseEndianU32(frameHeader->frameSizePrevious);
905 {
906 s32 i;
907 for (i = 0; i < componentNum; i++)
908 {
909 frameHeader->comp[i] = THPUtyReverseEndianU32(frameHeader->comp[i]);
910 }
911 }
912
913 return THP_ERROR_NOERROR;
914 }
915
916 /*---------------------------------------------------------------------------*
917 Name: THPUtyReadTHPFileHeader
918
919 Description: Reads the THPFileHeader structure from a THP file specified by ip.
920 The read position needs to be set to the THPFileHeader position in advance.
921
922 Arguments: ip a file pointer to the THP file
923 fileHeader a pointer to the THPFileHeader
924
925 Returns: THP_ERROR_NOERROR -- normal completion
926 THP_ERROR_FILEIO file read error
927 THP_ERROR_THPFILE THP file error
928 *---------------------------------------------------------------------------*/
THPUtyReadTHPFileHeader(FILE * ip,THPFileHeader * fileHeader)929 s32 THPUtyReadTHPFileHeader(FILE* ip, THPFileHeader* fileHeader)
930 {
931 s32 rtn;
932 u32 i;
933
934 // Seek THPHeader Offset
935 rtn = fseek(ip, 0, SEEK_SET);
936 if (rtn != 0)
937 {
938 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
939 return THP_ERROR_FILEIO;
940 }
941
942 // Read THPHeader
943 rtn = THPUtyReadTHPHeader(ip, &fileHeader->header);
944 if (rtn != THP_ERROR_NOERROR)
945 {
946 return rtn;
947 }
948
949 // Seek THPFrameCompInfo Offset
950 rtn = fseek(ip, fileHeader->header.compInfoDataOffsets, SEEK_SET);
951 if (rtn != 0)
952 {
953 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
954 return THP_ERROR_FILEIO;
955 }
956
957 // Read THPFrameCompInfo
958 rtn = THPUtyReadTHPFrameCompInfo(ip, &fileHeader->frameCompInfo);
959 if (rtn != THP_ERROR_NOERROR)
960 {
961 return rtn;
962 }
963
964 // Read THPVideoInfo/THPAudioInfo
965 for (i = 0; i < fileHeader->frameCompInfo.numComponents; i++)
966 {
967 switch (fileHeader->frameCompInfo.frameComp[i])
968 {
969
970 case THP_VIDEO_COMP: // THPVideoInfo
971 if (fileHeader->header.version > 0x10000)
972 {
973 // Ver 1.1 or later
974 rtn = THPUtyReadTHPVideoInfo(ip, &fileHeader->videoInfo);
975 }
976 else
977 {
978 // Ver1.0
979 rtn = THPUtyReadTHPVideoInfoOld(ip, &fileHeader->videoInfo);
980 }
981 if (rtn != THP_ERROR_NOERROR)
982 {
983 return rtn;
984 }
985 break;
986
987 case THP_AUDIO_COMP: //THPAudioInfo
988 if (fileHeader->header.version > 0x10000)
989 {
990 // Ver 1.1 or later
991 rtn = THPUtyReadTHPAudioInfo(ip, &fileHeader->audioInfo);
992 }
993 else
994 {
995 // Ver1.0
996 rtn = THPUtyReadTHPAudioInfoOld(ip, &fileHeader->audioInfo);
997 }
998 if (rtn != THP_ERROR_NOERROR)
999 {
1000 return rtn;
1001 }
1002 break;
1003
1004 case THP_NOCOMP_COMP:
1005 THPPrintError("\aERROR : Strange numComponents (%ld)\n", __LINE__);
1006 return THP_ERROR_THPFILE;
1007 break;
1008
1009 default:
1010 THPPrintError("\aERROR : Unsupported Components (%ld)\n", __LINE__);
1011 return THP_ERROR_THPFILE;
1012 break;
1013 }
1014 }
1015
1016 return THP_ERROR_NOERROR;
1017 }
1018
1019 /*---------------------------------------------------------------------------*
1020 *---------------------------------------------------------------------------*
1021 * THP File Manipulating Functions *
1022 *---------------------------------------------------------------------------*
1023 *---------------------------------------------------------------------------*/
1024 /*---------------------------------------------------------------------------*
1025 Name: THPUtyCreateTHP
1026
1027 Description: Creates a THP file based on the fileHeader information.
1028
1029 Arguments: op a pointer to the output file
1030 fileFlag flag specifying the input data's type
1031 filePtr a pointer to the input data corresponding to fileFlag
1032 fileHeader a pointer to the THPFileHeader structure
1033 audioHandleList a list of pointers to the THPAudioHandle structures
1034
1035 Returns: THP_ERROR_NOERROR -- normal completion
1036 THP_ERROR_FILEIO file read/write failure
1037 THP_ERROR_JPEGFILE JPG file error
1038 THP_ERROR_THPFILE THP file error
1039 THP_ERROR_DATA data error
1040 THP_ERROR_FATAL memory allocation failure
1041 *---------------------------------------------------------------------------*/
1042 /*---------------------------------------------------------------------------*
1043
1044 - fileFlag
1045
1046 fileFlag = THP_CREATETHP_FILEFLAG_JPEGS :
1047 filePtr is a list of JPG files specified in the THPFileName structure's array.
1048 The JPG files specified by filePtr are converted to THP format and a THP file is created.
1049 A list of the specified number in headerHeader.header.numFrames is needed.
1050
1051 fileFlag = THP_CREATETHP_FILEFLAG_THP :
1052 filePtr is a file pointer to the input THP file.
1053
1054 - fileHeader
1055
1056 The following members must be set prior to calling.
1057 (Other members are set by this function.)
1058
1059 [THPHeader]
1060 fileHeader->header.magic
1061 fileHeader->header.version
1062 fileHeader->header.frameRate
1063 fileHeader->header.numFrames
1064 fileHeader->header.compInfoDataOffsets
1065 fileHeader->header.offsetDataOffsets (the value must not be 0 when an offset is used)
1066
1067 [THPFrameCompInfo]
1068 fileHeader->frameCompInfo.frameComp[]
1069 fileHeader->frameCompInfo.numComponents
1070
1071 [THPVideoInfo]
1072 fileHeader->videoInfo.videoType
1073
1074 [THPAudioInfo]
1075 fileHeader->audioInfo.sndChannels
1076 fileHeader->audioInfo.sndFrequency
1077 fileHeader->audioInfo.sndNumSamples
1078 fileHeader->audioInfo.sndNumTracks
1079
1080 - audioHandleList
1081
1082 After the multiple WAV files specified by audioHandleList are encoded, they are
1083 interleaved with the video data and output to a THP file.
1084 The specified THPAudioHandle structure must be opened with THPAudioCreateHandle.
1085 The number of lists must be as in audioInfo.sndNumTracks.
1086 NULL is specified when there is no audio conversion.
1087
1088 *---------------------------------------------------------------------------*/
THPUtyCreateTHP(FILE * op,s32 fileFlag,void * filePtr,THPFileHeader * fileHeader,THPAudioHandle ** audioHandleList)1089 s32 THPUtyCreateTHP(FILE* op, s32 fileFlag,
1090 void* filePtr,
1091 THPFileHeader* fileHeader,
1092 THPAudioHandle** audioHandleList)
1093 {
1094 s32 rtn;
1095 s32 compInfoSize;
1096 u32 i, compCnt;
1097 THPFrameHeader frameHeader;
1098 u32* frameOffsetData = NULL;
1099 u32 frameHeaderSize;
1100 u32 frameSize;
1101 u32 frameSizeMax = 0;
1102 s32 frameSizeFirst = 0;
1103 s32 frameSizePrevious = 0;
1104 s32 movieDataSize = 0;
1105 u32 xSize, ySize;
1106 u8 tempZero[32];
1107 s32 error = THP_ERROR_NOERROR;
1108 u32 NumFrames = fileHeader->header.numFrames;
1109 THPImageStatus imageStatus;
1110 THPFileHeader videoFileHeader;
1111 FILE* videoTHPFp;
1112
1113 switch (fileHeader->videoInfo.videoType)
1114 {
1115 case THP_VIDEO_NON_INTERLACE:
1116 THPPrintLog("Video Type: [Non-interlace]\n");
1117 break;
1118 case THP_VIDEO_ODD_INTERLACE:
1119 THPPrintLog("Video Type: [Interlace ODD start]\n");
1120 break;
1121 case THP_VIDEO_EVEN_INTERLACE:
1122 THPPrintLog("Video Type: [Interlace EVEN start]\n");
1123 break;
1124 }
1125
1126 //
1127 // THPFileHeader is read
1128 //
1129
1130 rtn = THPUtyWriteTHPFileHeader(op, fileHeader, &compInfoSize);
1131 if (rtn != THP_ERROR_NOERROR)
1132 {
1133 THPPrintError("\aERROR : Can't write THPFileHeader (%ld)\n", __LINE__);
1134 error = rtn;
1135 goto ERROR_END;
1136 }
1137
1138 // read the header from the original THP file (when adding/changing audio data)
1139 if (fileFlag == THP_CREATETHP_FILEFLAG_THP)
1140 {
1141 videoTHPFp = (FILE*)filePtr;
1142 rtn = THPUtyReadTHPFileHeader(videoTHPFp, &videoFileHeader);
1143 if (rtn != THP_ERROR_NOERROR)
1144 {
1145 THPPrintError("\aERROR : Can't read THPFileHeader (%ld)\n", __LINE__);
1146 error = rtn;
1147 goto ERROR_END;
1148 }
1149
1150 // Seek movie data top
1151 rtn = fseek(videoTHPFp, videoFileHeader.header.movieDataOffsets, SEEK_SET);
1152 if (rtn != 0)
1153 {
1154 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1155 error = THP_ERROR_FILEIO;
1156 goto ERROR_END;
1157 }
1158 }
1159
1160 //
1161 // write offset data
1162 //
1163 // NB: frameOffsetData is an offset array from the second frame to the end of the last frame
1164 // however, procedurally, the array is set up from the first frame. When written,
1165 // it goes from the second frame.
1166
1167 frameOffsetData = (u32*)THPMalloc(sizeof(u32) * (NumFrames + 1));
1168 if (frameOffsetData == NULL)
1169 {
1170 THPPrintError("\aERROR : Can't allocate memory (%ld Bytes) (%ld)\n",
1171 sizeof(u32) * (NumFrames + 1), __LINE__);
1172 error = THP_ERROR_FATAL;
1173 goto ERROR_END;
1174 }
1175
1176 if (fileHeader->header.offsetDataOffsets)
1177 {
1178 // A dummy write of the offset value. The actual offset value is written last.
1179 fileHeader->header.offsetDataOffsets
1180 = sizeof(THPFrameCompInfo)
1181 + fileHeader->header.compInfoDataOffsets + compInfoSize;
1182 rtn = fwrite(frameOffsetData, sizeof(u32) * NumFrames, 1, op);
1183 if (rtn != 1)
1184 {
1185 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
1186 error = THP_ERROR_FILEIO;
1187 goto ERROR_END;
1188 }
1189 }
1190
1191 //
1192 // all frame data is written
1193 //
1194
1195 memset(tempZero, 0, sizeof(tempZero));
1196
1197 frameHeaderSize =
1198 sizeof(u32) * fileHeader->frameCompInfo.numComponents + sizeof(u32) * 2;
1199
1200 THPPrintLog("START: Write THP Frame Datas.\n");
1201 if (THPVerboseFlag == 0)
1202 {
1203 THPPrint(" << THP Packing START >>\r");
1204 }
1205 else
1206 {
1207 THPPrint(" << THP Packing START >>\n");
1208 }
1209
1210 for (i = 0; i < NumFrames; i++)
1211 {
1212 s32 currPos;
1213
1214 if (THPVerboseFlag == 0)
1215 {
1216 THPPrint(" Now Packing: No.%5ld/%5ld\r", i, NumFrames);
1217 }
1218 else
1219 {
1220 THPPrint(" Now Packing: No.%5ld/%5ld\n", i, NumFrames);
1221 }
1222
1223 frameSize = frameHeaderSize;
1224
1225 frameOffsetData[i] = (u32)ftell(op);
1226 if (frameOffsetData[i] == 0xFFFFFFFF)
1227 {
1228 THPPrintError("\aERROR : ftell error (%ld)\n", __LINE__);
1229 error = THP_ERROR_FILEIO;
1230 goto ERROR_END;
1231 }
1232
1233 frameHeader.frameSizePrevious = frameSizePrevious;
1234
1235 rtn = fseek(op, frameHeaderSize, SEEK_CUR);
1236 if (rtn != 0)
1237 {
1238 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1239 error = THP_ERROR_FILEIO;
1240 goto ERROR_END;
1241 }
1242
1243 for (compCnt = 0; compCnt < fileHeader->frameCompInfo.numComponents; compCnt++)
1244 {
1245
1246 // Write Frame
1247 switch (fileHeader->frameCompInfo.frameComp[compCnt])
1248 {
1249 case THP_VIDEO_COMP: // Write Video Component
1250
1251 if (fileFlag == THP_CREATETHP_FILEFLAG_JPEGS)
1252 {
1253 THPFileName* fileNameList = (THPFileName*)filePtr;
1254
1255 rtn = THPUtyWriteVideoOneFrame(op, &fileNameList[i], &imageStatus);
1256 if (rtn != THP_ERROR_NOERROR)
1257 {
1258 THPPrintError("\aERROR : Can't write video data (%ld)\n",
1259 __LINE__);
1260 error = rtn;
1261 goto ERROR_END;
1262 }
1263
1264 // Check Image Format
1265 if (i == 0)
1266 {
1267 xSize = imageStatus.xSize;
1268 ySize = imageStatus.ySize;
1269 }
1270 else if ((xSize != imageStatus.xSize) || (ySize != imageStatus.ySize))
1271 {
1272 THPPrintError("\aERROR : Invalid x/y size (%ld)\n", __LINE__);
1273 THPPrintError(" All frames must have the same xsize\n");
1274 THPPrintError(" and ysize with the 1st frame!!\n");
1275 error = THP_ERROR_DATA;
1276 goto ERROR_END;
1277 }
1278 frameHeader.comp[compCnt] = imageStatus.imageSize;
1279 frameSize += imageStatus.imageSize;
1280 }
1281 else if (fileFlag == THP_CREATETHP_FILEFLAG_THP)
1282 {
1283 u32 videoFrameSize;
1284
1285 rtn = THPUtyCopyVideoFrame(op,
1286 videoTHPFp,
1287 &videoFileHeader,
1288 &videoFrameSize);
1289 if (rtn != THP_ERROR_NOERROR)
1290 {
1291 THPPrintError("\aERROR : Can't write video data (%ld)\n",
1292 __LINE__);
1293 error = rtn;
1294 goto ERROR_END;
1295 }
1296 frameHeader.comp[compCnt] = videoFrameSize;
1297 frameSize += videoFrameSize;
1298 }
1299
1300 break;
1301
1302 case THP_AUDIO_COMP: // Write Audio Component
1303
1304 if (audioHandleList == NULL)
1305 {
1306 THPPrintError("\aERROR : Input audio file is not specified (%ld)\n",
1307 __LINE__);
1308 error = THP_ERROR_DATA;
1309 goto ERROR_END;
1310 }
1311
1312 frameHeader.comp[compCnt] = THPAudioGetFrameSize(audioHandleList[0], i);
1313
1314 rtn = THPUtyWriteAudioOneFrame(op,
1315 fileHeader,
1316 audioHandleList,
1317 frameHeader.comp[compCnt],
1318 i);
1319 if (rtn != THP_ERROR_NOERROR)
1320 {
1321 THPPrintError("\aERROR : Can't write audio data (%ld)\n", __LINE__);
1322 error = rtn;
1323 goto ERROR_END;
1324 }
1325
1326 frameSize +=
1327 frameHeader.comp[compCnt] * fileHeader->audioInfo.sndNumTracks;
1328
1329 break;
1330
1331 case THP_NOCOMP_COMP:
1332 THPPrintError("\aERROR : Strange numComponents (%ld)\n", __LINE__);
1333 error = THP_ERROR_DATA;
1334 goto ERROR_END;
1335 break;
1336
1337 default:
1338 THPPrintError("\aERROR : Unsupported Components (%ld)\n", __LINE__);
1339 error = THP_ERROR_DATA;
1340 goto ERROR_END;
1341 break;
1342 }
1343 }
1344
1345 // 32Byte alignment
1346 if (frameSize % 32)
1347 {
1348 u32 remain = 32 - (frameSize % 32);
1349 rtn = fwrite(tempZero, remain, 1, op);
1350 if (rtn != 1)
1351 {
1352 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
1353 error = THP_ERROR_FILEIO;
1354 goto ERROR_END;
1355 }
1356 frameSize += remain;
1357 }
1358
1359 // Get Current file position
1360 currPos = ftell(op);
1361 if (currPos == -1)
1362 {
1363 THPPrintError("\aERROR : ftell error (%ld)\n", __LINE__);
1364 error = THP_ERROR_FILEIO;
1365 goto ERROR_END;
1366 }
1367
1368 rtn = fseek(op, frameOffsetData[i], SEEK_SET);
1369 if (rtn != 0)
1370 {
1371 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1372 error = THP_ERROR_FILEIO;
1373 goto ERROR_END;
1374 }
1375
1376 rtn = THPUtyWriteTHPFrameHeader(op, &fileHeader->frameCompInfo, &frameHeader);
1377 if (rtn != THP_ERROR_NOERROR)
1378 {
1379 THPPrintError("\aERROR : Can't write THPFrameHeader (%ld)\n", __LINE__);
1380 error = rtn;
1381 goto ERROR_END;
1382 }
1383
1384 if (i == 0)
1385 {
1386 frameSizeFirst = frameSize;
1387 }
1388 else
1389 {
1390 // Update Previous THPFrameHeader.frameSizeNext
1391 rtn = fseek(op, frameOffsetData[i - 1], SEEK_SET);
1392 if (rtn != 0)
1393 {
1394 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1395 error = THP_ERROR_FILEIO;
1396 goto ERROR_END;
1397 }
1398 rtn = THPUtyPutU32(op, frameSize);
1399 if (rtn != THP_ERROR_NOERROR)
1400 {
1401 THPPrintError("\aERROR : Can't write frameSizeNext (%ld)\n", __LINE__);
1402 error = rtn;
1403 goto ERROR_END;
1404 }
1405 }
1406
1407 // Seek next frame top
1408 rtn = fseek(op, currPos, SEEK_SET);
1409 if (rtn != 0)
1410 {
1411 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1412 error = THP_ERROR_FILEIO;
1413 goto ERROR_END;
1414 }
1415
1416 if (frameSize > frameSizeMax)
1417 {
1418 frameSizeMax = frameSize;
1419 }
1420 frameSizePrevious = frameSize;
1421 movieDataSize += frameSize;
1422 }
1423
1424 THPPrint(" << THP Packing END >> \n");
1425 THPPrintLog("END : Write THP Frame Datas.\n");
1426
1427 //
1428 // update THPFrameHeader.frameSizeNext for the final frame
1429 //
1430
1431 rtn = fseek(op, frameOffsetData[NumFrames - 1], SEEK_SET);
1432 if (rtn != 0)
1433 {
1434 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1435 error = THP_ERROR_FILEIO;
1436 goto ERROR_END;
1437 }
1438
1439 rtn = THPUtyPutU32(op, frameSizeFirst);
1440 if (rtn != THP_ERROR_NOERROR)
1441 {
1442 THPPrintError("\aERROR : Can't write frameSizeNext (%ld)\n", __LINE__);
1443 error = rtn;
1444 goto ERROR_END;
1445 }
1446
1447 //
1448 // update THPFileHeader
1449 //
1450
1451 // Setup THPHeader
1452 fileHeader->header.version = THP_VERSION;
1453 fileHeader->header.bufSize = frameSizeMax;
1454 fileHeader->header.firstFrameSize = frameSizeFirst;
1455 fileHeader->header.movieDataSize = movieDataSize;
1456 fileHeader->header.finalFrameDataOffsets = frameOffsetData[NumFrames -1];
1457 fileHeader->header.movieDataOffsets = frameOffsetData[0];
1458
1459 // Setup THPVideoInfo
1460 if (fileFlag == THP_CREATETHP_FILEFLAG_JPEGS)
1461 {
1462 fileHeader->videoInfo.xSize = imageStatus.xSize;
1463 fileHeader->videoInfo.ySize = imageStatus.ySize;
1464 }
1465
1466 // Update THPHeader, THFrameCompInfo, THPVideoInfo, THPAudioInfo
1467 rtn = THPUtyWriteTHPFileHeader(op, fileHeader, NULL);
1468 if (rtn != THP_ERROR_NOERROR)
1469 {
1470 THPPrintError("\aERROR : Can't write THPFileHeader (%ld)\n", __LINE__);
1471 error = rtn;
1472 goto ERROR_END;
1473 }
1474
1475 //
1476 // update THPFrameHeader.frameSizePrevious for the first frame
1477 //
1478
1479 rtn = fseek(op, fileHeader->header.movieDataOffsets + sizeof(u32), SEEK_SET);
1480 if (rtn != 0)
1481 {
1482 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1483 error = THP_ERROR_FILEIO;
1484 goto ERROR_END;
1485 }
1486 rtn = THPUtyPutU32(op, frameSize);
1487 if (rtn != THP_ERROR_NOERROR)
1488 {
1489 THPPrintError("\aERROR : Can't write frameSizePrevious (%ld)\n", __LINE__);
1490 error = rtn;
1491 goto ERROR_END;
1492 }
1493
1494 //
1495 // write offset data
1496 //
1497
1498 if (fileHeader->header.offsetDataOffsets)
1499 {
1500 THPPrintLog("START: Write THP Offset Data.\n");
1501 THPPrint(" << Put Offset Data >>\n");
1502
1503 // frameOffsetData adjusts the value as it is the offset from the header of movidData.
1504 for (i = 1; i < NumFrames; i++)
1505 {
1506 frameOffsetData[i]
1507 = THPUtyReverseEndianU32(frameOffsetData[i] - frameOffsetData[0]);
1508 }
1509 frameOffsetData[NumFrames] = THPUtyReverseEndianU32(movieDataSize);
1510
1511 // Update THPFrameOffsetData
1512 rtn = fseek(op, fileHeader->header.offsetDataOffsets, SEEK_SET);
1513 if (rtn != 0)
1514 {
1515 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1516 error = THP_ERROR_FILEIO;
1517 goto ERROR_END;
1518 }
1519
1520 rtn = fwrite(&frameOffsetData[1], sizeof(u32) * NumFrames, 1, op);
1521 if (rtn != 1)
1522 {
1523 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
1524 error = THP_ERROR_FILEIO;
1525 goto ERROR_END;
1526 }
1527
1528 THPPrintLog("END : Write THP Offset Data.\n");
1529 }
1530
1531 ERROR_END:
1532
1533 if (frameOffsetData != NULL)
1534 {
1535 THPFree(frameOffsetData);
1536 frameOffsetData = NULL;
1537 }
1538
1539 return error;
1540 }
1541
1542 /*---------------------------------------------------------------------------*
1543 Name: THPUtyChangeAudioTrack
1544
1545 Description: Replaces the audio track for the THP file specified by iop with the audio
1546 specified by audioHandleList.
1547
1548 Arguments: iop a file pointer to the THPO file whose audio will be replaced
1549 fileHeader a pointer to the THPFileHeader storing the THP header information
1550 audioHandleList a list of pointers for handles for the replacement audio
1551 There must be as many arrays as the value in fileHeader.audioInfo.sndNumTracks, with
1552 NULL in arrays corresponding to tracks that are not to be replaced.
1553
1554 Returns: THP_ERROR_NOERROR -- normal completion
1555 THP_ERROR_FILEIO file read/write failure
1556 THP_ERROR_THPFILE THP file error
1557 *---------------------------------------------------------------------------*/
THPUtyChangeAudioTrack(FILE * iop,THPFileHeader * fileHeader,THPAudioHandle ** audioHandleList)1558 s32 THPUtyChangeAudioTrack(FILE* iop, THPFileHeader* fileHeader,
1559 THPAudioHandle** audioHandleList)
1560 {
1561 s32 rtn;
1562 s32 error = THP_ERROR_NOERROR;
1563 u32 i;
1564 u32 frameHeaderSize;
1565
1566 // checks the existence of the audio track
1567 if ((fileHeader->audioInfo.sndChannels == 0) || (fileHeader->audioInfo.sndFrequency == 0))
1568 {
1569 THPPrintError("\aERROR : This file doesn't have audio data (%ld)\n", __LINE__);
1570 error = THP_ERROR_THPFILE;
1571 goto ERROR_END;
1572 }
1573
1574 // moves to the first frame
1575 rtn = fseek(iop, fileHeader->header.movieDataOffsets, SEEK_SET);
1576 if (rtn != 0)
1577 {
1578 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1579 error = THP_ERROR_FILEIO;
1580 goto ERROR_END;
1581 }
1582
1583 // gets the size of the frame header
1584 frameHeaderSize
1585 = sizeof(u32) * fileHeader->frameCompInfo.numComponents + sizeof(u32) * 2;
1586
1587 THPPrintLog("START: Write THP Frame Datas.\n");
1588 if (THPVerboseFlag == 0)
1589 {
1590 THPPrint(" << THP Restructuring START >>\r");
1591 }
1592 else
1593 {
1594 THPPrint(" << THP Restructuring START >>\n");
1595 }
1596
1597 //
1598 // replaces the audio data for each frame
1599 //
1600
1601 for (i = 0; i < fileHeader->header.numFrames; i++)
1602 {
1603 THPFrameHeader frameHeader;
1604 u32 compCnt;
1605 s32 framePos;
1606 u32 frameSize;
1607
1608 if (THPVerboseFlag == 0)
1609 {
1610 THPPrint(" Now Restructuring: No.%5ld/%5ld\r", i, fileHeader->header.numFrames);
1611 }
1612 else
1613 {
1614 THPPrint(" Now Restructuring: No.%5ld/%5ld\n", i, fileHeader->header.numFrames);
1615 }
1616
1617 // gets the current file position
1618 framePos = ftell(iop);
1619 if (framePos == -1)
1620 {
1621 THPPrintError("\aERROR : ftell error (%ld)\n", __LINE__);
1622 error = THP_ERROR_FILEIO;
1623 goto ERROR_END;
1624 }
1625
1626 // gets THPFrameHeader
1627 rtn = THPUtyReadTHPFrameHeader(iop,
1628 &frameHeader,
1629 fileHeader->frameCompInfo.numComponents);
1630 if (rtn != THP_ERROR_NOERROR)
1631 {
1632 THPPrintError("\aERROR : Can't read THPFrameHeader (%ld)\n", __LINE__);
1633 error = rtn;
1634 goto ERROR_END;
1635 }
1636
1637 frameSize = frameHeaderSize;
1638
1639 for (compCnt = 0; compCnt < fileHeader->frameCompInfo.numComponents; compCnt++)
1640 {
1641
1642 switch (fileHeader->frameCompInfo.frameComp[compCnt])
1643 {
1644 case THP_VIDEO_COMP:
1645
1646 // video data is skipped
1647 rtn = fseek(iop, frameHeader.comp[compCnt], SEEK_CUR);
1648 if (rtn != 0)
1649 {
1650 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1651 error = THP_ERROR_FILEIO;
1652 goto ERROR_END;
1653 }
1654 frameSize += frameHeader.comp[compCnt];
1655 break;
1656
1657 case THP_AUDIO_COMP:
1658
1659 // audio data is overwritten
1660 rtn = THPUtyWriteAudioOneFrame(iop,
1661 fileHeader,
1662 audioHandleList,
1663 frameHeader.comp[compCnt],
1664 i);
1665 if (rtn != THP_ERROR_NOERROR)
1666 {
1667 THPPrintError("\aERROR : Can't write audio data (%ld)\n", __LINE__);
1668 error = rtn;
1669 goto ERROR_END;
1670 }
1671 frameSize +=
1672 frameHeader.comp[compCnt] * fileHeader->audioInfo.sndNumTracks;
1673 break;
1674
1675 case THP_NOCOMP_COMP:
1676 THPPrintError("\aERROR : Strange numComponents (%ld)\n", __LINE__);
1677 error = THP_ERROR_THPFILE;
1678 goto ERROR_END;
1679 break;
1680
1681 default:
1682 THPPrintError("\aERROR : Unsupported Components (%ld)\n", __LINE__);
1683 error = THP_ERROR_THPFILE;
1684 goto ERROR_END;
1685 break;
1686 }
1687 }
1688
1689 // moves to the next frame
1690 frameSize = (frameSize + 31) & ~31;
1691 rtn = fseek(iop, framePos + frameSize, SEEK_SET);
1692 if (rtn != 0)
1693 {
1694 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1695 error = THP_ERROR_FILEIO;
1696 goto ERROR_END;
1697 }
1698 }
1699
1700 THPPrint(" << THP Restructuring END >> \n");
1701 THPPrintLog("END : Write THP Frame Datas.\n");
1702
1703 ERROR_END:
1704
1705 return error;
1706 }
1707
1708 /*---------------------------------------------------------------------------*
1709 Name: THPUtyCopyTHPFile
1710
1711 Description: copies the THP file specified by ip to op
1712
1713 Arguments: ip a file pointer to the source THP file
1714 fileHeader a pointer to the THPFileHeader
1715 op a file pointer to the target THP file
1716
1717 Returns: THP_ERROR_NOERROR -- normal completion
1718 THP_ERROR_FILEIO file read/write failure
1719 THP_ERROR_DATA data error
1720 THP_ERROR_FATAL memory allocation failure
1721 *---------------------------------------------------------------------------*/
1722 #define THPUTY_COPY_SIZE 0x100000
1723 #define THPUTY_MAX_PADDING_SIZE 32
1724
THPUtyCopyTHPFile(FILE * ip,THPFileHeader * fileHeader,FILE * op)1725 s32 THPUtyCopyTHPFile(FILE* ip, THPFileHeader* fileHeader, FILE* op)
1726 {
1727 s32 rtn;
1728 s32 error = THP_ERROR_NOERROR;
1729 u8* tmp_buffer = NULL;
1730 u32* frame_offsets = NULL;
1731
1732 //
1733 // when the source THP file is version 1.10 or later
1734 //
1735
1736 if (fileHeader->header.version > 0x10000)
1737 {
1738 u32 file_size;
1739 u32 read_size;
1740 u32 wrote_size = 0;
1741
1742 // allocates a temporary buffer
1743 tmp_buffer = (u8*)THPMalloc(THPUTY_COPY_SIZE);
1744 if (tmp_buffer == NULL)
1745 {
1746 THPPrintError("\aERROR : Can't allocate memory (%ld Bytes) (%ld)\n",
1747 THPUTY_COPY_SIZE, __LINE__);
1748 error = THP_ERROR_FATAL;
1749 goto ERROR_END;
1750 }
1751
1752 // gets the file size
1753 rtn = fseek(ip, 0, SEEK_END);
1754 if (rtn != 0)
1755 {
1756 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1757 error = THP_ERROR_FILEIO;
1758 goto ERROR_END;
1759 }
1760
1761 file_size = ftell(ip);
1762 if (file_size == -1L)
1763 {
1764 THPPrintError("\aERROR : ftell error (%ld)\n", __LINE__);
1765 error = THP_ERROR_FILEIO;
1766 goto ERROR_END;
1767 }
1768
1769 rtn = fseek(ip, 0, SEEK_SET);
1770 if (rtn != 0)
1771 {
1772 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1773 error = THP_ERROR_FILEIO;
1774 goto ERROR_END;
1775 }
1776
1777 // copies the file as is
1778 while (wrote_size < file_size)
1779 {
1780 if (file_size - wrote_size < THPUTY_COPY_SIZE)
1781 {
1782 read_size = file_size - wrote_size;
1783 }
1784 else
1785 {
1786 read_size = THPUTY_COPY_SIZE;
1787 }
1788
1789 rtn = fread(tmp_buffer, read_size, 1, ip);
1790 if(rtn != 1)
1791 {
1792 THPPrintError("\aERROR : fread error (%ld)", __LINE__);
1793 error = THP_ERROR_FILEIO;
1794 goto ERROR_END;
1795 }
1796
1797 rtn = fwrite(tmp_buffer, read_size, 1, op);
1798 if(rtn != 1)
1799 {
1800 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
1801 error = THP_ERROR_FILEIO;
1802 goto ERROR_END;
1803 }
1804
1805 wrote_size += read_size;
1806 }
1807
1808 if (fileHeader->header.offsetDataOffsets)
1809 {
1810 THPPrint(" << Put Offset Data >>\n");
1811 }
1812 }
1813
1814 //
1815 // when the source THP file is version 1.00 or older
1816 //
1817
1818 else
1819 {
1820 u32 ii, jj;
1821 u32 num_frames;
1822 s32 compinfo_size;
1823 u32 old_size;
1824 u32 frame_size;
1825 u32 prev_size = 0;
1826 u32 first_size;
1827 u32 max_size = 0;
1828 u32 total_size = 0;
1829 u32 remain;
1830 u32 tmp_loc;
1831 u8 zero_buffer[THPUTY_MAX_PADDING_SIZE];
1832
1833 THPFrameHeader* frame_header;
1834
1835 // moves the file pointer to the first frame data
1836 rtn = fseek(ip, fileHeader->header.movieDataOffsets, SEEK_SET);
1837 if (rtn != 0)
1838 {
1839 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1840 error = THP_ERROR_FILEIO;
1841 goto ERROR_END;
1842 }
1843
1844 //
1845 // THPFileHeader is read
1846 //
1847 rtn = THPUtyWriteTHPFileHeader(op, fileHeader, &compinfo_size);
1848 if (rtn != THP_ERROR_NOERROR)
1849 {
1850 THPPrintError("\aERROR : Can't write THPFileHeader (%ld)\n", __LINE__);
1851 error = rtn;
1852 goto ERROR_END;
1853 }
1854
1855 //
1856 // A dummy write of the offset value. The actual offset value is written last.
1857 //
1858 // NB: the offset data is an offset array from the second frame to the end of the last frame;
1859 // however, procedurally, the array is set up from the first frame. When written,
1860 // it goes from the second frame.
1861 //
1862
1863 // gets the number of frames
1864 num_frames = fileHeader->header.numFrames;
1865
1866 frame_offsets = (u32*)THPMalloc(sizeof(u32) * (num_frames + 1));
1867 if (frame_offsets == NULL)
1868 {
1869 THPPrintError("\aERROR : Can't allocate memory (%ld Bytes) (%ld)\n",
1870 sizeof(u32) * (num_frames + 1), __LINE__);
1871 error = THP_ERROR_FATAL;
1872 goto ERROR_END;
1873 }
1874
1875 if (fileHeader->header.offsetDataOffsets)
1876 {
1877 fileHeader->header.offsetDataOffsets
1878 = fileHeader->header.compInfoDataOffsets
1879 + sizeof(THPFrameCompInfo)
1880 + compinfo_size;
1881 rtn = fwrite(frame_offsets, sizeof(u32) * num_frames, 1, op);
1882 if (rtn != 1)
1883 {
1884 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
1885 error = THP_ERROR_FILEIO;
1886 goto ERROR_END;
1887 }
1888 }
1889
1890 //
1891 // all frame data is written
1892 //
1893
1894 // initializes the padding data
1895 memset(zero_buffer, 0, sizeof(zero_buffer));
1896
1897 // gets the old size of the first frame
1898 old_size = fileHeader->header.firstFrameSize;
1899
1900 for (ii = 0; ii < num_frames; ii++)
1901 {
1902 // gets the offset information
1903 frame_offsets[ii] = (u32)ftell(op);
1904 if (frame_offsets[ii] == 0xFFFFFFFF)
1905 {
1906 THPPrintError("\aERROR : ftell error (%ld)\n", __LINE__);
1907 error = THP_ERROR_FILEIO;
1908 goto ERROR_END;
1909 }
1910
1911 // allocates a region for reading
1912 tmp_buffer = THPMalloc(old_size + THPUTY_MAX_PADDING_SIZE);
1913 if (tmp_buffer == NULL)
1914 {
1915 THPPrintError("\aERROR : Can't allocate memory (%ld Bytes) (%ld)\n",
1916 (old_size + THPUTY_MAX_PADDING_SIZE), __LINE__);
1917 error = THP_ERROR_FATAL;
1918 goto ERROR_END;
1919 }
1920
1921 // reading the frame data
1922 rtn = fread(tmp_buffer, old_size, 1, ip);
1923 if (rtn != 1)
1924 {
1925 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
1926 error = THP_ERROR_FILEIO;
1927 goto ERROR_END;
1928 }
1929
1930 // gets the frame size without padding
1931 frame_header = (THPFrameHeader *)tmp_buffer;
1932 frame_size = sizeof(u32) * (2 + fileHeader->frameCompInfo.numComponents);
1933 for (jj = 0; jj < fileHeader->frameCompInfo.numComponents; jj++)
1934 {
1935 frame_size += THPUtyReverseEndianU32(frame_header->comp[jj]);
1936 }
1937
1938 // gets the size of the next frame
1939 old_size = THPUtyReverseEndianU32(frame_header->frameSizeNext);
1940
1941 // updates the frame header (1) - frameSizePrevious
1942 frame_header->frameSizePrevious = THPUtyReverseEndianU32(prev_size);
1943
1944 // writes the frame data
1945 rtn = fwrite(tmp_buffer, frame_size, 1, op);
1946 if (rtn != 1)
1947 {
1948 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
1949 error = THP_ERROR_FILEIO;
1950 goto ERROR_END;
1951 }
1952
1953 // re-padding
1954 if (frame_size % 32)
1955 {
1956 remain = 32 - (frame_size % 32);
1957 rtn = fwrite(zero_buffer, remain, 1, op);
1958 if (rtn != 1)
1959 {
1960 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
1961 error = THP_ERROR_FILEIO;
1962 goto ERROR_END;
1963 }
1964 frame_size += remain;
1965 }
1966
1967 // deallocates a region for reading
1968 THPFree(tmp_buffer);
1969 tmp_buffer = NULL;
1970
1971 // updates the frame header (2) - frameSizeNext
1972 if (ii != 0)
1973 {
1974 tmp_loc = ftell(op);
1975
1976 // rewind the file pointer to the header of the previous frame data
1977 rtn = fseek(op, frame_offsets[ii - 1], SEEK_SET);
1978 if (rtn != 0)
1979 {
1980 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1981 error = THP_ERROR_FILEIO;
1982 goto ERROR_END;
1983 }
1984
1985 // write the current frame size (frameSizeNext is the header)
1986 rtn = THPUtyPutU32(op, frame_size);
1987 if (rtn != THP_ERROR_NOERROR)
1988 {
1989 THPPrintError("\aERROR : Can't write frameSizeNext (%ld)\n", __LINE__);
1990 error = rtn;
1991 goto ERROR_END;
1992 }
1993
1994 // return the file pointer to the end of the current frame data
1995 rtn = fseek(op, tmp_loc, SEEK_SET);
1996 if (rtn != 0)
1997 {
1998 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
1999 error = THP_ERROR_FILEIO;
2000 goto ERROR_END;
2001 }
2002 }
2003
2004 // size inheritance
2005 prev_size = frame_size;
2006
2007 // update first size, reflecting it to THPHeader.firstFrameSize
2008 if (ii == 0)
2009 {
2010 first_size = frame_size;
2011 }
2012
2013 // update max size, reflecting it to THPHeader.bufSize
2014 if (frame_size > max_size)
2015 {
2016 max_size = frame_size;
2017 }
2018
2019 // update total size, reflecting it to THPHeader.movieDataSize
2020 total_size += frame_size;
2021 }
2022
2023 //
2024 // update THPFrameHeader.frameSizePrevious for the first frame
2025 //
2026
2027 rtn = fseek(op, frame_offsets[0] + sizeof(u32), SEEK_SET);
2028 if (rtn != 0)
2029 {
2030 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
2031 error = THP_ERROR_FILEIO;
2032 goto ERROR_END;
2033 }
2034
2035 rtn = THPUtyPutU32(op, frame_size);
2036 if (rtn != THP_ERROR_NOERROR)
2037 {
2038 THPPrintError("\aERROR : Can't write frameSizePrevious (%ld)\n", __LINE__);
2039 error = rtn;
2040 goto ERROR_END;
2041 }
2042
2043 //
2044 // update THPFrameHeader.frameSizeNext for the final frame
2045 //
2046
2047 rtn = fseek(op, frame_offsets[num_frames - 1], SEEK_SET);
2048 if (rtn != 0)
2049 {
2050 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
2051 error = THP_ERROR_FILEIO;
2052 goto ERROR_END;
2053 }
2054
2055 rtn = THPUtyPutU32(op, first_size);
2056 if (rtn != THP_ERROR_NOERROR)
2057 {
2058 THPPrintError("\aERROR : Can't write frameSizeNext (%ld)\n", __LINE__);
2059 error = rtn;
2060 goto ERROR_END;
2061 }
2062
2063 //
2064 // update THPHeader
2065 //
2066
2067 fileHeader->header.version = THP_VERSION;
2068 fileHeader->header.bufSize = max_size;
2069 fileHeader->header.firstFrameSize = first_size;
2070 fileHeader->header.movieDataSize = total_size;
2071 fileHeader->header.movieDataOffsets = frame_offsets[0];
2072 fileHeader->header.finalFrameDataOffsets = frame_offsets[num_frames -1];
2073
2074 rtn = THPUtyWriteTHPFileHeader(op, fileHeader, NULL);
2075 if (rtn != THP_ERROR_NOERROR)
2076 {
2077 THPPrintError("\aERROR : Can't write THPFileHeader (%ld)\n", __LINE__);
2078 error = rtn;
2079 goto ERROR_END;
2080 }
2081
2082 //
2083 // writes the offset data
2084 //
2085
2086 if (fileHeader->header.offsetDataOffsets)
2087 {
2088 THPPrint(" << Put Offset Data >>\n");
2089
2090 // the offset data for each frame is the offset value from the first frame
2091 for (ii = 1; ii < num_frames; ii++)
2092 {
2093 frame_offsets[ii]
2094 = THPUtyReverseEndianU32(frame_offsets[ii] - frame_offsets[0]);
2095 }
2096 frame_offsets[num_frames] = THPUtyReverseEndianU32(total_size);
2097
2098 rtn = fseek(op, fileHeader->header.offsetDataOffsets, SEEK_SET);
2099 if (rtn != 0)
2100 {
2101 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
2102 error = THP_ERROR_FILEIO;
2103 goto ERROR_END;
2104 }
2105
2106 rtn = fwrite(&frame_offsets[1], sizeof(u32) * num_frames, 1, op);
2107 if (rtn != 1)
2108 {
2109 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
2110 error = THP_ERROR_FILEIO;
2111 goto ERROR_END;
2112 }
2113 }
2114 }
2115
2116 ERROR_END:
2117
2118 if (tmp_buffer)
2119 {
2120 THPFree(tmp_buffer);
2121 }
2122
2123 if (frame_offsets)
2124 {
2125 THPFree(frame_offsets);
2126 }
2127
2128 return error;
2129 }
2130
2131 /*---------------------------------------------------------------------------*
2132 *---------------------------------------------------------------------------*
2133 * Local Functions *
2134 *---------------------------------------------------------------------------*
2135 *---------------------------------------------------------------------------*/
2136 /*---------------------------------------------------------------------------*
2137 Name: THPUtyWriteVideoOneFrame
2138
2139 Description: Reads the JPG file specified by fileName, converts it to THP format, and outputs
2140 it to the file specified by thpFp.
2141
2142 Arguments: thpFp a file pointer to the THP file to be output
2143 fileName the file name for the JPG file to be converted
2144 imageStatus a pointer to the THPImageStatus structure storing the converted image information
2145
2146 Returns: THP_ERROR_NOERROR -- normal completion
2147 THP_ERROR_FILEIO file read/write failure
2148 THP_ERROR_JPEGFILE JPG file error
2149 THP_ERROR_FATAL memory allocation failure
2150 *---------------------------------------------------------------------------*/
THPUtyWriteVideoOneFrame(FILE * thpFp,THPFileName * fileName,THPImageStatus * imageStatus)2151 static s32 THPUtyWriteVideoOneFrame(FILE* thpFp, THPFileName* fileName,
2152 THPImageStatus* imageStatus)
2153 {
2154 FILE* jpegFp = NULL;
2155 u8* jpegBuffer = NULL;
2156 u8* thpBuffer = NULL;
2157 s32 error = THP_ERROR_NOERROR;
2158 s32 rtn;
2159
2160 jpegBuffer = (u8*)THPMalloc(fileName->fileSize);
2161 if (jpegBuffer == NULL)
2162 {
2163 THPPrintError("\aERROR : Can't allocate memory (%ld Bytes) (%ld)\n",
2164 fileName->fileSize, __LINE__);
2165 error = THP_ERROR_FATAL;
2166 goto ERROR_END;
2167 }
2168
2169 thpBuffer = (u8*)THPMalloc(fileName->fileSize * 2);
2170 if (thpBuffer == NULL)
2171 {
2172 THPPrintError("\aERROR : Can't allocate memory (%ld Bytes) (%ld)\n",
2173 fileName->fileSize * 2, __LINE__);
2174 error = THP_ERROR_FATAL;
2175 goto ERROR_END;
2176 }
2177
2178 jpegFp = fopen(fileName->name, "rb");
2179 if (jpegFp == NULL)
2180 {
2181 THPPrintError("\aERROR : Can't open [%s] file (%ld)\n", fileName->name, __LINE__);
2182 error = THP_ERROR_FILEIO;
2183 goto ERROR_END;
2184 }
2185
2186 rtn = fread(jpegBuffer, fileName->fileSize, 1, jpegFp);
2187 if (rtn != 1)
2188 {
2189 THPPrintError("\aERROR : fread error (%ld)", __LINE__);
2190 error = THP_ERROR_FILEIO;
2191 goto ERROR_END;
2192 }
2193
2194 fclose(jpegFp);
2195 jpegFp = NULL;
2196
2197 rtn = THPConvertJPEG2THP(jpegBuffer, thpBuffer, fileName->fileSize, imageStatus);
2198 if (rtn != THP_ERROR_NOERROR)
2199 {
2200 THPPrintError("\aERROR : Can't convert [%s] file to THP (%ld)\n",
2201 fileName->name, __LINE__);
2202 error = rtn;
2203 goto ERROR_END;
2204 }
2205
2206 while (imageStatus->imageSize % 4)
2207 {
2208 *(thpBuffer + imageStatus->imageSize) = 0x00;
2209 imageStatus->imageSize++;
2210 }
2211
2212 rtn = fwrite(thpBuffer, imageStatus->imageSize, 1, thpFp);
2213 if (rtn != 1)
2214 {
2215 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
2216 error = THP_ERROR_FILEIO;
2217 goto ERROR_END;
2218 }
2219
2220 ERROR_END:
2221
2222 if (jpegBuffer != NULL)
2223 {
2224 THPFree(jpegBuffer);
2225 }
2226
2227 if (thpBuffer != NULL)
2228 {
2229 THPFree(thpBuffer);
2230 }
2231
2232 if (jpegFp != NULL)
2233 {
2234 fclose(jpegFp);
2235 }
2236
2237 return error;
2238 }
2239
2240 /*---------------------------------------------------------------------------*
2241 Name: THPUtyWriteAudioOneFrame
2242
2243 Description: Encodes the first frame's worth of multiple audio specified by audioHandleList and
2244 outputs it to the file specified by thpFp.
2245 Only the frameSize portion is sought for NULL array elements in the audioHandleList.
2246
2247 Arguments: thpFp a file pointer to the THP file to be output
2248 fileHeader a pointer to the THPFileHeader
2249 audioHandleList a pointer array for THPAudioHandle
2250 The array number must be as in fileHeader.audioInfo.sndNumTracks.
2251 frameSize the size of the audio for the first frame
2252 frameNum the frame number
2253
2254 Returns: THP_ERROR_NOERROR -- normal completion
2255 THP_ERROR_FILEIO -- file output failed
2256 *---------------------------------------------------------------------------*/
THPUtyWriteAudioOneFrame(FILE * thpFp,THPFileHeader * fileHeader,THPAudioHandle ** audioHandleList,u32 frameSize,u32 frameNum)2257 static s32 THPUtyWriteAudioOneFrame(FILE* thpFp, THPFileHeader* fileHeader,
2258 THPAudioHandle** audioHandleList,
2259 u32 frameSize,
2260 u32 frameNum)
2261 {
2262 u32 cnt;
2263 u32 flag;
2264 s32 error = THP_ERROR_NOERROR;
2265
2266 flag = (frameNum == (fileHeader->header.numFrames - 1)) ? 1 : 0;
2267
2268 for (cnt = 0; cnt < fileHeader->audioInfo.sndNumTracks; cnt++)
2269 {
2270 if (audioHandleList[cnt] == NULL)
2271 {
2272 u32 rtn;
2273
2274 rtn = fseek(thpFp, frameSize, SEEK_CUR);
2275 if (rtn != 0)
2276 {
2277 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
2278 error = THP_ERROR_FILEIO;
2279 goto ERROR_END;
2280 }
2281 }
2282 else
2283 {
2284 if (THPAudioWriteFrame(audioHandleList[cnt], thpFp, flag) == FALSE)
2285 {
2286 THPPrintError("\aERROR : Can't convert [%s] file to THP Audio (%ld)\n",
2287 audioHandleList[cnt]->audioInfo.fileName, __LINE__);
2288 error = THP_ERROR_FILEIO;
2289 goto ERROR_END;
2290 }
2291 }
2292 }
2293
2294 ERROR_END:
2295
2296 return error;
2297 }
2298
2299 /*---------------------------------------------------------------------------*
2300 Name: THPUtyCopyVideoFrame
2301
2302 Description: Copies the video data from the THP file specified by videoTHPFp to the file
2303 specified by thpFp.
2304
2305 Arguments: thpFp a file pointer to the video data target
2306 videoTHPFp a file pointer to the source video data
2307 videoFileHeader the header of the source THP file
2308 videoCompSize a pointer to the stored size of the copied video data
2309
2310 Returns: THP_ERROR_NOERROR -- normal completion
2311 THP_ERROR_FILEIO file read/write failure
2312 THP_ERROR_THPFILE THP file error
2313 THP_ERROR_FATAL memory allocation failure
2314 *---------------------------------------------------------------------------*/
THPUtyCopyVideoFrame(FILE * thpFp,FILE * videoTHPFp,THPFileHeader * videoFileHeader,u32 * videoCompSize)2315 static s32 THPUtyCopyVideoFrame(FILE* thpFp, FILE* videoTHPFp,
2316 THPFileHeader* videoFileHeader,
2317 u32* videoCompSize)
2318 {
2319 u8* buffer = NULL;
2320 u32 compCnt;
2321 s32 rtn;
2322 s32 error = THP_ERROR_NOERROR;
2323 u32 framePos;
2324 u32 frameSize;
2325 THPFrameHeader frameHeader;
2326
2327 framePos = ftell(videoTHPFp);
2328 if (framePos == -1)
2329 {
2330 THPPrintError("\aERROR : ftell error (%ld)\n", __LINE__);
2331 error = THP_ERROR_FILEIO;
2332 goto ERROR_END;
2333 }
2334
2335 rtn = THPUtyReadTHPFrameHeader(videoTHPFp,
2336 &frameHeader,
2337 videoFileHeader->frameCompInfo.numComponents);
2338 if (rtn != THP_ERROR_NOERROR)
2339 {
2340 THPPrintError("\aERROR : Can't read THPFrameHeader (%ld)\n", __LINE__);
2341 error = rtn;
2342 goto ERROR_END;
2343 }
2344
2345 frameSize
2346 = sizeof(u32) * videoFileHeader->frameCompInfo.numComponents + sizeof(u32) * 2;
2347
2348 for (compCnt = 0; compCnt < videoFileHeader->frameCompInfo.numComponents; compCnt++)
2349 {
2350 switch (videoFileHeader->frameCompInfo.frameComp[compCnt])
2351 {
2352 case THP_VIDEO_COMP:
2353
2354 buffer = (u8*)THPMalloc(frameHeader.comp[compCnt]);
2355 if (buffer == NULL)
2356 {
2357 THPPrintError("\aERROR : Can't allocate memory (%ld Bytes) (%ld)\n",
2358 frameHeader.comp[compCnt], __LINE__);
2359 error = THP_ERROR_FATAL;
2360 goto ERROR_END;
2361 }
2362
2363 rtn = fread(buffer, frameHeader.comp[compCnt], 1, videoTHPFp);
2364 if (rtn != 1)
2365 {
2366 THPPrintError("\aERROR : fread error (%ld)\n", __LINE__);
2367 error = THP_ERROR_FILEIO;
2368 goto ERROR_END;
2369 }
2370
2371 rtn = fwrite(buffer, frameHeader.comp[compCnt], 1, thpFp);
2372 if (rtn != 1)
2373 {
2374 THPPrintError("\aERROR : fwrite error (%ld)\n", __LINE__);
2375 error = THP_ERROR_FILEIO;
2376 goto ERROR_END;
2377 }
2378
2379 THPFree(buffer);
2380 buffer = NULL;
2381
2382 frameSize += frameHeader.comp[compCnt];
2383 if (videoCompSize != NULL)
2384 {
2385 *videoCompSize = frameHeader.comp[compCnt];
2386 }
2387 break;
2388
2389 case THP_AUDIO_COMP:
2390 frameSize +=
2391 frameHeader.comp[compCnt] * videoFileHeader->audioInfo.sndNumTracks;
2392 break;
2393
2394 case THP_NOCOMP_COMP:
2395 THPPrintError("\aERROR : Strange numComponents (%ld)\n", __LINE__);
2396 error = THP_ERROR_THPFILE;
2397 goto ERROR_END;
2398 break;
2399
2400 default:
2401 THPPrintError("\aERROR : Unsupported Components (%ld)\n", __LINE__);
2402 error = THP_ERROR_THPFILE;
2403 goto ERROR_END;
2404 break;
2405 }
2406 }
2407
2408 frameSize = (frameSize + 31) & ~31;
2409
2410 rtn = fseek(videoTHPFp, framePos + frameSize, SEEK_SET);
2411 if (rtn != 0)
2412 {
2413 THPPrintError("\aERROR : fseek error (%ld)\n", __LINE__);
2414 error = THP_ERROR_FILEIO;
2415 goto ERROR_END;
2416 }
2417
2418 ERROR_END:
2419
2420 if (buffer != NULL)
2421 {
2422 THPFree(buffer);
2423 buffer = NULL;
2424 }
2425
2426 return error;
2427 }
2428