All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tesseract::Bmp8 Class Reference

#include <bmp_8.h>

Inheritance diagram for tesseract::Bmp8:
tesseract::CharSamp

Public Member Functions

 Bmp8 (unsigned short wid, unsigned short hgt)
 
 ~Bmp8 ()
 
bool Clear ()
 
unsigned short Width () const
 
unsigned short Stride () const
 
unsigned short Height () const
 
unsigned char * RawData () const
 
bool ScaleFrom (Bmp8 *bmp, bool isotropic=true)
 
bool Deslant ()
 
bool HorizontalDeslant (double *deslant_angle)
 
bool IsIdentical (Bmp8 *pBmp) const
 
ConComp ** FindConComps (int *concomp_cnt, int min_size) const
 
float ForegroundRatio () const
 
float MeanHorizontalHistogramEntropy () const
 
int * HorizontalHistogram () const
 

Static Public Member Functions

static Bmp8FromCharDumpFile (CachedFile *fp)
 
static Bmp8FromCharDumpFile (FILE *fp)
 

Protected Member Functions

bool LoadFromCharDumpFile (CachedFile *fp)
 
bool LoadFromCharDumpFile (FILE *fp)
 
bool LoadFromCharDumpFile (unsigned char **raw_data)
 
bool LoadFromRawData (unsigned char *data)
 
bool SaveBmp2CharDumpFile (FILE *fp) const
 
bool IsBlankColumn (int x) const
 
bool IsBlankRow (int y) const
 
void Crop (int *xst_src, int *yst_src, int *wid, int *hgt)
 
void Copy (int x, int y, int wid, int hgt, Bmp8 *bmp_dest) const
 

Protected Attributes

unsigned short wid_
 
unsigned short hgt_
 
unsigned char ** line_buff_
 

Static Protected Attributes

static const int kConCompAllocChunk = 16
 
static const int kDeslantAngleCount
 

Detailed Description

Definition at line 41 of file bmp_8.h.

Constructor & Destructor Documentation

tesseract::Bmp8::Bmp8 ( unsigned short  wid,
unsigned short  hgt 
)

Definition at line 38 of file bmp_8.cpp.

39  : wid_(wid)
40  , hgt_(hgt) {
41  line_buff_ = CreateBmpBuffer();
42 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
tesseract::Bmp8::~Bmp8 ( )

Definition at line 44 of file bmp_8.cpp.

44  {
45  FreeBmpBuffer(line_buff_);
46 }
unsigned char ** line_buff_
Definition: bmp_8.h:98

Member Function Documentation

bool tesseract::Bmp8::Clear ( )

Definition at line 128 of file bmp_8.cpp.

128  {
129  if (line_buff_ == NULL) {
130  return false;
131  }
132 
133  memset(line_buff_[0], 0xff, stride_ * hgt_ * sizeof(*line_buff_[0]));
134  return true;
135 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
void tesseract::Bmp8::Copy ( int  x,
int  y,
int  wid,
int  hgt,
Bmp8 bmp_dest 
) const
protected

Definition at line 578 of file bmp_8.cpp.

578  {
579  int x_end = min(x_st + wid, static_cast<int>(wid_)),
580  y_end = min(y_st + hgt, static_cast<int>(hgt_));
581 
582  for (int y = y_st; y < y_end; y++) {
583  for (int x = x_st; x < x_end; x++) {
584  bmp_dest->line_buff_[y - y_st][x - x_st] =
585  line_buff_[y][x];
586  }
587  }
588 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
void tesseract::Bmp8::Crop ( int *  xst_src,
int *  yst_src,
int *  wid,
int *  hgt 
)
protected

Definition at line 348 of file bmp_8.cpp.

348  {
349  (*xst) = 0;
350  (*yst) = 0;
351 
352  int xend = wid_ - 1;
353  int yend = hgt_ - 1;
354 
355  while ((*xst) < (wid_ - 1) && (*xst) <= xend) {
356  // column is not empty
357  if (!IsBlankColumn((*xst))) {
358  break;
359  }
360  (*xst)++;
361  }
362 
363  while (xend > 0 && xend >= (*xst)) {
364  // column is not empty
365  if (!IsBlankColumn(xend)) {
366  break;
367  }
368  xend--;
369  }
370 
371  while ((*yst) < (hgt_ - 1) && (*yst) <= yend) {
372  // column is not empty
373  if (!IsBlankRow((*yst))) {
374  break;
375  }
376  (*yst)++;
377  }
378 
379  while (yend > 0 && yend >= (*yst)) {
380  // column is not empty
381  if (!IsBlankRow(yend)) {
382  break;
383  }
384  yend--;
385  }
386 
387  (*wid) = xend - (*xst) + 1;
388  (*hgt) = yend - (*yst) + 1;
389 }
bool IsBlankRow(int y) const
Definition: bmp_8.cpp:337
unsigned short hgt_
Definition: bmp_8.h:96
bool IsBlankColumn(int x) const
Definition: bmp_8.cpp:327
unsigned short wid_
Definition: bmp_8.h:95
bool tesseract::Bmp8::Deslant ( )

Definition at line 795 of file bmp_8.cpp.

795  {
796  int x;
797  int y;
798  int des_x;
799  int des_y;
800  int ang_idx;
801  int best_ang;
802  int min_des_x;
803  int max_des_x;
804  int des_wid;
805 
806  // only do deslanting if bitmap is wide enough
807  // otherwise it slant estimate might not be reliable
808  if (wid_ < (hgt_ * 2)) {
809  return true;
810  }
811 
812  // compute tan table if needed
813  if (tan_table_ == NULL && !ComputeTanTable()) {
814  return false;
815  }
816 
817  // compute min and max values for x after deslant
818  min_des_x = static_cast<int>(0.5f + (hgt_ - 1) * tan_table_[0]);
819  max_des_x = (wid_ - 1) +
820  static_cast<int>(0.5f + (hgt_ - 1) * tan_table_[kDeslantAngleCount - 1]);
821 
822  des_wid = max_des_x - min_des_x + 1;
823 
824  // alloc memory for histograms
825  int **angle_hist = new int*[kDeslantAngleCount];
826  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
827  angle_hist[ang_idx] = new int[des_wid];
828  if (angle_hist[ang_idx] == NULL) {
829  delete[] angle_hist;
830  return false;
831  }
832  memset(angle_hist[ang_idx], 0, des_wid * sizeof(*angle_hist[ang_idx]));
833  }
834 
835  // compute histograms
836  for (y = 0; y < hgt_; y++) {
837  for (x = 0; x < wid_; x++) {
838  // find a non-bkgrnd pixel
839  if (line_buff_[y][x] != 0xff) {
840  des_y = hgt_ - y - 1;
841  // stamp all histograms
842  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
843  des_x = x + static_cast<int>(0.5f + (des_y * tan_table_[ang_idx]));
844  if (des_x >= min_des_x && des_x <= max_des_x) {
845  angle_hist[ang_idx][des_x - min_des_x]++;
846  }
847  }
848  }
849  }
850  }
851 
852  // find the histogram with the lowest entropy
853  float entropy;
854  double best_entropy = 0.0f;
855  double norm_val;
856 
857  best_ang = -1;
858  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
859  entropy = 0.0f;
860 
861  for (x = min_des_x; x <= max_des_x; x++) {
862  if (angle_hist[ang_idx][x - min_des_x] > 0) {
863  norm_val = (1.0f * angle_hist[ang_idx][x - min_des_x] / hgt_);
864  entropy += (-1.0f * norm_val * log(norm_val));
865  }
866  }
867 
868  if (best_ang == -1 || entropy < best_entropy) {
869  best_ang = ang_idx;
870  best_entropy = entropy;
871  }
872 
873  // free the histogram
874  delete[] angle_hist[ang_idx];
875  }
876  delete[] angle_hist;
877 
878  // deslant
879  if (best_ang != -1) {
880  unsigned char **dest_lines;
881  int old_wid = wid_;
882 
883  // create a new buffer
884  wid_ = des_wid;
885  dest_lines = CreateBmpBuffer();
886  if (dest_lines == NULL) {
887  return false;
888  }
889 
890  for (y = 0; y < hgt_; y++) {
891  for (x = 0; x < old_wid; x++) {
892  // find a non-bkgrnd pixel
893  if (line_buff_[y][x] != 0xff) {
894  des_y = hgt_ - y - 1;
895  // compute new pos
896  des_x = x + static_cast<int>(0.5f + (des_y * tan_table_[best_ang]));
897  dest_lines[y][des_x - min_des_x] = 0;
898  }
899  }
900  }
901 
902  // free old buffer
903  FreeBmpBuffer(line_buff_);
904  line_buff_ = dest_lines;
905  }
906  return true;
907 }
unsigned short hgt_
Definition: bmp_8.h:96
static const int kDeslantAngleCount
Definition: bmp_8.h:101
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
ConComp ** tesseract::Bmp8::FindConComps ( int *  concomp_cnt,
int  min_size 
) const

Definition at line 605 of file bmp_8.cpp.

605  {
606  (*concomp_cnt) = 0;
607 
608  unsigned int **out_bmp_array = CreateBmpBuffer(wid_, hgt_, 0);
609  if (out_bmp_array == NULL) {
610  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not allocate "
611  "bitmap array\n");
612  return NULL;
613  }
614 
615  // listed of connected components
616  ConComp **concomp_array = NULL;
617 
618  int x;
619  int y;
620  int x_nbr;
621  int y_nbr;
622  int concomp_id;
623  int alloc_concomp_cnt = 0;
624 
625  // neighbors to check
626  const int nbr_cnt = 4;
627 
628  // relative coordinates of nbrs
629  int x_del[nbr_cnt] = {-1, 0, 1, -1},
630  y_del[nbr_cnt] = {-1, -1, -1, 0};
631 
632 
633  for (y = 0; y < hgt_; y++) {
634  for (x = 0; x < wid_; x++) {
635  // is this a foreground pix
636  if (line_buff_[y][x] != 0xff) {
637  int master_concomp_id = 0;
638  ConComp *master_concomp = NULL;
639 
640  // checkout the nbrs
641  for (int nbr = 0; nbr < nbr_cnt; nbr++) {
642  x_nbr = x + x_del[nbr];
643  y_nbr = y + y_del[nbr];
644 
645  if (x_nbr < 0 || y_nbr < 0 || x_nbr >= wid_ || y_nbr >= hgt_) {
646  continue;
647  }
648 
649  // is this nbr a foreground pix
650  if (line_buff_[y_nbr][x_nbr] != 0xff) {
651  // get its concomp ID
652  concomp_id = out_bmp_array[y_nbr][x_nbr];
653 
654  // this should not happen
655  if (concomp_id < 1 || concomp_id > alloc_concomp_cnt) {
656  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): illegal "
657  "connected component id: %d\n", concomp_id);
658  FreeBmpBuffer(out_bmp_array);
659  delete []concomp_array;
660  return NULL;
661  }
662 
663  // if we has previously found a component then merge the two
664  // and delete the latest one
665  if (master_concomp != NULL && concomp_id != master_concomp_id) {
666  // relabel all the pts
667  ConCompPt *pt_ptr = concomp_array[concomp_id - 1]->Head();
668  while (pt_ptr != NULL) {
669  out_bmp_array[pt_ptr->y()][pt_ptr->x()] = master_concomp_id;
670  pt_ptr = pt_ptr->Next();
671  }
672 
673  // merge the two concomp
674  if (!master_concomp->Merge(concomp_array[concomp_id - 1])) {
675  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
676  "merge connected component: %d\n", concomp_id);
677  FreeBmpBuffer(out_bmp_array);
678  delete []concomp_array;
679  return NULL;
680  }
681 
682  // delete the merged concomp
683  delete concomp_array[concomp_id - 1];
684  concomp_array[concomp_id - 1] = NULL;
685  } else {
686  // this is the first concomp we encounter
687  master_concomp_id = concomp_id;
688  master_concomp = concomp_array[master_concomp_id - 1];
689 
690  out_bmp_array[y][x] = master_concomp_id;
691 
692  if (!master_concomp->Add(x, y)) {
693  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
694  "add connected component (%d,%d)\n", x, y);
695  FreeBmpBuffer(out_bmp_array);
696  delete []concomp_array;
697  return NULL;
698  }
699  }
700  } // foreground nbr
701  } // nbrs
702 
703  // if there was no foreground pix, then create a new concomp
704  if (master_concomp == NULL) {
705  master_concomp = new ConComp();
706  if (master_concomp == NULL || master_concomp->Add(x, y) == false) {
707  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
708  "allocate or add a connected component\n");
709  FreeBmpBuffer(out_bmp_array);
710  delete []concomp_array;
711  return NULL;
712  }
713 
714  // extend the list of concomps if needed
715  if ((alloc_concomp_cnt % kConCompAllocChunk) == 0) {
716  ConComp **temp_con_comp =
717  new ConComp *[alloc_concomp_cnt + kConCompAllocChunk];
718  if (temp_con_comp == NULL) {
719  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
720  "extend array of connected components\n");
721  FreeBmpBuffer(out_bmp_array);
722  delete []concomp_array;
723  return NULL;
724  }
725 
726  if (alloc_concomp_cnt > 0) {
727  memcpy(temp_con_comp, concomp_array,
728  alloc_concomp_cnt * sizeof(*concomp_array));
729 
730  delete []concomp_array;
731  }
732 
733  concomp_array = temp_con_comp;
734  }
735 
736  concomp_array[alloc_concomp_cnt++] = master_concomp;
737  out_bmp_array[y][x] = alloc_concomp_cnt;
738  }
739  } // foreground pix
740  } // x
741  } // y
742 
743  // free the concomp bmp
744  FreeBmpBuffer(out_bmp_array);
745 
746  if (alloc_concomp_cnt > 0 && concomp_array != NULL) {
747  // scan the array of connected components and color
748  // the o/p buffer with the corresponding concomps
749  (*concomp_cnt) = 0;
750  ConComp *concomp = NULL;
751 
752  for (int concomp_idx = 0; concomp_idx < alloc_concomp_cnt; concomp_idx++) {
753  concomp = concomp_array[concomp_idx];
754 
755  // found a concomp
756  if (concomp != NULL) {
757  // add the connected component if big enough
758  if (concomp->PtCnt() > min_size) {
759  concomp->SetLeftMost(true);
760  concomp->SetRightMost(true);
761  concomp->SetID((*concomp_cnt));
762  concomp_array[(*concomp_cnt)++] = concomp;
763  } else {
764  delete concomp;
765  }
766  }
767  }
768  }
769 
770  return concomp_array;
771 }
static const int kConCompAllocChunk
Definition: bmp_8.h:100
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
float tesseract::Bmp8::ForegroundRatio ( ) const

Definition at line 970 of file bmp_8.cpp.

970  {
971  int fore_cnt = 0;
972 
973  if (wid_ == 0 || hgt_ == 0) {
974  return 1.0;
975  }
976 
977  for (int y = 0; y < hgt_; y++) {
978  for (int x = 0; x < wid_; x++) {
979  fore_cnt += (line_buff_[y][x] == 0xff ? 0 : 1);
980  }
981  }
982 
983  return (1.0 * (fore_cnt / hgt_) / wid_);
984 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
Bmp8 * tesseract::Bmp8::FromCharDumpFile ( CachedFile fp)
static

Definition at line 217 of file bmp_8.cpp.

217  {
218  // create a Bmp8 object
219  Bmp8 *bmp_obj = new Bmp8(0, 0);
220  if (bmp_obj == NULL) {
221  return NULL;
222  }
223 
224  if (bmp_obj->LoadFromCharDumpFile(fp) == false) {
225  delete bmp_obj;
226  return NULL;
227  }
228 
229  return bmp_obj;
230 }
Bmp8(unsigned short wid, unsigned short hgt)
Definition: bmp_8.cpp:38
#define NULL
Definition: host.h:144
Bmp8 * tesseract::Bmp8::FromCharDumpFile ( FILE *  fp)
static

Definition at line 312 of file bmp_8.cpp.

312  {
313  // create a Bmp8 object
314  Bmp8 *bmp_obj = new Bmp8(0, 0);
315  if (bmp_obj == NULL) {
316  return NULL;
317  }
318 
319  if (bmp_obj->LoadFromCharDumpFile(fp) == false) {
320  delete bmp_obj;
321  return NULL;
322  }
323 
324  return bmp_obj;
325 }
Bmp8(unsigned short wid, unsigned short hgt)
Definition: bmp_8.cpp:38
#define NULL
Definition: host.h:144
unsigned short tesseract::Bmp8::Height ( ) const
inline

Definition at line 50 of file bmp_8.h.

50 { return hgt_; }
unsigned short hgt_
Definition: bmp_8.h:96
bool tesseract::Bmp8::HorizontalDeslant ( double *  deslant_angle)

Definition at line 987 of file bmp_8.cpp.

987  {
988  int x;
989  int y;
990  int des_y;
991  int ang_idx;
992  int best_ang;
993  int min_des_y;
994  int max_des_y;
995  int des_hgt;
996 
997  // compute tan table if necess.
998  if (tan_table_ == NULL && !ComputeTanTable()) {
999  return false;
1000  }
1001 
1002  // compute min and max values for x after deslant
1003  min_des_y = min(0, static_cast<int>((wid_ - 1) * tan_table_[0]));
1004  max_des_y = (hgt_ - 1) +
1005  max(0, static_cast<int>((wid_ - 1) * tan_table_[kDeslantAngleCount - 1]));
1006 
1007  des_hgt = max_des_y - min_des_y + 1;
1008 
1009  // alloc memory for histograms
1010  int **angle_hist = new int*[kDeslantAngleCount];
1011  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
1012  angle_hist[ang_idx] = new int[des_hgt];
1013  if (angle_hist[ang_idx] == NULL) {
1014  delete[] angle_hist;
1015  return false;
1016  }
1017  memset(angle_hist[ang_idx], 0, des_hgt * sizeof(*angle_hist[ang_idx]));
1018  }
1019 
1020  // compute histograms
1021  for (y = 0; y < hgt_; y++) {
1022  for (x = 0; x < wid_; x++) {
1023  // find a non-bkgrnd pixel
1024  if (line_buff_[y][x] != 0xff) {
1025  // stamp all histograms
1026  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
1027  des_y = y - static_cast<int>(x * tan_table_[ang_idx]);
1028  if (des_y >= min_des_y && des_y <= max_des_y) {
1029  angle_hist[ang_idx][des_y - min_des_y]++;
1030  }
1031  }
1032  }
1033  }
1034  }
1035 
1036  // find the histogram with the lowest entropy
1037  float entropy;
1038  float best_entropy = 0.0f;
1039  float norm_val;
1040 
1041  best_ang = -1;
1042  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
1043  entropy = 0.0f;
1044 
1045  for (y = min_des_y; y <= max_des_y; y++) {
1046  if (angle_hist[ang_idx][y - min_des_y] > 0) {
1047  norm_val = (1.0f * angle_hist[ang_idx][y - min_des_y] / wid_);
1048  entropy += (-1.0f * norm_val * log(norm_val));
1049  }
1050  }
1051 
1052  if (best_ang == -1 || entropy < best_entropy) {
1053  best_ang = ang_idx;
1054  best_entropy = entropy;
1055  }
1056 
1057  // free the histogram
1058  delete[] angle_hist[ang_idx];
1059  }
1060  delete[] angle_hist;
1061 
1062  (*deslant_angle) = 0.0;
1063 
1064  // deslant
1065  if (best_ang != -1) {
1066  unsigned char **dest_lines;
1067  int old_hgt = hgt_;
1068 
1069  // create a new buffer
1070  min_des_y = min(0, static_cast<int>((wid_ - 1) * -tan_table_[best_ang]));
1071  max_des_y = (hgt_ - 1) +
1072  max(0, static_cast<int>((wid_ - 1) * -tan_table_[best_ang]));
1073  hgt_ = max_des_y - min_des_y + 1;
1074  dest_lines = CreateBmpBuffer();
1075  if (dest_lines == NULL) {
1076  return false;
1077  }
1078 
1079  for (y = 0; y < old_hgt; y++) {
1080  for (x = 0; x < wid_; x++) {
1081  // find a non-bkgrnd pixel
1082  if (line_buff_[y][x] != 0xff) {
1083  // compute new pos
1084  des_y = y - static_cast<int>((x * tan_table_[best_ang]));
1085  dest_lines[des_y - min_des_y][x] = 0;
1086  }
1087  }
1088  }
1089 
1090  // free old buffer
1091  FreeBmpBuffer(line_buff_);
1092  line_buff_ = dest_lines;
1093 
1094  (*deslant_angle) = kMinDeslantAngle + (best_ang * kDeslantAngleDelta);
1095  }
1096 
1097  return true;
1098 }
unsigned short hgt_
Definition: bmp_8.h:96
static const int kDeslantAngleCount
Definition: bmp_8.h:101
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
int * tesseract::Bmp8::HorizontalHistogram ( ) const

Definition at line 1123 of file bmp_8.cpp.

1123  {
1124  int *hist = new int[hgt_];
1125  if (hist == NULL) {
1126  return NULL;
1127  }
1128 
1129  // compute histograms
1130  for (int y = 0; y < hgt_; y++) {
1131  hist[y] = 0;
1132 
1133  for (int x = 0; x < wid_; x++) {
1134  // find a non-bkgrnd pixel
1135  if (line_buff_[y][x] != 0xff) {
1136  hist[y]++;
1137  }
1138  }
1139  }
1140 
1141  return hist;
1142 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
bool tesseract::Bmp8::IsBlankColumn ( int  x) const
protected

Definition at line 327 of file bmp_8.cpp.

327  {
328  for (int y = 0; y < hgt_; y++) {
329  if (line_buff_[y][x] != 0xff) {
330  return false;
331  }
332  }
333 
334  return true;
335 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98
bool tesseract::Bmp8::IsBlankRow ( int  y) const
protected

Definition at line 337 of file bmp_8.cpp.

337  {
338  for (int x = 0; x < wid_; x++) {
339  if (line_buff_[y][x] != 0xff) {
340  return false;
341  }
342  }
343 
344  return true;
345 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
bool tesseract::Bmp8::IsIdentical ( Bmp8 pBmp) const

Definition at line 590 of file bmp_8.cpp.

590  {
591  if (wid_ != pBmp->wid_ || hgt_ != pBmp->hgt_) {
592  return false;
593  }
594 
595  for (int y = 0; y < hgt_; y++) {
596  if (memcmp(line_buff_[y], pBmp->line_buff_[y], wid_) != 0) {
597  return false;
598  }
599  }
600 
601  return true;
602 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
bool tesseract::Bmp8::LoadFromCharDumpFile ( CachedFile fp)
protected

Definition at line 137 of file bmp_8.cpp.

137  {
138  unsigned short wid;
139  unsigned short hgt;
140  unsigned short x;
141  unsigned short y;
142  int buf_size;
143  int pix;
144  int pix_cnt;
145  unsigned int val32;
146  unsigned char *buff;
147 
148  // read and check 32 bit marker
149  if (fp->Read(&val32, sizeof(val32)) != sizeof(val32)) {
150  return false;
151  }
152 
153  if (val32 != kMagicNumber) {
154  return false;
155  }
156 
157  // read wid and hgt
158  if (fp->Read(&wid, sizeof(wid)) != sizeof(wid)) {
159  return false;
160  }
161 
162  if (fp->Read(&hgt, sizeof(hgt)) != sizeof(hgt)) {
163  return false;
164  }
165 
166  // read buf size
167  if (fp->Read(&buf_size, sizeof(buf_size)) != sizeof(buf_size)) {
168  return false;
169  }
170 
171  // validate buf size: for now, only 3 channel (RBG) is supported
172  pix_cnt = wid * hgt;
173  if (buf_size != (3 * pix_cnt)) {
174  return false;
175  }
176 
177  // alloc memory & read the 3 channel buffer
178  buff = new unsigned char[buf_size];
179  if (buff == NULL) {
180  return false;
181  }
182 
183  if (fp->Read(buff, buf_size) != buf_size) {
184  delete []buff;
185  return false;
186  }
187 
188  // create internal buffers
189  wid_ = wid;
190  hgt_ = hgt;
191 
192  line_buff_ = CreateBmpBuffer();
193  if (line_buff_ == NULL) {
194  delete []buff;
195  return false;
196  }
197 
198  // copy the data
199  for (y = 0, pix = 0; y < hgt_; y++) {
200  for (x = 0; x < wid_; x++, pix += 3) {
201  // for now we only support gray scale,
202  // so we expect R = G = B, it this is not the case, bail out
203  if (buff[pix] != buff[pix + 1] || buff[pix] != buff[pix + 2]) {
204  delete []buff;
205  return false;
206  }
207  line_buff_[y][x] = buff[pix];
208  }
209  }
210 
211  // delete temp buffer
212  delete[]buff;
213 
214  return true;
215 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
bool tesseract::Bmp8::LoadFromCharDumpFile ( FILE *  fp)
protected

Definition at line 232 of file bmp_8.cpp.

232  {
233  unsigned short wid;
234  unsigned short hgt;
235  unsigned short x;
236  unsigned short y;
237  int buf_size;
238  int pix;
239  int pix_cnt;
240  unsigned int val32;
241  unsigned char *buff;
242 
243  // read and check 32 bit marker
244  if (fread(&val32, 1, sizeof(val32), fp) != sizeof(val32)) {
245  return false;
246  }
247 
248  if (val32 != kMagicNumber) {
249  return false;
250  }
251 
252  // read wid and hgt
253  if (fread(&wid, 1, sizeof(wid), fp) != sizeof(wid)) {
254  return false;
255  }
256 
257  if (fread(&hgt, 1, sizeof(hgt), fp) != sizeof(hgt)) {
258  return false;
259  }
260 
261  // read buf size
262  if (fread(&buf_size, 1, sizeof(buf_size), fp) != sizeof(buf_size)) {
263  return false;
264  }
265 
266  // validate buf size: for now, only 3 channel (RBG) is supported
267  pix_cnt = wid * hgt;
268  if (buf_size != (3 * pix_cnt)) {
269  return false;
270  }
271 
272  // alloc memory & read the 3 channel buffer
273  buff = new unsigned char[buf_size];
274  if (buff == NULL) {
275  return false;
276  }
277 
278  if (fread(buff, 1, buf_size, fp) != buf_size) {
279  delete []buff;
280  return false;
281  }
282 
283  // create internal buffers
284  wid_ = wid;
285  hgt_ = hgt;
286 
287  line_buff_ = CreateBmpBuffer();
288  if (line_buff_ == NULL) {
289  delete []buff;
290  return false;
291  }
292 
293  // copy the data
294  for (y = 0, pix = 0; y < hgt_; y++) {
295  for (x = 0; x < wid_; x++, pix += 3) {
296  // for now we only support gray scale,
297  // so we expect R = G = B, it this is not the case, bail out
298  if (buff[pix] != buff[pix + 1] || buff[pix] != buff[pix + 2]) {
299  delete []buff;
300  return false;
301  }
302  line_buff_[y][x] = buff[pix];
303  }
304  }
305 
306  // delete temp buffer
307  delete[]buff;
308 
309  return true;
310 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
bool tesseract::Bmp8::LoadFromCharDumpFile ( unsigned char **  raw_data)
protected

Definition at line 910 of file bmp_8.cpp.

910  {
911  unsigned short wid;
912  unsigned short hgt;
913  unsigned short x;
914  unsigned short y;
915  unsigned char *raw_data = (*raw_data_ptr);
916  int buf_size;
917  int pix;
918  unsigned int val32;
919 
920  // read and check 32 bit marker
921  memcpy(&val32, raw_data, sizeof(val32));
922  raw_data += sizeof(val32);
923 
924  if (val32 != kMagicNumber) {
925  return false;
926  }
927 
928  // read wid and hgt
929  memcpy(&wid, raw_data, sizeof(wid));
930  raw_data += sizeof(wid);
931 
932  memcpy(&hgt, raw_data, sizeof(hgt));
933  raw_data += sizeof(hgt);
934 
935  // read buf size
936  memcpy(&buf_size, raw_data, sizeof(buf_size));
937  raw_data += sizeof(buf_size);
938 
939  // validate buf size: for now, only 3 channel (RBG) is supported
940  if (buf_size != (3 * wid * hgt)) {
941  return false;
942  }
943 
944  wid_ = wid;
945  hgt_ = hgt;
946 
947  line_buff_ = CreateBmpBuffer();
948  if (line_buff_ == NULL) {
949  return false;
950  }
951 
952  // copy the data
953  for (y = 0, pix = 0; y < hgt_; y++) {
954  for (x = 0; x < wid_; x++, pix += 3) {
955  // for now we only support gray scale,
956  // so we expect R = G = B, it this is not the case, bail out
957  if (raw_data[pix] != raw_data[pix + 1] ||
958  raw_data[pix] != raw_data[pix + 2]) {
959  return false;
960  }
961 
962  line_buff_[y][x] = raw_data[pix];
963  }
964  }
965 
966  (*raw_data_ptr) = raw_data + buf_size;
967  return true;
968 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
bool tesseract::Bmp8::LoadFromRawData ( unsigned char *  data)
protected

Definition at line 504 of file bmp_8.cpp.

504  {
505  unsigned char *pline_data = data;
506 
507  // copy the data
508  for (int y = 0; y < hgt_; y++, pline_data += wid_) {
509  memcpy(line_buff_[y], pline_data, wid_ * sizeof(*pline_data));
510  }
511 
512  return true;
513 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
float tesseract::Bmp8::MeanHorizontalHistogramEntropy ( ) const

Definition at line 1100 of file bmp_8.cpp.

1100  {
1101  float entropy = 0.0f;
1102 
1103  // compute histograms
1104  for (int y = 0; y < hgt_; y++) {
1105  int pix_cnt = 0;
1106 
1107  for (int x = 0; x < wid_; x++) {
1108  // find a non-bkgrnd pixel
1109  if (line_buff_[y][x] != 0xff) {
1110  pix_cnt++;
1111  }
1112  }
1113 
1114  if (pix_cnt > 0) {
1115  float norm_val = (1.0f * pix_cnt / wid_);
1116  entropy += (-1.0f * norm_val * log(norm_val));
1117  }
1118  }
1119 
1120  return entropy / hgt_;
1121 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
unsigned char* tesseract::Bmp8::RawData ( ) const
inline

Definition at line 51 of file bmp_8.h.

51  {
52  return (line_buff_ == NULL ? NULL : line_buff_[0]);
53  }
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
bool tesseract::Bmp8::SaveBmp2CharDumpFile ( FILE *  fp) const
protected

Definition at line 515 of file bmp_8.cpp.

515  {
516  unsigned short wid;
517  unsigned short hgt;
518  unsigned short x;
519  unsigned short y;
520  int buf_size;
521  int pix;
522  int pix_cnt;
523  unsigned int val32;
524  unsigned char *buff;
525 
526  // write and check 32 bit marker
527  val32 = kMagicNumber;
528  if (fwrite(&val32, 1, sizeof(val32), fp) != sizeof(val32)) {
529  return false;
530  }
531 
532  // write wid and hgt
533  wid = wid_;
534  if (fwrite(&wid, 1, sizeof(wid), fp) != sizeof(wid)) {
535  return false;
536  }
537 
538  hgt = hgt_;
539  if (fwrite(&hgt, 1, sizeof(hgt), fp) != sizeof(hgt)) {
540  return false;
541  }
542 
543  // write buf size
544  pix_cnt = wid * hgt;
545  buf_size = 3 * pix_cnt;
546  if (fwrite(&buf_size, 1, sizeof(buf_size), fp) != sizeof(buf_size)) {
547  return false;
548  }
549 
550  // alloc memory & write the 3 channel buffer
551  buff = new unsigned char[buf_size];
552  if (buff == NULL) {
553  return false;
554  }
555 
556  // copy the data
557  for (y = 0, pix = 0; y < hgt_; y++) {
558  for (x = 0; x < wid_; x++, pix += 3) {
559  buff[pix] =
560  buff[pix + 1] =
561  buff[pix + 2] = line_buff_[y][x];
562  }
563  }
564 
565  if (fwrite(buff, 1, buf_size, fp) != buf_size) {
566  delete []buff;
567  return false;
568  }
569 
570  // delete temp buffer
571  delete[]buff;
572 
573  return true;
574 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
#define NULL
Definition: host.h:144
bool tesseract::Bmp8::ScaleFrom ( Bmp8 bmp,
bool  isotropic = true 
)

Definition at line 393 of file bmp_8.cpp.

393  {
394  int x_num;
395  int x_denom;
396  int y_num;
397  int y_denom;
398  int xoff;
399  int yoff;
400  int xsrc;
401  int ysrc;
402  int xdest;
403  int ydest;
404  int xst_src = 0;
405  int yst_src = 0;
406  int xend_src = bmp->wid_ - 1;
407  int yend_src = bmp->hgt_ - 1;
408  int wid_src;
409  int hgt_src;
410 
411  // src dimensions
412  wid_src = xend_src - xst_src + 1,
413  hgt_src = yend_src - yst_src + 1;
414 
415  // scale to maintain aspect ratio if required
416  if (isotropic) {
417  if ((wid_ * hgt_src) > (hgt_ * wid_src)) {
418  x_num = y_num = hgt_;
419  x_denom = y_denom = hgt_src;
420  } else {
421  x_num = y_num = wid_;
422  x_denom = y_denom = wid_src;
423  }
424  } else {
425  x_num = wid_;
426  y_num = hgt_;
427  x_denom = wid_src;
428  y_denom = hgt_src;
429  }
430 
431  // compute offsets needed to center new bmp
432  xoff = (wid_ - ((x_num * wid_src) / x_denom)) / 2;
433  yoff = (hgt_ - ((y_num * hgt_src) / y_denom)) / 2;
434 
435  // scale up
436  if (y_num > y_denom) {
437  for (ydest = yoff; ydest < (hgt_ - yoff); ydest++) {
438  // compute un-scaled y
439  ysrc = static_cast<int>(0.5 + (1.0 * (ydest - yoff) *
440  y_denom / y_num));
441  if (ysrc < 0 || ysrc >= hgt_src) {
442  continue;
443  }
444 
445  for (xdest = xoff; xdest < (wid_ - xoff); xdest++) {
446  // compute un-scaled y
447  xsrc = static_cast<int>(0.5 + (1.0 * (xdest - xoff) *
448  x_denom / x_num));
449  if (xsrc < 0 || xsrc >= wid_src) {
450  continue;
451  }
452 
453  line_buff_[ydest][xdest] =
454  bmp->line_buff_[ysrc + yst_src][xsrc + xst_src];
455  }
456  }
457  } else {
458  // or scale down
459  // scaling down is a bit tricky: we'll accumulate pixels
460  // and then compute the means
461  unsigned int **dest_line_buff = CreateBmpBuffer(wid_, hgt_, 0),
462  **dest_pix_cnt = CreateBmpBuffer(wid_, hgt_, 0);
463 
464  for (ysrc = 0; ysrc < hgt_src; ysrc++) {
465  // compute scaled y
466  ydest = yoff + static_cast<int>(0.5 + (1.0 * ysrc * y_num / y_denom));
467  if (ydest < 0 || ydest >= hgt_) {
468  continue;
469  }
470 
471  for (xsrc = 0; xsrc < wid_src; xsrc++) {
472  // compute scaled y
473  xdest = xoff + static_cast<int>(0.5 + (1.0 * xsrc * x_num / x_denom));
474  if (xdest < 0 || xdest >= wid_) {
475  continue;
476  }
477 
478  dest_line_buff[ydest][xdest] +=
479  bmp->line_buff_[ysrc + yst_src][xsrc + xst_src];
480  dest_pix_cnt[ydest][xdest]++;
481  }
482  }
483 
484  for (ydest = 0; ydest < hgt_; ydest++) {
485  for (xdest = 0; xdest < wid_; xdest++) {
486  if (dest_pix_cnt[ydest][xdest] > 0) {
487  unsigned int pixval =
488  dest_line_buff[ydest][xdest] / dest_pix_cnt[ydest][xdest];
489 
490  line_buff_[ydest][xdest] =
491  (unsigned char) min((unsigned int)255, pixval);
492  }
493  }
494  }
495 
496  // we no longer need these temp buffers
497  FreeBmpBuffer(dest_line_buff);
498  FreeBmpBuffer(dest_pix_cnt);
499  }
500 
501  return true;
502 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98
unsigned short tesseract::Bmp8::Stride ( ) const
inline

Definition at line 49 of file bmp_8.h.

49 { return stride_; }
unsigned short tesseract::Bmp8::Width ( ) const
inline

Definition at line 48 of file bmp_8.h.

48 { return wid_; }
unsigned short wid_
Definition: bmp_8.h:95

Member Data Documentation

unsigned short tesseract::Bmp8::hgt_
protected

Definition at line 96 of file bmp_8.h.

const int tesseract::Bmp8::kConCompAllocChunk = 16
staticprotected

Definition at line 100 of file bmp_8.h.

const int tesseract::Bmp8::kDeslantAngleCount
staticprotected
Initial value:
= (1 + static_cast<int>(0.5f +
(kMaxDeslantAngle - kMinDeslantAngle) / kDeslantAngleDelta))

Definition at line 101 of file bmp_8.h.

unsigned char** tesseract::Bmp8::line_buff_
protected

Definition at line 98 of file bmp_8.h.

unsigned short tesseract::Bmp8::wid_
protected

Definition at line 95 of file bmp_8.h.


The documentation for this class was generated from the following files: