tesseract  3.05.02
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

◆ Bmp8()

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 wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ ~Bmp8()

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

◆ Clear()

bool tesseract::Bmp8::Clear ( )

Definition at line 110 of file bmp_8.cpp.

110  {
111  if (line_buff_ == NULL) {
112  return false;
113  }
114 
115  memset(line_buff_[0], 0xff, stride_ * hgt_ * sizeof(*line_buff_[0]));
116  return true;
117 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ Copy()

void tesseract::Bmp8::Copy ( int  x,
int  y,
int  wid,
int  hgt,
Bmp8 bmp_dest 
) const
protected

Definition at line 545 of file bmp_8.cpp.

545  {
546  int x_end = min(x_st + wid, static_cast<int>(wid_)),
547  y_end = min(y_st + hgt, static_cast<int>(hgt_));
548 
549  for (int y = y_st; y < y_end; y++) {
550  for (int x = x_st; x < x_end; x++) {
551  bmp_dest->line_buff_[y - y_st][x - x_st] =
552  line_buff_[y][x];
553  }
554  }
555 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ Crop()

void tesseract::Bmp8::Crop ( int *  xst_src,
int *  yst_src,
int *  wid,
int *  hgt 
)
protected

Definition at line 318 of file bmp_8.cpp.

318  {
319  (*xst) = 0;
320  (*yst) = 0;
321 
322  int xend = wid_ - 1;
323  int yend = hgt_ - 1;
324 
325  while ((*xst) < (wid_ - 1) && (*xst) <= xend) {
326  // column is not empty
327  if (!IsBlankColumn((*xst))) {
328  break;
329  }
330  (*xst)++;
331  }
332 
333  while (xend > 0 && xend >= (*xst)) {
334  // column is not empty
335  if (!IsBlankColumn(xend)) {
336  break;
337  }
338  xend--;
339  }
340 
341  while ((*yst) < (hgt_ - 1) && (*yst) <= yend) {
342  // column is not empty
343  if (!IsBlankRow((*yst))) {
344  break;
345  }
346  (*yst)++;
347  }
348 
349  while (yend > 0 && yend >= (*yst)) {
350  // column is not empty
351  if (!IsBlankRow(yend)) {
352  break;
353  }
354  yend--;
355  }
356 
357  (*wid) = xend - (*xst) + 1;
358  (*hgt) = yend - (*yst) + 1;
359 }
bool IsBlankRow(int y) const
Definition: bmp_8.cpp:307
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
bool IsBlankColumn(int x) const
Definition: bmp_8.cpp:297

◆ Deslant()

bool tesseract::Bmp8::Deslant ( )

Definition at line 752 of file bmp_8.cpp.

752  {
753  int x;
754  int y;
755  int des_x;
756  int des_y;
757  int ang_idx;
758  int best_ang;
759  int min_des_x;
760  int max_des_x;
761  int des_wid;
762 
763  // only do deslanting if bitmap is wide enough
764  // otherwise it slant estimate might not be reliable
765  if (wid_ < (hgt_ * 2)) {
766  return true;
767  }
768 
769  // compute tan table if needed
770  if (tan_table_ == NULL && !ComputeTanTable()) {
771  return false;
772  }
773 
774  // compute min and max values for x after deslant
775  min_des_x = static_cast<int>(0.5f + (hgt_ - 1) * tan_table_[0]);
776  max_des_x = (wid_ - 1) +
777  static_cast<int>(0.5f + (hgt_ - 1) * tan_table_[kDeslantAngleCount - 1]);
778 
779  des_wid = max_des_x - min_des_x + 1;
780 
781  // alloc memory for histograms
782  int **angle_hist = new int*[kDeslantAngleCount];
783  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
784  angle_hist[ang_idx] = new int[des_wid];
785  memset(angle_hist[ang_idx], 0, des_wid * sizeof(*angle_hist[ang_idx]));
786  }
787 
788  // compute histograms
789  for (y = 0; y < hgt_; y++) {
790  for (x = 0; x < wid_; x++) {
791  // find a non-bkgrnd pixel
792  if (line_buff_[y][x] != 0xff) {
793  des_y = hgt_ - y - 1;
794  // stamp all histograms
795  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
796  des_x = x + static_cast<int>(0.5f + (des_y * tan_table_[ang_idx]));
797  if (des_x >= min_des_x && des_x <= max_des_x) {
798  angle_hist[ang_idx][des_x - min_des_x]++;
799  }
800  }
801  }
802  }
803  }
804 
805  // find the histogram with the lowest entropy
806  float entropy;
807  double best_entropy = 0.0f;
808  double norm_val;
809 
810  best_ang = -1;
811  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
812  entropy = 0.0f;
813 
814  for (x = min_des_x; x <= max_des_x; x++) {
815  if (angle_hist[ang_idx][x - min_des_x] > 0) {
816  norm_val = (1.0f * angle_hist[ang_idx][x - min_des_x] / hgt_);
817  entropy += (-1.0f * norm_val * log(norm_val));
818  }
819  }
820 
821  if (best_ang == -1 || entropy < best_entropy) {
822  best_ang = ang_idx;
823  best_entropy = entropy;
824  }
825 
826  // free the histogram
827  delete[] angle_hist[ang_idx];
828  }
829  delete[] angle_hist;
830 
831  // deslant
832  if (best_ang != -1) {
833  unsigned char **dest_lines;
834  int old_wid = wid_;
835 
836  // create a new buffer
837  wid_ = des_wid;
838  dest_lines = CreateBmpBuffer();
839  if (dest_lines == NULL) {
840  return false;
841  }
842 
843  for (y = 0; y < hgt_; y++) {
844  for (x = 0; x < old_wid; x++) {
845  // find a non-bkgrnd pixel
846  if (line_buff_[y][x] != 0xff) {
847  des_y = hgt_ - y - 1;
848  // compute new pos
849  des_x = x + static_cast<int>(0.5f + (des_y * tan_table_[best_ang]));
850  dest_lines[y][des_x - min_des_x] = 0;
851  }
852  }
853  }
854 
855  // free old buffer
856  FreeBmpBuffer(line_buff_);
857  line_buff_ = dest_lines;
858  }
859  return true;
860 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98
static const int kDeslantAngleCount
Definition: bmp_8.h:101

◆ FindConComps()

ConComp ** tesseract::Bmp8::FindConComps ( int *  concomp_cnt,
int  min_size 
) const

Definition at line 572 of file bmp_8.cpp.

572  {
573  (*concomp_cnt) = 0;
574 
575  unsigned int **out_bmp_array = CreateBmpBuffer(wid_, hgt_, 0);
576  if (out_bmp_array == NULL) {
577  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not allocate "
578  "bitmap array\n");
579  return NULL;
580  }
581 
582  // listed of connected components
583  ConComp **concomp_array = NULL;
584 
585  int x;
586  int y;
587  int x_nbr;
588  int y_nbr;
589  int concomp_id;
590  int alloc_concomp_cnt = 0;
591 
592  // neighbors to check
593  const int nbr_cnt = 4;
594 
595  // relative coordinates of nbrs
596  int x_del[nbr_cnt] = {-1, 0, 1, -1},
597  y_del[nbr_cnt] = {-1, -1, -1, 0};
598 
599 
600  for (y = 0; y < hgt_; y++) {
601  for (x = 0; x < wid_; x++) {
602  // is this a foreground pix
603  if (line_buff_[y][x] != 0xff) {
604  int master_concomp_id = 0;
605  ConComp *master_concomp = NULL;
606 
607  // checkout the nbrs
608  for (int nbr = 0; nbr < nbr_cnt; nbr++) {
609  x_nbr = x + x_del[nbr];
610  y_nbr = y + y_del[nbr];
611 
612  if (x_nbr < 0 || y_nbr < 0 || x_nbr >= wid_ || y_nbr >= hgt_) {
613  continue;
614  }
615 
616  // is this nbr a foreground pix
617  if (line_buff_[y_nbr][x_nbr] != 0xff) {
618  // get its concomp ID
619  concomp_id = out_bmp_array[y_nbr][x_nbr];
620 
621  // this should not happen
622  if (concomp_id < 1 || concomp_id > alloc_concomp_cnt) {
623  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): illegal "
624  "connected component id: %d\n", concomp_id);
625  FreeBmpBuffer(out_bmp_array);
626  delete []concomp_array;
627  return NULL;
628  }
629 
630  // if we has previously found a component then merge the two
631  // and delete the latest one
632  if (master_concomp != NULL && concomp_id != master_concomp_id) {
633  // relabel all the pts
634  ConCompPt *pt_ptr = concomp_array[concomp_id - 1]->Head();
635  while (pt_ptr != NULL) {
636  out_bmp_array[pt_ptr->y()][pt_ptr->x()] = master_concomp_id;
637  pt_ptr = pt_ptr->Next();
638  }
639 
640  // merge the two concomp
641  if (!master_concomp->Merge(concomp_array[concomp_id - 1])) {
642  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
643  "merge connected component: %d\n", concomp_id);
644  FreeBmpBuffer(out_bmp_array);
645  delete []concomp_array;
646  return NULL;
647  }
648 
649  // delete the merged concomp
650  delete concomp_array[concomp_id - 1];
651  concomp_array[concomp_id - 1] = NULL;
652  } else {
653  // this is the first concomp we encounter
654  master_concomp_id = concomp_id;
655  master_concomp = concomp_array[master_concomp_id - 1];
656 
657  out_bmp_array[y][x] = master_concomp_id;
658 
659  if (!master_concomp->Add(x, y)) {
660  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
661  "add connected component (%d,%d)\n", x, y);
662  FreeBmpBuffer(out_bmp_array);
663  delete []concomp_array;
664  return NULL;
665  }
666  }
667  } // foreground nbr
668  } // nbrs
669 
670  // if there was no foreground pix, then create a new concomp
671  if (master_concomp == NULL) {
672  master_concomp = new ConComp();
673  if (master_concomp->Add(x, y) == false) {
674  fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
675  "allocate or add a connected component\n");
676  FreeBmpBuffer(out_bmp_array);
677  delete []concomp_array;
678  return NULL;
679  }
680 
681  // extend the list of concomps if needed
682  if ((alloc_concomp_cnt % kConCompAllocChunk) == 0) {
683  ConComp **temp_con_comp =
684  new ConComp *[alloc_concomp_cnt + kConCompAllocChunk];
685 
686  if (alloc_concomp_cnt > 0) {
687  memcpy(temp_con_comp, concomp_array,
688  alloc_concomp_cnt * sizeof(*concomp_array));
689 
690  delete []concomp_array;
691  }
692 
693  concomp_array = temp_con_comp;
694  }
695 
696  concomp_array[alloc_concomp_cnt++] = master_concomp;
697  out_bmp_array[y][x] = alloc_concomp_cnt;
698  }
699  } // foreground pix
700  } // x
701  } // y
702 
703  // free the concomp bmp
704  FreeBmpBuffer(out_bmp_array);
705 
706  if (alloc_concomp_cnt > 0 && concomp_array != NULL) {
707  // scan the array of connected components and color
708  // the o/p buffer with the corresponding concomps
709  (*concomp_cnt) = 0;
710  ConComp *concomp = NULL;
711 
712  for (int concomp_idx = 0; concomp_idx < alloc_concomp_cnt; concomp_idx++) {
713  concomp = concomp_array[concomp_idx];
714 
715  // found a concomp
716  if (concomp != NULL) {
717  // add the connected component if big enough
718  if (concomp->PtCnt() > min_size) {
719  concomp->SetLeftMost(true);
720  concomp->SetRightMost(true);
721  concomp->SetID((*concomp_cnt));
722  concomp_array[(*concomp_cnt)++] = concomp;
723  } else {
724  delete concomp;
725  }
726  }
727  }
728  }
729 
730  return concomp_array;
731 }
static const int kConCompAllocChunk
Definition: bmp_8.h:100
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ ForegroundRatio()

float tesseract::Bmp8::ForegroundRatio ( ) const

Definition at line 923 of file bmp_8.cpp.

923  {
924  int fore_cnt = 0;
925 
926  if (wid_ == 0 || hgt_ == 0) {
927  return 1.0;
928  }
929 
930  for (int y = 0; y < hgt_; y++) {
931  for (int x = 0; x < wid_; x++) {
932  fore_cnt += (line_buff_[y][x] == 0xff ? 0 : 1);
933  }
934  }
935 
936  return (1.0 * (fore_cnt / hgt_) / wid_);
937 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ FromCharDumpFile() [1/2]

Bmp8 * tesseract::Bmp8::FromCharDumpFile ( CachedFile fp)
static

Definition at line 196 of file bmp_8.cpp.

196  {
197  // create a Bmp8 object
198  Bmp8 *bmp_obj = new Bmp8(0, 0);
199 
200  if (bmp_obj->LoadFromCharDumpFile(fp) == false) {
201  delete bmp_obj;
202  return NULL;
203  }
204 
205  return bmp_obj;
206 }
Bmp8(unsigned short wid, unsigned short hgt)
Definition: bmp_8.cpp:38

◆ FromCharDumpFile() [2/2]

Bmp8 * tesseract::Bmp8::FromCharDumpFile ( FILE *  fp)
static

Definition at line 285 of file bmp_8.cpp.

285  {
286  // create a Bmp8 object
287  Bmp8 *bmp_obj = new Bmp8(0, 0);
288 
289  if (bmp_obj->LoadFromCharDumpFile(fp) == false) {
290  delete bmp_obj;
291  return NULL;
292  }
293 
294  return bmp_obj;
295 }
Bmp8(unsigned short wid, unsigned short hgt)
Definition: bmp_8.cpp:38

◆ Height()

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

◆ HorizontalDeslant()

bool tesseract::Bmp8::HorizontalDeslant ( double *  deslant_angle)

Definition at line 940 of file bmp_8.cpp.

940  {
941  int x;
942  int y;
943  int des_y;
944  int ang_idx;
945  int best_ang;
946  int min_des_y;
947  int max_des_y;
948  int des_hgt;
949 
950  // compute tan table if necess.
951  if (tan_table_ == NULL && !ComputeTanTable()) {
952  return false;
953  }
954 
955  // compute min and max values for x after deslant
956  min_des_y = min(0, static_cast<int>((wid_ - 1) * tan_table_[0]));
957  max_des_y = (hgt_ - 1) +
958  max(0, static_cast<int>((wid_ - 1) * tan_table_[kDeslantAngleCount - 1]));
959 
960  des_hgt = max_des_y - min_des_y + 1;
961 
962  // alloc memory for histograms
963  int **angle_hist = new int*[kDeslantAngleCount];
964  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
965  angle_hist[ang_idx] = new int[des_hgt];
966  memset(angle_hist[ang_idx], 0, des_hgt * sizeof(*angle_hist[ang_idx]));
967  }
968 
969  // compute histograms
970  for (y = 0; y < hgt_; y++) {
971  for (x = 0; x < wid_; x++) {
972  // find a non-bkgrnd pixel
973  if (line_buff_[y][x] != 0xff) {
974  // stamp all histograms
975  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
976  des_y = y - static_cast<int>(x * tan_table_[ang_idx]);
977  if (des_y >= min_des_y && des_y <= max_des_y) {
978  angle_hist[ang_idx][des_y - min_des_y]++;
979  }
980  }
981  }
982  }
983  }
984 
985  // find the histogram with the lowest entropy
986  float entropy;
987  float best_entropy = 0.0f;
988  float norm_val;
989 
990  best_ang = -1;
991  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
992  entropy = 0.0f;
993 
994  for (y = min_des_y; y <= max_des_y; y++) {
995  if (angle_hist[ang_idx][y - min_des_y] > 0) {
996  norm_val = (1.0f * angle_hist[ang_idx][y - min_des_y] / wid_);
997  entropy += (-1.0f * norm_val * log(norm_val));
998  }
999  }
1000 
1001  if (best_ang == -1 || entropy < best_entropy) {
1002  best_ang = ang_idx;
1003  best_entropy = entropy;
1004  }
1005 
1006  // free the histogram
1007  delete[] angle_hist[ang_idx];
1008  }
1009  delete[] angle_hist;
1010 
1011  (*deslant_angle) = 0.0;
1012 
1013  // deslant
1014  if (best_ang != -1) {
1015  unsigned char **dest_lines;
1016  int old_hgt = hgt_;
1017 
1018  // create a new buffer
1019  min_des_y = min(0, static_cast<int>((wid_ - 1) * -tan_table_[best_ang]));
1020  max_des_y = (hgt_ - 1) +
1021  max(0, static_cast<int>((wid_ - 1) * -tan_table_[best_ang]));
1022  hgt_ = max_des_y - min_des_y + 1;
1023  dest_lines = CreateBmpBuffer();
1024  if (dest_lines == NULL) {
1025  return false;
1026  }
1027 
1028  for (y = 0; y < old_hgt; y++) {
1029  for (x = 0; x < wid_; x++) {
1030  // find a non-bkgrnd pixel
1031  if (line_buff_[y][x] != 0xff) {
1032  // compute new pos
1033  des_y = y - static_cast<int>((x * tan_table_[best_ang]));
1034  dest_lines[des_y - min_des_y][x] = 0;
1035  }
1036  }
1037  }
1038 
1039  // free old buffer
1040  FreeBmpBuffer(line_buff_);
1041  line_buff_ = dest_lines;
1042 
1043  (*deslant_angle) = kMinDeslantAngle + (best_ang * kDeslantAngleDelta);
1044  }
1045 
1046  return true;
1047 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98
static const int kDeslantAngleCount
Definition: bmp_8.h:101

◆ HorizontalHistogram()

int * tesseract::Bmp8::HorizontalHistogram ( ) const

Definition at line 1072 of file bmp_8.cpp.

1072  {
1073  int *hist = new int[hgt_];
1074 
1075  // compute histograms
1076  for (int y = 0; y < hgt_; y++) {
1077  hist[y] = 0;
1078 
1079  for (int x = 0; x < wid_; x++) {
1080  // find a non-bkgrnd pixel
1081  if (line_buff_[y][x] != 0xff) {
1082  hist[y]++;
1083  }
1084  }
1085  }
1086 
1087  return hist;
1088 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ IsBlankColumn()

bool tesseract::Bmp8::IsBlankColumn ( int  x) const
protected

Definition at line 297 of file bmp_8.cpp.

297  {
298  for (int y = 0; y < hgt_; y++) {
299  if (line_buff_[y][x] != 0xff) {
300  return false;
301  }
302  }
303 
304  return true;
305 }
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ IsBlankRow()

bool tesseract::Bmp8::IsBlankRow ( int  y) const
protected

Definition at line 307 of file bmp_8.cpp.

307  {
308  for (int x = 0; x < wid_; x++) {
309  if (line_buff_[y][x] != 0xff) {
310  return false;
311  }
312  }
313 
314  return true;
315 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ IsIdentical()

bool tesseract::Bmp8::IsIdentical ( Bmp8 pBmp) const

Definition at line 557 of file bmp_8.cpp.

557  {
558  if (wid_ != pBmp->wid_ || hgt_ != pBmp->hgt_) {
559  return false;
560  }
561 
562  for (int y = 0; y < hgt_; y++) {
563  if (memcmp(line_buff_[y], pBmp->line_buff_[y], wid_) != 0) {
564  return false;
565  }
566  }
567 
568  return true;
569 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ LoadFromCharDumpFile() [1/3]

bool tesseract::Bmp8::LoadFromCharDumpFile ( CachedFile fp)
protected

Definition at line 119 of file bmp_8.cpp.

119  {
120  unsigned short wid;
121  unsigned short hgt;
122  unsigned short x;
123  unsigned short y;
124  int buf_size;
125  int pix;
126  int pix_cnt;
127  unsigned int val32;
128  unsigned char *buff;
129 
130  // read and check 32 bit marker
131  if (fp->Read(&val32, sizeof(val32)) != sizeof(val32)) {
132  return false;
133  }
134 
135  if (val32 != kMagicNumber) {
136  return false;
137  }
138 
139  // read wid and hgt
140  if (fp->Read(&wid, sizeof(wid)) != sizeof(wid)) {
141  return false;
142  }
143 
144  if (fp->Read(&hgt, sizeof(hgt)) != sizeof(hgt)) {
145  return false;
146  }
147 
148  // read buf size
149  if (fp->Read(&buf_size, sizeof(buf_size)) != sizeof(buf_size)) {
150  return false;
151  }
152 
153  // validate buf size: for now, only 3 channel (RBG) is supported
154  pix_cnt = wid * hgt;
155  if (buf_size != (3 * pix_cnt)) {
156  return false;
157  }
158 
159  // alloc memory & read the 3 channel buffer
160  buff = new unsigned char[buf_size];
161 
162  if (fp->Read(buff, buf_size) != buf_size) {
163  delete []buff;
164  return false;
165  }
166 
167  // create internal buffers
168  wid_ = wid;
169  hgt_ = hgt;
170 
171  line_buff_ = CreateBmpBuffer();
172  if (line_buff_ == NULL) {
173  delete []buff;
174  return false;
175  }
176 
177  // copy the data
178  for (y = 0, pix = 0; y < hgt_; y++) {
179  for (x = 0; x < wid_; x++, pix += 3) {
180  // for now we only support gray scale,
181  // so we expect R = G = B, it this is not the case, bail out
182  if (buff[pix] != buff[pix + 1] || buff[pix] != buff[pix + 2]) {
183  delete []buff;
184  return false;
185  }
186  line_buff_[y][x] = buff[pix];
187  }
188  }
189 
190  // delete temp buffer
191  delete[]buff;
192 
193  return true;
194 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ LoadFromCharDumpFile() [2/3]

bool tesseract::Bmp8::LoadFromCharDumpFile ( FILE *  fp)
protected

Definition at line 208 of file bmp_8.cpp.

208  {
209  unsigned short wid;
210  unsigned short hgt;
211  unsigned short x;
212  unsigned short y;
213  int buf_size;
214  int pix;
215  int pix_cnt;
216  unsigned int val32;
217  unsigned char *buff;
218 
219  // read and check 32 bit marker
220  if (fread(&val32, 1, sizeof(val32), fp) != sizeof(val32)) {
221  return false;
222  }
223 
224  if (val32 != kMagicNumber) {
225  return false;
226  }
227 
228  // read wid and hgt
229  if (fread(&wid, 1, sizeof(wid), fp) != sizeof(wid)) {
230  return false;
231  }
232 
233  if (fread(&hgt, 1, sizeof(hgt), fp) != sizeof(hgt)) {
234  return false;
235  }
236 
237  // read buf size
238  if (fread(&buf_size, 1, sizeof(buf_size), fp) != sizeof(buf_size)) {
239  return false;
240  }
241 
242  // validate buf size: for now, only 3 channel (RBG) is supported
243  pix_cnt = wid * hgt;
244  if (buf_size != (3 * pix_cnt)) {
245  return false;
246  }
247 
248  // alloc memory & read the 3 channel buffer
249  buff = new unsigned char[buf_size];
250 
251  if (fread(buff, 1, buf_size, fp) != buf_size) {
252  delete []buff;
253  return false;
254  }
255 
256  // create internal buffers
257  wid_ = wid;
258  hgt_ = hgt;
259 
260  line_buff_ = CreateBmpBuffer();
261  if (line_buff_ == NULL) {
262  delete []buff;
263  return false;
264  }
265 
266  // copy the data
267  for (y = 0, pix = 0; y < hgt_; y++) {
268  for (x = 0; x < wid_; x++, pix += 3) {
269  // for now we only support gray scale,
270  // so we expect R = G = B, it this is not the case, bail out
271  if (buff[pix] != buff[pix + 1] || buff[pix] != buff[pix + 2]) {
272  delete []buff;
273  return false;
274  }
275  line_buff_[y][x] = buff[pix];
276  }
277  }
278 
279  // delete temp buffer
280  delete[]buff;
281 
282  return true;
283 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ LoadFromCharDumpFile() [3/3]

bool tesseract::Bmp8::LoadFromCharDumpFile ( unsigned char **  raw_data)
protected

Definition at line 863 of file bmp_8.cpp.

863  {
864  unsigned short wid;
865  unsigned short hgt;
866  unsigned short x;
867  unsigned short y;
868  unsigned char *raw_data = (*raw_data_ptr);
869  int buf_size;
870  int pix;
871  unsigned int val32;
872 
873  // read and check 32 bit marker
874  memcpy(&val32, raw_data, sizeof(val32));
875  raw_data += sizeof(val32);
876 
877  if (val32 != kMagicNumber) {
878  return false;
879  }
880 
881  // read wid and hgt
882  memcpy(&wid, raw_data, sizeof(wid));
883  raw_data += sizeof(wid);
884 
885  memcpy(&hgt, raw_data, sizeof(hgt));
886  raw_data += sizeof(hgt);
887 
888  // read buf size
889  memcpy(&buf_size, raw_data, sizeof(buf_size));
890  raw_data += sizeof(buf_size);
891 
892  // validate buf size: for now, only 3 channel (RBG) is supported
893  if (buf_size != (3 * wid * hgt)) {
894  return false;
895  }
896 
897  wid_ = wid;
898  hgt_ = hgt;
899 
900  line_buff_ = CreateBmpBuffer();
901  if (line_buff_ == NULL) {
902  return false;
903  }
904 
905  // copy the data
906  for (y = 0, pix = 0; y < hgt_; y++) {
907  for (x = 0; x < wid_; x++, pix += 3) {
908  // for now we only support gray scale,
909  // so we expect R = G = B, it this is not the case, bail out
910  if (raw_data[pix] != raw_data[pix + 1] ||
911  raw_data[pix] != raw_data[pix + 2]) {
912  return false;
913  }
914 
915  line_buff_[y][x] = raw_data[pix];
916  }
917  }
918 
919  (*raw_data_ptr) = raw_data + buf_size;
920  return true;
921 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ LoadFromRawData()

bool tesseract::Bmp8::LoadFromRawData ( unsigned char *  data)
protected

Definition at line 474 of file bmp_8.cpp.

474  {
475  unsigned char *pline_data = data;
476 
477  // copy the data
478  for (int y = 0; y < hgt_; y++, pline_data += wid_) {
479  memcpy(line_buff_[y], pline_data, wid_ * sizeof(*pline_data));
480  }
481 
482  return true;
483 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ MeanHorizontalHistogramEntropy()

float tesseract::Bmp8::MeanHorizontalHistogramEntropy ( ) const

Definition at line 1049 of file bmp_8.cpp.

1049  {
1050  float entropy = 0.0f;
1051 
1052  // compute histograms
1053  for (int y = 0; y < hgt_; y++) {
1054  int pix_cnt = 0;
1055 
1056  for (int x = 0; x < wid_; x++) {
1057  // find a non-bkgrnd pixel
1058  if (line_buff_[y][x] != 0xff) {
1059  pix_cnt++;
1060  }
1061  }
1062 
1063  if (pix_cnt > 0) {
1064  float norm_val = (1.0f * pix_cnt / wid_);
1065  entropy += (-1.0f * norm_val * log(norm_val));
1066  }
1067  }
1068 
1069  return entropy / hgt_;
1070 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ RawData()

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

◆ SaveBmp2CharDumpFile()

bool tesseract::Bmp8::SaveBmp2CharDumpFile ( FILE *  fp) const
protected

Definition at line 485 of file bmp_8.cpp.

485  {
486  unsigned short wid;
487  unsigned short hgt;
488  unsigned short x;
489  unsigned short y;
490  int buf_size;
491  int pix;
492  int pix_cnt;
493  unsigned int val32;
494  unsigned char *buff;
495 
496  // write and check 32 bit marker
497  val32 = kMagicNumber;
498  if (fwrite(&val32, 1, sizeof(val32), fp) != sizeof(val32)) {
499  return false;
500  }
501 
502  // write wid and hgt
503  wid = wid_;
504  if (fwrite(&wid, 1, sizeof(wid), fp) != sizeof(wid)) {
505  return false;
506  }
507 
508  hgt = hgt_;
509  if (fwrite(&hgt, 1, sizeof(hgt), fp) != sizeof(hgt)) {
510  return false;
511  }
512 
513  // write buf size
514  pix_cnt = wid * hgt;
515  buf_size = 3 * pix_cnt;
516  if (fwrite(&buf_size, 1, sizeof(buf_size), fp) != sizeof(buf_size)) {
517  return false;
518  }
519 
520  // alloc memory & write the 3 channel buffer
521  buff = new unsigned char[buf_size];
522 
523  // copy the data
524  for (y = 0, pix = 0; y < hgt_; y++) {
525  for (x = 0; x < wid_; x++, pix += 3) {
526  buff[pix] =
527  buff[pix + 1] =
528  buff[pix + 2] = line_buff_[y][x];
529  }
530  }
531 
532  if (fwrite(buff, 1, buf_size, fp) != buf_size) {
533  delete []buff;
534  return false;
535  }
536 
537  // delete temp buffer
538  delete[]buff;
539 
540  return true;
541 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ ScaleFrom()

bool tesseract::Bmp8::ScaleFrom ( Bmp8 bmp,
bool  isotropic = true 
)

Definition at line 363 of file bmp_8.cpp.

363  {
364  int x_num;
365  int x_denom;
366  int y_num;
367  int y_denom;
368  int xoff;
369  int yoff;
370  int xsrc;
371  int ysrc;
372  int xdest;
373  int ydest;
374  int xst_src = 0;
375  int yst_src = 0;
376  int xend_src = bmp->wid_ - 1;
377  int yend_src = bmp->hgt_ - 1;
378  int wid_src;
379  int hgt_src;
380 
381  // src dimensions
382  wid_src = xend_src - xst_src + 1,
383  hgt_src = yend_src - yst_src + 1;
384 
385  // scale to maintain aspect ratio if required
386  if (isotropic) {
387  if ((wid_ * hgt_src) > (hgt_ * wid_src)) {
388  x_num = y_num = hgt_;
389  x_denom = y_denom = hgt_src;
390  } else {
391  x_num = y_num = wid_;
392  x_denom = y_denom = wid_src;
393  }
394  } else {
395  x_num = wid_;
396  y_num = hgt_;
397  x_denom = wid_src;
398  y_denom = hgt_src;
399  }
400 
401  // compute offsets needed to center new bmp
402  xoff = (wid_ - ((x_num * wid_src) / x_denom)) / 2;
403  yoff = (hgt_ - ((y_num * hgt_src) / y_denom)) / 2;
404 
405  // scale up
406  if (y_num > y_denom) {
407  for (ydest = yoff; ydest < (hgt_ - yoff); ydest++) {
408  // compute un-scaled y
409  ysrc = static_cast<int>(0.5 + (1.0 * (ydest - yoff) *
410  y_denom / y_num));
411  if (ysrc < 0 || ysrc >= hgt_src) {
412  continue;
413  }
414 
415  for (xdest = xoff; xdest < (wid_ - xoff); xdest++) {
416  // compute un-scaled y
417  xsrc = static_cast<int>(0.5 + (1.0 * (xdest - xoff) *
418  x_denom / x_num));
419  if (xsrc < 0 || xsrc >= wid_src) {
420  continue;
421  }
422 
423  line_buff_[ydest][xdest] =
424  bmp->line_buff_[ysrc + yst_src][xsrc + xst_src];
425  }
426  }
427  } else {
428  // or scale down
429  // scaling down is a bit tricky: we'll accumulate pixels
430  // and then compute the means
431  unsigned int **dest_line_buff = CreateBmpBuffer(wid_, hgt_, 0),
432  **dest_pix_cnt = CreateBmpBuffer(wid_, hgt_, 0);
433 
434  for (ysrc = 0; ysrc < hgt_src; ysrc++) {
435  // compute scaled y
436  ydest = yoff + static_cast<int>(0.5 + (1.0 * ysrc * y_num / y_denom));
437  if (ydest < 0 || ydest >= hgt_) {
438  continue;
439  }
440 
441  for (xsrc = 0; xsrc < wid_src; xsrc++) {
442  // compute scaled y
443  xdest = xoff + static_cast<int>(0.5 + (1.0 * xsrc * x_num / x_denom));
444  if (xdest < 0 || xdest >= wid_) {
445  continue;
446  }
447 
448  dest_line_buff[ydest][xdest] +=
449  bmp->line_buff_[ysrc + yst_src][xsrc + xst_src];
450  dest_pix_cnt[ydest][xdest]++;
451  }
452  }
453 
454  for (ydest = 0; ydest < hgt_; ydest++) {
455  for (xdest = 0; xdest < wid_; xdest++) {
456  if (dest_pix_cnt[ydest][xdest] > 0) {
457  unsigned int pixval =
458  dest_line_buff[ydest][xdest] / dest_pix_cnt[ydest][xdest];
459 
460  line_buff_[ydest][xdest] =
461  (unsigned char) min((unsigned int)255, pixval);
462  }
463  }
464  }
465 
466  // we no longer need these temp buffers
467  FreeBmpBuffer(dest_line_buff);
468  FreeBmpBuffer(dest_pix_cnt);
469  }
470 
471  return true;
472 }
unsigned short wid_
Definition: bmp_8.h:95
unsigned short hgt_
Definition: bmp_8.h:96
unsigned char ** line_buff_
Definition: bmp_8.h:98

◆ Stride()

unsigned short tesseract::Bmp8::Stride ( ) const
inline

Definition at line 49 of file bmp_8.h.

49 { return stride_; }

◆ Width()

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

◆ hgt_

unsigned short tesseract::Bmp8::hgt_
protected

Definition at line 96 of file bmp_8.h.

◆ kConCompAllocChunk

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

Definition at line 100 of file bmp_8.h.

◆ kDeslantAngleCount

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.

◆ line_buff_

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

Definition at line 98 of file bmp_8.h.

◆ wid_

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: