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

📄 simple_image_writer.c

📁 JPEG2000实现的源码
💻 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,&params)) != 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 + -