예제 #1
0
//---------------------------------------------------------------------------
//
// QuantizeColor
//
// Returns the palette table index of an RGB color by traversing the
// octree to the leaf level
//
int QuantizeColor(OctreeType *tree, RGBType *color)
{
	if (tree->isleaf) {
		return tree->index;
	}
	else {
        QuantizeColor(tree->child[LEVEL(color,6-tree->level)],color);
	}
}
예제 #2
0
파일: Palette.cpp 프로젝트: evansf/SWPhase2
int CPalette::Palettize(cv::Mat& src, cv::Mat& dst)
{
	if((dst.rows != src.rows) || (dst.cols != src.cols) || (dst.type() != CV_8UC1) )
	{	// re-allocate destination
		dst.create(src.rows,src.cols,CV_8UC1);
	}
	int height, width;
	height = src.rows; width = src.cols;

	BGRType color;
	unsigned char *pSrc, *pDst;
	int i,j;
	for(i=0; i<height; i++)
	{
		pSrc = (unsigned char*)src.ptr(i);
		pDst = (unsigned char*)dst.ptr(i);
		for(j=0; j<width; j++)
		{
			color.b = pSrc[3*j]; color.g = pSrc[3*j+1]; color.r = pSrc[3*j+2];
			pDst[j] = QuantizeColor(color);
		}
	}
	return 0;	// OK
}
예제 #3
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
		}
	}
}
예제 #4
0
/****************************************************************************
**
** SaveAsPCX
**
** Write a PCX file version of the image
*/
int SaveAsPCX(FILE *f,
			  OctreeType *octree,
			  int resx,
			  int resy,
			  double nrgbr,
			  double nrgbg,
			  double nrgbb,
			  int npal,
			  RGBType *colortable)
{
    PCXhdr          hdr;
	FILE            *pf;
    unsigned char   *buf;
	PCXCOLOR        *pal;
    int             i,j,k;
	char            pcxfile[128];
    double          r, g, b;
	RGBType			color;

	printf("\nPCX file name : ");
	scanf("%s",pcxfile);

	if ((pf = fopen(pcxfile, "wb")) == NULL) {
        fprintf(stderr, "Can't open file %s for writing\n", pcxfile);
		return 1;
    }

    /*
	** Set up the PCX palette.
    */
	pal = (PCXCOLOR *)malloc(256*sizeof(PCXCOLOR));
	for (k = 0; k < npal ; k++) {
		pal[k].r = (unsigned char)(colortable[k].r);
		pal[k].g = (unsigned char)(colortable[k].g);
		pal[k].b = (unsigned char)(colortable[k].b);
	}
    /*
	** Fill in the PCX header
    */
	hdr.manuf = (char)10;
    hdr.vers = (char)5;
	hdr.rle = (char)1;
    hdr.bitpx = 8;
	hdr.x1 = hdr.y1 = 0;
	hdr.x2 = resx - 1;
	hdr.y2 = resy - 1;
	hdr.hres = 640;
	hdr.vres = 480;
	hdr.hscreen = 0;
	hdr.vscreen = 0;
    hdr.bpline = hdr.x2;
	hdr.vmode = (char)0;
    hdr.nplanes = 1;
	hdr.palinfo = 1;
    memset(hdr.xtra,0x00,54);

    fwrite(&hdr, sizeof(PCXhdr), 1, pf);

    /*
	** Scan the image and pack pixels for the PCX image
    */
	buf = (unsigned char *)malloc(resx * sizeof(unsigned char));

	for (i = 0; i < resy; i++) {
        fprintf(stderr, "%1.0f\%\r", 100.0*(float)i/(float)resy);
		/*
		** Build a scan line of color table indices
		*/
		for (j = 0; j < resx; j++) {
            if (fscanf(f,"%lf %lf %lf",&r,&g,&b) == EOF) {
				fprintf(stderr, "\n\nUnexpected end of input file (%d,%d)\n", i, j);
				exit(1);
			}
            color.r = (byte)(r * nrgbr);
            color.g = (byte)(g * nrgbg);
            color.b = (byte)(b * nrgbb);
			if (color.r > nrgbr) color.r = nrgbr;
			if (color.g > nrgbg) color.g = nrgbg;
            if (color.b > nrgbb) color.b = nrgbb;
			buf[j] = QuantizeColor(octree, &color);
		}
		/*
		** Encode this scan line and write it to the file.  If return is non-0
		** then the write failed
		*/
		if (encline(buf, hdr.x2, pf)) {
			fclose(pf);
			free(buf);
			free(pal);
			return 1;
		}
	}
	/*
	** Store the palette
	*/
	for (i = 0; i < 256; i++) {
        pal[i].r *= 4;
        pal[i].g *= 4;
        pal[i].b *= 4;
	}
	putc(0x0c, pf);
	fwrite(pal, 768, 1, pf);
	fclose(pf);
	free(buf);
	free(pal);
	return 0;
}