1 /* $Header: /home/yav/xpx/RCS/tim.c,v 1.7 1996/04/24 23:08:27 yav Exp $
2 *
3 * TIM file access routine for xpx
4 * written by yav (UHD98984@pcvan.or.jp)
5 *
6 *
7 * WARNING:
8 *
9 * Permission to use and distribute this source is granted without fee.
10 * But, It is not permitted to analyze this source without license.
11 *
12 *
13 */
14
15 #include <X11/Xlib.h>
16
17 #include "xpx.h"
18 #include "headers.h"
19 #include "work.h"
20 #define PUBLIC_TIM_C
21 #include "extern.h"
22
23
24 char rcsid_tim[] = "$Id: tim.c,v 1.7 1996/04/24 23:08:27 yav Exp $";
25
26 /*
27 * TIM - Tohshinden image file format
28 *
29 * +0: Header block
30 * +0 - 3 magic number?
31 * +4 - 7 bit1-0: bytes per pixel
32 * (0: 4bits per pixel)
33 * bit3-2: bytes per color
34 * (0: no CLUT?)
35 *
36 * +8: CLUT block
37 * +0 - 3 CLUT block length
38 * +4,5 (unknown)
39 * +6,7 (unknown)
40 * +8,9 number of colors?
41 * +10,11 number of color groups?
42 * +12... color data
43 * 2bytes per color:
44 * (bit14-10:blue, 9-5:green, 4-0:red)
45 *
46 * +8+12+n*(2or3): Pixel block
47 * +0 - 3 Pixel block length
48 * +4,5 x-offset?
49 * +6,7 y-offset?
50 * +8,9 image width (unit short)
51 * +10,11 image height
52 * +12... pixel data
53 *
54 */
55
56 typedef struct _TIM_BLOCK_INFO {
57 long len; /* Block length (byte) */
58 short x, y;
59 short w, h;
60 } TIM_BLOCK_INFO;
61
read_tim_block_info(fp,p)62 int read_tim_block_info(fp, p)
63 FILE *fp;
64 TIM_BLOCK_INFO *p;
65 {
66 p->len = readlelong(fp);
67 p->x = readleshort(fp);
68 p->y = readleshort(fp);
69 p->w = readleshort(fp);
70 p->h = readleshort(fp);
71 message(" len = %ld, x = %d, y = %d, w = %d, h = %d\n",
72 p->len, p->x, p->y, p->w, p->h);
73 if (debug_mode)
74 fprintf(stderr, " len = %ld, x = %d, y = %d, w = %d, h = %d\n",
75 p->len, p->x, p->y, p->w, p->h);
76 return 0;
77 }
78
79
80 /* read CLUT block */
read_clut(fp)81 int read_clut(fp)
82 FILE *fp;
83 {
84 int i, n, c;
85 TIM_BLOCK_INFO info;
86 COL *cp;
87
88 read_tim_block_info(fp, &info);
89 free_color_all();
90 colposx = info.x;
91 colposy = info.y;
92 colfilew = info.w;
93 colfileh = info.h;
94 n = (info.len - 12) / 2; /* number of colors */
95 cp = color_buf;
96 for (i = 0; i < n; i++) {
97 c = readleshort(fp);
98 if (i < 256) {
99 cp->rgb.red = (c & 0x1f) << 3;
100 cp->rgb.green = ((c >> 5) & 0x1f) << 3;
101 cp->rgb.blue = ((c >> 10) & 0x1f) << 3;
102 cp++;
103 }
104 }
105 if (i > 256)
106 i = 256;
107 get_color(color_buf, i);
108 get_requested_colors();
109 return 0;
110 }
111
112 /* read TIM file */
rd_tim(fp)113 int rd_tim(fp)
114 FILE *fp;
115 {
116 int c;
117 int clut; /* bytes per color */
118 int bpp; /* bytes per pixel (0:4bit) */
119 int x, y, w, h;
120 long l;
121 TIM_BLOCK_INFO info;
122 unsigned char lnbuf[1024];
123
124 /* skip magic number */
125 l = readlelong(fp);
126 message("\nLoad TIM file.\n");
127 message(" magic number = 0x%08lx\n", l);
128 if (debug_mode)
129 fprintf(stderr, " magic number = 0x%08lx\n", l);
130 /* read header */
131 l = readlelong(fp);
132 c = l;
133 bpp = c & 3;
134 clut = (c >> 2) & 3;
135 message(" mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut);
136 if (debug_mode)
137 fprintf(stderr, " mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut);
138
139 if (clut)
140 read_clut(fp);
141
142 /* read pixel block */
143 read_tim_block_info(fp, &info);
144 imgposx = info.x;
145 imgposy = info.y;
146 w = info.w;
147 h = info.h;
148 for (y = 0; y < h; y++) {
149 if (y >= imgmaxh)
150 break;
151 fread(lnbuf, 1, w*2, fp);
152 switch (bpp) {
153 case 0: /* 1/2 byte per pixel */
154 for (x = 0; x < w*2; x++) {
155 imgdata[y*imgmaxw+x*2] = lnbuf[x] & 0x0f;
156 imgdata[y*imgmaxw+x*2+1] = lnbuf[x] >> 4;
157 }
158 break;
159 case 1: /* 1 byte per pixel */
160 memcpy(imgdata+y*imgmaxw, lnbuf, w*2);
161 break;
162 default: /* other depth */
163 message("!\nNot supported pixel depth!\n");
164 return 1;
165 }
166 }
167 /* calc true image width */
168 switch (bpp) {
169 case 0: /* 1/2 byte per pixel */
170 w *= 4;
171 imgfiledepth = 4;
172 break;
173 case 1: /* 1 byte per pixel */
174 w *= 2;
175 imgfiledepth = 8;
176 break;
177 default: /* other depth */
178 message("!\nNot supported pixel depth!\n");
179 return 1;
180 }
181 imgupdate(w, h);
182 return 0;
183 }
184
185 /* write TIM file */
wr_tim(fp)186 int wr_tim(fp)
187 FILE *fp;
188 {
189 long l;
190 int i, x, y;
191 COL *cp;
192 char *p;
193 char buf[1024];
194
195 setlelong(buf, 0x10L);
196 if (imgfiledepth < 0)
197 return 1;
198 if (!imgfiledepth)
199 imgfiledepth = 4;
200
201 if (imgfiledepth <= 4)
202 l = 0;
203 else if (imgfiledepth <= 8)
204 l = 1;
205 else
206 return 1;
207
208 l |= 8; /* 2 bytes per color */
209 setlelong(buf+4, l);
210 if (!fwrite(buf, 8, 1, fp))
211 return 1; /* header write error! */
212
213 /* colors */
214 l = 4 + 2 + 2 + 2 + 2 + colfilew * colfileh * 2;
215 setlelong(buf, l);
216 setleshort(buf+4, colposx);
217 setleshort(buf+6, colposy);
218 setleshort(buf+8, colfilew);
219 setleshort(buf+10, colfileh);
220 if (!fwrite(buf, 12, 1, fp))
221 return 1; /* clut block header write error! */
222
223 cp = color_buf;
224 for (y = 0; y < colfileh; y++) {
225 for (x = 0; x < colfilew; x++) {
226 l = (cp->rgb.red >> 3)
227 | ((cp->rgb.green >> 3) << 5)
228 | ((cp->rgb.blue >> 3) << 10);
229 cp++;
230 setleshort(buf+x*2, (int)l);
231 }
232 if (!fwrite(buf, colfilew*2, 1, fp))
233 return 1; /* color data write error! */
234 }
235
236 /* pixel block */
237 /* get width short count */
238 i = (imgfiledepth == 4) ? imgfilew/4 : imgfilew/2;
239 l = 4 + 2 + 2 + 2 + 2 + i * 2 * imgfileh;
240 setlelong(buf, l);
241 setleshort(buf+4, imgposx);
242 setleshort(buf+6, imgposy);
243 setleshort(buf+8, i);
244 setleshort(buf+10, imgfileh);
245 if (!fwrite(buf, 12, 1, fp))
246 return 1; /* pixel block header write error! */
247
248 if (imgfiledepth == 4) {
249 for (y = 0; y < imgfileh; y++) {
250 p = buf;
251 for (x = 0; x < i; x++) {
252 *p++ = imgdata[y*imgmaxw+x*4+0] + (imgdata[y*imgmaxw+x*4+1]<<4);
253 *p++ = imgdata[y*imgmaxw+x*4+2] + (imgdata[y*imgmaxw+x*4+3]<<4);
254 }
255 if (!fwrite(buf, i*2, 1, fp))
256 return 1; /* pixel write error! */
257 }
258 } else {
259 for (y = 0; y < imgfileh; y++) {
260 if (!fwrite(imgdata+y*imgmaxw, i*2, 1, fp))
261 return 1; /* pixel write error! */
262 }
263 }
264 return 0;
265 }
266
267 /* read CLS file */
rd_cls(fp)268 int rd_cls(fp)
269 FILE *fp;
270 {
271 long l;
272 int c, bpp, clut;
273
274 l = readlelong(fp);
275 message("\nLoad CLS file.\n");
276 message(" magic number = 0x%08lx\n", l);
277 if (debug_mode)
278 fprintf(stderr, " magic number = 0x%08lx\n", l);
279
280 /* read header */
281 l = readlelong(fp);
282 c = l;
283 bpp = c & 3;
284 clut = (c >> 2) & 3;
285 message(" mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut);
286 if (debug_mode)
287 fprintf(stderr, " mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut);
288
289 read_clut(fp);
290 return 0;
291 }
292
293 /* End of file */
294