sync
This commit is contained in:
parent
8e853b2857
commit
25d508ff3c
@ -1,6 +1,8 @@
|
||||
noinst_LTLIBRARIES = libfile.la
|
||||
|
||||
libfile_la_SOURCES = \
|
||||
jpeg.c \
|
||||
jpeg.h \
|
||||
jpegload.c \
|
||||
file.c
|
||||
|
||||
|
@ -611,14 +611,217 @@ vips_file_save_print_class( VipsObjectClass *object_class, VipsBuf *buf )
|
||||
*/
|
||||
}
|
||||
|
||||
/* Generate the saveable image.
|
||||
*/
|
||||
static int
|
||||
vips_file_convert_saveable( VipsFileSave *save )
|
||||
{
|
||||
VipsFileSaveClass *class = VIPS_FILE_SAVE_GET_CLASS( save );
|
||||
VipsImage *in = save->in;
|
||||
|
||||
/* If this is an VIPS_CODING_LABQ, we can go straight to RGB.
|
||||
*/
|
||||
if( in->Coding == VIPS_CODING_LABQ ) {
|
||||
IMAGE *t = im_open_local( out, "conv:1", "p" );
|
||||
static void *table = NULL;
|
||||
|
||||
/* Make sure fast LabQ2disp tables are built. 7 is sRGB.
|
||||
*/
|
||||
if( !table )
|
||||
table = im_LabQ2disp_build_table( NULL,
|
||||
im_col_displays( 7 ) );
|
||||
|
||||
if( !t || im_LabQ2disp_table( in, t, table ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
|
||||
/* If this is an IM_CODING_RAD, we go to float RGB or XYZ. We should
|
||||
* probably un-gamma-correct the RGB :(
|
||||
*/
|
||||
if( in->Coding == IM_CODING_RAD ) {
|
||||
IMAGE *t;
|
||||
|
||||
if( !(t = im_open_local( out, "conv:1", "p" )) ||
|
||||
im_rad2float( in, t ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
|
||||
/* Get the bands right.
|
||||
*/
|
||||
if( in->Coding == IM_CODING_NONE ) {
|
||||
if( in->Bands == 2 && saveable != IM__RGBA ) {
|
||||
IMAGE *t = im_open_local( out, "conv:1", "p" );
|
||||
|
||||
if( !t || im_extract_band( in, t, 0 ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
else if( in->Bands > 3 && saveable == IM__RGB ) {
|
||||
IMAGE *t = im_open_local( out, "conv:1", "p" );
|
||||
|
||||
if( !t ||
|
||||
im_extract_bands( in, t, 0, 3 ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
else if( in->Bands > 4 &&
|
||||
(saveable == IM__RGB_CMYK || saveable == IM__RGBA) ) {
|
||||
IMAGE *t = im_open_local( out, "conv:1", "p" );
|
||||
|
||||
if( !t ||
|
||||
im_extract_bands( in, t, 0, 4 ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
|
||||
/* Else we have saveable IM__ANY and we don't chop bands down.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Interpret the Type field for colorimetric images.
|
||||
*/
|
||||
if( in->Bands == 3 && in->BandFmt == IM_BANDFMT_SHORT &&
|
||||
in->Type == IM_TYPE_LABS ) {
|
||||
IMAGE *t = im_open_local( out, "conv:1", "p" );
|
||||
|
||||
if( !t || im_LabS2LabQ( in, t ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
|
||||
if( in->Coding == IM_CODING_LABQ ) {
|
||||
IMAGE *t = im_open_local( out, "conv:1", "p" );
|
||||
|
||||
if( !t || im_LabQ2Lab( in, t ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
|
||||
if( in->Coding != IM_CODING_NONE ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( in->Bands == 3 && in->Type == IM_TYPE_LCH ) {
|
||||
IMAGE *t[2];
|
||||
|
||||
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
|
||||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
|
||||
im_LCh2Lab( t[0], t[1] ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t[1];
|
||||
}
|
||||
|
||||
if( in->Bands == 3 && in->Type == IM_TYPE_YXY ) {
|
||||
IMAGE *t[2];
|
||||
|
||||
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
|
||||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
|
||||
im_Yxy2XYZ( t[0], t[1] ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t[1];
|
||||
}
|
||||
|
||||
if( in->Bands == 3 && in->Type == IM_TYPE_UCS ) {
|
||||
IMAGE *t[2];
|
||||
|
||||
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
|
||||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
|
||||
im_UCS2XYZ( t[0], t[1] ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t[1];
|
||||
}
|
||||
|
||||
if( in->Bands == 3 && in->Type == IM_TYPE_LAB ) {
|
||||
IMAGE *t[2];
|
||||
|
||||
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
|
||||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
|
||||
im_Lab2XYZ( t[0], t[1] ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t[1];
|
||||
}
|
||||
|
||||
if( in->Bands == 3 && in->Type == IM_TYPE_XYZ ) {
|
||||
IMAGE *t[2];
|
||||
|
||||
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
|
||||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
|
||||
im_XYZ2disp( t[0], t[1], im_col_displays( 7 ) ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t[1];
|
||||
}
|
||||
|
||||
/* Cast to the output format.
|
||||
*/
|
||||
{
|
||||
IMAGE *t = im_open_local( out, "conv:1", "p" );
|
||||
|
||||
if( !t || im_clip2fmt( in, t, format_table[in->BandFmt] ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
in = t;
|
||||
}
|
||||
|
||||
if( im_copy( in, out ) ) {
|
||||
im_close( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_file_save_build( VipsObject *object )
|
||||
{
|
||||
VipsFileSave *save = VIPS_FILE_SAVE( object );
|
||||
/*
|
||||
VipsFile *file = VIPS_FILE( object );
|
||||
VipsFileSave *save = VIPS_FILE_SAVE( object );
|
||||
*/
|
||||
|
||||
if( vips_file_convert_saveable( save ) )
|
||||
return( -1 );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_file_save_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
@ -766,4 +969,3 @@ vips_file_operation_init( void )
|
||||
vips_file_load_jpeg_get_type();
|
||||
#endif /*HAVE_JPEG*/
|
||||
}
|
||||
|
||||
|
102
libvips/file/jpeg.c
Normal file
102
libvips/file/jpeg.c
Normal file
@ -0,0 +1,102 @@
|
||||
/* common jpeg definitions
|
||||
*
|
||||
* 24/11/11
|
||||
* - from im_vips2jpeg.c
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
/* jpeglib includes jconfig.h, which can define HAVE_STDLIB_H ... which we
|
||||
* also define. Make sure it's turned off.
|
||||
*/
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#undef HAVE_STDLIB_H
|
||||
#endif /*HAVE_STDLIB_H*/
|
||||
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
|
||||
#include "jpeg.h"
|
||||
|
||||
/* New output message method - send to VIPS.
|
||||
*/
|
||||
void
|
||||
vips__new_output_message( j_common_ptr cinfo )
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
(*cinfo->err->format_message)( cinfo, buffer );
|
||||
vips_error( "VipsFile*Jpeg", _( "%s" ), buffer );
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "jpeg.c: new_output_message: \"%s\"\n", buffer );
|
||||
#endif /*DEBUG*/
|
||||
}
|
||||
|
||||
/* New error_exit handler.
|
||||
*/
|
||||
void
|
||||
vips__new_error_exit( j_common_ptr cinfo )
|
||||
{
|
||||
ErrorManager *eman = (ErrorManager *) cinfo->err;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "jpeg.c: new_error_exit\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* Close the fp if necessary.
|
||||
*/
|
||||
if( eman->fp ) {
|
||||
(void) fclose( eman->fp );
|
||||
eman->fp = NULL;
|
||||
}
|
||||
|
||||
/* Send the error message to VIPS. This method is overridden above.
|
||||
*/
|
||||
(*cinfo->err->output_message)( cinfo );
|
||||
|
||||
/* Jump back.
|
||||
*/
|
||||
longjmp( eman->jmp, 1 );
|
||||
}
|
||||
|
57
libvips/file/jpeg.h
Normal file
57
libvips/file/jpeg.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* common defs for jpeg read/write
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 1991-2005 The National Gallery
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifndef VIPS_JPEG_H
|
||||
#define VIPS_JPEG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/* Define a new error handler for when we bomb out.
|
||||
*/
|
||||
typedef struct {
|
||||
/* Public fields.
|
||||
*/
|
||||
struct jpeg_error_mgr pub;
|
||||
|
||||
/* Private stuff for us.
|
||||
*/
|
||||
jmp_buf jmp; /* longjmp() here to get back to VIPS */
|
||||
FILE *fp; /* fclose() if non-NULL */
|
||||
} ErrorManager;
|
||||
|
||||
void vips__new_output_message( j_common_ptr cinfo );
|
||||
void vips__new_error_exit( j_common_ptr cinfo );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#endif /*VIPS_JPEG_H*/
|
@ -112,6 +112,8 @@
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
|
||||
#include "jpeg.h"
|
||||
|
||||
typedef struct _VipsFileLoadJpeg {
|
||||
VipsFileLoad parent_object;
|
||||
|
||||
@ -166,61 +168,6 @@ vips_file_load_jpeg_is_a( const char *filename )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
/* Define a new error handler for when we bomb out.
|
||||
*/
|
||||
typedef struct {
|
||||
/* Public fields.
|
||||
*/
|
||||
struct jpeg_error_mgr pub;
|
||||
|
||||
/* Private stuff for us.
|
||||
*/
|
||||
jmp_buf jmp; /* longjmp() here to get back to VIPS */
|
||||
FILE *fp; /* fclose() if non-NULL */
|
||||
} ErrorManager;
|
||||
|
||||
/* New output message method - send to VIPS.
|
||||
*/
|
||||
METHODDEF(void)
|
||||
new_output_message( j_common_ptr cinfo )
|
||||
{
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
|
||||
(*cinfo->err->format_message)( cinfo, buffer );
|
||||
im_error( "VipsFileLoadJpeg", _( "%s" ), buffer );
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "VipsFileLoadJpeg: new_output_message: \"%s\"\n", buffer );
|
||||
#endif /*DEBUG*/
|
||||
}
|
||||
|
||||
/* New error_exit handler.
|
||||
*/
|
||||
METHODDEF(void)
|
||||
new_error_exit( j_common_ptr cinfo )
|
||||
{
|
||||
ErrorManager *eman = (ErrorManager *) cinfo->err;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "VipsFileLoadJpeg: new_error_exit\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* Close the fp if necessary.
|
||||
*/
|
||||
if( eman->fp ) {
|
||||
(void) fclose( eman->fp );
|
||||
eman->fp = NULL;
|
||||
}
|
||||
|
||||
/* Send the error message to VIPS. This method is overridden above.
|
||||
*/
|
||||
(*cinfo->err->output_message)( cinfo );
|
||||
|
||||
/* Jump back.
|
||||
*/
|
||||
longjmp( eman->jmp, 1 );
|
||||
}
|
||||
|
||||
/* Read a cinfo to a VIPS image. Set invert_pels if the pixel reader needs to
|
||||
* do 255-pel.
|
||||
*/
|
||||
@ -801,11 +748,11 @@ vips_file_load_jpeg_header( VipsFileLoad *load )
|
||||
/* Make jpeg dcompression object.
|
||||
*/
|
||||
cinfo.err = jpeg_std_error( &eman.pub );
|
||||
eman.pub.error_exit = new_error_exit;
|
||||
eman.pub.output_message = new_output_message;
|
||||
eman.pub.error_exit = vips__new_error_exit;
|
||||
eman.pub.output_message = vips__new_output_message;
|
||||
eman.fp = NULL;
|
||||
if( setjmp( eman.jmp ) ) {
|
||||
/* Here for longjmp() from new_error_exit().
|
||||
/* Here for longjmp() from vips__new_error_exit().
|
||||
*/
|
||||
jpeg_destroy_decompress( &cinfo );
|
||||
|
||||
@ -904,11 +851,11 @@ vips_file_load_jpeg_load( VipsFileLoad *load )
|
||||
/* Make jpeg dcompression object.
|
||||
*/
|
||||
cinfo.err = jpeg_std_error( &eman.pub );
|
||||
eman.pub.error_exit = new_error_exit;
|
||||
eman.pub.output_message = new_output_message;
|
||||
eman.pub.error_exit = vips__new_error_exit;
|
||||
eman.pub.output_message = vips__new_output_message;
|
||||
eman.fp = NULL;
|
||||
if( setjmp( eman.jmp ) ) {
|
||||
/* Here for longjmp() from new_error_exit().
|
||||
/* Here for longjmp() from vips__new_error_exit().
|
||||
*/
|
||||
jpeg_destroy_decompress( &cinfo );
|
||||
|
||||
|
@ -79,6 +79,7 @@
|
||||
/*
|
||||
#define DEBUG_VERBOSE
|
||||
#define DEBUG
|
||||
#define VIPS_DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -106,8 +107,9 @@
|
||||
#endif /*HAVE_EXIF*/
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
#include <vips/debug.h>
|
||||
#include <vips/buf.h>
|
||||
|
||||
/* jpeglib includes jconfig.h, which can define HAVE_STDLIB_H ... which we
|
||||
* also define. Make sure it's turned off.
|
||||
@ -119,6 +121,8 @@
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
|
||||
#include "jpeg.h"
|
||||
|
||||
typedef struct _VipsFileSaveJpeg {
|
||||
VipsFileSave parent_object;
|
||||
|
||||
|
@ -174,6 +174,23 @@ const char *vips_file_find_load( const char *filename );
|
||||
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
|
||||
VIPS_TYPE_FILE_SAVE, VipsFileSaveClass ))
|
||||
|
||||
/**
|
||||
* VipsSaveable:
|
||||
* @VIPS_SAVEABLE_RGB: 1 or 3 bands (eg. PPM)
|
||||
* @VIPS_SAVEABLE_RGBA: 1, 2, 3 or 4 bands (eg. PNG)
|
||||
* @VIPS_SAVEABLE_RGB_CMYK: 1, 3 or 4 bands (eg. JPEG)
|
||||
* @VIPS_SAVEABLE_ANY: any number of bands (eg. TIFF)
|
||||
*
|
||||
* See also: #VipsFileSave.
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_SAVEABLE_RGB,
|
||||
VIPS_SAVEABLE_RGBA,
|
||||
VIPS_SAVEABLE_RGB_CMYK,
|
||||
VIPS_SAVEABLE_ANY,
|
||||
VIPS_SAVEABLE_LAST
|
||||
} VipsSaveable;
|
||||
|
||||
typedef struct _VipsFileSave {
|
||||
VipsFile parent_object;
|
||||
/*< public >*/
|
||||
@ -182,6 +199,10 @@ typedef struct _VipsFileSave {
|
||||
*/
|
||||
VipsImage *in;
|
||||
|
||||
/* The image converted to a saveable format (eg. 8-bit RGB).
|
||||
*/
|
||||
VipsImage *in;
|
||||
|
||||
} VipsFileSave;
|
||||
|
||||
typedef struct _VipsFileSaveClass {
|
||||
@ -189,6 +210,13 @@ typedef struct _VipsFileSaveClass {
|
||||
|
||||
/*< public >*/
|
||||
|
||||
/* How this format treats bands.
|
||||
*/
|
||||
VipsSaveable saveable;
|
||||
|
||||
/* How this format treats band formats.
|
||||
*/
|
||||
VipsBandFormat format_table[VIPS_FORMAT_LAST];
|
||||
} VipsFileSaveClass;
|
||||
|
||||
GType vips_file_save_get_type( void );
|
||||
|
Loading…
x
Reference in New Issue
Block a user