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