Пример #1
0
//---------------------------------------------------------------------------
//
// MakePaletteTable
//
// Given a color octree, traverse the tree and do the following:
//	- Add the averaged RGB leaf color to the color palette table;
//	- Store the palette table index in the tree;
//
// When this recursive function finally returns, 'index' will contain
// the total number of colors in the palette table.
//
void MakePaletteTable(OctreeType *tree, RGBType table[], int *index)
{
	int	i;

	if (tree->isleaf) {
		table[*index].r = (byte)(tree->redsum / tree->npixels);
        table[*index].g = (byte)(tree->greensum / tree->npixels);
        table[*index].b = (byte)(tree->bluesum / tree->npixels);
		tree->index = *index;
		(*index)++;
	}
	else {
        for (i = 0; i < COLORBITS; i++) {
			if (tree->child[i]) {
				MakePaletteTable(tree->child[i], table, index);
			}
		}
	}
}
Пример #2
0
void main(int argc, char *argv[])
{
	double      r, g, b;
	uint        rows, cols;
	char        fname[256];
	double      colormag;
	time_t      tstart, tend;
    int         nrgbr = 63, nrgbg = 63, nrgbb = 63;
	OctreeType  *octree;
	RGBType		color;
	FILE		*f;
	char		title[40];
	char		description[128];
    ulong       i;
    uint        j;
	int			n;
	RGBType		palette[256];
	ulong		image_start;
	union REGS	regs;
	int			resx, resy;
	int			px, py;
	int			ii;
	int			cols2, rows2;
	int			k;
	int			cli;
    int         maxr=0, maxg=0, maxb=0;

#if defined METAWINDO
	rect        screen;
#endif

	printf("Image file : ");
	scanf("%s",fname);
	if ((f = fopen(fname,"rb")) == NULL) {
        printf("%s not found.\n",fname);
		exit(1);
	}

    /*
    ** Read the image file header
    */
	fgets(title,40,f);
	fgets(description,128,f);
	fscanf(f,"%d %d",&cols,&rows);
    fscanf(f,"%lf",&colormag);
	image_start = ftell(f);

	cols2 = cols/2;
	rows2 = rows/2;
	time(&tstart);

	/*
    ** Initialize the color octree
	*/
    octree = CreateOctNode(0);

	/*
    ** Loop through the image and store each unique color.
	*/
	for (i = 0L; i < (ulong)rows*(ulong)cols; i++) {
		/*
		** Show progress...
		*/
		if ((i % (ulong)cols) == 0L) printf("%ld\r",i/cols);

        fscanf(f,"%lf %lf %lf",&r,&g,&b);
		/*
		** Convert input floating point values to bytes.  NOTE: We assume that
		** all input values are between 0..1.0
		*/
        color.r = (unsigned char)(r  * nrgbr);
        color.g = (unsigned char)(g  * nrgbg);
        color.b = (unsigned char)(b  * nrgbb);
		if (color.r > nrgbr) color.r = nrgbr;
		if (color.g > nrgbg) color.g = nrgbg;
		if (color.b > nrgbb) color.b = nrgbb;

		/*
		** Insert this color into the octree
		*/
		InsertTree(&octree, &color, 0);

		/*
		** If there are too many colors in the tree as a result of this
		** insert, reduce the octree
		*/
		while (TotalLeafNodes() > npal) {
			ReduceTree();
		}
	}

	/*
	** Make a pass through the completed octree to average down the
	** rgb components.  When done, 'n' contains the actual number of
	** colors in the palette table.
	*/
	n = 0;
	MakePaletteTable(octree, palette, &n);

	/*
	** How long did it take?
	*/
	time(&tend);
	printf("Processed %ld pixels per second\ninto %d quantized colors\n",
		   ((long)rows*(long)cols)/(tend-tstart), n);

	j = 0;
	while (j != 3) {
		printf("Output to (1)monitor or (2).PCX file or (3) quit: ");
		scanf("%s",title);
		j = atoi(title);
		if (j == 2) {
			fseek(f,image_start,0);
            SaveAsPCX(f, octree, cols, rows, nrgbr, nrgbg, nrgbb, npal, palette);
		}
		else if (j == 1) {
#if defined METAWINDO
			/*
			** NOTE: This section requires MetaWINDOW graphics lib
			**
			** Let the user choose his graphics device and resolution
			*/
			MetQuery(argc,argv);
			if (InitGraphics(GrafixCard) != 0) {
				printf("\n---Error initializing graphics device---\n");
				exit(1);
			}
			SetDisplay(GrafPg0);
			BackColor(0);
			/*
			** Set the VGA palette
			*/
			for (j = 0; j < n; j++) {
				regs.h.al = 0x10;
				regs.h.ah = 0x10;
				regs.h.bl = j;
				regs.h.bh = 0;
				regs.h.ch = (int)(palette[j].g);
				regs.h.cl = (int)(palette[j].b);
				regs.h.dh = (int)(palette[j].r);
				int86(0x10,&regs,&regs);
			}

			/*
			** Center the image on the screen
			*/
			ScreenRect(&screen);
			resx = screen.Xmax;
			resy = screen.Ymax;
			px = resx/2 - npal;

			/*
			** Display a color bar at the top of the screen
			*/
			for (ii = 0; ii < npal; ii++){
				PenColor(ii);
				SetPixel(ii*2+px,1);
				SetPixel(ii*2+px+1,1);
				SetPixel(ii*2+px,2);
				SetPixel(ii*2+px+1,2);
				SetPixel(ii*2+px,3);
				SetPixel(ii*2+px+1,3);
				SetPixel(ii*2+px,4);
				SetPixel(ii*2+px+1,4);
			}

			fseek(f,image_start,0);

			py = resy/2 - rows2 - 1;
			for (ii = 0; ii < rows ; ii++) {
				px = resx/2 - cols2;
				for (k = 0; k < cols; k++) {
					if (fscanf(f,"%f %f %f",&r,&g,&b) == EOF) {
						goto pdone;
					}
					color.r = (byte)(nrgbr * r);
					color.g = (byte)(nrgbg * g);
					color.b = (byte)(nrgbb * b);
					cli = QuantizeColor(octree, &color);
					PenColor(cli);
					SetPixel(px,py);
					px++;
				}
				py++;
			}
pdone:      getch();
			SetDisplay(TextPg0);
			StopGraphics();
#endif
		}
	}
}