home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d541 / gifmachine.lha / GIFMachine / Sources / giftosham.c < prev    next >
C/C++ Source or Header  |  1991-09-17  |  5KB  |  238 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 char *AbortMsg;
  11.  
  12. extern BOOL DisplayCounts;
  13.  
  14. extern BOOL Laced;
  15.  
  16. UWORD *SHAMmem;
  17.  
  18. struct RGB Palette[16];
  19.  
  20. extern UBYTE PaletteBuf[MAXCOLOURS];
  21. extern ULONG ColourBuf[MAXCOLOURS];
  22. static ULONG ErrBuf[MAXCOLOURS];
  23.  
  24. #define ISLACED (Laced && (y != gdesc.gd_Height - 1))
  25.  
  26. void GIFtoSHAM(void)
  27. {
  28.     register UWORD x;
  29.     register UWORD current;
  30.     register int index;
  31.     register int index2;
  32.     ULONG error;
  33.     UWORD y;
  34.     int Pal;
  35.     int ShamIndex;
  36.     int colours;
  37.  
  38.     ULONG TotalErr, LineErr;
  39.  
  40.     ULONG bestpal;
  41.     ULONG besterr;
  42.  
  43.     UBYTE CurrentRed,  CurrentGreen,  CurrentBlue;
  44.     UBYTE PreviousRed, PreviousGreen, PreviousBlue;
  45.  
  46.     MyPrintf("...Converting to SHAM format.\n......");
  47.     if (DisplayCounts)
  48.         PutStr("Line");
  49.     else
  50.         PutStr("Working");
  51.     Flush(Output());
  52.  
  53.     ShamIndex = TotalErr = 0;
  54.  
  55.     /* palette zero is always the background colour.  regardless of
  56.        what the GIF specified for the background, we always use black.
  57.        this is a kludge to get around a hardware `feature' that causes
  58.        all overscanned screens to have a black background regardless
  59.        of what the background was specified to be.
  60.     */
  61.  
  62.     Palette[0].rgb_Red = Palette[0].rgb_Green = Palette[0].rgb_Blue = 0;
  63.  
  64.     for (y = 0; y < gdesc.gd_Height; y += (ISLACED ? 2 : 1)) {
  65.         if (DisplayCounts) {
  66.             if (ISLACED)
  67.                 MyPrintf("s %5ld-%5ld", y, y + 1);
  68.             else
  69.                 MyPrintf(" %5ld", y);
  70.         }
  71.  
  72.         if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  73.             MyPrintf("\n%s", AbortMsg);
  74.             MyExit(ABORTEXITVAL);
  75.         }
  76.  
  77.         memset((char *)ColourBuf, 0, sizeof(ColourBuf));
  78.  
  79.         for (colours = index2 = 0; index2 < (ISLACED ? 2 : 1); index2++)
  80.             for (x = 0; x < gdesc.gd_Width; x++) {
  81.                 current = GetValue(x, y + index2);
  82.  
  83.                 if (ColourBuf[current]++ == 0)
  84.                     colours++;
  85.             }
  86.  
  87.         if (DisplayCounts)
  88.             MyPrintf(", %4ld unique colours", colours);
  89.  
  90.         memset((char *)PaletteBuf, 0, sizeof(PaletteBuf));
  91.  
  92.         for (index = 0; index < MAXCOLOURS; index++) {
  93.             if (ColourBuf[index] == 0)
  94.                 continue;
  95.  
  96.             ErrBuf[index] = RGBdiff(GetRed(index),
  97.                         GetGreen(index),
  98.                         GetBlue(index),
  99.                         Palette[0].rgb_Red,
  100.                         Palette[0].rgb_Green,
  101.                         Palette[0].rgb_Blue);
  102.         }
  103.  
  104.         for (Pal = 1; Pal < 16; Pal++) {
  105.             for (besterr = index = 0; index < MAXCOLOURS; index++) {
  106.                 if (ColourBuf[index] == 0)
  107.                     continue;
  108.  
  109.                 if (ErrBuf[index] * ColourBuf[index] >= besterr) {
  110.                     bestpal = index;
  111.                     besterr = ErrBuf[index] * ColourBuf[index];
  112.                 }
  113.             }
  114.  
  115.             Palette[Pal].rgb_Red   = GetRed(bestpal);
  116.             Palette[Pal].rgb_Green = GetGreen(bestpal);
  117.             Palette[Pal].rgb_Blue  = GetBlue(bestpal);
  118.  
  119.             for (index = 0; index < MAXCOLOURS; index++) {
  120.                 if (ColourBuf[index] == 0)
  121.                     continue;
  122.  
  123.                 error = RGBdiff(GetRed(index),
  124.                         GetGreen(index),
  125.                         GetBlue(index),
  126.                         Palette[Pal].rgb_Red,
  127.                         Palette[Pal].rgb_Green,
  128.                         Palette[Pal].rgb_Blue);
  129.  
  130.                 if (error < ErrBuf[index]) {
  131.                     ErrBuf[index] = error;
  132.                     PaletteBuf[index] = Pal;
  133.                 }
  134.             }
  135.         }
  136.  
  137.         for (index = 0; index < 16; index++)
  138.             SHAMmem[ShamIndex++] = (UWORD)(
  139.                 Palette[index].rgb_Red   << 8 |
  140.                 Palette[index].rgb_Green << 4 |
  141.                 Palette[index].rgb_Blue);
  142.  
  143.         for (index2 = 0; index2 < (ISLACED ? 2 : 1); index2++) {
  144.             PreviousRed   = Palette[0].rgb_Red;
  145.             PreviousGreen = Palette[0].rgb_Green;
  146.             PreviousBlue  = Palette[0].rgb_Blue;
  147.  
  148.             for (LineErr = x = 0; x < gdesc.gd_Width; x++) {
  149.                 current = GetValue(x, y + index2);
  150.  
  151.                 CurrentRed   = GetRed(current);
  152.                 CurrentGreen = GetGreen(current);
  153.                 CurrentBlue  = GetBlue(current);
  154.  
  155.                 besterr = ErrBuf[current];
  156.                 bestpal = PaletteBuf[current];
  157.  
  158.                 error = RGBdiff(
  159.                     CurrentRed,
  160.                     CurrentGreen,
  161.                     CurrentBlue,
  162.                     CurrentRed,
  163.                     PreviousGreen,
  164.                     PreviousBlue);
  165.  
  166.                 if (error < besterr) {
  167.                     besterr = error;
  168.                     bestpal = 16;
  169.                 }
  170.  
  171.                 error = RGBdiff(
  172.                     CurrentRed,
  173.                     CurrentGreen,
  174.                     CurrentBlue,
  175.                     PreviousRed,
  176.                     CurrentGreen,
  177.                     PreviousBlue);
  178.  
  179.                 if (error < besterr) {
  180.                     besterr = error;
  181.                     bestpal = 17;
  182.                 }
  183.  
  184.                 error = RGBdiff(
  185.                     CurrentRed,
  186.                     CurrentGreen,
  187.                     CurrentBlue,
  188.                     PreviousRed,
  189.                     PreviousGreen,
  190.                     CurrentBlue);
  191.  
  192.                 if (error < besterr) {
  193.                     besterr = error;
  194.                     bestpal = 18;
  195.                 }
  196.  
  197.                 if (bestpal < 16) {
  198.                     PutValue(x, y + index2, bestpal);
  199.  
  200.                     PreviousRed   = Palette[bestpal].rgb_Red;
  201.                     PreviousGreen = Palette[bestpal].rgb_Green;
  202.                     PreviousBlue  = Palette[bestpal].rgb_Blue;
  203.                 } else if (bestpal == 16) {
  204.                     PutValue(x, y + index2, CurrentRed | 0x20);
  205.  
  206.                     PreviousRed = CurrentRed;
  207.                 } else if (bestpal == 17) {
  208.                     PutValue(x, y + index2, CurrentGreen | 0x30);
  209.  
  210.                     PreviousGreen = CurrentGreen;
  211.                 } else {
  212.                     PutValue(x, y + index2, CurrentBlue | 0x10);
  213.  
  214.                     PreviousBlue = CurrentBlue;
  215.                 }
  216.  
  217.                 LineErr += besterr;
  218.             }
  219.  
  220.             TotalErr += LineErr;
  221.         }
  222.  
  223.         if (DisplayCounts)
  224.             MyPrintf("\x1B[%sD\x1B[K", (ISLACED ? "34" : "27"));
  225.     }
  226.  
  227.     {
  228.         ULONG    ErrPerPixel;
  229.         char    TextBuf[10];
  230.  
  231.         ErrPerPixel = ((TotalErr / gdesc.gd_Height) * 1000) / gdesc.gd_Width;
  232.         MySPrintf(TextBuf, "%ld.%03ld", ErrPerPixel / 1000, ErrPerPixel % 1000);
  233.  
  234.         MyPrintf("\x1B[%ldDTotal colour error = %ld, Mean per line = %ld, Per pixel = %s.\n",
  235.             (DisplayCounts ? 4 : 7), TotalErr, TotalErr / gdesc.gd_Height, TextBuf);
  236.     }
  237. }
  238.