home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
rexx
/
library2
/
gbmrexx
/
gbm
/
gbmht.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-27
|
35KB
|
1,492 lines
/*
GBMHT.C Halftoner
*/
/*...sincludes:0:*/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "standard.h"
#include "gbm.h"
/*...vgbm\46\h:0:*/
/*...e*/
/*...svars:0:*/
static BOOLEAN inited = FALSE;
/*
For 6Rx6Gx6B, 7Rx8Gx4B palettes etc.
*/
static byte index4 [0x400];
static byte index6 [0x400];
static byte index7 [0x400];
static byte index8 [0x400];
static byte scale4 [] = { 0, 85, 170, 255 };
static byte scale6 [] = { 0, 51, 102, 153, 204, 255 };
static byte scale7 [] = { 0, 43, 85, 128, 170, 213, 255 };
static byte scale8 [] = { 0, 36, 73, 109, 146, 182, 219, 255 };
static byte map_to_012 [0x900];
/* Returns 0 if index < 0x80 */
/* 1 if index >= 0x80 and index < 0xff */
/* 2 if index = 0xff */
static byte map_to_inx [3][3][3];
static GBMRGB gbmrgb_vga [] =
{
0, 0, 0,
128, 0, 0,
0,128, 0,
128,128, 0,
0, 0,128,
128, 0,128,
0,128,128,
128,128,128,
204,204,204,
255, 0, 0,
0,255, 0,
255,255, 0,
0, 0,255,
255, 0,255,
0,255,255,
255,255,255,
};
static GBMRGB gbmrgb_8 [] =
{
0, 0, 0,
0, 0,255,
0,255, 0,
0,255,255,
255, 0, 0,
255, 0,255,
255,255, 0,
255,255,255,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
};
/*...e*/
/*...sdivt:0:*/
/*
This fold encompases a way to get rapid division via lookup tables.
*/
static word divt9 [9 * 0x100];
static word divt7 [9 * 0x100];
static word divt6 [9 * 0x100];
static word divt5 [9 * 0x100];
static word divt3 [9 * 0x100];
/*...smake_divt:0:*/
static void make_divt(word *divt, int size, int by)
{
int i;
for ( i = 0; i < size; i++ )
divt [i] = (word) (i / by);
}
/*...e*/
#define div9(w) divt9[w]
#define div8(w) ((w)>>3)
#define div7(w) divt7[w]
#define div6(w) divt6[w]
#define div5(w) divt5[w]
#define div4(w) ((w)>>2)
#define div3(w) divt3[w]
#define div2(w) ((w)>>1)
/*...e*/
/*...sinit:0:*/
/*
This function initialises this module.
*/
/*...stakeout_inx:0:*/
/*
For the supplied value, find the index of the highest value in the scale
less than or equal to the value.
*/
static byte takeout_inx(int value, byte ab [], unsigned short cb)
{
byte inx = 0;
unsigned short i;
for ( i = 0; i < cb; i++ )
if ( (unsigned short) ab [i] <= (unsigned short) value )
inx = i;
return ( inx );
}
/*...e*/
/*...stakeout_inx_vga:0:*/
/*
The idea is to take as much of the r, g and b as possible by chosing a
colour from the VGA palette that leaves as little left over as possible.
Since there are 2 mid-greys, we discourage the use of one.
The only justification for this is that the results seem to come out better!
Also, I have tried allowing takefrom to return the closest index, allowing
more to be taken than r,g and b. This gives less grey results, but the
output is a lot dirtier and speckled.
*/
static byte takeout_inx_vga(word r, word g, word b)
{
byte inx;
byte inx_min = 0;
int e_min = (int) ( r + g + b );
for ( inx = 1; inx < 16; inx++ )
if ( inx != 8 )
{
int re = (int) ( r - (word) gbmrgb_vga [inx].r );
int ge = (int) ( g - (word) gbmrgb_vga [inx].g );
int be = (int) ( b - (word) gbmrgb_vga [inx].b );
if ( re >= 0 && ge >= 0 && be >= 0 )
{
int e = re + ge + be;
if ( e < e_min )
{
e_min = e;
inx_min = inx;
}
}
}
return ( inx_min );
}
/*...e*/
static void init(void)
{
static word val [] = { 0, 0x80, 0xff };
int i;
int volatile r; /* C-Set/2 optimiser fix */
int volatile g;
int volatile b;
if ( inited )
return;
/* For 7 Red x 8 Green x 4 Blue palettes etc. */
for ( i = 0; i < 0x400; i++ )
{
index4 [i] = takeout_inx(i, scale4 , sizeof(scale4));
index6 [i] = takeout_inx(i, scale6 , sizeof(scale6));
index7 [i] = takeout_inx(i, scale7 , sizeof(scale7));
index8 [i] = takeout_inx(i, scale8 , sizeof(scale8));
}
memset(map_to_012, 0, 0x80);
memset(map_to_012 + 0x80, 1, 0x7f);
memset(map_to_012 + 0xff, 2, 0x801);
for ( r = 0; r < 3; r++ )
for ( g = 0; g < 3; g++ )
for ( b = 0; b < 3; b++ )
map_to_inx [r][g][b] = takeout_inx_vga(val [r], val [g], val [b]);
make_divt(divt9, sizeof(divt9)/sizeof(word), 9);
make_divt(divt7, sizeof(divt7)/sizeof(word), 7);
make_divt(divt6, sizeof(divt6)/sizeof(word), 6);
make_divt(divt5, sizeof(divt5)/sizeof(word), 5);
make_divt(divt3, sizeof(divt3)/sizeof(word), 3);
inited = TRUE;
}
/*...e*/
/*...stakefrom:0:*/
#define takefrom(r,g,b) ( map_to_inx [map_to_012 [r]][map_to_012 [g]][map_to_012 [b]] )
/*...e*/
/*...ssplit_into:0:*/
/* n is only ever 2, 3, 4, 6 or 9 */
static void split_into(
word r, word g, word b,
int n, byte *inxs
)
{
byte inx;
if ( n >= 9 )
{
inx = takefrom(div9(r), div9(g), div9(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
inx = takefrom(div8(r), div8(g), div8(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
inx = takefrom(div7(r), div7(g), div7(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
}
if ( n >= 6 )
{
inx = takefrom(div6(r), div6(g), div6(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
inx = takefrom(div5(r), div5(g), div5(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
}
if ( n >= 4 )
{
inx = takefrom(div4(r), div4(g), div4(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
}
if ( n >= 3 )
{
inx = takefrom(div3(r), div3(g), div3(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
}
inx = takefrom(div2(r), div2(g), div2(b));
b -= gbmrgb_vga [inx].b;
g -= gbmrgb_vga [inx].g;
r -= gbmrgb_vga [inx].r;
*inxs++ = inx;
*inxs = takefrom(r, g, b);
}
/*...e*/
/*...stakefrom8:0:*/
/*
Find the largest colour from the 8 colour palette.
*/
#define takefrom8(r,g,b) ( (((r)>=255)<<2) | (((g)>=255)<<1) | ((b)>=255) )
/*...e*/
/*...ssplit_into8:0:*/
/* n is only ever 2, 3, 4, 6 or 9 */
static void split_into8(
word r, word g, word b,
int n, byte *inxs
)
{
byte inx;
if ( n >= 9 )
{
inx = takefrom8(div9(r), div9(g), div9(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
inx = takefrom8(div8(r), div8(g), div8(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
inx = takefrom8(div7(r), div7(g), div7(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
}
if ( n >= 6 )
{
inx = takefrom8(div6(r), div6(g), div6(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
inx = takefrom8(div5(r), div5(g), div5(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
}
if ( n >= 4 )
{
inx = takefrom8(div4(r), div4(g), div4(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
}
if ( n >= 3 )
{
inx = takefrom8(div3(r), div3(g), div3(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
}
inx = takefrom8(div2(r), div2(g), div2(b));
b -= gbmrgb_8 [inx].b;
g -= gbmrgb_8 [inx].g;
r -= gbmrgb_8 [inx].r;
*inxs++ = inx;
*inxs = takefrom8(r, g, b);
}
/*...e*/
/*...sgbm_ht_24_2x2 \45\ halftone by 2x2 to r\58\g\58\b bits:0:*/
void gbm_ht_24_2x2(GBM *gbm, byte *src24, byte *dest24, byte rm, byte gm, byte bm)
{
int stride = ((gbm -> w * 3 + 3) & ~3);
int x, y;
init();
src24 -= stride;
dest24 -= stride;
for ( y = 0; y < gbm -> h - 1; y += 2 )
{
byte *src24a = (src24 += stride);
byte *src24b = (src24 += stride);
byte *dest24a = (dest24 += stride);
byte *dest24b = (dest24 += stride);
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x2 case:24:*/
{
word r,g,b;
byte ri,gi,bi;
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
bi = (div4(b) & bm); gi = (div4(g) & gm); ri = (div4(r) & rm);
*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
b -= bi; g -= gi; r -= ri;
if ( b > 255 * 3 ) b = 255 * 3;
if ( g > 255 * 3 ) g = 255 * 3;
if ( r > 255 * 3 ) r = 255 * 3;
bi = (div3(b) & bm); gi = (div3(g) & gm); ri = (div3(r) & rm);
*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
b -= bi; g -= gi; r -= ri;
if ( b > 255 * 2 ) b = 255 * 2;
if ( g > 255 * 2 ) g = 255 * 2;
if ( r > 255 * 2 ) r = 255 * 2;
bi = (div2(b) & bm); gi = (div2(g) & gm); ri = (div2(r) & rm);
*dest24b++ = bi; *dest24b++ = gi; *dest24b++ = ri;
b -= bi; g -= gi; r -= ri;
if ( b > 255 ) b = 255;
if ( g > 255 ) g = 255;
if ( r > 255 ) r = 255;
bi = (b & bm); gi = (g & gm); ri = (r & rm);
*dest24b++ = bi; *dest24b++ = gi; *dest24b++ = ri;
tmp = dest24a; dest24a = dest24b; dest24b = tmp;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x2 case:24:*/
{
word r,g,b;
byte ri, gi, bi;
b = *src24a++; g = *src24a++; r = *src24a;
b += *src24b++; g += *src24b++; r += *src24b;
bi = (div2(b) & bm); gi = (div2(g) & gm); ri = (div2(r) & rm);
*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
b -= bi; g -= gi; r -= ri;
if ( b > 255 ) b = 255;
if ( g > 255 ) g = 255;
if ( r > 255 ) r = 255;
bi = (b & bm); gi = (g & gm); ri = (r & rm);
*dest24b++ = bi; *dest24b++ = gi; *dest24b = ri;
}
/*...e*/
}
if ( y < gbm -> h )
{
byte *src24a = src24 + stride;
byte *dest24a = dest24 + stride;
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x1 case:24:*/
{
word r,g,b;
byte ri, gi, bi;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
bi = (div2(b) & bm); gi = (div2(g) & gm); ri = (div2(r) & rm);
*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
b -= bi; g -= gi; r -= ri;
if ( b > 255 ) b = 255;
if ( g > 255 ) g = 255;
if ( r > 255 ) r = 255;
bi = (b & bm); gi = (g & gm); ri = (r & rm);
*dest24a++ = bi; *dest24a++ = gi; *dest24a++ = ri;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x1 case:24:*/
{
byte ri, gi, bi;
bi = ((*src24a++) & bm); gi = ((*src24a++) & gm); ri = ((*src24a) & rm);
*dest24a++ = bi; *dest24a++ = gi; *dest24a = ri;
}
/*...e*/
}
}
/*...e*/
/*...sgbm_ht_pal_6R6G6B \45\ return 6Rx6Gx6B palette:0:*/
/*
This function makes the palette for the 6 red x 6 green x 6 blue palette.
216 palette entrys used. Remaining 40 left blank.
*/
void gbm_ht_pal_6R6G6B(GBMRGB *gbmrgb)
{
byte volatile r; /* C-Set/2 optimiser fix */
byte volatile g;
byte volatile b;
init();
memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
for ( r = 0; r < 6; r++ )
for ( g = 0; g < 6; g++ )
for ( b = 0; b < 6; b++ )
{
gbmrgb -> r = scale6 [r];
gbmrgb -> g = scale6 [g];
gbmrgb -> b = scale6 [b];
gbmrgb++;
}
}
/*...e*/
/*...sgbm_ht_6R6G6B_2x2 \45\ halftone by 2x2 to 6Rx6Gx6B palette:0:*/
#define PIX666(ri,gi,bi) (byte) (6 * (6 * ri + gi) + bi)
void gbm_ht_6R6G6B_2x2(GBM *gbm, byte *src24, byte *dest8)
{
int stride24 = ((gbm -> w * 3 + 3) & ~3);
int stride8 = ((gbm -> w + 3) & ~3);
int x, y;
init();
src24 -= stride24;
dest8 -= stride8;
for ( y = 0; y < gbm -> h - 1; y += 2 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *dest8a = (dest8 += stride8);
byte *dest8b = (dest8 += stride8);
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x2 case:24:*/
{
word r,g,b;
byte ri,gi,bi;
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
bi = index6 [div4(b)]; gi = index6 [div4(g)]; ri = index6 [div4(r)];
*dest8a++ = PIX666(ri,gi,bi);
b -= scale6 [bi]; g -= scale6 [gi]; r -= scale6 [ri];
bi = index6 [div3(b)]; gi = index6 [div3(g)]; ri = index6 [div3(r)];
*dest8a++ = PIX666(ri,gi,bi);
b -= scale6 [bi]; g -= scale6 [gi]; r -= scale6 [ri];
bi = index6 [div2(b)]; gi = index6 [div2(g)]; ri = index6 [div2(r)];
*dest8b++ = PIX666(ri,gi,bi);
b -= scale6 [bi]; g -= scale6 [gi]; r -= scale6 [ri];
bi = index6 [b ]; gi = index6 [g ]; ri = index6 [r ];
*dest8b++ = PIX666(ri,gi,bi);
tmp = dest8a; dest8a = dest8b; dest8b = tmp;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x2 case:24:*/
{
word r,g,b;
byte ri, gi, bi;
b = *src24a++; g = *src24a++; r = *src24a;
b += *src24b++; g += *src24b++; r += *src24b;
bi = index6 [div2(b)]; gi = index6 [div2(g)]; ri = index6 [div2(r)];
*dest8a = PIX666(ri,gi,bi);
b -= scale6 [bi]; g -= scale6 [gi]; r -= scale6 [ri];
bi = index6 [b ]; gi = index6 [g ]; ri = index6 [r ];
*dest8b = PIX666(ri,gi,bi);
}
/*...e*/
}
if ( y < gbm -> h )
{
byte *src24a = src24 + stride24;
byte *dest8a = dest8 + stride8;
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x1 case:24:*/
{
word r,g,b;
byte ri, gi, bi;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
bi = index6 [div2(b)]; gi = index6 [div2(g)]; ri = index6 [div2(r)];
*dest8a++ = PIX666(ri,gi,bi);
b -= scale6 [bi]; g -= scale6 [gi]; r -= scale6 [ri];
bi = index6 [b ]; gi = index6 [g ]; ri = index6 [r ];
*dest8a++ = PIX666(ri,gi,bi);
}
/*...e*/
if ( x < gbm -> w )
/*...s1x1 case:24:*/
{
byte ri, gi, bi;
bi = index6 [*src24a++]; gi = index6 [*src24a++]; ri = index6 [*src24a];
*dest8a = PIX666(ri,gi,bi);
}
/*...e*/
}
}
/*...e*/
/*...sgbm_ht_pal_7R8G4B \45\ return 7Rx8Gx4B palette:0:*/
/*
This function makes the palette for the 7 red x 8 green x 4 blue palette.
224 palette entrys used. Remaining 32 left blank.
Colours calculated to match those used by 8514/A PM driver.
*/
void gbm_ht_pal_7R8G4B(GBMRGB *gbmrgb)
{
byte volatile r; /* C-Set/2 optimiser fix */
byte volatile g;
byte volatile b;
init();
memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
for ( r = 0; r < 7; r++ )
for ( g = 0; g < 8; g++ )
for ( b = 0; b < 4; b++ )
{
gbmrgb -> r = scale7 [r];
gbmrgb -> g = scale8 [g];
gbmrgb -> b = scale4 [b];
gbmrgb++;
}
}
/*...e*/
/*...sgbm_ht_7R8G4B_2x2 \45\ halftone by 2x2 to 7Rx8Gx4B palette:0:*/
#define PIX784(ri,gi,bi) (byte) (((((ri)<<3)+(gi))<<2)+(bi))
void gbm_ht_7R8G4B_2x2(GBM *gbm, byte *src24, byte *dest8)
{
int stride24 = ((gbm -> w * 3 + 3) & ~3);
int stride8 = ((gbm -> w + 3) & ~3);
int x, y;
init();
src24 -= stride24;
dest8 -= stride8;
for ( y = 0; y < gbm -> h - 1; y += 2 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *dest8a = (dest8 += stride8);
byte *dest8b = (dest8 += stride8);
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x2 case:24:*/
{
word r,g,b;
byte ri,gi,bi;
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
bi = index4 [div4(b)]; gi = index8 [div4(g)]; ri = index7 [div4(r)];
*dest8a++ = PIX784(ri,gi,bi);
b -= scale4 [bi]; g -= scale8 [gi]; r -= scale7 [ri];
bi = index4 [div3(b)]; gi = index8 [div3(g)]; ri = index7 [div3(r)];
*dest8a++ = PIX784(ri,gi,bi);
b -= scale4 [bi]; g -= scale8 [gi]; r -= scale7 [ri];
bi = index4 [div2(b)]; gi = index8 [div2(g)]; ri = index7 [div2(r)];
*dest8b++ = PIX784(ri,gi,bi);
b -= scale4 [bi]; g -= scale8 [gi]; r -= scale7 [ri];
bi = index4 [b ]; gi = index8 [g ]; ri = index7 [r ];
*dest8b++ = PIX784(ri,gi,bi);
tmp = dest8a; dest8a = dest8b; dest8b = tmp;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x2 case:24:*/
{
word r,g,b;
byte ri, gi, bi;
b = *src24a++; g = *src24a++; r = *src24a;
b += *src24b++; g += *src24b++; r += *src24b;
bi = index4 [div2(b)]; gi = index8 [div2(g)]; ri = index7 [div2(r)];
*dest8a = PIX784(ri,gi,bi);
b -= scale4 [bi]; g -= scale8 [gi]; r -= scale7 [ri];
bi = index4 [b ]; gi = index8 [g ]; ri = index7 [r ];
*dest8b = PIX784(ri,gi,bi);
}
/*...e*/
}
if ( y < gbm -> h )
{
byte *src24a = src24 + stride24;
byte *dest8a = dest8 + stride8;
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x1 case:24:*/
{
word r,g,b;
byte ri, gi, bi;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
bi = index4 [div2(b)]; gi = index8 [div2(g)]; ri = index7 [div2(r)];
*dest8a++ = PIX784(ri,gi,bi);
b -= scale4 [bi]; g -= scale8 [gi]; r -= scale7 [ri];
bi = index4 [b ]; gi = index8 [g ]; ri = index7 [r ];
*dest8a++ = PIX784(ri,gi,bi);
}
/*...e*/
if ( x < gbm -> w )
/*...s1x1 case:24:*/
{
byte ri, gi, bi;
bi = index4 [*src24a++]; gi = index8 [*src24a++]; ri = index7 [*src24a];
*dest8a = PIX784(ri,gi,bi);
}
/*...e*/
}
}
/*...e*/
/*...sgbm_ht_pal_VGA \45\ return default VGA palette:0:*/
/*
This function makes the palette for the 16 colour VGA palette.
*/
void gbm_ht_pal_VGA(GBMRGB *gbmrgb)
{
init();
memcpy((char *) gbmrgb, (char *) gbmrgb_vga, sizeof(gbmrgb_vga));
}
/*...e*/
/*...sgbm_ht_VGA_2x2 \45\ halftone by 2x2 to default VGA palette:0:*/
void gbm_ht_VGA_2x2(GBM *gbm, byte *src24, byte *dest4)
{
int stride24 = ((gbm -> w * 3 + 3) & ~3);
int stride4 = ((gbm -> w * 4 + 31) / 32) * 4;
int x, y;
init();
src24 -= stride24;
dest4 -= stride4;
for ( y = 0; y < gbm -> h - 1; y += 2 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
byte *dest4b = (dest4 += stride4);
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x2 case:24:*/
{
word r,g,b;
byte inx;
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
inx = takefrom(div4(r), div4(g), div4(b)); *dest4a = (inx << 4);
b -= gbmrgb_vga [inx].b; g -= gbmrgb_vga [inx].g; r -= gbmrgb_vga [inx].r;
inx = takefrom(div3(r), div3(g), div3(b)); *dest4a++ |= inx;
b -= gbmrgb_vga [inx].b; g -= gbmrgb_vga [inx].g; r -= gbmrgb_vga [inx].r;
inx = takefrom(div2(r), div2(g), div2(b)); *dest4b = (inx << 4);
b -= gbmrgb_vga [inx].b; g -= gbmrgb_vga [inx].g; r -= gbmrgb_vga [inx].r;
inx = takefrom(r , g , b ); *dest4b++ |= inx;
tmp = dest4a; dest4a = dest4b; dest4b = tmp;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x2 case:24:*/
{
word r,g,b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a;
b += *src24b++; g += *src24b++; r += *src24b;
inx = takefrom(div2(r), div2(g), div2(b)); *dest4a = (inx << 4);
b -= gbmrgb_vga [inx].b; g -= gbmrgb_vga [inx].g; r -= gbmrgb_vga [inx].r;
inx = takefrom(r , g , b ); *dest4b = (inx << 4);
}
/*...e*/
}
if ( y < gbm -> h )
{
byte *src24a = src24 + stride24;
byte *dest4a = dest4 + stride4;
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x1 case:24:*/
{
word r,g,b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
inx = takefrom(div2(r), div2(g), div2(b)); *dest4a = (inx << 4);
b -= gbmrgb_vga [inx].b; g -= gbmrgb_vga [inx].g; r -= gbmrgb_vga [inx].r;
inx = takefrom(r , g , b ); *dest4a++ |= inx;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x1 case:24:*/
{
word r, g, b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a;
inx = takefrom(r, g, b); *dest4a = (inx << 4);
}
/*...e*/
}
}
/*...e*/
/*...sgbm_ht_VGA_3x3 \45\ halftone by 3x3 to default VGA palette:0:*/
void gbm_ht_VGA_3x3(GBM *gbm, byte *src24, byte *dest4)
{
int stride24 = ((gbm -> w * 3 + 3) & ~3);
int stride4 = ((gbm -> w * 4 + 31) / 32) * 4;
int x, y;
init();
src24 -= stride24;
dest4 -= stride4;
for ( y = 0; y < gbm -> h - 2; y += 3 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *src24c = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
byte *dest4b = (dest4 += stride4);
byte *dest4c = (dest4 += stride4);
BOOLEAN left = TRUE;
for ( x = 0; x < gbm -> w - 2; x += 3, left = !left )
/*...s3x3 case:24:*/
{
word r,g,b;
byte inxs [9];
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24c++; g += *src24c++; r += *src24c++;
b += *src24c++; g += *src24c++; r += *src24c++;
b += *src24c++; g += *src24c++; r += *src24c++;
split_into(r, g, b, 9, inxs);
if ( left )
{
*dest4a++ = ((inxs [0] << 4) | inxs [1]); *dest4a = (inxs [2] << 4);
*dest4b++ = ((inxs [3] << 4) | inxs [4]); *dest4b = (inxs [5] << 4);
*dest4c++ = ((inxs [6] << 4) | inxs [7]); *dest4c = (inxs [8] << 4);
}
else
{
*dest4a++ |= inxs [0]; *dest4a++ = ((inxs [1] << 4) | inxs [2]);
*dest4b++ |= inxs [3]; *dest4b++ = ((inxs [4] << 4) | inxs [5]);
*dest4c++ |= inxs [6]; *dest4c++ = ((inxs [7] << 4) | inxs [8]);
}
tmp = dest4a; dest4a = dest4b; dest4b = dest4c; dest4c = tmp;
}
/*...e*/
if ( x < gbm -> w - 1 )
/*...s2x3 case:24:*/
{
word r,g,b;
byte inxs [6];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24c++; g += *src24c++; r += *src24c++;
b += *src24c++; g += *src24c++; r += *src24c++;
split_into(r, g, b, 6, inxs);
if ( left )
{
*dest4a = ((inxs [0] << 4) | inxs [1]);
*dest4b = ((inxs [2] << 4) | inxs [3]);
*dest4c = ((inxs [4] << 4) | inxs [5]);
}
else
{
*dest4a++ |= inxs [0]; *dest4a = (inxs [1] << 4);
*dest4b++ |= inxs [2]; *dest4b = (inxs [3] << 4);
*dest4c++ |= inxs [4]; *dest4c = (inxs [5] << 4);
}
}
/*...e*/
else if ( x < gbm -> w )
/*...s1x3 case:24:*/
{
word r,g,b;
byte inxs [3];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24c++; g += *src24c++; r += *src24c++;
split_into(r, g, b, 3, inxs);
if ( left )
{
*dest4a = (inxs [0] << 4);
*dest4b = (inxs [1] << 4);
*dest4c = (inxs [2] << 4);
}
else
{
*dest4a |= inxs [0];
*dest4b |= inxs [1];
*dest4c |= inxs [2];
}
}
/*...e*/
}
if ( y < gbm -> h - 1 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
byte *dest4b = (dest4 += stride4);
BOOLEAN left = TRUE;
for ( x = 0; x < gbm -> w - 2; x += 3, left = !left )
/*...s3x2 case:24:*/
{
word r,g,b;
byte inxs [6];
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
split_into(r, g, b, 6, inxs);
if ( left )
{
*dest4a++ = (inxs [0] << 4) | inxs [1]; *dest4a = (inxs [2] << 4);
*dest4b++ = (inxs [3] << 4) | inxs [4]; *dest4b = (inxs [5] << 4);
}
else
{
*dest4a++ |= inxs [0]; *dest4a++ = ((inxs [1] << 4) | inxs [2]);
*dest4b++ |= inxs [3]; *dest4b++ = ((inxs [4] << 4) | inxs [5]);
}
tmp = dest4a; dest4a = dest4b; dest4b = tmp;
}
/*...e*/
if ( x < gbm -> w - 1 )
/*...s2x2 case:24:*/
{
word r,g,b;
byte inxs [4];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
split_into(r, g, b, 4, inxs);
if ( left )
{
*dest4a = ((inxs [0] << 4) | inxs [1]);
*dest4b = ((inxs [2] << 4) | inxs [3]);
}
else
{
*dest4a++ |= inxs [0]; *dest4a = (inxs [1] << 4);
*dest4b++ |= inxs [2]; *dest4b = (inxs [3] << 4);
}
}
/*...e*/
else if ( x < gbm -> w )
/*...s1x2 case:24:*/
{
word r,g,b;
byte inxs [2];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
split_into(r, g, b, 2, inxs);
if ( left )
{
*dest4a = (inxs [0] << 4);
*dest4b = (inxs [1] << 4);
}
else
{
*dest4a |= inxs [0];
*dest4b |= inxs [1];
}
}
/*...e*/
}
else if ( y < gbm -> h )
{
byte *src24a = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
BOOLEAN left = TRUE;
for ( x = 0; x < gbm -> w - 2; x += 3, left = !left )
/*...s3x1 case:24:*/
{
word r,g,b;
byte inxs [3];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
split_into(r, g, b, 3, inxs);
if ( left )
{
*dest4a++ = ((inxs [0] << 4) | inxs [1]); *dest4a = (inxs [2] << 4);
}
else
{
*dest4a++ |= inxs [0]; *dest4a++ = ((inxs [1] << 4) | inxs [2]);
}
}
/*...e*/
if ( x < gbm -> w - 1 )
/*...s2x1 case:24:*/
{
word r,g,b;
byte inxs [2];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
split_into(r, g, b, 4, inxs);
if ( left )
*dest4a = ((inxs [0] << 4) | inxs [1]);
else
{
*dest4a++ |= inxs [0]; *dest4a = (inxs [1] << 4);
}
}
/*...e*/
else if ( x < gbm -> w )
/*...s1x1 case:24:*/
{
word r,g,b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a++;
inx = takefrom(r, g, b);
if ( left )
*dest4a = (inx << 4);
else
*dest4a |= inx;
}
/*...e*/
}
}
/*...e*/
/*...sgbm_ht_pal_8 \45\ return default 8 colour palette:0:*/
/*
This function makes the palette for the 8 colour palette.
*/
void gbm_ht_pal_8(GBMRGB *gbmrgb)
{
init();
memcpy((char *) gbmrgb, (char *) gbmrgb_8, sizeof(gbmrgb_8));
}
/*...e*/
/*...sgbm_ht_8_2x2 \45\ halftone by 2x2 to default 8 colour palette:0:*/
void gbm_ht_8_2x2(GBM *gbm, byte *src24, byte *dest4)
{
int stride24 = ((gbm -> w * 3 + 3) & ~3);
int stride4 = ((gbm -> w * 4 + 31) / 32) * 4;
int x, y;
init();
src24 -= stride24;
dest4 -= stride4;
for ( y = 0; y < gbm -> h - 1; y += 2 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
byte *dest4b = (dest4 += stride4);
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x2 case:24:*/
{
word r,g,b;
byte inx;
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
inx = takefrom8(r >> 2, g >> 2, b >> 2); *dest4a = (inx << 4);
b -= gbmrgb_8 [inx].b; g -= gbmrgb_8 [inx].g; r -= gbmrgb_8 [inx].r;
inx = takefrom8(r / 3, g / 3, b / 3); *dest4a++ |= inx;
b -= gbmrgb_8 [inx].b; g -= gbmrgb_8 [inx].g; r -= gbmrgb_8 [inx].r;
inx = takefrom8(r >> 1, g >> 1, b >> 1); *dest4b = (inx << 4);
b -= gbmrgb_8 [inx].b; g -= gbmrgb_8 [inx].g; r -= gbmrgb_8 [inx].r;
inx = takefrom8(r , g , b ); *dest4b++ |= inx;
tmp = dest4a; dest4a = dest4b; dest4b = tmp;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x2 case:24:*/
{
word r,g,b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a;
b += *src24b++; g += *src24b++; r += *src24b;
inx = takefrom8(r >> 1, g >> 1, b >> 1); *dest4a = (inx << 4);
b -= gbmrgb_8 [inx].b; g -= gbmrgb_8 [inx].g; r -= gbmrgb_8 [inx].r;
inx = takefrom8(r , g , b ); *dest4b = (inx << 4);
}
/*...e*/
}
if ( y < gbm -> h )
{
byte *src24a = src24 + stride24;
byte *dest4a = dest4 + stride4;
for ( x = 0; x < gbm -> w - 1; x += 2 )
/*...s2x1 case:24:*/
{
word r,g,b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
inx = takefrom8(r >> 1, g >> 1, b >> 1); *dest4a = (inx << 4);
b -= gbmrgb_8 [inx].b; g -= gbmrgb_8 [inx].g; r -= gbmrgb_8 [inx].r;
inx = takefrom8(r , g , b ); *dest4a++ |= inx;
}
/*...e*/
if ( x < gbm -> w )
/*...s1x1 case:24:*/
{
word r, g, b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a;
inx = takefrom8(r, g, b); *dest4a = (inx << 4);
}
/*...e*/
}
}
/*...e*/
/*...sgbm_ht_8_3x3 \45\ halftone by 3x3 to default 8 colour palette:0:*/
void gbm_ht_8_3x3(GBM *gbm, byte *src24, byte *dest4)
{
int stride24 = ((gbm -> w * 3 + 3) & ~3);
int stride4 = ((gbm -> w * 4 + 31) / 32) * 4;
int x, y;
init();
src24 -= stride24;
dest4 -= stride4;
for ( y = 0; y < gbm -> h - 2; y += 3 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *src24c = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
byte *dest4b = (dest4 += stride4);
byte *dest4c = (dest4 += stride4);
BOOLEAN left = TRUE;
for ( x = 0; x < gbm -> w - 2; x += 3, left = !left )
/*...s3x3 case:24:*/
{
word r,g,b;
byte inxs [9];
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24c++; g += *src24c++; r += *src24c++;
b += *src24c++; g += *src24c++; r += *src24c++;
b += *src24c++; g += *src24c++; r += *src24c++;
split_into8(r, g, b, 9, inxs);
if ( left )
{
*dest4a++ = ((inxs [0] << 4) | inxs [1]); *dest4a = (inxs [2] << 4);
*dest4b++ = ((inxs [3] << 4) | inxs [4]); *dest4b = (inxs [5] << 4);
*dest4c++ = ((inxs [6] << 4) | inxs [7]); *dest4c = (inxs [8] << 4);
}
else
{
*dest4a++ |= inxs [0]; *dest4a++ = ((inxs [1] << 4) | inxs [2]);
*dest4b++ |= inxs [3]; *dest4b++ = ((inxs [4] << 4) | inxs [5]);
*dest4c++ |= inxs [6]; *dest4c++ = ((inxs [7] << 4) | inxs [8]);
}
tmp = dest4a; dest4a = dest4b; dest4b = dest4c; dest4c = tmp;
}
/*...e*/
if ( x < gbm -> w - 1 )
/*...s2x3 case:24:*/
{
word r,g,b;
byte inxs [6];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24c++; g += *src24c++; r += *src24c++;
b += *src24c++; g += *src24c++; r += *src24c++;
split_into8(r, g, b, 6, inxs);
if ( left )
{
*dest4a = ((inxs [0] << 4) | inxs [1]);
*dest4b = ((inxs [2] << 4) | inxs [3]);
*dest4c = ((inxs [4] << 4) | inxs [5]);
}
else
{
*dest4a++ |= inxs [0]; *dest4a = (inxs [1] << 4);
*dest4b++ |= inxs [2]; *dest4b = (inxs [3] << 4);
*dest4c++ |= inxs [4]; *dest4c = (inxs [5] << 4);
}
}
/*...e*/
else if ( x < gbm -> w )
/*...s1x3 case:24:*/
{
word r,g,b;
byte inxs [3];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24c++; g += *src24c++; r += *src24c++;
split_into8(r, g, b, 3, inxs);
if ( left )
{
*dest4a = (inxs [0] << 4);
*dest4b = (inxs [1] << 4);
*dest4c = (inxs [2] << 4);
}
else
{
*dest4a |= inxs [0];
*dest4b |= inxs [1];
*dest4c |= inxs [2];
}
}
/*...e*/
}
if ( y < gbm -> h - 1 )
{
byte *src24a = (src24 += stride24);
byte *src24b = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
byte *dest4b = (dest4 += stride4);
BOOLEAN left = TRUE;
for ( x = 0; x < gbm -> w - 2; x += 3, left = !left )
/*...s3x2 case:24:*/
{
word r,g,b;
byte inxs [6];
byte *tmp;
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
split_into8(r, g, b, 6, inxs);
if ( left )
{
*dest4a++ = (inxs [0] << 4) | inxs [1]; *dest4a = (inxs [2] << 4);
*dest4b++ = (inxs [3] << 4) | inxs [4]; *dest4b = (inxs [5] << 4);
}
else
{
*dest4a++ |= inxs [0]; *dest4a++ = ((inxs [1] << 4) | inxs [2]);
*dest4b++ |= inxs [3]; *dest4b++ = ((inxs [4] << 4) | inxs [5]);
}
tmp = dest4a; dest4a = dest4b; dest4b = tmp;
}
/*...e*/
if ( x < gbm -> w - 1 )
/*...s2x2 case:24:*/
{
word r,g,b;
byte inxs [4];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
b += *src24b++; g += *src24b++; r += *src24b++;
split_into8(r, g, b, 4, inxs);
if ( left )
{
*dest4a = ((inxs [0] << 4) | inxs [1]);
*dest4b = ((inxs [2] << 4) | inxs [3]);
}
else
{
*dest4a++ |= inxs [0]; *dest4a = (inxs [1] << 4);
*dest4b++ |= inxs [2]; *dest4b = (inxs [3] << 4);
}
}
/*...e*/
else if ( x < gbm -> w )
/*...s1x2 case:24:*/
{
word r,g,b;
byte inxs [2];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24b++; g += *src24b++; r += *src24b++;
split_into8(r, g, b, 2, inxs);
if ( left )
{
*dest4a = (inxs [0] << 4);
*dest4b = (inxs [1] << 4);
}
else
{
*dest4a |= inxs [0];
*dest4b |= inxs [1];
}
}
/*...e*/
}
else if ( y < gbm -> h )
{
byte *src24a = (src24 += stride24);
byte *dest4a = (dest4 += stride4);
BOOLEAN left = TRUE;
for ( x = 0; x < gbm -> w - 2; x += 3, left = !left )
/*...s3x1 case:24:*/
{
word r,g,b;
byte inxs [3];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
split_into8(r, g, b, 3, inxs);
if ( left )
{
*dest4a++ = ((inxs [0] << 4) | inxs [1]); *dest4a = (inxs [2] << 4);
}
else
{
*dest4a++ |= inxs [0]; *dest4a++ = ((inxs [1] << 4) | inxs [2]);
}
}
/*...e*/
if ( x < gbm -> w - 1 )
/*...s2x1 case:24:*/
{
word r,g,b;
byte inxs [2];
b = *src24a++; g = *src24a++; r = *src24a++;
b += *src24a++; g += *src24a++; r += *src24a++;
split_into8(r, g, b, 4, inxs);
if ( left )
*dest4a = ((inxs [0] << 4) | inxs [1]);
else
{
*dest4a++ |= inxs [0]; *dest4a = (inxs [1] << 4);
}
}
/*...e*/
else if ( x < gbm -> w )
/*...s1x1 case:24:*/
{
word r,g,b;
byte inx;
b = *src24a++; g = *src24a++; r = *src24a++;
inx = takefrom8(r, g, b);
if ( left )
*dest4a = (inx << 4);
else
*dest4a |= inx;
}
/*...e*/
}
}
/*...e*/