664 lines
16 KiB
C
664 lines
16 KiB
C
/* Common functions for interfacing with ImageMagick.
|
|
*
|
|
* 22/12/17 dlemstra
|
|
*
|
|
* 24/7/18
|
|
* - add the sniffer
|
|
*/
|
|
|
|
/*
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301 USA
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
|
|
|
*/
|
|
|
|
#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 <vips/vips.h>
|
|
#include <vips/internal.h>
|
|
|
|
#include "pforeign.h"
|
|
#include "magick.h"
|
|
|
|
#ifdef HAVE_MAGICK7
|
|
|
|
Image *
|
|
magick_acquire_image( const ImageInfo *image_info, ExceptionInfo *exception )
|
|
{
|
|
return( AcquireImage( image_info, exception ) );
|
|
}
|
|
|
|
void
|
|
magick_acquire_next_image( const ImageInfo *image_info, Image *image,
|
|
ExceptionInfo *exception )
|
|
{
|
|
AcquireNextImage( image_info, image, exception );
|
|
}
|
|
|
|
int
|
|
magick_set_image_size( Image *image, const size_t width, const size_t height,
|
|
ExceptionInfo *exception )
|
|
{
|
|
return( SetImageExtent( image, width, height, exception ) );
|
|
}
|
|
|
|
int
|
|
magick_import_pixels( Image *image, const ssize_t x, const ssize_t y,
|
|
const size_t width, const size_t height, const char *map,
|
|
const StorageType type,const void *pixels, ExceptionInfo *exception )
|
|
{
|
|
return( ImportImagePixels( image, x, y, width, height, map,
|
|
type, pixels, exception ) );
|
|
}
|
|
|
|
void *
|
|
magick_images_to_blob( const ImageInfo *image_info, Image *images,
|
|
size_t *length, ExceptionInfo *exception )
|
|
{
|
|
return( ImagesToBlob( image_info, images, length, exception ) );
|
|
}
|
|
|
|
void
|
|
magick_set_property( Image *image, const char *property, const char *value,
|
|
ExceptionInfo *exception )
|
|
{
|
|
(void) SetImageProperty( image, property, value, exception );
|
|
}
|
|
|
|
int
|
|
magick_set_profile( Image *image,
|
|
const char *name, const void *data, size_t length,
|
|
ExceptionInfo *exception )
|
|
{
|
|
StringInfo *string;
|
|
MagickBooleanType result;
|
|
|
|
string = BlobToStringInfo( data, length );
|
|
result = SetImageProfile( image, name, string, exception );
|
|
DestroyStringInfo( string );
|
|
|
|
return( result );
|
|
}
|
|
|
|
void *
|
|
magick_profile_map( Image *image, MagickMapProfileFn fn, void *a )
|
|
{
|
|
char *name;
|
|
|
|
ResetImageProfileIterator( image );
|
|
while( (name = GetNextImageProfile( image )) ) {
|
|
const StringInfo *profile;
|
|
void *data;
|
|
size_t length;
|
|
void *result;
|
|
|
|
profile = GetImageProfile( image, name );
|
|
data = GetStringInfoDatum( profile );
|
|
length = GetStringInfoLength( profile );
|
|
if( (result = fn( image, name, data, length, a )) )
|
|
return( result );
|
|
}
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
ExceptionInfo *
|
|
magick_acquire_exception( void )
|
|
{
|
|
return( AcquireExceptionInfo() );
|
|
}
|
|
|
|
void
|
|
magick_destroy_exception( ExceptionInfo *exception )
|
|
{
|
|
VIPS_FREEF( DestroyExceptionInfo, exception );
|
|
}
|
|
|
|
void
|
|
magick_inherit_exception( ExceptionInfo *exception, Image *image )
|
|
{
|
|
(void) exception;
|
|
(void) image;
|
|
}
|
|
|
|
void
|
|
magick_set_number_scenes( ImageInfo *image_info, int scene, int number_scenes )
|
|
{
|
|
/* I can't find docs for these fields, but this seems to work.
|
|
*/
|
|
char page[256];
|
|
|
|
image_info->scene = scene;
|
|
image_info->number_scenes = number_scenes;
|
|
|
|
/* Some IMs must have the string version set as well.
|
|
*/
|
|
vips_snprintf( page, 256, "%d-%d", scene, scene + number_scenes );
|
|
image_info->scenes = strdup( page );
|
|
}
|
|
|
|
#endif /*HAVE_MAGICK7*/
|
|
|
|
#ifdef HAVE_MAGICK6
|
|
|
|
Image *
|
|
magick_acquire_image( const ImageInfo *image_info, ExceptionInfo *exception )
|
|
{
|
|
(void) exception;
|
|
|
|
#ifdef HAVE_ACQUIREIMAGE
|
|
return( AcquireImage( image_info ) );
|
|
#else /*!HAVE_ACQUIREIMAGE*/
|
|
/* IM5-ish and GraphicsMagick use AllocateImage().
|
|
*/
|
|
return( AllocateImage( image_info ) );
|
|
#endif
|
|
}
|
|
|
|
void
|
|
magick_acquire_next_image( const ImageInfo *image_info, Image *image,
|
|
ExceptionInfo *exception )
|
|
{
|
|
(void) exception;
|
|
#ifdef HAVE_ACQUIREIMAGE
|
|
AcquireNextImage( image_info, image );
|
|
#else /*!HAVE_ACQUIREIMAGE*/
|
|
/* IM5-ish and GraphicsMagick use AllocateNextImage().
|
|
*/
|
|
AllocateNextImage( image_info, image );
|
|
#endif
|
|
}
|
|
|
|
int
|
|
magick_set_image_size( Image *image, const size_t width, const size_t height,
|
|
ExceptionInfo *exception )
|
|
{
|
|
(void) exception;
|
|
#ifdef HAVE_SETIMAGEEXTENT
|
|
return( SetImageExtent( image, width, height ) );
|
|
#else /*!HAVE_SETIMAGEEXTENT*/
|
|
image->columns = width;
|
|
image->rows = height;
|
|
|
|
/* imagemagick does a SyncImagePixelCache() at the end of
|
|
* SetImageExtent(), but GM does not really have an equivalent. Just
|
|
* always return True.
|
|
*/
|
|
return( MagickTrue );
|
|
#endif /*HAVE_SETIMAGEEXTENT*/
|
|
}
|
|
|
|
int
|
|
magick_import_pixels( Image *image, const ssize_t x, const ssize_t y,
|
|
const size_t width, const size_t height, const char *map,
|
|
const StorageType type, const void *pixels, ExceptionInfo *exception )
|
|
{
|
|
#ifdef HAVE_IMPORTIMAGEPIXELS
|
|
return( ImportImagePixels( image, x, y, width, height, map,
|
|
type, pixels ) );
|
|
#else /*!HAVE_IMPORTIMAGEPIXELS*/
|
|
Image *constitute_image;
|
|
|
|
g_assert( image );
|
|
g_assert( image->signature == MagickSignature );
|
|
|
|
constitute_image = ConstituteImage( width, height, map, type,
|
|
pixels, &image->exception );
|
|
if( !constitute_image )
|
|
return( MagickFalse );
|
|
|
|
(void) CompositeImage( image, CopyCompositeOp, constitute_image, x, y );
|
|
DestroyImage( constitute_image );
|
|
|
|
return( image->exception.severity == UndefinedException );
|
|
#endif /*HAVE_IMPORTIMAGEPIXELS*/
|
|
}
|
|
|
|
void *
|
|
magick_images_to_blob( const ImageInfo *image_info, Image *images,
|
|
size_t *length, ExceptionInfo *exception )
|
|
{
|
|
#ifdef HAVE_IMAGESTOBLOB
|
|
return( ImagesToBlob( image_info, images, length, exception ) );
|
|
#else
|
|
return( ImageToBlob( image_info, images, length, exception ) );
|
|
#endif /*HAVE_IMAGESTOBLOB*/
|
|
}
|
|
|
|
void
|
|
magick_set_property( Image *image, const char *property, const char *value,
|
|
ExceptionInfo *exception )
|
|
{
|
|
(void) exception;
|
|
#ifdef HAVE_SETIMAGEPROPERTY
|
|
(void) SetImageProperty( image, property, value );
|
|
#else /*!HAVE_SETIMAGEPROPERTY*/
|
|
(void) SetImageAttribute( image, property, value );
|
|
#endif /*HAVE_SETIMAGEPROPERTY*/
|
|
}
|
|
|
|
int
|
|
magick_set_profile( Image *image,
|
|
const char *name, const void *data, size_t length,
|
|
ExceptionInfo *exception )
|
|
{
|
|
int result;
|
|
|
|
#ifdef HAVE_BLOBTOSTRINGINFO
|
|
StringInfo *string;
|
|
|
|
string = BlobToStringInfo( data, length );
|
|
result = SetImageProfile( image, name, string );
|
|
DestroyStringInfo( string );
|
|
#else /*HAVE_BLOBTOSTRINGINFO*/
|
|
result = SetImageProfile( image, name, data, length );
|
|
#endif /*HAVE_BLOBTOSTRINGINFO*/
|
|
|
|
return( result );
|
|
}
|
|
|
|
void *
|
|
magick_profile_map( Image *image, MagickMapProfileFn fn, void *a )
|
|
{
|
|
const char *name;
|
|
const void *data;
|
|
size_t length;
|
|
void *result;
|
|
|
|
#ifdef HAVE_RESETIMAGEPROFILEITERATOR
|
|
ResetImageProfileIterator( image );
|
|
while( (name = GetNextImageProfile( image )) ) {
|
|
const StringInfo *profile;
|
|
|
|
profile = GetImageProfile( image, name );
|
|
data = GetStringInfoDatum( profile );
|
|
length = GetStringInfoLength( profile );
|
|
if( (result = fn( image, name, data, length, a )) )
|
|
return( result );
|
|
}
|
|
#else /*!HAVE_RESETIMAGEPROFILEITERATOR*/
|
|
{
|
|
ImageProfileIterator *iter;
|
|
|
|
iter = AllocateImageProfileIterator( image );
|
|
while( NextImageProfile( iter,
|
|
&name, (const unsigned char **) &data, &length ) ) {
|
|
if( (result = fn( image, name, data, length, a )) ) {
|
|
DeallocateImageProfileIterator( iter );
|
|
return( result );
|
|
}
|
|
}
|
|
DeallocateImageProfileIterator( iter );
|
|
}
|
|
#endif /*HAVE_RESETIMAGEPROFILEITERATOR*/
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
ExceptionInfo *
|
|
magick_acquire_exception( void )
|
|
{
|
|
ExceptionInfo *exception;
|
|
|
|
#ifdef HAVE_ACQUIREEXCEPTIONINFO
|
|
/* IM6+
|
|
*/
|
|
exception = AcquireExceptionInfo();
|
|
#else /*!HAVE_ACQUIREEXCEPTIONINFO*/
|
|
/* gm
|
|
*/
|
|
exception = g_new( ExceptionInfo, 1 );
|
|
GetExceptionInfo( exception );
|
|
#endif /*HAVE_ACQUIREEXCEPTIONINFO*/
|
|
|
|
return( exception );
|
|
}
|
|
|
|
void
|
|
magick_destroy_exception( ExceptionInfo *exception )
|
|
{
|
|
#ifdef HAVE_ACQUIREEXCEPTIONINFO
|
|
/* IM6+ will free the exception in destroy.
|
|
*/
|
|
VIPS_FREEF( DestroyExceptionInfo, exception );
|
|
#else /*!HAVE_ACQUIREEXCEPTIONINFO*/
|
|
/* gm and very old IM need to free the memory too.
|
|
*/
|
|
if( exception ) {
|
|
DestroyExceptionInfo( exception );
|
|
g_free( exception );
|
|
}
|
|
#endif /*HAVE_ACQUIREEXCEPTIONINFO*/
|
|
}
|
|
|
|
void
|
|
magick_inherit_exception( ExceptionInfo *exception, Image *image )
|
|
{
|
|
#ifdef HAVE_INHERITEXCEPTION
|
|
InheritException( exception, &image->exception );
|
|
#endif /*HAVE_INHERITEXCEPTION*/
|
|
}
|
|
|
|
void
|
|
magick_set_number_scenes( ImageInfo *image_info, int scene, int number_scenes )
|
|
{
|
|
#ifdef HAVE_NUMBER_SCENES
|
|
/* I can't find docs for these fields, but this seems to work.
|
|
*/
|
|
char page[256];
|
|
|
|
image_info->scene = scene;
|
|
image_info->number_scenes = number_scenes;
|
|
|
|
/* Some IMs must have the string version set as well.
|
|
*/
|
|
vips_snprintf( page, 256, "%d-%d", scene, scene + number_scenes );
|
|
image_info->scenes = strdup( page );
|
|
#else /*!HAVE_NUMBER_SCENES*/
|
|
/* This works with GM 1.2.31 and probably others.
|
|
*/
|
|
image_info->subimage = scene;
|
|
image_info->subrange = number_scenes;
|
|
#endif
|
|
}
|
|
|
|
#endif /*HAVE_MAGICK6*/
|
|
|
|
#if defined(HAVE_MAGICK6) || defined(HAVE_MAGICK7)
|
|
|
|
void
|
|
magick_set_image_option( ImageInfo *image_info,
|
|
const char *name, const char *value )
|
|
{
|
|
#ifdef HAVE_SETIMAGEOPTION
|
|
SetImageOption( image_info, name, value );
|
|
#endif /*HAVE_SETIMAGEOPTION*/
|
|
}
|
|
|
|
typedef struct _MagickColorspaceTypeNames {
|
|
ColorspaceType colorspace;
|
|
const char *name;
|
|
} MagickColorspaceTypeNames;
|
|
|
|
static MagickColorspaceTypeNames magick_colorspace_names[] = {
|
|
{ UndefinedColorspace, "UndefinedColorspace" },
|
|
{ CMYColorspace, "CMYColorspace" },
|
|
{ CMYKColorspace, "CMYKColorspace" },
|
|
{ GRAYColorspace, "GRAYColorspace" },
|
|
{ HCLColorspace, "HCLColorspace" },
|
|
{ HCLpColorspace, "HCLpColorspace" },
|
|
{ HSBColorspace, "HSBColorspace" },
|
|
{ HSIColorspace, "HSIColorspace" },
|
|
{ HSLColorspace, "HSLColorspace" },
|
|
{ HSVColorspace, "HSVColorspace" },
|
|
{ HWBColorspace, "HWBColorspace" },
|
|
{ LabColorspace, "LabColorspace" },
|
|
{ LCHColorspace, "LCHColorspace" },
|
|
{ LCHabColorspace, "LCHabColorspace" },
|
|
{ LCHuvColorspace, "LCHuvColorspace" },
|
|
{ LogColorspace, "LogColorspace" },
|
|
{ LMSColorspace, "LMSColorspace" },
|
|
{ LuvColorspace, "LuvColorspace" },
|
|
{ OHTAColorspace, "OHTAColorspace" },
|
|
{ Rec601YCbCrColorspace, "Rec601YCbCrColorspace" },
|
|
{ Rec709YCbCrColorspace, "Rec709YCbCrColorspace" },
|
|
{ RGBColorspace, "RGBColorspace" },
|
|
{ scRGBColorspace, "scRGBColorspace" },
|
|
{ sRGBColorspace, "sRGBColorspace" },
|
|
{ TransparentColorspace, "TransparentColorspace" },
|
|
{ xyYColorspace, "xyYColorspace" },
|
|
{ XYZColorspace, "XYZColorspace" },
|
|
{ YCbCrColorspace, "YCbCrColorspace" },
|
|
{ YCCColorspace, "YCCColorspace" },
|
|
{ YDbDrColorspace, "YDbDrColorspace" },
|
|
{ YIQColorspace, "YIQColorspace" },
|
|
{ YPbPrColorspace, "YPbPrColorspace" },
|
|
{ YUVColorspace, "YUVColorspace" }
|
|
|
|
/* More recent imagemagicks add these.
|
|
*
|
|
{ LinearGRAYColorspace, "LinearGRAYColorspace" }
|
|
*
|
|
*/
|
|
};
|
|
|
|
const char *
|
|
magick_ColorspaceType2str( ColorspaceType colorspace )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; i < VIPS_NUMBER( magick_colorspace_names ); i++ )
|
|
if( magick_colorspace_names[i].colorspace == colorspace )
|
|
return( magick_colorspace_names[i].name );
|
|
|
|
return( "<unknown ColorspaceType>" );
|
|
}
|
|
|
|
/* ImageMagick can't detect some formats, like ICO, by examining the contents --
|
|
* ico.c simply does not have a recogniser.
|
|
*
|
|
* For these formats, do the detection ourselves.
|
|
*
|
|
* Return an IM format specifier, or NULL to let IM do the detection.
|
|
*/
|
|
static const char *
|
|
magick_sniff( const unsigned char *bytes, size_t length )
|
|
{
|
|
if( length >= 4 &&
|
|
bytes[0] == 0 &&
|
|
bytes[1] == 0 &&
|
|
bytes[2] == 1 &&
|
|
bytes[3] == 0 )
|
|
return( "ICO" );
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
void
|
|
magick_sniff_bytes( ImageInfo *image_info,
|
|
const unsigned char *bytes, size_t length )
|
|
{
|
|
const char *format;
|
|
|
|
if( (format = magick_sniff( bytes, length )) )
|
|
vips_strncpy( image_info->magick, format, MaxTextExtent );
|
|
}
|
|
|
|
void
|
|
magick_sniff_file( ImageInfo *image_info, const char *filename )
|
|
{
|
|
unsigned char bytes[256];
|
|
size_t length;
|
|
|
|
if( (length = vips__get_bytes( filename, bytes, 256 )) >= 4 )
|
|
magick_sniff_bytes( image_info, bytes, 256 );
|
|
}
|
|
|
|
void
|
|
magick_vips_error( const char *domain, ExceptionInfo *exception )
|
|
{
|
|
if( exception ) {
|
|
if( exception->reason &&
|
|
exception->description )
|
|
vips_error( domain, _( "libMagick error: %s %s" ),
|
|
exception->reason, exception->description );
|
|
else if( exception->reason )
|
|
vips_error( domain, _( "libMagick error: %s" ),
|
|
exception->reason );
|
|
else
|
|
vips_error( domain, "%s", _( "libMagick error:" ) );
|
|
}
|
|
}
|
|
|
|
static void *
|
|
magick_genesis_cb( void *client )
|
|
{
|
|
#ifdef DEBUG
|
|
printf( "magick_genesis_cb:\n" );
|
|
#endif /*DEBUG*/
|
|
|
|
#if defined(HAVE_MAGICKCOREGENESIS) || defined(HAVE_MAGICK7)
|
|
MagickCoreGenesis( vips_get_argv0(), MagickFalse );
|
|
#else /*!HAVE_MAGICKCOREGENESIS*/
|
|
InitializeMagick( "" );
|
|
#endif /*HAVE_MAGICKCOREGENESIS*/
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
void
|
|
magick_genesis( void )
|
|
{
|
|
static GOnce once = G_ONCE_INIT;
|
|
|
|
VIPS_ONCE( &once, magick_genesis_cb, NULL );
|
|
}
|
|
|
|
/* Set vips metadata from a magick profile.
|
|
*/
|
|
static void *
|
|
magick_set_vips_profile_cb( Image *image,
|
|
const char *name, const void *data, size_t length, void *a )
|
|
{
|
|
VipsImage *im = (VipsImage *) a;
|
|
|
|
char name_text[256];
|
|
VipsBuf vips_name = VIPS_BUF_STATIC( name_text );
|
|
|
|
if( strcmp( name, "XMP" ) == 0 )
|
|
vips_buf_appendf( &vips_name, VIPS_META_XMP_NAME );
|
|
else if( strcmp( name, "IPTC" ) == 0 )
|
|
vips_buf_appendf( &vips_name, VIPS_META_IPTC_NAME );
|
|
else if( strcmp( name, "ICM" ) == 0 )
|
|
vips_buf_appendf( &vips_name, VIPS_META_ICC_NAME );
|
|
else if( strcmp( name, "EXIF" ) == 0 )
|
|
vips_buf_appendf( &vips_name, VIPS_META_EXIF_NAME );
|
|
else
|
|
vips_buf_appendf( &vips_name, "magickprofile-%s", name );
|
|
|
|
vips_image_set_blob_copy( im,
|
|
vips_buf_all( &vips_name ), data, length );
|
|
|
|
if( strcmp( name, "exif" ) == 0 )
|
|
(void) vips__exif_parse( im );
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
/* Set vips metadata from ImageMagick profiles.
|
|
*/
|
|
int
|
|
magick_set_vips_profile( VipsImage *im, Image *image )
|
|
{
|
|
if( magick_profile_map( image, magick_set_vips_profile_cb, im ) )
|
|
return( -1 );
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
typedef struct {
|
|
Image *image;
|
|
ExceptionInfo *exception;
|
|
} CopyProfileInfo;
|
|
|
|
static void *
|
|
magick_set_magick_profile_cb( VipsImage *im,
|
|
const char *name, GValue *value, CopyProfileInfo *info )
|
|
{
|
|
char txt[256];
|
|
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
|
const void *data;
|
|
size_t length;
|
|
|
|
if( strcmp( name, VIPS_META_XMP_NAME ) == 0 )
|
|
vips_buf_appendf( &buf, "XMP" );
|
|
else if( strcmp( name, VIPS_META_IPTC_NAME ) == 0 )
|
|
vips_buf_appendf( &buf, "IPTC" );
|
|
else if( strcmp( name, VIPS_META_ICC_NAME ) == 0 )
|
|
vips_buf_appendf( &buf, "ICM" );
|
|
else if( strcmp( name, VIPS_META_EXIF_NAME ) == 0 )
|
|
vips_buf_appendf( &buf, "EXIF" );
|
|
else if( vips_isprefix( "magickprofile-", name ) )
|
|
vips_buf_appendf( &buf,
|
|
"%s", name + strlen( "magickprofile-" ) );
|
|
|
|
if( vips_buf_is_empty( &buf ) )
|
|
return( NULL );
|
|
if( !vips_image_get_typeof( im, name ) )
|
|
return( NULL );
|
|
if( vips_image_get_blob( im, name, &data, &length ) )
|
|
return( im );
|
|
|
|
if( !magick_set_profile( info->image,
|
|
vips_buf_all( &buf ), data, length, info->exception ) )
|
|
return( im );
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
/* Set magick metadata from a VipsImage.
|
|
*/
|
|
int
|
|
magick_set_magick_profile( Image *image,
|
|
VipsImage *im, ExceptionInfo *exception )
|
|
{
|
|
CopyProfileInfo info;
|
|
|
|
info.image = image;
|
|
info.exception = exception;
|
|
if( vips_image_map( im,
|
|
(VipsImageMapFn) magick_set_magick_profile_cb, &info ) )
|
|
return( -1 );
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
/* Does a few bytes look like a file IM can handle?
|
|
*/
|
|
gboolean
|
|
magick_ismagick( const unsigned char *bytes, size_t length )
|
|
{
|
|
#ifdef HAVE_MAGICK7
|
|
char format[MagickPathExtent];
|
|
#else /*HAVE_MAGICK6*/
|
|
char format[MaxTextExtent];
|
|
#endif
|
|
|
|
magick_genesis();
|
|
|
|
/* Try with our custom sniffers first.
|
|
*/
|
|
return( magick_sniff( bytes, length ) ||
|
|
GetImageMagick( bytes, length, format ) );
|
|
}
|
|
|
|
#endif /*HAVE_MAGICK*/
|