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