1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - tools - ppmconv8
3 File: ppmconv8.c
4
5 Copyright 2003-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:: $
14 $Rev:$
15 $Author:$
16 *---------------------------------------------------------------------------*/
17 //
18 // The 'ppmconv8' tool is for $TwlSDK/build/demos/GX/UnitTest/2D_BmpBg_*
19 // Please see detail at 2D_BmpBg_* directories.
20 //
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 #define MAX_COLORS 256 // 256 color limits
28
29 #define TRUE 1
30 #define FALSE 0
31
32 #define NUM_COLUMN_TEXEL 16
33 #define NUM_COLUMN_PALETTE 16
34
35 #define V5bit( x ) ((x)>>3)
36 #define RGB5551( r, g, b, a ) ((V5bit(r)<<0) | (V5bit(g)<<5) | (V5bit(b)<<10)| (((a)&1)<<15))
37
38 #define SIZE_READBUFFER 1024
39
40 enum
41 {
42 PHASE_READ_MAGIC_NUMBER,
43 PHASE_READ_WIDTH,
44 PHASE_READ_HEIGHT,
45 PHASE_READ_DEPTH,
46 };
47
48 typedef unsigned char u8;
49 typedef unsigned short u16;
50
51 typedef struct
52 {
53 u16 color[MAX_COLORS];
54 int num_colors;
55 }
56 ColorTable;
57
usage(void)58 static void usage(void)
59 {
60 fprintf(stderr, "Usage: ppmconv8 [256color ppm file] [label_name]\n");
61 exit(1);
62 }
63
64 /*---------------------------------------------------------------------------*
65 Name: ReadHeader
66
67 Description: Read header information of ppm file
68
69 Arguments: fp ppm file
70 pwidth output ptr for the width of ppm picture
71 pheight output ptr for the height of ppm picture
72 pdepth output ptr for the depth of ppm picture
73
74 Returns: 1 if success, 0 if error
75 *---------------------------------------------------------------------------*/
ReadHeader(FILE * fp,int * pwidth,int * pheight,int * pdepth)76 static int ReadHeader(FILE * fp, int *pwidth, int *pheight, int *pdepth)
77 {
78 // Get ppm header
79 //
80 // P6[WS]256[WS]192[WS]255[WS]\n WS=Space,Tab,CR
81 //
82 char buffer[SIZE_READBUFFER], *p;
83 int n;
84 int phase = PHASE_READ_MAGIC_NUMBER;
85
86 while (buffer == fgets(buffer, sizeof(buffer), fp))
87 {
88 if (buffer[0] == '#') // comment
89 {
90 continue;
91 }
92
93 p = buffer;
94 while (*p != '\0')
95 {
96 switch (phase)
97 {
98 case PHASE_READ_MAGIC_NUMBER:
99 if (0 != sscanf(p, "P6%n", &n))
100 {
101 return FALSE; // not ppm file
102 }
103 phase = PHASE_READ_WIDTH;
104 break;
105
106 case PHASE_READ_WIDTH:
107 if (1 != sscanf(p, "%d%n", pwidth, &n))
108 {
109 return FALSE;
110 }
111 phase = PHASE_READ_HEIGHT;
112 break;
113
114 case PHASE_READ_HEIGHT:
115 if (1 != sscanf(p, "%d%n", pheight, &n))
116 {
117 return FALSE;
118 }
119 phase = PHASE_READ_DEPTH;
120 break;
121
122 case PHASE_READ_DEPTH:
123 if (1 != sscanf(p, "%d%n", pdepth, &n))
124 {
125 return FALSE;
126 }
127 return TRUE;
128
129 default:
130 break;
131 }
132
133 for (p += n; isspace(*p); p++)
134 {
135 // Do nothing
136 }
137 }
138 }
139 return FALSE;
140 }
141
142
143 /*---------------------------------------------------------------------------*
144 Name: ReadBody
145
146 Description: Read picture image
147
148 Arguments: fp ppm file
149 buffer output ptr for image
150 size buffer size
151
152 Returns: 1 if success, 0 if error
153 *---------------------------------------------------------------------------*/
ReadBody(FILE * fp,u8 * buffer,int size)154 static int ReadBody(FILE * fp, u8 *buffer, int size)
155 {
156 return size == fread(buffer, sizeof(u8), size, fp);
157 }
158
159
160 /*---------------------------------------------------------------------------*
161 Name: ColorTableInit
162
163 Description: Initialize Color Table
164
165 Arguments: None
166
167 Returns: N/A
168 *---------------------------------------------------------------------------*/
ColorTableInit(ColorTable * t)169 static void ColorTableInit(ColorTable * t)
170 {
171 int i;
172 for (i = 0; i < MAX_COLORS; i++)
173 {
174 t->color[i] = 0x0000;
175 }
176 t->num_colors = 0;
177 }
178
179 /*---------------------------------------------------------------------------*
180 Name: ColorTableAppend
181
182 Description: Get color index from Color Table
183
184 Arguments: t ptr for color table
185 color color to be added
186
187 Returns: >= 0 : index number if color is in color table
188 == -1 : error no room to append color
189 *---------------------------------------------------------------------------*/
ColorTableAppend(ColorTable * t,u16 color)190 static int ColorTableAppend(ColorTable * t, u16 color)
191 {
192 int i;
193
194 for (i = 0; i < t->num_colors; i++)
195 {
196 if (t->color[i] == color)
197 {
198 return i;
199 }
200 }
201
202 if (i >= MAX_COLORS)
203 {
204 return -1;
205 }
206
207 t->color[i] = color;
208 t->num_colors++;
209 return i;
210 }
211
212
213 /*---------------------------------------------------------------------------*
214 Name: ColorTableGetColor
215
216 Description: Get color table from Color Table
217
218 Arguments: None
219
220 Returns: N/A
221 *---------------------------------------------------------------------------*/
ColorTableGetColor(ColorTable * t,int index)222 static u16 ColorTableGetColor(ColorTable * t, int index)
223 {
224 return index < t->num_colors ? t->color[index] : 0x0000;
225 }
226
227
228 /*---------------------------------------------------------------------------*
229 Name: main
230
231 Description: output 256 color-ed ppm image bitmap as the format
232 like C source code
233 *---------------------------------------------------------------------------*/
main(int argc,char * argv[])234 int main(int argc, char *argv[])
235 {
236 FILE *fp;
237 u8 *buffer;
238 int result = 1;
239 int width;
240 int height;
241 int depth;
242 int size;
243 int column;
244 int i, index;
245 u16 color;
246 ColorTable color_table;
247
248 if (argc != 3)
249 {
250 usage();
251 }
252
253 if (NULL != (fp = fopen(argv[1], "rb")))
254 {
255 if (ReadHeader(fp, &width, &height, &depth) && depth == 255)
256 {
257 size = width * height * 3;
258 if (NULL != (buffer = (u8 *)malloc(size)))
259 {
260 if (ReadBody(fp, buffer, size))
261 {
262 printf("const unsigned char %s_Texel[%d * %d] =\n{\n", argv[2], width, height);
263 printf("\t/* %s: WIDTH=%d HEIGHT=%d DEPTH=%d */\n", argv[1], width, height,
264 depth);
265
266 column = 0;
267 ColorTableInit(&color_table);
268 for (i = 0; i < size; i += 3)
269 {
270 if (column % NUM_COLUMN_TEXEL == 0)
271 {
272 printf("\t");
273 }
274 color = RGB5551(buffer[i], buffer[i + 1], buffer[i + 2], 1);
275 index = ColorTableAppend(&color_table, color);
276 if (index < 0)
277 {
278 fprintf(stderr, "ppmconv8: Error too many colors (over 256)\n");
279 return 1;
280 }
281 printf("0x%02x, ", index);
282 column++;
283 if (column % NUM_COLUMN_TEXEL == 0)
284 {
285 printf("\n");
286 }
287 }
288 printf("\n};\n\n");
289 printf("const unsigned short %s_Palette[%d] =\n{\n", argv[2], MAX_COLORS);
290
291 column = 0;
292 for (i = 0; i < MAX_COLORS; i++)
293 {
294 if (column % NUM_COLUMN_PALETTE == 0)
295 {
296 printf("\t");
297 }
298 printf("0x%04x, ", ColorTableGetColor(&color_table, i));
299 column++;
300 if (column % NUM_COLUMN_PALETTE == 0)
301 {
302 printf("\n");
303 }
304 }
305 printf("\n};\n\n");
306
307 result = 0;
308 }
309 }
310 free(buffer);
311 }
312 fclose(fp);
313 }
314
315 if (result)
316 {
317 fprintf(stderr, "Cannot convert file \"%s\".\n", argv[1]);
318 }
319
320 return result;
321 }
322