To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.cad.devOpen lugnet.cad.dev in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 CAD / Development / 6206
6205  |  6207
Subject: 
Re: Substitute Colors for Dithered Colors?
Newsgroups: 
lugnet.cad.dev
Date: 
Mon, 2 Jul 2001 01:13:22 GMT
Viewed: 
413 times
  
Erik Olson wrote...
I'm wondering how to treat dithered colors (LDRAW 0x0100 to 0x01ff, see
FAQ). Short of implementing a dithered texture--which would preserve that
old-timey look--I'm seeking a conversion function.

My first guess is that the perceptual equivalent of a dithered color is the
average of its RGB components. Good enough or not?

I use the average of the two colors' RGB. Try it out in L3Lab by toggling
the "Dither or blend colord 256-511" button in the toolbar.
Here is the code I use for color decoding:

/* Return -1 on invalid LDraw color. rgb may be NULL for test only. */
int                  Color2rgb(long Color, float rgb[], int *IsTransparent)
{
   int                  c1;
   int                  c2;

   if (rgb)
      rgb[0] = rgb[1] = rgb[2] = 0.5;     /* default                         */
   if (IsTransparent)
      *IsTransparent = 0;                 /* Assume opaque (non-transparent  */

   /* if ((0 <= Color && Color <= 15) || (32 <= Color && Color <= 47)) */
   if (0 <= Color && Color <= 63 && !(Rgbs[(int) Color] & 0x80000000)) /* (int) is for TurboC */
   {
      if (rgb)
      {
         rgb[0] = GetRValue(Rgbs[(int) Color]) / 255.0;  /* (int)            */
         rgb[1] = GetGValue(Rgbs[(int) Color]) / 255.0;  /* is for           */
         rgb[2] = GetBValue(Rgbs[(int) Color]) / 255.0;  /* TurboC           */
      }
      if (IsTransparent && Color >= 32)
         *IsTransparent = 1;
      return 0;
   }
   if (256 <= Color && Color <= 511)
   {
      if (rgb)
      {
         c1 = ((int) Color) & 15;         /* (int) is for TurboC             */
         c2 = (((int) Color) >> 4) & 15;  /* (int) is for TurboC             */
         rgb[0] = (GetRValue(Rgbs[c1]) + GetRValue(Rgbs[c2])) / (2 * 255.0);
         rgb[1] = (GetGValue(Rgbs[c1]) + GetGValue(Rgbs[c2])) / (2 * 255.0);
         rgb[2] = (GetBValue(Rgbs[c1]) + GetBValue(Rgbs[c2])) / (2 * 255.0);
      }
      return 0;
   }
   /* switch (Color) -- TurboC (K&R1) only accepts int */
   c1 = (unsigned char) (Color >> 24);
   switch (c1)
   {
      case 3:
         if (IsTransparent)
            *IsTransparent = 1;
         /* Fall through */
      case 2:
         if (rgb)
         {
            rgb[0] = ((Color >> 16) & 255) / 255.0;
            rgb[1] = ((Color >> 8) & 255) / 255.0;
            rgb[2] = (Color & 255) / 255.0;
         }
         return 0;
      case 4:
         if (rgb)
         {
            rgb[0] = (((Color >> 20) & 15) + ((Color >> 8) & 15)) / (2 * 15.0);
            rgb[1] = (((Color >> 16) & 15) + ((Color >> 4) & 15)) / (2 * 15.0);
            rgb[2] = (((Color >> 12) & 15) + (Color & 15)) / (2 * 15.0);
         }
         return 0;
      case 5:                             /* Use 0x05RGB000                  */
         Color >>= 12;
         /* Fall through */
      case 6:                             /* Use 0x06000RGB                  */
         if (rgb)
         {
            rgb[0] = ((Color >> 8) & 15) / 15.0;
            rgb[1] = ((Color >> 4) & 15) / 15.0;
            rgb[2] = (Color & 15) / 15.0;
         }
         if (IsTransparent)
            *IsTransparent = 1;
         return 0;
      case 7:
         if (rgb)
         {
            rgb[0] = rgb[1] = rgb[2] = 0.0;  /* Invisible!                   */
         }
         return 0;
   }
   return -1;
}

Rgbs is an array holding the RGB values for the first 64 colors:
COLORREF             Rgbs[64] =
{
   RGB(0, 0, 0),
   RGB(0, 0, 170),
   RGB(0, 170, 0),
   RGB(0, 170, 170),
   RGB(170, 0, 0),
   RGB(170, 85, 127),
    ...
   0x80000000, /* Color 16 is illegal here */
   ...
};
COLORREF is a Windows thing:

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef DWORD        COLORREF;
#define RGB(r,g,b)          ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#define GetRValue(rgb)      ((BYTE)(rgb))
#define GetGValue(rgb)      ((BYTE)(((WORD)(rgb)) >> 8))
#define GetBValue(rgb)      ((BYTE)((rgb)>>16))

i.e. the color is encoded 0x00BBGGRR
I set a bit (0x80000000) for illegal colors, such as 16, 24, 29 etc.

Also you may find this table useful:
// Color24 has edge colors (contrast colors/complement colors) for colors 0..15
// Complementing is not reversible for colors 6,7,14,15.
// i.e. Color24[Color24[6]] == 8
int                  Color24[32] = {
   8, 9, 10, 11, 12, 13, 0, 8,
   0, 1, 2, 3, 4, 5, 8, 8,
   24, 2, 8, 6, 22, 8, 20, 9,
   0, 4, 13, 2, 6, 15, 15, 15
};
/Lars (leaving for vacation in Norway :-)



Message has 1 Reply:
  Re: Substitute Colors for Dithered Colors?
 
Wow, Lars, that was a lot of code to support r = (r1+r2)/2. The obvious hypothesis would say that the eye performs spatial integration on the pixels, so therefore values are averaged. I guess I can try it on my eyes with L3Lab then. I looked in (...) (23 years ago, 2-Jul-01, to lugnet.cad.dev)

Message is in Reply To:
  Substitute Colors for Dithered Colors?
 
Hi, I'm wondering how to treat dithered colors (LDRAW 0x0100 to 0x01ff, see FAQ). Short of implementing a dithered texture--which would preserve that old-timey look--I'm seeking a conversion function. My first guess is that the perceptual equivalent (...) (23 years ago, 30-Jun-01, to lugnet.cad.dev)

5 Messages in This Thread:


Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR