mirror of
https://github.com/aaronsgiles/JPEGView.git
synced 2024-06-01 03:41:27 +00:00
92bdb55672
These are the sources for the final official release of JPEGView for the Mac, back in 1994.
1 line
3.2 KiB
C
1 line
3.2 KiB
C
/*********************************************************/
|
|
/* This source code copyright (c) 1991-2001, Aaron Giles */
|
|
/* See the Read Me file for licensing information. */
|
|
/* Contact email: mac@aarongiles.com */
|
|
/*********************************************************/
|
|
|
|
// void DitherCopyTo8Odd(ulong *srcRow, void *dstRowStart, uchar *iTable, ColorSpec *cTable,
|
|
// DitherErrorsPtr eBuffer, DitherErrorsPtr oBuffer,
|
|
// short *rgnBuffer, uchar *errorMap, short columns)
|
|
|
|
// internals:
|
|
ulong *src = srcRow; // pointer to the 32-bit source row
|
|
uchar *dst = (uchar *)dstRowStart;
|
|
ulong pixel; // scratch for the current pixel
|
|
long red; // red scratch area
|
|
long green; // green scratch area
|
|
long blue; // blue scratch area
|
|
long red2; // 2 * the red error; used for fast calculations
|
|
long green2; // 2 * the green error
|
|
long blue2; // 2 * the blue error
|
|
long rgnCol; // region column counter
|
|
|
|
// Skip to the ends of everything here
|
|
dst += columns;
|
|
src += columns;
|
|
eBuffer += columns;
|
|
oBuffer += columns;
|
|
|
|
// initialize our counters and clear out next row
|
|
red = green = blue = 0;
|
|
eBuffer[-1].red = eBuffer[-1].green = eBuffer[-1].blue = 0;
|
|
|
|
// set up the region column counter
|
|
while (*rgnBuffer++ < columns);
|
|
--rgnBuffer;
|
|
if (*rgnBuffer == columns) rgnCol = *--rgnBuffer - columns;
|
|
else rgnCol = columns - *--rgnBuffer;
|
|
|
|
// begin main loop here
|
|
while (columns--) {
|
|
|
|
// combine the accumulated errors and round to a pixel value
|
|
--oBuffer;
|
|
red += oBuffer->red + 8;
|
|
red >>= 4;
|
|
red = errorMap[red];
|
|
green += oBuffer->green + 8;
|
|
green >>= 4;
|
|
green = errorMap[green];
|
|
blue += oBuffer->blue + 8;
|
|
blue >>= 4;
|
|
blue = errorMap[blue];
|
|
|
|
// offset the current pixel by the errors
|
|
pixel = *--src;
|
|
blue += pixel & 0xff;
|
|
pixel >>= 8;
|
|
green += pixel & 0xff;
|
|
pixel >>= 8;
|
|
red += pixel & 0xff;
|
|
|
|
// check for overflows and handle them
|
|
if (red > 255) red = 255;
|
|
else if (red < 0) red = 0;
|
|
if (blue > 255) blue = 255;
|
|
else if (blue < 0) blue = 0;
|
|
if (green > 255) green = 255;
|
|
else if (green < 0) green = 0;
|
|
|
|
// get the inverse color table entry
|
|
pixel = red >> 3;
|
|
pixel <<= 5;
|
|
pixel += green >> 3;
|
|
pixel <<= 5;
|
|
pixel += blue >> 3;
|
|
pixel = iTable[pixel];
|
|
|
|
// determine whether or not to draw this pixel, and handle switches
|
|
if (rgnCol > 0) {
|
|
--dst;
|
|
if (!--rgnCol) rgnCol = rgnBuffer[-1] - rgnBuffer[0], rgnBuffer--;
|
|
} else {
|
|
*--dst = pixel;
|
|
if (!++rgnCol) rgnCol = rgnBuffer[0] - rgnBuffer[-1], rgnBuffer--;
|
|
}
|
|
|
|
// calculate the new errors
|
|
red -= cTable[pixel].rgb.red >> 8;
|
|
green -= cTable[pixel].rgb.green >> 8;
|
|
blue -= cTable[pixel].rgb.blue >> 8;
|
|
|
|
// calculate 2 * the new error for fast ops ahead
|
|
red2 = red << 1;
|
|
green2 = green << 1;
|
|
blue2 = blue << 1;
|
|
|
|
// store 1/16, 3/16, and 5/16 into next row; leave 7/16 for neighbor
|
|
--eBuffer;
|
|
eBuffer[-1].red = red;
|
|
eBuffer[-1].green = green;
|
|
eBuffer[-1].blue = blue;
|
|
eBuffer[1].red += (red += red2);
|
|
eBuffer[1].green += (green += green2);
|
|
eBuffer[1].blue += (blue += blue2);
|
|
eBuffer->red += (red += red2);
|
|
eBuffer->green += (green += green2);
|
|
eBuffer->blue += (blue += blue2);
|
|
red += red2;
|
|
green += green2;
|
|
blue += blue2;
|
|
}
|