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

📄 jpegtools.c

📁 linux下开源图片codec
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * jpegtran.c * * Copyright (C) 1995-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. *  * plenty of changes by Gerd Knorr <kraxel@bytesex.org>, with focus on * digital image processing and sane exif handling: * *   - does transformations only (flip/rotate/transpose/transverse). *   - also transforms the exif thumbnail if present. *   - can automatically figure transformation from the *     exif orientation tag. *   - updates the exif orientation tag. *   - updates the exif pixel dimension tags. * * This file contains a command-line user interface for JPEG transcoding. * It is very similar to cjpeg.c, but provides lossless transcoding between * different JPEG file formats.  It also provides some lossless and sort-of- * lossless transformations of JPEG data. */#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <utime.h>#include <setjmp.h>#include <sys/stat.h>#include <sys/types.h>#include <jpeglib.h>#include "jpeg/transupp.h"		/* Support routines for jpegtran */#include "jpegtools.h"#ifdef HAVE_LIBEXIF# include <libexif/exif-data.h># include <libexif/exif-utils.h># include <libexif/exif-ifd.h># include <libexif/exif-tag.h>#endifstatic int do_transform(struct jpeg_decompress_struct *src,			struct jpeg_compress_struct   *dst,			JXFORM_CODE transform,			unsigned char *comment,			unsigned int flags);static JXFORM_CODE transmagic[] = {    [ 1 ] = JXFORM_NONE,    [ 2 ] = JXFORM_FLIP_H,    [ 3 ] = JXFORM_ROT_180,    [ 4 ] = JXFORM_FLIP_V,    [ 5 ] = JXFORM_TRANSPOSE,    [ 6 ] = JXFORM_ROT_90,    [ 7 ] = JXFORM_TRANSVERSE,    [ 8 ] = JXFORM_ROT_270,};#if 0static char *transname[] = {    [ JXFORM_NONE ]       = "none",    [ JXFORM_FLIP_H ]     = "flip h",    [ JXFORM_FLIP_V ]     = "flip v",    [ JXFORM_TRANSPOSE ]  = "transpose",    [ JXFORM_TRANSVERSE ] = "transverse",    [ JXFORM_ROT_90 ]     = "rot 90",    [ JXFORM_ROT_180 ]    = "rot 190",    [ JXFORM_ROT_270 ]    = "rot 270",};#endif/* ---------------------------------------------------------------------- *//* libjpeg error handler -- exit via longjump */struct longjmp_error_mgr {    struct jpeg_error_mgr jpeg;    jmp_buf setjmp_buffer;};static void longjmp_error_exit(j_common_ptr cinfo){    struct longjmp_error_mgr *h = (struct longjmp_error_mgr*)cinfo->err;    (*cinfo->err->output_message)(cinfo);    longjmp(h->setjmp_buffer, 1);}/* ---------------------------------------------------------------------- */#ifdef HAVE_LIBEXIFstatic long get_int(ExifData *ed, ExifEntry *ee){    ExifByteOrder o = exif_data_get_byte_order(ed);    long value;        switch (ee->format) {    case EXIF_FORMAT_SHORT:	value = exif_get_short (ee->data, o);	break;    case EXIF_FORMAT_LONG:	value = exif_get_long (ee->data, o);	break;    case EXIF_FORMAT_SLONG:	value = exif_get_slong (ee->data, o);	break;    default:	fprintf(stderr,"get_int oops\n");	exit(1);    }    return value;}static void set_int(ExifData *ed, ExifEntry *ee, long value){    ExifByteOrder o = exif_data_get_byte_order(ed);    switch (ee->format) {    case EXIF_FORMAT_SHORT:	exif_set_short (ee->data, o, value);	break;    case EXIF_FORMAT_LONG:	exif_set_long (ee->data, o, value);	break;    case EXIF_FORMAT_SLONG:	exif_set_slong (ee->data, o, value);	break;    default:	fprintf(stderr,"set_int oops\n");	exit(1);    }}static void update_orientation(ExifData *ed, int ifd, int orientation){    ExifEntry *ee;    ee = exif_content_get_entry(ed->ifd[ifd], 0x0112);    if (NULL == ee)	return;    set_int(ed,ee,orientation);}static void update_dimension(ExifData *ed, JXFORM_CODE transform,			     int src_x, int src_y){    static struct {	int idf;	int tag;	int x;    } fields[] = {	{	    .idf = EXIF_IFD_EXIF,	    .tag = EXIF_TAG_PIXEL_X_DIMENSION,	    .x   = 1,	},{	    .idf = EXIF_IFD_EXIF,	    .tag = EXIF_TAG_PIXEL_Y_DIMENSION,	    .x   = 0,	},{	    .idf = EXIF_IFD_INTEROPERABILITY,	    .tag = EXIF_TAG_RELATED_IMAGE_WIDTH,	    .x   = 1,	},{	    .idf = EXIF_IFD_INTEROPERABILITY,	    .tag = EXIF_TAG_RELATED_IMAGE_LENGTH,	    .x   = 0,	}    };    ExifEntry *ee;    int i;    for (i = 0; i < sizeof(fields)/sizeof(fields[0]); i++) {	ee = exif_content_get_entry(ed->ifd[fields[i].idf], fields[i].tag);	if (!ee)	    continue;	switch (transform) {	case JXFORM_ROT_90:	case JXFORM_ROT_270:	case JXFORM_TRANSPOSE:	case JXFORM_TRANSVERSE:	    /* x/y reversed */	    set_int(ed, ee, fields[i].x ? src_y : src_x);	    break;	default:	    /* normal */	    set_int(ed, ee, fields[i].x ? src_x : src_y);	    break;	}    }}static int get_orientation(ExifData *ed){    ExifEntry *ee;    ee = exif_content_get_entry(ed->ifd[EXIF_IFD_0], 0x0112);    if (NULL == ee)	return 1; /* top - left */    return get_int(ed,ee);}/* ---------------------------------------------------------------------- */#define container_of(ptr, type, member) ({			\        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\        (type *)( (char *)__mptr - offsetof(type,member) );})struct th {    struct jpeg_decompress_struct src;    struct jpeg_compress_struct   dst;    struct jpeg_error_mgr jsrcerr, jdsterr;    unsigned char *in;    unsigned char *out;    int isize, osize;};static void thumbnail_src_init(struct jpeg_decompress_struct *cinfo){    struct th *h  = container_of(cinfo, struct th, src);    cinfo->src->next_input_byte = h->in;    cinfo->src->bytes_in_buffer = h->isize;}static int thumbnail_src_fill(struct jpeg_decompress_struct *cinfo){    fprintf(stderr,"jpeg: panic: no more thumbnail input data\n");    exit(1);}static void thumbnail_src_skip(struct jpeg_decompress_struct *cinfo,			       long num_bytes){    cinfo->src->next_input_byte += num_bytes;}static void thumbnail_src_term(struct jpeg_decompress_struct *cinfo){    /* nothing */}static void thumbnail_dest_init(struct jpeg_compress_struct *cinfo){    struct th *h  = container_of(cinfo, struct th, dst);    h->osize = h->isize * 2;    h->out   = malloc(h->osize);    cinfo->dest->next_output_byte = h->out;    cinfo->dest->free_in_buffer   = h->osize;}static boolean thumbnail_dest_flush(struct jpeg_compress_struct *cinfo){    fprintf(stderr,"jpeg: panic: output buffer full\n");    exit(1);}static void thumbnail_dest_term(struct jpeg_compress_struct *cinfo){    struct th *h  = container_of(cinfo, struct th, dst);    h->osize -= cinfo->dest->free_in_buffer;}static struct jpeg_source_mgr thumbnail_src = {    .init_source         = thumbnail_src_init,    .fill_input_buffer   = thumbnail_src_fill,    .skip_input_data     = thumbnail_src_skip,    .resync_to_restart   = jpeg_resync_to_restart,    .term_source         = thumbnail_src_term,};static struct jpeg_destination_mgr thumbnail_dst = {    .init_destination    = thumbnail_dest_init,    .empty_output_buffer = thumbnail_dest_flush,    .term_destination    = thumbnail_dest_term,};static void do_thumbnail(ExifData *ed, JXFORM_CODE transform){    struct th th;    if (JXFORM_NONE == transform)	return;        th.in    = ed->data;    th.isize = ed->size;        /* setup src */    th.src.err = jpeg_std_error(&th.jsrcerr);    jpeg_create_decompress(&th.src);    th.src.src = &thumbnail_src;        /* setup dst */    th.dst.err = jpeg_std_error(&th.jdsterr);    jpeg_create_compress(&th.dst);    th.dst.dest = &thumbnail_dst;    /* transform image */    do_transform(&th.src,&th.dst,transform,NULL,JFLAG_TRANSFORM_IMAGE);    /* cleanup */    jpeg_destroy_decompress(&th.src);

⌨️ 快捷键说明

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