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

📄 mcraw_image_writer.c

📁 JPEG2000实现的源码
💻 C
字号:
/*****************************************************************************/
/* Copyright 1999, Eastman Kodak Company                                     */
/* All rights reserved                                                       */
/* File: "mcraw_image_writer.c"                                              */
/* Description: Multi-component raw image implementation of the              */
/*              `image_writer' object                                        */
/* Author: Austin Lan                                                        */
/* Affiliation: Eastman Kodak Company                                        */
/* Version: VM9.0                                                            */
/* Last Revised: 18 April, 2001                                              */
/*****************************************************************************/
#include <image_io.h>
#include <local_services.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "mcraw_image_writer_local.h"
#include "mcraw_common.h"

/* ========================================================================= */
/* ------------------------- Interface Implementation ---------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                         __initialize                               */
/*****************************************************************************/

static void
__initialize(image_writer_ref base, int num_components,
             int bitdepths[], canvas_dims_ptr dims,
             /* Begin Aerospace MCT mods (JHK) */
             int *dims_reference,
             /* End Aerospace MCT mods */
             cmdl_ref cmdl)
{
   mcraw_image_writer_ref self = (mcraw_image_writer_ref) base;
   int max_bitdepth, is_signed;
   int n, p;
   char **params;

   /* Set up some defaults before parsing command line:
      data organization = BIL
      skip bytes = 0
      no byte swapping */

   self->filename = NULL;
   self->pack_bytes = -1;
   self->reverse_byte_order = 0;
   self->data_org = BIL;
   self->skip_bytes = 0; /* Always zero */

   /* EKC mct begin */
   if ((p = cmdl->extract(cmdl,"-o",-1,&params)) == 1) {
      self->filename = (char *) local_malloc(IMAGE_IO_MEM_KEY, strlen(params[0])+1);
      strcpy(self->filename, params[0]);
   } else {
      local_error("The `-o' argument is invalid.");
   }
   /* EKC mct end */

   if ((p = cmdl->extract(cmdl,"-bd",-1,&params)) == 1) {
      self->pack_bytes = atoi(params[0]);
   }
   if ((p = cmdl->extract(cmdl,"-do",-1,&params)) == 1) {
      if (strcmp(params[0], "bsq") == 0) {
	 self->data_org = BSQ;
      } else if (strcmp(params[0], "bil") == 0) {
	 self->data_org = BIL;
      } else if (strcmp(params[0], "bip") == 0) {
	 self->data_org = BIP;
      } else {
	 local_error("Valid values for the `-do' argument are \"bsq\", \"bil\", \"bip\"");
      }
   }
   if ((p = cmdl->extract(cmdl,"-swap",-1,&params)) == 0) {
      self->reverse_byte_order = 1;
   }

   /* Error checking */

   /* EKC mct begin */
   if (self->filename == NULL)
      local_error("Must supply an output image file name via the `-o' "
		  "argument!");
   /* EKC mct end */

   /* Set up the dimension fields of mcraw_image_writer_obj.  The rows
      and cols of the multi-component image are expected to be the 
      same for all components. */

   self->num_components = num_components;
   self->rows = dims[dims_reference[0]].rows;
   self->cols = dims[dims_reference[0]].cols;
   
   /* Set up the `bitdepths' and `is_signed' fields of mcraw_image_writer_obj.  Also
      determine the maximum bit depth value. */

   self->bitdepths = 
      (int *) local_malloc(IMAGE_IO_MEM_KEY, (self->num_components * sizeof(int)));
   self->is_signed = 
      (int *) local_malloc(IMAGE_IO_MEM_KEY, (self->num_components * sizeof(int)));
   for (n=0, max_bitdepth=0, is_signed=0; n<self->num_components; n++) {
      if (bitdepths[n] < 0) {
	 is_signed = 1;
	 self->is_signed[n] = 1;
	 self->bitdepths[n] = -bitdepths[n];
      } else {
	 self->is_signed[n] = 0;
	 self->bitdepths[n] = bitdepths[n];
      }
      if (self->bitdepths[n] > max_bitdepth) {
	 max_bitdepth = self->bitdepths[n];
      }
   }

   /* Perform error checking to make sure the desired byte depth is
      compatible with the reconstructed data. */

   if (self->pack_bytes > 0) {
      int print_warning = 0;
      if (max_bitdepth <= 8) {
	 if (self->pack_bytes < 1) {
	    print_warning = 1;
	    self->pack_bytes = 1;
	 }
      } else if (max_bitdepth <= 16) {
	 if (self->pack_bytes < 2) {
	    print_warning = 1;
	    self->pack_bytes = 2;
	 }
      } else if (max_bitdepth <= 32) {
	 if (self->pack_bytes < 4) {
	    print_warning = 1;
	    self->pack_bytes = 4;
	 }
      } else {
	 local_error("At least one output component has %d-bit "
		     "sample values!!  Cannot support such high bit-depths "
		     "with current implementation precision.  Try changing "
		     "the IMPLEMENTATION_PRECISION macro in \"ifc.h\" and "
		     "recompiling!", max_bitdepth);
      }
      if (print_warning) {
	 local_printf(0,76,"\nWARNING");
	 local_printf(6,70, "Requested byte depth cannot hold the reconstructed "
		      "data without truncation.  Increasing the output file byte "
		      "depth to match the component with the largest bit depth.");
      }
   } else {
      if (max_bitdepth <= 8) {
	 self->pack_bytes = 1;
      } else if (max_bitdepth <= 16) {
	 self->pack_bytes = 2;
      } else if (max_bitdepth <= 32) {
	 self->pack_bytes = 4;
      } else {
	 local_error("At least one output component has %d-bit "
		     "sample values!!  Cannot support such high bit-depths "
		     "with current implementation precision.  Try changing "
		     "the IMPLEMENTATION_PRECISION macro in \"ifc.h\" and "
		     "recompiling!", max_bitdepth);
      }
   }

   /* Error checking */

   if ((self->reverse_byte_order) && (self->pack_bytes == 1)) {
      local_printf(0,76,"\nWARNING");
      local_printf(6,70, "No byte swapping will be applied since the output file byte "
		   "depth is only a single byte.");
      self->reverse_byte_order = 0;
   }


   /* Open the user-specified image file */

   if ((self->fp = fopen(self->filename, "wb")) == NULL) {
      local_error("Unable to open the specified image file, %s, for writing", 
		  self->filename);
   }

   /* Initialize the data buffer */

   self->current_row_idx = 0;
   self->comp_written_so_far = 0;
   
   self->line_buf = 
      (void **) local_malloc(IMAGE_IO_MEM_KEY, (self->num_components * sizeof(void *)));
   self->line_buf[0] =
      (void *) local_malloc(IMAGE_IO_MEM_KEY, 
			    (self->num_components * self->cols * self->pack_bytes));
   for (n=1; n<self->num_components; n++) {
      self->line_buf[n] = (char *)self->line_buf[0] + (n * self->cols * self->pack_bytes);
   }

   /* Print input image information to the screen for the user */
   
   local_printf(0,76,"\nInformation on output multi-component raw image:");
   local_printf(6,70,"(rows, cols, components) = (%d, %d, %d)",
		self->rows, self->cols, self->num_components);
   local_printf(6,70,"Signed:  %s", (is_signed) ? "YES" : "NO");
   local_printf(6,70,"Data storage:  %d byte%s", self->pack_bytes,
		(self->pack_bytes > 1) ? "s" : "");
   local_printf(6,70,"Data organization:  %s", (self->data_org == BSQ) ? "Band-sequential" : 
		(self->data_org == BIL) ? "Band-interleaved-by-line" : 
		"Band-interleaved-by-pixel");
   local_printf(6,70,"Swap bytes:  %s", (self->reverse_byte_order) ? "YES" : "NO");
   local_printf(6,70,"Skip bytes:  %d", self->skip_bytes);
   local_printf(6,70,"Bit depths:  %d...%d", 
		self->bitdepths[0], self->bitdepths[self->num_components-1]);
   local_printf(0,76,"\n");
}

/*****************************************************************************/
/* STATIC                         __get_usage                                */
/*****************************************************************************/

static char **
  __get_usage(image_writer_ref base)
{
   static char *args[] = {
      /* EKC mct begin */
      "-o <mcraw image file>",
        "Mandatory argument, identifying the reconstructed multi-component raw "
        "image file name.  File extensions that are recognized include \".img\", "
        "\".nrm\", \".bil\", \".raw\", \".bsq\", \".bip\".",
      /* EKC mct end */
      "-bd <byte depth> (default = use bitstream info) (*MCRAW OUTPUT ONLY*)",
        "Optional argument for `-o', specifying the desired output file "
        "byte depth.  Must be large enough to hold the values that are "
        "reconstructed.  Sign is determined from information in the "
        "compressed bitstream.",
      "-do <data organization> (default = \"bil\") (*MCRAW OUTPUT ONLY*)",
        "Optional argument for `-o', specifying the desired data "
        "organization of the output file.  Valid inputs are \"bsq\", "
        "\"bil\", \"bip\".",
      "-swap (default = no swapping) (*MCRAW OUTPUT ONLY*)",
        "Optional argument for `-o', indicating that the byte order of "
        "each sample should be swapped before writing to file.",
      NULL}; /* Null terminator for arg array. */

   return(args);
}

/*****************************************************************************/
/* STATIC                         __push_line                                */
/*****************************************************************************/

static void
  __push_line(image_writer_ref base, ifc_int *line_buf, int component_idx,
	      int width)
{
   mcraw_image_writer_ref self = (mcraw_image_writer_ref) base;
   ifc_int *sp, val, mask, offset;
   int n;
   char *status;
  
   assert((component_idx < self->num_components) &&
	  (width == self->cols) && (self->current_row_idx < self->rows));
   
   /* Clip range excursions. */

   if (self->bitdepths[component_idx] < 32)
      mask = ((ifc_int)(-1)) << ((ifc_int) self->bitdepths[component_idx]);
   else
      mask = 0;
   offset = 0;
   if (self->is_signed[component_idx])
      offset = ((ifc_int) 1) << ((ifc_int)(self->bitdepths[component_idx]-1));
   for (sp=line_buf, n=width; n > 0; n--)
   {
      val = *sp;
      val += offset;
      if (val & mask)
	 val = (val<0)?0:(~mask);
      val -= offset;
      *(sp++) = val;
   }

   /* Pack output words. */

   switch (self->pack_bytes) {
      case 1:
	 {
	    std_byte *dp;

	    for (sp=line_buf, dp=(std_byte *) sp, n=width; n > 0; n--)
	       *(dp++) = (std_byte)(*(sp++));          
	 } 
	 break;
      case 2:
	 {
	    std_short *dp;

	    for (sp=line_buf, dp=(std_short *) sp, n=width; n > 0; n--)
	       *(dp++) = (std_short)(*(sp++));          
	 } 
	 break;
#if (IMPLEMENTATION_PRECISION >= 32)
      case 4:
	 {
	    std_int *dp;

	    for (sp=line_buf, dp=(std_int *) sp, n=width; n > 0; n--)
	       *(dp++) = (std_int)(*(sp++));          
	 }
	 break;
#endif /* IMPLEMENTATION_PRECISION >= 32 */
      default:
      assert(0);
   }

   /* See if we need to reverse the byte order. */
   
   if (self->reverse_byte_order)
   {
      if (self->pack_bytes == 2)
      {
	 std_short *dp, temp;
	 
	 for (dp=(std_short *) line_buf, n=width; n > 0; n--)
	 {
	    temp = *dp;
	    temp = ((temp >> 8) & 0x00FF) | (temp << 8);
	    *(dp++) = temp;
	 }
      }
      else if (self->pack_bytes == 4)
      {
	 std_int *dp, temp;
	 
	 for (dp=(std_int *) line_buf, n=width; n > 0; n--)
	 {
	    temp = *dp;
	    temp = ((temp>>24) & 0x000000FF) | ((temp>>8) & 0x0000FF00) |
	       ((temp<<8)  & 0x00FF0000) | (temp<<24);
	    *(dp++) = temp;
	 }
      }
   }

   /* Copy the *packed* line of data to the output buffer */

   memcpy((void *)self->line_buf[component_idx],
	  (void *)line_buf,
	  (self->cols * self->pack_bytes));
   self->comp_written_so_far++;

   if (self->comp_written_so_far == self->num_components) {

      /* This signals that a page should be written to disk */

      if ((status = writeBxP(self->line_buf, self->rows, self->cols, self->num_components, 
			    self->pack_bytes, self->data_org, self->skip_bytes, 
			    self->current_row_idx, self->fp))) {
	 local_error(status);
      }
      self->comp_written_so_far = 0;

      /* We write one image line at a time in order, so increment the 
	 row counter now */
      
      self->current_row_idx++;
   }
}

/*****************************************************************************/
/* STATIC                         __terminate                                */
/*****************************************************************************/

static void
  __terminate(image_writer_ref base)
{
   mcraw_image_writer_ref self = (mcraw_image_writer_ref) base;

   if (self->filename != NULL) {
      local_free((void *)self->filename);
   }
   if (self->fp != NULL) {
      fclose(self->fp);
   }
   if (self->bitdepths != NULL) {
      local_free((void *)self->bitdepths);
   }
   if (self->is_signed != NULL) {
      local_free((void *)self->is_signed);
   }
   if (self->line_buf != NULL) {
      local_free((void *)self->line_buf[0]);
      local_free((void *)self->line_buf);
   }
   local_free(self);
}

/*****************************************************************************/
/* EXTERN                   create_mcraw_image_writer                        */
/*****************************************************************************/

image_writer_ref
  create_mcraw_image_writer(void)
{
   mcraw_image_writer_ref result;

   result = (mcraw_image_writer_ref)
      local_malloc(IMAGE_IO_MEM_KEY,sizeof(mcraw_image_writer_obj));
   memset(result,0,sizeof(mcraw_image_writer_obj));
   result->base.initialize = __initialize;
   result->base.get_usage = __get_usage;
   result->base.push_line = __push_line;
   result->base.terminate = __terminate;
   return((image_writer_ref) result);
}

⌨️ 快捷键说明

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