1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - SSP - demos - jpegEncoder
3   File:     main.c
4 
5   Copyright 2007-2009 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   $Date:: 2009-04-27#$
14   $Rev: 10467 $
15   $Author: kitase_hirotake $
16  *---------------------------------------------------------------------------*/
17 #ifdef SDK_TWL
18 #include <twl.h>
19 #else
20 #include <nitro.h>
21 #endif
22 
23 // The output buffer and the JPEG file that is actually created have the same size
24 #define OUTPUT_DATA_SIZE 307200
25 
26 static u8 encodeOutputBuffer[OUTPUT_DATA_SIZE] ATTRIBUTE_ALIGN(4);
27 static u32 encodeOutputSize;
28 
29 #include <twl/ssp/ARM9/jpegenc.h>
30 #include <twl/ssp/ARM9/exifenc.h>
31 
32 
33 static u8* decodeOutputBuffer;
34 
35 #include <twl/ssp/ARM9/jpegdec.h>
36 #include <twl/ssp/ARM9/exifdec.h>
37 
38 #include "DEMO.h"
39 
40 static const char* sDebugMessageFunc[4] =
41 {
42     "SSP_StartJpegEncoder",
43     "SSP_StartJpegEncoderWithEncodeData",
44     "SSP_StartJpegEncoderLite",
45     "SSP_StartJpegEncoderFast"
46 };
47 
48 /*---------------------------------------------------------------------------*
49   Name:         MyAlloc
50 
51   Description:  OS_Alloc wrapper function.
52  *---------------------------------------------------------------------------*/
MyAlloc(u32 size)53 static void* MyAlloc(u32 size)
54 {
55     void* ptr;
56 
57     ptr = OS_Alloc(size);
58 
59     return ptr;
60 }
61 
62 /*---------------------------------------------------------------------------*
63   Name:         MyFree
64 
65   Description:  OS_Free wrapper function.
66  *---------------------------------------------------------------------------*/
MyFree(void * ptr)67 static void MyFree(void* ptr)
68 {
69     OS_Free(ptr);
70 }
71 
72 /*---------------------------------------------------------------------------*
73   Name:         InitializeAllocateSystem
74 
75   Description:  Initializes the memory allocation system within the main memory arena.
76 
77   Arguments:    None.
78 
79   Returns:      None.
80  *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)81 static void InitializeAllocateSystem(void)
82 {
83     void *tempLo;
84     OSHeapHandle hh;
85 
86     tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
87     OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
88     hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
89     if (hh < 0)
90     {
91         OS_Panic("ARM9: Fail to create heap...\n");
92     }
93     hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
94 }
95 
96 
97 /*---------------------------------------------------------------------------*/
98 /* Functions */
99 
100 /*---------------------------------------------------------------------------*
101   Name:         VBlankIntr
102 
103   Description:  VBlankIntr
104 
105   Arguments:    None.
106 
107   Returns:      None.
108  *---------------------------------------------------------------------------*/
VBlankIntr(void)109 static void VBlankIntr(void)
110 {
111     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
112 }
113 
114 /*---------------------------------------------------------------------------*
115   Name:         TwlMain / NitroMain
116 
117   Description:  Main.
118 
119   Arguments:    None.
120 
121   Returns:      None.
122  *---------------------------------------------------------------------------*/
123 #ifdef SDK_TWL
TwlMain(void)124 void TwlMain(void)
125 #else
126 void NitroMain(void)
127 #endif
128 {
129     int retryCount=0;
130 
131     /* OS initialization */
132     OS_Init();
133     OS_InitTick();
134     OS_InitAlarm();
135 
136     RTC_Init();
137 
138     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
139     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
140 
141     (void)OS_EnableIrq();
142     (void)GX_VBlankIntr(TRUE);
143 
144     (void)OS_EnableInterrupts();
145 
146     DEMOInitCommon();
147     DEMOInitVRAM();
148     DEMOInitDisplayBitmap();
149     DEMOHookConsole();
150     DEMOStartDisplay();
151 
152     // SD initialization
153     FS_Init( FS_DMA_NOT_USE );
154 
155     InitializeAllocateSystem();
156 
157     OS_TPrintf("\n");
158     OS_TPrintf("===================================\n");
159     OS_TPrintf("    SSP JpegEncoder Test\n");
160     OS_TPrintf("===================================\n");
161 
162     do
163     {
164         {
165             u8 *data;
166             u32 length;
167             FSFile file[1];
168 
169             u8 dateTime[20];
170 
171             OSTick jpegEncode_begin,jpegEncode_end;
172 
173             OS_TPrintf("Start Encode ...\n");
174 
175             jpegEncode_begin = OS_GetTick();
176 
177             {
178                 OSTick core_begin, core_end;
179                 u16* yuvBuf = NULL;
180                 u8* tmpBuf;
181 
182                 static char userData[32] ATTRIBUTE_ALIGN(32);
183 
184                 FS_InitFile(file);
185                 if( !FS_OpenFileEx(file, "rom:/rgb555.dat", FS_FILEMODE_R) )
186                 {
187                     OS_Panic("failed FS_OpenFileEx");
188                 }
189                 length = FS_GetFileLength(file);
190                 data = MyAlloc(length);
191                 if(data == 0)
192                 {
193                     OS_Panic("Cannot allocate memory ... data!");
194                 }
195                 if( FS_ReadFile(file, data, (s32)length) == -1)
196                 {
197                     OS_Panic("failed FS_ReadFile");
198                 }
199                 (void)FS_CloseFile(file);
200 
201                 {
202                     const u32 option = SSP_JPEG_THUMBNAIL | SSP_JPEG_RGB555;
203 
204                     MI_CpuFill8(userData, 0x10, 32);
205                     MI_CpuCopy8("USER_DATA", userData, 9);
206                     userData[9] = '\0';
207 
208                     SSP_SetJpegEncoderMakerNoteEx(SSP_MAKERNOTE_USER, (u8*)userData, 32);
209 
210                     if(retryCount < 2)
211                     {
212                         tmpBuf = (u8*)MyAlloc(SSP_GetJpegEncoderBufferSize(256,192,SSP_JPEG_OUTPUT_YUV422,option));
213                         OS_TPrintf("SSP_GetJpegEncoderBufferSize()=%d\n", SSP_GetJpegEncoderBufferSize(256,192,SSP_JPEG_OUTPUT_YUV422,option));
214                     }
215                     else if(retryCount == 2)
216                     {
217                         tmpBuf = (u8*)MyAlloc(SSP_GetJpegEncoderLiteBufferSize(option));
218                         OS_TPrintf("SSP_GetJpegEncoderLiteBufferSize()=%d\n", SSP_GetJpegEncoderLiteBufferSize(option));
219                     }
220                     else
221                     {
222                         tmpBuf = (u8*)MyAlloc(SSP_GetJpegEncoderFastBufferSize(option));
223                         OS_TPrintf("SSP_GetJpegEncoderFastBufferSize()=%d\n", SSP_GetJpegEncoderFastBufferSize(option));
224                     }
225 
226                     if ( !SSP_SetJpegEncoderDateTimeNow() )
227                     {
228                         MI_CpuFill8(dateTime, 0x00, 20);
229                         SSP_SetJpegEncoderDateTime(dateTime);
230                     }
231 
232                     core_begin = OS_GetTick();
233 
234                     switch (retryCount)
235                     {
236                     case 0:
237                         encodeOutputSize = SSP_StartJpegEncoder(data, encodeOutputBuffer, OUTPUT_DATA_SIZE, tmpBuf, 256, 192, 90, SSP_JPEG_OUTPUT_YUV422, option);
238                         MyFree(data);
239                         break;
240                     case 1:
241                         if(SSP_ConvertJpegEncodeData(data, tmpBuf, 256, 192, SSP_JPEG_OUTPUT_YUV422, option) == FALSE)
242                             OS_Panic("failed SSP_ConvertRGB555");
243                         MyFree(data);
244                         encodeOutputSize = SSP_StartJpegEncoderWithEncodeData(encodeOutputBuffer, OUTPUT_DATA_SIZE, tmpBuf, 256, 192, 90, SSP_JPEG_OUTPUT_YUV422, option);
245                         break;
246                     case 2:
247                         encodeOutputSize = SSP_StartJpegEncoderLite(data, encodeOutputBuffer, OUTPUT_DATA_SIZE, tmpBuf, 256, 192, 90, SSP_JPEG_OUTPUT_YUV422, option);
248                         MyFree(data);
249                         break;
250                     case 3:
251                         encodeOutputSize = SSP_StartJpegEncoderFast(data, encodeOutputBuffer, OUTPUT_DATA_SIZE, tmpBuf, 256, 192, 90, SSP_JPEG_OUTPUT_YUV422, option);
252                         MyFree(data);
253                         break;
254                     }
255 
256                     core_end = OS_GetTick();
257 
258                     OS_TPrintf("[TIMER] Core %s time[usec] = %d\n", sDebugMessageFunc[retryCount], OS_TicksToMicroSeconds(core_end - core_begin));
259 
260                     MyFree( tmpBuf );
261                 }
262             }
263 
264             jpegEncode_end = OS_GetTick();
265 
266             OS_TPrintf("[TIMER] %s time[usec] = %d\n", sDebugMessageFunc[retryCount], OS_TicksToMicroSeconds(jpegEncode_end - jpegEncode_begin));
267             OS_TPrintf("encodeOutputSize=%d\n", encodeOutputSize);
268         }
269 
270         {
271             s16 decode_file_width, decode_file_height;
272 
273             OSTick jpegDecode_begin,jpegDecode_end;
274             BOOL result;
275 
276             OS_TPrintf("Start Decode ... encodeOutputSize = %d\n", encodeOutputSize);
277 
278             jpegDecode_begin = OS_GetTick();
279 
280             decode_file_width = 256;
281             decode_file_height = 192;
282             decodeOutputBuffer = MyAlloc(decode_file_width * decode_file_height * sizeof(u16));
283 
284             result = SSP_StartJpegDecoder(encodeOutputBuffer, encodeOutputSize, decodeOutputBuffer, &decode_file_width, &decode_file_height, SSP_JPEG_RGB555);
285 
286             jpegDecode_end = OS_GetTick();
287 
288             if(result == 0)
289                 OS_Panic("Failed Cpu Decode\n");
290 
291             OS_TPrintf("[TIMER] MAIN SSP_StartJpegDecoder time[usec] = %d\n", OS_TicksToMicroSeconds(jpegDecode_end - jpegDecode_begin));
292             OS_TPrintf("[DEBUG] MAIN decode_file_width = %d : decode_file_height = %d\n", decode_file_width, decode_file_height);
293 
294             {
295                 int i,j;
296                 float i_step,j_step;
297                 int i_count,j_count;
298                 s16 t_width = decode_file_width;
299 
300                 j_step = (float)decode_file_width / 256;
301                 i_step = (float)decode_file_height / 192;
302 
303                 i_count = j_count = 0;
304                 for(i = 0; i < 192; i++)
305                 {
306                     for(j = 0; j < 256; j++)
307                     {
308                         *((u16*)((int)G2_GetBG3ScrPtr() + i*256*2 + j*2)) = *((u16*)((u32)decodeOutputBuffer + (u32)(i_count * decode_file_width*2) + (u32)(j_count*2)));
309                         j_count = (int)((double)j*j_step);
310                     }
311                     i_count=(int)((double)i*i_step);
312                 }
313             }
314 
315             // Try to display the date and time
316             {
317                 u8 dateTime[20];
318 
319                 (void)SSP_GetJpegDecoderDateTime(dateTime);
320                 OS_TPrintf("DateTimeOriginal = %s\n", dateTime);
321             }
322             {
323                 char software[30];
324                 u32 initialCode;
325 
326                 (void)SSP_GetJpegDecoderSoftware(software);
327                 // The Exif software tag contains a little-endian game code
328                 MI_CpuCopy8(software, &initialCode, 4);
329                 OS_TPrintf("InitialCode = %c%c%c%c\n", initialCode>>24, initialCode>>16, initialCode>>8, initialCode);
330             }
331             // Get the MakerNote address and size
332             {
333                 u8 *makerNotePhotoAddr = SSP_GetJpegDecoderMakerNoteAddrEx(SSP_MAKERNOTE_PHOTO);
334                 u16 makerNotePhotoSize = SSP_GetJpegDecoderMakerNoteSizeEx(SSP_MAKERNOTE_PHOTO);
335                 u8 *makerNoteUserAddr = SSP_GetJpegDecoderMakerNoteAddrEx(SSP_MAKERNOTE_USER);
336                 u16 makerNoteUserSize = SSP_GetJpegDecoderMakerNoteSizeEx(SSP_MAKERNOTE_USER);
337 
338                 OS_TPrintf("makerNotePhotoAddr = 0x%X\n", makerNotePhotoAddr);
339                 OS_TPrintf("makerNotePhotoSize = 0x%X\n", makerNotePhotoSize);
340                 OS_TPrintf("MakerNoteUserAddr = 0x%X\n", makerNoteUserAddr);
341                 OS_TPrintf("MakerNoteUserSize = 0x%X\n", makerNoteUserSize);
342             }
343             MyFree(decodeOutputBuffer);
344         }
345 
346         if(retryCount < 3)
347         {
348             OS_TPrintf("Press A button\n");
349             while(1)
350             {
351                 DEMOReadKey();
352                 if(DEMO_IS_PRESS(PAD_BUTTON_A))
353                 {
354                     retryCount++;
355                     break;
356                 }
357                 OS_WaitVBlankIntr();
358             }
359         }
360         else
361             retryCount++;
362     }while(retryCount < 4);
363     OS_TPrintf("\n");
364     OS_TPrintf("===================================\n");
365     OS_TPrintf("    End\n");
366     OS_TPrintf("===================================\n");
367     OS_Terminate();
368 }
369