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

📄 image_in.cpp

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      scan->next_x_tnum = 0;    }  assert((scan->width-scan->accessed_samples) >= line.get_width());  if (line.get_buf32() != NULL)    {      if (line.is_absolute())        convert_words_to_ints(scan->buf+sample_bytes*scan->accessed_samples,                              line.get_buf32(),line.get_width(),                              precision,is_signed,sample_bytes);      else        convert_words_to_floats(scan->buf+sample_bytes*scan->accessed_samples,                                line.get_buf32(),line.get_width(),                                precision,is_signed,sample_bytes);    }  else    {      if (line.is_absolute())        convert_words_to_shorts(scan->buf+sample_bytes*scan->accessed_samples,                                line.get_buf16(),line.get_width(),                                precision,is_signed,sample_bytes);      else        convert_words_to_fixpoint(scan->buf+sample_bytes*scan->accessed_samples,                                  line.get_buf16(),line.get_width(),                                  precision,is_signed,sample_bytes);    }  scan->next_x_tnum++;  scan->accessed_samples += line.get_width();  if (scan->accessed_samples == scan->width)    { // Send empty line to free list.      assert(scan == incomplete_lines);      incomplete_lines = scan->next;      scan->next = free_lines;      free_lines = scan;    }  return true;}/* ========================================================================= *//*                                   bmp_in                                  *//* ========================================================================= *//*****************************************************************************//*                               bmp_in::bmp_in                              *//*****************************************************************************/bmp_in::bmp_in(char const *fname, siz_params *siz, int &next_comp_idx,               bool &vflip, kdu_rgb8_palette *palette){  int n;  if ((in = fopen(fname,"rb")) == NULL)    { kdu_error e;      e << "Unable to open input image file, \"" << fname <<"\"."; }  kdu_byte magic[14];  bmp_header header;  fread(magic,1,14,in);  if ((magic[0] != 'B') || (magic[1] != 'M') || (fread(&header,1,40,in) != 40))    { kdu_error e; e << "BMP image file must start with the magic string, "      "\"BM\", and continue with a header whose total size is at least 54 "      "bytes."; }  from_little_endian((kdu_int32 *) &header,10);  cols = header.width;  rows = header.height;  if (rows < 0)    rows = -rows;  else    vflip = true;  bytes = nibbles = bits = expand_palette = false;  int precision = 8;  if (header.bit_count == 24)    num_components = 3;  else if (header.bit_count == 8)    { num_components = 1; bytes = true; }  else if (header.bit_count == 4)    { num_components = 1; nibbles = true; precision = 4; }  else if (header.bit_count == 1)    { num_components = 1; bits = true; precision = 1; }  else    { kdu_error e;      e << "We currently support only 1-, 4-, 8- and 24-bit BMP files."; }  int header_size = 54 + ((num_components==1)?(4<<precision):0);  int offset = magic[13];  offset <<= 8; offset += magic[12];  offset <<= 8; offset += magic[11];  offset <<= 8; offset += magic[10];  if (offset < header_size)    { kdu_error e; e << "Invalid sample data offset field specified in BMP "      "file header!"; }  if (num_components == 1)    {      fread(map,1,4<<precision,in);      if (bytes)        {          for (n=0; n < 256; n++)            if ((map[4*n] != n) || (map[4*n+1] != n) || (map[4*n+2] != n))              break;          if (n == 256)            bytes = false; // No need to use palette        }    }  if (bytes || nibbles || bits)    {      if ((palette == NULL) || palette->exists())        {          expand_palette = true; // Need to expand the palette here.          precision = 8;          for (n=0; n < 256; n++)            if ((map[4*n] != map[4*n+1]) || (map[4*n] != map[4*n+2]))              break; // Not a monochrome source.          num_components = (n==256)?1:3;        }      else        { // Set up the colour palette.          palette->input_bits = precision;          palette->output_bits = 8;          palette->source_component = next_comp_idx;          for (n=0; n < (1<<precision); n++)            {              palette->blue[n] = map[4*n+0];              palette->green[n] = map[4*n+1];              palette->red[n] = map[4*n+2];            }          for (n=0; n < (1<<precision); n++)            map[n] = n; // Set identity permutation for now.          if (nibbles || bytes)            palette->rearrange(map); // Try to find a better permutation.        }    }  if (offset > header_size)    fseek(in,offset-header_size,SEEK_CUR);  first_comp_idx = next_comp_idx;  for (n=0; n < num_components; n++)    {      next_comp_idx++;      siz->set(Sdims,first_comp_idx+n,0,rows);      siz->set(Sdims,first_comp_idx+n,1,cols);      siz->set(Ssigned,first_comp_idx+n,0,false);      siz->set(Sprecision,first_comp_idx+n,0,precision);    }  incomplete_lines = NULL;  free_lines = NULL;  num_unread_rows = rows;  if (bytes)    line_bytes = cols;  else if (nibbles)    line_bytes = (cols+1)>>1;  else if (bits)    line_bytes = (cols+7)>>3;  else    line_bytes = cols*num_components;  line_bytes += (-line_bytes) & 3; // Pad to a multiple of 4 bytes.}/*****************************************************************************//*                               bmp_in::~bmp_in                             *//*****************************************************************************/bmp_in::~bmp_in(){  if ((num_unread_rows > 0) || (incomplete_lines != NULL))    { kdu_warning w;      w << "Not all rows of image components "        << first_comp_idx << " through "        << first_comp_idx+num_components-1        << " were consumed!";    }  image_line_buf *tmp;  while ((tmp=incomplete_lines) != NULL)    { incomplete_lines = tmp->next; delete tmp; }  while ((tmp=free_lines) != NULL)    { free_lines = tmp->next; delete tmp; }  fclose(in);}/*****************************************************************************//*                                 bmp_in::get                               *//*****************************************************************************/bool  bmp_in::get(int comp_idx, kdu_line_buf &line, int x_tnum){  int idx = comp_idx - this->first_comp_idx;  assert((idx >= 0) && (idx < num_components));  x_tnum = x_tnum*num_components+idx;  image_line_buf *scan, *prev=NULL;  for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next)    {      assert(scan->next_x_tnum >= x_tnum);      if (scan->next_x_tnum == x_tnum)        break;    }  if (scan == NULL)    { // Need to read a new image line.      assert(x_tnum == 0); // Must consume in very specific order.      if (num_unread_rows == 0)        return false;      if ((scan = free_lines) == NULL)        scan = new image_line_buf(cols+7,num_components);                          // Big enough for padding and expanding bits to bytes      free_lines = scan->next;      if (prev == NULL)        incomplete_lines = scan;      else        prev->next = scan;      if (fread(scan->buf,1,(size_t) line_bytes,in) != (size_t) line_bytes)        { kdu_error e; e << "Image file for components " << first_comp_idx          << " through " << first_comp_idx+num_components-1          << " terminated prematurely!"; }      num_unread_rows--;      scan->accessed_samples = 0;      scan->next_x_tnum = 0;      if (bytes)        map_palette_index_bytes(scan->buf,line.is_absolute());      else if (nibbles)        map_palette_index_nibbles(scan->buf,line.is_absolute());      else if (bits)        map_palette_index_bits(scan->buf,line.is_absolute());    }  assert((cols-scan->accessed_samples) >= line.get_width());  int comp_offset = (num_components==3)?(2-idx):0;  kdu_byte *sp = scan->buf+num_components*scan->accessed_samples + comp_offset;  int n=line.get_width();  if (line.get_buf32() != NULL)    {      kdu_sample32 *dp = line.get_buf32();      if (line.is_absolute())        { // 32-bit absolute integers          kdu_int32 offset = 128;          if ((num_components == 1) && nibbles) offset = 8;          if ((num_components == 1) && bits) offset = 1;          for (; n > 0; n--, sp+=num_components, dp++)            dp->ival = ((kdu_int32)(*sp)) - offset;        }      else        { // true 32-bit floats          for (; n > 0; n--, sp+=num_components, dp++)            dp->fval = (((float)(*sp)) / 256.0F) - 0.5F;        }    }  else    {      kdu_sample16 *dp = line.get_buf16();      if (line.is_absolute())        { // 16-bit absolute integers          kdu_int16 offset = 128;          if ((num_components == 1) && nibbles) offset = 8;          if ((num_components == 1) && bits) offset = 1;          for (; n > 0; n--, sp+=num_components, dp++)            dp->ival = ((kdu_int16)(*sp)) - offset;        }      else        { // 16-bit normalized representation.          for (; n > 0; n--, sp+=num_components, dp++)            dp->ival = (((kdu_int16)(*sp)) - 128) << (KDU_FIX_POINT-8);        }    }  scan->next_x_tnum++;  if (idx == (num_components-1))    scan->accessed_samples += line.get_width();  if (scan->accessed_samples == cols)    { // Send empty line to free list.      assert(scan == incomplete_lines);      incomplete_lines = scan->next;      scan->next = free_lines;      free_lines = scan;    }  return true;}/*****************************************************************************//*                       bmp_in::map_palette_index_bytes                     *//*****************************************************************************/void  bmp_in::map_palette_index_bytes(kdu_byte *buf, bool absolute){  int n = cols;  if (num_components == 3)    { // Expand single component through palette      assert(expand_palette);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + (3*n);      kdu_byte *mp;      for (; n > 0; n--)        {          mp = map + (((int) *(--sp))<<2);          *(--dp) = mp[2]; *(--dp) = mp[1]; *(--dp) = mp[0];        }    }  else if (expand_palette)    {      assert(num_components == 1);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + n;      for (; n > 0; n--)        *(--dp) = map[((int) *(--sp))<<2];    }  else    { // Apply optimized permutation map to the palette indices      assert(num_components == 1);      for (; n > 0; n--, buf++)        *buf = map[*buf];    }}/*****************************************************************************//*                      bmp_in::map_palette_index_nibbles                    *//*****************************************************************************/void  bmp_in::map_palette_index_nibbles(kdu_byte *buf, bool absolute){  int n = (cols+1)>>1;  if (num_components == 3)    { // Expand single component through palette      assert(expand_palette);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + (6*n);      kdu_byte *mp;      kdu_uint32 val;      for (; n > 0; n--)        {          val = *(--sp);          mp = map + ((val & 0x0F)<<2);          *(--dp) = mp[2]; *(--dp) = mp[1]; *(--dp) = mp[0];          val >>= 4;          mp = map + ((val & 0x0F)<<2);          *(--dp) = mp[2]; *(--dp) = mp[1]; *(--dp) = mp[0];        }    }  else if (expand_palette)    {      assert(num_components == 1);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + (2*n);      kdu_uint32 val;      for (; n > 0; n--)        {          val = *(--sp);          *(--dp) = map[(val & 0x0F) << 2];          val >>= 4;          *(--dp) = map[(val & 0x0F) << 2];        }    }  else    { // Apply optimized permutation map to the palette indices      assert(num_components == 1);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + (2*n);      kdu_byte val;      if (absolute)        { // Map nibbles and store in least significant 4 bits of byte          for (; n > 0; n--)            {              val = *(--sp);              *(--dp) = map[val & 0x0F];              val >>= 4;              *(--dp) = map[val & 0x0F];            }        }      else        { // Map nibbles and store in most significant 4 bits of byte          for (; n > 0; n--)            {              val = *(--sp);              *(--dp) = map[val & 0x0F]<<4;              val >>= 4;              *(--dp) = map[val & 0x0F]<<4;            }        }    }}/*****************************************************************************//*                       bmp_in::map_palette_index_bits                      *//*****************************************************************************/void  bmp_in::map_palette_index_bits(kdu_byte *buf, bool absolute){  int b, n = (cols+7)>>3;  if (num_components == 3)    { // Expand single component through palette      assert(expand_palette);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + (24*n);      kdu_byte *mp;      kdu_uint32 val;      for (; n > 0; n--)        {          val = *(--sp);          for (b=8; b > 0; b--, val>>=1)            {              mp = map + ((val & 1)<<2);              *(--dp) = mp[2]; *(--dp) = mp[1]; *(--dp) = mp[0];            }        }    }  else if (expand_palette)    {      assert(num_components == 1);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + (8*n);      kdu_uint32 val;      for (; n > 0; n--)        {          val = *(--sp);          for (b=8; b > 0; b--, val>>=1)            *(--dp) = map[(val & 1)<<2];        }    }  else    { // Apply optimized permutation map to the palette indices      assert(num_components == 1);      kdu_byte *sp = buf + n;      kdu_byte *dp = buf + (8*n);      kdu_byte val;      if (absolute)        { // Store bits in LSB's of bytes          for (; n > 0; n--)            {              val = *(--sp);              for (b=8; b > 0; b--, val>>=1)                *(--dp) = val&1;            }        }      else        { // Store bits in MSB's of bytes          for (; n > 0; n--)            {              val = *(--sp);              for (b=8; b > 0; b--, val>>=1)                *(--dp) = (val&1)<<7;            }        }    }}

⌨️ 快捷键说明

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