1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "general.h"
6 #include "fileoutput.h"
7
8 /*
9
10 Ringtone Tools - Copyright 2001-2005 Michael Kohn (mike@mikekohn.net)
11 This falls under the Kohnian license. Please read
12 it at http://ringtonetools.mikekohn.net/
13
14 This program is NOT opensourced. You may not use any part
15 of this program for your own software.
16
17 */
18
19 /* BMP */
20
write_bmp_info_header(FILE * out,struct note_t * note,int bits,int * palette,int palette_count)21 void write_bmp_info_header(FILE *out, struct note_t *note, int bits, int *palette, int palette_count)
22 {
23 int t;
24 /* int t,d; */
25
26 /* d=ftell(out); */
27
28 write_long(out,40); /* biSize */
29 write_long(out,note->width);
30 write_long(out,note->height);
31 write_word(out,1);
32 write_word(out,bits);
33 write_long(out,0); /* compression */
34 /* write_long(out,image_size); */
35 write_long(out,0);
36 write_long(out,0); /* biXPelsperMetre */
37 write_long(out,0); /* biYPelsperMetre */
38 write_long(out,palette_count); /* biClrUsed */
39 write_long(out,palette_count); /* biClrImportant */
40
41 for (t=0; t<palette_count; t++)
42 { write_long(out,palette[t]); }
43
44 /*
45 t=ftell(out);
46 fseek(out,d,SEEK_SET);
47 write_long(out,t-d);
48 fseek(out,t,SEEK_SET);
49 */
50 }
51
write_bmp_header(FILE * out,struct note_t * note)52 void write_bmp_header(FILE *out, struct note_t *note)
53 {
54 write_chars(out,"BM");
55 write_long(out,0);
56 write_word(out,0);
57 write_word(out,0);
58 write_long(out,0); /* size */
59 }
60
color_distance(int c1,int c2)61 int color_distance(int c1, int c2)
62 {
63 int d;
64
65 d=abs((c1&255)-(c2&255))+(((c1>>8)&255)-((c2>>8)&255))+(((c1>>16)&255)-((c2>>16)&255));
66
67 return d/3;
68 }
69
compute_palette(struct note_t * note,int * palette,int * palette_count,int true_color)70 int compute_palette(struct note_t *note,int *palette,int *palette_count,int true_color)
71 {
72 int l,ptr,c,count;
73
74 count=0;
75 l=note->width*note->height;
76
77 for (ptr=0; ptr<l; ptr++)
78 {
79 for (c=0; c<count; c++)
80 {
81 if (palette[c]==note->picture[ptr]) break;
82 }
83
84 if (c==count)
85 {
86 if (count>=256)
87 {
88 if (true_color==1) return 24;
89 return 8;
90 }
91 palette[count++]=note->picture[ptr];
92 }
93 }
94
95 *palette_count=count;
96
97 if (count<=2) return 1;
98 else
99 if (count<=16) return 4;
100 else
101 if (count<=256) return 8;
102
103 return 24;
104 }
105
get_color(int col,int * palette,int palette_count)106 int get_color(int col, int *palette, int palette_count)
107 {
108 int d,c;
109
110 for (c=0; c<palette_count; c++)
111 {
112 if (col==palette[c]) return c;
113 }
114
115 for (d=0; d<255; d++)
116 {
117 for (c=0; c<palette_count; c++)
118 {
119 if (color_distance(col,palette[c])<=d) return c;
120 }
121 }
122
123 return 0;
124 }
125
write_bmp_data(FILE * out,struct note_t * note,int bits,int * palette,int palette_count)126 void write_bmp_data(FILE *out, struct note_t *note, int bits, int *palette, int palette_count)
127 {
128 int x,y,c,b,k,padding;
129
130 if (bits==1)
131 {
132 padding=note->width/8;
133 if ((note->width%8)!=0) padding++;
134 padding=padding%4;
135 if (padding==0) padding=4;
136
137 for (y=note->height-1; y>=0; y--)
138 {
139 x=0;
140 while(x<note->width)
141 {
142 k=0;
143
144 for (b=7; b>=0; b--)
145 {
146 if (x<note->width)
147 {
148 c=note->picture[x+(y*note->width)];
149 c=((c&255)+((c>>8)&255)+((c>>16)&255))/3;
150
151 if (c>COLOR_THRESHOLD)
152 { k=k+(1<<b); }
153 }
154 x++;
155 }
156 putc(k,out);
157 }
158
159 for (x=padding; x<4; x++)
160 { putc(0,out); }
161 }
162 }
163 else
164 if (bits==4)
165 {
166 padding=(note->width>>1)+(note->width&1);
167 padding=(padding%4);
168 if (padding==0) padding=4;
169
170 for (y=note->height-1; y>=0; y--)
171 {
172 for (x=0; x<note->width; x++)
173 {
174 b=get_color(note->picture[x+(y*note->width)],palette,palette_count)<<4;
175 x++;
176 if (x<note->width);
177 { b|=get_color(note->picture[x+(y*note->width)],palette,palette_count); }
178 putc(b,out);
179 }
180
181 for (x=padding; x<4; x++)
182 { putc(0,out); }
183 }
184 }
185 else
186 if (bits==8)
187 {
188 padding=(note->width)%4;
189 if (padding==0) padding=4;
190
191 for (y=note->height-1; y>=0; y--)
192 {
193 for (x=0; x<note->width; x++)
194 {
195 putc(get_color(note->picture[x+(y*note->width)],palette,palette_count),out);
196 }
197
198 for (x=padding; x<4; x++)
199 { putc(0,out); }
200 }
201 }
202 else
203 if (bits==24)
204 {
205 padding=(note->width*3)%4;
206 if (padding==0) padding=4;
207
208 for (y=note->height-1; y>=0; y--)
209 {
210 for (x=0; x<note->width; x++)
211 {
212 putc(((note->picture[x+(y*note->width)])&255),out);
213 putc(((note->picture[x+(y*note->width)]>>8)&255),out);
214 putc(((note->picture[x+(y*note->width)]>>16)&255),out);
215 }
216
217 for (x=padding; x<4; x++)
218 { putc(0,out); }
219 }
220 }
221
222 }
223
write_bmp_footer(FILE * out,struct note_t * note)224 void write_bmp_footer(FILE *out, struct note_t *note)
225 {
226 int data_length,palette_count,bits;
227 int palette[256];
228 int t;
229
230 palette_count=0;
231
232 if ((note->bmp_flags&4)==0)
233 {
234 bits=1;
235 palette[palette_count++]=0;
236 palette[palette_count++]=0xffffff;
237 }
238 else
239 {
240 bits=compute_palette(note,palette,&palette_count,1);
241 }
242
243 write_bmp_info_header(out,note,bits,palette,palette_count);
244
245 data_length=ftell(out);
246 fseek(out,10,SEEK_SET);
247 write_long(out,data_length);
248 fseek(out,data_length,SEEK_SET);
249
250 /* printf("pointer to data %d\n",data_length); */
251
252 t=ftell(out);
253 write_bmp_data(out,note,bits,palette,palette_count);
254
255 data_length=ftell(out);
256 fseek(out,2,SEEK_SET);
257 write_long(out,data_length);
258 fseek(out,34,SEEK_SET);
259 write_long(out,data_length-t);
260 fseek(out,data_length,SEEK_SET);
261 }
262
263 /*
264 void write_bmp_footer(FILE *out, struct note_t *note)
265 {
266 int x,y,k,b,c;
267 int padding=0;
268 int data_length;
269 int image_size;
270
271 if ((note->bmp_flags&4)==0)
272 {
273 image_size=note->width/8;
274 if (note->width%8>0) image_size++;
275 if (image_size%4!=0)
276 { image_size=image_size+(4-(image_size%4)); }
277 }
278 else
279 {
280 image_size=note->width*3;
281 while ((image_size%4)!=0) image_size++;
282 image_size=image_size*note->height;
283 }
284
285
286 data_length=ftell(out);
287 fseek(out,2,SEEK_SET);
288 write_long(out,data_length);
289 fseek(out,data_length,SEEK_SET);
290 }
291
292 */
293
write_text_footer(FILE * out,struct note_t * note)294 void write_text_footer(FILE *out, struct note_t *note)
295 {
296 int x,y,c;
297
298 for (y=0; y<note->height; y++)
299 {
300 for (x=0; x<note->width; x++)
301 {
302 c=note->picture[x+(y*note->width)];
303 c=((c&255)+((c>>8)&255)+((c>>16)&255))/3;
304
305 if (c>COLOR_THRESHOLD)
306 { putc('*',out); }
307 else
308 { putc(' ',out); }
309 }
310 putc('\n',out);
311 }
312 }
313
write_wbmp_header(FILE * out,struct note_t * note)314 void write_wbmp_header(FILE *out, struct note_t *note)
315 {
316 putc(0,out);
317 putc(0,out);
318 putc(note->width,out);
319 putc(note->height,out);
320 }
321
write_wbmp_footer(FILE * out,struct note_t * note)322 void write_wbmp_footer(FILE *out, struct note_t *note)
323 {
324 int x,y,k,b,c;
325 int ptr;
326
327 ptr=0;
328
329 for (y=0; y<note->height; y++)
330 {
331 x=0;
332 while (x<note->width)
333 {
334 k=0;
335
336 for (b=7; b>=0; b--)
337 {
338 if (x<note->width)
339 {
340 c=note->picture[ptr++];
341 c=((c&255)+((c>>8)&255)+((c>>16)&255))/3;
342
343 if (c>COLOR_THRESHOLD)
344 { k=k+(1<<b); }
345 }
346 x++;
347 }
348 putc(k,out);
349 }
350 }
351 }
352
353
write_icon_header(FILE * out,struct note_t * note)354 void write_icon_header(FILE *out, struct note_t *note)
355 {
356 if (note->width!=16 && note->width!=32 && note->width!=64)
357 {
358 note->width=0;
359 printf("Invalid width for icon file\n");
360 return;
361 }
362
363 if (note->height!=16 && note->height!=32 && note->height!=64)
364 {
365 note->height=0;
366 printf("Invalid width for icon file\n");
367 return;
368 }
369
370 write_word(out,0);
371 write_word(out,1);
372 write_word(out,1);
373
374 putc(note->width,out);
375 putc(note->height,out);
376 }
377
write_icon_footer(FILE * out,struct note_t * note)378 void write_icon_footer(FILE *out, struct note_t *note)
379 {
380 int data_length,palette_count,bits,bmp_start;
381 int palette[256],t,d,k,p,x,y;
382
383 palette_count=0;
384
385 if ((note->bmp_flags&4)==0)
386 {
387 bits=1;
388 palette[palette_count++]=0;
389 palette[palette_count++]=0xffffff;
390 }
391 else
392 {
393 bits=compute_palette(note,palette,&palette_count,1);
394 }
395
396 if (bits>=8)
397 { putc(0,out); }
398 else
399 { putc((1<<bits),out); }
400
401 putc(0,out);
402 write_word(out,0);
403 write_word(out,0);
404 t=ftell(out);
405 write_long(out,0);
406 write_long(out,ftell(out)+4);
407
408 #ifdef DEBUG
409 printf("Palette count=%d bits=%d\n",palette_count,bits);
410 #endif
411
412 bmp_start=ftell(out);
413 write_bmp_info_header(out,note,bits,palette,palette_count);
414 if ((1<<bits)!=palette_count && bits<24)
415 {
416 d=1<<bits;
417 for (k=palette_count; k<d; k++)
418 {
419 write_long(out,0);
420 }
421 }
422 write_bmp_data(out,note,bits,palette,palette_count);
423
424 for (y=note->height-1; y>=0; y--)
425 {
426 x=0;
427 while(x<note->width)
428 {
429 k=0;
430 if (note->trans>=0)
431 {
432 for (p=7; p>=0; p--)
433 {
434 if (x<note->width && note->picture[x+(y*note->width)]==note->trans)
435 { k=k+(1<<p); }
436 x++;
437 }
438 }
439 else
440 { x=x+8; }
441 putc(k,out);
442 }
443
444 if ((x%32)!=0)
445 {
446 p=((x%32)/8);
447 for(k=0; k<p; k++) putc(0,out);
448 }
449 }
450
451 data_length=ftell(out);
452
453 fseek(out,t,SEEK_SET); /* Icon Offset */
454 write_long(out,data_length-bmp_start);
455 /* write_long(out,data_length-(t+8)); */
456
457 fseek(out,t+16,SEEK_SET); /* biHeight */
458 write_long(out,note->height*2);
459
460 fseek(out,t+28,SEEK_SET); /* biSizeImage */
461 /* write_long(out,data_length-d-40); */
462 write_long(out,0);
463 write_long(out,0);
464 write_long(out,0);
465 write_long(out,0);
466 write_long(out,0);
467
468 /* write_long(out,data_length-(t+8-40)); */
469 fseek(out,data_length,SEEK_SET);
470
471 }
472
473
474