OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [mwin/] [bmp/] [convbmp.c] - Blame information for rev 673

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
3
 *
4
 * Windows BMP to Microwindows image converter
5
 *
6
 * 6/9/1999 g haerr
7
 *
8
 * 05/01/2000 Michael Temari <Michael@TemWare.Com>
9
 * Modified to output .s ACK format for Minix
10
 */
11
 
12
#include <stdio.h>
13
#include <string.h>
14
#include <stdlib.h>
15
#include "device.h"
16
 
17
/* separators for DOS & Unix file systems */
18
#define OS_FILE_SEPARATOR   "/\\"
19
 
20
#define PIX2BYTES(n)    (((n)+7)/8)
21
 
22
#define BI_RGB          0L
23
#define BI_RLE8         1L
24
#define BI_RLE4         2L
25
#define BI_BITFIELDS    3L
26
 
27
typedef unsigned char   UCHAR;
28
typedef unsigned char   BYTE;
29
 
30
#if !_MINIX
31
typedef unsigned short  WORD;
32
typedef unsigned long   DWORD;
33
typedef long            LONG;
34
#define CASTWORD
35
#define CASTDWORD
36
#define CASTLONG
37
#else
38
/* The Minix ACK compiler cannot pack a structure so we do it the hardway */
39
typedef unsigned char   WORD[2];
40
typedef unsigned char   DWORD[4];
41
typedef unsigned char   LONG[4];
42
#define CASTWORD        *(unsigned short *)&
43
#define CASTDWORD       *(unsigned long *)&
44
#define CASTLONG        *(long *)&
45
#endif
46
 
47
#pragma pack(1)
48
/* windows style*/
49
typedef struct {
50
        /* BITMAPFILEHEADER*/
51
        BYTE    bfType[2];
52
        DWORD   bfSize;
53
        WORD    bfReserved1;
54
        WORD    bfReserved2;
55
        DWORD   bfOffBits;
56
        /* BITMAPINFOHEADER*/
57
        DWORD   BiSize;
58
        LONG    BiWidth;
59
        LONG    BiHeight;
60
        WORD    BiPlanes;
61
        WORD    BiBitCount;
62
        DWORD   BiCompression;
63
        DWORD   BiSizeImage;
64
        LONG    BiXpelsPerMeter;
65
        LONG    BiYpelsPerMeter;
66
        DWORD   BiClrUsed;
67
        DWORD   BiClrImportant;
68
} BMPHEAD;
69
 
70
/* os/2 style*/
71
typedef struct {
72
        /* BITMAPFILEHEADER*/
73
        BYTE    bfType[2];
74
        DWORD   bfSize;
75
        WORD    bfReserved1;
76
        WORD    bfReserved2;
77
        DWORD   bfOffBits;
78
        /* BITMAPCOREHEADER*/
79
        DWORD   bcSize;
80
        WORD    bcWidth;
81
        WORD    bcHeight;
82
        WORD    bcPlanes;
83
        WORD    bcBitCount;
84
} BMPCOREHEAD;
85
#pragma pack()
86
 
87
int     ConvBMP(FILE *fp,char *name);
88
void    outline(UCHAR *linebuffer, int bitdepth, int linesize, int y);
89
int     DecodeRLE8(UCHAR *buf,FILE *fp);
90
int     DecodeRLE4(UCHAR *buf,FILE *fp);
91
void    put4(int b);
92
 
93
int     s_flag = 0;
94
 
95
int main(int argc,char *argv[])
96
{
97
FILE    *fp;
98
char    *p;
99
char    name[64];
100
char    oname[64];
101
 
102
   /* skip the program name */
103
   argc--;
104
   argv++;
105
 
106
   /* check for -s flag */
107
   if(argc && strcmp(*argv, "-s") == 0) {
108
        s_flag = -1;
109
        argc--;
110
        argv++;
111
   }
112
 
113
   /* need at least one file to convert */
114
   if(argc == 0) {
115
        fprintf(stderr, "Usage: convbmp [-s] <bmpfile>\n");
116
        return(-1);
117
   }
118
 
119
   /* go back one since the first thing in the loop is to increment */
120
   argv--;
121
   while(argc--) {
122
        argv++;
123
        if((p = strrchr(*argv, '.')) != (char *)NULL)
124
                *p = '\0';
125
        strcpy(name, *argv);
126
        strcpy(oname, *argv);
127
        if(s_flag)
128
                strcat(oname, ".s");
129
        else
130
                strcat(oname, ".c");
131
        if(p != (char *)NULL)
132
                *p = '.';
133
        if((fp = fopen(*argv, "rb")) == (FILE *)NULL) {
134
                fprintf(stderr, "Can't open file: %s\n", *argv);
135
                continue;
136
        }
137
        if(freopen(oname, "w", stdout) == (FILE *)NULL) {
138
                fclose(fp);
139
                fprintf(stderr, "Could not open output file %s\n", oname);
140
                continue;
141
        }
142
 
143
   /*
144
      let's strip any directory from the path passed in.
145
      This prevent problems if this utility is given
146
      path is not for the curent directory.
147
   */
148
   p = name;
149
   while( 1 )
150
   {
151
      char *p1 = p;
152
      p1 = strpbrk( p, OS_FILE_SEPARATOR );
153
      if( p1 )
154
      {
155
         p = p1+1;
156
      }
157
      else
158
      {
159
          break;
160
      }
161
   }
162
        if(ConvBMP(fp, p)) {
163
                fprintf(stderr, "Conversion failed: %s\n", *argv);
164
                fclose(fp);
165
                continue;
166
        }
167
        fclose(fp);
168
   }
169
   return(0);
170
}
171
 
172
/* decode a bmp file*/
173
int ConvBMP(FILE *fp, char *name)
174
{
175
BMPHEAD         bmp;
176
BMPCOREHEAD     *bmc;
177
int             i, palsize;
178
UCHAR           *linebuffer = NULL;
179
unsigned int    cx, cy, bitdepth, linesize;
180
long            compression;
181
MWPALENTRY      cmap[256];
182
long l;
183
int g;
184
int bytesperpixel;
185
UCHAR *p = (UCHAR *)&l;
186
 
187
   /* read BMP header*/
188
   if(fread(&bmp, 1, sizeof(BMPHEAD), fp) != sizeof(BMPHEAD)) {
189
        fprintf(stderr, "Error reading .bmp file header\n");
190
        return(-1);
191
   }
192
 
193
   /* might be windows or os/2 header*/
194
   if(CASTDWORD bmp.BiSize == 12) {
195
        bmc = (BMPCOREHEAD *)&bmp;
196
        cx = (int)CASTWORD bmc->bcWidth;
197
        cy = (int)CASTWORD bmc->bcHeight;
198
        bitdepth = CASTWORD bmc->bcBitCount;
199
        palsize = 1 << bitdepth;
200
        compression = BI_RGB;
201
        fseek(fp, sizeof(BMPCOREHEAD), SEEK_SET);
202
   } else {
203
        cx = (int)CASTLONG bmp.BiWidth;
204
        cy = (int)CASTLONG bmp.BiHeight;
205
        bitdepth = CASTWORD bmp.BiBitCount;
206
        palsize = (int)CASTDWORD bmp.BiClrUsed;
207
        if(palsize == 0)
208
                palsize = 1 << bitdepth;
209
        compression = CASTDWORD bmp.BiCompression;
210
   }
211
 
212
   if(bitdepth > 8)
213
           palsize = 0;
214
 
215
   /* currently only 1, 4, 8 and 24 bpp bitmaps*/
216
   if(bitdepth > 8 && bitdepth != 24) {
217
        fprintf(stderr, "Error: bits per pixel must be 1, 4, 8 or 24\n");
218
        return(-1);
219
   }
220
 
221
   /* compute image line size and allocate line buffer*/
222
   if(bitdepth == 1) {
223
        linesize = PIX2BYTES(cx);
224
        bytesperpixel = 1;
225
   } else if(bitdepth <= 4) {
226
        linesize = PIX2BYTES(cx<<2);
227
        bytesperpixel = 1;
228
   } else if(bitdepth <= 8) {
229
        linesize = cx;
230
        bytesperpixel = 1;
231
   } else if(bitdepth <= 16) {
232
        linesize = cx * 2;
233
        bytesperpixel = 2;
234
   } else if(bitdepth <= 24) {
235
        linesize = cx * 3;
236
        bytesperpixel = 3;
237
   } else {
238
        linesize = cx * 4;
239
        bytesperpixel = 4;
240
   }
241
 
242
   linesize = (linesize+3) & ~3;
243
 
244
   if((linebuffer = malloc(linesize)) == (UCHAR *)NULL) {
245
        fprintf(stderr, "Error with malloc(%d)\n", linesize);
246
        return(-1);
247
   }
248
 
249
   if(!s_flag) {
250
        printf("/* Generated by convbmp*/\n");
251
        printf("#include \"device.h\"\n\n");
252
        printf("/* MWIMAGEHDR image_%s converted from %s.bmp*/\n\n",
253
                name, name);
254
   }
255
 
256
   /* get colormap*/
257
   if(bitdepth <= 8) {
258
        for(i=0; i<palsize; i++) {
259
                cmap[i].b = fgetc(fp);
260
                cmap[i].g = fgetc(fp);
261
                cmap[i].r = fgetc(fp);
262
                if(CASTDWORD bmp.BiSize != 12)
263
                        fgetc(fp);
264
        }
265
 
266
        if(!s_flag) {
267
                /* extract palette*/
268
                printf("static MWPALENTRY palette[%d] = {\n", palsize);
269
                for(i=0; i<palsize; ++i)
270
                        printf("  RGBDEF( %3d, %3d, %3d ),\t/* pal %d*/\n",
271
                                cmap[i].r, cmap[i].g, cmap[i].b, i);
272
                printf("};\n\n");
273
        } else {
274
                printf(".sect .text; .sect .rom; .sect .data; .sect .bss\n");
275
                printf(".sect .data\n");
276
                printf("__II0:\n");
277
                l = 0L; g = 0; p = (UCHAR *)&l;
278
                for(i=0; i<palsize; ++i) {
279
                        p[g++] = cmap[i].r;
280
                        if(g == 4)
281
                                { g = 0; printf(".data4\t%ld\n", l); l = 0L; }
282
                        p[g++] = cmap[i].g;
283
                        if(g == 4)
284
                                { g = 0; printf(".data4\t%ld\n", l); l = 0L; }
285
                        p[g++] = cmap[i].b;
286
                        if(g == 4)
287
                                { g = 0; printf(".data4\t%ld\n", l); l = 0L; }
288
                }
289
                if(g)
290
                        printf(".data4\t%ld\n", l);
291
        }
292
   }
293
 
294
   if(!s_flag) {
295
        printf("static MWUCHAR imagebits[] = {\n");
296
   } else {
297
        printf("__II1:\n");
298
        l = 0L; g = 0;
299
   }
300
 
301
   /* decode image data*/
302
   fseek(fp, CASTDWORD bmp.bfOffBits, SEEK_SET);
303
   if(compression == BI_RLE8) {
304
        for(i = cy-1; i>= 0; i--) {
305
                if(!DecodeRLE8(linebuffer, fp))
306
                        break;
307
                outline(linebuffer, bitdepth, linesize, i);
308
        }
309
   } else if(compression == BI_RLE4) {
310
        for(i = cy-1; i>= 0; i--) {
311
                if(!DecodeRLE4(linebuffer, fp))
312
                        break;
313
                outline(linebuffer, bitdepth, linesize, i);
314
        }
315
   } else {
316
        for(i=0; i<cy; i++) {
317
                if(fread(linebuffer, 1, linesize, fp) != (size_t)linesize) {
318
                        free(linebuffer);
319
                        fprintf(stderr, "Error fread\n");
320
                        return(-1);
321
                }
322
                outline(linebuffer, bitdepth, linesize, cy-i-1);
323
        }
324
   }
325
 
326
   if(!s_flag) {
327
        printf("};\n\n");
328
 
329
        printf("MWIMAGEHDR image_%s = {\n", name);
330
        printf("  %d, %d,\t/* width, height*/\n", cx, cy);
331
        printf("  %d, %d,\t\t/* planes, bpp*/\n", 1, bitdepth);
332
        printf("  %d, %d,\t/* pitch, bytesperpixel*/\n",
333
                linesize, bytesperpixel);
334
        printf("  %d, %d,\t/* compression, palsize*/\n", 1, palsize);
335
        printf("  %ldL,\t\t/* transcolor*/\n", -1L);
336
        if(palsize)
337
                printf("  palette,\n");
338
        else
339
                printf("  0,\n");
340
        printf("  imagebits,\n");
341
        printf("};\n");
342
   } else {
343
        printf(".extern _image_%s\n", name);
344
        printf("_image_%s:\n", name);
345
        printf(".data4\t%ld\n",(long)cx);
346
        printf(".data4\t%ld\n",(long)cy);
347
        printf(".data4\t%ld\n",1L);
348
        printf(".data4\t%ld\n",(long)bitdepth);
349
        printf(".data4\t%ld\n",(long)linesize);
350
        printf(".data4\t%ld\n",(long)bytesperpixel);
351
        printf(".data4\t%ld\n",1L);
352
        printf(".data4\t%ld\n",(long)palsize);
353
        printf(".data4\t%ld\n",-1L);
354
        printf(".data4\t__II0\n");
355
        if(palsize)
356
                printf(".data4\t__II1\n");
357
        else
358
                printf(".data4\t0\n");
359
        printf(".sect .text\n");
360
   }
361
 
362
   free(linebuffer);
363
 
364
   return(0);
365
}
366
 
367
void outline(UCHAR *linebuffer, int bitdepth, int linesize, int y)
368
{
369
static int bc = 0;
370
static long l = 0;
371
static char *p = (char *)&l;
372
int     n;
373
 
374
   switch(bitdepth) {
375
        case 1:
376
        case 4:
377
                for(n=0; n<linesize; ++n) {
378
                        if(!s_flag)
379
                                printf("0x%02x,", linebuffer[n]);
380
                        else {
381
                                p[bc++] = linebuffer[n];
382
                                if(bc == 4) {
383
                                        bc = 0;
384
                                        printf(".data4\t%ld\n", l);
385
                                        l = 0L;
386
                                }
387
                        }
388
                }
389
                break;
390
        case 8:
391
        default:
392
                for(n=0; n<linesize; ++n) {
393
                        if(!s_flag)
394
                                printf("%d,", linebuffer[n]);
395
                        else {
396
                                p[bc++] = linebuffer[n];
397
                                if(bc == 4) {
398
                                        bc = 0;
399
                                        printf(".data4\t%ld\n", l);
400
                                        l = 0L;
401
                                }
402
                        }
403
                }
404
   }
405
   if(!s_flag)
406
        printf("\n");
407
}
408
 
409
/*
410
 * Decode one line of RLE8, return 0 when done with all bitmap data
411
 */
412
int DecodeRLE8(UCHAR *buf,FILE *fp)
413
{
414
int             c, n;
415
UCHAR * p = buf;
416
 
417
   while(1) {
418
        switch(n = fgetc(fp)) {
419
                case EOF:
420
                        return(0);
421
                case 0:                                  /* 0 = escape*/
422
                        switch(n = fgetc(fp)) {
423
                        case 0:                  /* 0 0 = end of current scan line*/
424
                                return(1);
425
                        case 1:                         /* 0 1 = end of data*/
426
                                return(1);
427
                        case 2:                         /* 0 2 xx yy delta mode - NOT SUPPORTED*/
428
                                (void)fgetc(fp);
429
                                (void)fgetc(fp);
430
                                continue;
431
                        default:                        /* 0 3..255 xx nn uncompressed data*/
432
                                for(c=0; c<n; c++)
433
                                        *p++ = fgetc(fp);
434
                                if(n & 1)
435
                                        (void)fgetc(fp);
436
                                continue;
437
                        }
438
                default:
439
                        c = fgetc(fp);
440
                        while(n--)
441
                                *p++ = c;
442
                        continue;
443
                }
444
        }
445
}
446
 
447
/*
448
 * Decode one line of RLE4, return 0 when done with all bitmap data
449
 */
450
static UCHAR *p;
451
static int      once;
452
 
453
void put4(int b)
454
{
455
static int      last;
456
 
457
   last = (last << 4) | b;
458
   if(++once == 2) {
459
        *p++ = last;
460
        once = 0;
461
   }
462
}
463
 
464
int DecodeRLE4(UCHAR *buf, FILE *fp)
465
{
466
int             c, n, c1, c2;
467
 
468
   p = buf;
469
   once = 0;
470
   while(1) {
471
        switch(n = fgetc(fp)) {
472
                case EOF:
473
                        return(0);
474
                case 0:                                  /* 0 = escape*/
475
                switch(n = fgetc(fp)) {
476
                        case 0:                  /* 0 0 = end of current scan line*/
477
                                if(once)
478
                                        put4(0);
479
                                return(1);
480
                        case 1:                         /* 0 1 = end of data*/
481
                                if(once)
482
                                        put4(0);
483
                                return(1);
484
                        case 2:                         /* 0 2 xx yy delta mode - NOT SUPPORTED*/
485
                                (void)fgetc(fp);
486
                                (void)fgetc(fp);
487
                                continue;
488
                        default:                        /* 0 3..255 xx nn uncompressed data*/
489
                                c2 = (n+3) & ~3;
490
                                for(c=0; c<c2; c++) {
491
                                        if((c & 1) == 0)
492
                                                        c1 = fgetc(fp);
493
                                        if(c < n)
494
                                                        put4((c1 >> 4) & 0x0f);
495
                                        c1 <<= 4;
496
                                }
497
                                continue;
498
                        }
499
                default:
500
                        c = fgetc(fp);
501
                        c1 = (c >> 4) & 0x0f;
502
                        c2 = c & 0x0f;
503
                        for(c=0; c<n; c++)
504
                                put4((c&1)? c2: c1);
505
                        continue;
506
                }
507
        }
508
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.