|
|
|
|
The screen captures above, (and most of the screen captures used throughout this article), are from the AppleWin Apple IIe emulator, running in color Double Hi-Res Graphics (DHGR) mode. The AppleWin display emulates Composite Artifacting which provides subpixel rendering similar to a real Apple IIe NTSC display. The nominal resolution of DHGR is 140 x 192, which is very coarse and does not have square pixels like today’s typical display modes. For comparison purposes, the images from the screen captures above are shown below using today’s square pixel RGB display without the advantage of composite artifacting.
|
|
|
|
However, it is not composite artifacting alone that makes possible the high quality display of images converted from today’s continuous tone images in the Apple IIe’s DHGR mode, (which supports only 15 colors from a fixed palette). The high precision error diffusion dithering (E-dithering) that you see here, and throughout this article is my own, developed initially for the DHGR NTSC display of the Apple IIe. Combined with the accurate NTSC conversion palette developed by Sheldon Simms, conversions like these go far beyond what has been commonly seen in the not so distant past on the DHGR display. Keep in mind however, that DHGR emulators like the Apple IIgs fall far short of producing accurate results of a similar quality even compared to images rendered using today’s square pixel RGB display without the advantage of composite artifacting. Note that I have referred to the Apple IIgs display as a DHGR emulator, because that is merely what it is, compared to the original DHGR NTSC display of the Apple IIe.
Some
Considerations for Display and Conversion of Apple II Double Hi-Res Graphics
Series of Articles and Background Notes – DHGR Plus
Selecting the Conversion Palette for the Target DHGR
Display
A Severe Compromise in 16 Colors or Less
Color Space and Color Matching for DHGR
A2B Source Code Listing – Setting Luma Coefficients
A2B Source Code Listing – Closest Color
Original Source and Win32 Download
This is an article is about some of the technical considerations surrounding converting modern graphics images to Apple II Double Hi-Res Graphics (DHGR) 140 x 192 screen images using my A2B converter in conjunction with ImageMagick and other modern graphics utilities. For the most part, the results speak for themselves. It seems pretty obvious to me that the NTSC DHGR display on the Apple IIe provides a mighty fine platform for properly converted graphics like those produced by my utilities.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The A2B Converter comes with the B2D Converter (Bmp2DHR). A2B was originally released in November 2012 as A2FCBmp (an MS-DOS companion utility for my earlier MS-DOS DHGR converter called BmpA2FC written in 2009). Today, between both utilities, graphic images for almost every Apple II video mode can be produced. The evolution of both A2B and B2D has been continuous and ongoing, experimental and cumulative. More good news is that all the DHGR conversion features that originally appeared in each utility are still there!
During the time that A2B started as a command line utility included in Bmp2DHR, it was first used as a one-way converter, for converting native Apple II Double Hi-Res (DHGR) files to Windows BMP files (not as a bi-directional converter like today). A2B’s DHGR monochrome BMP output is incorporated from the MS-DOS DMONO utility also released in 2012.
The documentation for both A2B and B2D lags far behind their capabilities. As I added more functionality, I put my efforts into developing these utilities and not writing about them consistently, which really did little harm since the Apple II Enthusiasts that are around today are generally not interested much in displaying today’s better graphics on yesterday’s computers. In some if not most cases, it is much worse than that.
But for the few who are interested, below are some of my articles on DHGR graphics and conversion…
The Apple II was not initially sold with a display, and instead Apple recommended that users plug into their NTSC television sets. When DHGR was introduced, Apple still did not offer a color display of its own. NTSC color television sets and 3rd party color composite monitors provided DHGR with the capability of sub-pixel rendering caused by composite artifacting, which was not possible with Apple’s introduction of their RGB displays for the Apple //e and Apple IIgs that followed. Even with an NTSC television or a composite display, the Apple IIgs took DHGR yet another step backward, by introducing an emulation of DHGR composite colors that were not the same as the original, and were instead based on the RGB display of the Apple IIgs. It is for these and related reasons that a “stock” Apple IIe with a composite display using an NTSC color televison or a composite color monitor provides the best platform for displaying converted DHGR output. Read-on!
Converting from a modern continuous tone image to DHGR’s fixed palette requires a severe compromise; not only must the modern image typically be scaled down in size, to a mere 140 x 192 resolution, but 16.7 million potential 24-bit colors must be reduced to only 15-colors for composite DHGR, or 16-colors for RGB DHGR. I noted above that there are different colors for DHGR on an Apple IIgs than are on an Apple //e. So you can appreciate that mapping the reduced colors to a palette intended for an Apple //e with an NTSC television set will result in entirely different colors if displayed on an Apple IIgs with an RGB monitor, and vice-versa.
The A2B Converter comes with the same built-in DHGR conversion palettes that the B2D converter uses. In my article titled Introduction to Pseudo-Palettes in Bmp2DHR, I cover the use of some of these palettes in detail. There is no getting around the fact that unlike NTSC DHGR colors, RGB DHGR colors do not balance well enough for good conversion.
Apple
//e Composite Display
|
Apple
IIgs RGB Display
|
The DHGR patterns above from Beagle Graphics that show
all DHGR colors are exactly the same native-mode DHGR image displayed on the
two major Apple II color DHGR displays. These are screen captures from
emulators but close enough to show the difference in the “original” composite
DHGR colors offered by the Apple //e and the emulated RGB DHGR colors offered
by the Apple IIgs. Keep in mind that the Apple IIgs DHGR colors were just
another emulator palette. As shown below, separate converted images produced
using NTSC and RGB DHGR conversion palettes respectively can be used for the
NTSC and RGB displays.
A2B and B2D NTSC Conversion Palette 5 – Used by Sheldon Simm’s tohgr for DHGR colors This palette is derived from Sheldon Simm’s work with AppleWin NTSC’s DHGR colors
|
A2B and B2D RGB Conversion Palette 12 – Used by Kegs32 and Super Convert for DHGR colors
|
A2B and B2D NTSC Conversion Palette 5
|
A2B and B2D RGB Conversion Palette 12
|
A2B and B2D NTSC Conversion Palette 5
|
A2B and B2D RGB Conversion Palette 12
|
The A2B (and B2D) converter like many modern graphics utilities uses a Euclidian Distance Algorithm to match colors in a 24-bit image with the nearest palette color. Due to DHGR’s restriction of only 15 or 16 colors and the fact that there can be 26,880 unique colors in a scaled 24-bit input image before conversion, the A2B converter must agree mathematically with the nearest color measurements used by the “Original” input image and not use some “home-made” mapping technique to assign colors to a palette color.
void setluma()
{
FILE *fp;
char buf[128];
double dred, dgreen, dblue;
int
status = -1;
/* optional text file
with 3-lines,
each
with a luma coefficient for red,green
and blue respectively */
/* over-rides hard-coded luma values
this
is for someone who really knows what they are doing */
fp
= fopen("luma.txt","r");
if (NULL != fp) {
for (;;) {
/* read
custom luma values */
if (NULL
== fgets(buf, 128, fp)) break;
nocr(buf);
dred = atof(buf);
if (NULL
== fgets(buf, 128, fp)) break;
nocr(buf);
dgreen = atof(buf);
if (NULL
== fgets(buf, 128, fp)) break;
nocr(buf);
dblue
= atof(buf);
status =
-2;
/*
generous range check */
if (dred > 0.999 || dred <
0.001) break;
if (dgreen > 0.999 || dgreen <
0.001) break;
if (dblue > 0.999 || dblue <
0.001) break;
/* set custom luma values */
dlumaRED = dred; lumaRED = (int)(dred * 1000);
dlumaGREEN = dgreen; lumaGREEN = (int)(dgreen * 1000);
dlumaBLUE = dblue; lumaBLUE = (int)(dblue * 1000);
status =
SUCCESS;
break;
}
fclose(fp);
if (status ==
-1) puts("luma.txt: read error!");
else if
(status == -2) puts("luma.txt: invalid coefficient!");
else
puts("luma.txt: external coefficients in effect!");
}
if (status ==
SUCCESS) return;
switch(lumaREQ)
{
/* HDMI II - Rec.
2020 specifies that if a luma (Y') signal is made
that it
uses
the R’G’B’ coefficients
0.2627 for red, 0.6780 for green, and 0.0593 for blue */
case 2020:
lumaRED = 263;
lumaGREEN = 678; lumaBLUE = 59;
dlumaRED = 0.2627;
dlumaGREEN = 0.6780; dlumaBLUE
= 0.0593;
break;
case 240: /* SMPTE 240M transitional coefficients */
/* http://www.chromapure.com/colorscience-decoding.asp
*/
lumaRED = 212;
lumaGREEN = 701; lumaBLUE = 87;
dlumaRED = 0.2124;
dlumaGREEN = 0.7011; dlumaBLUE
= 0.0866;
break;
case 911: /* Sheldon Simms - tohgr -
probably not useful */
lumaRED = 77;
lumaGREEN = 151; lumaBLUE = 28;
dlumaRED = 0.077;dlumaGREEN = 0.151; dlumaBLUE = 0.028;
break;
case 411: /* The GIMP color managed */
/* https://mail.gnome.org/archives/gimp-user-list/2013-November/msg00173.html
*/
/*
sRGB color managed */
/* http://ninedegreesbelow.com/photography/srgb-luminance.html
*/
lumaRED = 223;
lumaGREEN = 717; lumaBLUE = 61;
dlumaRED = 0.2225; dlumaGREEN
= 0.7169; dlumaBLUE
= 0.0606;
break;
case 709: /* CCIR 709 - modern */
/*
ImageMagick non-color managed */
/* also The
GIMP 2.8 - http://fossies.org/dox/gimp-2.8.14/gimprgb_8h_source.html
*/
/* also
PhotoShop
*/
lumaRED = 213;
lumaGREEN = 715; lumaBLUE = 72;
dlumaRED = 0.212656;dlumaGREEN = 0.715158; dlumaBLUE = 0.072186;
break;
case 601: /* CCIR 601 - most digital standard definition formats */
/* for
monitors having phosphors that were contemporary
at the introduction of NTSC television in 1953.
/* these
coefficients do not accurately compute luminance for contemporary monitors */
default: lumaRED = 299; lumaGREEN = 587; lumaBLUE = 114;
dlumaRED = 0.298839;
dlumaGREEN = 0.586811; dlumaBLUE =
0.114350;
break;
}
}
A2B’s conversion palettes must also agree mathematically with the color science used by the “Original” input image and with all transformations of that input image, including cropping and padding, and scaling and saving. In all of this, the standardization of Color Space is important.
Like many if not most modern graphics editors, the A2B converter understands and implements standard color spaces, using standard Luma coeffients and color gamuts to match colors to target displays.
For example if we were targeting an NTSC television for DHGR output using a properly phased signal from an Apple IIe, we would use a hard-coded 15-color 24-bit conversion palette based on Sheldon Simm’s work with the AppleWin NTSC emulator and the tohgr converter. We could use Rec. 601 Luma coefficients to re-map the modern color gamut even though the “Original” input image likely uses sRGB color space. Because there is some debate (in my mind and in the wild) whether Rec. 709 Luma coefficients are a better bet for mapping from a modern image, for the purposes of the conversions in this article I have stayed with Rec. 709.
But if we were targeting an Apple IIgs RGB display with a crt monitor for DHGR output, we would use a hard-coded 16-color 24-bit conversion palette based on Super Convert and also used by the Kegs32 emulator. We would use Rec. 709 Luma coefficients to map the modern color gamut “as-is”. But our results still wouldn’t be as good as on an Apple IIe with a television as a monitor, because the Apple IIgs RGB display’s DHGR colors are not phased perfectly like the Apple IIe’s NTSC DHGR colors, and the RGB display does not provide NTSC artifacting which creates the advantage of subpixel rendering. As far as plugging a television into the the Apple IIgs composite output; it still uses the RGB display’s DHGR colors so even though artifacting occurs it has lost the advantage of the properly phased colors of the Apple IIe composite output.
/* use CCIR 601 luminosity to get closest color in current palette
*/
/* based on palette that has been selected for conversion */
uchar GetClosestColor(uchar r, uchar g, uchar b)
{
uchar
drawcolor;
double dr, dg, db, diffR, diffG, diffB, luma,
lumadiff, distance, prevdistance;
int
i,j=brooksline;
globaldistance
= 0.0;
/* look for exact
match */
for (i=0;i<16;i++) {
if (brooksline == 999) {
if (r == rgbArray[i][0] && g == rgbArray[i][1] && b == rgbArray[i][2]) return (uchar)i;
}
else {
if (r == rgbArrays[j][i][0] && g
== rgbArrays[j][i][1]
&& b == rgbArrays[j][i][2])
return (uchar)i;
}
}
/* if no exact
match use nearest color */
dr = (double)r;
dg = (double)g;
db = (double)b;
luma
= (dr*lumaRED + dg*lumaGREEN + db*lumaBLUE) /
(255.0*1000);
lumadiff
= rgbLuma[0]-luma;
/* Compare the
difference of RGB values, weigh by CCIR 601 luminosity */
/* set palette index to
color with shortest distance */
/* get color
distance to first palette color */
diffR
= (rgbDouble[0][0]-dr)/255.0;
diffG
= (rgbDouble[0][1]-dg)/255.0;
diffB
= (rgbDouble[0][2]-db)/255.0;
prevdistance
= (diffR*diffR*dlumaRED + diffG*diffG*dlumaGREEN + diffB*diffB*dlumaGREEN)*0.75
+ lumadiff*lumadiff;
/* set palette
index to first color */
drawcolor
= 0;
/* get color
distance to rest of palette colors */
for (i=1;i<16;i++) {
/* get color
distance of this index */
lumadiff
= rgbLuma[i]-luma;
diffR
= (rgbDouble[i][0]-dr)/255.0;
diffG
= (rgbDouble[i][1]-dg)/255.0;
diffB
= (rgbDouble[i][2]-db)/255.0;
distance = (diffR*diffR*dlumaRED
+ diffG*diffG*dlumaGREEN + diffB*diffB*dlumaBLUE)*0.75
+ lumadiff*lumadiff;
/* if distance
is smaller use this index */
if (distance
< prevdistance) {
prevdistance = distance;
drawcolor = (uchar)i;
}
}
globaldistance
= prevdistance;
return drawcolor;
}
This is admittedly not as straight-forward as just running some old GIF converter and hoping for the best.
http://www.appleoldies.ca/cc65/programs/dhgr/bmp2dhr.zip
You have a royalty-free right to use, modify, reproduce and distribute the above zip file including source code in any way you find useful, provided that you agree that Bill Buckels has no warranty obligations or liability resulting from said distribution in any way whatsoever.
Bill Buckels
January 10, 2017