Skip to content

Commit ac48824

Browse files
committed
Bundle FileBMP.HC, update package manifest
1 parent 19df6be commit ac48824

File tree

4 files changed

+394
-3
lines changed

4 files changed

+394
-3
lines changed

FileBMP.HC

Lines changed: 387 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,387 @@
1+
#help_index "Graphics/Windows BMP Files"
2+
3+
#define BMP_COLORS_NUM 16
4+
5+
class CFileBMP
6+
{
7+
U16 type;
8+
U32 file_size;
9+
U32 reserved;
10+
U32 data_offset;
11+
12+
U32 header_size;
13+
U32 width;
14+
U32 height;
15+
U16 planes;
16+
U16 bit_cnt;
17+
U32 compression;
18+
U32 image_size;
19+
U32 x_pixs_per_meter;
20+
U32 y_pixs_per_meter;
21+
U32 colors_used;
22+
U32 important_colors;
23+
24+
U0 end;
25+
26+
CBGR24 palette[BMP_COLORS_NUM];
27+
};
28+
29+
public CFileBMP *BMP4To(CDC *dc)
30+
{//To Windows 4-bit BMP.
31+
U8 *src,*ptr;
32+
CBGR48 palette[COLORS_NUM];
33+
I64 i,x,y,w=dc->width>>1,
34+
size=sizeof(CFileBMP)+dc->width*dc->height>>1;
35+
CFileBMP *bmp =CAlloc(size);
36+
bmp->type ='BM';
37+
bmp->planes =1;
38+
bmp->file_size=size;
39+
bmp->data_offset=sizeof(CFileBMP);
40+
bmp->header_size=offset(CFileBMP.end)-offset(CFileBMP.header_size);
41+
bmp->width =dc->width;
42+
bmp->height =dc->height;
43+
bmp->bit_cnt =4;
44+
bmp->image_size=dc->width*dc->height>>1;
45+
GrPaletteGet(palette);
46+
#assert COLORS_NUM==BMP_COLORS_NUM
47+
for (i=0;i<BMP_COLORS_NUM;i++) {
48+
bmp->palette[i].b=palette[i].b>>8;
49+
bmp->palette[i].g=palette[i].g>>8;
50+
bmp->palette[i].r=palette[i].r>>8;
51+
bmp->palette[i].pad=0;
52+
}
53+
ptr=bmp(U8 *)+bmp->data_offset;
54+
for (y=dc->height-1;y>=0;y--) {
55+
src=y*dc->width_internal+dc->body;
56+
for (x=0;x<w;x++) {
57+
*ptr|=(*src++&15)<<4;
58+
*ptr|=*src++&15;
59+
ptr++;
60+
}
61+
}
62+
return bmp;
63+
}
64+
65+
public CFileBMP *BMPRLE4To(CDC *dc)
66+
{//To Windows RLE4 bit BMP.
67+
U8 *src,*ptr,*start;
68+
I64 i,x,y,w=dc->width,cnt,pattern;
69+
CBGR48 palette[COLORS_NUM];
70+
CFileBMP *bmp =CAlloc(sizeof(CFileBMP)+2*(dc->width+1)*dc->height);
71+
bmp->type ='BM';
72+
bmp->planes =1;
73+
bmp->data_offset=sizeof(CFileBMP);
74+
bmp->header_size=offset(CFileBMP.end)-offset(CFileBMP.header_size);
75+
bmp->width =dc->width;
76+
bmp->height =dc->height;
77+
bmp->bit_cnt =4;
78+
bmp->compression=2; //RLE4
79+
GrPaletteGet(palette);
80+
#assert COLORS_NUM==BMP_COLORS_NUM
81+
for (i=0;i<BMP_COLORS_NUM;i++) {
82+
bmp->palette[i].b=palette[i].b>>8;
83+
bmp->palette[i].g=palette[i].g>>8;
84+
bmp->palette[i].r=palette[i].r>>8;
85+
bmp->palette[i].pad=0;
86+
}
87+
start=ptr=bmp(U8 *)+bmp->data_offset;
88+
for (y=dc->height-1;y>=0;y--) {
89+
src=y*dc->width_internal+dc->body;
90+
x=0;
91+
while (x<w) {
92+
pattern=(src[0]&15)<<4+src[1]&15;
93+
if (x+1<w && src[0]&15==src[1]&15) {
94+
src+=2;
95+
cnt=2;
96+
x+=2;
97+
while (x<w && cnt<U8_MAX) {
98+
if (*src&15==pattern&15) {
99+
src++;
100+
cnt++;
101+
x++;
102+
} else
103+
break;
104+
}
105+
} else {
106+
src+=2;
107+
if (x+1<w)
108+
cnt=2;
109+
else
110+
cnt=1;
111+
x+=2;
112+
}
113+
*ptr++=cnt;
114+
*ptr++=pattern;
115+
}
116+
*ptr(U16 *)++=0;
117+
}
118+
bmp->image_size=ptr-start;
119+
bmp->file_size=sizeof(CFileBMP)+bmp->image_size;
120+
return bmp;
121+
}
122+
123+
public CFileBMP *BMP24To(CDC *dc)
124+
{//To Windows 24-bit BMP.
125+
U8 *src;
126+
I64 i,x,y,size=offset(CFileBMP.end)+dc->width*dc->height*sizeof(CBGR24);
127+
CBGR24 *bgr;
128+
CFileBMP *bmp =CAlloc(size);
129+
bmp->type ='BM';
130+
bmp->planes =1;
131+
bmp->file_size=size;
132+
bmp->data_offset=offset(CFileBMP.end);
133+
bmp->header_size=offset(CFileBMP.end)-offset(CFileBMP.header_size);
134+
bmp->width =dc->width;
135+
bmp->height =dc->height;
136+
bmp->bit_cnt =32;
137+
bmp->image_size=dc->width*dc->height<<2;
138+
139+
bgr=bmp(U8 *)+bmp->data_offset;
140+
for (y=dc->height-1;y>=0;y--) {
141+
src=y*dc->width_internal+dc->body;
142+
for (x=0;x<dc->width;x++) {
143+
i=*src++;
144+
if (i&BLUE) bgr->b=0x7F;
145+
if (i&GREEN) bgr->g=0x7F;
146+
if (i&RED) bgr->r=0x7F;
147+
if (i&8) {
148+
if (bgr->b) bgr->b=0xFF;
149+
if (bgr->g) bgr->g=0xFF;
150+
if (bgr->r) bgr->r=0xFF;
151+
}
152+
bgr(U8 *)+=4;
153+
}
154+
}
155+
return bmp;
156+
}
157+
158+
public I64 BMPWrite(U8 *filename,CDC *dc,I64 bits=4)
159+
{//Window's BMP Files.
160+
I64 size;
161+
CFileBMP *bmp;
162+
if (bits==4) {
163+
if (IsDotZ(filename)) //.Z compression is better than RLE
164+
bmp=BMP4To(dc);
165+
else {
166+
bmp=BMPRLE4To(dc);
167+
if (bmp->file_size>sizeof(CFileBMP)+dc->width*dc->height>>1) {
168+
Free(bmp);
169+
bmp=BMP4To(dc);
170+
}
171+
}
172+
} else if (bits==24)
173+
bmp=BMP24To(dc);
174+
else {
175+
"Format Not Supported.\n";
176+
return 0;
177+
}
178+
size=bmp->file_size;
179+
FileWrite(filename,bmp,bmp->file_size);
180+
Free(bmp);
181+
return size;
182+
}
183+
184+
U8 *BMPPaletteNew(CFileBMP *bmp)
185+
{
186+
I64 i,j,best,score,best_score;
187+
CBGR48 palette[COLORS_NUM];
188+
U8 *res=CAlloc(BMP_COLORS_NUM*sizeof(U8));
189+
GrPaletteGet(palette);
190+
#assert COLORS_NUM==BMP_COLORS_NUM
191+
for (i=0;i<BMP_COLORS_NUM;i++) {
192+
best=i;
193+
best_score=I64_MAX;
194+
for (j=0;j<BMP_COLORS_NUM;j++) {
195+
score=SqrI64(bmp->palette[i].r-palette[j].r>>8)+
196+
SqrI64(bmp->palette[i].g-palette[j].g>>8)+
197+
SqrI64(bmp->palette[i].b-palette[j].b>>8);
198+
if (score<best_score) {
199+
best=j;
200+
best_score=score;
201+
}
202+
}
203+
res[i]=best;
204+
}
205+
return res;
206+
}
207+
208+
U8 ms_paint_palette[BMP_COLORS_NUM]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15};
209+
210+
I64 BMP24Color(CBGR24 *ptr,Bool dither_probability)
211+
{
212+
I64 res,k;
213+
if (dither_probability) {
214+
k=RandU32;
215+
if (SqrI64(ptr->r)+SqrI64(ptr->g)+SqrI64(ptr->b)>=3*SqrI64(k.u8[0]))
216+
res=8;
217+
else
218+
res=0;
219+
if (ptr->r>=k.u8[1]) res|=RED;
220+
if (ptr->g>=k.u8[2]) res|=GREEN;
221+
if (ptr->b>=k.u8[3]) res|=BLUE;
222+
} else {
223+
if (SqrI64(ptr->r)+SqrI64(ptr->g)+SqrI64(ptr->b)>=SqrI64(0x80)) {
224+
res=8;
225+
if (ptr->r>=0x80) res|=RED;
226+
if (ptr->g>=0x80) res|=GREEN;
227+
if (ptr->b>=0x80) res|=BLUE;
228+
} else {
229+
res=0;
230+
if (ptr->r>=0x40) res|=RED;
231+
if (ptr->g>=0x40) res|=GREEN;
232+
if (ptr->b>=0x40) res|=BLUE;
233+
}
234+
}
235+
return res;
236+
}
237+
238+
public CDC *BMPRead(U8 *filename,Bool dither_probability=FALSE,
239+
Bool use_ms_paint_palette=FALSE)
240+
{//Window's BMP Files.
241+
I64 i,j,cnt;
242+
U8 *palette_map,*ptr;
243+
Bool rle;
244+
CFileBMP *bmp;
245+
CDC *res=NULL;
246+
if (ptr=FileRead(filename)) {
247+
bmp=ptr;
248+
if (0<bmp->width<I32_MAX && 0<bmp->height<I32_MAX) {
249+
res=DCNew(bmp->width,bmp->height);
250+
ptr+=bmp->data_offset;
251+
if (bmp->compression==2)
252+
rle=TRUE;
253+
else
254+
rle=FALSE;
255+
if (use_ms_paint_palette)
256+
palette_map=ms_paint_palette;
257+
else
258+
palette_map=BMPPaletteNew(bmp);
259+
if (bmp->bit_cnt==4) {
260+
for (i=bmp->height-1;i>=0;i--)
261+
if (rle) {//We don't support full RLE4, just our own subset
262+
j=0;
263+
while (cnt=*ptr++) {
264+
if (cnt==1) {
265+
res->color=palette_map[*ptr++&15];
266+
GrPlot(res,j++,i);
267+
} else {
268+
if (cnt==2 && *ptr>>4!=*ptr&15) {
269+
res->color=palette_map[*ptr&15];
270+
GrPlot(res,j+1,i);
271+
res->color=palette_map[*ptr>>4];
272+
GrPlot(res,j,i);
273+
ptr++;
274+
j+=2;
275+
} else {
276+
res->color=palette_map[*ptr++&15];
277+
while (cnt--)
278+
GrPlot(res,j++,i);
279+
}
280+
}
281+
}
282+
ptr++;
283+
} else
284+
for (j=0;j<(bmp->width+7)&~7;) {
285+
res->color=palette_map[*ptr&15];
286+
GrPlot(res,j+1,i);
287+
res->color=palette_map[*ptr>>4];
288+
GrPlot(res,j,i);
289+
ptr++;
290+
j+=2;
291+
}
292+
if (!use_ms_paint_palette)
293+
Free(palette_map);
294+
} else if (bmp->bit_cnt==24) {
295+
for (i=bmp->height-1;i>=0;i--) {
296+
for (j=0;j<bmp->width;j++,ptr+=3) {
297+
res->color=BMP24Color(ptr,dither_probability);
298+
GrPlot(res,j,i);
299+
}
300+
ptr+=bmp->width&3;
301+
}
302+
if (!use_ms_paint_palette)
303+
Free(palette_map);
304+
} else if (bmp->bit_cnt>=32) {
305+
for (i=bmp->height-1;i>=0;i--)
306+
for (j=0;j<bmp->width;j++,ptr+=4) {
307+
res->color=BMP24Color(ptr,dither_probability);
308+
GrPlot(res,j,i);
309+
}
310+
if (!use_ms_paint_palette)
311+
Free(palette_map);
312+
} else {
313+
"Format Not Supported.\n";
314+
DCDel(res);
315+
res=NULL;
316+
}
317+
} else
318+
"Invalid BMP File\n";
319+
Free(bmp);
320+
}
321+
return res;
322+
}
323+
324+
#help_index "Graphics/Sprite;Graphics/Windows BMP Files;"\
325+
"DolDoc/Output;StdOut/DolDoc"
326+
public U0 DocBMP(CDoc *doc=NULL,U8 *filename,Bool dither_probability=FALSE,
327+
Bool use_ms_paint_palette=FALSE)
328+
{//Put a BMP file into a document as a sprite.
329+
CDC *dc=BMPRead(filename,dither_probability,use_ms_paint_palette);
330+
U8 *elems=DC2Sprite(dc);
331+
DocSprite(doc,elems);
332+
Free(elems);
333+
DCDel(dc);
334+
}
335+
336+
#help_index "Graphics/Windows BMP Files;Graphics/Scrn"
337+
public I64 BMPScrnCapture(U8 *filename,I64 bits=4,Bool include_zoom=TRUE)
338+
{//Capture scrn as BMP file.
339+
CDC *dc=DCScrnCapture(include_zoom);
340+
I64 size=BMPWrite(filename,dc,bits);
341+
DCDel(dc);
342+
return size;
343+
}
344+
345+
public I64 GR2BMPLst(U8 *files_find_mask,U8 *fu_flags=NULL,
346+
U8 *out_print_fmt="~:/Tmp/VID%05d.BMP.Z",F64 fps=30000.0/1001)
347+
{/*Cvt movie from GR lst to BMP lst
348+
"+d" will delete GRLst files.
349+
*/
350+
I64 res=0,fuf_flags=0;
351+
CDirEntry *tmpde,*tmpde1;
352+
CDC *dc,*base=DCNew(GR_WIDTH,GR_HEIGHT);
353+
U8 *st,*last_st;
354+
CDate in_cdt,out_cdt=I64_MIN;
355+
Bool old_silent;
356+
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
357+
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
358+
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND);
359+
last_st=MStrPrint(out_print_fmt,0);
360+
progress1_max=LinkedLstCnt(tmpde);
361+
while (tmpde) {
362+
dc=GRRead(tmpde->full_name);
363+
GrBlot(base,dc->x0,dc->y0,dc);
364+
in_cdt=Str2I64(tmpde->name,16);
365+
if (out_cdt==I64_MIN)
366+
out_cdt=in_cdt;
367+
while (out_cdt<=in_cdt) {
368+
st=MStrPrint(out_print_fmt,res++);
369+
BMPWrite(st,base);
370+
Free(st);
371+
out_cdt+=CDATE_FREQ/fps;
372+
}
373+
if (fuf_flags&FUF_DEL) {
374+
old_silent=Silent;
375+
Del(tmpde->full_name);
376+
Silent(old_silent);
377+
}
378+
DCDel(dc);
379+
progress1++;
380+
tmpde=tmpde->next;
381+
}
382+
progress1=progress1_max=0;
383+
DirTreeDel(tmpde1);
384+
Free(last_st);
385+
DCDel(base);
386+
return res;
387+
}

Screenfetch.HC

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// vim: set ft=cpp:
22

3+
#include "/Apps/Screenfetch/FileBMP"
4+
35
#define OS_NAME "$TX+CX,"TempleOS",D="DD_OS_NAME_VERSION"$"
46

57
U8 buf[256];

0 commit comments

Comments
 (0)