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

📄 tif_jpeg.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Header: /cvsroot/osrs/libtiff/libtiff/tif_jpeg.c,v 1.5 2001/07/20 15:00:35 warmerda Exp $ *//* * Copyright (c) 1994-1997 Sam Leffler * Copyright (c) 1994-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and  * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. *  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   *  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  * OF THIS SOFTWARE. */#include "tiffiop.h"#ifdef JPEG_SUPPORT/* * TIFF Library * * JPEG Compression support per TIFF Technical Note #2 * (*not* per the original TIFF 6.0 spec). * * This file is simply an interface to the libjpeg library written by * the Independent JPEG Group.  You need release 5 or later of the IJG * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/. * * Contributed by Tom Lane <tgl@sss.pgh.pa.us>. */#include <assert.h>#include <stdio.h>#include <setjmp.h>/* We undefine FAR to avoid conflict with JPEG definition */#ifdef FAR#undef FAR#endif/* The windows RPCNDR.H file defines boolean. */#ifdef __RPCNDR_H__#define HAVE_BOOLEAN#endif#include "..\jpeg\jpeglib.h"#include "..\jpeg\jerror.h"/* * On some machines it may be worthwhile to use _setjmp or sigsetjmp * in place of plain setjmp.  These macros will make it easier. */#define SETJMP(jbuf)		setjmp(jbuf)#define LONGJMP(jbuf,code)	longjmp(jbuf,code)#define JMP_BUF			jmp_buftypedef struct jpeg_destination_mgr jpeg_destination_mgr;typedef struct jpeg_source_mgr jpeg_source_mgr;typedef	struct jpeg_error_mgr jpeg_error_mgr;/* * State block for each open TIFF file using * libjpeg to do JPEG compression/decompression. * * libjpeg's visible state is either a jpeg_compress_struct * or jpeg_decompress_struct depending on which way we * are going.  comm can be used to refer to the fields * which are common to both. * * NB: cinfo is required to be the first member of JPEGState, *     so we can safely cast JPEGState* -> jpeg_xxx_struct* *     and vice versa! */typedef	struct {	union {		struct jpeg_compress_struct c;		struct jpeg_decompress_struct d;		struct jpeg_common_struct comm;	} cinfo;			/* NB: must be first */	jpeg_error_mgr	err;		/* libjpeg error manager */	JMP_BUF		exit_jmpbuf;	/* for catching libjpeg failures */	/*	 * The following two members could be a union, but	 * they're small enough that it's not worth the effort.	 */	jpeg_destination_mgr dest;	/* data dest for compression */	jpeg_source_mgr	src;		/* data source for decompression */					/* private state */	TIFF*		tif;		/* back link needed by some code */	uint16		photometric;	/* copy of PhotometricInterpretation */	uint16		h_sampling;	/* luminance sampling factors */	uint16		v_sampling;	tsize_t		bytesperline;	/* decompressed bytes per scanline */	/* pointers to intermediate buffers when processing downsampled data */	JSAMPARRAY	ds_buffer[MAX_COMPONENTS];	int		scancount;	/* number of "scanlines" accumulated */	int		samplesperclump;	TIFFVGetMethod	vgetparent;	/* super-class method */	TIFFVSetMethod	vsetparent;	/* super-class method */	TIFFStripMethod	defsparent;	/* super-class method */	TIFFTileMethod	deftparent;	/* super-class method */					/* pseudo-tag fields */	void*		jpegtables;	/* JPEGTables tag value, or NULL */	uint32		jpegtables_length; /* number of bytes in same */	int		jpegquality;	/* Compression quality level */	int		jpegcolormode;	/* Auto RGB<=>YCbCr convert? */	int		jpegtablesmode;	/* What to put in JPEGTables */} JPEGState;#define	JState(tif)	((JPEGState*)(tif)->tif_data)static	int JPEGDecode(TIFF*, tidata_t, tsize_t, tsample_t);static	int JPEGDecodeRaw(TIFF*, tidata_t, tsize_t, tsample_t);static	int JPEGEncode(TIFF*, tidata_t, tsize_t, tsample_t);static	int JPEGEncodeRaw(TIFF*, tidata_t, tsize_t, tsample_t);#define	FIELD_JPEGTABLES	(FIELD_CODEC+0)static const TIFFFieldInfo jpegFieldInfo[] = {    { TIFFTAG_JPEGTABLES,	 -1,-1,	TIFF_UNDEFINED,	FIELD_JPEGTABLES,      FALSE,	TRUE,	"JPEGTables" },    { TIFFTAG_JPEGQUALITY,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,      TRUE,	FALSE,	"" },    { TIFFTAG_JPEGCOLORMODE,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,      FALSE,	FALSE,	"" },    { TIFFTAG_JPEGTABLESMODE,	 0, 0,	TIFF_ANY,	FIELD_PSEUDO,      FALSE,	FALSE,	"" },};#define	N(a)	(sizeof (a) / sizeof (a[0]))/* * libjpeg interface layer. * * We use setjmp/longjmp to return control to libtiff * when a fatal error is encountered within the JPEG * library.  We also direct libjpeg error and warning * messages through the appropriate libtiff handlers. *//* * Error handling routines (these replace corresponding * IJG routines from jerror.c).  These are used for both * compression and decompression. */static voidTIFFjpeg_error_exit(j_common_ptr cinfo){	JPEGState *sp = (JPEGState *) cinfo;	/* NB: cinfo assumed first */	char buffer[JMSG_LENGTH_MAX];	(*cinfo->err->format_message) (cinfo, buffer);	TIFFError("JPEGLib", buffer);		/* display the error message */	jpeg_abort(cinfo);			/* clean up libjpeg state */	LONGJMP(sp->exit_jmpbuf, 1);		/* return to libtiff caller */}/* * This routine is invoked only for warning messages, * since error_exit does its own thing and trace_level * is never set > 0. */static voidTIFFjpeg_output_message(j_common_ptr cinfo){	char buffer[JMSG_LENGTH_MAX];	(*cinfo->err->format_message) (cinfo, buffer);	TIFFWarning("JPEGLib", buffer);}/* * Interface routines.  This layer of routines exists * primarily to limit side-effects from using setjmp. * Also, normal/error returns are converted into return * values per libtiff practice. */#define	CALLJPEG(sp, fail, op)	(SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))#define	CALLVJPEG(sp, op)	CALLJPEG(sp, 0, ((op),1))static intTIFFjpeg_create_compress(JPEGState* sp){	/* initialize JPEG error handling */	sp->cinfo.c.err = jpeg_std_error(&sp->err);	sp->err.error_exit = TIFFjpeg_error_exit;	sp->err.output_message = TIFFjpeg_output_message;	return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));}static intTIFFjpeg_create_decompress(JPEGState* sp){	/* initialize JPEG error handling */	sp->cinfo.d.err = jpeg_std_error(&sp->err);	sp->err.error_exit = TIFFjpeg_error_exit;	sp->err.output_message = TIFFjpeg_output_message;	return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));}static intTIFFjpeg_set_defaults(JPEGState* sp){	return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));}static intTIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace){	return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));}static intTIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline){	return CALLVJPEG(sp,	    jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));}static intTIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress){	return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));}static intTIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables){	return CALLVJPEG(sp,	    jpeg_start_compress(&sp->cinfo.c, write_all_tables));}static intTIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines){	return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,	    scanlines, (JDIMENSION) num_lines));}static intTIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines){	return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c,	    data, (JDIMENSION) num_lines));}static intTIFFjpeg_finish_compress(JPEGState* sp){	return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));}static intTIFFjpeg_write_tables(JPEGState* sp){	return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));}static intTIFFjpeg_read_header(JPEGState* sp, boolean require_image){	return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));}static intTIFFjpeg_start_decompress(JPEGState* sp){	return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));}static intTIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines){	return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,	    scanlines, (JDIMENSION) max_lines));}static intTIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines){	return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d,	    data, (JDIMENSION) max_lines));}static intTIFFjpeg_finish_decompress(JPEGState* sp){	return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d));}static intTIFFjpeg_abort(JPEGState* sp){	return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));}static intTIFFjpeg_destroy(JPEGState* sp){	return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));}static JSAMPARRAYTIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id,		      JDIMENSION samplesperrow, JDIMENSION numrows){	return CALLJPEG(sp, (JSAMPARRAY) NULL,	    (*sp->cinfo.comm.mem->alloc_sarray)		(&sp->cinfo.comm, pool_id, samplesperrow, numrows));}/* * JPEG library destination data manager. * These routines direct compressed data from libjpeg into the * libtiff output buffer. */static voidstd_init_destination(j_compress_ptr cinfo){	JPEGState* sp = (JPEGState*) cinfo;	TIFF* tif = sp->tif;	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;}static booleanstd_empty_output_buffer(j_compress_ptr cinfo){	JPEGState* sp = (JPEGState*) cinfo;	TIFF* tif = sp->tif;	/* the entire buffer has been filled */	tif->tif_rawcc = tif->tif_rawdatasize;	TIFFFlushData1(tif);	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;	return (TRUE);}static voidstd_term_destination(j_compress_ptr cinfo){	JPEGState* sp = (JPEGState*) cinfo;	TIFF* tif = sp->tif;	tif->tif_rawcp = (tidata_t) sp->dest.next_output_byte;	tif->tif_rawcc =	    tif->tif_rawdatasize - (tsize_t) sp->dest.free_in_buffer;	/* NB: libtiff does the final buffer flush */}static voidTIFFjpeg_data_dest(JPEGState* sp, TIFF* tif){	(void) tif;	sp->cinfo.c.dest = &sp->dest;	sp->dest.init_destination = std_init_destination;	sp->dest.empty_output_buffer = std_empty_output_buffer;	sp->dest.term_destination = std_term_destination;}/* * Alternate destination manager for outputting to JPEGTables field. */static voidtables_init_destination(j_compress_ptr cinfo){	JPEGState* sp = (JPEGState*) cinfo;	/* while building, jpegtables_length is allocated buffer size */	sp->dest.next_output_byte = (JOCTET*) sp->jpegtables;	sp->dest.free_in_buffer = (size_t) sp->jpegtables_length;}static booleantables_empty_output_buffer(j_compress_ptr cinfo){	JPEGState* sp = (JPEGState*) cinfo;	void* newbuf;	/* the entire buffer has been filled; enlarge it by 1000 bytes */	newbuf = _TIFFrealloc((tdata_t) sp->jpegtables,			      (tsize_t) (sp->jpegtables_length + 1000));	if (newbuf == NULL)		ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);	sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length;	sp->dest.free_in_buffer = (size_t) 1000;	sp->jpegtables = newbuf;	sp->jpegtables_length += 1000;	return (TRUE);}static voidtables_term_destination(j_compress_ptr cinfo){	JPEGState* sp = (JPEGState*) cinfo;	/* set tables length to number of bytes actually emitted */	sp->jpegtables_length -= sp->dest.free_in_buffer;}static intTIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif){	(void) tif;	/*	 * Allocate a working buffer for building tables.	 * Initial size is 1000 bytes, which is usually adequate.	 */	if (sp->jpegtables)		_TIFFfree(sp->jpegtables);	sp->jpegtables_length = 1000;	sp->jpegtables = (void*) _TIFFmalloc((tsize_t) sp->jpegtables_length);	if (sp->jpegtables == NULL) {		sp->jpegtables_length = 0;		TIFFError("TIFFjpeg_tables_dest", "No space for JPEGTables");		return (0);	}	sp->cinfo.c.dest = &sp->dest;	sp->dest.init_destination = tables_init_destination;	sp->dest.empty_output_buffer = tables_empty_output_buffer;	sp->dest.term_destination = tables_term_destination;	return (1);}/* * JPEG library source data manager. * These routines supply compressed data to libjpeg. */static voidstd_init_source(j_decompress_ptr cinfo){	JPEGState* sp = (JPEGState*) cinfo;	TIFF* tif = sp->tif;	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata;	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;}static booleanstd_fill_input_buffer(j_decompress_ptr cinfo){	JPEGState* sp = (JPEGState* ) cinfo;	static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI };	/*	 * Should never get here since entire strip/tile is	 * read into memory before the decompressor is called,	 * and thus was supplied by init_source.	 */	WARNMS(cinfo, JWRN_JPEG_EOF);	/* insert a fake EOI marker */	sp->src.next_input_byte = dummy_EOI;	sp->src.bytes_in_buffer = 2;	return (TRUE);}static voidstd_skip_input_data(j_decompress_ptr cinfo, long num_bytes){	JPEGState* sp = (JPEGState*) cinfo;	if (num_bytes > 0) {		if (num_bytes > (long) sp->src.bytes_in_buffer) {			/* oops, buffer overrun */			(void) std_fill_input_buffer(cinfo);		} else {			sp->src.next_input_byte += (size_t) num_bytes;			sp->src.bytes_in_buffer -= (size_t) num_bytes;		}	}}static voidstd_term_source(j_decompress_ptr cinfo){

⌨️ 快捷键说明

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