]>
iEval git - xfishtank.git/blob - medcut.c
9 #define FindHash(red, green, blue, h_ptr) \
10 h_ptr = Hash[((red * 299) + (green * 587) + (blue * 114)) / 1000 * NCells / 256]; \
11 while(h_ptr != NULL) \
13 if ((h_ptr->pixel[RED] == red)&& \
14 (h_ptr->pixel[GREEN] == green)&& \
15 (h_ptr->pixel[BLUE] == blue)) \
19 h_ptr = h_ptr->hash_next; \
25 struct color_rec
*hash_next
;
26 struct color_rec
*next
;
32 struct color_rec
*c_data
;
36 struct color_rec
*hash_ptr
;
37 struct color_rec
*tptr
;
38 static int Width
, Height
;
41 struct color_rec
*Tptr
;
48 C_boxes
[boxnum
].min_pix
[RED
] = 256;
49 C_boxes
[boxnum
].max_pix
[RED
] = 0;
50 C_boxes
[boxnum
].min_pix
[GREEN
] = 256;
51 C_boxes
[boxnum
].max_pix
[GREEN
] = 0;
52 C_boxes
[boxnum
].min_pix
[BLUE
] = 256;
53 C_boxes
[boxnum
].max_pix
[BLUE
] = 0;
58 AddHash(red
, green
, blue
)
63 lum
= ((red
* 299) + (green
* 587) + (blue
* 114)) / 1000 * NCells
/ 256;;
64 hash_ptr
= (struct color_rec
*) malloc(sizeof(struct color_rec
));
65 if (hash_ptr
== NULL
) {
66 fprintf(stderr
, "Cannot malloc %dth color\n", ColorCnt
);
69 hash_ptr
->pixel
[RED
] = red
;
70 hash_ptr
->pixel
[GREEN
] = green
;
71 hash_ptr
->pixel
[BLUE
] = blue
;
72 hash_ptr
->box_num
= 0;
73 hash_ptr
->next
= NULL
;
74 hash_ptr
->hash_next
= Hash
[lum
];
81 AddColor(cptr
, boxnum
)
82 struct color_rec
*cptr
;
85 struct color_rec
*ptr
;
87 while (cptr
!= NULL
) {
90 ptr
->box_num
= boxnum
;
91 ptr
->next
= C_boxes
[boxnum
].c_data
;
92 C_boxes
[boxnum
].c_data
= ptr
;
93 if (ptr
->pixel
[RED
] < C_boxes
[boxnum
].min_pix
[RED
])
94 C_boxes
[boxnum
].min_pix
[RED
] = ptr
->pixel
[RED
];
95 if (ptr
->pixel
[RED
] > C_boxes
[boxnum
].max_pix
[RED
])
96 C_boxes
[boxnum
].max_pix
[RED
] = ptr
->pixel
[RED
];
97 if (ptr
->pixel
[GREEN
] < C_boxes
[boxnum
].min_pix
[GREEN
])
98 C_boxes
[boxnum
].min_pix
[GREEN
] = ptr
->pixel
[GREEN
];
99 if (ptr
->pixel
[GREEN
] > C_boxes
[boxnum
].max_pix
[GREEN
])
100 C_boxes
[boxnum
].max_pix
[GREEN
] = ptr
->pixel
[GREEN
];
101 if (ptr
->pixel
[BLUE
] < C_boxes
[boxnum
].min_pix
[BLUE
])
102 C_boxes
[boxnum
].min_pix
[BLUE
] = ptr
->pixel
[BLUE
];
103 if (ptr
->pixel
[BLUE
] > C_boxes
[boxnum
].max_pix
[BLUE
])
104 C_boxes
[boxnum
].max_pix
[BLUE
] = ptr
->pixel
[BLUE
];
110 CountColors(data
, colrs
)
112 struct colr_data
*colrs
;
116 int red
, green
, blue
;
117 register struct color_rec
*tptr
;
120 C_boxes
[0].c_data
= NULL
;
121 tptr
= C_boxes
[0].c_data
;
126 for (j
= 0; j
< Height
; j
++) {
127 for (i
= 0; i
< Width
; i
++) {
128 red
= colrs
[(int) *dptr
].red
;
129 green
= colrs
[(int) *dptr
].green
;
130 blue
= colrs
[(int) *dptr
].blue
;
131 FindHash(red
, green
, blue
, tptr
);
133 tptr
= AddHash(red
, green
, blue
);
151 for (i
= 0; i
< BoxCount
; i
++) {
154 rr
= C_boxes
[i
].max_pix
[RED
] - C_boxes
[i
].min_pix
[RED
];
155 gr
= C_boxes
[i
].max_pix
[GREEN
] - C_boxes
[i
].min_pix
[GREEN
];
156 br
= C_boxes
[i
].max_pix
[BLUE
] - C_boxes
[i
].min_pix
[BLUE
];
178 SplitBox(boxnum
, color_indx
)
179 int boxnum
, color_indx
;
181 struct color_rec
*low
, *high
;
182 struct color_rec
*data
;
183 int med_cnt
, split_val
;
184 int low_cnt
, high_cnt
;
185 int Low_cnt
, High_cnt
;
188 Greater
= BoxCount
++;
192 data
= C_boxes
[boxnum
].c_data
;
193 med_cnt
= C_boxes
[boxnum
].count
/ 2;
194 C_boxes
[Lesser
].c_data
= NULL
;
195 C_boxes
[Greater
].c_data
= NULL
;
198 while (med_cnt
> 0) {
199 if (data
->pixel
[color_indx
] < data
->next
->pixel
[color_indx
]) {
212 split_val
= low
->pixel
[color_indx
];
213 while (data
!= NULL
) {
216 if (tptr
->pixel
[color_indx
] > split_val
) {
225 } /* end while data->next != NULL */
226 if (low_cnt
<= med_cnt
) {
227 AddColor(low
, Lesser
);
231 AddColor(high
, Greater
);
232 High_cnt
+= high_cnt
;
236 AddColor(high
, Greater
);
237 High_cnt
+= high_cnt
;
240 } /* end while med_cnt */
241 C_boxes
[Lesser
].count
= Low_cnt
;
242 C_boxes
[Greater
].count
= High_cnt
;
251 if (ColorCnt
< e_cnt
) {
254 tptr
= C_boxes
[0].c_data
;
255 for (i
= 0; i
< ColorCnt
; i
++) {
258 C_boxes
[i
].c_data
= hash_ptr
;
259 C_boxes
[i
].count
= 1;
260 hash_ptr
->box_num
= i
;
261 hash_ptr
->next
= NULL
;
266 while (BoxCount
< e_cnt
) {
267 int target
, color_indx
;
271 color_indx
= FindTarget(&target
);
272 SplitBox(target
, color_indx
);
279 * Colors passed in 0-65535, internally are 0-255
282 ConvertColor(rp
, gp
, bp
)
285 struct color_rec
*cptr
;
286 register struct color_rec
*hash_ptr
;
288 int red
, green
, blue
;
289 int Tred
, Tgreen
, Tblue
;
293 green
= *gp
/ NCells
;
295 FindHash(red
, green
, blue
, hash_ptr
);
296 if (hash_ptr
== NULL
) {
297 fprintf(stderr
, "Unknown color (%d,%d,%d)\n", red
, green
, blue
);
300 indx
= hash_ptr
->box_num
;
301 cptr
= C_boxes
[indx
].c_data
;
303 Tred
= Tgreen
= Tblue
= 0;
304 while (cptr
!= NULL
) {
305 Tred
+= cptr
->pixel
[RED
];
306 Tgreen
+= cptr
->pixel
[GREEN
];
307 Tblue
+= cptr
->pixel
[BLUE
];
313 green
= Tgreen
/ c_cnt
;
314 blue
= Tblue
/ c_cnt
;
318 *gp
= green
* NCells
;
324 ConvertData(data
, colrs
)
326 struct colr_data
*colrs
;
330 int red
, green
, blue
;
331 register struct color_rec
*hash_ptr
;
335 for (j
= 0; j
< Height
; j
++) {
336 for (i
= 0; i
< Width
; i
++) {
337 red
= colrs
[(int) *dptr
].red
;
338 green
= colrs
[(int) *dptr
].green
;
339 blue
= colrs
[(int) *dptr
].blue
;
340 FindHash(red
, green
, blue
, hash_ptr
);
341 if (hash_ptr
== NULL
) {
342 fprintf(stderr
, "Unknown color (%d,%d,%d)\n", red
, green
, blue
);
345 *dptr
++ = (unsigned char) hash_ptr
->box_num
;
352 PrintColormap(e_cnt
, colrs
)
354 struct colr_data
*colrs
;
358 for (i
= 0; i
< BoxCount
; i
++) {
359 int Tred
, Tgreen
, Tblue
;
363 Tred
= Tgreen
= Tblue
= 0;
364 tptr
= C_boxes
[i
].c_data
;
365 while (tptr
!= NULL
) {
366 Tred
+= tptr
->pixel
[RED
];
367 Tgreen
+= tptr
->pixel
[GREEN
];
368 Tblue
+= tptr
->pixel
[BLUE
];
372 colrs
[i
].red
= Tred
/ c_cnt
;
373 colrs
[i
].green
= Tgreen
/ c_cnt
;
374 colrs
[i
].blue
= Tblue
/ c_cnt
;
376 for (i
= BoxCount
; i
< e_cnt
; i
++) {
385 MedianCut(data
, w
, h
, colrs
, start_cnt
, end_cnt
)
388 struct colr_data
*colrs
;
389 int start_cnt
, end_cnt
;
398 for (i
= 0; i
< 256; i
++) {
400 C_boxes
[i
].c_data
= NULL
;
401 C_boxes
[i
].count
= 0;
403 CountColors(data
, colrs
);
404 C_boxes
[0].count
= ColorCnt
;
405 SplitColors(end_cnt
);
406 ConvertData(data
, colrs
);
407 PrintColormap(end_cnt
, colrs
);
408 for (i
= 0; i
< 256; i
++) {
410 while (hash_ptr
!= NULL
) {
412 hash_ptr
= hash_ptr
->hash_next
;
427 for (i
= 0; i
< 256; i
++) {
429 C_boxes
[i
].c_data
= NULL
;
430 C_boxes
[i
].count
= 0;
433 C_boxes
[0].c_data
= NULL
;
434 Tptr
= C_boxes
[0].c_data
;
439 * colrs are passed on 0-65535, but this median cut only deals with
443 MedianCount(data
, w
, h
, colrs
)
446 struct colr_data
*colrs
;
450 int red
, green
, blue
;
456 for (j
= 0; j
< Height
; j
++) {
457 for (i
= 0; i
< Width
; i
++) {
458 red
= colrs
[(int) *dptr
].red
/ NCells
;
459 green
= colrs
[(int) *dptr
].green
/ NCells
;
460 blue
= colrs
[(int) *dptr
].blue
/ NCells
;
461 FindHash(red
, green
, blue
, tptr
);
463 tptr
= AddHash(red
, green
, blue
);
478 C_boxes
[0].count
= ColorCnt
;
479 SplitColors(end_cnt
);
484 MedianConvert(data
, w
, h
, colrs
)
487 struct colr_data
*colrs
;
491 ConvertData(data
, colrs
);
496 MedianMerge(colrs
, end_cnt
)
497 struct colr_data
*colrs
;
502 PrintColormap(end_cnt
, colrs
);
503 for (i
= 0; i
< 256; i
++) {
505 while (hash_ptr
!= NULL
) {
507 hash_ptr
= hash_ptr
->hash_next
;
This page took 0.083808 seconds and 4 git commands to generate.