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