/**
   * デバック用の関数です。 ヒストグラムをラスタに書き出します。
   *
   * @param i_output 書き出し先のラスタオブジェクト 256ピクセル以上の幅があること。
   */
  public void debugDrawHistgramMap(IFLARRaster i_input, IFLARRaster i_output) throws FLARException {
    IFLARBufferReader in_buffer_reader = i_input.getBufferReader();
    IFLARBufferReader out_buffer_reader = i_output.getBufferReader();
    assert (in_buffer_reader.isEqualBufferType(IFLARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
    assert (out_buffer_reader.isEqualBufferType(IFLARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
    FLARIntSize size = i_output.getSize();

    int[][] out_buf = (int[][]) out_buffer_reader.getBuffer();
    // 0で塗りつぶし
    for (int y = 0; y < size.h; y++) {
      for (int x = 0; x < size.w; x++) {
        out_buf[y][x] = 0;
      }
    }
    // ヒストグラムを計算
    int[] histgram = new int[256];
    int threshold = createHistgram(in_buffer_reader, i_input.getSize(), histgram);

    // ヒストグラムの最大値を出す
    int max_v = 0;
    for (int i = 0; i < 255; i++) {
      if (max_v < histgram[i]) {
        max_v = histgram[i];
      }
    }
    // 目盛り
    for (int i = 0; i < size.h; i++) {
      out_buf[i][0] = 128;
      out_buf[i][128] = 128;
      out_buf[i][255] = 128;
    }
    // スケーリングしながら描画
    for (int i = 0; i < 255; i++) {
      out_buf[histgram[i] * (size.h - 1) / max_v][i] = 255;
    }
    // 値
    for (int i = 0; i < size.h; i++) {
      out_buf[i][threshold] = 255;
    }
    return;
  }
  private int createHistgram(IFLARBufferReader i_reader, FLARIntSize i_size, int[] o_histgram)
      throws FLARException {
    int[][] in_buf = (int[][]) i_reader.getBuffer();
    int[] histgram = o_histgram;

    // ヒストグラムを作成
    for (int i = 0; i < 256; i++) {
      histgram[i] = 0;
    }
    int sum = 0;
    for (int y = 0; y < i_size.h; y++) {
      int sum2 = 0;
      for (int x = 0; x < i_size.w; x++) {
        int v = in_buf[y][x];
        histgram[v]++;
        sum2 += v;
      }
      sum = sum + sum2 / i_size.w;
    }
    // 閾値ピクセル数確定
    int th_pixcels = i_size.w * i_size.h * this._persentage / 100;

    // 閾値判定
    int i;
    if (th_pixcels > 0) {
      // 黒点基準
      for (i = 0; i < 254; i++) {
        th_pixcels -= histgram[i];
        if (th_pixcels <= 0) {
          break;
        }
      }
    } else {
      // 白点基準
      for (i = 255; i > 1; i--) {
        th_pixcels += histgram[i];
        if (th_pixcels >= 0) {
          break;
        }
      }
    }
    // 閾値の保存
    return i;
  }
  public void doFilter(IFLARRaster i_input, IFLARRaster i_output) throws FLARException {
    IFLARBufferReader in_buffer_reader = i_input.getBufferReader();
    IFLARBufferReader out_buffer_reader = i_output.getBufferReader();
    assert (in_buffer_reader.isEqualBufferType(IFLARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
    assert (out_buffer_reader.isEqualBufferType(IFLARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
    assert (i_input.getSize().isEqualSize(i_output.getSize()) == true);

    int[][] out_buf = (int[][]) out_buffer_reader.getBuffer();
    int[][] in_buf = (int[][]) in_buffer_reader.getBuffer();

    int bp = 0;
    FLARIntSize size = i_output.getSize();
    for (int y = 1; y < size.h; y++) {
      int prev = 128;
      for (int x = 1; x < size.w; x++) {
        int w = in_buf[y][x];
        out_buf[y][x] = (Math.abs(w - prev) + Math.abs(w - in_buf[y - 1][x])) / 2;
        prev = w;
        bp += 3;
      }
    }
    return;
  }
 public void analyzeRaster(IFLARRaster i_input) throws FLARException {
   final IFLARBufferReader buffer_reader = i_input.getBufferReader();
   assert (buffer_reader.isEqualBufferType(IFLARBufferReader.BUFFERFORMAT_INT2D_GLAY_8));
   int[] histgram = new int[256];
   this._threshold = createHistgram(buffer_reader, i_input.getSize(), histgram);
 }