37 const unsigned char *RgbImage,
long NumPixels);
70 int Rgb2Ind(
unsigned char *Dest,
unsigned char *Palette,
int NumColors,
71 const unsigned char *RgbImage,
long NumPixels)
73 float Merit, MaxMerit;
74 const long NumEl = 3*NumPixels;
75 long i, Dist, MinDist, Diff;
76 int k, BestBox = 0, Channel, NumBoxes = 1;
79 if(!Dest || !Palette || NumColors > 256 || !RgbImage || NumPixels <= 0)
83 Box[0].
Min[0] = Box[0].
Min[1] = Box[0].
Min[2] = 255;
84 Box[0].
Max[0] = Box[0].
Max[1] = Box[0].
Max[2] = 0;
86 for(i = 0; i < NumEl; i += 3)
87 for(Channel = 0; Channel < 3; Channel++)
89 if(Box[0].Min[Channel] > RgbImage[i + Channel])
90 Box[0].
Min[Channel] = RgbImage[i + Channel];
91 if(Box[0].Max[Channel] < RgbImage[i + Channel])
92 Box[0].
Max[Channel] = RgbImage[i + Channel];
98 while(NumBoxes < NumColors)
105 for(k = 0; k < NumBoxes; k++)
107 && (Merit = (
float)Box[k].NumPixels) > MaxMerit)
114 for(k = 0; k < NumBoxes; k++)
116 && (Merit = ((
float)Box[k].NumPixels)
117 * ((
float)Box[k].Volume)) > MaxMerit)
124 MedianSplit(&Box[NumBoxes], &Box[BestBox], RgbImage, NumPixels);
128 for(k = 0; k < NumBoxes; k++)
135 for(i = 0; i < NumEl; i += 3)
137 for(k = 0; k < NumBoxes; k++)
138 if(Box[k].Min[0] <= RgbImage[i + 0]
139 && RgbImage[i + 0] <= Box[k].Max[0]
140 && Box[k].Min[1] <= RgbImage[i + 1]
141 && RgbImage[i + 1] <= Box[k].Max[1]
142 && Box[k].Min[2] <= RgbImage[i + 2]
143 && RgbImage[i + 2] <= Box[k].Max[2])
148 fprintf(stderr,
"Color (%d,%d,%d) unassigned\n",
149 RgbImage[i + 0], RgbImage[i + 1], RgbImage[i + 2]);
155 Box[k].
Average[0] += RgbImage[i + 0];
156 Box[k].
Average[1] += RgbImage[i + 1];
157 Box[k].
Average[2] += RgbImage[i + 2];
164 for(k = 0; k < NumBoxes; k++)
165 if(Box[k].NumPixels > 0)
166 for(Channel = 0; Channel < 3; Channel++)
170 if(Box[k].Average[Channel] < 0.5)
171 Palette[3*k + Channel] = 0;
172 else if(Box[k].Average[Channel] >= 254.5)
173 Palette[3*k + Channel] = 255;
175 Palette[3*k + Channel] =
176 (
unsigned char)(Box[k].Average[Channel] + 0.5);
179 for(Channel = 0; Channel < 3; Channel++)
180 Palette[3*k + Channel] = 0;
183 for(i = 0; i < NumEl; i += 3)
186 for(k = 0, MinDist = 1000000; k < NumBoxes; k++)
188 Diff = ((long)RgbImage[i + 0]) - Palette[3*k + 0];
190 Diff = ((long)RgbImage[i + 1]) - Palette[3*k + 1];
192 Diff = ((long)RgbImage[i + 2]) - Palette[3*k + 2];
213 return (Box.
Max[0] - Box.
Min[0] + 1)
214 * (Box.
Max[1] - Box.
Min[1] + 1)
215 * (Box.
Max[2] - Box.
Min[2] + 1);
221 const unsigned char *RgbImage,
long NumPixels)
223 bbox Box = *SplitBox;
224 const long NumEl = 3*NumPixels;
225 long i, Accum, Hist[256];
226 int Length, MaxLength, MaxDim;
229 MaxLength = MaxDim = 0;
231 for(i = 0; i < 3; i++)
232 if((Length = Box.
Max[i] - Box.
Min[i] + 1) > MaxLength)
239 memset(Hist, 0,
sizeof(
long)*256);
241 for(i = 0; i < NumEl; i += 3)
242 if(Box.
Min[0] <= RgbImage[i + 0] && RgbImage[i + 0] <= Box.
Max[0]
243 && Box.
Min[1] <= RgbImage[i + 1] && RgbImage[i + 1] <= Box.
Max[1]
244 && Box.
Min[2] <= RgbImage[i + 2] && RgbImage[i + 2] <= Box.
Max[2])
245 Hist[RgbImage[i + MaxDim]]++;
247 Accum = Hist[i = Box.
Min[MaxDim]];
250 while(2*Accum < Box.
NumPixels && i < 254)
254 if(i > Box.
Min[MaxDim]
255 && ((i - Box.
Min[MaxDim]) < (Box.
Max[MaxDim] - i - 1)))
259 for(; i >= Box.
Max[MaxDim]; i--)
264 NewBox->
Max[MaxDim] = i;
268 SplitBox->
Min[MaxDim] = i + 1;