⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compress.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  *num_cols = cols;
  *num_planes = planes;
  return(fp);
}

/*****************************************************************************/
/* STATIC                       read_image_line                              */
/*****************************************************************************/

static void
  read_image_line(ifc_int *buf, FILE *fp, int samples, int num_planes)
{
  int c, elts;
  ifc_int *dp, val, shift;
  unsigned char *sp;

  elts = samples * num_planes;
  shift = STD_NOMINAL_RANGE_BITS - 8;
  fread(buf,1,(size_t) elts,fp);
  sp = ((unsigned char *) buf) + elts;
  dp = buf + elts;
  for (c=elts; c > 0; c--)
    {
      val = (ifc_int)(*(--sp));
      val -= 128;
      val <<= shift;
      *(--dp) = val;
    }
}

/*****************************************************************************/
/* STATIC                         write_word                                 */
/*****************************************************************************/

static void
  write_word(FILE *fp, int word, int num_bytes)

 /* Writes the value represented by `word' into the supplied file, using only
    the `num_bytes' least significant bytes. */

{
  int byte;

  for (; num_bytes > 0; num_bytes--, word >>= 8)
    {
      byte = word & ~((-1)<<8);
      fputc(byte,fp);
    }
}

/*****************************************************************************/
/* STATIC                    open_output_bitstream                           */
/*****************************************************************************/

static FILE *
  open_output_bitstream(int argc, char *argv[], int num_levels,
                        int filter_set, int filter_flags, int coder_profile,
                        int max_bitplanes, int num_components,
                        int component_rows[], int component_cols[],
                        unsigned short int component_fixed_steps[],
                        int header_size)

 /* Parses the command line arguments to determine the name of the output
    file and opens the file, writing a small header to ensure that the
    decompressor can recover the key configuration parameters specified via
    all but the first two arguments.  The `header_size' argument
    identifies the number of bytes which should be allocated for the
    header.  The size of the header is actually included in the header so
    that empty space can be reserved.  If the actual header size exceeds the
    amount of space which is reserved, an error will be generated. */

{
  int comp, i, tmp, header_bytes;
  int level_rows[16], level_cols[16];
  char *name;
  FILE *fp;

  for (name=NULL, i=1; i < (argc-1); i++)
    if (strcmp(argv[i],"-o") == 0)
      {
        name = argv[i+1];
        argv[i] = argv[i+1] = "";
      }
  if (name == NULL)
    {
      fprintf(stderr,"Must supply output file name via `-o' switch!\n");
      exit(-1);
    }
  fp = local_fopen(name,"wb");
  if (fp == NULL)
    {
      fprintf(stderr,"Cannot open output file, \"%s\"!\n",name);
      exit(-1);
    }

  header_bytes = 0;

  /* Write magic string and header length specifier. */

  fprintf(fp,"JPLB"); /* Should change this magic string later. */
  header_bytes += 4;
  write_word(fp,header_size,2); header_bytes += 2;

  /* Write num levels (4 lsbs -> original levels; 4 msbs -> actual levels). */

  assert(num_levels < 16);
  tmp = num_levels | (num_levels<<4);
  write_word(fp,tmp,1); header_bytes += 1;

  /* Write filter info. */

  assert((filter_set < 16) && (filter_flags < 16));
  tmp = filter_set | (filter_flags<<4);
  write_word(fp,tmp,1); header_bytes += 1;

  /* Write profile flags. */

  assert(coder_profile < 256);
  write_word(fp,coder_profile,1); header_bytes += 1;

  /* Write max bit-planes. */

  assert(max_bitplanes < 32);
  write_word(fp,max_bitplanes,1); header_bytes += 1;

  /* Write num components. */

  assert(num_components < MAX_COMPONENTS);
  write_word(fp,num_components,1); header_bytes += 1;

  for (comp=0; comp < num_components; comp++)
    {
      int num_rows, num_cols;

      /* Write dimensions, building up from base (LL band) dimensions. */

      num_rows = component_rows[comp];
      num_cols = component_cols[comp];
      for (i=num_levels-1; i >= 0; i--)
        {
          level_rows[i] = num_rows;
          level_cols[i] = num_cols;
          num_rows = (num_rows+1)>>1;
          num_cols = (num_cols+1)>>1;
        }
      if ((num_rows >= (1<<16)) || (num_cols >= (1<<16)))
        {
          fprintf(stderr,"You must use a wavelet decomposition with more "
                  "resolution levels\n  with such a large image!\n");
          exit(-1);
        }
      write_word(fp,num_rows,2); header_bytes += 2;
      write_word(fp,num_cols,2); header_bytes += 2;
      for (tmp=0, i=0; i < num_levels; i++)
        {
          tmp |= (level_rows[i] & 1) << (2*i);
          tmp |= (level_cols[i] & 1) << (2*i+1);
        }
      i = (num_levels+3) >> 2; /* Number of bytes to represent level info. */
      write_word(fp,tmp,i); header_bytes += i;
      
      /* Write base quantization step. */

      tmp = component_fixed_steps[comp];
      write_word(fp,tmp,2); header_bytes += 2;
    }

  /* Pad header to stated size. */

  while (header_bytes < header_size)
    {
      write_word(fp,0,1);
      header_bytes++;
    }
  if (header_size < header_bytes)
    {
      fprintf(stderr,"Header required at least %d bytes,\n"
              "  but only %d bytes were reserved!\n",
              header_bytes,header_size);
      exit(-1);
    }
  return(fp);
}

/*****************************************************************************/
/*                                   main                                    */
/*****************************************************************************/

int
  main(int argc, char *argv[])
{
  char **copy_argv;
  int num_levels, num_rows, num_cols, num_components, verbose;
  int filter_set, filter_flags;
  char *filter_id, *local_filter_name, filter_id_buf[2];
  int required_profile, supported_profile;
  int header_bytes, base_header_bytes, max_bytes, excess_bytes;
  int iterations, max_iterations, final_iteration;
  int found_min_step, found_max_step;
  float base_step, min_step, max_step, max_bpp;
  int component_rows[3], component_cols[3];
  float component_base_steps[3];
  unsigned short int component_fixed_steps[3];
  char *component_ids[3];
  int component_flags[3];
  FILE *image_fp, *bitstream_fp;
  ifc_int *interleaved_line, *line_buf;
  int r, n;

  filter_info_ref info;
  analysis_ref analysis;
  quantizer_ref quantizer;
  encoder_ref encoder;
  bitstream_sink_ref bitstream;

  /* Set default compression parameters. */

  verbose = 1;
  filter_set = 0; /* 7/9 filters. */
  local_filter_name = NULL;
  filter_flags = 0; /* No special filter flags. */
  header_bytes = 0;
  base_header_bytes = 20; /* File header size can be explicitly controlled. */
  num_levels = 5;
  required_profile = 0;
  max_bpp = 2.0F;
  base_step = 1.0F / 128.0F; /* Small power of 2 might be good default. */
  max_iterations = 0; /* No iteration. */

  /* Modify default parameters based on command-line switches. */

  if (argc == 1)
    {
      print_usage(base_header_bytes,num_levels,required_profile,max_bpp,
                  base_step,max_iterations,argv[0],stderr);
      return(-1);
    }
  for (r=1; r < argc; r++)
    if (strcmp(argv[r],"-u") == 0)
      { /* Allow usage statements to be printed to a file or other stdout. */
        FILE *fp;

        fp = stderr;
        r++;
        if ((r < argc) &&
            (((argv[r])[0] != '-') || ((argv[r])[1] == '\0')))
          {
            fp = local_fopen(argv[r],"w");
            if (fp == NULL)
              fp = stderr;
          }
        print_usage(base_header_bytes,num_levels,required_profile,max_bpp,
                    base_step,max_iterations,argv[0],fp);
        local_fclose(fp);
        return(-1);
      }

  copy_argv = (char **) local_malloc(sizeof(char *)*argc);
  memcpy(copy_argv,argv,sizeof(char *)*argc);
  parse_common_arguments(argc,copy_argv,&base_header_bytes,&num_levels,
                         &filter_set,&local_filter_name,&filter_flags,
                         &required_profile,&max_bpp,&base_step,
                         &max_iterations,&verbose);
  if (filter_set == 15)
    filter_id = local_filter_name;
  else
    {
      filter_id = filter_id_buf;
      sprintf(filter_id,"%1d",filter_set);
    }

  /* Enter rate control loop.
     No actual loop unless `max_rate_iterations' != 0. */

  iterations = final_iteration = 0;
  found_max_step = found_min_step = 0;
  min_step = max_step = 0.0F; /* Avoid compiler warnings. */
  do {
    int max_bitplanes;
    unsigned short int fixed_point_step;

    /* Open image and get dimensions. */

    image_fp = open_input_image_file(argc,copy_argv,&num_rows,&num_cols,
                                     &num_components);
    max_bytes = (int)(0.125F * max_bpp * (float)(num_rows * num_cols));
    header_bytes = base_header_bytes + 8*(num_components-1);
    fixed_point_step = get_fixed_point_step(&base_step);
    for (n=0; n < num_components; n++)
      {
        component_base_steps[n] = base_step;
        component_fixed_steps[n] = fixed_point_step;
        component_rows[n] = num_rows;
        component_cols[n] = num_cols;
        component_ids[n] = filter_id;
        component_flags[n] = filter_flags;
      }

    /* Create objects. */

    info = info_creator();
    analysis = analysis_creator();
    quantizer = quantizer_creator();
    encoder = encoder_creator();
    bitstream = bitstream_creator();
    
    /* Initialize all objects except for bit-stream sink. */

    max_bitplanes = 0;
    info->initialize(info,DECOMPOSITION__MALLAT,num_levels,num_components,
                     component_ids,component_flags,component_base_steps,
                     &max_bitplanes,argc,copy_argv);
    analysis->initialize(analysis,DECOMPOSITION__MALLAT,num_levels,
                         num_components,component_rows,component_cols,
                         info,quantizer,argc,copy_argv);
    quantizer->initialize(quantizer,DECOMPOSITION__MALLAT,num_levels,
                          num_components,component_rows,component_cols,
                          info,encoder,argc,copy_argv);
    supported_profile = required_profile;
    encoder->initialize(encoder,DECOMPOSITION__MALLAT,num_levels,
                        num_components,component_rows,component_cols,info,
                        required_profile,&supported_profile,header_bytes,
                        max_bytes-header_bytes,bitstream,argc,copy_argv);

    line_buf = interleaved_line = (ifc_int *)
      local_malloc(sizeof(ifc_int) * num_cols * num_components);
    if (num_components > 1)
      line_buf = (ifc_int *) local_malloc(sizeof(ifc_int) * num_cols);

    /* Open compressed output file, write header & initialize bitstream sink */

    bitstream_fp = open_output_bitstream(argc,copy_argv,num_levels,filter_set,
                                         filter_flags,supported_profile,
                                         max_bitplanes,num_components,
                                         component_rows,component_cols,
                                         component_fixed_steps,header_bytes);
    bitstream->initialize(bitstream,max_bytes-header_bytes,
                          bitstream_fp,argc,copy_argv);
    if (iterations == 0)
      check_all_arguments_used(argc,copy_argv);
    if (verbose && (iterations == 0))
      {
        fprintf(stderr,"\nBit-stream has the following feature profile:\n");
        print_profile_vector(supported_profile,stderr);
        fprintf(stderr,
                "Components = %d; Levels = %d; Header size = %d bytes;\n"
                "Target rate = %g bpp (i.e. %d bytes)\n",
                num_components,num_levels,header_bytes,max_bpp,max_bytes);
      }

    /* Push image rows into the analysis stage one at a time. */

    for (r=0; r < num_rows; r++)
      {
        read_image_line(interleaved_line,image_fp,num_cols,num_components);
        if (num_components == 1)
          analysis->push_line(analysis,interleaved_line,0);
        else
          {
            for (n=0; n < num_components; n++)
              {
                ifc_int *sp, *dp;
                int c;

                for (sp=interleaved_line+n, dp=line_buf,
                     c=num_cols; c > 0; c--, sp += num_components)
                  *(dp++) = *sp;
                analysis->push_line(analysis,line_buf,n);
              }
          }
      }

    /* Terminate all objects. */

    analysis->terminate(analysis); /* Pushes all subband samples out first. */
    quantizer->terminate(quantizer); /* Pushes all symbol indices out first. */
    encoder->terminate(encoder); /* Pushes the bit-stream out first. */
    excess_bytes = bitstream->terminate(bitstream);
    info->terminate(info);
    if (verbose)
      fprintf(stderr,"  Base step = %g -> generated %g bpp (i.e. %d bytes)\n",
              base_step,(8.0F*(float)(max_bytes+excess_bytes))/
              ((float)(num_rows*num_cols)),
              max_bytes+excess_bytes);

    /* Finish up. */

    if (line_buf != interleaved_line)
      local_free(line_buf);
    local_free(interleaved_line);
    local_fclose(image_fp);
    local_fclose(bitstream_fp);

    /* See if we need to try another step size: only in iterative mode. */

    if ((max_iterations == 0) || final_iteration)
      break;

    if (iterations == 0)
      found_min_step = found_max_step = 0;
    if (excess_bytes > 0)
      { found_min_step = 1; min_step = base_step; }
    else
      { found_max_step = 1; max_step = base_step; }
    iterations++;
    if ((iterations < max_iterations) || (!found_max_step))
      { /* Compute new base step. */
        if (!found_min_step)
          base_step *= 0.5F;
        else if (!found_max_step)
          base_step *= 2.0F;
        else
          {
            base_step = 0.5F * (min_step + max_step);
            get_fixed_point_step(&base_step);
            if ((base_step == min_step) || (base_step == max_step))
              final_iteration = 1; /* No point in iterating any further. */
          }
      }
    else
      final_iteration = 1;
    if (final_iteration)
      {
        if (base_step == max_step)
          break;
        base_step = max_step;
      }
    memcpy(copy_argv,argv,sizeof(char *)*argc);
  } while (excess_bytes != 0);
  local_free(copy_argv);
  return (0);
}

⌨️ 快捷键说明

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