00001 #ifndef RGB24_H 00002 #define RGB24_H 00003 00004 // The contents of this file are partly from 00005 // http://www.compuphase.com/graphic/scale2.htm#MAGNIFY2 00006 00007 struct rgb24 00008 { 00009 unsigned char c[3]; 00010 rgb24(){}; 00011 rgb24( unsigned long x ) 00012 { 00013 // will get shit on other-endian machines 00014 c[0] = x&0x0000ff; 00015 c[1] = (x&0x00ff00)>>8; 00016 c[2] = (x&0xff0000)>>16; 00017 }; 00018 unsigned long get_long( void ) 00019 { 00020 return (c[2]<<16)+(c[1]<<8)+c[0]; 00021 }; 00022 }; 00023 00024 extern unsigned long InterleaveTable24[256]; 00025 extern unsigned long InterleaveTable16[64]; 00026 00027 00028 void CreateInterleaveTable( void ); 00029 00030 inline long InterleavedValue24( rgb24 color ) 00031 { 00032 00033 return (InterleaveTable24[color.c[2]] << 2) | 00034 (InterleaveTable24[color.c[1]] << 1) | 00035 InterleaveTable24[color.c[0]]; 00036 00037 } 00038 00039 inline long InterleavedValue16( unsigned short color ) 00040 { 00041 00042 return (InterleaveTable16[color>>11] << 2) | 00043 (InterleaveTable16[(color>>5)&63] << 1) | 00044 InterleaveTable16[color&31]; 00045 00046 } 00047 00048 #define ABS(a) ( (a) >= 0 ? (a) : -(a) ) 00049 00050 inline long colordiff( rgb24 a, rgb24 b ) 00051 { 00052 return ABS(InterleavedValue24(a)-InterleavedValue24(b)); 00053 } 00054 00055 inline unsigned long colordiff( unsigned short a, unsigned short b ) 00056 { 00057 return ABS(InterleavedValue16(a)-InterleavedValue16(b)); 00058 } 00059 00060 00061 inline rgb24 average( rgb24 a, rgb24 b ) 00062 { 00063 rgb24 ret; 00064 ret.c[0] = (a.c[0]+(unsigned int)b.c[0])>>1; 00065 ret.c[1] = (a.c[1]+(unsigned int)b.c[1])>>1; 00066 ret.c[2] = (a.c[2]+(unsigned int)b.c[2])>>1; 00067 return ret; 00068 } 00069 00070 /* 16-bit HiColor (565 format) */ 00071 inline unsigned short average( unsigned short a, unsigned short b ) 00072 { 00073 if (a == b) { 00074 return a; 00075 } else { 00076 00077 // this mask taken from the guy does not work: 00078 //unsigned short mask = ~ (((a | b) & 0x0410) << 1); 00079 //return ((a & mask) + (b & mask)) >> 1; 00080 00081 // However, this one is simpler and seems to work: 00082 unsigned short mask = 0xf7df; // ~ (0x820); 00083 return ((a&mask) + (b&mask))>>1; 00084 00085 // reference 00086 //return (((((a&0xf800)>>1) + ((b&0xf800)>>1)))&0xf800) + 00087 //((((a&0x7e0) + (b&0x7e0))>>1)&0x7e0) + 00088 //(((a&0x1f) + (b&0x1f))>>1); 00089 } /* if */ 00090 } 00091 00092 00093 00094 00095 /* gray scale */ 00096 inline unsigned char average(unsigned char a, unsigned char b) 00097 { 00098 return (unsigned char)( ((int)a + (int)b) >> 1); 00099 } 00100 00101 /* 24-bit RGB (a pixel is packed in a 32-bit integer) */ 00102 inline unsigned long average(unsigned long a, unsigned long b) 00103 { 00104 return ((a & 0xfefefeffUL) + (b & 0xfefefeffUL)) >> 1; 00105 } 00106 00107 00108 #endif 00109