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 \****************************/
11 * $ANH-Date: 1432512809 2015/05/25 00:13:29 $ $ANH-Branch: master $:$ANH-Revision: 1.4 $
22 /* --- (X) IMG-Implementation ----------------- */
24 #define IMG_COMPRESSED
37 typedef enum { NONE
, SOLID0
, SOLID1
, PATRUN
, BITSTR
} IMG_MODE
;
39 typedef UBYTE IMG_SOLID
;
41 typedef enum { RGB
= 0, CMY
= 1, Pantone
= 2 } XIMG_COLMODEL
;
45 XIMG_COLMODEL img_colmodel
;
48 typedef struct RGB XIMG_RGB
;
51 bitmap_to_img(FILE_TYP typ
, int ww
, int wh
, unsigned int pixw
,
52 unsigned int pixh
, 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;
74 (UWORD
)(sizeof(xheader
) + colors
* sizeof(xrgb
)) / 2;
76 header
.img_nplanes
= planes
;
77 header
.img_patlen
= 2;
78 header
.img_pixw
= pixw
;
79 header
.img_pixh
= pixh
;
83 xheader
.img_ximg
= XIMG_MAGIC
;
84 xheader
.img_colmodel
= RGB
;
86 /* calculate linelength, allocate buffer. */
88 line_len
= (ww
+ 7) / 8;
90 line_buf
= malloc((size_t) planes
* line_len
);
94 /* Worst case: the bufferd line could grow to max. 3 times the length */
98 write_buf
= malloc((size_t) 3 * line_len
);
99 if (write_buf
== NULL
) {
106 file
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
);
116 if (write(file
, &header
, sizeof(header
)) != sizeof(header
)
118 && write(file
, &xheader
, sizeof(xheader
)) != sizeof(xheader
))) {
126 /* save the colortable if possible */
129 for (cnt
= 0; cnt
< colors
; cnt
++) {
130 get_color(cnt
, &xrgb
);
131 if (write(file
, &xrgb
, sizeof(xrgb
)) != sizeof(xrgb
)) {
140 /* And now line by line ... */
142 for (line
= 0; line
< wh
; line
++) {
143 /* get pixel, split it up and */
144 /* store it as planes in buffer */
146 for (byte
= 0; byte
< line_len
; byte
++) {
147 for (cnt
= 0; cnt
< planes
; cnt
++)
148 line_buf
[cnt
* line_len
+ byte
] = 0x00;
150 for (bit
= 0; bit
< 8; bit
++) {
151 if (8 * byte
+ bit
< ww
)
152 get_pixel(8 * byte
+ bit
, line
, &colind
);
154 for (cnt
= 0; cnt
< planes
; cnt
++) {
155 line_buf
[cnt
* line_len
+ byte
] <<= 1;
156 line_buf
[cnt
* line_len
+ byte
] |= colind
& 0x01;
162 /* compress bitstrings in buffer */
163 /* and write it to file */
165 for (cnt
= 0; cnt
< planes
; cnt
++) {
166 /* Bitstringpointer to start of plane */
168 startpnt
= &line_buf
[cnt
* line_len
];
171 while (startpnt
< &line_buf
[(cnt
+ 1) * line_len
]) {
172 /*********************************************/
173 /* Which _new_ compression-mode "fits" the */
176 /* Note: the compressing modes get choosen */
177 /* "positive". The non compressing BITSTR- */
178 /* mode is choosen only if nothing else */
181 /*********************************************/
191 if (startpnt
< &line_buf
[(cnt
+ 1) * line_len
- 3]
192 && *(startpnt
) == *(startpnt
+ 2)
193 && *(startpnt
+ 1) == *(startpnt
+ 3))
199 /************************************************/
200 /* The mode is choosen, now work with it.
202 /* The compressing modi stay current as long as */
205 /************************************************/
211 while ((startpnt
< &line_buf
[(cnt
+ 1) * line_len
])
212 && (*(startpnt
) == 0x00) && (count
< 0x7F)) {
220 while ((startpnt
< &line_buf
[(cnt
+ 1) * line_len
])
221 && (*(startpnt
) == 0xFF) && (count
< 0x7F)) {
225 *(bufpnt
++) = 0x80 | count
;
232 while (startpnt
< &line_buf
[(cnt
+ 1) * line_len
- 1]
233 && *(startpnt
) == *(startpnt
- 2)
234 && *(startpnt
+ 1) == *(startpnt
- 1)
240 *(bufpnt
++) = *(startpnt
- 2);
241 *(bufpnt
++) = *(startpnt
- 1);
244 /************************************************/
245 /* The while Condition is ment as follows: */
247 /* while ( NOT(2-Byte-Solidrun possible) &&
249 /* NOT(6-Byte-Patternrun possible) &&
253 /* still Bytes remaining )
256 /* As soon as a _compressing_ alternative shows */
257 /* up, BITSTR gets cancelled!
259 /************************************************/
263 while (!(((startpnt
+ count
)
264 < &line_buf
[(cnt
+ 1) * line_len
- 1])
265 && (((*(startpnt
+ count
) == 0xFF)
266 && (*(startpnt
+ count
+ 1) == 0xFF))
267 || ((*(startpnt
+ count
) == 0x00)
268 && (*(startpnt
+ count
+ 1) == 0x00))))
269 && !(((startpnt
+ count
)
270 < &line_buf
[(cnt
+ 1) * line_len
- 5])
271 && (*(startpnt
+ count
)
272 == *(startpnt
+ count
+ 2))
273 && (*(startpnt
+ count
+ 1)
274 == *(startpnt
+ count
+ 3))
275 && (*(startpnt
+ count
)
276 == *(startpnt
+ count
+ 4))
277 && (*(startpnt
+ count
+ 1)
278 == *(startpnt
+ count
+ 5)))
280 && ((startpnt
+ count
)
281 < &line_buf
[(cnt
+ 1) * line_len
]))
284 for (; count
> 0; count
--)
285 *(bufpnt
++) = *(startpnt
++);
290 if (write(file
, write_buf
, bufpnt
- write_buf
)
291 != (bufpnt
- write_buf
)) {
301 /*close file, free buffer. */
309 /*---filetype-dispatcher--------------------*/
312 get_file_ext(FILE_TYP typ
)
324 bitmap_to_file(FILE_TYP typ
, int ww
, int wh
, unsigned int pwx
,
325 unsigned int pwy
, 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
))
333 return (bitmap_to_img(typ
, ww
, wh
, pwx
, pwy
, planes
, colors
, filename
,
334 get_color
, get_pixel
));