26 #ifdef USE_STD_NAMESPACE
33 #define M_PI 3.14159265358979323846
40 (kMaxDeslantAngle - kMinDeslantAngle) / kDeslantAngleDelta));
41 float *Bmp8::tan_table_ =
NULL;
54 void Bmp8::FreeBmpBuffer(
unsigned char **buff) {
56 if (buff[0] !=
NULL) {
63 void Bmp8::FreeBmpBuffer(
unsigned int **buff) {
65 if (buff[0] !=
NULL) {
73 unsigned char **Bmp8::CreateBmpBuffer(
unsigned char init_val) {
81 stride_ = ((
wid_ % 4) == 0) ?
wid_ : (4 * (1 + (
wid_ / 4)));
83 buff = (
unsigned char **)
new unsigned char *[
hgt_ *
sizeof(*buff)];
90 buff[0] = (
unsigned char *)
91 new unsigned char[stride_ *
hgt_ *
sizeof(*buff[0])];
96 memset(buff[0], init_val, stride_ *
hgt_ *
sizeof(*buff[0]));
98 for (
int y = 1; y <
hgt_; y++) {
99 buff[y] = buff[y -1] + stride_;
106 unsigned int ** Bmp8::CreateBmpBuffer(
int wid,
int hgt,
107 unsigned char init_val) {
111 buff = (
unsigned int **)
new unsigned int *[hgt *
sizeof(*buff)];
118 buff[0] = (
unsigned int *)
new unsigned int[wid * hgt *
sizeof(*buff[0])];
123 memset(buff[0], init_val, wid * hgt *
sizeof(*buff[0]));
125 for (
int y = 1; y < hgt; y++) {
126 buff[y] = buff[y -1] + wid;
154 if (fp->
Read(&val32,
sizeof(val32)) !=
sizeof(val32)) {
158 if (val32 != kMagicNumber) {
163 if (fp->
Read(&wid,
sizeof(wid)) !=
sizeof(wid)) {
167 if (fp->
Read(&hgt,
sizeof(hgt)) !=
sizeof(hgt)) {
172 if (fp->
Read(&buf_size,
sizeof(buf_size)) !=
sizeof(buf_size)) {
178 if (buf_size != (3 * pix_cnt)) {
183 buff =
new unsigned char[buf_size];
188 if (fp->
Read(buff, buf_size) != buf_size) {
204 for (y = 0, pix = 0; y <
hgt_; y++) {
205 for (x = 0; x <
wid_; x++, pix += 3) {
208 if (buff[pix] != buff[pix + 1] || buff[pix] != buff[pix + 2]) {
225 if (bmp_obj ==
NULL) {
248 if (fread(&val32, 1,
sizeof(val32), fp) !=
sizeof(val32)) {
252 if (val32 != kMagicNumber) {
257 if (fread(&wid, 1,
sizeof(wid), fp) !=
sizeof(wid)) {
261 if (fread(&hgt, 1,
sizeof(hgt), fp) !=
sizeof(hgt)) {
266 if (fread(&buf_size, 1,
sizeof(buf_size), fp) !=
sizeof(buf_size)) {
272 if (buf_size != (3 * pix_cnt)) {
277 buff =
new unsigned char[buf_size];
282 if (fread(buff, 1, buf_size, fp) != buf_size) {
298 for (y = 0, pix = 0; y <
hgt_; y++) {
299 for (x = 0; x <
wid_; x++, pix += 3) {
302 if ( buff[pix] != buff[pix + 1] ||
303 buff[pix] != buff[pix + 2]
322 if (bmp_obj ==
NULL) {
334 for (
int y = 0; y <
hgt_; y++) {
344 for (
int x = 0; x <
wid_; x++) {
361 while ((*xst) < (
wid_ - 1) && (*xst) <= xend) {
369 while (xend > 0 && xend >= (*xst)) {
377 while ((*yst) < (
hgt_ - 1) && (*yst) <= yend) {
385 while (yend > 0 && yend >= (*yst)) {
393 (*wid) = xend - (*xst) + 1;
394 (*hgt) = yend - (*yst) + 1;
412 int xend_src = bmp->
wid_ - 1;
413 int yend_src = bmp->
hgt_ - 1;
418 wid_src = xend_src - xst_src + 1,
419 hgt_src = yend_src - yst_src + 1;
423 if ((
wid_ * hgt_src) > (
hgt_ * wid_src)) {
424 x_num = y_num =
hgt_;
425 x_denom = y_denom = hgt_src;
427 x_num = y_num =
wid_;
428 x_denom = y_denom = wid_src;
438 xoff = (
wid_ - ((x_num * wid_src) / x_denom)) / 2;
439 yoff = (
hgt_ - ((y_num * hgt_src) / y_denom)) / 2;
442 if (y_num > y_denom) {
443 for (ydest = yoff; ydest < (
hgt_ - yoff); ydest++) {
445 ysrc =
static_cast<int>(0.5 + (1.0 * (ydest - yoff) *
447 if (ysrc < 0 || ysrc >= hgt_src) {
451 for (xdest = xoff; xdest < (
wid_ - xoff); xdest++) {
453 xsrc =
static_cast<int>(0.5 + (1.0 * (xdest - xoff) *
455 if (xsrc < 0 || xsrc >= wid_src) {
460 bmp->
line_buff_[ysrc + yst_src][xsrc + xst_src];
467 unsigned int **dest_line_buff = CreateBmpBuffer(
wid_,
hgt_, 0),
468 **dest_pix_cnt = CreateBmpBuffer(
wid_,
hgt_, 0);
470 for (ysrc = 0; ysrc < hgt_src; ysrc++) {
472 ydest = yoff +
static_cast<int>(0.5 + (1.0 * ysrc * y_num / y_denom));
473 if (ydest < 0 || ydest >=
hgt_) {
477 for (xsrc = 0; xsrc < wid_src; xsrc++) {
479 xdest = xoff +
static_cast<int>(0.5 + (1.0 * xsrc * x_num / x_denom));
480 if (xdest < 0 || xdest >=
wid_) {
484 dest_line_buff[ydest][xdest] +=
485 bmp->
line_buff_[ysrc + yst_src][xsrc + xst_src];
486 dest_pix_cnt[ydest][xdest]++;
490 for (ydest = 0; ydest <
hgt_; ydest++) {
491 for (xdest = 0; xdest <
wid_; xdest++) {
492 if (dest_pix_cnt[ydest][xdest] > 0) {
493 unsigned int pixval =
494 dest_line_buff[ydest][xdest] / dest_pix_cnt[ydest][xdest];
497 (
unsigned char) min((
unsigned int)255, pixval);
503 FreeBmpBuffer(dest_line_buff);
504 FreeBmpBuffer(dest_pix_cnt);
511 unsigned char *pline_data = data;
514 for (
int y = 0; y <
hgt_; y++, pline_data +=
wid_) {
533 val32 = kMagicNumber;
534 if (fwrite(&val32, 1,
sizeof(val32), fp) !=
sizeof(val32)) {
540 if (fwrite(&wid, 1,
sizeof(wid), fp) !=
sizeof(wid)) {
545 if (fwrite(&hgt, 1,
sizeof(hgt), fp) !=
sizeof(hgt)) {
551 buf_size = 3 * pix_cnt;
552 if (fwrite(&buf_size, 1,
sizeof(buf_size), fp) !=
sizeof(buf_size)) {
557 buff =
new unsigned char[buf_size];
563 for (y = 0, pix = 0; y <
hgt_; y++) {
564 for (x = 0; x <
wid_; x++, pix += 3) {
571 if (fwrite(buff, 1, buf_size, fp) != buf_size) {
585 int x_end = min(x_st + wid, static_cast<int>(
wid_)),
586 y_end = min(y_st + hgt, static_cast<int>(
hgt_));
588 for (
int y = y_st; y < y_end; y++) {
589 for (
int x = x_st; x < x_end; x++) {
601 for (
int y = 0; y <
hgt_; y++) {
614 unsigned int **out_bmp_array = CreateBmpBuffer(
wid_,
hgt_, 0);
615 if (out_bmp_array ==
NULL) {
616 fprintf(stderr,
"Cube ERROR (Bmp8::FindConComps): could not allocate "
629 int alloc_concomp_cnt = 0;
632 const int nbr_cnt = 4;
635 int x_del[nbr_cnt] = {-1, 0, 1, -1},
636 y_del[nbr_cnt] = {-1, -1, -1, 0};
639 for (y = 0; y <
hgt_; y++) {
640 for (x = 0; x <
wid_; x++) {
643 int master_concomp_id = 0;
647 for (
int nbr = 0; nbr < nbr_cnt; nbr++) {
648 x_nbr = x + x_del[nbr];
649 y_nbr = y + y_del[nbr];
651 if (x_nbr < 0 || y_nbr < 0 || x_nbr >= wid_ || y_nbr >= hgt_) {
658 concomp_id = out_bmp_array[y_nbr][x_nbr];
661 if (concomp_id < 1 || concomp_id > alloc_concomp_cnt) {
662 fprintf(stderr,
"Cube ERROR (Bmp8::FindConComps): illegal "
663 "connected component id: %d\n", concomp_id);
664 FreeBmpBuffer(out_bmp_array);
665 delete []concomp_array;
671 if (master_concomp !=
NULL && concomp_id != master_concomp_id) {
674 while (pt_ptr !=
NULL) {
675 out_bmp_array[pt_ptr->
y()][pt_ptr->
x()] = master_concomp_id;
676 pt_ptr = pt_ptr->
Next();
680 if (!master_concomp->
Merge(concomp_array[concomp_id - 1])) {
681 fprintf(stderr,
"Cube ERROR (Bmp8::FindConComps): could not "
682 "merge connected component: %d\n", concomp_id);
683 FreeBmpBuffer(out_bmp_array);
684 delete []concomp_array;
689 delete concomp_array[concomp_id - 1];
690 concomp_array[concomp_id - 1] =
NULL;
693 master_concomp_id = concomp_id;
694 master_concomp = concomp_array[master_concomp_id - 1];
696 out_bmp_array[y][x] = master_concomp_id;
698 if (!master_concomp->
Add(x, y)) {
699 fprintf(stderr,
"Cube ERROR (Bmp8::FindConComps): could not "
700 "add connected component (%d,%d)\n", x, y);
701 FreeBmpBuffer(out_bmp_array);
702 delete []concomp_array;
710 if (master_concomp ==
NULL) {
711 master_concomp =
new ConComp();
712 if (master_concomp ==
NULL || master_concomp->
Add(x, y) ==
false) {
713 fprintf(stderr,
"Cube ERROR (Bmp8::FindConComps): could not "
714 "allocate or add a connected component\n");
715 FreeBmpBuffer(out_bmp_array);
716 delete []concomp_array;
724 if (temp_con_comp ==
NULL) {
725 fprintf(stderr,
"Cube ERROR (Bmp8::FindConComps): could not "
726 "extend array of connected components\n");
727 FreeBmpBuffer(out_bmp_array);
728 delete []concomp_array;
732 if (alloc_concomp_cnt > 0) {
733 memcpy(temp_con_comp, concomp_array,
734 alloc_concomp_cnt *
sizeof(*concomp_array));
736 delete []concomp_array;
739 concomp_array = temp_con_comp;
742 concomp_array[alloc_concomp_cnt++] = master_concomp;
743 out_bmp_array[y][x] = alloc_concomp_cnt;
750 FreeBmpBuffer(out_bmp_array);
752 if (alloc_concomp_cnt > 0 && concomp_array !=
NULL) {
758 for (
int concomp_idx = 0; concomp_idx < alloc_concomp_cnt; concomp_idx++) {
759 concomp = concomp_array[concomp_idx];
762 if (concomp !=
NULL) {
764 if (concomp->
PtCnt() > min_size) {
767 concomp->
SetID((*concomp_cnt));
768 concomp_array[(*concomp_cnt)++] = concomp;
776 return concomp_array;
780 bool Bmp8::ComputeTanTable() {
787 if (tan_table_ ==
NULL) {
791 for (ang_idx = 0, ang_val = kMinDeslantAngle;
793 tan_table_[ang_idx] = tan(ang_val * M_PI / 180.0
f);
794 ang_val += kDeslantAngleDelta;
819 if (tan_table_ ==
NULL && !ComputeTanTable()) {
824 min_des_x =
static_cast<int>(0.5f + (
hgt_ - 1) * tan_table_[0]);
825 max_des_x = (
wid_ - 1) +
828 des_wid = max_des_x - min_des_x + 1;
833 angle_hist[ang_idx] =
new int[des_wid];
834 if (angle_hist[ang_idx] ==
NULL) {
838 memset(angle_hist[ang_idx], 0, des_wid *
sizeof(*angle_hist[ang_idx]));
842 for (y = 0; y <
hgt_; y++) {
843 for (x = 0; x <
wid_; x++) {
846 des_y = hgt_ - y - 1;
849 des_x = x +
static_cast<int>(0.5f + (des_y * tan_table_[ang_idx]));
850 if (des_x >= min_des_x && des_x <= max_des_x) {
851 angle_hist[ang_idx][des_x - min_des_x]++;
860 double best_entropy = 0.0f;
867 for (x = min_des_x; x <= max_des_x; x++) {
868 if (angle_hist[ang_idx][x - min_des_x] > 0) {
869 norm_val = (1.0f * angle_hist[ang_idx][x - min_des_x] /
hgt_);
870 entropy += (-1.0f * norm_val * log(norm_val));
874 if (best_ang == -1 || entropy < best_entropy) {
876 best_entropy = entropy;
880 delete[] angle_hist[ang_idx];
885 if (best_ang != -1) {
886 unsigned char **dest_lines;
891 dest_lines = CreateBmpBuffer();
892 if (dest_lines ==
NULL) {
896 for (y = 0; y <
hgt_; y++) {
897 for (x = 0; x < old_wid; x++) {
900 des_y = hgt_ - y - 1;
902 des_x = x +
static_cast<int>(0.5f + (des_y * tan_table_[best_ang]));
903 dest_lines[y][des_x - min_des_x] = 0;
921 unsigned char *raw_data = (*raw_data_ptr);
927 memcpy(&val32, raw_data,
sizeof(val32));
928 raw_data +=
sizeof(val32);
930 if (val32 != kMagicNumber) {
935 memcpy(&wid, raw_data,
sizeof(wid));
936 raw_data +=
sizeof(wid);
938 memcpy(&hgt, raw_data,
sizeof(hgt));
939 raw_data +=
sizeof(hgt);
942 memcpy(&buf_size, raw_data,
sizeof(buf_size));
943 raw_data +=
sizeof(buf_size);
946 if (buf_size != (3 * wid * hgt)) {
959 for (y = 0, pix = 0; y <
hgt_; y++) {
960 for (x = 0; x <
wid_; x++, pix += 3) {
963 if (raw_data[pix] != raw_data[pix + 1] ||
964 raw_data[pix] != raw_data[pix + 2]) {
972 (*raw_data_ptr) = raw_data + buf_size;
983 for (
int y = 0; y <
hgt_; y++) {
984 for (
int x = 0; x <
wid_; x++) {
985 fore_cnt += (
line_buff_[y][x] == 0xff ? 0 : 1);
989 return (1.0 * (fore_cnt / hgt_) /
wid_);
1004 if (tan_table_ ==
NULL && !ComputeTanTable()) {
1009 min_des_y = min(0, static_cast<int>((
wid_ - 1) * tan_table_[0]));
1010 max_des_y = (
hgt_ - 1) +
1013 des_hgt = max_des_y - min_des_y + 1;
1018 angle_hist[ang_idx] =
new int[des_hgt];
1019 if (angle_hist[ang_idx] ==
NULL) {
1020 delete[] angle_hist;
1023 memset(angle_hist[ang_idx], 0, des_hgt *
sizeof(*angle_hist[ang_idx]));
1027 for (y = 0; y <
hgt_; y++) {
1028 for (x = 0; x <
wid_; x++) {
1033 des_y = y -
static_cast<int>(x * tan_table_[ang_idx]);
1034 if (des_y >= min_des_y && des_y <= max_des_y) {
1035 angle_hist[ang_idx][des_y - min_des_y]++;
1044 float best_entropy = 0.0f;
1051 for (y = min_des_y; y <= max_des_y; y++) {
1052 if (angle_hist[ang_idx][y - min_des_y] > 0) {
1053 norm_val = (1.0f * angle_hist[ang_idx][y - min_des_y] /
wid_);
1054 entropy += (-1.0f * norm_val * log(norm_val));
1058 if (best_ang == -1 || entropy < best_entropy) {
1060 best_entropy = entropy;
1064 delete[] angle_hist[ang_idx];
1066 delete[] angle_hist;
1068 (*deslant_angle) = 0.0;
1071 if (best_ang != -1) {
1072 unsigned char **dest_lines;
1076 min_des_y = min(0, static_cast<int>((
wid_ - 1) * -tan_table_[best_ang]));
1077 max_des_y = (hgt_ - 1) +
1078 max(0, static_cast<int>((
wid_ - 1) * -tan_table_[best_ang]));
1079 hgt_ = max_des_y - min_des_y + 1;
1080 dest_lines = CreateBmpBuffer();
1081 if (dest_lines ==
NULL) {
1085 for (y = 0; y < old_hgt; y++) {
1086 for (x = 0; x <
wid_; x++) {
1090 des_y = y -
static_cast<int>((x * tan_table_[best_ang]));
1091 dest_lines[des_y - min_des_y][x] = 0;
1100 (*deslant_angle) = kMinDeslantAngle + (best_ang * kDeslantAngleDelta);
1107 float entropy = 0.0f;
1110 for (
int y = 0; y <
hgt_; y++) {
1113 for (
int x = 0; x <
wid_; x++) {
1121 float norm_val = (1.0f * pix_cnt /
wid_);
1122 entropy += (-1.0f * norm_val * log(norm_val));
1126 return entropy /
hgt_;
1130 int *hist =
new int[
hgt_];
1136 for (
int y = 0; y <
hgt_; y++) {
1139 for (
int x = 0; x <
wid_; x++) {