[comp.os.msdos.programmer] VGA palette

am42+@andrew.cmu.edu (Alexander Paul Morris) (01/30/91)

I have some 24-bit images that I'd like to display on a 256 color vga
adapter.  But I can't seem to translate the appropriate colors.  First
of all, the vga palette is on 18 bits, so color resolution is already
lost there.  But if all I were doing was going from 24-bit to 18-bit
rgb, it would not really be a problem.  But going to 256 colors (8-bit),
I don't know which of the 18-bit palette to place into the 256 color
positions.  Has anyone done any work with this?  Does anyone have any
idea on how to get a good palette from this?  Thanks in advance for any
help.

    Alexander Morris                  "People die, things change...
    Carnegie Mellon                             It's sad."

eversole@acae037.cadence.com (Richard Eversole; x6239) (02/01/91)

What is the format for the 24-bit map ?


Are you familiar with pbmplus ? It is a PD graphics file format
translator that runs on Unix platforms. One of the utilities is
ppmquant, which can quantize a pixel map into a limited set of
colors. Not perfect but them changing 24-bit map into 256 colors
is not likely to be perfect.

Pbmplus supports many input & output formats.

Check the alt.graphics.pixutils to find out where the latest version is.
pbmplus is in a Beta test cycle right now for the latest release
-- 
  
  =====================================================================

    eversole@cadence.com
  
    Live long and prosper !

  ==========================================================================

           -------------  
                       /  
          ----------  /   
                   / /    
        --------  / /      ____   ------  ____   _____         ____  _____
       ------  / / /      /    \    /\    |   \  |     |\   | /    \ |
      ----  / / / /       |        /  \   |    | |__   | \  | |      |__
     --  / / / / /        |       /----\  |    | |     |  \ | |      |
    / / / / / / /         \____/ /      \ |___/  |____ |   \| \____/ |____
    \ \ \ \ \ \ \         
   
   ==========================================================================

dave@tygra.UUCP (David Conrad) (03/27/91)

Here are routines which modify the VGA palette, in response to a query
posted in comp.lang.c.  I've used the Pascal routines quite extensively,
but the C routines I translated from Pascal.  I did test them, but being
somewhat of a novice in C I'd appreciate it if anyone who is bilingual
would scan the two for any misteaks.  Compiled and tested under Turbo
Pascal 5.5 and Turbo C++ 1.0 (patched) under MS-DOS 3.30 on AutoComputer
VIP 286/12 IBM PC-AT Compatible with Paradise SVGA card.

File VGAPAL.PAS
unit vgapal;  (* release 3-91 pas *)

(* BIOS level routines to change the VGA palette registers from Turbo Pascal,
   should work on any VGA BIOS-compatible with IBM VGA (probably all of 'em).
   There is no SetRGBPalette corresponding to GetRGBPalette because this
   routine is already provided by the Graph unit, however if it is needed it
   should be easy to write given the SetDACBlock routine.
   (Get|Set)DACBlock were written by the chaps at Borland and came with the
   VGA256.BGI driver, GetRGBPalette was written and tested by me, David R.
   Conrad.  I hereby disclaim all warranties, both expressed and implied,
   as to the merchantability or fitness for a particular purpose of this
   program.  GetDACBlock and SetDACBlock are Copyright 1990 Borland Intl.,
   GetRGBPalette is Copyright 1991 David Conrad, all are Public Domain. *)

interface

uses dos;

type
  RGBcolor   = record
                 R, G, B : byte;
               end;
  VGApalette = array[0..255] of RGBColor;

(*
  example on how to get/set the entire palette:

  GetDACBlock(0, 256, VGAPal);
  SetDACBlock(0, 256, VGAPal);
*)

procedure GetRGBPalette (ColorNum : integer; var Color : RGBcolor);
procedure GetDACBlock (Start, Count : integer; var Pal : VGApalette);
procedure SetDACBlock (Start, Count : integer; var Pal : VGApalette);

implementation

procedure GetRGBPalette (ColorNum : integer; var Color : RGBcolor);
var
  Regs : Registers;
begin
  with Regs do
  begin
    AH := $10;
    AL := $17;
    BX := ColorNum;
    CX := 1;
    ES := Seg(Color);
    DX := Ofs(Color);
  end;
  Intr($10, Regs);
end;

procedure GetDACBlock (Start, Count : integer; var Pal : VGApalette);
var
  Regs : Registers;
begin
  with Regs do
  begin
    AH := $10;
    AL := $17;
    BX := Start;
    CX := Count;
    ES := Seg(Pal);
    DX := Ofs(Pal);
  end;
  Intr($10, Regs);
end;

procedure SetDACBlock (Start, Count : integer; var Pal : VGApalette);
var
  Regs : Registers;
begin
  with Regs do
  begin
    AH := $10;
    AL := $12;
    BX := Start;
    CX := Count;
    ES := Seg(Pal);
    DX := Ofs(Pal);
  end;
  Intr($10, Regs);
end;

end.

File VGAPAL.H
/* vgapal.h release 3-91 c */

/* BIOS level routines to change the VGA palette register from C.  Should
   work on any VGA which is BIOS-compatible with the IBM VGA (which should
   be all of them).  Tested under Turbo C++ 1.00 (with patches applied),
   may work under 1.01, TC 2.0, 1.5, 1.0, should be easily portable to
   other MS-DOS C compilers.  (The only problem I can forsee is with the
   interrupt calling mechanism, which varies from vendor to vendor.)
   There is no setrgbpalette() corresponding to getrgbpalette() because
   that is already provided by graphics.h.
   This code is based on code written by Borland Intl.; it is Copyright
   1991 David R. Conrad, Public Domain, and I disclaim all warranties,
   both expressed and implied, as to the merchantability or fitness for
   a particular purpose of this program.  */

#ifndef __VGAPAL_H
#define __VGAPAL_H

#include <dos.h>

struct rgbcolor {
  unsigned char rcolor;
  unsigned char gcolor;
  unsigned char bcolor;
};

typedef struct rgbcolor vgapalette[256];

/*
  example on how to get/set the entire palette:

  getdacblock (0, 256, &vgapal);
  setdacblock (0, 256, &vgapal);
*/

#ifdef __cplusplus
extern "C" {
#endif

void getrgbpalette (int colornum, struct rgbcolor *color)
{
  union REGS regs;
  struct SREGS sregs;

  regs.h.ah = 0x10;
  regs.h.al = 0x17;
  regs.x.bx = colornum;
  regs.x.cx = 1;
  sregs.es  = FP_SEG(color);
  regs.x.dx = FP_OFF(color);
  int86x (0x10, &regs, &regs, &sregs);
}

void getdacblock (int start, int count, vgapalette *pal)
{
  union REGS regs;
  struct SREGS sregs;

  regs.h.ah = 0x10;
  regs.h.al = 0x17;
  regs.x.bx = start;
  regs.x.cx = count;
  sregs.es  = FP_SEG(pal);
  regs.x.dx = FP_OFF(pal);
  int86x (0x10, &regs, &regs, &sregs);
}

void setdacblock (int start, int count, vgapalette *pal)
{
  union REGS regs;
  struct SREGS sregs;

  regs.h.ah = 0x10;
  regs.h.al = 0x12;
  regs.x.bx = start;
  regs.x.cx = count;
  sregs.es  = FP_SEG(pal);
  regs.x.dx = FP_OFF(pal);
  int86x (0x10, &regs, &regs, &sregs);
}

#ifdef __cplusplus
}
#endif

#endif
-- 
=  CAT-TALK Conferencing Network, Computer Conferencing and File Archive  =
-  1-313-343-0800, 300/1200/2400/9600 baud, 8/N/1. New users use 'new'    - 
=  as a login id.  AVAILABLE VIA PC-PURSUIT!!! (City code "MIDET")        =
   E-MAIL Address: dave%tygra@sharkey.cc.umich.edu

coy@ssc-vax (Stephen B Coy) (04/01/91)

In article <1991Mar27.090742.1726@tygra.UUCP> dave@tygra.UUCP (David Conrad) writes:
>   This code is based on code written by Borland Intl.; it is Copyright
>   1991 David R. Conrad, Public Domain, and I disclaim all warranties,
>   both expressed and implied, as to the merchantability or fitness for
>   a particular purpose of this program.  */

OK, what is it?  You've got a copyright notice and public domain
written above.  If you want to release this code into the public
domain then please take your copyright notice out of it.  If you
want to retain the copyright take the words "public domain" out and
clearly explain the conditions for its distribution and/or use.

Stephen Coy
coy@ssc-vax.UUCP

				BDIF