source: trunk/JPGPROC/source/gbmsrc/gbmkps.c@ 4

Last change on this file since 4 was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 6.6 KB
Line 
1/*
2
3gbmkps.c - IBM KIPS support
4
5Reads array as 8 bit palettised colour.
6Writes 8 bit palettised colour.
7Input options: pal,kpl (default: pal)
8Output options: pal,kpl (default: pal)
9
10*/
11
12/*...sincludes:0:*/
13#include <stdio.h>
14#include <ctype.h>
15#include <stddef.h>
16#include <stdlib.h>
17#include <string.h>
18#include "gbm.h"
19#include "gbmhelp.h"
20
21/*...vgbm\46\h:0:*/
22/*...vgbmhelp\46\h:0:*/
23
24/* Handle case for UNIX machines where O_BINARY has no meaning */
25
26#ifndef O_BINARY
27#define O_BINARY 0
28#endif
29/*...e*/
30
31/*...suseful:0:*/
32#define low_byte(w) ((byte) ( (w)&0x00ffU) )
33#define high_byte(w) ((byte) (((unsigned)(w)&0xff00U)>>8))
34#define make_word(a,b) (((word)a) + (((word)b) << 8))
35/*...e*/
36/*...sextension:0:*/
37static char *extension(char *fn)
38 {
39 char *dot, *slash;
40
41 if ( (dot = strrchr(fn, '.')) == NULL )
42 return NULL;
43
44 if ( (slash = strpbrk(fn, "/\\")) == NULL )
45 return dot + 1;
46
47 return ( slash < dot ) ? dot + 1 : NULL;
48 }
49/*...e*/
50
51static GBMFT kps_gbmft =
52 {
53 "KIPS",
54 "IBM KIPS",
55 "KPS",
56 GBM_FT_R8|
57 GBM_FT_W8,
58 };
59
60#define GBM_ERR_KPS_OPEN ((GBM_ERR) 500)
61#define GBM_ERR_KPS_CREATE ((GBM_ERR) 501)
62
63/*...skps file header definition:0:*/
64/*
65This defines the 32 byte header found on .KPS and .KPL files.
66*/
67
68#define KPS_SIGNITURE "DFIMAG00"
69
70typedef struct
71 {
72 byte signiture[8]; /* Usually "DFIMAG00" */
73 byte height_low;
74 byte height_high; /* Image height in pixels */
75 byte width_low;
76 byte width_high; /* Image width in pixels */
77 byte unknown[20]; /* 20 unknown bytes */
78 } KPS_HEADER;
79/*...e*/
80
81typedef struct
82 {
83 char fn[600+1];
84 BOOLEAN kpl;
85 } KPS_PRIV;
86
87/*...skps_qft:0:*/
88GBM_ERR kps_qft(GBMFT *gbmft)
89 {
90 *gbmft = kps_gbmft;
91 return GBM_ERR_OK;
92 }
93/*...e*/
94/*...skps_rhdr:0:*/
95GBM_ERR kps_rhdr(const char *fn, int fd, GBM *gbm, const char *opt)
96 {
97 BOOLEAN pal = ( gbm_find_word(opt, "pal") != NULL );
98 BOOLEAN kpl = ( gbm_find_word(opt, "kpl") != NULL );
99 KPS_HEADER kps_header;
100 KPS_PRIV *priv = (KPS_PRIV *) gbm->priv;
101 int w, h;
102
103 if ( kpl && pal )
104 return GBM_ERR_BAD_OPTION;
105
106 gbm_file_read(fd, (char *) &kps_header, sizeof(KPS_HEADER));
107
108 if ( memcmp(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE)) )
109 return GBM_ERR_BAD_MAGIC;
110
111 w = make_word(kps_header.width_low , kps_header.width_high );
112 h = make_word(kps_header.height_low, kps_header.height_high);
113
114 if ( w <= 0 || h <= 0 )
115 return GBM_ERR_BAD_SIZE;
116
117 gbm->w = w;
118 gbm->h = h;
119 gbm->bpp = 8;
120
121 /* Keep these for a later kps_rpal() call */
122
123 strcpy(priv->fn, fn);
124 priv->kpl = kpl;
125
126 return GBM_ERR_OK;
127 }
128/*...e*/
129/*...skps_rpal:0:*/
130GBM_ERR kps_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
131 {
132 KPS_PRIV *priv = (KPS_PRIV *) gbm->priv;
133 char fn2[600+1], *ext;
134
135 fd=fd; /* Suppress 'unref arg' compiler warning */
136
137 strcpy(fn2, priv->fn);
138 ext = extension(fn2);
139 if ( priv->kpl )
140/*...sread a \46\kpl palette file:16:*/
141{
142int fd2, i, w, h;
143byte p[3][0x100];
144KPS_HEADER kps_header;
145
146if ( ext != NULL )
147 strcpy(ext, "kpl");
148else
149 strcat(fn2, ".kpl");
150
151if ( (fd2 = gbm_file_open(fn2, O_RDONLY|O_BINARY)) == -1 )
152 return GBM_ERR_KPS_OPEN;
153
154gbm_file_read(fd2, (char *) &kps_header, sizeof(KPS_HEADER));
155if ( memcmp(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE)) )
156 return GBM_ERR_BAD_MAGIC;
157
158w = make_word(kps_header.width_low , kps_header.width_high );
159h = make_word(kps_header.height_low, kps_header.height_high);
160
161if ( w != 0x100 || h != 3 )
162 return GBM_ERR_BAD_SIZE;
163
164gbm_file_read(fd2, &(p[0][0]), 0x300);
165gbm_file_close(fd2);
166
167for ( i = 0; i < 0x100; i++ )
168 {
169 gbmrgb[i].r = p[0][i];
170 gbmrgb[i].b = p[1][i];
171 gbmrgb[i].g = p[2][i];
172 }
173}
174/*...e*/
175 else
176/*...sread a \46\pal palette file:16:*/
177{
178int fd2, i;
179byte b[4];
180
181if ( ext != NULL )
182 strcpy(ext, "pal");
183else
184 strcat(fn2, ".pal");
185
186if ( (fd2 = gbm_file_open(fn2, O_RDONLY|O_BINARY)) == -1 )
187 return GBM_ERR_KPS_OPEN;
188
189for ( i = 0; i < 0x100; i++ )
190 {
191 gbm_file_read(fd2, (char *) b, 4);
192 gbmrgb[i].r = b[0];
193 gbmrgb[i].b = b[1];
194 gbmrgb[i].g = b[2];
195 }
196gbm_file_close(fd2);
197}
198/*...e*/
199
200 return GBM_ERR_OK;
201 }
202/*...e*/
203/*...skps_rdata:0:*/
204GBM_ERR kps_rdata(int fd, GBM *gbm, byte *data)
205 {
206 int i, stride;
207 byte *p;
208
209 stride = ((gbm->w + 3) & ~3);
210 p = data + ((gbm->h - 1) * stride);
211 for ( i = gbm->h - 1; i >= 0; i-- )
212 {
213 gbm_file_read(fd, p, gbm->w);
214 p -= stride;
215 }
216
217 return GBM_ERR_OK;
218 }
219/*...e*/
220/*...skps_w:0:*/
221GBM_ERR kps_w(const char *fn, int fd, const GBM *gbm, const GBMRGB *gbmrgb, const byte *data, const char *opt)
222 {
223 KPS_HEADER kps_header;
224 int i, stride;
225 const byte *p;
226 char fn2[600+1], *ext;
227 BOOLEAN pal = ( gbm_find_word(opt, "pal") != NULL );
228 BOOLEAN kpl = ( gbm_find_word(opt, "kpl") != NULL );
229
230 if ( gbm->bpp != 8 )
231 return GBM_ERR_NOT_SUPP;
232
233 if ( pal && kpl )
234 return GBM_ERR_BAD_OPTION;
235
236 memcpy(kps_header.signiture, KPS_SIGNITURE, strlen(KPS_SIGNITURE));
237 kps_header.width_low = low_byte(gbm->w);
238 kps_header.width_high = high_byte(gbm->w);
239 kps_header.height_low = low_byte(gbm->h);
240 kps_header.height_high = high_byte(gbm->h);
241 kps_header.unknown[0] = 1;
242 memset(&kps_header.unknown[1], 0, 19);
243 gbm_file_write(fd, (char *) &kps_header, sizeof(KPS_HEADER));
244
245 stride = ((gbm->w + 3) & ~3);
246 p = data + ((gbm->h - 1) * stride);
247 for ( i = gbm->h - 1; i >= 0; i-- )
248 {
249 gbm_file_write(fd, p, gbm->w);
250 p -= stride;
251 }
252
253 strcpy(fn2, fn);
254 ext = extension(fn2);
255 if ( kpl )
256/*...swrite a \46\kpl palette file:16:*/
257{
258int fd2, j;
259byte palette[3][0x100];
260
261if ( ext != NULL )
262 strcpy(ext, "kpl");
263else
264 strcat(fn2, ".kpl");
265
266if ( (fd2 = gbm_file_create(fn2, O_WRONLY|O_BINARY)) == -1 )
267 return GBM_ERR_KPS_CREATE;
268
269kps_header.width_low = low_byte(0x100);
270kps_header.width_high = high_byte(0x100);
271kps_header.height_low = low_byte(3);
272kps_header.height_high = high_byte(3);
273gbm_file_write(fd2, (char *) &kps_header, sizeof(KPS_HEADER));
274
275for ( j = 0; j < 0x100; j++ )
276 {
277 palette[0][j] = gbmrgb[j].r;
278 palette[1][j] = gbmrgb[j].b;
279 palette[2][j] = gbmrgb[j].g;
280 }
281
282gbm_file_write(fd2, &(palette[0][0]), 0x300);
283gbm_file_close(fd2);
284}
285/*...e*/
286 else
287/*...swrite a \46\pal palette file:16:*/
288{
289int fd2;
290byte b[4];
291
292if ( ext != NULL )
293 strcpy(ext, "pal");
294else
295 strcat(fn2, ".pal");
296
297if ( (fd2 = gbm_file_create(fn2, O_WRONLY|O_BINARY)) == -1 )
298 return GBM_ERR_KPS_CREATE;
299
300b[3] = 0;
301for ( i = 0; i < 0x100; i++ )
302 {
303 b[0] = gbmrgb[i].r;
304 b[1] = gbmrgb[i].b;
305 b[2] = gbmrgb[i].g;
306 gbm_file_write(fd2, (char *) b, 4);
307 }
308gbm_file_close(fd2);
309}
310/*...e*/
311
312 return GBM_ERR_OK;
313 }
314/*...e*/
315/*...skps_err:0:*/
316const char *kps_err(GBM_ERR rc)
317 {
318 switch ( (int) rc )
319 {
320 case GBM_ERR_KPS_OPEN:
321 return "can't open complementary palette file";
322 case GBM_ERR_KPS_CREATE:
323 return "can't create complementary palette file";
324 }
325 return NULL;
326 }
327/*...e*/
Note: See TracBrowser for help on using the repository browser.