1
/****************************\
2
* Bitmap mit Farbtabelle als *
3
* Graphik-Datei speichern *
4
* Autor: Gabriel Schmidt *
5
* (c) 1992 by MAXON-Computer *
6
* Modifiziert von Sebastian *
9
\****************************/
19
/* --- (X) IMG-Implementation ----------------- */
21
#define IMG_COMPRESSED
35
typedef enum {NONE, SOLID0, SOLID1, PATRUN, BITSTR} IMG_MODE;
37
typedef UBYTE IMG_SOLID;
39
typedef enum { RGB=0, CMY=1, Pantone=2 } XIMG_COLMODEL;
44
XIMG_COLMODEL img_colmodel;
47
typedef struct RGB XIMG_RGB;
50
int bitmap_to_img(FILE_TYP typ, int ww, int wh,
51
unsigned int pixw, unsigned int pixh,
52
unsigned int planes, unsigned int colors,
54
void(*get_color)(unsigned int colind, struct RGB *rgb),
55
void(*get_pixel)(int x, int y, unsigned int *colind) )
62
UBYTE *line_buf, *write_buf;
63
register UBYTE *startpnt, *bufpnt;
64
unsigned int colind, line_len, line, bit;
65
register unsigned int byte;
68
/* fill in (X) IMG-Header */
70
header.img_version = 1;
71
header.img_headlen = (UWORD) sizeof(header) /2;
73
header.img_headlen += (UWORD)(sizeof(xheader)+colors*sizeof(xrgb))/2;
75
header.img_nplanes = planes;
76
header.img_patlen = 2;
77
header.img_pixw = pixw;
78
header.img_pixh = pixh;
82
xheader.img_ximg = XIMG_MAGIC;
83
xheader.img_colmodel= RGB;
85
/* calculate linelength, allocate buffer. */
89
line_buf = malloc((size_t)planes*line_len);
93
/* Worst case: the bufferd line could grow to max. 3 times the length */
94
/* of the original! */
96
write_buf = malloc((size_t)3*line_len);
97
if (write_buf == NULL)
105
file = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
116
if (write (file, &header, sizeof(header)) != sizeof(header) ||
117
(typ == XIMG && write (file, &xheader, sizeof(xheader) ) != sizeof(xheader)))
126
/* save the colortable if possible */
129
for (cnt=0; cnt<colors; cnt++)
131
get_color(cnt,&xrgb);
132
if (write(file,&xrgb,sizeof(xrgb)) != sizeof(xrgb))
142
/* And now line by line ... */
144
for (line=0; line<wh; line++)
146
/* get pixel, split it up and */
147
/* store it as planes in buffer */
149
for (byte=0; byte<line_len; byte++)
151
for (cnt=0; cnt<planes; cnt++)
152
line_buf[cnt*line_len+byte] = 0x00;
154
for (bit=0; bit<8; bit++)
157
get_pixel(8*byte+bit, line, &colind);
159
for (cnt=0; cnt<planes; cnt++)
161
line_buf[cnt*line_len+byte] <<= 1;
162
line_buf[cnt*line_len+byte] |= colind & 0x01;
168
/* compress bitstrings in buffer */
169
/* and write it to file */
171
for (cnt=0; cnt<planes; cnt++)
173
/* Bitstringpointer to start of plane */
175
startpnt = &line_buf[cnt*line_len];
178
while (startpnt < &line_buf[(cnt+1)*line_len])
180
/*********************************************/
181
/* Which _new_ compression-mode "fits" the */
182
/* the current byte? */
183
/* Note: the compressing modes get choosen */
184
/* "positive". The non compressing BITSTR- */
185
/* mode is choosen only if nothing else */
187
/*********************************************/
198
if ( startpnt < &line_buf[(cnt+1)*line_len-3] &&
199
*(startpnt) == *(startpnt+2) &&
200
*(startpnt+1) == *(startpnt+3) )
206
/************************************************/
207
/* The mode is choosen, now work with it. */
208
/* The compressing modi stay current as long as */
210
/************************************************/
217
while ( (startpnt < &line_buf[(cnt+1)*line_len]) &&
218
(*(startpnt)==0x00) &&
228
while ( (startpnt < &line_buf[(cnt+1)*line_len]) &&
229
(*(startpnt)==0xFF) &&
235
*(bufpnt++) = 0x80 | count;
242
while ( startpnt < &line_buf[(cnt+1)*line_len-1] &&
243
*(startpnt) == *(startpnt-2) &&
244
*(startpnt+1) == *(startpnt-1) &&
251
*(bufpnt++) = *(startpnt-2);
252
*(bufpnt++) = *(startpnt-1);
255
/************************************************/
256
/* The while Condition is ment as follows: */
258
/* while ( NOT(2-Byte-Solidrun possible) && */
259
/* NOT(6-Byte-Patternrun possible) && */
260
/* count < 0xFF && */
261
/* still Bytes remaining ) */
263
/* As soon as a _compressing_ alternative shows */
264
/* up, BITSTR gets cancelled! */
265
/************************************************/
269
while ( !(((startpnt+count)<&line_buf[(cnt+1)*line_len-1])&&
270
(((*(startpnt+count)==0xFF) && (*(startpnt+count+1)==0xFF))||
271
((*(startpnt+count)==0x00) && (*(startpnt+count+1)==0x00)))) &&
272
!(((startpnt+count)<&line_buf[(cnt+1)*line_len-5])&&
273
(*(startpnt+count) == *(startpnt+count+2))&&
274
(*(startpnt+count+1) == *(startpnt+count+3))&&
275
(*(startpnt+count) == *(startpnt+count+4))&&
276
(*(startpnt+count+1) == *(startpnt+count+5))) &&
278
((startpnt+count) < &line_buf[(cnt+1)*line_len]) )
281
for(; count>0; count--)
282
*(bufpnt++) = *(startpnt++);
287
if (write(file,write_buf,bufpnt-write_buf) != (bufpnt-write_buf))
299
/*close file, free buffer. */
308
/*---filetype-dispatcher--------------------*/
310
const char *get_file_ext(FILE_TYP typ)
323
int bitmap_to_file(FILE_TYP typ, int ww, int wh,
324
unsigned int pwx, unsigned int pwy,
325
unsigned int planes, unsigned int colors,
326
const char *filename,
327
void (*get_color)(unsigned int colind, struct RGB *rgb),
328
void (*get_pixel)(int x, int y, unsigned int *colind))
335
return(bitmap_to_img(typ,ww,wh,pwx,pwy,planes,colors,filename,get_color,get_pixel));