398 int width = pixGetWidth(pix);
399 int height = pixGetHeight(pix);
400 int left_pad =
MAX(rect.
left() - 2 * factor, 0) / factor;
401 int top_pad = (rect.
top() + 2 * factor + (factor - 1)) / factor;
402 top_pad =
MIN(height, top_pad);
403 int right_pad = (rect.
right() + 2 * factor + (factor - 1)) / factor;
404 right_pad =
MIN(width, right_pad);
405 int bottom_pad =
MAX(rect.
bottom() - 2 * factor, 0) / factor;
406 int width_pad = right_pad - left_pad;
407 int height_pad = top_pad - bottom_pad;
408 if (width_pad < 1 || height_pad < 1 || width_pad + height_pad < 4)
411 Box* scaled_box = boxCreate(left_pad, height - top_pad,
412 width_pad, height_pad);
413 Pix* scaled = pixClipRectangle(pix, scaled_box,
NULL);
416 STATS red_stats(0, 256);
417 STATS green_stats(0, 256);
418 STATS blue_stats(0, 256);
419 uinT32* data = pixGetData(scaled);
421 for (
int y = 0; y < height_pad; ++y) {
422 for (
int x = 0; x < width_pad; ++x, ++data) {
423 int r = GET_DATA_BYTE(data, COLOR_RED);
424 int g = GET_DATA_BYTE(data, COLOR_GREEN);
425 int b = GET_DATA_BYTE(data, COLOR_BLUE);
427 green_stats.add(g, 1);
428 blue_stats.add(b, 1);
435 int best_l8 =
static_cast<int>(red_stats.ile(0.125
f));
436 int best_u8 =
static_cast<int>(ceil(red_stats.ile(0.875f)));
437 int best_i8r = best_u8 - best_l8;
438 int x_color = COLOR_RED;
439 int y1_color = COLOR_GREEN;
440 int y2_color = COLOR_BLUE;
441 int l8 =
static_cast<int>(green_stats.ile(0.125
f));
442 int u8 =
static_cast<int>(ceil(green_stats.ile(0.875f)));
443 if (u8 - l8 > best_i8r) {
447 x_color = COLOR_GREEN;
448 y1_color = COLOR_RED;
450 l8 =
static_cast<int>(blue_stats.ile(0.125
f));
451 u8 =
static_cast<int>(ceil(blue_stats.ile(0.875f)));
452 if (u8 - l8 > best_i8r) {
456 x_color = COLOR_BLUE;
457 y1_color = COLOR_GREEN;
458 y2_color = COLOR_RED;
463 uinT32* data = pixGetData(scaled);
464 for (
int im_y = 0; im_y < height_pad; ++im_y) {
465 for (
int im_x = 0; im_x < width_pad; ++im_x, ++data) {
466 int x = GET_DATA_BYTE(data, x_color);
467 int y1 = GET_DATA_BYTE(data, y1_color);
468 int y2 = GET_DATA_BYTE(data, y2_color);
473 double m1 = line1.
m();
474 double c1 = line1.
c(m1);
475 double m2 = line2.
m();
476 double c2 = line2.
c(m2);
477 double rms = line1.
rms(m1, c1) + line2.
rms(m2, c2);
481 color1[y1_color] =
ClipToByte(m1 * best_l8 + c1 + 0.5);
482 color1[y2_color] =
ClipToByte(m2 * best_l8 + c2 + 0.5);
485 color2[y1_color] =
ClipToByte(m1 * best_u8 + c1 + 0.5);
486 color2[y2_color] =
ClipToByte(m2 * best_u8 + c2 + 0.5);
490 color1[COLOR_RED] =
ClipToByte(red_stats.median());
491 color1[COLOR_GREEN] =
ClipToByte(green_stats.median());
492 color1[COLOR_BLUE] =
ClipToByte(blue_stats.median());
493 color1[L_ALPHA_CHANNEL] = 0;
494 memcpy(color2, color1, 4);
496 if (color_map1 !=
NULL) {
497 pixSetInRectArbitrary(color_map1, scaled_box,
500 color1[COLOR_BLUE]));
501 pixSetInRectArbitrary(color_map2, scaled_box,
504 color2[COLOR_BLUE]));
505 pixSetInRectArbitrary(rms_map, scaled_box, color1[L_ALPHA_CHANNEL]);
508 boxDestroy(&scaled_box);
static uinT8 ClipToByte(double pixel)
double rms(double m, double c) const
const int kMinColorDifference
#define g(oldyc, yc, oldxc, xc)
const double kRMSFitScaling
static uinT32 ComposeRGB(uinT32 r, uinT32 g, uinT32 b)
void add(double x, double y)