📄 tif_ojpeg.c
字号:
bad_photometry[]={"PhotometricInterpretation %u not allowed for JPEG"}, bad_subsampling[]={"invalid YCbCr subsampling factor(s)"},# ifdef never no_write_frac[]={"fractional scan line discarded"},# endif no_read_frac[]={"fractional scan line not read"}, no_jtable_space[]={"No space for JPEGTables"};/* The following diagnostic subroutines interface with and replace default subroutines in the JPEG Library. Our basic strategy is to use "setjmp()"/ "longjmp()" in order to return control to the TIFF Library when the JPEG library detects an error, and to use TIFF Library subroutines for displaying diagnostic messages to a client application.*/static voidTIFFojpeg_error_exit(register j_common_ptr cinfo){ char buffer[JMSG_LENGTH_MAX]; int code = cinfo->err->msg_code; if (((OJPEGState *)cinfo)->is_WANG) { if (code == JERR_SOF_DUPLICATE || code == JERR_SOI_DUPLICATE) return; /* ignore it */ } (*cinfo->err->format_message)(cinfo,buffer); TIFFError(JPEGLib_name,buffer); /* Display error message */ jpeg_abort(cinfo); /* Clean up JPEG Library state */ LONGJMP(((OJPEGState *)cinfo)->exit_jmpbuf,1); /* Return to TIFF client */}static voidTIFFojpeg_output_message(register j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; /* This subroutine is invoked only for warning messages, since the JPEG Library's "error_exit" method does its own thing and "trace_level" is never set > 0. */ (*cinfo->err->format_message)(cinfo,buffer); TIFFWarning(JPEGLib_name,buffer); }/* The following subroutines, which also interface with the JPEG Library, exist mainly in limit the side effects of "setjmp()" and convert JPEG normal/error conditions into TIFF Library return codes.*/#define CALLJPEG(sp,fail,op)(SETJMP((sp)->exit_jmpbuf)?(fail):(op))#define CALLVJPEG(sp,op)CALLJPEG(sp,0,((op),1))#ifdef neverstatic intTIFFojpeg_create_compress(register OJPEGState *sp) { sp->cinfo.c.err = jpeg_std_error(&sp->err); /* Initialize error handling */ sp->err.error_exit = TIFFojpeg_error_exit; sp->err.output_message = TIFFojpeg_output_message; return CALLVJPEG(sp,jpeg_create_compress(&sp->cinfo.c)); }/* The following subroutines comprise a JPEG Library "destination" data manager by directing compressed data from the JPEG Library to a TIFF Library output buffer.*/static voidstd_init_destination(register j_compress_ptr cinfo){} /* "Dummy" stub */static booleanstd_empty_output_buffer(register j_compress_ptr cinfo) {# define sp ((OJPEGState *)cinfo) register TIFF *tif = sp->tif; tif->tif_rawcc = tif->tif_rawdatasize; /* Entire buffer has been filled */ TIFFFlushData1(tif); sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; return TRUE;# undef sp }static voidstd_term_destination(register j_compress_ptr cinfo) {# define sp ((OJPEGState *)cinfo) register TIFF *tif = sp->tif; /* NB: The TIFF Library does the final buffer flush. */ tif->tif_rawcp = (tidata_t)sp->dest.next_output_byte; tif->tif_rawcc = tif->tif_rawdatasize - (tsize_t)sp->dest.free_in_buffer;# undef sp }/* Alternate destination manager to output JPEGTables field: */static voidtables_init_destination(register j_compress_ptr cinfo) {# define sp ((OJPEGState *)cinfo) /* The "jpegtables_length" field is the allocated buffer size while building */ sp->dest.next_output_byte = (JOCTET *)sp->jpegtables; sp->dest.free_in_buffer = (size_t)sp->jpegtables_length;# undef sp }static booleantables_empty_output_buffer(register j_compress_ptr cinfo) { void *newbuf;# define sp ((OJPEGState *)cinfo) /* The entire buffer has been filled, so enlarge it by 1000 bytes. */ if (!( newbuf = _TIFFrealloc( (tdata_t)sp->jpegtables , (tsize_t)(sp->jpegtables_length + 1000) ) ) ) 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;# undef sp }static voidtables_term_destination(register j_compress_ptr cinfo) {# define sp ((OJPEGState *)cinfo) /* Set tables length to no. of Bytes actually emitted. */ sp->jpegtables_length -= sp->dest.free_in_buffer;# undef sp }/*ARGSUSED*/ static intTIFFojpeg_tables_dest(register OJPEGState *sp, TIFF *tif) { /* Allocate a working buffer for building tables. The initial size is 1000 Bytes, which is usually adequate. */ if (sp->jpegtables) _TIFFfree(sp->jpegtables); if (!(sp->jpegtables = (void*) _TIFFmalloc((tsize_t)(sp->jpegtables_length = 1000)) ) ) { sp->jpegtables_length = 0; TIFFError("TIFFojpeg_tables_dest",no_jtable_space); 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; }#else /* well, hardly ever */static int_notSupported(register TIFF *tif) { const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); TIFFError(tif->tif_name,"%s compression not supported",c->name); return 0; }#endif /* never *//* The following subroutines comprise a JPEG Library "source" data manager by by directing compressed data to the JPEG Library from a TIFF Library input buffer.*/static voidstd_init_source(register j_decompress_ptr cinfo) {# define sp ((OJPEGState *)cinfo) register TIFF *tif = sp->tif; if (sp->src.bytes_in_buffer == 0) { sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata; sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; };# undef sp }static booleanstd_fill_input_buffer(register j_decompress_ptr cinfo) { static const JOCTET dummy_EOI[2]={0xFF,JPEG_EOI};# define sp ((OJPEGState *)cinfo) /* Control should never get here, since an entire strip/tile is read into memory before the decompressor is called; thus, data should have been supplied by the "init_source" method. ...But, sometimes things fail. */ WARNMS(cinfo,JWRN_JPEG_EOF); sp->src.next_input_byte = dummy_EOI; /* Insert a fake EOI marker */ sp->src.bytes_in_buffer = sizeof dummy_EOI; return TRUE;# undef sp }static voidstd_skip_input_data(register j_decompress_ptr cinfo, long num_bytes) {# define sp ((OJPEGState *)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; } }# undef sp }/*ARGSUSED*/ static voidstd_term_source(register j_decompress_ptr cinfo){} /* "Dummy" stub *//* Allocate temporary I/O buffers for downsampled data, using values computed in "jpeg_start_{de}compress()". We use the JPEG Library's allocator so that buffers will be released automatically when done with a strip/tile. This is also a handy place to compute samplesperclump, bytesperline, etc.*/static intalloc_downsampled_buffers(TIFF *tif,jpeg_component_info *comp_info, int num_components) { register OJPEGState *sp = OJState(tif); sp->samplesperclump = 0; if (num_components > 0) { tsize_t size = sp->cinfo.comm.is_decompressor# ifdef D_LOSSLESS_SUPPORTED ? sp->cinfo.d.min_codec_data_unit# else ? DCTSIZE# endif# ifdef C_LOSSLESS_SUPPORTED : sp->cinfo.c.data_unit;# else : DCTSIZE;# endif int ci = 0; register jpeg_component_info *compptr = comp_info; do { JSAMPARRAY buf; sp->samplesperclump += compptr->h_samp_factor * compptr->v_samp_factor;# if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED) if (!(buf = CALLJPEG(sp,0,(*sp->cinfo.comm.mem->alloc_sarray)(&sp->cinfo.comm,JPOOL_IMAGE,compptr->width_in_data_units*size,compptr->v_samp_factor*size))))# else if (!(buf = CALLJPEG(sp,0,(*sp->cinfo.comm.mem->alloc_sarray)(&sp->cinfo.comm,JPOOL_IMAGE,compptr->width_in_blocks*size,compptr->v_samp_factor*size))))# endif return 0; sp->ds_buffer[ci] = buf; } while (++compptr,++ci < num_components); }; return 1; }#ifdef never/* JPEG Encoding begins here. *//*ARGSUSED*/ static intOJPEGEncode(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s) { tsize_t rows; /* No. of unprocessed rows in file */ register OJPEGState *sp = OJState(tif); /* Encode a chunk of pixels, where returned data is NOT down-sampled (the standard case). The data is expected to be written in scan-line multiples. */ if (cc % sp->bytesperline) TIFFWarning(tif->tif_name,no_write_frac); if ( (cc /= bytesperline) /* No. of complete rows in caller's buffer */ > (rows = sp->cinfo.c.image_height - sp->cinfo.c.next_scanline) ) cc = rows; while (--cc >= 0) { if ( CALLJPEG(sp,-1,jpeg_write_scanlines(&sp->cinfo.c,(JSAMPARRAY)&buf,1)) != 1 ) return 0; ++tif->tif_row; buf += sp->bytesperline; }; return 1; }/*ARGSUSED*/ static intOJPEGEncodeRaw(register TIFF *tif,tidata_t buf,tsize_t cc,tsample_t s) { tsize_t rows; /* No. of unprocessed rows in file */ JDIMENSION lines_per_MCU, size; register OJPEGState *sp = OJState(tif); /* Encode a chunk of pixels, where returned data is down-sampled as per the sampling factors. The data is expected to be written in scan-line multiples. */ cc /= sp->bytesperline; if (cc % sp->bytesperline) TIFFWarning(tif->tif_name,no_write_frac); if ( (cc /= bytesperline) /* No. of complete rows in caller's buffer */ > (rows = sp->cinfo.c.image_height - sp->cinfo.c.next_scanline) ) cc = rows;# ifdef C_LOSSLESS_SUPPORTED lines_per_MCU = sp->cinfo.c.max_samp_factor*(size = sp->cinfo.d.data_unit);# else lines_per_MCU = sp->cinfo.c.max_samp_factor*(size = DCTSIZE);# endif while (--cc >= 0) { int ci = 0, clumpoffset = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -