1 /************************************************************************
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
25 typedef struct bmp_file_header_s
{
31 } __attribute__((packed
)) bmp_file_header_t
;
33 typedef struct bmp_info_header_s
{
39 unsigned int compression
;
40 unsigned int img_size
;
43 unsigned int palette_colors
;
44 unsigned int important_colors
;
45 } __attribute__((packed
)) bmp_info_header_t
;
47 /* is it a bmp image? */
48 int image_is_bmp(file_t
*f
)
50 bmp_file_header_t bmfh
;
51 file_read(f
,&bmfh
,sizeof(bmp_file_header_t
));
52 file_seek(f
,0,SEEK_SET
);
53 if (bmfh
.type
== 19778)
58 /* load a bitmap image to a texture */
59 int image_load_bmp(file_t
*f
, image_t
*p
)
63 unsigned char* p_data
;
65 bmp_info_header_t bmih
;
66 bmp_file_header_t bmfh
;
73 file_read(f
,&bmfh
,sizeof(bmp_file_header_t
));
74 file_read(f
,&bmih
,sizeof(bmp_info_header_t
));
79 size
= (p
->w
*p
->h
*(unsigned int)(bmih
.bpp
/8.0));
81 /* unsupported format */
85 /* get the colour index for 8bit images */
87 colours
= file_get(f
);
89 pad
= (int)((float)p
->w
*(float)bmih
.bpp
/8.0);
97 p
->pixels
= malloc(sizeof(unsigned char)*(p
->w
*p
->h
*4));
102 file_seek(f
,bmfh
.offset
,SEEK_SET
);
103 p_data
= file_get(f
);
105 /* convert whatever pixel format the image is in to 32 bit RGBA */
107 /* 8 bits per pixel */
112 for (i
=0; i
<t
;i
+=4) {
115 p
->pixels
[i
] = colours
[p_data
[j
]].b
;
116 p
->pixels
[i
+1] = colours
[p_data
[j
]].g
;
117 p
->pixels
[i
+2] = colours
[p_data
[j
]].r
;
118 p
->pixels
[i
+3] = 255;
124 for (i
=0; i
<t
; i
+=4) {
127 p
->pixels
[i
] = colours
[p_data
[j
]].b
;
128 p
->pixels
[i
+1] = colours
[p_data
[j
]].g
;
129 p
->pixels
[i
+2] = colours
[p_data
[j
]].r
;
130 p
->pixels
[i
+3] = 255;
134 /* 24 bits per pixel */
135 }else if (bmih
.bpp
== 24) {
137 for (i
=0, j
=0; j
<size
; j
+=3, i
+=4) {
140 p
->pixels
[i
+3] = 255;
141 p
->pixels
[i
+2] = p_data
[j
];
142 p
->pixels
[i
+1] = p_data
[j
+1];
143 p
->pixels
[i
] = p_data
[j
+2];
147 for (i
=0; i
<size
; i
+=4) {
148 /* if ((i+1)%pad == 0)
150 p
->pixels
[i
+3] = 255;
151 p
->pixels
[j
+2] = p_data
[i
];
152 p
->pixels
[j
+1] = p_data
[i
+1];
153 p
->pixels
[j
] = p_data
[i
+2];
157 /* 32 bits per pixel */
158 }else if (bmih
.bpp
== 32) {
161 for (y
=p
->h
-1; y
>-1; y
--) {
162 for (x
=0; x
<p
->w
; x
++) {
166 p
->pixels
[j
] = p_data
[i
+2];
167 p
->pixels
[j
+1] = p_data
[i
+1];
168 p
->pixels
[j
+2] = p_data
[i
];
169 p
->pixels
[j
+3] = p_data
[i
+3];
175 for (i
=0; i
<size
; i
+=4) {
178 p
->pixels
[j
+3] = p_data
[i
+3];
179 p
->pixels
[j
+2] = p_data
[i
];
180 p
->pixels
[j
+1] = p_data
[i
+1];
181 p
->pixels
[j
] = p_data
[i
+2];
185 /* unsupported bits per pixel */
193 /* write pixel data to a bmp image */
194 int image_save_bmp(image_t
*p
, char* file
)
199 bmp_file_header_t bmfh
;
200 bmp_info_header_t bmih
;
202 bmih
.size
= sizeof(bmp_info_header_t
);
207 bmih
.compression
= 0;
208 bmih
.img_size
= p
->w
*p
->h
*4;
211 bmih
.palette_colors
= 0;
212 bmih
.important_colors
= 0;
215 bmfh
.size
= sizeof(bmp_file_header_t
)+sizeof(bmp_info_header_t
)+bmih
.img_size
;
218 bmfh
.offset
= sizeof(bmp_file_header_t
)+sizeof(bmp_info_header_t
);
220 if (!path_get(NULL
,file
,0,buff
,2048))
222 f
= fopen(buff
,"wb");
226 fwrite(&bmfh
,sizeof(bmp_file_header_t
),1,f
);
227 fwrite(&bmih
,sizeof(bmp_info_header_t
),1,f
);
229 /* bmp expects BGRA so change it from RGBA */
230 for (i
=0; i
<bmih
.img_size
; i
+=4) {
231 fwrite(&p
->pixels
[i
+2],1,1,f
);
232 fwrite(&p
->pixels
[i
+1],1,1,f
);
233 fwrite(&p
->pixels
[i
],1,1,f
);
234 fwrite(&p
->pixels
[i
+3],1,1,f
);