//--------------------------------------------------------------------------- // // 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); } } } }
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,®s,®s); } /* ** 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 } } }