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

📄 image_in.cpp

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/// File: image_in.cpp [scope = APPS/IMAGE-IO]// Version: Kakadu, V2.2.1// Author: David Taubman// Last Revised: 5 July, 2001/*****************************************************************************/// Copyright 2001, David Taubman, The University of New South Wales (UNSW)// The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW)// Neither this copyright statement, nor the licensing details below// may be removed from this file or dissociated from its contents./*****************************************************************************/// Licensee: Book Owner// License number: 99999// The Licensee has been granted a NON-COMMERCIAL license to the contents of// this source file, said Licensee being the owner of a copy of the book,// "JPEG2000: Image Compression Fundamentals, Standards and Practice," by// Taubman and Marcellin (Kluwer Academic Publishers, 2001).  A brief summary// of the license appears below.  This summary is not to be relied upon in// preference to the full text of the license agreement, which was accepted// upon breaking the seal of the compact disc accompanying the above-mentioned// book.// 1. The Licensee has the right to Non-Commercial Use of the Kakadu software,//    Version 2.2, including distribution of one or more Applications built//    using the software, provided such distribution is not for financial//    return.// 2. The Licensee has the right to personal use of the Kakadu software,//    Version 2.2.// 3. The Licensee has the right to distribute Reusable Code (including//    source code and dynamically or statically linked libraries) to a Third//    Party, provided the Third Party possesses a license to use the Kakadu//    software, Version 2.2, and provided such distribution is not for//    financial return./******************************************************************************Description:   Implements image file reading for a variety of different file formats:currently BMP, PGM, PPM and RAW only.  Readily extendible to include otherfile formats without affecting the rest of the system.******************************************************************************/// System includes#include <string.h>#include <math.h>#include <assert.h>// Core includes#include "kdu_messaging.h"#include "kdu_sample_processing.h"// Image includes#include "kdu_image.h"#include "image_local.h"/* ========================================================================= *//*                             Internal Functions                            *//* ========================================================================= *//*****************************************************************************//* STATIC                       to_little_endian                             *//*****************************************************************************/static void  to_little_endian(kdu_int32 * words, int num_words){  kdu_int32 test = 1;  kdu_byte *first_byte = (kdu_byte *) &test;  if (*first_byte)    return; // Machine uses little-endian architecture already.  kdu_int32 tmp;  for (; num_words--; words++)    {      tmp = *words;      *words = ((tmp >> 24) & 0x000000FF) +               ((tmp >> 8)  & 0x0000FF00) +               ((tmp << 8)  & 0x00FF0000) +               ((tmp << 24) & 0xFF000000);    }}/*****************************************************************************//* INLINE                      from_little_endian                            *//*****************************************************************************/static inline void  from_little_endian(kdu_int32 * words, int num_words){  to_little_endian(words,num_words);}/*****************************************************************************//* INLINE                    eat_white_and_comments                          *//*****************************************************************************/static inline void  eat_white_and_comments(FILE *in){  int ch;  bool in_comment;  in_comment = false;  while ((ch = getc(in)) != EOF)    if (ch == '#')      in_comment = true;    else if (ch == '\n')      in_comment = false;    else if ((!in_comment) && (ch != ' ') && (ch != '\t') && (ch != '\r'))      {        ungetc(ch,in);        return;      }}/*****************************************************************************//* STATIC                    convert_words_to_floats                         *//*****************************************************************************/static void  convert_words_to_floats(kdu_byte *src, kdu_sample32 *dest, int num,                          int precision, bool is_signed, int sample_bytes){  float scale;  if (precision < 30)    scale = (float)(1<<precision);  else    scale = ((float)(1<<30)) * ((float)(1<<(precision-30)));  scale = 1.0F / scale;    kdu_int32 centre = 1<<(precision-1);  kdu_int32 offset = (is_signed)?centre:0;  kdu_int32 mask = ~((-1)<<precision);  kdu_int32 val;  if (sample_bytes == 1)    for (; num > 0; num--, dest++)      {        val = *(src++);        val += offset;        val &= mask;        val -= centre;        dest->fval = ((float) val) * scale;      }  else if (sample_bytes == 2)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->fval = ((float) val) * scale;      }  else if (sample_bytes == 3)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->fval = ((float) val) * scale;      }  else if (sample_bytes == 4)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++);        val = (val<<8) + *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->fval = ((float) val) * scale;      }  else    assert(0);}/*****************************************************************************//* STATIC                   convert_words_to_fixpoint                        *//*****************************************************************************/static void  convert_words_to_fixpoint(kdu_byte *src, kdu_sample16 *dest, int num,                            int precision, bool is_signed, int sample_bytes){  kdu_int32 upshift = KDU_FIX_POINT-precision;  if (upshift < 0)    { kdu_error e; e << "Cannot use 16-bit representation with high "      "bit-depth data"; }  kdu_int32 centre = 1<<(precision-1);  kdu_int32 offset = (is_signed)?centre:0;  kdu_int32 mask = ~((-1)<<precision);  kdu_int32 val;  if (sample_bytes == 1)    for (; num > 0; num--, dest++)      {        val = *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = (kdu_int16)(val<<upshift);      }  else if (sample_bytes == 2)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = (kdu_int16)(val<<upshift);      }  else    { kdu_error e; e << "Cannot use 16-bit representation with high "      "bit-depth data"; }}/*****************************************************************************//* STATIC                     convert_words_to_ints                          *//*****************************************************************************/static void  convert_words_to_ints(kdu_byte *src, kdu_sample32 *dest, int num,                        int precision, bool is_signed, int sample_bytes){  kdu_int32 centre = 1<<(precision-1);  kdu_int32 offset = (is_signed)?centre:0;  kdu_int32 mask = ~((-1)<<precision);  kdu_int32 val;  if (sample_bytes == 1)    for (; num > 0; num--, dest++)      {        val = *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = val;      }  else if (sample_bytes == 2)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = val;      }  else if (sample_bytes == 3)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = val;      }  else if (sample_bytes == 4)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++);        val = (val<<8) + *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = val;      }  else    assert(0);}/*****************************************************************************//* STATIC                   convert_words_to_shorts                          *//*****************************************************************************/static void  convert_words_to_shorts(kdu_byte *src, kdu_sample16 *dest, int num,                          int precision, bool is_signed, int sample_bytes){  kdu_int32 centre = 1<<(precision-1);  kdu_int32 offset = (is_signed)?centre:0;  kdu_int32 mask = ~((-1)<<precision);  kdu_int32 val;  if (sample_bytes == 1)    for (; num > 0; num--, dest++)      {        val = *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = (kdu_int16) val;      }  else if (sample_bytes == 2)    for (; num > 0; num--, dest++)      {        val = *(src++); val = (val<<8) + *(src++);        val += offset;        val &= mask;        val -= centre;        dest->ival = (kdu_int16) val;      }  else    { kdu_error e; e << "Cannot use 16-bit representation with high "      "bit-depth data"; }}/* ========================================================================= *//*                                kdu_image_in                               *//* ========================================================================= *//*****************************************************************************//*                         kdu_image_in::kdu_image_in                        *//*****************************************************************************/kdu_image_in::kdu_image_in(char const *fname, siz_params *siz,                           int &next_comp_idx, bool &vflip,                           kdu_rgb8_palette *palette){  char const *suffix;  in = NULL;  vflip = false; // Allows derived constructors to ignore the argument.  if ((suffix = strrchr(fname,'.')) != NULL)    {      if ((strcmp(suffix+1,"pbm") == 0) || (strcmp(suffix+1,"PBM") == 0))        in = new pbm_in(fname,siz,next_comp_idx,palette);      else if ((strcmp(suffix+1,"pgm") == 0) || (strcmp(suffix+1,"PGM") == 0))        in = new pgm_in(fname,siz,next_comp_idx);      else if ((strcmp(suffix+1,"ppm") == 0) || (strcmp(suffix+1,"PPM") == 0))        in = new ppm_in(fname,siz,next_comp_idx);      else if ((strcmp(suffix+1,"bmp") == 0) || (strcmp(suffix+1,"BMP") == 0))        in = new bmp_in(fname,siz,next_comp_idx,vflip,palette);      else if ((strcmp(suffix+1,"raw") == 0) || (strcmp(suffix+1,"RAW") == 0))        in = new raw_in(fname,siz,next_comp_idx);    }  if (in == NULL)    { kdu_error e; e << "Image file, \"" << fname << ", does not have a "      "recognized suffix.  Valid suffices are currently: "      "\"bmp\", \"pgm\", \"ppm\" and \"raw\".  "      "Upper or lower case may be used, but must be used consistently.";    }}/* ========================================================================= *//*                                   pbm_in                                  *//* ========================================================================= *//*****************************************************************************//*                               pbm_in::pbm_in                              *//*****************************************************************************/pbm_in::pbm_in(char const *fname, siz_params *siz, int &next_comp_idx,               kdu_rgb8_palette *palette){  char magic[3];  if ((in = fopen(fname,"rb")) == NULL)    { kdu_error e;      e << "Unable to open input image file, \"" << fname <<"\".";}  magic[0] = magic[1] = magic[2] = '\0';  fread(magic,1,2,in);  if (strcmp(magic,"P4") != 0)    { kdu_error e; e << "PBM image file must start with the magic string, "      "\"P4\"!"; }  bool failed = false;  eat_white_and_comments(in);  if (fscanf(in,"%d",&cols) != 1)    failed = true;  eat_white_and_comments(in);  if (fscanf(in,"%d",&rows) != 1)    failed = true;  if (failed)    {kdu_error e; e << "Image file \"" << fname << "\" does not appear to "     "have a valid PBM header."; }  int ch;  while ((ch = fgetc(in)) != EOF)    if (ch == '\n')      break;  comp_idx = next_comp_idx++;  siz->set(Sdims,comp_idx,0,rows);  siz->set(Sdims,comp_idx,1,cols);  siz->set(Ssigned,comp_idx,0,false);  siz->set(Sprecision,comp_idx,0,1);  if ((palette != NULL) && !palette->exists())    {      palette->input_bits = 1;      palette->output_bits = 8;      palette->source_component = comp_idx;      palette->blue[0] = palette->green[0] = palette->red[0] = 0;      palette->blue[1] = palette->green[1] = palette->red[1] = 255;      // Note that we will be flipping the bits so that a 0 really does      // represent black, rather than white -- this is more efficient for      // coding facsimile type images where the background is white.    }  incomplete_lines = free_lines = NULL;  num_unread_rows = rows;}/*****************************************************************************//*                               pbm_in::~pbm_in                             *//*****************************************************************************/pbm_in::~pbm_in(){  if ((num_unread_rows > 0) || (incomplete_lines != NULL))    { kdu_warning w;      w << "Not all rows of image component "        << comp_idx << " 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);}/*****************************************************************************//*                                 pbm_in::get                               *//*****************************************************************************/bool  pbm_in::get(int comp_idx, kdu_line_buf &line, int x_tnum){  assert(comp_idx == this->comp_idx);  image_line_buf *scan, *prev=NULL;  kdu_byte *sp;  int n;  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 line from left to right.      if (num_unread_rows == 0)        return false;      if ((scan = free_lines) == NULL)        scan = new image_line_buf(cols+7,1);      free_lines = scan->next;      if (prev == NULL)        incomplete_lines = scan;      else        prev->next = scan;      n = (cols+7) >> 3;      if (fread(scan->buf,1,(size_t) n,in) != (size_t) n)        { kdu_error e; e << "Image file for component " << comp_idx          << " terminated prematurely!"; }      // Expand the packed representation into whole bytes, flipping and      // storing each binary digit in the LSB of a single byte.  The reason      // for flipping is that PBM files represent white using a 0 and      // black using a 1, but the more natural and also more efficient      // representation for coding unsigned data with 1-bit precision in      // JPEG2000 is the opposite.

⌨️ 快捷键说明

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