📄 simple_image_writer.c
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company */
/* All rights reserved */
/* File: "simple_image_writer.c" */
/* Description: Simple implementation of the `image_writer' object */
/* Author: David Taubman */
/* Affiliation: Hewlett-Packard and */
/* The University of New South Wales, Australia */
/* Version: VM9.0 */
/* Last Revised: 18 April, 2001 */
/*****************************************************************************/
#include <local_services.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <image_io.h>
#include "simple_image_writer_local.h"
/* ========================================================================= */
/* ---------------------------- Internal Functions ------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC create_filename */
/*****************************************************************************/
static char *
create_filename(char *basename, char *ext, int idx, int is_mono,
char *default_ext)
{
char *filename;
int base_length;
base_length = strlen(basename);
if (ext != NULL)
base_length = (ext - basename);
filename = (char *)
local_malloc(IMAGE_IO_MEM_KEY,base_length+11);
strncpy(filename,basename,base_length);
if (!is_mono)
{
/* Begin Aerospace modification for zero-based indexing (JHK) */
#ifdef ZERO_INDEXING
sprintf(filename+base_length,"_%d",idx);
#else
sprintf(filename+base_length,"_%d",idx+1);
#endif
/* End Aerospace modifications for zero-based indexing (JHK) */
base_length = strlen(filename);
}
if (ext != NULL)
strcpy(filename+base_length,ext);
else
strcpy(filename+base_length,default_ext);
return(filename);
}
/* ========================================================================= */
/* ------------------------- Interface Implementation ---------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC __initialize */
/*****************************************************************************/
static void
__initialize(image_writer_ref base, int num_components,
int bitdepths[], canvas_dims_ptr dims,
/* Begin Aerospace MCT mods (TSW) */
int *dims_reference,
/* End Aerospace MCT mods */
cmdl_ref cmdl)
{
simple_image_writer_ref self = (simple_image_writer_ref) base;
image_component_ptr comp;
char *basename, *ext, **params;
int format; /* 1 for PGM, 2 for PGX, 0 for unknown. */
int p;
if ((p = cmdl->extract(cmdl,"-o",-1,¶ms)) != 1)
local_error("Must supply exactly one output file base name via the `-o' "
"argument!");
basename = params[0];
format = 0;
ext = strrchr(basename,'.');
if ((ext != NULL) && ((ext[1] == 'p') || (ext[1] == 'P')) &&
((ext[2] == 'g') || (ext[2] == 'G')))
{
if ((ext[3] == 'm') || (ext[3] == 'M'))
format = 1;
else if ((ext[3] == 'x') || (ext[3] == 'X'))
format = 2;
}
for (p=0; p < num_components; p++)
if (bitdepths[p] != 8)
{
if (format == 0)
format = 2;
else if (format != 2)
local_error("Cannot write PGM output files, since one "
"or more components have something other than an "
"unsigned 8-bit representation! You must use the "
"PGX file format!");
}
if (format == 0)
format = 1; /* Default to PGM. */
self->num_components = num_components;
self->components = (image_component_ptr)
local_malloc(IMAGE_IO_MEM_KEY,sizeof(image_component)*num_components);
memset(self->components,0,sizeof(image_component)*num_components);
for (p=0; p < num_components; p++)
{
comp = self->components + p;
/* Begin Aerospace MCT mods (TSW) */
/*comp->rows = comp->unwritten_rows = dims[p].rows;
comp->cols = dims[p].cols;*/
comp->rows = comp->unwritten_rows =
dims[dims_reference[p]].rows;
comp->cols = dims[dims_reference[p]].cols;
/* End Aeropsace MCT mods */
comp->bitdepth = bitdepths[p];
comp->is_signed = 0;
if (comp->bitdepth < 0)
{
comp->bitdepth = -comp->bitdepth;
comp->is_signed = 1;
}
if (comp->bitdepth <= 8)
comp->pack_bytes = 1;
else if (comp->bitdepth <= 16)
comp->pack_bytes = 2;
#if (IMPLEMENTATION_PRECISION >= 32)
else if (comp->bitdepth <= 32)
comp->pack_bytes = 4;
#endif /* IMPLEMENTATION_PRECISION >= 32 */
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!",comp->bitdepth);
comp->line_bytes = comp->cols * comp->pack_bytes;
comp->filename = create_filename(basename,ext,p,(num_components==1),
(format==1)?".pgm":".pgx");
comp->fp = fopen(comp->filename,"wb");
if (comp->fp == NULL)
local_printf(0,76,"Unable to open output file, \"%s\"!",
comp->filename);
if (format == 1)
fprintf(comp->fp,"P5\n%d %d\n255\n",comp->cols,comp->rows);
else
{
int lsb_first;
assert(format == 2);
lsb_first = 0;
((std_byte *)(&lsb_first))[0] = 1;
lsb_first = (lsb_first==1)?1:0;
fprintf(comp->fp,"PG %s %c%d %d %d\n",
((lsb_first)?"LM":"ML"),((comp->is_signed)?'-':' '),
comp->bitdepth,comp->cols,comp->rows);
}
}
}
/*****************************************************************************/
/* STATIC __get_usage */
/*****************************************************************************/
static char **
__get_usage(image_writer_ref base)
{
static char *args[] = {
"-o <image file>",
"Mandatory argument, identifying the base name of the file(s) to which "
"the decompressed image components will be written. The file format "
"is one of PGM or PGX, depending upon the suffix. If the suffix is "
"neither \".pgm\" nor \".pgx\" then the PGX format will be adopted "
"unless all components have 8-bit unsigned data, in which case the "
"PGM format will be selected, and the relevant extension will be "
"appended. PGX is a trivial monochrome file format defined just to "
"enable simple testing of JPEG2000 with image data having unusual "
"bit-depths. The file consists of a single text header line of the "
"form \"PG <byte order> [+|-]<bit-depth> <cols> <rows>\", "
"with the binary data appearing immediately after the newline "
"character, packed into 1, 2 or 4 bytes per sample, depending upon the "
"value of <bit-depth>. The <byte order> field is one of the fixed "
"strings, \"LM\" (LSB's first) or \"ML\" (MSB's first), while the "
"optional `+' (default) or `-' character preceding the <bit-depth> "
"field indicates whether the data is signed or not. If there are "
"multiple image components, suffices of the form, \"-1\", \"-2\", etc., "
"will be inserted immediately before the extension to identify the "
"individual components.",
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)
{
simple_image_writer_ref self = (simple_image_writer_ref) base;
image_component_ptr comp;
ifc_int *sp, val, mask, offset;
int n;
comp = self->components + component_idx;
assert((component_idx < self->num_components) &&
(width == comp->cols) && (comp->unwritten_rows > 0));
/* Clip range excursions. */
if (comp->bitdepth < 32)
mask = ((ifc_int)(-1)) << ((ifc_int) comp->bitdepth);
else
mask = 0;
offset = 0;
if (comp->is_signed)
offset = ((ifc_int) 1) << ((ifc_int)(comp->bitdepth-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 (comp->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);
}
/* Output line. */
if (fwrite(line_buf,1,(size_t)(comp->line_bytes),comp->fp) !=
(size_t)(comp->line_bytes))
local_error("Unable to finish writing to image output file, "
"\"%s\"!",comp->filename);
comp->unwritten_rows--;
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(image_writer_ref base)
{
simple_image_writer_ref self = (simple_image_writer_ref) base;
image_component_ptr comp;
int n;
if (self->components != NULL)
{
for (n=0; n < self->num_components; n++)
{
comp = self->components + n;
fclose(comp->fp);
local_free(comp->filename);
}
local_free(self->components);
}
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_simple_image_writer */
/*****************************************************************************/
image_writer_ref
create_simple_image_writer(void)
{
simple_image_writer_ref result;
result = (simple_image_writer_ref)
local_malloc(IMAGE_IO_MEM_KEY,sizeof(simple_image_writer_obj));
memset(result,0,sizeof(simple_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 + -