home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d541 / gifmachine.lha / GIFMachine / Sources / 24to12.c next >
C/C++ Source or Header  |  1991-09-17  |  4KB  |  184 lines

  1. /* Copyright 1990 by Christopher A. Wichura.
  2.    See file GIFMachine.doc for full description of rights.
  3. */
  4.  
  5. #include "GIFMachine.h"
  6.  
  7. extern struct GIFdescriptor gdesc;
  8. EXTERNBITPLANE;
  9.  
  10. extern BOOL DisplayCounts;
  11.  
  12. /* since both MasterColourTable and the PaletteBuf are the same size and
  13.    type we will define MCT to be the PaletteBuf to cut down on static
  14.    memory declarations */
  15. #define MasterColourTable PaletteBuf
  16.  
  17. extern UBYTE MasterColourTable[MAXCOLOURS];
  18. static UWORD TotalColours;
  19.  
  20. extern BYTE *CurrentLineErr[3];
  21. extern BYTE *LastLineErr[3];
  22.  
  23. extern char *AbortMsg;
  24.  
  25. #define MAXERR 2
  26.  
  27. void ReduceTo12(void)
  28. {
  29.     register UWORD x;
  30.     register UWORD y;
  31.  
  32.     PutStr("...Reducing palette to 12 bits.\n......");
  33.     if (DisplayCounts)
  34.         PutStr("Line ");
  35.     else
  36.         PutStr("Working");
  37.     Flush(Output());
  38.  
  39.     TotalColours = 0;
  40.     memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
  41.  
  42.     for (y = 0; y < gdesc.gd_Height; y++) {
  43.         if (DisplayCounts)
  44.             MyPrintf("%5ld", y);
  45.  
  46.         if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  47.             MyPrintf("\n%s", AbortMsg);
  48.             MyExit(ABORTEXITVAL);
  49.         }
  50.  
  51.         for (x = 0; x < gdesc.gd_Width; x++)
  52.             PutValue(x, y, AddColour(&BitPlane[y][x]));
  53.  
  54.         if (DisplayCounts)
  55.             PutStr("\x1B[5D");
  56.     }
  57.  
  58.     MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
  59. }
  60.  
  61. void DitherTo12(void)
  62. {
  63.     register UWORD x;
  64.     register UWORD y;
  65.     register int RedErr;
  66.     register int GreenErr;
  67.     register int BlueErr;
  68.     BYTE **cerr, **lerr, **terr;
  69.     struct RGB rgb;
  70.  
  71.     PutStr("...Dithering palette to 12 bits.\n......Setup");
  72.     Flush(Output());
  73.  
  74.     TotalColours = 0;
  75.     memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
  76.  
  77.     cerr = (BYTE **)&CurrentLineErr[0];
  78.     lerr = (BYTE **)&LastLineErr[0];
  79.  
  80.     /* the top, left and right borders will be used unmodified */
  81.  
  82.     for (x = 0; x < gdesc.gd_Width; x++)
  83.         PutValue(x, 0, AddColour(&BitPlane[0][x]));
  84.  
  85.     for (y = 1; y < gdesc.gd_Height; y++) {
  86.         PutValue(0, y, AddColour(&BitPlane[y][0]));
  87.         PutValue(gdesc.gd_Width - 1, y, AddColour(&BitPlane[y][gdesc.gd_Width - 1]));
  88.     }
  89.  
  90.     /* since the error tables are alloced with MEMF_CLEAR we won't bother
  91.        to clear them here.  instead, we just hit the main loop */
  92.  
  93.     if (DisplayCounts)
  94.         PutStr("\x1B[5DLine ");
  95.     else
  96.         PutStr("\x1B[5DWorking");
  97.     Flush(Output());
  98.  
  99.     for (y = 1; y < gdesc.gd_Height; y++) {
  100.         if (DisplayCounts)
  101.             MyPrintf("%5ld", y);
  102.  
  103.         if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  104.             MyPrintf("\n%s", AbortMsg);
  105.             MyExit(ABORTEXITVAL);
  106.         }
  107.  
  108.         for (x = 1; x < (gdesc.gd_Width - 1); x++) {
  109.             rgb = BitPlane[y][x];
  110.  
  111.             RedErr   = cerr[0][x - 1] + 7*lerr[0][x - 1] + 5*lerr[0][x] + 3*lerr[0][x + 1];
  112.             GreenErr = cerr[1][x - 1] + 7*lerr[1][x - 1] + 5*lerr[1][x] + 3*lerr[1][x + 1];
  113.             BlueErr  = cerr[2][x - 1] + 7*lerr[2][x - 1] + 5*lerr[2][x] + 3*lerr[2][x + 1];
  114.  
  115.             RedErr   >>= 4;
  116.             GreenErr >>= 4;
  117.             BlueErr  >>= 4;
  118.  
  119.     /* now we add the errors into the colour we want.  if this would push
  120.        us over 255 (and thus out of range) we subtract the error out so
  121.        that we still see some dithering instead of washing out the area. */
  122.  
  123.             if (rgb.rgb_Red + RedErr > 255)
  124.                 rgb.rgb_Red -= RedErr;
  125.             else
  126.                 rgb.rgb_Red += RedErr;
  127.  
  128.             if (rgb.rgb_Green + GreenErr > 255)
  129.                 rgb.rgb_Green -= GreenErr;
  130.             else
  131.                 rgb.rgb_Green += GreenErr;
  132.  
  133.             if (rgb.rgb_Blue + BlueErr > 255)
  134.                 rgb.rgb_Blue -= BlueErr;
  135.             else
  136.                 rgb.rgb_Blue += BlueErr;
  137.  
  138.             PutValue(x, y, AddColour(&rgb));
  139.  
  140.             RedErr   = (int)rgb.rgb_Red   - (int)(rgb.rgb_Red   & 0xF0);
  141.             GreenErr = (int)rgb.rgb_Green - (int)(rgb.rgb_Green & 0xF0);
  142.             BlueErr  = (int)rgb.rgb_Blue  - (int)(rgb.rgb_Blue  & 0xF0);
  143.  
  144.             if (RedErr > MAXERR)
  145.                 RedErr = (RedErr * 3) >> 2;
  146.  
  147.             if (GreenErr > MAXERR)
  148.                 GreenErr = (GreenErr * 3) >> 2;
  149.  
  150.             if (BlueErr > MAXERR)
  151.                 BlueErr = (BlueErr * 3) >> 2;
  152.  
  153.             cerr[0][x] = RedErr;
  154.             cerr[1][x] = GreenErr;
  155.             cerr[2][x] = BlueErr;
  156.         }
  157.  
  158.             terr = lerr;
  159.             lerr = cerr;
  160.             cerr = terr;
  161.  
  162.         if (DisplayCounts)
  163.             PutStr("\x1B[5D");
  164.     }
  165.  
  166.     MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
  167. }
  168.  
  169. UWORD AddColour(struct RGB *rgb)
  170. {
  171.     register UWORD colour;
  172.  
  173.     colour = ((rgb->rgb_Red << 4) & 0xF00) |
  174.          (rgb->rgb_Green & 0xF0) |
  175.          (rgb->rgb_Blue >> 4);
  176.  
  177.     if (!MasterColourTable[colour]) {
  178.         MasterColourTable[colour] = 1;
  179.         TotalColours++;
  180.     }
  181.  
  182.     return colour;
  183. }
  184.