home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d553 / 24bittools.lha / 24BitTools / IFF24To8 / main.c < prev    next >
C/C++ Source or Header  |  1991-10-28  |  5KB  |  220 lines

  1. #include "iff.h"
  2. #include <stdio.h>
  3.  
  4. void *GfxBase;
  5.  
  6. /* Our remapper version takes advantage of private knowledge of the
  7.    structure of the 256-color fixed palette for tremendous speed. */
  8.  
  9. UWORD div1[256],div2[256],div3[256],div4[256];
  10.  
  11.   void
  12. split_row8(struct PicMap *picmap,int y,UBYTE *assemble)
  13. {
  14.   short bytelen,index,tmp,plane,bit;
  15.   int vertical,tmp2;
  16.   UBYTE *buf2,chunk;
  17.  
  18.   /* Read 8-bit per pixel line from image; break apart into separate
  19.      bitplanes, compress each separate bitplane, and write each
  20.      bitplane out. Yes, this is relatively slow. */
  21.  
  22.   bytelen=picmap->BitMap.BytesPerRow;
  23.   vertical=bytelen*y;
  24.  
  25.   for (index=0;index<bytelen;index++) {
  26.     tmp=index*8;
  27.     tmp2=index+vertical;
  28.  
  29.     for (bit=7;bit>=0;bit--) {
  30.  
  31.       plane=8;
  32.  
  33.       while (plane--) {
  34.         buf2=picmap->BitMap.Planes[plane]+tmp2;
  35.  
  36.         chunk=assemble[tmp + bit];
  37.         if (chunk & (1<<plane)) *buf2 |= (1<<(7-bit));
  38.       }
  39.     } /* bit loop */
  40.   } /* byte loop */
  41. }
  42.  
  43.   void
  44. pack_row8(struct PicMap *picmap,int y,UBYTE *assemble)
  45. {
  46.   register UBYTE *tmp;
  47.   register USHORT p;
  48.   register ULONG color;
  49.  
  50.   USHORT index,bit,px,tmp2,
  51.          bytelen=picmap->BitMap.BytesPerRow;
  52.   ULONG rgbu,tmp3,vertical=bytelen*y;
  53.   UBYTE r,g,b;
  54.  
  55.   struct rmap {    /* 24-bit IFF long color separation struct */
  56.     /*UBYTE r,g,b,u; (for 386) */
  57.     UBYTE u,b,g,r;
  58.   };
  59.  
  60.   #define COLORCONV(x) ((struct rmap *)(&x))
  61.  
  62.   for (index=0;index<bytelen;index++) {
  63.     tmp2=index*8;
  64.  
  65.     for (bit=0;bit<8;bit++) {
  66.  
  67.       /* Assemble a 24-bit pen number from the bits across the planes,
  68.          and remap this into an 8-bit value. Yes, this is a slow process. */
  69.  
  70.       p=24;
  71.       color=0;
  72.       tmp3=vertical+index;
  73.  
  74.       while(p--) {
  75.         tmp=picmap->BitMap.Planes[p] + tmp3;
  76.         color |= ((*tmp & (1<<bit)) != 0) << p;
  77.       }
  78.  
  79.       /* Pixels in a byte need to be spit out in reverse order;
  80.          i.e., the MSB represents the leftmost pixel. */
  81.  
  82.       px=tmp2+(7-bit);
  83.  
  84.       rgbu=color;
  85.  
  86.       r=COLORCONV(rgbu)->r;
  87.       g=COLORCONV(rgbu)->g;
  88.       b=COLORCONV(rgbu)->b;
  89.  
  90.       /* Attempt to match monochrome colors to the higher-resolution
  91.          monochrome portion of the palette. Since we're dealing with
  92.          guaranteed greys here, we don't worry about the different
  93.          eye r,g,b component sensitivities. Greyscales that aren't
  94.          exactly grey (but close) fall into the color test */
  95.  
  96.       if (r==g && g==b) assemble[px]=div4[r]; /* monochrome */
  97.       else
  98.         assemble[px]=div1[b] + div2[g] + div3[r];    /* color result */
  99.  
  100.     } /* bit loop */
  101.   } /* byte loop */
  102. }
  103.  
  104. ILBM24To8(struct PicMap *src,struct PicMap *dst)
  105. {
  106.   UWORD *colormap=dst->colormap,r,g,b,i,j;
  107.   UBYTE assemble[1024],*pal=dst->palette;
  108.   int y,w=src->BitMap.BytesPerRow*8,h=src->BitMap.Rows;
  109.  
  110.   memset(dst,0,sizeof(*dst));
  111.   dst->ViewModes=src->ViewModes;
  112.  
  113.   InitBitMap(&dst->BitMap,8,(long)w,(long)h);
  114.  
  115.   /* note that we're not necessarily allocating CHIP_MEM here! */
  116.  
  117.   for (i=0;i<8;i++)
  118.     if (!(dst->BitMap.Planes[i]=AllocMem(RASSIZE(w,h),MEMF_PUBLIC|MEMF_CLEAR))) {
  119.       FreeBitMap(&dst->BitMap);
  120.       return(OUT_OF_MEM);
  121.     }
  122.  
  123.   /* generate a 6x6x6 color cube followed by 40 grays */
  124.  
  125.   for (r=0;r<256;r+=51)
  126.     for (g=0;g<256;g+=51)
  127.       for (b=0;b<256;b+=51) {
  128.  
  129.         *colormap++ = r<<8 | g<<4 | b; /* 4-bit Amiga res'n not enough here */
  130.  
  131.         *pal++ = r;
  132.         *pal++ = g;
  133.         *pal++ = b;
  134.       }
  135.  
  136.   pal=&dst->palette[216*3];
  137.   colormap=&dst->colormap[216];
  138.  
  139.   for (i=3;i<=42;i++) {
  140.     j=i*6;
  141.  
  142.     *colormap++ = j<<8 | j<<4 | j;     /* 4-bit Amiga res'n not enough here */
  143.  
  144.     *pal++=j;
  145.     *pal++=j;
  146.     *pal++=j;
  147.   }
  148.    
  149.   CopyMem((char*)dst->palette,(char*)src->palette,sizeof(dst->palette));
  150.   CopyMem((char*)dst->colormap,(char*)src->colormap,sizeof(dst->colormap));
  151.  
  152.   /* setup some fast math tables for the remapper. Note that
  153.      colors falling "in between" palette entries get rounded */
  154.  
  155.   for (i=0;i<256;i++) {
  156.     j=(i+25)/51;
  157.  
  158.     div1[i]=j;
  159.     div2[i]=j*6;
  160.     div3[i]=j*36;
  161.  
  162.     j=(i+3)/6;
  163.     if (j>2) div4[i]=j+213; else div4[i]=0;
  164.   }
  165.  
  166.   printf("[%dx%d] Working",w,h); fflush(stdout);
  167.  
  168.   for (y=0;y<h;y++) {
  169.     if (!(y%10)) {
  170.       putchar('.');
  171.       fflush(stdout);
  172.     }
  173.     pack_row8(src,y,assemble);
  174.     split_row8(dst,y,assemble);
  175.   }
  176.  
  177.   puts(" Done.");
  178.   return(0);
  179. }
  180.  
  181. main(int argc,char *argv[])
  182. {
  183.   static struct PicMap srcmap,dstmap;
  184.  
  185.   GfxBase=OpenLibrary("graphics.library",0L);
  186.  
  187.   puts("IFF24To8 : (c) 1991 Dallas J. Hodgson\n");
  188.  
  189.   if (argc!=3) {
  190.     puts("Usage: IFF24To8 <24-bit image> <8-bit output>");
  191.     exit(100);
  192.   }
  193.  
  194.   if (ReadILBM(argv[1],DISK_MODE,&srcmap)) {
  195.     printf("Couldn't read file %s.\n",argv[1]);
  196.     goto cleanup;
  197.   }
  198.  
  199.   if (srcmap.BitMap.Depth!=24) {
  200.     puts("IFF image is not 24-bit!");
  201.     goto cleanup;
  202.   }
  203.  
  204.   if (ILBM24To8(&srcmap,&dstmap)) {
  205.     puts("not enough memory!");
  206.     goto cleanup;
  207.   }
  208.  
  209.   if (WriteILBM(argv[2],&dstmap)) {
  210.     printf("Couldn't write file %s.\n",argv[2]);
  211.     goto cleanup;
  212.   }
  213.   
  214. cleanup:
  215.   FreeBitMap(&srcmap.BitMap);
  216.   FreeBitMap(&dstmap.BitMap);
  217.  
  218.   return(0);
  219. }
  220.