#include <stdlib.h>
#include <string.h>
+#if defined(__VISAGECPP__)
+#define RGB_RED_OS2 0
+#define RGB_GREEN_OS2 1
+#define RGB_BLUE_OS2 2
+#else
#define RGB_RED 0
#define RGB_GREEN 1
#define RGB_BLUE 2
+#endif
#define RGB_PIXELSIZE 3
#define MAXJSAMPLE 255
* color space, and repeatedly splits the "largest" remaining box until we
* have as many boxes as desired colors. Then the mean color in each
* remaining box becomes one of the possible output colors.
- *
+ *
* The second pass over the image maps each input pixel to the closest output
* color (optionally after applying a Floyd-Steinberg dithering correction).
* This mapping is logically trivial, but making it go fast enough requires
* you'll probably want to tweak the histogram sizes too.
*/
+#if defined(__VISAGECPP__)
+
+#if RGB_RED_OS2 == 0
+#define C0_SCALE R_SCALE
+#endif
+#if RGB_BLUE_OS2 == 0
+#define C0_SCALE B_SCALE
+#endif
+#if RGB_GREEN_OS2 == 1
+#define C1_SCALE G_SCALE
+#endif
+#if RGB_RED_OS2 == 2
+#define C2_SCALE R_SCALE
+#endif
+#if RGB_BLUE_OS2 == 2
+#define C2_SCALE B_SCALE
+#endif
+
+#else
+
#if RGB_RED == 0
#define C0_SCALE R_SCALE
#endif
#define C2_SCALE B_SCALE
#endif
+#endif
/*
* First we have the histogram data structure and routines for creating it.
for (row = 0; row < num_rows; row++) {
ptr = input_buf[row];
for (col = width; col > 0; col--) {
-
+
{
-
+
/* get pixel value and index into the histogram */
histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
[GETJSAMPLE(ptr[1]) >> C1_SHIFT]
register int i;
register long maxc = 0;
boxptr which = NULL;
-
+
for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
if (boxp->colorcount > maxc && boxp->volume > 0) {
which = boxp;
register int i;
register INT32 maxv = 0;
boxptr which = NULL;
-
+
for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
if (boxp->volume > maxv) {
which = boxp;
int c0min,c0max,c1min,c1max,c2min,c2max;
INT32 dist0,dist1,dist2;
long ccount;
-
+
c0min = boxp->c0min; c0max = boxp->c0max;
c1min = boxp->c1min; c1max = boxp->c1max;
c2min = boxp->c2min; c2max = boxp->c2max;
-
+
if (c0max > c0min)
for (c0 = c0min; c0 <= c0max; c0++)
for (c1 = c1min; c1 <= c1max; c1++) {
dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
-
+
/* Now scan remaining volume of box and compute population */
ccount = 0;
for (c0 = c0min; c0 <= c0max; c0++)
/* We want to break any ties in favor of green, then red, blue last.
* This code does the right thing for R,G,B or B,G,R color orders only.
*/
+#if defined(__VISAGECPP__)
+
+#if RGB_RED_OS2 == 0
+ cmax = c1; n = 1;
+ if (c0 > cmax) { cmax = c0; n = 0; }
+ if (c2 > cmax) { n = 2; }
+#else
+ cmax = c1; n = 1;
+ if (c2 > cmax) { cmax = c2; n = 2; }
+ if (c0 > cmax) { n = 0; }
+#endif
+
+#else
+
#if RGB_RED == 0
cmax = c1; n = 1;
if (c0 > cmax) { cmax = c0; n = 0; }
cmax = c1; n = 1;
if (c2 > cmax) { cmax = c2; n = 2; }
if (c0 > cmax) { n = 0; }
+#endif
+
#endif
/* Choose split point along selected axis, and update box bounds.
* Current algorithm: split at halfway point.
long c0total = 0;
long c1total = 0;
long c2total = 0;
-
+
c0min = boxp->c0min; c0max = boxp->c0max;
c1min = boxp->c1min; c1max = boxp->c1max;
c2min = boxp->c2min; c2max = boxp->c2max;
-
+
for (c0 = c0min; c0 <= c0max; c0++)
for (c1 = c1min; c1 <= c1max; c1++) {
histp = & histogram[c0][c1][c2min];
}
}
}
-
+
cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
for (i = 0; i < numboxes; i++)
compute_color(cinfo, & boxlist[i], i);
cinfo->actual_number_of_colors = numboxes;
-
+
free(boxlist); //FIXME?? I don't know if this is correct - VS
}
bptr = bestdist;
for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
*bptr++ = 0x7FFFFFFFL;
-
+
/* For each color selected by find_nearby_colors,
* compute its distance to the center of each cell in the box.
* If that's less than best-so-far, update best distance and color number.
*/
-
+
/* Nominal steps between cell centers ("x" in Thomas article) */
#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE)
#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE)
#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
-
+
for (i = 0; i < numcolors; i++) {
icolor = GETJSAMPLE(colorlist[i]);
/* Compute (square of) distance from minc0/c1/c2 to this color */
minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
-
+
/* Determine which colormap entries are close enough to be candidates
* for the nearest entry to some cell in the update box.
*/
JSAMPROW colormap0 = cinfo->colormap[0];
JSAMPROW colormap1 = cinfo->colormap[1];
JSAMPROW colormap2 = cinfo->colormap[2];
-
+
for (row = 0; row < num_rows; row++) {
inptr = input_buf[row];
cquantize->sv_colormap[0] = (JSAMPROW) malloc(sizeof(JSAMPLE) * desired);
cquantize->sv_colormap[1] = (JSAMPROW) malloc(sizeof(JSAMPLE) * desired);
cquantize->sv_colormap[2] = (JSAMPROW) malloc(sizeof(JSAMPLE) * desired);
-
+
cquantize->desired = desired;
- }
+ }
/* Allocate Floyd-Steinberg workspace if necessary.
* This isn't really needed until pass 2, but again it is storage.
bool wxQuantize::Quantize(const wxImage& src, wxImage& dest, wxPalette** pPalette, int desiredNoColours,
unsigned char** eightBitData, int flags)
-{
+{
int i;
int w = src.GetWidth();
int h = src.GetHeight();
unsigned char **outrows = new unsigned char *[h];
for (i = 0; i < h; i++)
outrows[i] = data8bit + w * i;
-
+
//RGB->palette
DoQuantize(w, h, rows, outrows, palette, desiredNoColours);
-
+
delete[] rows;
- delete[] outrows;
-
+ delete[] outrows;
+
// palette->RGB(max.256)
if (flags & wxQUANTIZE_FILL_DESTINATION_IMAGE)
delete[] g;
delete[] b;
}
-
+
return TRUE;
}