diff options
-rw-r--r-- | TODO | 6 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/Makefile.in | 7 | ||||
-rw-r--r-- | src/imlib.c | 6 | ||||
-rw-r--r-- | src/jpegint.h | 388 | ||||
-rw-r--r-- | src/transupp.c | 1244 | ||||
-rw-r--r-- | src/transupp.h | 125 |
7 files changed, 5 insertions, 1776 deletions
@@ -27,9 +27,3 @@ Control thumbnail mode (image selection, mainly) with keys. Xinerama support is present, but far from perfect. Some day I will debug that, I guess. - -Lossless rotation is horribly broken. The code was copied from libjpeg6b -and does not work with libjpeg8. However, it _has_ to be copied because -the rotation functions are not available externally. -Executing the jpegtran binary from inside feh is probably the best way -to "fix" this... diff --git a/src/Makefile.am b/src/Makefile.am index 1dbc0f0..b87f0e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,9 +14,8 @@ feh_SOURCES = main.c getopt.c getopt1.c getopt.h feh.h \ options.c options.h winwidget.c winwidget.h menu.c menu.h structs.h \ filelist.c filelist.h multiwindow.c imlib.c index.c slideshow.c \ utils.c utils.h keyevents.c timers.c timers.h list.c collage.c debug.h \ -events.c events.h support.c support.h transupp.c transupp.h \ -thumbnail.c thumbnail.h ipc.c ipc.h md5.c md5.h feh_png.c feh_png.h \ -jpegint.h +events.c events.h support.c support.h \ +thumbnail.c thumbnail.h ipc.c ipc.h md5.c md5.h feh_png.c feh_png.h feh_LDADD = -lX11 -lz -lpng @IMLIB_LIBS@ @GIBLIB_LIBS@ diff --git a/src/Makefile.in b/src/Makefile.in index 815f187..1476066 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -88,7 +88,7 @@ INCLUDES = -I/usr/X11R6/include $(X_CFLAGS) -I$(prefix)/incl LIBOBJS = @LIBOBJS@ bin_PROGRAMS = feh -feh_SOURCES = main.c getopt.c getopt1.c getopt.h feh.h options.c options.h winwidget.c winwidget.h menu.c menu.h structs.h filelist.c filelist.h multiwindow.c imlib.c index.c slideshow.c utils.c utils.h keyevents.c timers.c timers.h list.c collage.c debug.h events.c events.h support.c support.h transupp.c transupp.h thumbnail.c thumbnail.h ipc.c ipc.h md5.c md5.h feh_png.c feh_png.h jpegint.h +feh_SOURCES = main.c getopt.c getopt1.c getopt.h feh.h options.c options.h winwidget.c winwidget.h menu.c menu.h structs.h filelist.c filelist.h multiwindow.c imlib.c index.c slideshow.c utils.c utils.h keyevents.c timers.c timers.h list.c collage.c debug.h events.c events.h support.c support.h thumbnail.c thumbnail.h ipc.c ipc.h md5.c md5.h feh_png.c feh_png.h feh_LDADD = -lX11 -lz -lpng @IMLIB_LIBS@ @GIBLIB_LIBS@ @@ -111,7 +111,7 @@ CPPFLAGS = @CPPFLAGS@ LIBS = @LIBS@ feh_OBJECTS = main.o getopt.o getopt1.o options.o winwidget.o menu.o \ filelist.o multiwindow.o imlib.o index.o slideshow.o utils.o \ -keyevents.o timers.o list.o collage.o events.o support.o transupp.o \ +keyevents.o timers.o list.o collage.o events.o support.o \ thumbnail.o ipc.o md5.o feh_png.o feh_DEPENDENCIES = feh_LDFLAGS = @@ -363,7 +363,7 @@ filelist.o: filelist.c feh.h config.h getopt.h structs.h menu.h ipc.h \ getopt.o: getopt.c config.h getopt1.o: getopt1.c config.h getopt.h imlib.o: imlib.c feh.h config.h getopt.h structs.h menu.h ipc.h utils.h \ - debug.h filelist.h winwidget.h options.h transupp.h + debug.h filelist.h winwidget.h options.h index.o: index.c feh.h config.h getopt.h structs.h menu.h ipc.h utils.h \ debug.h filelist.h winwidget.h options.h ipc.o: ipc.c feh.h config.h getopt.h structs.h menu.h ipc.h utils.h \ @@ -391,7 +391,6 @@ thumbnail.o: thumbnail.c feh.h config.h getopt.h structs.h menu.h ipc.h \ md5.h feh_png.h timers.o: timers.c feh.h config.h getopt.h structs.h menu.h ipc.h \ utils.h debug.h options.h timers.h -transupp.o: transupp.c transupp.h utils.o: utils.c feh.h config.h getopt.h structs.h menu.h ipc.h utils.h \ debug.h options.h winwidget.o: winwidget.c feh.h config.h getopt.h structs.h menu.h ipc.h \ diff --git a/src/imlib.c b/src/imlib.c index 6051206..acdbc4f 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -33,9 +33,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> -#include <jpeglib.h> - -#include "transupp.h" Display *disp = NULL; Visual *vis = NULL; @@ -968,9 +965,6 @@ gib_list *feh_wrap_string(char *text, int wrap_width, int max_height, Imlib_Font void feh_edit_inplace_lossless_rotate(winwidget w, int orientation) { - struct jpeg_decompress_struct srcinfo; - struct jpeg_compress_struct dstinfo; - struct jpeg_error_mgr jsrcerr, jdsterr; char *filename = FEH_FILE(w->file->data)->filename; int len = 44 + (strlen(filename) * 2); char *command = emalloc(len); diff --git a/src/jpegint.h b/src/jpegint.h deleted file mode 100644 index e55a2be..0000000 --- a/src/jpegint.h +++ /dev/null @@ -1,388 +0,0 @@ -/* - * jpegint.h - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides common declarations for the various JPEG modules. - * These declarations are considered internal to the JPEG library; most - * applications using the library shouldn't need to include this file. - */ - -/* Declarations for both compression & decompression */ - -typedef enum { /* Operating modes for buffer controllers */ - JBUF_PASS_THRU, /* Plain stripwise operation */ - /* Remaining modes require a full-image buffer to have been created */ - JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ - JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ - JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ -} J_BUF_MODE; - -/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ -#define CSTATE_START 100 /* after create_compress */ -#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ -#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ -#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ -#define DSTATE_START 200 /* after create_decompress */ -#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ -#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ -#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress */ -#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ -#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ -#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ -#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ -#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ -#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ -#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ - -/* Declarations for compression modules */ - -/* Master control module */ -struct jpeg_comp_master { - JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); - JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean call_pass_startup; /* True if pass_startup must be called */ - boolean is_last_pass; /* True during last pass */ -}; - -/* Main buffer control (downsampled-data buffer) */ -struct jpeg_c_main_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, - (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION * in_row_ctr, JDIMENSION in_rows_avail)); -}; - -/* Compression preprocessing (downsampling input buffer control) */ -struct jpeg_c_prep_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, pre_process_data, - (j_compress_ptr cinfo, JSAMPARRAY input_buf, - JDIMENSION * in_row_ctr, JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, JDIMENSION * out_row_group_ctr, JDIMENSION out_row_groups_avail)); -}; - -/* Coefficient buffer control */ -struct jpeg_c_coef_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, JSAMPIMAGE input_buf)); -}; - -/* Colorspace conversion */ -struct jpeg_color_converter { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, color_convert, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, - JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)); -}; - -/* Downsampling */ -struct jpeg_downsampler { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, downsample, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION in_row_index, JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)); - - boolean need_context_rows; /* TRUE if need rows above & below */ -}; - -/* Forward DCT (also controls coefficient quantization) */ -struct jpeg_forward_dct { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - /* perhaps this should be an array??? */ - JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, - jpeg_component_info * compptr, - JSAMPARRAY sample_data, - JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, JDIMENSION num_blocks)); -}; - -/* Entropy encoding */ -struct jpeg_entropy_encoder { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); - JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW * MCU_data)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); -}; - -/* Marker writing */ -struct jpeg_marker_writer { - JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); - JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); - /* These routines are exported to allow insertion of extra markers */ - /* Probably only COM and APPn markers should be written this way */ - JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, unsigned int datalen)); - JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); -}; - -/* Declarations for decompression modules */ - -/* Master control module */ -struct jpeg_decomp_master { - JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ -}; - -/* Input control module */ -struct jpeg_input_controller { - JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); - JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean has_multiple_scans; /* True if file has multiple scans */ - boolean eoi_reached; /* True when EOI has been consumed */ -}; - -/* Main buffer control (downsampled-data buffer) */ -struct jpeg_d_main_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, - (j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION * out_row_ctr, JDIMENSION out_rows_avail)); -}; - -/* Coefficient buffer control */ -struct jpeg_d_coef_controller { - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); - JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); - /* Pointer to array of coefficient virtual arrays, or NULL if none */ - jvirt_barray_ptr *coef_arrays; -}; - -/* Decompression postprocessing (color quantization buffer control) */ -struct jpeg_d_post_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, post_process_data, - (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, - JDIMENSION * in_row_group_ctr, - JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf, - JDIMENSION * out_row_ctr, JDIMENSION out_rows_avail)); -}; - -/* Marker reading & parsing */ -struct jpeg_marker_reader { - JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); - /* Read markers until SOS or EOI. - * Returns same codes as are defined for jpeg_consume_input: - * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - */ - JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); - /* Read a restart marker --- exported for use by entropy decoder only */ - jpeg_marker_parser_method read_restart_marker; - - /* State of marker reader --- nominally internal, but applications - * supplying COM or APPn handlers might like to know the state. - */ - boolean saw_SOI; /* found SOI? */ - boolean saw_SOF; /* found SOF? */ - int next_restart_num; /* next restart number expected (0-7) */ - unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ -}; - -/* Entropy decoding */ -struct jpeg_entropy_decoder { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKROW * MCU_data)); - - /* This is here to share code between baseline and progressive decoders; */ - /* other modules probably should not use it */ - boolean insufficient_data; /* set TRUE after emitting warning */ -}; - -/* Inverse DCT (also performs dequantization) */ -typedef JMETHOD(void, inverse_DCT_method_ptr, - (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); - -struct jpeg_inverse_dct { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - /* It is useful to allow each component to have a separate IDCT method. */ - inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; -}; - -/* Upsampling (note that upsampler must also call color converter) */ -struct jpeg_upsampler { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, upsample, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION * in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION * out_row_ctr, JDIMENSION out_rows_avail)); - - boolean need_context_rows; /* TRUE if need rows above & below */ -}; - -/* Colorspace conversion */ -struct jpeg_color_deconverter { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, color_convert, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)); -}; - -/* Color quantization or color precision reduction */ -struct jpeg_color_quantizer { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); - JMETHOD(void, color_quantize, - (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)); - JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); -}; - -/* Miscellaneous useful macros */ - -#undef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#undef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -/* We assume that right shift corresponds to signed division by 2 with - * rounding towards minus infinity. This is correct for typical "arithmetic - * shift" instructions that shift in copies of the sign bit. But some - * C compilers implement >> with an unsigned shift. For these machines you - * must define RIGHT_SHIFT_IS_UNSIGNED. - * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. - * It is only applied with constant shift counts. SHIFT_TEMPS must be - * included in the variables of any routine using RIGHT_SHIFT. - */ - -#ifdef RIGHT_SHIFT_IS_UNSIGNED -#define SHIFT_TEMPS INT32 shift_temp; -#define RIGHT_SHIFT(x,shft) \ - ((shift_temp = (x)) < 0 ? \ - (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ - (shift_temp >> (shft))) -#else -#define SHIFT_TEMPS -#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) -#endif - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jinit_compress_master jICompress -#define jinit_c_master_control jICMaster -#define jinit_c_main_controller jICMainC -#define jinit_c_prep_controller jICPrepC -#define jinit_c_coef_controller jICCoefC -#define jinit_color_converter jICColor -#define jinit_downsampler jIDownsampler -#define jinit_forward_dct jIFDCT -#define jinit_huff_encoder jIHEncoder -#define jinit_phuff_encoder jIPHEncoder -#define jinit_marker_writer jIMWriter -#define jinit_master_decompress jIDMaster -#define jinit_d_main_controller jIDMainC -#define jinit_d_coef_controller jIDCoefC -#define jinit_d_post_controller jIDPostC -#define jinit_input_controller jIInCtlr -#define jinit_marker_reader jIMReader -#define jinit_huff_decoder jIHDecoder -#define jinit_phuff_decoder jIPHDecoder -#define jinit_inverse_dct jIIDCT -#define jinit_upsampler jIUpsampler -#define jinit_color_deconverter jIDColor -#define jinit_1pass_quantizer jI1Quant -#define jinit_2pass_quantizer jI2Quant -#define jinit_merged_upsampler jIMUpsampler -#define jinit_memory_mgr jIMemMgr -#define jdiv_round_up jDivRound -#define jround_up jRound -#define jcopy_sample_rows jCopySamples -#define jcopy_block_row jCopyBlocks -#define jzero_far jZeroFar -#define jpeg_zigzag_order jZIGTable -#define jpeg_natural_order jZAGTable -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - -/* Compression module initialization routines */ -EXTERN(void) -jinit_compress_master JPP((j_compress_ptr cinfo)); -EXTERN(void) -jinit_c_master_control JPP((j_compress_ptr cinfo, boolean transcode_only)); -EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, boolean need_full_buffer)); -EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, boolean need_full_buffer)); -EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, boolean need_full_buffer)); -EXTERN(void) -jinit_color_converter JPP((j_compress_ptr cinfo)); -EXTERN(void) -jinit_downsampler JPP((j_compress_ptr cinfo)); -EXTERN(void) -jinit_forward_dct JPP((j_compress_ptr cinfo)); -EXTERN(void) -jinit_huff_encoder JPP((j_compress_ptr cinfo)); -EXTERN(void) -jinit_phuff_encoder JPP((j_compress_ptr cinfo)); -EXTERN(void) -jinit_marker_writer JPP((j_compress_ptr cinfo)); -/* Decompression module initialization routines */ -EXTERN(void) -jinit_master_decompress JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, boolean need_full_buffer)); -EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, boolean need_full_buffer)); -EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, boolean need_full_buffer)); -EXTERN(void) -jinit_input_controller JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_marker_reader JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_huff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_inverse_dct JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_upsampler JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_color_deconverter JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN(void) -jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); -/* Memory manager initialization */ -EXTERN(void) -jinit_memory_mgr JPP((j_common_ptr cinfo)); - -/* Utility routines in jutils.c */ -EXTERN(long) -jdiv_round_up JPP((long a, long b)); -EXTERN(long) -jround_up JPP((long a, long b)); -EXTERN(void) -jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, int num_rows, JDIMENSION num_cols)); -EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, JDIMENSION num_blocks)); -EXTERN(void) -jzero_far JPP((void FAR * target, size_t bytestozero)); -/* Constant tables in jutils.c */ -#if 0 /* This table is not actually needed in v6a */ -extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ -#endif -extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ - -/* Suppress undefined-structure complaints if necessary. */ - -#ifdef INCOMPLETE_TYPES_BROKEN -#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ -struct jvirt_sarray_control { - long dummy; -}; -struct jvirt_barray_control { - long dummy; -}; -#endif -#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/src/transupp.c b/src/transupp.c deleted file mode 100644 index 162cc3f..0000000 --- a/src/transupp.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* - * transupp.c - * - * Copyright (C) 1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains image transformation routines and other utility code - * used by the jpegtran sample application. These are NOT part of the core - * JPEG library. But we keep these routines separate from jpegtran.c to - * ease the task of maintaining jpegtran-like programs that have other user - * interfaces. - */ - -/* Although this file really shouldn't have access to the library internals, - * it's helpful to let it call jround_up() and jcopy_block_row(). - */ -#define JPEG_INTERNALS - -#include <stddef.h> -#include <stdlib.h> -#include <sys/types.h> -#include <stdio.h> - -#include <string.h> -#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) -#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) -#define SIZEOF(object) ((size_t) sizeof(object)) -#define JFREAD(file,buf,sizeofbuf) \ - ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) -#define JFWRITE(file,buf,sizeofbuf) \ - ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) - -#include "jpeglib.h" -#include "transupp.h" /* My own external interface */ - -#if TRANSFORMS_SUPPORTED - -/* - * Lossless image transformation routines. These routines work on DCT - * coefficient arrays and thus do not require any lossy decompression - * or recompression of the image. - * Thanks to Guido Vollbeding for the initial design and code of this feature. - * - * Horizontal flipping is done in-place, using a single top-to-bottom - * pass through the virtual source array. It will thus be much the - * fastest option for images larger than main memory. - * - * The other routines require a set of destination virtual arrays, so they - * need twice as much memory as jpegtran normally does. The destination - * arrays are always written in normal scan order (top to bottom) because - * the virtual array manager expects this. The source arrays will be scanned - * in the corresponding order, which means multiple passes through the source - * arrays for most of the transforms. That could result in much thrashing - * if the image is larger than main memory. - * - * Some notes about the operating environment of the individual transform - * routines: - * 1. Both the source and destination virtual arrays are allocated from the - * source JPEG object, and therefore should be manipulated by calling the - * source's memory manager. - * 2. The destination's component count should be used. It may be smaller - * than the source's when forcing to grayscale. - * 3. Likewise the destination's sampling factors should be used. When - * forcing to grayscale the destination's sampling factors will be all 1, - * and we may as well take that as the effective iMCU size. - * 4. When "trim" is in effect, the destination's dimensions will be the - * trimmed values but the source's will be untrimmed. - * 5. All the routines assume that the source and destination buffers are - * padded out to a full iMCU boundary. This is true, although for the - * source buffer it is an undocumented property of jdcoefct.c. - * Notes 2,3,4 boil down to this: generally we should use the destination's - * dimensions and ignore the source's. - */ - -LOCAL(void) do_flip_h(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays) -/* Horizontal flip; done in-place, so no separate dest array is required */ -{ - JDIMENSION MCU_cols, comp_width, blk_x, blk_y; - int ci, k, offset_y; - JBLOCKARRAY buffer; - JCOEFPTR ptr1, ptr2; - JCOEF temp1, temp2; - jpeg_component_info *compptr; - - /* Horizontal mirroring of DCT blocks is accomplished by swapping - * pairs of blocks in-place. Within a DCT block, we perform horizontal - * mirroring by changing the signs of odd-numbered columns. - * Partial iMCUs at the right edge are left untouched. - */ - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - for (blk_y = 0; blk_y < compptr->height_in_blocks; blk_y += compptr->v_samp_factor) { - buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], - blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { - ptr1 = buffer[offset_y][blk_x]; - ptr2 = buffer[offset_y][comp_width - blk_x - 1]; - /* this unrolled loop doesn't need to know which row it's on... */ - for (k = 0; k < DCTSIZE2; k += 2) { - temp1 = *ptr1; /* swap even column */ - temp2 = *ptr2; - *ptr1++ = temp2; - *ptr2++ = temp1; - temp1 = *ptr1; /* swap odd column with sign change */ - temp2 = *ptr2; - *ptr1++ = -temp2; - *ptr2++ = -temp1; - } - } - } - } - } -} - -LOCAL(void) -do_flip_v(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) -/* Vertical flip */ -{ - JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JBLOCKROW src_row_ptr, dst_row_ptr; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* We output into a separate array because we can't touch different - * rows of the source virtual array simultaneously. Otherwise, this - * is a pretty straightforward analog of horizontal flip. - * Within a DCT block, vertical mirroring is done by changing the signs - * of odd-numbered rows. - * Partial iMCUs at the bottom edge are copied verbatim. - */ - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], - dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); - if (dst_blk_y < comp_height) { - /* Row is within the mirrorable area. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, - src_coef_arrays[ci], - comp_height - dst_blk_y - - (JDIMENSION) compptr->v_samp_factor, (JDIMENSION) compptr->v_samp_factor, FALSE); - } else { - /* Bottom-edge blocks will be copied verbatim. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, - src_coef_arrays[ci], dst_blk_y, (JDIMENSION) compptr->v_samp_factor, FALSE); - } - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - if (dst_blk_y < comp_height) { - /* Row is within the mirrorable area. */ - dst_row_ptr = dst_buffer[offset_y]; - src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; - for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[dst_blk_x]; - for (i = 0; i < DCTSIZE; i += 2) { - /* copy even row */ - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = *src_ptr++; - /* copy odd row with sign change */ - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = -*src_ptr++; - } - } - } else { - /* Just copy row verbatim. */ - jcopy_block_row(src_buffer - [offset_y], dst_buffer[offset_y], compptr->width_in_blocks); - } - } - } - } -} - -LOCAL(void) -do_transpose(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) -/* Transpose source into destination */ -{ - JDIMENSION dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* Transposing pixels within a block just requires transposing the - * DCT coefficients. - * Partial iMCUs at the edges require no special treatment; we simply - * process all the available DCT blocks for every component. - */ - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], - dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; - dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) - compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - src_ptr = src_buffer[offset_x] - [dst_blk_y + offset_y]; - dst_ptr = dst_buffer[offset_y] - [dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - } - } - } - } - } -} - -LOCAL(void) -do_rot_90(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) -/* 90 degree rotation is equivalent to - * 1. Transposing the image; - * 2. Horizontal mirroring. - * These two steps are merged into a single processing routine. - */ -{ - JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* Because of the horizontal mirror step, we can't process partial iMCUs - * at the (output) right edge properly. They just get transposed and - * not mirrored. - */ - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], - dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; - dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) - compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - src_ptr = src_buffer[offset_x] - [dst_blk_y + offset_y]; - if (dst_blk_x < comp_width) { - /* Block is within the mirrorable area. */ - dst_ptr = dst_buffer[offset_y] - [comp_width - dst_blk_x - offset_x - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - i++; - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = -src_ptr[i * DCTSIZE + j]; - } - } else { - /* Edge blocks are transposed but not mirrored. */ - dst_ptr = dst_buffer[offset_y] - [dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - } - } - } - } - } - } -} - -LOCAL(void) -do_rot_270(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) -/* 270 degree rotation is equivalent to - * 1. Horizontal mirroring; - * 2. Transposing the image. - * These two steps are merged into a single processing routine. - */ -{ - JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* Because of the horizontal mirror step, we can't process partial iMCUs - * at the (output) bottom edge properly. They just get transposed and - * not mirrored. - */ - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], - dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; - dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) - compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - dst_ptr = dst_buffer[offset_y] - [dst_blk_x + offset_x]; - if (dst_blk_y < comp_height) { - /* Block is within the mirrorable area. */ - src_ptr = src_buffer[offset_x] - [comp_height - dst_blk_y - offset_y - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - j++; - dst_ptr[j * DCTSIZE + i] - = -src_ptr[i * DCTSIZE + j]; - } - } - } else { - /* Edge blocks are transposed but not mirrored. */ - src_ptr = src_buffer[offset_x] - [dst_blk_y + offset_y]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - } - } - } - } - } - } -} - -LOCAL(void) -do_rot_180(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) -/* 180 degree rotation is equivalent to - * 1. Vertical mirroring; - * 2. Horizontal mirroring. - * These two steps are merged into a single processing routine. - */ -{ - JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JBLOCKROW src_row_ptr, dst_row_ptr; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], - dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); - if (dst_blk_y < comp_height) { - /* Row is within the vertically mirrorable area. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, - src_coef_arrays[ci], - comp_height - dst_blk_y - - (JDIMENSION) compptr->v_samp_factor, (JDIMENSION) compptr->v_samp_factor, FALSE); - } else { - /* Bottom-edge rows are only mirrored horizontally. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, - src_coef_arrays[ci], dst_blk_y, (JDIMENSION) compptr->v_samp_factor, FALSE); - } - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - if (dst_blk_y < comp_height) { - /* Row is within the mirrorable area. */ - dst_row_ptr = dst_buffer[offset_y]; - src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; - /* Process the blocks that can be mirrored both ways. */ - for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; - for (i = 0; i < DCTSIZE; i += 2) { - /* For even row, negate every odd column. */ - for (j = 0; j < DCTSIZE; j += 2) { - *dst_ptr++ = *src_ptr++; - *dst_ptr++ = -*src_ptr++; - } - /* For odd row, negate every even column. */ - for (j = 0; j < DCTSIZE; j += 2) { - *dst_ptr++ = -*src_ptr++; - *dst_ptr++ = *src_ptr++; - } - } - } - /* Any remaining right-edge blocks are only mirrored vertically. */ - for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[dst_blk_x]; - for (i = 0; i < DCTSIZE; i += 2) { - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = *src_ptr++; - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = -*src_ptr++; - } - } - } else { - /* Remaining rows are just mirrored horizontally. */ - dst_row_ptr = dst_buffer[offset_y]; - src_row_ptr = src_buffer[offset_y]; - /* Process the blocks that can be mirrored. */ - for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; - for (i = 0; i < DCTSIZE2; i += 2) { - *dst_ptr++ = *src_ptr++; - *dst_ptr++ = -*src_ptr++; - } - } - /* Any remaining right-edge blocks are only copied. */ - for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[dst_blk_x]; - for (i = 0; i < DCTSIZE2; i++) - *dst_ptr++ = *src_ptr++; - } - } - } - } - } -} - -LOCAL(void) -do_transverse(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) -/* Transverse transpose is equivalent to - * 1. 180 degree rotation; - * 2. Transposition; - * or - * 1. Horizontal mirroring; - * 2. Transposition; - * 3. Horizontal mirroring. - * These steps are merged into a single processing routine. - */ -{ - JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], - dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; - dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) - compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - if (dst_blk_y < comp_height) { - src_ptr = src_buffer[offset_x] - [comp_height - dst_blk_y - offset_y - 1]; - if (dst_blk_x < comp_width) { - /* Block is within the mirrorable area. */ - dst_ptr = dst_buffer[offset_y] - [comp_width - dst_blk_x - offset_x - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - j++; - dst_ptr[j * DCTSIZE + i] - = -src_ptr[i * DCTSIZE + j]; - } - i++; - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j * DCTSIZE + i] - = -src_ptr[i * DCTSIZE + j]; - j++; - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - } - } - } else { - /* Right-edge blocks are mirrored in y only */ - dst_ptr = dst_buffer[offset_y] - [dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - j++; - dst_ptr[j * DCTSIZE + i] - = -src_ptr[i * DCTSIZE + j]; - } - } - } - } else { - src_ptr = src_buffer[offset_x] - [dst_blk_y + offset_y]; - if (dst_blk_x < comp_width) { - /* Bottom-edge blocks are mirrored in x only */ - dst_ptr = dst_buffer[offset_y] - [comp_width - dst_blk_x - offset_x - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - i++; - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = -src_ptr[i * DCTSIZE + j]; - } - } else { - /* At lower right corner, just transpose, no mirroring */ - dst_ptr = dst_buffer[offset_y] - [dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j * DCTSIZE + i] - = src_ptr[i * DCTSIZE + j]; - } - } - } - } - } - } - } -} - -/* Request any required workspace. - * - * We allocate the workspace virtual arrays from the source decompression - * object, so that all the arrays (both the original data and the workspace) - * will be taken into account while making memory management decisions. - * Hence, this routine must be called after jpeg_read_header (which reads - * the image dimensions) and before jpeg_read_coefficients (which realizes - * the source's virtual arrays). - */ - -GLOBAL(void) jtransform_request_workspace(j_decompress_ptr srcinfo, jpeg_transform_info * info) -{ - jvirt_barray_ptr *coef_arrays = NULL; - jpeg_component_info *compptr; - int ci; - - if (info->force_grayscale && srcinfo->jpeg_color_space == JCS_YCbCr && srcinfo->num_components == 3) { - /* We'll only process the first component */ - info->num_components = 1; - } else { - /* Process all the components */ - info->num_components = srcinfo->num_components; - } - - switch (info->transform) { - case JXFORM_NONE: - case JXFORM_FLIP_H: - /* Don't need a workspace array */ - break; - case JXFORM_FLIP_V: - case JXFORM_ROT_180: - /* Need workspace arrays having same dimensions as source image. - * Note that we allocate arrays padded out to the next iMCU boundary, - * so that transform routines need not worry about missing edge blocks. - */ - coef_arrays = (jvirt_barray_ptr *) - (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, SIZEOF(jvirt_barray_ptr) - * info->num_components); - for (ci = 0; ci < info->num_components; ci++) { - compptr = srcinfo->comp_info + ci; - coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) - ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, (JDIMENSION) jround_up((long) - compptr->width_in_blocks, - (long) - compptr->h_samp_factor), - (JDIMENSION) jround_up((long) - compptr->height_in_blocks, (long) - compptr->v_samp_factor), (JDIMENSION) compptr->v_samp_factor); - } - break; - case JXFORM_TRANSPOSE: - case JXFORM_TRANSVERSE: - case JXFORM_ROT_90: - case JXFORM_ROT_270: - /* Need workspace arrays having transposed dimensions. - * Note that we allocate arrays padded out to the next iMCU boundary, - * so that transform routines need not worry about missing edge blocks. - */ - coef_arrays = (jvirt_barray_ptr *) - (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, SIZEOF(jvirt_barray_ptr) - * info->num_components); - for (ci = 0; ci < info->num_components; ci++) { - compptr = srcinfo->comp_info + ci; - coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) - ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, (JDIMENSION) jround_up((long) - compptr->height_in_blocks, - (long) - compptr->v_samp_factor), - (JDIMENSION) jround_up((long) - compptr->width_in_blocks, (long) - compptr->h_samp_factor), (JDIMENSION) compptr->h_samp_factor); - } - break; - } - info->workspace_coef_arrays = coef_arrays; -} - -/* Transpose destination image parameters */ - -LOCAL(void) transpose_critical_parameters(j_compress_ptr dstinfo) -{ - int tblno, i, j, ci, itemp; - jpeg_component_info *compptr; - JQUANT_TBL *qtblptr; - JDIMENSION dtemp; - UINT16 qtemp; - - /* Transpose basic image dimensions */ - dtemp = dstinfo->image_width; - dstinfo->image_width = dstinfo->image_height; - dstinfo->image_height = dtemp; - - /* Transpose sampling factors */ - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - itemp = compptr->h_samp_factor; - compptr->h_samp_factor = compptr->v_samp_factor; - compptr->v_samp_factor = itemp; - } - - /* Transpose quantization tables */ - for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { - qtblptr = dstinfo->quant_tbl_ptrs[tblno]; - if (qtblptr != NULL) { - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < i; j++) { - qtemp = qtblptr->quantval[i * DCTSIZE + j]; - qtblptr->quantval[i * DCTSIZE + j] = qtblptr->quantval[j * DCTSIZE + i]; - qtblptr->quantval[j * DCTSIZE + i] = qtemp; - } - } - } - } -} - -/* Trim off any partial iMCUs on the indicated destination edge */ - -LOCAL(void) trim_right_edge(j_compress_ptr dstinfo) -{ - int ci, max_h_samp_factor; - JDIMENSION MCU_cols; - - /* We have to compute max_h_samp_factor ourselves, - * because it hasn't been set yet in the destination - * (and we don't want to use the source's value). - */ - max_h_samp_factor = 1; - for (ci = 0; ci < dstinfo->num_components; ci++) { - int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; - max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); - } - MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); - if (MCU_cols > 0) /* can't trim to 0 pixels */ - dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); -} - -LOCAL(void) trim_bottom_edge(j_compress_ptr dstinfo) -{ - int ci, max_v_samp_factor; - JDIMENSION MCU_rows; - - /* We have to compute max_v_samp_factor ourselves, - * because it hasn't been set yet in the destination - * (and we don't want to use the source's value). - */ - max_v_samp_factor = 1; - for (ci = 0; ci < dstinfo->num_components; ci++) { - int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; - max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); - } - MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); - if (MCU_rows > 0) /* can't trim to 0 pixels */ - dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); -} - -LOCAL(void) set_exif_orientation(JOCTET FAR * data, unsigned int length, unsigned char new_orient) -{ - boolean is_motorola; /* Flag for byte order */ - unsigned int number_of_tags, tagnum; - unsigned int firstoffset, offset; - - if (length < 12) - return; /* Length of an IFD entry */ - - /* Discover byte order */ - if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) - is_motorola = FALSE; - else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) - is_motorola = TRUE; - else - return; - - /* Check Tag Mark */ - if (is_motorola) { - if (GETJOCTET(data[2]) != 0) - return; - if (GETJOCTET(data[3]) != 0x2A) - return; - } else { - if (GETJOCTET(data[3]) != 0) - return; - if (GETJOCTET(data[2]) != 0x2A) - return; - } - - /* Get first IFD offset (offset to IFD0) */ - if (is_motorola) { - if (GETJOCTET(data[4]) != 0) - return; - if (GETJOCTET(data[5]) != 0) - return; - firstoffset = GETJOCTET(data[6]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[7]); - } else { - if (GETJOCTET(data[7]) != 0) - return; - if (GETJOCTET(data[6]) != 0) - return; - firstoffset = GETJOCTET(data[5]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[4]); - } - if (firstoffset > length - 2) - return; /* check end of data segment */ - - /* Get the number of directory entries contained in this IFD */ - if (is_motorola) { - number_of_tags = GETJOCTET(data[firstoffset]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset + 1]); - } else { - number_of_tags = GETJOCTET(data[firstoffset + 1]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset]); - } - if (number_of_tags == 0) - return; - firstoffset += 2; - - /* Search for Orientation offset Tag in IFD0 */ - for (;;) { - if (firstoffset > length - 12) - return; /* check end of data segment */ - /* Get Tag number */ - if (is_motorola) { - tagnum = GETJOCTET(data[firstoffset]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset + 1]); - } else { - tagnum = GETJOCTET(data[firstoffset + 1]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset]); - } - if (tagnum == 0x0112) - break; /* found Orientation Tag */ - if (--number_of_tags == 0) - return; - firstoffset += 12; - } - - if (is_motorola) { - data[firstoffset + 2] = 0; /* Format = unsigned short (2 octets) */ - data[firstoffset + 3] = 3; - data[firstoffset + 4] = 0; /* Number Of Components = 1 */ - data[firstoffset + 5] = 0; - data[firstoffset + 6] = 0; - data[firstoffset + 7] = 1; - data[firstoffset + 8] = 0; - data[firstoffset + 9] = (unsigned char) new_orient; - data[firstoffset + 10] = 0; - data[firstoffset + 11] = 0; - } else { - data[firstoffset + 2] = 3; /* Format = unsigned short (2 octets) */ - data[firstoffset + 3] = 0; - data[firstoffset + 4] = 1; /* Number Of Components = 1 */ - data[firstoffset + 5] = 0; - data[firstoffset + 6] = 0; - data[firstoffset + 7] = 0; - data[firstoffset + 8] = (unsigned char) new_orient; - data[firstoffset + 9] = 0; - data[firstoffset + 10] = 0; - data[firstoffset + 11] = 0; - } -} - -/* Adjust Exif image parameters. - * - * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible. - */ - -LOCAL(void) adjust_exif_parameters(JOCTET FAR * data, unsigned int length, JDIMENSION new_width, JDIMENSION new_height) -{ - boolean is_motorola; /* Flag for byte order */ - unsigned int number_of_tags, tagnum; - unsigned int firstoffset, offset; - unsigned int new_orient; - JDIMENSION new_value; - - if (length < 12) - return; /* Length of an IFD entry */ - - /* Discover byte order */ - if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) - is_motorola = FALSE; - else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) - is_motorola = TRUE; - else - return; - - /* Check Tag Mark */ - if (is_motorola) { - if (GETJOCTET(data[2]) != 0) - return; - if (GETJOCTET(data[3]) != 0x2A) - return; - } else { - if (GETJOCTET(data[3]) != 0) - return; - if (GETJOCTET(data[2]) != 0x2A) - return; - } - - /* Get first IFD offset (offset to IFD0) */ - if (is_motorola) { - if (GETJOCTET(data[4]) != 0) - return; - if (GETJOCTET(data[5]) != 0) - return; - firstoffset = GETJOCTET(data[6]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[7]); - } else { - if (GETJOCTET(data[7]) != 0) - return; - if (GETJOCTET(data[6]) != 0) - return; - firstoffset = GETJOCTET(data[5]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[4]); - } - if (firstoffset > length - 2) - return; /* check end of data segment */ - - /* Get the number of directory entries contained in this IFD */ - if (is_motorola) { - number_of_tags = GETJOCTET(data[firstoffset]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset + 1]); - } else { - number_of_tags = GETJOCTET(data[firstoffset + 1]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset]); - } - if (number_of_tags == 0) - return; - firstoffset += 2; - - /* Search for ExifSubIFD offset Tag in IFD0 */ - for (;;) { - if (firstoffset > length - 12) - return; /* check end of data segment */ - /* Get Tag number */ - if (is_motorola) { - tagnum = GETJOCTET(data[firstoffset]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset + 1]); - } else { - tagnum = GETJOCTET(data[firstoffset + 1]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset]); - } - if (tagnum == 0x8769) - break; /* found ExifSubIFD offset Tag */ - if (--number_of_tags == 0) - return; - firstoffset += 12; - } - - /* Get the ExifSubIFD offset */ - if (is_motorola) { - if (GETJOCTET(data[firstoffset + 8]) != 0) - return; - if (GETJOCTET(data[firstoffset + 9]) != 0) - return; - offset = GETJOCTET(data[firstoffset + 10]); - offset <<= 8; - offset += GETJOCTET(data[firstoffset + 11]); - } else { - if (GETJOCTET(data[firstoffset + 11]) != 0) - return; - if (GETJOCTET(data[firstoffset + 10]) != 0) - return; - offset = GETJOCTET(data[firstoffset + 9]); - offset <<= 8; - offset += GETJOCTET(data[firstoffset + 8]); - } - if (offset > length - 2) - return; /* check end of data segment */ - - /* Get the number of directory entries contained in this SubIFD */ - if (is_motorola) { - number_of_tags = GETJOCTET(data[offset]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[offset + 1]); - } else { - number_of_tags = GETJOCTET(data[offset + 1]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[offset]); - } - if (number_of_tags < 2) - return; - offset += 2; - - /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ - do { - if (offset > length - 12) - return; /* check end of data segment */ - /* Get Tag number */ - if (is_motorola) { - tagnum = GETJOCTET(data[offset]); - tagnum <<= 8; - tagnum += GETJOCTET(data[offset + 1]); - } else { - tagnum = GETJOCTET(data[offset + 1]); - tagnum <<= 8; - tagnum += GETJOCTET(data[offset]); - } - if (tagnum == 0xA002 || tagnum == 0xA003) { - if (tagnum == 0xA002) { - new_value = new_width; /* ExifImageWidth Tag */ - } else { - new_value = new_height; /* ExifImageHeight Tag */ - } - if (is_motorola) { - data[offset + 2] = 0; /* Format = unsigned long (4 octets) */ - data[offset + 3] = 4; - data[offset + 4] = 0; /* Number Of Components = 1 */ - data[offset + 5] = 0; - data[offset + 6] = 0; - data[offset + 7] = 1; - data[offset + 8] = 0; - data[offset + 9] = 0; - data[offset + 10] = (JOCTET) ((new_value >> 8) & 0xFF); - data[offset + 11] = (JOCTET) (new_value & 0xFF); - } else { - data[offset + 2] = 4; /* Format = unsigned long (4 octets) */ - data[offset + 3] = 0; - data[offset + 4] = 1; /* Number Of Components = 1 */ - data[offset + 5] = 0; - data[offset + 6] = 0; - data[offset + 7] = 0; - data[offset + 8] = (JOCTET) (new_value & 0xFF); - data[offset + 9] = (JOCTET) ((new_value >> 8) & 0xFF); - data[offset + 10] = 0; - data[offset + 11] = 0; - } - } - offset += 12; - } while (--number_of_tags); -} - -/* Adjust output image parameters as needed. - * - * This must be called after jpeg_copy_critical_parameters() - * and before jpeg_write_coefficients(). - * - * The return value is the set of virtual coefficient arrays to be written - * (either the ones allocated by jtransform_request_workspace, or the - * original source data arrays). The caller will need to pass this value - * to jpeg_write_coefficients(). - */ - -GLOBAL(jvirt_barray_ptr *) - jtransform_adjust_parameters(j_decompress_ptr srcinfo, - j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info) -{ - jpeg_saved_marker_ptr marker; - /* If force-to-grayscale is requested, adjust destination parameters */ - if (info->force_grayscale) { - /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed - * properly. Among other things, the target h_samp_factor & v_samp_factor - * will get set to 1, which typically won't match the source. - * In fact we do this even if the source is already grayscale; that - * provides an easy way of coercing a grayscale JPEG with funny sampling - * factors to the customary 1,1. (Some decoders fail on other factors.) - */ - if ((dstinfo->jpeg_color_space == JCS_YCbCr && - dstinfo->num_components == 3) || - (dstinfo->jpeg_color_space == JCS_GRAYSCALE && dstinfo->num_components == 1)) { - /* We have to preserve the source's quantization table number. */ - int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; - jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); - dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; - } else { - /* Sorry, can't do it */ - ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); - } - } - - /* Correct the destination's image dimensions etc if necessary */ - switch (info->transform) { - case JXFORM_NONE: - /* Nothing to do */ - break; - case JXFORM_FLIP_H: - if (info->trim) - trim_right_edge(dstinfo); - break; - case JXFORM_FLIP_V: - if (info->trim) - trim_bottom_edge(dstinfo); - break; - case JXFORM_TRANSPOSE: - transpose_critical_parameters(dstinfo); - /* transpose does NOT have to trim anything */ - break; - case JXFORM_TRANSVERSE: - transpose_critical_parameters(dstinfo); - if (info->trim) { - trim_right_edge(dstinfo); - trim_bottom_edge(dstinfo); - } - break; - case JXFORM_ROT_90: - transpose_critical_parameters(dstinfo); - if (info->trim) - trim_right_edge(dstinfo); - break; - case JXFORM_ROT_180: - if (info->trim) { - trim_right_edge(dstinfo); - trim_bottom_edge(dstinfo); - } - break; - case JXFORM_ROT_270: - transpose_critical_parameters(dstinfo); - if (info->trim) - trim_bottom_edge(dstinfo); - break; - } - - for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { - if (marker->marker != JPEG_APP0 + 1) - continue; - /* Adjust Exif properties */ - if (marker->marker == JPEG_APP0 + 1 && - marker->data_length >= 6 && - GETJOCTET(marker->data[0]) == 0x45 && - GETJOCTET(marker->data[1]) == 0x78 && - GETJOCTET(marker->data[2]) == 0x69 && - GETJOCTET(marker->data[3]) == 0x66 && - GETJOCTET(marker->data[4]) == 0 && GETJOCTET(marker->data[5]) == 0) { - /* Suppress output of JFIF marker */ - dstinfo->write_JFIF_header = FALSE; - /* Adjust Exif image parameters */ - if (dstinfo->image_width != srcinfo->image_width || - dstinfo->image_height != srcinfo->image_height) - /* Align data segment to start of TIFF structure for parsing */ - adjust_exif_parameters(marker->data + 6, - marker->data_length - 6, - dstinfo->image_width, dstinfo->image_height); - /* I'm honestly not sure what the right thing to do is here.. The - * existing orientation tag may be incorrect, so making a change based - * on the previous value seems like the wrong thing to do. For now, I'm - * going to assume that the user is always "fixing" the orientation, - * i.e. putting the image the "right way up". In this case, we want to - * set the orientation to "top left". - */ - set_exif_orientation(marker->data + 6, marker->data_length - 6, 1); - } - } - - /* Return the appropriate output data set */ - if (info->workspace_coef_arrays != NULL) - return info->workspace_coef_arrays; - return src_coef_arrays; -} - -/* Execute the actual transformation, if any. - * - * This must be called *after* jpeg_write_coefficients, because it depends - * on jpeg_write_coefficients to have computed subsidiary values such as - * the per-component width and height fields in the destination object. - * - * Note that some transformations will modify the source data arrays! - */ - -GLOBAL(void) - - - jtransform_execute_transformation(j_decompress_ptr srcinfo, - j_compress_ptr dstinfo, - jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info) -{ - jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; - - switch (info->transform) { - case JXFORM_NONE: - break; - case JXFORM_FLIP_H: - do_flip_h(srcinfo, dstinfo, src_coef_arrays); - break; - case JXFORM_FLIP_V: - do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_TRANSPOSE: - do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_TRANSVERSE: - do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_ROT_90: - do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_ROT_180: - do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_ROT_270: - do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - } -} - -#endif /* TRANSFORMS_SUPPORTED */ - -/* Setup decompression object to save desired markers in memory. - * This must be called before jpeg_read_header() to have the desired effect. - */ - -GLOBAL(void) jcopy_markers_setup(j_decompress_ptr srcinfo, JCOPY_OPTION option) -{ -#ifdef SAVE_MARKERS_SUPPORTED - int m; - - /* Save comments except under NONE option */ - if (option != JCOPYOPT_NONE) { - jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); - } - /* Save all types of APPn markers iff ALL option */ - if (option == JCOPYOPT_ALL) { - for (m = 0; m < 16; m++) - jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); - } -#endif /* SAVE_MARKERS_SUPPORTED */ -} - -/* Copy markers saved in the given source object to the destination object. - * This should be called just after jpeg_start_compress() or - * jpeg_write_coefficients(). - * Note that those routines will have written the SOI, and also the - * JFIF APP0 or Adobe APP14 markers if selected. - */ - -GLOBAL(void) jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, JCOPY_OPTION option) -{ - jpeg_saved_marker_ptr marker; - - /* In the current implementation, we don't actually need to examine the - * option flag here; we just copy everything that got saved. - * But to avoid confusion, we do not output JFIF and Adobe APP14 markers - * if the encoder library already wrote one. - */ - for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { - if (dstinfo->write_JFIF_header - && marker->marker == JPEG_APP0 - && marker->data_length >= 5 - && GETJOCTET(marker->data[0]) == 0x4A - && GETJOCTET(marker->data[1]) == 0x46 - && GETJOCTET(marker->data[2]) == 0x49 - && GETJOCTET(marker->data[3]) == 0x46 && GETJOCTET(marker->data[4]) == 0) - continue; /* reject duplicate JFIF */ - if (dstinfo->write_Adobe_marker && - marker->marker == JPEG_APP0 + 14 && - marker->data_length >= 5 && - GETJOCTET(marker->data[0]) == 0x41 && - GETJOCTET(marker->data[1]) == 0x64 && - GETJOCTET(marker->data[2]) == 0x6F && - GETJOCTET(marker->data[3]) == 0x62 && GETJOCTET(marker->data[4]) == 0x65) - continue; /* reject duplicate Adobe */ -#ifdef NEED_FAR_POINTERS - /* We could use jpeg_write_marker if the data weren't FAR... */ - { - unsigned int i; - jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); - for (i = 0; i < marker->data_length; i++) - jpeg_write_m_byte(dstinfo, marker->data[i]); - } -#else - jpeg_write_marker(dstinfo, marker->marker, marker->data, marker->data_length); -#endif - } -} diff --git a/src/transupp.h b/src/transupp.h deleted file mode 100644 index 056a282..0000000 --- a/src/transupp.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * transupp.h - * - * Copyright (C) 1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains declarations for image transformation routines and - * other utility code used by the jpegtran sample application. These are - * NOT part of the core JPEG library. But we keep these routines separate - * from jpegtran.c to ease the task of maintaining jpegtran-like programs - * that have other user interfaces. - * - * NOTE: all the routines declared here have very specific requirements - * about when they are to be executed during the reading and writing of the - * source and destination files. See the comments in transupp.c, or see - * jpegtran.c for an example of correct usage. - */ - -/* If you happen not to want the image transform support, disable it here */ -#ifndef TRANSFORMS_SUPPORTED -#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ -#endif - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jtransform_request_workspace jTrRequest -#define jtransform_adjust_parameters jTrAdjust -#define jtransform_execute_transformation jTrExec -#define jcopy_markers_setup jCMrkSetup -#define jcopy_markers_execute jCMrkExec -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - -/* - * Codes for supported types of image transformations. - */ - -typedef enum { - JXFORM_NONE, /* no transformation */ - JXFORM_FLIP_H, /* horizontal flip */ - JXFORM_FLIP_V, /* vertical flip */ - JXFORM_TRANSPOSE, /* transpose across UL-to-LR axis */ - JXFORM_TRANSVERSE, /* transpose across UR-to-LL axis */ - JXFORM_ROT_90, /* 90-degree clockwise rotation */ - JXFORM_ROT_180, /* 180-degree rotation */ - JXFORM_ROT_270 /* 270-degree clockwise (or 90 ccw) */ -} JXFORM_CODE; - -/* - * Although rotating and flipping data expressed as DCT coefficients is not - * hard, there is an asymmetry in the JPEG format specification for images - * whose dimensions aren't multiples of the iMCU size. The right and bottom - * image edges are padded out to the next iMCU boundary with junk data; but - * no padding is possible at the top and left edges. If we were to flip - * the whole image including the pad data, then pad garbage would become - * visible at the top and/or left, and real pixels would disappear into the - * pad margins --- perhaps permanently, since encoders & decoders may not - * bother to preserve DCT blocks that appear to be completely outside the - * nominal image area. So, we have to exclude any partial iMCUs from the - * basic transformation. - * - * Transpose is the only transformation that can handle partial iMCUs at the - * right and bottom edges completely cleanly. flip_h can flip partial iMCUs - * at the bottom, but leaves any partial iMCUs at the right edge untouched. - * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched. - * The other transforms are defined as combinations of these basic transforms - * and process edge blocks in a way that preserves the equivalence. - * - * The "trim" option causes untransformable partial iMCUs to be dropped; - * this is not strictly lossless, but it usually gives the best-looking - * result for odd-size images. Note that when this option is active, - * the expected mathematical equivalences between the transforms may not hold. - * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim - * followed by -rot 180 -trim trims both edges.) - * - * We also offer a "force to grayscale" option, which simply discards the - * chrominance channels of a YCbCr image. This is lossless in the sense that - * the luminance channel is preserved exactly. It's not the same kind of - * thing as the rotate/flip transformations, but it's convenient to handle it - * as part of this package, mainly because the transformation routines have to - * be aware of the option to know how many components to work on. - */ - -typedef struct { - /* Options: set by caller */ - JXFORM_CODE transform; /* image transform operator */ - boolean trim; /* if TRUE, trim partial MCUs as needed */ - boolean force_grayscale; /* if TRUE, convert color image to grayscale */ - - /* Internal workspace: caller should not touch these */ - int num_components; /* # of components in workspace */ - jvirt_barray_ptr *workspace_coef_arrays; /* workspace for transformations */ -} jpeg_transform_info; - -#if TRANSFORMS_SUPPORTED - -/* Request any required workspace */ -EXTERN(void) jtransform_request_workspace JPP((j_decompress_ptr srcinfo, jpeg_transform_info * info)); -/* Adjust output image parameters */ -EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters -JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info)); -/* Execute the actual transformation, if any */ -EXTERN(void) jtransform_execute_transformation -JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info)); - -#endif /* TRANSFORMS_SUPPORTED */ - -/* - * Support for copying optional markers from source to destination file. - */ - -typedef enum { - JCOPYOPT_NONE, /* copy no optional markers */ - JCOPYOPT_COMMENTS, /* copy only comment (COM) markers */ - JCOPYOPT_ALL /* copy all optional markers */ -} JCOPY_OPTION; - -#define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ - -/* Setup decompression object to save desired markers in memory */ -EXTERN(void) -jcopy_markers_setup JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); -/* Copy markers saved in the given source object to the destination object */ -EXTERN(void) jcopy_markers_execute JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, JCOPY_OPTION option)); |