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