home *** CD-ROM | disk | FTP | other *** search
- #include "iff.h"
- #include <stdio.h>
-
- void *GfxBase;
-
- /* Our remapper version takes advantage of private knowledge of the
- structure of the 256-color fixed palette for tremendous speed. */
-
- UWORD div1[256],div2[256],div3[256],div4[256];
-
- void
- split_row8(struct PicMap *picmap,int y,UBYTE *assemble)
- {
- short bytelen,index,tmp,plane,bit;
- int vertical,tmp2;
- UBYTE *buf2,chunk;
-
- /* Read 8-bit per pixel line from image; break apart into separate
- bitplanes, compress each separate bitplane, and write each
- bitplane out. Yes, this is relatively slow. */
-
- bytelen=picmap->BitMap.BytesPerRow;
- vertical=bytelen*y;
-
- for (index=0;index<bytelen;index++) {
- tmp=index*8;
- tmp2=index+vertical;
-
- for (bit=7;bit>=0;bit--) {
-
- plane=8;
-
- while (plane--) {
- buf2=picmap->BitMap.Planes[plane]+tmp2;
-
- chunk=assemble[tmp + bit];
- if (chunk & (1<<plane)) *buf2 |= (1<<(7-bit));
- }
- } /* bit loop */
- } /* byte loop */
- }
-
- void
- pack_row8(struct PicMap *picmap,int y,UBYTE *assemble)
- {
- register UBYTE *tmp;
- register USHORT p;
- register ULONG color;
-
- USHORT index,bit,px,tmp2,
- bytelen=picmap->BitMap.BytesPerRow;
- ULONG rgbu,tmp3,vertical=bytelen*y;
- UBYTE r,g,b;
-
- struct rmap { /* 24-bit IFF long color separation struct */
- /*UBYTE r,g,b,u; (for 386) */
- UBYTE u,b,g,r;
- };
-
- #define COLORCONV(x) ((struct rmap *)(&x))
-
- for (index=0;index<bytelen;index++) {
- tmp2=index*8;
-
- for (bit=0;bit<8;bit++) {
-
- /* Assemble a 24-bit pen number from the bits across the planes,
- and remap this into an 8-bit value. Yes, this is a slow process. */
-
- p=24;
- color=0;
- tmp3=vertical+index;
-
- while(p--) {
- tmp=picmap->BitMap.Planes[p] + tmp3;
- color |= ((*tmp & (1<<bit)) != 0) << p;
- }
-
- /* Pixels in a byte need to be spit out in reverse order;
- i.e., the MSB represents the leftmost pixel. */
-
- px=tmp2+(7-bit);
-
- rgbu=color;
-
- r=COLORCONV(rgbu)->r;
- g=COLORCONV(rgbu)->g;
- b=COLORCONV(rgbu)->b;
-
- /* Attempt to match monochrome colors to the higher-resolution
- monochrome portion of the palette. Since we're dealing with
- guaranteed greys here, we don't worry about the different
- eye r,g,b component sensitivities. Greyscales that aren't
- exactly grey (but close) fall into the color test */
-
- if (r==g && g==b) assemble[px]=div4[r]; /* monochrome */
- else
- assemble[px]=div1[b] + div2[g] + div3[r]; /* color result */
-
- } /* bit loop */
- } /* byte loop */
- }
-
- ILBM24To8(struct PicMap *src,struct PicMap *dst)
- {
- UWORD *colormap=dst->colormap,r,g,b,i,j;
- UBYTE assemble[1024],*pal=dst->palette;
- int y,w=src->BitMap.BytesPerRow*8,h=src->BitMap.Rows;
-
- memset(dst,0,sizeof(*dst));
- dst->ViewModes=src->ViewModes;
-
- InitBitMap(&dst->BitMap,8,(long)w,(long)h);
-
- /* note that we're not necessarily allocating CHIP_MEM here! */
-
- for (i=0;i<8;i++)
- if (!(dst->BitMap.Planes[i]=AllocMem(RASSIZE(w,h),MEMF_PUBLIC|MEMF_CLEAR))) {
- FreeBitMap(&dst->BitMap);
- return(OUT_OF_MEM);
- }
-
- /* generate a 6x6x6 color cube followed by 40 grays */
-
- for (r=0;r<256;r+=51)
- for (g=0;g<256;g+=51)
- for (b=0;b<256;b+=51) {
-
- *colormap++ = r<<8 | g<<4 | b; /* 4-bit Amiga res'n not enough here */
-
- *pal++ = r;
- *pal++ = g;
- *pal++ = b;
- }
-
- pal=&dst->palette[216*3];
- colormap=&dst->colormap[216];
-
- for (i=3;i<=42;i++) {
- j=i*6;
-
- *colormap++ = j<<8 | j<<4 | j; /* 4-bit Amiga res'n not enough here */
-
- *pal++=j;
- *pal++=j;
- *pal++=j;
- }
-
- CopyMem((char*)dst->palette,(char*)src->palette,sizeof(dst->palette));
- CopyMem((char*)dst->colormap,(char*)src->colormap,sizeof(dst->colormap));
-
- /* setup some fast math tables for the remapper. Note that
- colors falling "in between" palette entries get rounded */
-
- for (i=0;i<256;i++) {
- j=(i+25)/51;
-
- div1[i]=j;
- div2[i]=j*6;
- div3[i]=j*36;
-
- j=(i+3)/6;
- if (j>2) div4[i]=j+213; else div4[i]=0;
- }
-
- printf("[%dx%d] Working",w,h); fflush(stdout);
-
- for (y=0;y<h;y++) {
- if (!(y%10)) {
- putchar('.');
- fflush(stdout);
- }
- pack_row8(src,y,assemble);
- split_row8(dst,y,assemble);
- }
-
- puts(" Done.");
- return(0);
- }
-
- main(int argc,char *argv[])
- {
- static struct PicMap srcmap,dstmap;
-
- GfxBase=OpenLibrary("graphics.library",0L);
-
- puts("IFF24To8 : (c) 1991 Dallas J. Hodgson\n");
-
- if (argc!=3) {
- puts("Usage: IFF24To8 <24-bit image> <8-bit output>");
- exit(100);
- }
-
- if (ReadILBM(argv[1],DISK_MODE,&srcmap)) {
- printf("Couldn't read file %s.\n",argv[1]);
- goto cleanup;
- }
-
- if (srcmap.BitMap.Depth!=24) {
- puts("IFF image is not 24-bit!");
- goto cleanup;
- }
-
- if (ILBM24To8(&srcmap,&dstmap)) {
- puts("not enough memory!");
- goto cleanup;
- }
-
- if (WriteILBM(argv[2],&dstmap)) {
- printf("Couldn't write file %s.\n",argv[2]);
- goto cleanup;
- }
-
- cleanup:
- FreeBitMap(&srcmap.BitMap);
- FreeBitMap(&dstmap.BitMap);
-
- return(0);
- }
-