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