Tesseract  3.02
tesseract::Bmp8 Class Reference

#include <bmp_8.h>

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

List of all members.

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 43 of file bmp_8.cpp.

    : wid_(wid)
    , hgt_(hgt) {
  line_buff_ = CreateBmpBuffer();
}
tesseract::Bmp8::~Bmp8 ( )

Definition at line 49 of file bmp_8.cpp.

            {
  FreeBmpBuffer(line_buff_);
}

Member Function Documentation

bool tesseract::Bmp8::Clear ( )

Definition at line 133 of file bmp_8.cpp.

                 {
  if (line_buff_ == NULL) {
    return false;
  }

  memset(line_buff_[0], 0xff, stride_ * hgt_ * sizeof(*line_buff_[0]));
  return true;
}
void tesseract::Bmp8::Copy ( int  x,
int  y,
int  wid,
int  hgt,
Bmp8 bmp_dest 
) const [protected]

Definition at line 584 of file bmp_8.cpp.

                                                                          {
  int x_end = min(x_st + wid, static_cast<int>(wid_)),
  y_end = min(y_st + hgt, static_cast<int>(hgt_));

  for (int y = y_st; y < y_end; y++) {
    for (int x = x_st; x < x_end; x++) {
      bmp_dest->line_buff_[y - y_st][x - x_st] =
          line_buff_[y][x];
    }
  }
}
void tesseract::Bmp8::Crop ( int *  xst_src,
int *  yst_src,
int *  wid,
int *  hgt 
) [protected]

Definition at line 354 of file bmp_8.cpp.

                                                      {
  (*xst) = 0;
  (*yst) = 0;

  int xend = wid_ - 1;
  int yend = hgt_ - 1;

  while ((*xst) < (wid_ - 1) && (*xst) <= xend) {
    // column is not empty
    if (!IsBlankColumn((*xst))) {
      break;
    }
    (*xst)++;
  }

  while (xend > 0 && xend >= (*xst)) {
    // column is not empty
    if (!IsBlankColumn(xend)) {
      break;
    }
    xend--;
  }

  while ((*yst) < (hgt_ - 1) && (*yst) <= yend) {
    // column is not empty
    if (!IsBlankRow((*yst))) {
      break;
    }
    (*yst)++;
  }

  while (yend > 0 && yend >= (*yst)) {
    // column is not empty
    if (!IsBlankRow(yend)) {
      break;
    }
    yend--;
  }

  (*wid) = xend - (*xst) + 1;
  (*hgt) = yend - (*yst) + 1;
}
bool tesseract::Bmp8::Deslant ( )

Definition at line 801 of file bmp_8.cpp.

                   {
  int x;
  int y;
  int des_x;
  int des_y;
  int ang_idx;
  int best_ang;
  int min_des_x;
  int max_des_x;
  int des_wid;

  // only do deslanting if bitmap is wide enough
  // otherwise it slant estimate might not be reliable
  if (wid_ < (hgt_ * 2)) {
    return true;
  }

  // compute tan table if needed
  if (tan_table_ == NULL && !ComputeTanTable()) {
    return false;
  }

  // compute min and max values for x after deslant
  min_des_x = static_cast<int>(0.5f + (hgt_ - 1) * tan_table_[0]);
  max_des_x = (wid_ - 1) +
      static_cast<int>(0.5f + (hgt_ - 1) * tan_table_[kDeslantAngleCount - 1]);

  des_wid = max_des_x - min_des_x + 1;

  // alloc memory for histograms
  int **angle_hist = new int*[kDeslantAngleCount];
  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
    angle_hist[ang_idx] = new int[des_wid];
    if (angle_hist[ang_idx] == NULL) {
      delete[] angle_hist;
      return false;
    }
    memset(angle_hist[ang_idx], 0, des_wid * sizeof(*angle_hist[ang_idx]));
  }

  // compute histograms
  for (y = 0; y < hgt_; y++) {
    for (x = 0; x < wid_; x++) {
      // find a non-bkgrnd pixel
      if (line_buff_[y][x] != 0xff) {
        des_y = hgt_ - y - 1;
        // stamp all histograms
        for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
          des_x = x + static_cast<int>(0.5f + (des_y * tan_table_[ang_idx]));
          if (des_x >= min_des_x && des_x <= max_des_x) {
            angle_hist[ang_idx][des_x - min_des_x]++;
          }
        }
      }
    }
  }

  // find the histogram with the lowest entropy
  float entropy;
  double best_entropy = 0.0f;
  double norm_val;

  best_ang = -1;
  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
    entropy = 0.0f;

    for (x = min_des_x; x <= max_des_x; x++) {
      if (angle_hist[ang_idx][x - min_des_x] > 0) {
        norm_val = (1.0f * angle_hist[ang_idx][x - min_des_x] / hgt_);
        entropy += (-1.0f * norm_val * log(norm_val));
      }
    }

    if (best_ang == -1 || entropy < best_entropy) {
      best_ang = ang_idx;
      best_entropy = entropy;
    }

    // free the histogram
    delete[] angle_hist[ang_idx];
  }
  delete[] angle_hist;

  // deslant
  if (best_ang != -1) {
    unsigned char **dest_lines;
    int old_wid = wid_;

    // create a new buffer
    wid_ = des_wid;
    dest_lines = CreateBmpBuffer();
    if (dest_lines == NULL) {
      return false;
    }

    for (y = 0; y < hgt_; y++) {
      for (x = 0; x < old_wid; x++) {
        // find a non-bkgrnd pixel
        if (line_buff_[y][x] != 0xff) {
          des_y = hgt_ - y - 1;
          // compute new pos
          des_x = x + static_cast<int>(0.5f + (des_y * tan_table_[best_ang]));
          dest_lines[y][des_x - min_des_x] = 0;
        }
      }
    }

    // free old buffer
    FreeBmpBuffer(line_buff_);
    line_buff_ = dest_lines;
  }
  return true;
}
ConComp ** tesseract::Bmp8::FindConComps ( int *  concomp_cnt,
int  min_size 
) const

Definition at line 611 of file bmp_8.cpp.

                                                                  {
  (*concomp_cnt) = 0;

  unsigned int **out_bmp_array = CreateBmpBuffer(wid_, hgt_, 0);
  if (out_bmp_array == NULL) {
    fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not allocate "
            "bitmap array\n");
    return NULL;
  }

  // listed of connected components
  ConComp **concomp_array = NULL;

  int x;
  int y;
  int x_nbr;
  int y_nbr;
  int concomp_id;
  int alloc_concomp_cnt = 0;

  // neighbors to check
  const int nbr_cnt = 4;

  // relative coordinates of nbrs
  int x_del[nbr_cnt] = {-1, 0, 1, -1},
    y_del[nbr_cnt] = {-1, -1, -1, 0};


  for (y = 0; y < hgt_; y++) {
    for (x = 0; x < wid_; x++) {
      // is this a foreground pix
      if (line_buff_[y][x] != 0xff) {
        int master_concomp_id = 0;
        ConComp *master_concomp = NULL;

        // checkout the nbrs
        for (int nbr = 0; nbr < nbr_cnt; nbr++) {
          x_nbr = x + x_del[nbr];
          y_nbr = y + y_del[nbr];

          if (x_nbr < 0 || y_nbr < 0 || x_nbr >= wid_ || y_nbr >= hgt_) {
            continue;
          }

          // is this nbr a foreground pix
          if (line_buff_[y_nbr][x_nbr] != 0xff) {
            // get its concomp ID
            concomp_id = out_bmp_array[y_nbr][x_nbr];

            // this should not happen
            if (concomp_id < 1 || concomp_id > alloc_concomp_cnt) {
              fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): illegal "
                      "connected component id: %d\n", concomp_id);
              FreeBmpBuffer(out_bmp_array);
              delete []concomp_array;
              return NULL;
            }

            // if we has previously found a component then merge the two
            // and delete the latest one
            if (master_concomp != NULL && concomp_id != master_concomp_id) {
              // relabel all the pts
              ConCompPt *pt_ptr = concomp_array[concomp_id - 1]->Head();
              while (pt_ptr != NULL) {
                out_bmp_array[pt_ptr->y()][pt_ptr->x()] = master_concomp_id;
                pt_ptr = pt_ptr->Next();
              }

              // merge the two concomp
              if (!master_concomp->Merge(concomp_array[concomp_id - 1])) {
                fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
                        "merge connected component: %d\n", concomp_id);
                FreeBmpBuffer(out_bmp_array);
                delete []concomp_array;
                return NULL;
              }

              // delete the merged concomp
              delete concomp_array[concomp_id - 1];
              concomp_array[concomp_id - 1] = NULL;
            } else {
              // this is the first concomp we encounter
              master_concomp_id = concomp_id;
              master_concomp = concomp_array[master_concomp_id - 1];

              out_bmp_array[y][x] = master_concomp_id;

              if (!master_concomp->Add(x, y)) {
                fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
                        "add connected component (%d,%d)\n", x, y);
                FreeBmpBuffer(out_bmp_array);
                delete []concomp_array;
                return NULL;
              }
            }
          }  // foreground nbr
        }  // nbrs

        // if there was no foreground pix, then create a new concomp
        if (master_concomp == NULL) {
          master_concomp = new ConComp();
          if (master_concomp == NULL || master_concomp->Add(x, y) == false) {
            fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
                    "allocate or add a connected component\n");
            FreeBmpBuffer(out_bmp_array);
            delete []concomp_array;
            return NULL;
          }

          // extend the list of concomps if needed
          if ((alloc_concomp_cnt % kConCompAllocChunk) == 0) {
            ConComp **temp_con_comp =
                new ConComp *[alloc_concomp_cnt + kConCompAllocChunk];
            if (temp_con_comp == NULL) {
              fprintf(stderr, "Cube ERROR (Bmp8::FindConComps): could not "
                      "extend array of connected components\n");
              FreeBmpBuffer(out_bmp_array);
              delete []concomp_array;
              return NULL;
            }

            if (alloc_concomp_cnt > 0) {
              memcpy(temp_con_comp, concomp_array,
                     alloc_concomp_cnt * sizeof(*concomp_array));

              delete []concomp_array;
            }

            concomp_array = temp_con_comp;
          }

          concomp_array[alloc_concomp_cnt++] = master_concomp;
          out_bmp_array[y][x] = alloc_concomp_cnt;
        }
      }  // foreground pix
    }  // x
  }  // y

  // free the concomp bmp
  FreeBmpBuffer(out_bmp_array);

  if (alloc_concomp_cnt > 0 && concomp_array != NULL) {
    // scan the array of connected components and color
    // the o/p buffer with the corresponding concomps
    (*concomp_cnt) = 0;
    ConComp *concomp = NULL;

    for (int concomp_idx = 0; concomp_idx < alloc_concomp_cnt; concomp_idx++) {
      concomp = concomp_array[concomp_idx];

      // found a concomp
      if (concomp != NULL) {
        // add the connected component if big enough
        if (concomp->PtCnt() > min_size) {
          concomp->SetLeftMost(true);
          concomp->SetRightMost(true);
          concomp->SetID((*concomp_cnt));
          concomp_array[(*concomp_cnt)++] = concomp;
        } else {
          delete concomp;
        }
      }
    }
  }

  return concomp_array;
}
float tesseract::Bmp8::ForegroundRatio ( ) const

Definition at line 976 of file bmp_8.cpp.

                                  {
  int fore_cnt = 0;

  if (wid_ <= 0 || hgt_ <= 0) {
    return 1.0;
  }

  for (int y = 0; y < hgt_; y++) {
    for (int x = 0; x < wid_; x++) {
      fore_cnt += (line_buff_[y][x] == 0xff ? 0 : 1);
    }
  }

  return (1.0 * (fore_cnt / hgt_) / wid_);
}
Bmp8 * tesseract::Bmp8::FromCharDumpFile ( CachedFile fp) [static]

Reimplemented in tesseract::CharSamp.

Definition at line 222 of file bmp_8.cpp.

                                            {
  // create a Bmp8 object
  Bmp8 *bmp_obj = new Bmp8(0, 0);
  if (bmp_obj == NULL) {
    return NULL;
  }

  if (bmp_obj->LoadFromCharDumpFile(fp) == false) {
    delete bmp_obj;
  }

  return bmp_obj;
}
Bmp8 * tesseract::Bmp8::FromCharDumpFile ( FILE *  fp) [static]

Reimplemented in tesseract::CharSamp.

Definition at line 319 of file bmp_8.cpp.

                                      {
  // create a Bmp8 object
  Bmp8 *bmp_obj = new Bmp8(0, 0);
  if (bmp_obj == NULL) {
    return NULL;
  }

  if (bmp_obj->LoadFromCharDumpFile(fp) == false) {
    delete bmp_obj;
  }

  return bmp_obj;
}
unsigned short tesseract::Bmp8::Height ( ) const [inline]

Definition at line 50 of file bmp_8.h.

{ return hgt_; }
bool tesseract::Bmp8::HorizontalDeslant ( double *  deslant_angle)

Definition at line 993 of file bmp_8.cpp.

                                                  {
  int x;
  int y;
  int des_y;
  int ang_idx;
  int best_ang;
  int min_des_y;
  int max_des_y;
  int des_hgt;

  // compute tan table if necess.
  if (tan_table_ == NULL && !ComputeTanTable()) {
    return false;
  }

  // compute min and max values for x after deslant
  min_des_y = min(0, static_cast<int>((wid_ - 1) * tan_table_[0]));
  max_des_y = (hgt_ - 1) +
      max(0, static_cast<int>((wid_ - 1) * tan_table_[kDeslantAngleCount - 1]));

  des_hgt = max_des_y - min_des_y + 1;

  // alloc memory for histograms
  int **angle_hist = new int*[kDeslantAngleCount];
  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
    angle_hist[ang_idx] = new int[des_hgt];
    if (angle_hist[ang_idx] == NULL) {
      delete[] angle_hist;
      return false;
    }
    memset(angle_hist[ang_idx], 0, des_hgt * sizeof(*angle_hist[ang_idx]));
  }

  // compute histograms
  for (y = 0; y < hgt_; y++) {
    for (x = 0; x < wid_; x++) {
      // find a non-bkgrnd pixel
      if (line_buff_[y][x] != 0xff) {
        // stamp all histograms
        for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
          des_y = y - static_cast<int>(x * tan_table_[ang_idx]);
          if (des_y >= min_des_y && des_y <= max_des_y) {
            angle_hist[ang_idx][des_y - min_des_y]++;
          }
        }
      }
    }
  }

  // find the histogram with the lowest entropy
  float entropy;
  float best_entropy =  0.0f;
  float norm_val;

  best_ang = -1;
  for (ang_idx = 0; ang_idx < kDeslantAngleCount; ang_idx++) {
    entropy = 0.0f;

    for (y = min_des_y; y <= max_des_y; y++) {
      if (angle_hist[ang_idx][y - min_des_y] > 0) {
        norm_val = (1.0f * angle_hist[ang_idx][y - min_des_y] / wid_);
        entropy += (-1.0f * norm_val * log(norm_val));
      }
    }

    if (best_ang == -1 || entropy < best_entropy) {
      best_ang = ang_idx;
      best_entropy = entropy;
    }

    // free the histogram
    delete[] angle_hist[ang_idx];
  }
  delete[] angle_hist;

  (*deslant_angle) = 0.0;

  // deslant
  if (best_ang != -1) {
    unsigned char **dest_lines;
    int old_hgt = hgt_;

    // create a new buffer
    min_des_y = min(0, static_cast<int>((wid_ - 1) * -tan_table_[best_ang]));
    max_des_y = (hgt_ - 1) +
        max(0, static_cast<int>((wid_ - 1) * -tan_table_[best_ang]));
    hgt_ = max_des_y - min_des_y + 1;
    dest_lines = CreateBmpBuffer();
    if (dest_lines == NULL) {
      return false;
    }

    for (y = 0; y < old_hgt; y++) {
      for (x = 0; x < wid_; x++) {
        // find a non-bkgrnd pixel
        if (line_buff_[y][x] != 0xff) {
          // compute new pos
          des_y = y - static_cast<int>((x * tan_table_[best_ang]));
          dest_lines[des_y - min_des_y][x] = 0;
        }
      }
    }

    // free old buffer
    FreeBmpBuffer(line_buff_);
    line_buff_ = dest_lines;

    (*deslant_angle) = kMinDeslantAngle + (best_ang * kDeslantAngleDelta);
  }

  return true;
}
int * tesseract::Bmp8::HorizontalHistogram ( ) const

Definition at line 1129 of file bmp_8.cpp.

                                     {
  int *hist = new int[hgt_];
  if (hist == NULL) {
    return NULL;
  }

  // compute histograms
  for (int y = 0; y < hgt_; y++) {
    hist[y] = 0;

    for (int x = 0; x < wid_; x++) {
      // find a non-bkgrnd pixel
      if (line_buff_[y][x] != 0xff) {
        hist[y]++;
      }
    }
  }

  return hist;
}
bool tesseract::Bmp8::IsBlankColumn ( int  x) const [protected]

Definition at line 333 of file bmp_8.cpp.

                                    {
  for (int y = 0; y < hgt_; y++) {
    if (line_buff_[y][x] != 0xff) {
      return false;
    }
  }

  return true;
}
bool tesseract::Bmp8::IsBlankRow ( int  y) const [protected]

Definition at line 343 of file bmp_8.cpp.

                                 {
  for (int x = 0; x < wid_; x++) {
    if (line_buff_[y][x] != 0xff) {
      return false;
    }
  }

  return true;
}
bool tesseract::Bmp8::IsIdentical ( Bmp8 pBmp) const

Definition at line 596 of file bmp_8.cpp.

                                       {
  if (wid_ != pBmp->wid_ || hgt_ != pBmp->hgt_) {
    return false;
  }

  for (int y = 0; y < hgt_; y++) {
    if (memcmp(line_buff_[y], pBmp->line_buff_[y], wid_) != 0) {
      return false;
    }
  }

  return true;
}
bool tesseract::Bmp8::LoadFromCharDumpFile ( CachedFile fp) [protected]

Definition at line 142 of file bmp_8.cpp.

                                              {
  unsigned short wid;
  unsigned short hgt;
  unsigned short x;
  unsigned short y;
  int buf_size;
  int pix;
  int pix_cnt;
  unsigned int val32;
  unsigned char *buff;

  // read and check 32 bit marker
  if (fp->Read(&val32, sizeof(val32)) != sizeof(val32)) {
    return false;
  }

  if (val32 != kMagicNumber) {
    return false;
  }

  // read wid and hgt
  if (fp->Read(&wid, sizeof(wid)) != sizeof(wid)) {
    return false;
  }

  if (fp->Read(&hgt, sizeof(hgt)) != sizeof(hgt)) {
    return false;
  }

  // read buf size
  if (fp->Read(&buf_size, sizeof(buf_size)) != sizeof(buf_size)) {
    return false;
  }

  // validate buf size: for now, only 3 channel (RBG) is supported
  pix_cnt = wid * hgt;
  if (buf_size != (3 * pix_cnt)) {
    return false;
  }

  // alloc memory & read the 3 channel buffer
  buff = new unsigned char[buf_size];
  if (buff == NULL) {
    return false;
  }

  if (fp->Read(buff, buf_size) != buf_size) {
    delete []buff;
    return false;
  }

  // create internal buffers
  wid_ = wid;
  hgt_ = hgt;

  line_buff_ = CreateBmpBuffer();
  if (line_buff_ == NULL) {
    delete []buff;
    return false;
  }

  // copy the data
  for (y = 0, pix = 0; y < hgt_; y++) {
    for (x = 0; x < wid_; x++, pix += 3) {
      // for now we only support gray scale,
      // so we expect R = G = B, it this is not the case, bail out
      if  (buff[pix] != buff[pix + 1] || buff[pix] != buff[pix + 2]) {
        delete []buff;
        return false;
      }
      line_buff_[y][x] = buff[pix];
    }
  }

  // delete temp buffer
  delete[]buff;

  return true;
}
bool tesseract::Bmp8::LoadFromCharDumpFile ( FILE *  fp) [protected]

Definition at line 236 of file bmp_8.cpp.

                                        {
  unsigned short wid;
  unsigned short hgt;
  unsigned short x;
  unsigned short y;
  int buf_size;
  int pix;
  int pix_cnt;
  unsigned int val32;
  unsigned char *buff;

  // read and check 32 bit marker
  if (fread(&val32, 1, sizeof(val32), fp) != sizeof(val32)) {
    return false;
  }

  if (val32 != kMagicNumber) {
    return false;
  }

  // read wid and hgt
  if (fread(&wid, 1, sizeof(wid), fp) != sizeof(wid)) {
    return false;
  }

  if (fread(&hgt, 1, sizeof(hgt), fp) != sizeof(hgt)) {
    return false;
  }

  // read buf size
  if (fread(&buf_size, 1, sizeof(buf_size), fp) != sizeof(buf_size)) {
    return false;
  }

  // validate buf size: for now, only 3 channel (RBG) is supported
  pix_cnt = wid * hgt;
  if (buf_size != (3 * pix_cnt)) {
    return false;
  }

  // alloc memory & read the 3 channel buffer
  buff = new unsigned char[buf_size];
  if (buff == NULL) {
    return false;
  }

  if (fread(buff, 1, buf_size, fp) != buf_size) {
    delete []buff;
    return false;
  }

  // create internal buffers
  wid_ = wid;
  hgt_ = hgt;

  line_buff_ = CreateBmpBuffer();
  if (line_buff_ == NULL) {
    delete []buff;
    return false;
  }

  // copy the data
  for (y = 0, pix = 0; y < hgt_; y++) {
    for (x = 0; x < wid_; x++, pix += 3) {
      // for now we only support gray scale,
      // so we expect R = G = B, it this is not the case, bail out
      if  ( buff[pix] != buff[pix + 1] ||
            buff[pix] != buff[pix + 2]
          ) {
        delete []buff;
        return false;
          }

          line_buff_[y][x] = buff[pix];
    }
  }

  // delete temp buffer
  delete[]buff;

  return true;
}
bool tesseract::Bmp8::LoadFromCharDumpFile ( unsigned char **  raw_data) [protected]

Definition at line 916 of file bmp_8.cpp.

                                                            {
  unsigned short wid;
  unsigned short hgt;
  unsigned short x;
  unsigned short y;
  unsigned char *raw_data = (*raw_data_ptr);
  int buf_size;
  int pix;
  unsigned int val32;

  // read and check 32 bit marker
  memcpy(&val32, raw_data, sizeof(val32));
  raw_data += sizeof(val32);

  if (val32 != kMagicNumber) {
    return false;
  }

  // read wid and hgt
  memcpy(&wid, raw_data, sizeof(wid));
  raw_data += sizeof(wid);

  memcpy(&hgt, raw_data, sizeof(hgt));
  raw_data += sizeof(hgt);

  // read buf size
  memcpy(&buf_size, raw_data, sizeof(buf_size));
  raw_data += sizeof(buf_size);

  // validate buf size: for now, only 3 channel (RBG) is supported
  if (buf_size != (3 * wid * hgt)) {
    return false;
  }

  wid_ = wid;
  hgt_ = hgt;

  line_buff_ = CreateBmpBuffer();
  if (line_buff_ == NULL) {
    return false;
  }

  // copy the data
  for (y = 0, pix = 0; y < hgt_; y++) {
    for (x = 0; x < wid_; x++, pix += 3) {
      // for now we only support gray scale,
      // so we expect R = G = B, it this is not the case, bail out
      if  (raw_data[pix] != raw_data[pix + 1] ||
           raw_data[pix] != raw_data[pix + 2]) {
        return false;
      }

      line_buff_[y][x] = raw_data[pix];
    }
  }

  (*raw_data_ptr) = raw_data + buf_size;
  return true;
}
bool tesseract::Bmp8::LoadFromRawData ( unsigned char *  data) [protected]

Definition at line 510 of file bmp_8.cpp.

                                              {
  unsigned char *pline_data = data;

  // copy the data
  for (int y = 0; y < hgt_; y++, pline_data += wid_) {
    memcpy(line_buff_[y], pline_data, wid_ * sizeof(*pline_data));
  }

  return true;
}
float tesseract::Bmp8::MeanHorizontalHistogramEntropy ( ) const

Definition at line 1106 of file bmp_8.cpp.

                                                 {
  float entropy = 0.0f;

  // compute histograms
  for (int y = 0; y < hgt_; y++) {
    int pix_cnt = 0;

    for (int x = 0; x < wid_; x++) {
      // find a non-bkgrnd pixel
      if (line_buff_[y][x] != 0xff) {
        pix_cnt++;
      }
    }

    if (pix_cnt > 0) {
      float norm_val = (1.0f * pix_cnt / wid_);
      entropy += (-1.0f * norm_val * log(norm_val));
    }
  }

  return entropy / hgt_;
}
unsigned char* tesseract::Bmp8::RawData ( ) const [inline]

Definition at line 51 of file bmp_8.h.

                                        {
    return (line_buff_ == NULL ? NULL : line_buff_[0]);
  }
bool tesseract::Bmp8::SaveBmp2CharDumpFile ( FILE *  fp) const [protected]

Definition at line 521 of file bmp_8.cpp.

                                              {
  unsigned short wid;
  unsigned short hgt;
  unsigned short x;
  unsigned short y;
  int buf_size;
  int pix;
  int pix_cnt;
  unsigned int val32;
  unsigned char *buff;

  // write and check 32 bit marker
  val32 = kMagicNumber;
  if (fwrite(&val32, 1, sizeof(val32), fp) != sizeof(val32)) {
    return false;
  }

  // write wid and hgt
  wid = wid_;
  if (fwrite(&wid, 1, sizeof(wid), fp) != sizeof(wid)) {
    return false;
  }

  hgt = hgt_;
  if (fwrite(&hgt, 1, sizeof(hgt), fp) != sizeof(hgt)) {
    return false;
  }

  // write buf size
  pix_cnt = wid * hgt;
  buf_size = 3 * pix_cnt;
  if (fwrite(&buf_size, 1, sizeof(buf_size), fp) != sizeof(buf_size)) {
    return false;
  }

  // alloc memory & write the 3 channel buffer
  buff = new unsigned char[buf_size];
  if (buff == NULL) {
    return false;
  }

  // copy the data
  for (y = 0, pix = 0; y < hgt_; y++) {
    for (x = 0; x < wid_; x++, pix += 3) {
      buff[pix] =
      buff[pix + 1] =
      buff[pix + 2] = line_buff_[y][x];
    }
  }

  if (fwrite(buff, 1, buf_size, fp) != buf_size) {
    delete []buff;
    return false;
  }

  // delete temp buffer
  delete[]buff;

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

Definition at line 399 of file bmp_8.cpp.

                                              {
  int x_num;
  int x_denom;
  int y_num;
  int y_denom;
  int xoff;
  int yoff;
  int xsrc;
  int ysrc;
  int xdest;
  int ydest;
  int xst_src = 0;
  int yst_src = 0;
  int xend_src = bmp->wid_ - 1;
  int yend_src = bmp->hgt_ - 1;
  int wid_src;
  int hgt_src;

  // src dimensions
  wid_src = xend_src - xst_src + 1,
  hgt_src = yend_src - yst_src + 1;

  // scale to maintain aspect ratio if required
  if (isotropic) {
    if ((wid_ * hgt_src) > (hgt_ * wid_src)) {
      x_num = y_num = hgt_;
      x_denom = y_denom = hgt_src;
    } else {
      x_num = y_num = wid_;
      x_denom = y_denom = wid_src;
    }
  } else {
    x_num = wid_;
    y_num = hgt_;
    x_denom = wid_src;
    y_denom = hgt_src;
  }

  // compute offsets needed to center new bmp
  xoff = (wid_ - ((x_num * wid_src) / x_denom)) / 2;
  yoff = (hgt_ - ((y_num * hgt_src) / y_denom)) / 2;

  // scale up
  if (y_num > y_denom) {
    for (ydest = yoff; ydest < (hgt_ - yoff); ydest++) {
      // compute un-scaled y
      ysrc = static_cast<int>(0.5 + (1.0 * (ydest - yoff) *
          y_denom / y_num));
      if (ysrc < 0 || ysrc >= hgt_src) {
        continue;
      }

      for (xdest = xoff; xdest < (wid_ - xoff); xdest++) {
        // compute un-scaled y
        xsrc = static_cast<int>(0.5 + (1.0 * (xdest - xoff) *
            x_denom / x_num));
        if (xsrc < 0 || xsrc >= wid_src) {
          continue;
        }

        line_buff_[ydest][xdest] =
            bmp->line_buff_[ysrc + yst_src][xsrc + xst_src];
      }
    }
  } else {
    // or scale down
    // scaling down is a bit tricky: we'll accumulate pixels
    // and then compute the means
    unsigned int **dest_line_buff = CreateBmpBuffer(wid_, hgt_, 0),
      **dest_pix_cnt =  CreateBmpBuffer(wid_, hgt_, 0);

    for (ysrc = 0; ysrc < hgt_src; ysrc++) {
      // compute scaled y
      ydest = yoff + static_cast<int>(0.5 + (1.0 * ysrc * y_num / y_denom));
      if (ydest < 0 || ydest >= hgt_) {
        continue;
      }

      for (xsrc = 0; xsrc < wid_src; xsrc++) {
        // compute scaled y
        xdest = xoff + static_cast<int>(0.5 + (1.0 * xsrc * x_num / x_denom));
        if (xdest < 0 || xdest >= wid_) {
          continue;
        }

        dest_line_buff[ydest][xdest] +=
            bmp->line_buff_[ysrc + yst_src][xsrc + xst_src];
        dest_pix_cnt[ydest][xdest]++;
      }
    }

    for (ydest = 0; ydest < hgt_; ydest++) {
      for (xdest = 0; xdest < wid_; xdest++) {
        if (dest_pix_cnt[ydest][xdest] > 0) {
          unsigned int pixval =
              dest_line_buff[ydest][xdest] / dest_pix_cnt[ydest][xdest];

          line_buff_[ydest][xdest] =
              (unsigned char) min((unsigned int)255, pixval);
        }
      }
    }

    // we no longer need these temp buffers
    FreeBmpBuffer(dest_line_buff);
    FreeBmpBuffer(dest_pix_cnt);
  }

  return true;
}
unsigned short tesseract::Bmp8::Stride ( ) const [inline]

Definition at line 49 of file bmp_8.h.

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

Definition at line 48 of file bmp_8.h.

{ return wid_; }

Member Data Documentation

unsigned short tesseract::Bmp8::hgt_ [protected]

Definition at line 96 of file bmp_8.h.

const int tesseract::Bmp8::kConCompAllocChunk = 16 [static, protected]

Definition at line 100 of file bmp_8.h.

const int tesseract::Bmp8::kDeslantAngleCount [static, protected]
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: