1 |
/* |
2 |
* pngrender.c |
3 |
*/ |
4 |
|
5 |
/* |
6 |
________________________________________________________________________________ |
7 |
|
8 |
Copyright (c) 2001 James Bursa |
9 |
|
10 |
All rights reserved. |
11 |
|
12 |
Permission is hereby granted, free of charge, to any person obtaining a |
13 |
copy of this software and associated documentation files (the |
14 |
"Software"), to deal in the Software without restriction, including |
15 |
without limitation the rights to use, copy, modify, merge, publish, |
16 |
distribute, and/or sell copies of the Software, and to permit persons |
17 |
to whom the Software is furnished to do so, provided that the above |
18 |
copyright notice(s) and this permission notice appear in all copies of |
19 |
the Software and that both the above copyright notice(s) and this |
20 |
permission notice appear in supporting documentation. |
21 |
|
22 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
23 |
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
24 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT |
25 |
OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
26 |
HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL |
27 |
INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING |
28 |
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
29 |
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
30 |
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
31 |
|
32 |
Except as contained in this notice, the name of a copyright holder |
33 |
shall not be used in advertising or otherwise to promote the sale, use |
34 |
or other dealings in this Software without prior written authorization |
35 |
of the copyright holder. |
36 |
|
37 |
________________________________________________________________________________ |
38 |
|
39 |
james.bursa@strcprstskrzkrk.co.uk |
40 |
http://www.strcprstskrzkrk.co.uk/ |
41 |
|
42 |
________________________________________________________________________________ |
43 |
*/ |
44 |
|
45 |
#include <stdio.h> |
46 |
#include <stdlib.h> |
47 |
|
48 |
#include <png.h> |
49 |
|
50 |
#include <colourtrans.h> |
51 |
#include <os.h> |
52 |
|
53 |
/********************************************************************************/ |
54 |
|
55 |
int render_png_file(const char *path, signed int x, signed int y); |
56 |
int load_png_file(png_struct *png, png_info *info, const char *path); |
57 |
int render_png_to_screen(png_struct *png, png_info *info, signed int value_list[], |
58 |
signed int x, signed int y); |
59 |
void png_render_32(png_byte *prows[], unsigned char *srow, signed int x0, |
60 |
signed int y0, signed int x1, signed int y1, signed int sx, |
61 |
unsigned int sline_length, unsigned int pchannels); |
62 |
void png_render_16(png_byte *prows[], unsigned char *srow, signed int x0, |
63 |
signed int y0, signed int x1, signed int y1, signed int sx, |
64 |
unsigned int sline_length, unsigned int pchannels); |
65 |
int png_render_8(png_byte *prows[], unsigned char *srow, signed int x0, |
66 |
signed int y0, signed int x1, signed int y1, signed int sx, |
67 |
unsigned int sline_length, unsigned int pchannels); |
68 |
int png_render_4(png_byte *prows[], unsigned char *srow, signed int x0, |
69 |
signed int y0, signed int x1, signed int y1, signed int sx, |
70 |
unsigned int sline_length, unsigned int pchannels); |
71 |
os_palette *read_palette(); |
72 |
|
73 |
/********************************************************************************/ |
74 |
|
75 |
float alpha_table[] = { |
76 |
0.0, 1.0/255, 2.0/255, 3.0/255, 4.0/255, 5.0/255, |
77 |
6.0/255, 7.0/255, 8.0/255, 9.0/255, 10.0/255, 11.0/255, |
78 |
12.0/255, 13.0/255, 14.0/255, 15.0/255, 16.0/255, 17.0/255, |
79 |
18.0/255, 19.0/255, 20.0/255, 21.0/255, 22.0/255, 23.0/255, |
80 |
24.0/255, 25.0/255, 26.0/255, 27.0/255, 28.0/255, 29.0/255, |
81 |
30.0/255, 31.0/255, 32.0/255, 33.0/255, 34.0/255, 35.0/255, |
82 |
36.0/255, 37.0/255, 38.0/255, 39.0/255, 40.0/255, 41.0/255, |
83 |
42.0/255, 43.0/255, 44.0/255, 45.0/255, 46.0/255, 47.0/255, |
84 |
48.0/255, 49.0/255, 50.0/255, 51.0/255, 52.0/255, 53.0/255, |
85 |
54.0/255, 55.0/255, 56.0/255, 57.0/255, 58.0/255, 59.0/255, |
86 |
60.0/255, 61.0/255, 62.0/255, 63.0/255, 64.0/255, 65.0/255, |
87 |
66.0/255, 67.0/255, 68.0/255, 69.0/255, 70.0/255, 71.0/255, |
88 |
72.0/255, 73.0/255, 74.0/255, 75.0/255, 76.0/255, 77.0/255, |
89 |
78.0/255, 79.0/255, 80.0/255, 81.0/255, 82.0/255, 83.0/255, |
90 |
84.0/255, 85.0/255, 86.0/255, 87.0/255, 88.0/255, 89.0/255, |
91 |
90.0/255, 91.0/255, 92.0/255, 93.0/255, 94.0/255, 95.0/255, |
92 |
96.0/255, 97.0/255, 98.0/255, 99.0/255, 100.0/255, 101.0/255, |
93 |
102.0/255, 103.0/255, 104.0/255, 105.0/255, 106.0/255, 107.0/255, |
94 |
108.0/255, 109.0/255, 110.0/255, 111.0/255, 112.0/255, 113.0/255, |
95 |
114.0/255, 115.0/255, 116.0/255, 117.0/255, 118.0/255, 119.0/255, |
96 |
120.0/255, 121.0/255, 122.0/255, 123.0/255, 124.0/255, 125.0/255, |
97 |
126.0/255, 127.0/255, 128.0/255, 129.0/255, 130.0/255, 131.0/255, |
98 |
132.0/255, 133.0/255, 134.0/255, 135.0/255, 136.0/255, 137.0/255, |
99 |
138.0/255, 139.0/255, 140.0/255, 141.0/255, 142.0/255, 143.0/255, |
100 |
144.0/255, 145.0/255, 146.0/255, 147.0/255, 148.0/255, 149.0/255, |
101 |
150.0/255, 151.0/255, 152.0/255, 153.0/255, 154.0/255, 155.0/255, |
102 |
156.0/255, 157.0/255, 158.0/255, 159.0/255, 160.0/255, 161.0/255, |
103 |
162.0/255, 163.0/255, 164.0/255, 165.0/255, 166.0/255, 167.0/255, |
104 |
168.0/255, 169.0/255, 170.0/255, 171.0/255, 172.0/255, 173.0/255, |
105 |
174.0/255, 175.0/255, 176.0/255, 177.0/255, 178.0/255, 179.0/255, |
106 |
180.0/255, 181.0/255, 182.0/255, 183.0/255, 184.0/255, 185.0/255, |
107 |
186.0/255, 187.0/255, 188.0/255, 189.0/255, 190.0/255, 191.0/255, |
108 |
192.0/255, 193.0/255, 194.0/255, 195.0/255, 196.0/255, 197.0/255, |
109 |
198.0/255, 199.0/255, 200.0/255, 201.0/255, 202.0/255, 203.0/255, |
110 |
204.0/255, 205.0/255, 206.0/255, 207.0/255, 208.0/255, 209.0/255, |
111 |
210.0/255, 211.0/255, 212.0/255, 213.0/255, 214.0/255, 215.0/255, |
112 |
216.0/255, 217.0/255, 218.0/255, 219.0/255, 220.0/255, 221.0/255, |
113 |
222.0/255, 223.0/255, 224.0/255, 225.0/255, 226.0/255, 227.0/255, |
114 |
228.0/255, 229.0/255, 230.0/255, 231.0/255, 232.0/255, 233.0/255, |
115 |
234.0/255, 235.0/255, 236.0/255, 237.0/255, 238.0/255, 239.0/255, |
116 |
240.0/255, 241.0/255, 242.0/255, 243.0/255, 244.0/255, 245.0/255, |
117 |
246.0/255, 247.0/255, 248.0/255, 249.0/255, 250.0/255, 251.0/255, |
118 |
252.0/255, 253.0/255, 254.0/255, 1.0 }; |
119 |
|
120 |
/********************************************************************************/ |
121 |
|
122 |
int main(int argc, char *argv[]) |
123 |
{ |
124 |
char *end; |
125 |
|
126 |
if (argc != 4) |
127 |
{ |
128 |
fprintf(stderr, "Usage: pngrender file x y\n"); |
129 |
exit(1); |
130 |
} |
131 |
|
132 |
return render_png_file(argv[1], strtol(argv[2], &end, 10), strtol(argv[3], &end, 10)); |
133 |
} |
134 |
|
135 |
/******************************************************************************** |
136 |
* render a png file to the screen |
137 |
* => path -- filename of png file to render |
138 |
* x, y -- position of bottom-left corner in os units from screen bottom-left |
139 |
* <= return code: |
140 |
* 0 - OK |
141 |
* -1 - file failed to open |
142 |
* -2 - couldn't read header |
143 |
* -3 - not a png |
144 |
* -4 - bpp of png not understood |
145 |
* -5 - malloc or colourtrans failed |
146 |
* other - os error number from OS_ReadVduVariables |
147 |
*/ |
148 |
|
149 |
int render_png_file(const char *path, signed int x, signed int y) |
150 |
{ |
151 |
unsigned int status; |
152 |
signed int value_list[20]; |
153 |
png_struct *png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); |
154 |
png_info *info = png_create_info_struct(png); |
155 |
const os_vdu_var var_list[] = {os_MODEVAR_LINE_LENGTH, os_MODEVAR_LOG2_BPP, |
156 |
os_MODEVAR_XEIG_FACTOR, os_MODEVAR_YEIG_FACTOR, |
157 |
os_VDUVAR_GWL_COL, os_VDUVAR_GWB_ROW, os_VDUVAR_GWR_COL, os_VDUVAR_GWT_ROW, |
158 |
os_VDUVAR_ORGX, os_VDUVAR_ORGY, os_VDUVAR_SCREEN_START, |
159 |
os_MODEVAR_YWIND_LIMIT, -1}; |
160 |
os_error const *error; |
161 |
|
162 |
status = load_png_file(png, info, path); |
163 |
if (status) |
164 |
{ |
165 |
png_destroy_read_struct(&png, &info, (png_info **) NULL); |
166 |
return status; |
167 |
} |
168 |
|
169 |
error = xos_read_vdu_variables((os_vdu_var_list *) &var_list, value_list); |
170 |
if (error) |
171 |
{ |
172 |
png_destroy_read_struct(&png, &info, (png_info **) NULL); |
173 |
return error->errnum; |
174 |
} |
175 |
|
176 |
status = render_png_to_screen(png, info, value_list, x, y); |
177 |
png_destroy_read_struct(&png, &info, (png_info **) NULL); |
178 |
return status; |
179 |
} |
180 |
|
181 |
/********************************************************************************/ |
182 |
|
183 |
int load_png_file(png_struct *png, png_info *info, const char *path) |
184 |
{ |
185 |
unsigned char buf[10]; |
186 |
FILE *file; |
187 |
|
188 |
if (!(file = fopen(path, "rb"))) return -1; |
189 |
if (fread(buf, 1, 8, file) < 8) return -2; |
190 |
if (png_sig_cmp(buf, 0, 8) != 0) return -3; |
191 |
|
192 |
rewind(file); |
193 |
|
194 |
png_init_io(png, file); |
195 |
png_read_png(png, info, |
196 |
PNG_TRANSFORM_STRIP_16 // Strip 16-bit samples to 8 bits |
197 |
| PNG_TRANSFORM_PACKING // Expand 1, 2 and 4-bit samples to bytes |
198 |
| PNG_TRANSFORM_EXPAND // Perform set_expand() |
199 |
, NULL); |
200 |
|
201 |
fclose(file); |
202 |
|
203 |
return 0; |
204 |
} |
205 |
|
206 |
/********************************************************************************/ |
207 |
|
208 |
int render_png_to_screen(png_struct *png, png_info *info, signed int value_list[], |
209 |
signed int sx, signed int sy) |
210 |
{ |
211 |
unsigned char *srow; |
212 |
unsigned int pwidth, pheight, pchannels, sbpp, sline_length, ox, oy; |
213 |
signed int x0, y0, x1, y1; |
214 |
png_byte **prows; |
215 |
|
216 |
pchannels = png_get_channels(png, info); /* png channels, including alpha */ |
217 |
pwidth = png_get_image_width(png, info); /* png width / pixels */ |
218 |
pheight = png_get_image_height(png, info); /* png height / pixels */ |
219 |
prows = png_get_rows(png, info); /* array of png rows data */ |
220 |
|
221 |
sline_length = value_list[0]; /* screen line length / bytes */ |
222 |
sbpp = 1 << value_list[1]; /* screen depth */ |
223 |
|
224 |
ox = value_list[8] >> value_list[2]; /* graphics origin / pixels */ |
225 |
oy = value_list[9] >> value_list[2]; |
226 |
sx = (sx >> value_list[2]) + ox; /* x / pixels */ |
227 |
sy = (sy >> value_list[3]) + oy; /* y / pixels */ |
228 |
|
229 |
x0 = value_list[4] - sx; /* graphics window relative to */ |
230 |
y0 = value_list[5] - sy; /* image origin / pixels */ |
231 |
x1 = value_list[6] - sx; |
232 |
y1 = value_list[7] - sy; |
233 |
|
234 |
if (x0 < 0) x0 = 0; /* region of image to render */ |
235 |
if (y0 < 0) y0 = 0; |
236 |
if (x1 >= pwidth) x1 = pwidth - 1; |
237 |
if (y1 >= pheight) y1 = pheight - 1; |
238 |
|
239 |
if (x0 >= pwidth) return 0; /* outside graphics window */ |
240 |
if (y0 >= pheight) return 0; |
241 |
if (x1 < 0) return 0; |
242 |
if (y1 < 0) return 0; |
243 |
|
244 |
srow = (unsigned char *) (value_list[10] + |
245 |
(value_list[11] - sy - pheight + 1) * sline_length); |
246 |
|
247 |
switch (sbpp) |
248 |
{ |
249 |
case 32: |
250 |
png_render_32(prows, srow, x0, pheight - 1 - y1, x1, pheight - 1 - y0, |
251 |
sx, sline_length, pchannels); |
252 |
break; |
253 |
|
254 |
case 16: |
255 |
png_render_16(prows, srow, x0, pheight - 1 - y1, x1, pheight - 1 - y0, |
256 |
sx, sline_length, pchannels); |
257 |
break; |
258 |
|
259 |
case 8: |
260 |
return png_render_8(prows, srow, x0, pheight - 1 - y1, x1, pheight - 1 - y0, |
261 |
sx, sline_length, pchannels); |
262 |
|
263 |
case 4: |
264 |
return png_render_4(prows, srow, x0, pheight - 1 - y1, x1, pheight - 1 - y0, |
265 |
sx, sline_length, pchannels); |
266 |
} |
267 |
|
268 |
return 0; |
269 |
} |
270 |
|
271 |
/********************************************************************************/ |
272 |
|
273 |
void png_render_32(png_byte *prows[], unsigned char *srow, signed int x0, |
274 |
signed int y0, signed int x1, signed int y1, signed int sx, |
275 |
unsigned int sline_length, unsigned int pchannels) |
276 |
{ |
277 |
unsigned char pr, pg, pb, sr, sb, sg, *pbyte, *sbyte; |
278 |
unsigned int prow, pcol, palpha; |
279 |
float alphaf, ialphaf; |
280 |
|
281 |
for (prow = y0; prow <= y1; prow++) |
282 |
{ |
283 |
pbyte = prows[prow] + (x0 * pchannels); |
284 |
sbyte = srow + sline_length * prow + (sx + x0) * 4; |
285 |
|
286 |
for (pcol = x0; pcol <= x1; pcol++) |
287 |
{ |
288 |
pr = *pbyte++; |
289 |
if (pchannels == 1 || pchannels == 2) pg = pb = pr; /* greyscale */ |
290 |
else { pg = *pbyte++; pb = *pbyte++; } /* colour */ |
291 |
|
292 |
palpha = (pchannels == 4 || pchannels == 2 ? *pbyte++ : 255); |
293 |
|
294 |
if (palpha == 0) { sbyte += 4; continue; } /* fully transparent */ |
295 |
|
296 |
if (palpha != 255) /* partially transparent */ |
297 |
{ |
298 |
alphaf = alpha_table[palpha]; |
299 |
ialphaf = alpha_table[255 - palpha]; |
300 |
|
301 |
sr = *sbyte; sg = *(sbyte + 1); sb = *(sbyte + 2); |
302 |
|
303 |
pr = alphaf * pr + ialphaf * sr; |
304 |
pg = alphaf * pg + ialphaf * sg; |
305 |
pb = alphaf * pb + ialphaf * sb; |
306 |
} |
307 |
|
308 |
*sbyte++ = pr; *sbyte++ = pg; *sbyte++ = pb; sbyte++; |
309 |
} |
310 |
} |
311 |
} |
312 |
|
313 |
/********************************************************************************/ |
314 |
|
315 |
void png_render_16(png_byte *prows[], unsigned char *srow, signed int x0, |
316 |
signed int y0, signed int x1, signed int y1, signed int sx, |
317 |
unsigned int sline_length, unsigned int pchannels) |
318 |
{ |
319 |
unsigned char pr, pg, pb, sr, sb, sg, *pbyte, *sbyte; |
320 |
unsigned int prow, pcol, palpha; |
321 |
float alphaf, ialphaf; |
322 |
|
323 |
for (prow = y0; prow <= y1; prow++) |
324 |
{ |
325 |
pbyte = prows[prow] + (x0 * pchannels); |
326 |
sbyte = srow + sline_length * prow + (sx + x0) * 2; |
327 |
|
328 |
for (pcol = x0; pcol <= x1; pcol++) |
329 |
{ |
330 |
pr = *pbyte++ >> 3; |
331 |
if (pchannels == 1 || pchannels == 2) pg = pb = pr; |
332 |
else { pg = *pbyte++ >> 3; pb = *pbyte++ >> 3; } |
333 |
|
334 |
palpha = (pchannels == 4 || pchannels == 2 ? *pbyte++ : 255); |
335 |
|
336 |
if (palpha == 0) { sbyte += 2; continue; } |
337 |
|
338 |
if (palpha != 255) |
339 |
{ |
340 |
alphaf = alpha_table[palpha]; |
341 |
ialphaf = alpha_table[255 - palpha]; |
342 |
|
343 |
sr = *sbyte & 0x1f; |
344 |
sg = (*sbyte >> 5) | ((*(sbyte + 1) & 0x3) << 3); |
345 |
sb = (*(sbyte + 1) >> 2) & 0x1f; |
346 |
|
347 |
pr = alphaf * pr + ialphaf * sr; |
348 |
pg = alphaf * pg + ialphaf * sg; |
349 |
pb = alphaf * pb + ialphaf * sb; |
350 |
} |
351 |
|
352 |
*sbyte++ = (pg << 5) | pr; |
353 |
*sbyte++ = (pb << 2) | (pg >> 3); |
354 |
} |
355 |
} |
356 |
} |
357 |
|
358 |
/********************************************************************************/ |
359 |
|
360 |
int png_render_8(png_byte *prows[], unsigned char *srow, signed int x0, |
361 |
signed int y0, signed int x1, signed int y1, signed int sx, |
362 |
unsigned int sline_length, unsigned int pchannels) |
363 |
{ |
364 |
unsigned char pr, pg, pb, sr, sb, sg, *pbyte, *sbyte, map[0x1000]; |
365 |
unsigned int prow, pcol, palpha, colour; |
366 |
float alphaf, ialphaf; |
367 |
os_palette *palette; |
368 |
os_colour scolour; |
369 |
|
370 |
palette = read_palette(); |
371 |
if (!palette) return -5; |
372 |
|
373 |
for (colour = 0; colour < 0x1000; colour++) |
374 |
{ |
375 |
map[colour] = colourtrans_return_colour_number( |
376 |
((colour & 0xf) << 8) | /* red */ |
377 |
((colour & 0xf) << 12) | |
378 |
(((colour >> 4) & 0xf) << 16) | /* green */ |
379 |
(((colour >> 4) & 0xf) << 20) | |
380 |
(((colour >> 8) & 0xf) << 24) | /* blue */ |
381 |
(((colour >> 8) & 0xf) << 28)); |
382 |
} |
383 |
|
384 |
/* render image */ |
385 |
for (prow = y0; prow <= y1; prow++) |
386 |
{ |
387 |
pbyte = prows[prow] + (x0 * pchannels); |
388 |
sbyte = srow + sline_length * prow + sx + x0; |
389 |
|
390 |
for (pcol = x0; pcol <= x1; pcol++) |
391 |
{ |
392 |
pr = *pbyte++; |
393 |
if (pchannels == 1 || pchannels == 2) pg = pb = pr; |
394 |
else { pg = *pbyte++; pb = *pbyte++; } |
395 |
|
396 |
palpha = (pchannels == 4 || pchannels == 2 ? *pbyte++ : 255); |
397 |
|
398 |
if (palpha == 0) { sbyte++; continue; } |
399 |
|
400 |
if (palpha != 255) |
401 |
{ |
402 |
alphaf = alpha_table[palpha]; |
403 |
ialphaf = alpha_table[255 - palpha]; |
404 |
|
405 |
scolour = palette->entries[*sbyte]; |
406 |
sr = (scolour >> 8) & 0xff; |
407 |
sg = (scolour >> 16) & 0xff; |
408 |
sb = (scolour >> 24) & 0xff; |
409 |
|
410 |
pr = alphaf * pr + ialphaf * sr; |
411 |
pg = alphaf * pg + ialphaf * sg; |
412 |
pb = alphaf * pb + ialphaf * sb; |
413 |
} |
414 |
|
415 |
*sbyte++ = map[(pr >> 4) | (pg & 0xf0) | ((pb << 4) & 0xf00)]; |
416 |
} |
417 |
} |
418 |
|
419 |
free(palette); |
420 |
|
421 |
return 0; |
422 |
} |
423 |
|
424 |
/********************************************************************************/ |
425 |
|
426 |
int png_render_4(png_byte *prows[], unsigned char *srow, signed int x0, |
427 |
signed int y0, signed int x1, signed int y1, signed int sx, |
428 |
unsigned int sline_length, unsigned int pchannels) |
429 |
{ |
430 |
unsigned char pr, pg, pb, sr, sb, sg, *pbyte, *sbyte, map[0x1000]; |
431 |
unsigned int prow, pcol, palpha, spix, colour; |
432 |
float alphaf, ialphaf; |
433 |
os_palette *palette; |
434 |
os_colour scolour; |
435 |
|
436 |
palette = read_palette(); |
437 |
if (!palette) return -5; |
438 |
|
439 |
for (colour = 0; colour < 0x1000; colour++) |
440 |
{ |
441 |
map[colour] = colourtrans_return_colour_number( |
442 |
((colour & 0xf) << 8) | /* red */ |
443 |
((colour & 0xf) << 12) | |
444 |
(((colour >> 4) & 0xf) << 16) | /* green */ |
445 |
(((colour >> 4) & 0xf) << 20) | |
446 |
(((colour >> 8) & 0xf) << 24) | /* blue */ |
447 |
(((colour >> 8) & 0xf) << 28)); |
448 |
} |
449 |
|
450 |
/* render image */ |
451 |
for (prow = y0; prow <= y1; prow++) |
452 |
{ |
453 |
pbyte = prows[prow] + (x0 * pchannels); |
454 |
sbyte = srow + sline_length * prow + (sx + x0) / 2; |
455 |
spix = (sx + x0) & 1; |
456 |
|
457 |
for (pcol = x0; pcol <= x1; pcol++) |
458 |
{ |
459 |
pr = *pbyte++; |
460 |
if (pchannels == 1 || pchannels == 2) pg = pb = pr; |
461 |
else { pg = *pbyte++; pb = *pbyte++; } |
462 |
|
463 |
palpha = (pchannels == 4 || pchannels == 2 ? *pbyte++ : 255); |
464 |
|
465 |
if (palpha == 0) |
466 |
{ |
467 |
spix = 1 - spix; |
468 |
if (spix == 0) sbyte++; |
469 |
continue; |
470 |
} |
471 |
|
472 |
if (palpha != 255) |
473 |
{ |
474 |
alphaf = alpha_table[palpha]; |
475 |
ialphaf = alpha_table[255 - palpha]; |
476 |
|
477 |
scolour = (spix ? palette->entries[(*sbyte >> 4) & 0xf] |
478 |
: palette->entries[*sbyte & 0xf]); |
479 |
sr = (scolour >> 8) & 0xff; |
480 |
sg = (scolour >> 16) & 0xff; |
481 |
sb = (scolour >> 24) & 0xff; |
482 |
|
483 |
pr = alphaf * pr + ialphaf * sr; |
484 |
pg = alphaf * pg + ialphaf * sg; |
485 |
pb = alphaf * pb + ialphaf * sb; |
486 |
} |
487 |
|
488 |
*sbyte = (spix ? |
489 |
(map[(pr >> 4) | (pg & 0xf0) | ((pb << 4) & 0xf00)] << 4) | (*sbyte & 0xf) : |
490 |
map[(pr >> 4) | (pg & 0xf0) | ((pb << 4) & 0xf00)] | (*sbyte & 0xf0)); |
491 |
|
492 |
spix = 1 - spix; |
493 |
if (spix == 0) sbyte++; |
494 |
} |
495 |
} |
496 |
|
497 |
free(palette); |
498 |
|
499 |
return 0; |
500 |
} |
501 |
|
502 |
/******************************************************************************** |
503 |
* read screen palette |
504 |
*/ |
505 |
|
506 |
os_palette *read_palette() |
507 |
{ |
508 |
unsigned int size; |
509 |
os_palette *palette; |
510 |
os_error const *error; |
511 |
|
512 |
error = xcolourtrans_read_palette((osspriteop_area const *) -1, (osspriteop_id) -1, |
513 |
(os_palette *) 0, 0, 0, &size); |
514 |
if (error) return 0; |
515 |
|
516 |
palette = malloc(size); |
517 |
if (!palette) return 0; |
518 |
|
519 |
error = xcolourtrans_read_palette((osspriteop_area const *) -1, (osspriteop_id) -1, |
520 |
palette, size, 0, NULL); |
521 |
if (error) return 0; |
522 |
|
523 |
return palette; |
524 |
} |
525 |
|
526 |
/********************************************************************************/ |