Overview
Comment: | Add imgtofhm.c |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5a195fae3714fdcf06c46c7e4beb1d3b |
User & Date: | user on 2021-10-30 00:01:47 |
Other Links: | manifest | tags |
Context
2021-10-31
| ||
23:05 | Add more questions/answers in Frequently Asked Questions section. check-in: 41ebe83ec5 user: user tags: trunk | |
2021-10-30
| ||
00:01 | Add imgtofhm.c check-in: 5a195fae37 user: user tags: trunk | |
2021-10-29
| ||
23:44 | Add conversion from DOS game "Vampiric Tower". check-in: 69ea6fbdf0 user: user tags: trunk | |
Changes
Modified README from [a613e20e9f] to [461de96af6].
︙ | ︙ | |||
171 172 173 174 175 176 177 178 179 180 181 182 183 184 | * codepage.har: Contains fonts for code pages. Code page 437 is included inside of the executable file and does not need this file; this file is only needed for code pages other than 437. * default.heromeshrc: An example configuration file which you can customize for your own use. You should at least set the proper paths to the files. * mbtofhm.c: Converter from Everett Kaser's MESH engine into Free Hero Mesh. Give the base name of the output files as the command-line argument, and receives the .mb file from stdin. * misc/har.c: A small C program for dealing with Hamster archives. This is not properly a part of Free Hero Mesh (and is not needed in order to use | > > > > > > | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | * codepage.har: Contains fonts for code pages. Code page 437 is included inside of the executable file and does not need this file; this file is only needed for code pages other than 437. * default.heromeshrc: An example configuration file which you can customize for your own use. You should at least set the proper paths to the files. * imgtofhm.c: Converts pictures into the Free Hero Mesh format. The command line arguments are: the maximum number of pictures, the lump name prefix, and then the transparency colour (in hex format) (optional). It receives the pictures in farbfeld format in a vertical strip from stdin, and writes the Hamster archive to stdout (which can be appended to a .xclass file). * mbtofhm.c: Converter from Everett Kaser's MESH engine into Free Hero Mesh. Give the base name of the output files as the command-line argument, and receives the .mb file from stdin. * misc/har.c: A small C program for dealing with Hamster archives. This is not properly a part of Free Hero Mesh (and is not needed in order to use |
︙ | ︙ |
Added imgtofhm.c version [02e60ddc20].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | #if 0 gcc -s -O2 -o ./imgtofhm -Wno-unused-result -fwrapv imgtofhm.c exit #endif #define _GNU_SOURCE #include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { unsigned char size,meth; unsigned char data[0xFFFE]; // the first row is all 0, since the compression algorithm requires this } Picture; typedef struct { unsigned char x[8]; } Color; static const char default_palette[]= "C020FF " "000000 222222 333333 444444 555555 666666 777777 888888 999999 AAAAAA BBBBBB CCCCCC DDDDDD EEEEEE FFFFFF " "281400 412300 5F3200 842100 A05000 C35F14 E1731E FF8232 FF9141 FFA050 FFAF5F FFBE73 FFD282 FFE191 FFF0A0 " "321E1E 412220 5F2830 823040 A03A4C BE4658 E15464 FF6670 FF7F7B FF8E7F FF9F7F FFAF7F FFBF7F FFCF7F FFDF7F " "280D0D 401515 602020 802A2A A03535 C04040 E04A4A FF5555 FF6764 FF6F64 FF7584 FF849D FF94B7 FF9FD1 FFAEEA " "901400 A02000 B03000 C04000 D05000 E06000 F07000 FF8000 FF9000 FFA000 FFB000 FFC000 FFD000 FFE000 FFF000 " "280000 400000 600000 800000 A00000 C00000 E00000 FF0000 FF2828 FF4040 FF6060 FF8080 FFA0A0 FFC0C0 FFE0E0 " "280028 400040 600060 800080 A000A0 C000C0 E000E0 FF00FF FF28FF FF40FF FF60FF FF80FF FFA0FF FFC0FF FFE0FF " "281428 402040 603060 804080 A050A0 C060C0 E070E0 FF7CFF FF8CFF FF9CFF FFACFF FFBCFF FFCCFF FFDCFF FFECFF " "280050 350566 420A7C 4F0F92 5C14A8 6919BE 761ED4 8323EA 9028FF A040FF B060FF C080FF D0A0FF E0C0FF F0E0FF " "000028 000040 000060 000080 0000A0 0000C0 0000E0 0000FF 0A28FF 284AFF 466AFF 678AFF 87AAFF A7CAFF C7EBFF " "0F1E1E 142323 193232 1E4141 285050 325F5F 377373 418282 469191 50A0A0 5AAFAF 5FC3C3 69D2D2 73E1E1 78F0F0 " "002828 004040 006060 008080 00A0A0 00C0C0 00E0E0 00FFFF 28FFFF 40FFFF 60FFFF 80FFFF A0FFFF C0FFFF E0FFFF " "002800 004000 006000 008000 00A000 00C000 00E000 00FF00 28FF28 40FF40 60FF60 80FF80 A0FFA0 C0FFC0 E0FFE0 " "002110 234123 325F32 418241 50A050 5FC35F 73E173 85FF7A 91FF6E A0FF5F B4FF50 C3FF41 D2FF32 E1FF23 F0FF0F " "282800 404000 606000 808000 A0A000 C0C000 E0E000 FFFF00 FFFF28 FFFF40 FFFF60 FFFF80 FFFFA0 FFFFC0 FFFFE0 " "442100 00FF55 0055FF FF5500 55FF00 FF0055 5500FF CA8B25 F078F0 F0F078 FF7F00 DD6D01 7AFF00 111111 " "000000 0000AA 00AA00 00AAAA AA0000 AA00AA AAAA00 AAAAAA " "555555 5555FF 55FF55 55FFFF FF5555 FF55FF FFFF55 FFFFFF " ; static unsigned char head[16]; static int maxpic,size; static const char*prefix; static Color pal[256]; static Picture pic; static FILE*sizer; static int total=0; static ssize_t cookie_write(void*cookie,const char*buf,size_t size) { total+=size; return size; } static int cookie_seek(void*cookie,off64_t*offset,int whence) { if(whence==SEEK_SET) total=*offset; else if(whence==SEEK_CUR) total+=*offset; else return -1; *offset=total; return 0; } static void load_palette(void) { int i; for(i=0;i<256;i++) { sscanf(default_palette+i*7,"%2hhX%2hhX%2hhX ",pal[i].x+0,pal[i].x+2,pal[i].x+4); pal[i].x[1]=pal[i].x[0]; pal[i].x[3]=pal[i].x[2]; pal[i].x[5]=pal[i].x[4]; pal[i].x[7]=pal[i].x[6]=i?255:0; } } static void set_transparency(const char*s) { if(*s) switch(strlen(s)) { case 6: sscanf(s,"%2hhX%2hhX%2hhX",pal->x+0,pal->x+2,pal->x+4); pal->x[1]=pal->x[0]; pal->x[3]=pal->x[2]; pal->x[5]=pal->x[4]; pal->x[7]=pal->x[6]=255; break; case 12: sscanf(s,"%2hhX%2hhX%2hhX%2hhX%2hhX%2hhX",pal->x+0,pal->x+1,pal->x+2,pal->x+3,pal->x+4,pal->x+5); pal->x[7]=pal->x[6]=255; break; default: errx(1,"Incorrect transparency specification"); } } static void load_rotate(void) { int x,y; int m=pic.meth; unsigned char*d=pic.data+size; static unsigned char buf[255*255]; unsigned char*p; p=buf; for(y=0;y<size;y++) for(x=0;x<size;x++) { if(m&1) x=size-x-1; if(m&2) y=size-y-1; *p++=d[m&4?x*size+y:y*size+x]; if(m&1) x=size-x-1; if(m&2) y=size-y-1; } memcpy(d,buf,size*size); } static void out_run(FILE*fp,int ch,int am,const unsigned char*d,int le) { int n=am%85?:85; fputc(ch+n-1,fp); if(le) fwrite(d,1,le<n?le:n,fp); if(ch) d+=n,le-=n; while(am-=n) { n=am>7225?7225:am; fputc(ch+n/85-1,fp); if(le>0) fwrite(d,1,le<n?le:n,fp); if(ch) d+=n,le-=n; } } static void compress_picture(FILE*fp) { int ps=pic.size; int ms=ps*ps; const unsigned char*d=pic.data+ps; int i=0; int ca,homo,hetero; while(i<ms) { ca=0; while(i+ca<ms && d[i+ca]==d[i+ca-ps]) ca++; homo=1; while(i+homo<ms && d[i+homo]==d[i]) homo++; hetero=1; while(i+hetero<ms) { if(d[i+hetero]==d[i+hetero-ps] && d[i+hetero+1]==d[i+hetero+1-ps]) break; if(d[i+hetero]==d[i+hetero+1] && i+hetero==ms-1) break; if(d[i+hetero]==d[i+hetero+1] && d[i+hetero]==d[i+hetero+2]) break; hetero++; } if(ca>=homo && (ca>=hetero || homo>1)) { out_run(fp,170,ca,0,0); i+=ca; } else if(homo>1) { out_run(fp,0,homo-1,d+i,1); i+=homo; } else { if(hetero>85) hetero=85; out_run(fp,85,hetero,d+i,hetero); i+=hetero; } } } static void import_one(int numb) { int a,b,i,j,m,s,x,y; unsigned char buf[8]; unsigned char*q; // Load picture data pic.size=size; pic.meth=15; memset(pic.data,0,255); q=pic.data+pic.size; for(y=0;y<size;y++) for(x=0;x<size;x++) { if(fread(buf,1,8,stdin)<=0) err(1,"I/O error"); if(buf[6]&0x80) { for(i=0;i<255;i++) if(!memcmp(buf,pal[i].x,8)) goto found; i=1; a=0x300000; for(j=1;j<255;j++) { b=abs(buf[0]-pal[j].x[0])+abs(buf[2]-pal[j].x[2])+abs(buf[4]-pal[j].x[4]); if(b<=a) a=b,i=j; } found: *q++=i; } else { *q++=0; } } // Try compression m=15; s=size*size; rewind(sizer); for(i=0;i<8;i++) { compress_picture(sizer); j=ftell(sizer); if(j>0 && j<s) s=j,m=i; rewind(sizer); pic.meth="\1\3\1\7\1\3\1\7"[i]; load_rotate(); } // Write header s+=2; printf("%s%d.IMG",prefix,numb); putchar(0); putchar(s>>020); putchar(s>>030); putchar(s>>000); putchar(s>>010); // Write compressed data putchar((m<<4)|1); putchar(size); pic.meth=m; load_rotate(); if(m==15) fwrite(pic.data+pic.size,pic.size,pic.size,stdout); else compress_picture(stdout); } int main(int argc,char**argv) { int i; if(argc!=3 && argc!=4) errx(1,"Incorrect number of arguments"); maxpic=strtol(argv[1],0,10); prefix=argv[2]; load_palette(); if(argc==4) set_transparency(argv[3]); sizer=fopencookie("","w+",(cookie_io_functions_t){.write=cookie_write,.seek=cookie_seek}); if(!sizer) err(1,"Allocation failed"); fread(head,1,16,stdin); if(memcmp(head,"farbfeld",8)) errx(1,"Unrecognized input format"); if(head[8]|head[9]|head[10]) errx(1,"Picture is too big"); size=head[11]; if(!size) errx(1,"Wrong horizontal size"); i=(head[12]<<030)|(head[13]<<020)|(head[14]<<010)|(head[15]<<000); if(!i) errx(1,"Wrong vertical size"); if(maxpic>i/size || maxpic<=0) { maxpic=i/size; if(i%size) errx(1,"Wrong vertical size"); } for(i=0;i<maxpic;i++) import_one(i); return 0; } |