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