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