1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - SSP - demos - jpegEncoder
3   File:     main.c
4 
5   Copyright 2007-2008 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:: 2008-12-08#$
14   $Rev: 9562 $
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                     tmpBuf = (u8*)MyAlloc(SSP_GetJpegEncoderBufferSize(256,192,SSP_JPEG_OUTPUT_YUV422,option));
203                     OS_TPrintf("SSP_GetJpegEncoderBufferSize()=%d\n", SSP_GetJpegEncoderBufferSize(256,192,SSP_JPEG_OUTPUT_YUV422,option));
204 
205                     if ( !SSP_SetJpegEncoderDateTimeNow() )
206                     {
207                         MI_CpuFill8(dateTime, 0x00, 20);
208                         SSP_SetJpegEncoderDateTime(dateTime);
209                     }
210 
211                     core_begin = OS_GetTick();
212 
213                     switch (retryCount)
214                     {
215                     case 0:
216                         encodeOutputSize = SSP_StartJpegEncoder(data, encodeOutputBuffer, OUTPUT_DATA_SIZE, tmpBuf, 256, 192, 90, SSP_JPEG_OUTPUT_YUV422, option);
217                         MyFree(data);
218                         break;
219                     case 1:
220                         if(SSP_ConvertJpegEncodeData(data, tmpBuf, 256, 192, SSP_JPEG_OUTPUT_YUV422, option) == FALSE)
221                             OS_Panic("failed SSP_ConvertRGB555");
222                         MyFree(data);
223                         encodeOutputSize = SSP_StartJpegEncoderWithEncodeData(encodeOutputBuffer, OUTPUT_DATA_SIZE, tmpBuf, 256, 192, 90, SSP_JPEG_OUTPUT_YUV422, option);
224                     }
225 
226                     core_end = OS_GetTick();
227 
228                     OS_TPrintf("[TIMER] Core SSP_StartJpegEncoder time[usec] = %d\n", OS_TicksToMicroSeconds(core_end - core_begin));
229 
230                     MyFree( tmpBuf );
231                 }
232             }
233 
234             jpegEncode_end = OS_GetTick();
235 
236             OS_TPrintf("[TIMER] SSP_StartJpegEncoder time[usec] = %d\n", OS_TicksToMicroSeconds(jpegEncode_end - jpegEncode_begin));
237             OS_TPrintf("encodeOutputSize=%d\n", encodeOutputSize);
238         }
239 
240         {
241             s16 decode_file_width, decode_file_height;
242 
243             OSTick jpegDecode_begin,jpegDecode_end;
244             BOOL result;
245 
246             OS_TPrintf("Start Decode ... encodeOutputSize = %d\n", encodeOutputSize);
247 
248             jpegDecode_begin = OS_GetTick();
249 
250             decode_file_width = 256;
251             decode_file_height = 192;
252             decodeOutputBuffer = MyAlloc(decode_file_width * decode_file_height * sizeof(u16));
253 
254             result = SSP_StartJpegDecoder(encodeOutputBuffer, encodeOutputSize, decodeOutputBuffer, &decode_file_width, &decode_file_height, SSP_JPEG_RGB555);
255 
256             jpegDecode_end = OS_GetTick();
257 
258             if(result == 0)
259                 OS_Panic("Failed Cpu Decode\n");
260 
261             OS_TPrintf("[TIMER] MAIN SSP_StartJpegDecoder time[usec] = %d\n", OS_TicksToMicroSeconds(jpegDecode_end - jpegDecode_begin));
262             OS_TPrintf("[DEBUG] MAIN decode_file_width = %d : decode_file_height = %d\n", decode_file_width, decode_file_height);
263 
264             {
265                 int i,j;
266                 float i_step,j_step;
267                 int i_count,j_count;
268                 s16 t_width = decode_file_width;
269 
270                 j_step = (float)decode_file_width / 256;
271                 i_step = (float)decode_file_height / 192;
272 
273                 i_count = j_count = 0;
274                 for(i = 0; i < 192; i++)
275                 {
276                     for(j = 0; j < 256; j++)
277                     {
278                         *((u16*)((int)G2_GetBG3ScrPtr() + i*256*2 + j*2)) = *((u16*)((u32)decodeOutputBuffer + (u32)(i_count * decode_file_width*2) + (u32)(j_count*2)));
279                         j_count = (int)((double)j*j_step);
280                     }
281                     i_count=(int)((double)i*i_step);
282                 }
283             }
284 
285             // Try to display the date and time
286             {
287                 u8 dateTime[20];
288 
289                 (void)SSP_GetJpegDecoderDateTime(dateTime);
290                 OS_TPrintf("DateTimeOriginal = %s\n", dateTime);
291             }
292             {
293                 char software[30];
294                 u32 initialCode;
295 
296                 (void)SSP_GetJpegDecoderSoftware(software);
297                 // The Exif software tag contains a little-endian game code
298                 MI_CpuCopy8(software, &initialCode, 4);
299                 OS_TPrintf("InitialCode = %c%c%c%c\n", initialCode>>24, initialCode>>16, initialCode>>8, initialCode);
300             }
301             // Get the MakerNote address and size
302             {
303                 u8 *makerNotePhotoAddr = SSP_GetJpegDecoderMakerNoteAddrEx(SSP_MAKERNOTE_PHOTO);
304                 u16 makerNotePhotoSize = SSP_GetJpegDecoderMakerNoteSizeEx(SSP_MAKERNOTE_PHOTO);
305                 u8 *makerNoteUserAddr = SSP_GetJpegDecoderMakerNoteAddrEx(SSP_MAKERNOTE_USER);
306                 u16 makerNoteUserSize = SSP_GetJpegDecoderMakerNoteSizeEx(SSP_MAKERNOTE_USER);
307 
308                 OS_TPrintf("makerNotePhotoAddr = 0x%X\n", makerNotePhotoAddr);
309                 OS_TPrintf("makerNotePhotoSize = 0x%X\n", makerNotePhotoSize);
310                 OS_TPrintf("MakerNoteUserAddr = 0x%X\n", makerNoteUserAddr);
311                 OS_TPrintf("MakerNoteUserSize = 0x%X\n", makerNoteUserSize);
312             }
313             MyFree(decodeOutputBuffer);
314 
315             jpegDecode_begin = OS_GetTick();
316 
317             decode_file_width = SSP_JPEG_THUMBNAIL_WIDTH;
318             decode_file_height = SSP_JPEG_THUMBNAIL_HEIGHT;
319             decodeOutputBuffer = MyAlloc(decode_file_width * decode_file_height * sizeof(u16));
320 
321             result = SSP_StartJpegDecoder(encodeOutputBuffer, encodeOutputSize, decodeOutputBuffer, &decode_file_width, &decode_file_height, SSP_JPEG_THUMBNAIL | SSP_JPEG_RGB555);
322 
323             jpegDecode_end = OS_GetTick();
324 
325             if(result == 0)
326                 OS_Panic("Failed Cpu Decode\n");
327 
328             OS_TPrintf("[TIMER] Thumbnail SSP_StartJpegDecoder time[usec] = %d\n", OS_TicksToMicroSeconds(jpegDecode_end - jpegDecode_begin));
329             OS_TPrintf("[DEBUG] Thumbnail decode_file_width = %d : decode_file_height = %d\n", decode_file_width, decode_file_height);
330 
331 
332             // Try to display the date and time
333             {
334                 u8 dateTime[20];
335 
336                 (void)SSP_GetJpegDecoderDateTime(dateTime);
337                 OS_TPrintf("DateTimeOriginal = %s\n", dateTime);
338             }
339             {
340                 char software[30];
341                 u32 initialCode;
342 
343                 (void)SSP_GetJpegDecoderSoftware(software);
344                 // The Exif software tag contains a little-endian game code
345                 MI_CpuCopy8(software, &initialCode, 4);
346                 OS_TPrintf("InitialCode = %c%c%c%c\n", initialCode>>24, initialCode>>16, initialCode>>8, initialCode);
347             }
348             // Get the MakerNote address and size
349             {
350                 u8 *makerNotePhotoAddr = SSP_GetJpegDecoderMakerNoteAddrEx(SSP_MAKERNOTE_PHOTO);
351                 u16 makerNotePhotoSize = SSP_GetJpegDecoderMakerNoteSizeEx(SSP_MAKERNOTE_PHOTO);
352                 u8 *makerNoteUserAddr = SSP_GetJpegDecoderMakerNoteAddrEx(SSP_MAKERNOTE_USER);
353                 u16 makerNoteUserSize = SSP_GetJpegDecoderMakerNoteSizeEx(SSP_MAKERNOTE_USER);
354 
355                 OS_TPrintf("makerNotePhotoAddr = 0x%X\n", makerNotePhotoAddr);
356                 OS_TPrintf("makerNotePhotoSize = 0x%X\n", makerNotePhotoSize);
357                 OS_TPrintf("MakerNoteUserAddr = 0x%X\n", makerNoteUserAddr);
358                 OS_TPrintf("MakerNoteUserSize = 0x%X\n", makerNoteUserSize);
359             }
360             MyFree(decodeOutputBuffer);
361         }
362 
363         if(retryCount < 1)
364         {
365             OS_TPrintf("Press A button\n");
366             while(1)
367             {
368                 DEMOReadKey();
369                 if(DEMO_IS_PRESS(PAD_BUTTON_A))
370                 {
371                     retryCount++;
372                     break;
373                 }
374                 OS_WaitVBlankIntr();
375             }
376         }
377         else
378             retryCount++;
379     }while(retryCount < 2);
380     OS_Terminate();
381 }
382