1 /* SCCS Id: @(#)xpm2iff.c 3.2 95/08/04 */
2 /* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */
3 /* NetHack may be freely redistributed. See license for details. */
12 #include <dos/dosextens.h>
13 #include <graphics/gfx.h>
14 #include <graphics/gfxbase.h>
15 #include <graphics/view.h>
16 #include <libraries/iffparse.h>
17 #include <libraries/dos.h>
19 # include <proto/iffparse.h>
20 # include <proto/dos.h>
21 # include <proto/exec.h>
35 /* translation table from xpm characters to RGB and colormap slots */
39 int slot; /* output colortable index */
42 pixval ColorMap[3][MAXCOLORMAPSIZE];
46 * We are using a hybrid form of our own design which we call a BMAP (for
47 * bitmap) form. It is an ILBM with the bitmaps already deinterleaved,
48 * completely uncompressed.
49 * This speeds the loading of the images from the games point of view because it
50 * does not have to deinterleave and uncompress them.
52 #define ID_BMAP MAKE_ID( 'B', 'M', 'A', 'P' ) /* instead of ILBM */
53 #define ID_BMHD MAKE_ID( 'B', 'M', 'H', 'D' ) /* Same as ILBM */
54 #define ID_CAMG MAKE_ID( 'C', 'A', 'M', 'G' ) /* Same as ILBM */
55 #define ID_CMAP MAKE_ID( 'C', 'M', 'A', 'P' ) /* Same as ILBM */
56 #define ID_PDAT MAKE_ID( 'P', 'D', 'A', 'T' ) /* Extra data describing plane
57 * size due to graphics.library
58 * rounding requirements.
60 #define ID_PLNE MAKE_ID( 'P', 'L', 'N', 'E' ) /* The planes of the image */
64 /* BMHD from IFF documentation */
72 UWORD transparentColor;
73 UBYTE xAspect, yAspect;
74 WORD pageWidth, pageHeight;
81 pixel pixels[TILE_Y][TILE_X];
87 fprintf( stderr, "ERROR: %s\n", str );
92 main( int argc, char **argv )
104 long pbytes; /* Bytes of data in a plane */
107 struct IFFHandle *iff;
108 long camg = HIRES|LACE;
112 #if defined(_DCC) || defined (__GNUC__)
113 IFFParseBase = OpenLibrary( "iffparse.library", 0 );
114 if( !IFFParseBase ) {
115 error( "unable to open iffparse.library" );
120 if( fopen_xpm_file( argv[1], "r" ) != TRUE )
127 i = XpmScreen.Colors - 1;
134 planes = malloc( nplanes * sizeof( char * ) );
137 error( "can not allocate planes pointer" );
141 XpmScreen.BytesPerRow = ((XpmScreen.Width + 15)/16)*2;
142 pbytes = XpmScreen.BytesPerRow * XpmScreen.Height;
143 for( i = 0; i < nplanes; ++i )
145 planes[ i ] = malloc( pbytes );
146 if( planes[ i ] == 0 )
148 error( "can not allocate planes pointer" );
151 memset( planes[i], 0, pbytes );
157 error( "Can not allocate IFFHandle" );
161 iff->iff_Stream = Open( argv[2], MODE_NEWFILE );
162 if( !iff->iff_Stream )
164 error( "Can not open output file" );
169 OpenIFF( iff, IFFF_WRITE );
171 PushChunk( iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN );
173 bmhd.w = XpmScreen.Width;
174 bmhd.h = XpmScreen.Height;
177 bmhd.nPlanes = nplanes;
179 bmhd.compression = 0;
181 bmhd.transparentColor = 0;
184 bmhd.pageWidth = 0; /* not needed for this program */
185 bmhd.pageHeight = 0; /* not needed for this program */
187 PushChunk( iff, ID_BMAP, ID_BMHD, sizeof( bmhd ) );
188 WriteChunkBytes( iff, &bmhd, sizeof( bmhd ) );
191 PushChunk( iff, ID_BMAP, ID_CAMG, sizeof( camg ) );
192 WriteChunkBytes( iff, &camg, sizeof( camg ) );
196 cmap = malloc( (colors = (1L<<nplanes)) * sizeof(AmiColorMap) );
198 error("Can't allocate color map");
201 for(index = 0; index<256; index++){
202 if(ttable[index].flag){
203 cmap[ttable[index].slot].r = SCALE(ttable[index].r);
204 cmap[ttable[index].slot].g = SCALE(ttable[index].g);
205 cmap[ttable[index].slot].b = SCALE(ttable[index].b);
210 PushChunk( iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN );
211 WriteChunkBytes( iff, cmap, colors*sizeof(*cmap) );
216 pdat.nplanes = nplanes;
217 pdat.pbytes = pbytes;
218 pdat.xsize = XpmScreen.Width;
219 pdat.ysize = XpmScreen.Height;
224 PushChunk( iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN );
225 WriteChunkBytes( iff, &pdat, sizeof( pdat ) );
228 PushChunk( iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN );
229 for( i = 0; i < nplanes; ++i )
230 WriteChunkBytes( iff, planes[i], pbytes );
234 Close( iff->iff_Stream );
237 #if defined(_DCC) || defined (__GNUC__)
238 CloseLibrary( IFFParseBase );
243 #define SETBIT(Plane, Plane_offset, Col, Value) \
245 planes[Plane][Plane_offset + (Col/8)] |= 1<<(7-(Col & 7)); \
249 int row, col, planeno;
251 for(row = 0;row<XpmScreen.Height;row++){
252 char *xb = xpmgetline();
255 plane_offset = row*XpmScreen.BytesPerRow;
256 for(col = 0;col<XpmScreen.Width;col++){
259 if(!ttable[color].flag){
260 fprintf(stderr, "Bad image data\n");
262 slot = ttable[color].slot;
263 for(planeno = 0; planeno<nplanes; planeno++){
264 SETBIT(planeno, plane_offset, col, slot & (1<<planeno));
271 alloc( unsigned int n )
273 long *ret = malloc( n );
275 error("Can't allocate memory");
283 char *xpmbuf = initbuf;
285 /* version 1. Reads the raw xpm file, NOT the compiled version. This is
286 * not a particularly good idea but I don't have time to do the right thing
287 * at this point, even if I was absolutely sure what that was. */
288 fopen_xpm_file(const char *fn, const char *mode){
291 if(strcmp(mode, "r"))return FALSE; /* no choice now */
292 if(xpmfh)return FALSE; /* one file at a time */
293 xpmfh = fopen(fn, mode);
294 if(!xpmfh)return FALSE; /* I'm hard to please */
296 /* read the header */
298 if(xb == 0)return FALSE;
299 if(4 != sscanf(xb,"%d %d %d %d",
300 &XpmScreen.Width, &XpmScreen.Height,
301 &XpmScreen.Colors, &temp))return FALSE; /* bad header */
302 /* replace the original buffer with one big enough for
306 xpmbuf = malloc(XpmScreen.Width * 2);
308 error("Can't allocate line buffer");
311 if(temp != 1)return FALSE; /* limitation of this code */
314 /* read the colormap and translation table */
316 while(ccount++ < (XpmScreen.Colors-1)){
320 if(xb==0)return FALSE;
321 if(4 != sscanf(xb,"%c c #%2x%2x%2x",&index,&r,&g,&b)){
322 fprintf(stderr,"Bad color entry: %s\n",xb);
325 ttable[index].flag = 1; /* this color is valid */
329 ttable[index].slot = ccount;
335 /* This deserves better. Don't read it too closely - you'll get ill. */
341 if(fgets(buf, bufsz, xpmfh) == 0)return 0;
342 } while(buf[0] != '"');
343 /* strip off the trailing <",> if any */
344 for(bp = buf;*bp;bp++);
346 while(isspace(*bp))bp--;