encode.c

来自「稀疏矩阵、链表、图、队列、二叉树、多叉树、排序、遗传算法等的实现」· C语言 代码 · 共 599 行 · 第 1/2 页

C
599
字号
    if (free_bits < 4)
    {
      *t4_ptr++ = 0;
    }
    *t4_ptr++ = 0x80;
    free_bits = PIXELS_PER_OCTET;
    current_output = 0;
  }
  /* otherwise output the code word in the structure        */
  else
  {
    length = code->code_length;
    current_output |=
      ((unsigned long)code->bit_pattern << length);

    while (length >= free_bits)
    {
      current_output >>= free_bits;
      *t4_ptr++ = (unsigned char)(current_output & OCTET_MASK);
      length -= free_bits;
      free_bits = PIXELS_PER_OCTET;
    }

    if (length != 0)
    {
      current_output >>= length;
      free_bits -= length;
    }
  }
  return t4_ptr;
}

/* Function:    CountPixelRun
 *
 * Remarks:     only referenced from inside this source
 *              file so defined with the static keyword
 *              for internal linkage
 *
 * Inputs:      PIXEL_BITS wanted, indicating whether a run
 *              of black or white pixels is wanted
 *
 *              int maximum, indicating the maximum number
 *              of pixels in the current scan_line
 *
 *              FILE *fin, source file to read additional
 *              binary image pixel octets, as needed
 *
 * Returns:     an int, either 0 through 1728 indicating the
 *              length of the run of the specified color pixel
 *              or EOF if end of file or error encountered
 *
 * Description: this function extracts continuous runs of the
 *              selected pixel color from the input file
 */
static int
CountPixelRun(PIXEL_BITS wanted, int maximum, FILE *fin)
{
  int run_count = 0;
  int input;
  static int raw_pixels = 0;
  static int bits_used = 8;
  static int EOF_flag = 0;

  for ( ; ; )
  {
    if (bits_used >= PIXELS_PER_OCTET)
    {
      if (maximum >= 8)
      {
        if (EOF_flag)
        {
          return EOF;
        }
        else if ((input = fgetc(fin)) == EOF)
        {
          EOF_flag = 1;
          break;
        }
        raw_pixels = input & OCTET_MASK;
        bits_used = 0;
      }
      else
      {
        break;
      }
    }

    if (wanted == (raw_pixels & PIXEL_TEST))
    {
      ++run_count;
      ++bits_used;
      --maximum;
      raw_pixels <<= 1;
    }
    else
    {
       break;
    }
  }

  return run_count;
}

/* Function:    EncodeLine
 *
 * Remarks:     only referenced from inside this source
 *              file so defined with the static keyword
 *              for internal linkage
 *
 * Inputs:      unsigned char *t4_out, pointer to at least
 *              T4_BUFFER_SIZE bytes for holding a full row
 *              of T.4 code words generated from the binary
 *              image pixels
 *
 *              FILE *fin, pointer to the source file
 *              of the T.4 encoded image beind decoded
 *
 * Returns:     int:
 *                0 through 975 indicating the number of
 *                unsigned chars in the buffer holding
 *                the T.4 code words for the scan line, or
 *                the standard macro EOF if any errors occur
 *
 * Description: this function is used to construct T.4 code
 *              representing a single 1,728 pixels per scan line
 */
int
EncodeLine(unsigned char *t4_out, FILE *fin)
{
  int scan_count = PIXELS_PER_ROW;
  int run_count;
  unsigned char *t4_ptr = t4_out;
  PIXEL_BITS color = WHITE_PIXEL;

  while (scan_count > 0)
  {
    run_count = CountPixelRun(color, scan_count, fin);
    if (run_count == EOF)
    {
      return EOF;
    }

    if (color == BLACK_PIXEL)
    {
      if (run_count > 63)
      {
        t4_ptr = OutputCodeWord(
          black_makeup + (run_count / 64) - 1,
          t4_ptr);
      }
      t4_ptr = OutputCodeWord(
        black_terminate + (run_count % 64),
        t4_ptr);
      color = WHITE_PIXEL;
    }
    else
    {
      if (run_count > 63)
      {
        t4_ptr = OutputCodeWord(
          white_makeup + (run_count / 64) - 1,
          t4_ptr);
      }
      t4_ptr = OutputCodeWord(
        white_terminate + (run_count % 64),
        t4_ptr);
      color = BLACK_PIXEL;
    }

    scan_count -= run_count;
  }

  t4_ptr = OutputCodeWord(NULL, t4_ptr);
  return (int)(t4_ptr - t4_out);
}

/* Function:    EncodePage
 *
 * Remarks:     only referenced from inside this source
 *              file so defined with the static keyword
 *              for internal linkage
 *
 * Inputs:      FILE *fin, pointer to the source file
 *              of the T.4 encoded image beind decoded
 *
 *              FILE *fout, pointer to destination file
 *              for the decoded binary image
 *
 *              unsigned char *buff, pointer to at least
 *              T4_BUFFER_SIZE bytes for holding a full row
 *              of T.4 code words generated from the binary
 *              image pixels
 *
 *              char *output_name, a copy of argv[2], which
 *              contains the name of the output file, for use
 *              in messages in the event of error
 *
 * Returns:     int:
 *                0 through MAXIMUM_ROWS indicating the
 *                number of T.4 encoded lines written
 *                to the output file if no errors occurred, or
 *                the standard macro EOF if any errors occur
 *
 * Description: this function is used to construct T.4 code
 *              representing an encoded page image,
 *              consisting of 1,728 pixels per scan line
 *              and up to MAXIMUM_ROWS scan lines per
 *              page
 */
static int
EncodePage(FILE *fin, FILE *fout,
           unsigned char *buff,
           char *output_name)
{
  int size;
  int scan_lines;
  size_t written;

  /* write required initial EOL code word to file */
  if (sizeof EOL != fwrite(EOL, 1, sizeof EOL, fout))
  {
     printf(wr_err, output_name);
     return EOF;
  }

  for (scan_lines = 0;  scan_lines< MAXIMUM_ROWS; )
  {
    size = EncodeLine(buff, fin);

    if (size < 0)
    {
       break;
    }
    ++scan_lines;

    written = fwrite(buff, sizeof *buff, size, fout);
    if ((int)written != size)
    {
      printf(wr_err, output_name);
      return EOF;
    }
  }

  /* write the required six consecutive EOL code words  */
  /* to indicate end of page                            */
  if (sizeof EOP != fwrite(EOP, 1, sizeof EOP, fout))
  {
    printf(wr_err, output_name);
    return EOF;
  }

  return scan_lines;
}

int
main(int argc, char **argv)
{
  FILE *ifile, *ofile;
  unsigned char obuff[T4_BUFFER_SIZE];
  int scan_lines;

  /* check command line arguments and open files  */
  if (argc < 3)
  {
    puts("usage: encode binary-input-file, t4-output-file");
    return EXIT_FAILURE;
  }
  else if ((ifile = fopen(argv[1], "rb")) == NULL)
  {
    printf("encode: can't open %s\n", argv[1]);
    return EXIT_FAILURE;
  }
  else if ((ofile = fopen(argv[2], "wb")) == NULL)
  {
    printf("encode: can't make %s\n", argv[2]);
    fclose(ifile);
    return EXIT_FAILURE;
  }

  scan_lines = EncodePage(ifile, ofile, obuff, argv[2]);

  /* close the files  */
  fclose(ifile);
  fclose(ofile);

  if (scan_lines < 0)
  {
    return EXIT_FAILURE;
  }
  else
  {
    /* display results  */
    printf("encoded %d rows from %s to %s\n",
          scan_lines, argv[1], argv[2]);
    return EXIT_SUCCESS;
  }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?