📄 mcraw_image_writer.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,¶ms)) == 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,¶ms)) == 1) {
self->pack_bytes = atoi(params[0]);
}
if ((p = cmdl->extract(cmdl,"-do",-1,¶ms)) == 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,¶ms)) == 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 + -