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