home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * *
- * GetImage - a DeluxePaint to C data converter (gi) *
- * *
- * Copyright (c) 1986, Michael J. Farren *
- * This program may be freely distributed by any means *
- * desired, but may not be sold in any form. *
- * *
- * Modification History: *
- * *
- * 7/86 Dmil - Changed input routine to use the input *
- * filename as the output filename with '.c' tacked on *
- * the end if only one filename is given upon invocation. *
- * *
- * Example: GetImage brushfile <cr> will create brushfile.c *
- * *
- * Added code to write an Image structure along with the *
- * Image data. Also writes some pertinent info about the *
- * image in the file header. *
- * *
- * Note: The changes I've made to this program work fine for me,*
- * and I'm using over 80 images processed by this program as *
- * gadget images in my current project, some of which are over *
- * 100x30 med-res pixels in size in 16 colors. Try that with *
- * ImageMaker. It may or may not work as well for you. *
- * Caveat Emptor. *
- * *
- * Billions of thanks to Michael J. Farren for making this *
- * source available. It's saved my ass. *
- * *
- * David Milligan (Dmil), Integrated Systems, Inc. *
- * *
- * 1/90 CAB - Now searches for BODY label instead of assuming *
- * that it is 12 bytes passed the GRAB label (which it *
- * never was on any of my brush files), and now it shows *
- * all colors and marks the ones that are used instead of *
- * x'ing out the ones that are not used. *
- * Another feature I added, is that it does not print *
- * any bit plane data if it is all 0's, and it sets up the *
- * PlanePick value in the Image structure accordingly. *
- * This cuts down on the size of the object files for *
- * your images. *
- * Also, adds #include <exec/types.h> and #include< *
- * intuition/intuition.h> so you can compile the output *
- * C file immediately and just link it with your other *
- * files that use the Image data. *
- * *
- * Charles A. Brand (CAB), Correct Algorithm Builders, Inc. *
- * *
- * Using Manx Aztec C ver. 3.6a, compile this file as folows: *
- * *
- * Compile : cc GetImage -s +L -E200 *
- * Link : ln GetImage.o -lc32 *
- * *
- *****************************************************************/
-
-
- #include <stdio.h>
- #undef NULL
- #include <exec/types.h>
-
- struct BitMapHeader
- {
- UWORD w,h; /* raster width, height, in pixels */
- WORD x,y; /* pixel position for saved image */
- UBYTE nplanes; /* number of bit planes in source */
- UBYTE masking; /* masking technique */
- UBYTE compression; /* compression algorithm */
- UBYTE pad1; /* padding to justify next entry */
- UWORD transColor; /* transparent "color number" */
- UBYTE xAsp, yAsp; /* x:y aspect ratio */
- WORD pageW, pageH; /* source "page" size in pixels */
- } bmhd;
-
- UBYTE Cmap[96],old_cmap[96]; /* 32 color storage */
- APTR *(raster_lines[400][6]); /* pointers to raster lines in bit planes */
-
- LONG colors_in_byte[8], colors_used[32], tran_table[32];
- LONG twopowers[7] = { 1, 2, 4, 8, 16, 32, 64 };
- BOOL check;
- WORD planes_used[5];
- UBYTE PP;
- int num_planes;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- WORD bytes_per_line; /* Number of bytes per raster line */
- FILE *i_file, *o_file;
- UBYTE *buff_pointer, *body_data; /* storage pointers */
- UBYTE *data_pointer, *buff_pointer_save;
- LONG body_data_size, buff_size; /* size storage */
- LONG i, j, k, temp; /* various temporary variables */
- UBYTE tempbyte;
- char *samename;
- char *add_c = ".c";
-
-
- /* Check arguments, and try to open i/o files */
-
- if(argc > 3) {
- printf("\nUsage -> getimage <input file> <output file>\n");
- exit(20);
- }
-
- if((i_file = fopen(argv[1], "r")) == 0 ) {
- printf("\nCould not open input file %s!\n", argv[1]);
- exit(20);
- }
-
- if(argc = 2) {
- strcpy(samename,argv[1]);
- strcat(samename,add_c);
- if((o_file = fopen(samename, "w")) == 0) {
- printf("\nCould not open output file %s!\n", samename);
- exit(20);
- }
- }
- else
- if((o_file = fopen(argv[2], "w")) == 0 ) {
- printf("\nCould not open output file %s!\n", argv[2]);
- exit(20);
- }
-
- /* Files are O.K. - skip over first 20 bytes ("FORM", length, "ILBM",
- "BMHD", length) */
-
- printf("\nReading input file...\n");
- if(fseek(i_file, 20L, 0)) read_error();
-
- /* Now, read in the BMHD structure */
-
- chkread(&bmhd, sizeof(struct BitMapHeader), i_file);
-
-
- /* Skip the CMAP label, and read in the color map length, then the color
- map data. We assume that the color map length accurately reflects
- the number of bit planes, so don't bother to check the header entry
- bmhd.nplanes. Also, all Amiga color maps will have an even number of
- entries, so don't bother padding the read out. */
-
- if(fseek(i_file, 4L, 1)) read_error(); /* skip the label */
- chkread(&temp, sizeof(LONG), i_file); /* read the length */
-
- i = 0; /* and read in the map */
- while( i < temp)
- chkread(&Cmap[i++], 1, i_file);
-
- /* Now, check the next header. If it isn't "GRAB", this isn't a
- brush file, so get out */
-
- chkread(&temp, sizeof(LONG), i_file);
- if(temp != ('G'<<24 | 'R'<<16 | 'A'<<8 | 'B')) {
- printf("\nThe input file is not a DeluxePaint brush file!\n");
- exit(20);
- }
-
- /* It's probably a brush file. Search for the BODY label, then get
- the body length,then read the body data into body_data[] */
-
- check = FALSE;
- while(check != TRUE) {
- chkread(&temp, sizeof(LONG), i_file);
- if(temp == ('B'<<24 | 'O'<<16 | 'D'<<8 | 'Y')) check = TRUE;
- }
- chkread(&body_data_size, sizeof(LONG), i_file);
- body_data = AllocMem(body_data_size, NULL);
- chkread(body_data, body_data_size, i_file);
-
- /* Now, start the good stuff. First, allocate enough memory to hold
- the entire bitmap for the image. */
-
- bytes_per_line = (bmhd.w & 7 ? bmhd.w+8 : bmhd.w) >> 3;
- if(bytes_per_line & 1) bytes_per_line++;
-
- buff_size = bytes_per_line * bmhd.h * bmhd.nplanes;
- buff_pointer = AllocMem(buff_size, NULL );
- buff_pointer_save = buff_pointer;
- data_pointer = body_data;
-
- /* Next, go through the file line by line, bit plane by bit plane,
- and extract the image data, putting it into bitmap. As this is
- being done, save pointers to each line in the raster_lines array. */
-
- /* # of lines high */
- for(i=0; i!=bmhd.h; i++) {
- /* # of planes */
- for(j=0; j!=bmhd.nplanes; j++) {
- raster_lines[i][j] = buff_pointer; /* set the pointer */
- if(bmhd.compression == 1) {
- /* if compressed, decompress */
- expand_map(bytes_per_line, buff_pointer, &data_pointer);
- }
- else {
- for(k=0; k!=bytes_per_line; k++) {
- *(buff_pointer+k) = *(data_pointer++);
- }
- }
- buff_pointer += bytes_per_line;
- }
- }
-
- check_planes(bytes_per_line);
-
- FreeMem(body_data, body_data_size);
-
- /* Now, go through the data, determining the different colors used */
-
- calc_color:
-
- printf("\nAnalyzing data...");
- for(i=0; i!=twopowers[bmhd.nplanes]; colors_used[i++]=0);
-
- for(i=0; i!=bmhd.h; i++) {
- for(j=0; j!=bmhd.w; j++) {
- colors_used[get_a_bit(i,j)] = 1;
- }
- }
-
- /* Show the current color register stuff */
-
- start_over:
-
- printf("\nCurrent color register assignments for this picture are:\n");
- for(i=0; i!=twopowers[bmhd.nplanes]; i++) {
- if(colors_used[i]) {
- printf("%2d -> R:%2d G:%2d B:%2d ",
- i, Cmap[i*3]>>4, Cmap[i*3+1]>>4, Cmap[i*3+2]>>4);
- }
- else {
- printf("%2d -> Not Used ",i);
- }
- if(i&1) printf("\n");
- }
-
- /* Now, write the data to the output file, color map first, then data,
- plane by plane, line by line */
-
- printf("\nWriting output file...");
-
- /* Output a few statistics */
-
- /********************************************************
- * *
- * Start of Dmil's Image info hack *
- * *
- * I like to have as much info on the Image I'm *
- * working with as possible, especially if I'm trying *
- * to use PlanePick & PlaneOnOff, so I write out the *
- * following data with the Image data & structure. *
- * *
- ********************************************************/
-
- /* Put #include statements in source file. */
-
- fprintf(o_file, "#include <exec/types.h>\n");
- fprintf(o_file, "#include <intuition/intuition.h>\n");
-
- fprintf(o_file, "\n");
- fprintf(o_file, "/* Image %s%s \n",argv[1],"_image");
- fprintf(o_file, " Width: %d\n",bmhd.w);
- fprintf(o_file, " Height: %d\n",bmhd.h);
- fprintf(o_file, " Depth: %d\n",bmhd.nplanes);
- fprintf(o_file, " TransColor: %d */\n\n",bmhd.transColor);
-
- /* Start with the color map */
-
- fprintf(o_file,"/* Color Map */\n\n");
-
- fprintf(o_file, "USHORT map[] = {\n");
-
- for(i=0; i!=twopowers[bmhd.nplanes]; i++) {
- fprintf(o_file, " ");
- make_word((Cmap[i*3]<<4) + Cmap[i*3+1] + (Cmap[i*3+2]>>4), o_file);;
- if(i!=twopowers[bmhd.nplanes]-1) fprintf(o_file, ",");
- if(colors_used[i]) fprintf(o_file, "/* USED */");
- fprintf(o_file, "\n");
- }
- fprintf(o_file, "};\n\n");
-
- /* Now, do the data */
-
- fprintf(o_file, "/* Image Data */\n\n");
- fprintf(o_file, "UWORD %s[%d] =\n{\n", argv[1],(num_planes *
- bytes_per_line * bmhd.h)/2);
- for(i=0; i!=bmhd.nplanes; i++) {
- fprintf(o_file, "/* Bit Plane #%d */\n\n", i);
-
- /* If the Bit Plane is all 0's, don't print its data. */
- if(planes_used[i]) {
-
- for(j=0; j!=bmhd.h; j++) {
- fprintf(o_file, " ");
- buff_pointer = raster_lines[j][i];
- for(k=0; k<bytes_per_line; ) {
- tempbyte = *(buff_pointer+(k++));
- make_word((tempbyte << 8) | *(buff_pointer+(k++)), o_file);
- fprintf(o_file, ",");
- }
- fprintf(o_file, "\n");
- }
- fprintf(o_file, "\n");
- }
- else /* Print that the bit plane is not used. */
- fprintf(o_file, "/* This bit plane not used. */\n\n");
- }
- fseek(o_file, -3, 1); /* back up to wipe out the last comma */
- fprintf(o_file, "\n};\n");
-
- /********************************************************
- * *
- * Start of Dmil's Image structure hack *
- * *
- ********************************************************/
-
- /* Now, Sets up PlanePick value according to which bit planes are used. */
-
- fprintf(o_file, "struct Image %s_image =\n{\n",argv[1]);
- fprintf(o_file, "\t0,0,\t\t\t/* LeftEdge, TopEdge */\n");
- fprintf(o_file, "\t%d,%d,%d,\t\t/* Width, Height, Depth */\n",bmhd.w,bmhd.h,bmhd.nplanes);
- fprintf(o_file, "\t&%s[0],\t\t/* Pointer to Image data */\n",argv[1]);
- fprintf(o_file, "\t%d,0,\t\t\t/* PlanePick, PlaneOnOff */\n",PP);
- fprintf(o_file, "\tNULL,\t\t\t/* NextImage pointer */\n};\n");
-
- /* Close up, clean up, and get out */
-
- fclose(o_file);
- fclose(i_file);
- printf("\n");
- FreeMem(buff_pointer_save, buff_size);
- }
-
- /* read_error - called if a read error occured */
-
- read_error()
- {
- printf("\nRead error in input file, aborting\n");
- exit(20);
- }
-
- /* chkread - reads from input file, checking for errors */
-
- chkread(ptr, size, fd)
- APTR *ptr;
- WORD size;
- FILE *fd;
- {
- WORD readin;
- readin = fread(ptr, size, 1, fd);
- if(readin != 1) read_error();
- }
-
- /* expand_map - decompresses data compressed with the byte_run encoding
- scheme described in the IFF document. A signed byte, x,
- is read from the input block. If the signed value of x
- is negative, but not -128 ( 0x80 ), the next byte is read
- and is placed in the output block (-x+1) times. If the
- signed value is positive, the next (x+1) bytes are copied
- directly to the output block. If the signed value is -128,
- no operation is performed.
- */
-
-
- expand_map(length, pointer, data_pointer)
- WORD length;
- UBYTE *pointer;
- UBYTE **data_pointer;
- {
-
- WORD minus128 = -128;
- WORD temp;
- BYTE tempbyte;
- UBYTE tempubyte;
-
- while( length > 0 ) {
- tempbyte = *((*data_pointer)++);
- temp = tempbyte;
- if (temp >= 0) {
- temp += 1;
- length-=temp;
- do {
- *(pointer++) = *((*data_pointer)++);
- } while (--temp > 0);
- }
- else
- if (temp != minus128) {
- temp = (-temp) + 1;
- length -= temp;
- tempubyte = *((*data_pointer)++);
- do {
- *(pointer++) = tempubyte;
- } while (--temp > 0);
- }
- }
- }
-
- /* Determine which bit-planes are not used and set-up PlanePick value */
-
- check_planes(bpl)
- WORD bpl; /* byte_per_line */
- {
- int i,j,k;
- UBYTE *pt; /* pointer to body data */
-
- /* Clear planes_used[] array */
-
- for(i=0;i != bmhd.nplanes;i++)
- planes_used[i] = 0;
-
- /* Now determine if bit planes are all 0's */
-
- for(i=0;i != bmhd.nplanes;i++) {
- for(j=0;j != bmhd.h;j++) {
- pt = raster_lines[j][i];
- for(k=0;k < bpl;k++)
- planes_used[i] |= *(pt++);
- }
- }
-
- /* Set-up PlanePick value
- and number of planes actually used */
-
- num_planes = 0;
- PP = 0; /* Zero PlanePick variable */
- for(i = (bmhd.nplanes-1);i >= 0;i--) {
- PP = (PP << 1);
- if(planes_used[i]) {
- PP += 1;
- num_planes += 1;
- }
- }
- }
-
- /* get_a_bit - returns the color value of the bit at location x,y in the
- image.
- */
-
- get_a_bit(y, x)
- LONG y, x;
- {
- LONG xbyte, xbit,i;
- UBYTE tempbyte, color;
- UBYTE *pointer;
-
- color = 0; /* start with no color */
- xbyte =x>>3; /* xbyte = the byte location of x */
- xbit = (1<<(x&7)); /* xbit = the mask for the bit */
- for(i=0; i!=bmhd.nplanes; i++)
- { /* do all the planes */
- pointer = raster_lines[y][i]; /* get the base address */
- tempbyte = *(pointer + xbyte); /* get the proper byte */
- if(tempbyte & xbit) color |= (1 << i); /* OR in the color bit */
- }
- return color;
- }
-
- /* put_a_bit - sets a given bit to a given color */
-
- put_a_bit(y, x, color)
- LONG y, x, color;
- {
- LONG xbyte, xbit, i;
- UBYTE *pointer;
- UBYTE tempbyte;
-
- for(i=0; i!=bmhd.nplanes; i++)
- {
- xbyte = x>>3;
- xbit = (1 << (x & 7));
- pointer = raster_lines[y][i];
- tempbyte = *(pointer + xbyte); /* get the appropriate byte */
- tempbyte &= 0xff-xbit; /* mask off the proper bit */
- if(color & twopowers[i])
- { /* if the color bit is set, */
- tempbyte |= xbit; /* set the bit in the byte */
- }
- *(pointer + xbyte) = tempbyte; /* save the modified byte */
- }
- }
-
- /* get_new_colors - get the users choices for register assignments */
-
- get_new_colors()
- {
- int i,j;
-
- for(i=0; i!=twopowers[bmhd.nplanes]; tran_table[i++]=-1); /* reset */
- for(i=1; i!=twopowers[bmhd.nplanes]; i++)
- {
- if(colors_used[i])
- { /* for each color used in the original */
- getnew:
- printf("\nOld color register %2d (R:%2d G:%2d B:%2d) new number:",
- i, Cmap[i*3]>>4, Cmap[i*3+1]>>4, Cmap[i*3+2]>>4);
- scanf("%d", &j);
- if((j<1) || (j>=twopowers[bmhd.nplanes]))
- {
- printf("\nRegister number must be greater than zero, and less than %2d.",
- twopowers[bmhd.nplanes]);
- printf("\nTry again.");
- goto getnew;
- }
- tran_table[i] = j;
- }
- }
-
- /* Check the translation table for duplicated register assignments. */
-
- for(i=1; i!=twopowers[bmhd.nplanes]-1; i++)
- {
- for(j=i+1; j!=twopowers[bmhd.nplanes]; j++)
- {
- if((tran_table[i]==-1) || (tran_table[j]==-1)) continue;
- if(tran_table[i] == tran_table[j])
- {
- printf("\nDuplicate color register assignment - try again.");
- return -1;
- }
- }
- }
- return 0;
- }
-
- /* make_word - outputs a string representing a four-digit hex number */
-
- make_word(num, fp)
- UWORD num;
- FILE *fp;
- {
- char temp[10];
-
- sprintf(temp, "0000%x\0", num);
- fprintf(fp, "0x%s", &temp[strlen(temp)-4]);
- }
-
-