Added IdentifyImageType that returns the potential type of the image, GetImageType will no longer do this.

Added IdentifyPaletteImage that checks if the image  has 256 unique colors or less, IsPaletteImage will no longer do this.
Moved SetImageGray and SetImageMonochrome to colorspace.c
Renamed determineType to identifyType in Magick++
This commit is contained in:
dirk
2015-07-25 11:46:32 +00:00
parent 4167f3a934
commit ab4f0bb4e2
19 changed files with 596 additions and 497 deletions
+12 -15
View File
@@ -1609,10 +1609,7 @@ Magick::ImageType Magick::Image::type(void) const
{
if (constOptions()->type() != UndefinedType)
return(constOptions()->type());
else if (constImage()->type != UndefinedType)
return(constImage()->type);
else
return(determineType());
return(GetImageType(constImage()));
}
void Magick::Image::type(const Magick::ImageType type_)
@@ -2692,17 +2689,6 @@ void Magick::Image::despeckle(void)
ThrowImageException;
}
Magick::ImageType Magick::Image::determineType(void) const
{
ImageType
image_type;
GetPPException;
image_type=GetImageType(constImage(),exceptionInfo);
ThrowImageException;
return(image_type);
}
void Magick::Image::display(void)
{
GetPPException;
@@ -3234,6 +3220,17 @@ void Magick::Image::houghLine(const size_t width_,const size_t height_,
ThrowImageException;
}
Magick::ImageType Magick::Image::identifyType(void) const
{
ImageType
image_type;
GetPPException;
image_type=IdentifyImageType(constImage(),exceptionInfo);
ThrowImageException;
return(image_type);
}
void Magick::Image::implode(const double factor_)
{
MagickCore::Image
+4 -4
View File
@@ -821,10 +821,6 @@ namespace Magick
// Despeckle image (reduce speckle noise)
void despeckle(void);
// Determines the color type of the image. This method can be used to
// automaticly make the type GrayScale.
ImageType determineType(void) const;
// Display image on screen
void display(void);
@@ -978,6 +974,10 @@ namespace Magick
void houghLine(const size_t width_,const size_t height_,
const size_t threshold_=40);
// Identifies the potential color type of the image. This method can be
// used to detect if the type can be changed to GrayScale.
ImageType identifyType(void) const;
// Implode image (special effect)
void implode(const double factor_);
+226 -182
View File
@@ -568,19 +568,68 @@ MagickExport size_t GetImageQuantumDepth(const Image *image,
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetImageType() returns the potential type of image:
% GetImageType() returns the type of image:
%
% Bilevel Grayscale GrayscaleMatte
% Palette PaletteMatte TrueColor
% TrueColorMatte ColorSeparation ColorSeparationMatte
%
% To ensure the image type matches its potential, use SetImageType():
%
% (void) SetImageType(image,GetImageType(image));
%
% The format of the GetImageType method is:
%
% ImageType GetImageType(const Image *image,ExceptionInfo *exception)
% ImageType GetImageType(const Image *image)
%
% A description of each parameter follows:
%
% o image: the image.
%
*/
MagickExport ImageType GetImageType(const Image *image)
{
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->colorspace == CMYKColorspace)
{
if (image->alpha_trait == UndefinedPixelTrait)
return(ColorSeparationType);
return(ColorSeparationAlphaType);
}
if (IsImageMonochrome(image) != MagickFalse)
return(BilevelType);
if (IsImageGray(image) != MagickFalse)
{
if (image->alpha_trait != UndefinedPixelTrait)
return(GrayscaleAlphaType);
return(GrayscaleType);
}
if (IsPaletteImage(image) != MagickFalse)
{
if (image->alpha_trait != UndefinedPixelTrait)
return(PaletteAlphaType);
return(PaletteType);
}
if (image->alpha_trait != UndefinedPixelTrait)
return(TrueColorAlphaType);
return(TrueColorType);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I d e n t i f y I m a g e G r a y %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% IdentifyImageGray() returns grayscale if all the pixels in the image have
% the same red, green, and blue intensities, and bi-level is the intensity is
% either 0 or QuantumRange. Otherwise undefined is returned.
%
% The format of the IdentifyImageGray method is:
%
% ImageType IdentifyImageGray(const Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
@@ -589,7 +638,173 @@ MagickExport size_t GetImageQuantumDepth(const Image *image,
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport ImageType GetImageType(const Image *image,ExceptionInfo *exception)
MagickExport ImageType IdentifyImageGray(const Image *image,
ExceptionInfo *exception)
{
CacheView
*image_view;
ImageType
type;
register const Quantum
*p;
register ssize_t
x;
ssize_t
y;
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
(image->type == GrayscaleAlphaType))
return(image->type);
if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
return(UndefinedType);
type=BilevelType;
image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
if (IsPixelGray(image,p) == MagickFalse)
{
type=UndefinedType;
break;
}
if ((type == BilevelType) &&
(IsPixelMonochrome(image,p) == MagickFalse))
type=GrayscaleType;
p+=GetPixelChannels(image);
}
if (type == UndefinedType)
break;
}
image_view=DestroyCacheView(image_view);
if ((type == GrayscaleType) && (image->alpha_trait != UndefinedPixelTrait))
type=GrayscaleAlphaType;
return(type);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I d e n t i f y I m a g e M o n o c h r o m e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% IdentifyImageMonochrome() returns MagickTrue if all the pixels in the image
% have the same red, green, and blue intensities and the intensity is either
% 0 or QuantumRange.
%
% The format of the IdentifyImageMonochrome method is:
%
% MagickBooleanType IdentifyImageMonochrome(const Image *image,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType IdentifyImageMonochrome(const Image *image,
ExceptionInfo *exception)
{
CacheView
*image_view;
ImageType
type;
register ssize_t
x;
register const Quantum
*p;
ssize_t
y;
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (image->type == BilevelType)
return(MagickTrue);
if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
return(MagickFalse);
type=BilevelType;
image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
if (IsPixelMonochrome(image,p) == MagickFalse)
{
type=UndefinedType;
break;
}
p+=GetPixelChannels(image);
}
if (type == UndefinedType)
break;
}
image_view=DestroyCacheView(image_view);
if (type == BilevelType)
return(MagickTrue);
return(MagickFalse);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I d e n t i f y I m a g e T y p e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% IdentifyImageType() returns the potential type of image:
%
% Bilevel Grayscale GrayscaleMatte
% Palette PaletteMatte TrueColor
% TrueColorMatte ColorSeparation ColorSeparationMatte
%
% To ensure the image type matches its potential, use SetImageType():
%
% (void) SetImageType(image,IdentifyImageType(image,exception),exception);
%
% The format of the IdentifyImageType method is:
%
% ImageType IdentifyImageType(const Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport ImageType IdentifyImageType(const Image *image,
ExceptionInfo *exception)
{
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
@@ -601,15 +816,15 @@ MagickExport ImageType GetImageType(const Image *image,ExceptionInfo *exception)
return(ColorSeparationType);
return(ColorSeparationAlphaType);
}
if (SetImageMonochrome((Image *) image,exception) != MagickFalse)
if (IdentifyImageMonochrome(image,exception) != MagickFalse)
return(BilevelType);
if (SetImageGray((Image *) image,exception) != MagickFalse)
if (IdentifyImageGray(image,exception) != MagickFalse)
{
if (image->alpha_trait != UndefinedPixelTrait)
return(GrayscaleAlphaType);
return(GrayscaleType);
}
if (IsPaletteImage(image,exception) != MagickFalse)
if (IdentifyPaletteImage(image,exception) != MagickFalse)
{
if (image->alpha_trait != UndefinedPixelTrait)
return(PaletteAlphaType);
@@ -619,7 +834,7 @@ MagickExport ImageType GetImageType(const Image *image,ExceptionInfo *exception)
return(TrueColorAlphaType);
return(TrueColorType);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
@@ -983,177 +1198,6 @@ MagickExport MagickBooleanType SetImageDepth(Image *image,
% %
% %
% %
% S e t I m a g e G r a y %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetImageGray() returns MagickTrue if all the pixels in the image have the
% same red, green, and blue intensities and changes the type of the image to
% bi-level or grayscale.
%
% The format of the SetImageGray method is:
%
% MagickBooleanType SetImageGray(const Image *image,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType SetImageGray(Image *image,
ExceptionInfo *exception)
{
CacheView
*image_view;
ImageType
type;
register const Quantum
*p;
register ssize_t
x;
ssize_t
y;
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (IsImageGray(image))
return(MagickTrue);
if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
(IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
return(MagickFalse);
type=BilevelType;
image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
if (IsPixelGray(image,p) == MagickFalse)
{
type=UndefinedType;
break;
}
if ((type == BilevelType) &&
(IsPixelMonochrome(image,p) == MagickFalse))
type=GrayscaleType;
p+=GetPixelChannels(image);
}
if (type == UndefinedType)
break;
}
image_view=DestroyCacheView(image_view);
if (type == UndefinedType)
return(MagickFalse);
image->colorspace=GRAYColorspace;
if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
return(MagickFalse);
image->type=type;
if ((type == GrayscaleType) && (image->alpha_trait != UndefinedPixelTrait))
image->type=GrayscaleAlphaType;
return(MagickTrue);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t I m a g e M o n o c h r o m e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetImageMonochrome() returns MagickTrue if all the pixels in the image have
% the same red, green, and blue intensities and the intensity is either
% 0 or QuantumRange and changes the type of the image to bi-level.
%
% The format of the SetImageMonochrome method is:
%
% MagickBooleanType SetImageMonochrome(const Image *image,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType SetImageMonochrome(Image *image,
ExceptionInfo *exception)
{
CacheView
*image_view;
ImageType
type;
register ssize_t
x;
register const Quantum
*p;
ssize_t
y;
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (image->type == BilevelType)
return(MagickTrue);
if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
(IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
return(MagickFalse);
type=BilevelType;
image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
if (IsPixelMonochrome(image,p) == MagickFalse)
{
type=UndefinedType;
break;
}
p+=GetPixelChannels(image);
}
if (type == UndefinedType)
break;
}
image_view=DestroyCacheView(image_view);
if (type == UndefinedType)
return(MagickFalse);
image->colorspace=GRAYColorspace;
if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
return(MagickFalse);
image->type=type;
return(MagickTrue);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t I m a g e T y p e %
% %
% %
+4 -3
View File
@@ -26,15 +26,16 @@ extern "C" {
#endif
extern MagickExport ImageType
GetImageType(const Image *,ExceptionInfo *);
GetImageType(const Image *),
IdentifyImageGray(const Image *,ExceptionInfo *),
IdentifyImageType(const Image *,ExceptionInfo *);
extern MagickExport MagickBooleanType
IdentifyImageMonochrome(const Image *,ExceptionInfo *),
IsImageGray(const Image *),
IsImageMonochrome(const Image *),
IsImageOpaque(const Image *,ExceptionInfo *),
SetImageDepth(Image *,const size_t,ExceptionInfo *),
SetImageGray(Image *,ExceptionInfo *),
SetImageMonochrome(Image *,ExceptionInfo *),
SetImageType(Image *,const ImageType,ExceptionInfo *);
extern MagickExport RectangleInfo
+100 -1
View File
@@ -40,6 +40,7 @@
Include declarations.
*/
#include "MagickCore/studio.h"
#include "MagickCore/attribute.h"
#include "MagickCore/property.h"
#include "MagickCore/cache.h"
#include "MagickCore/cache-private.h"
@@ -1118,7 +1119,105 @@ MagickExport MagickBooleanType SetImageColorspace(Image *image,
image->type=type;
return(status);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t I m a g e G r a y %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetImageGray() returns MagickTrue if all the pixels in the image have the
% same red, green, and blue intensities and changes the type of the image to
% bi-level or grayscale.
%
% The format of the SetImageGray method is:
%
% MagickBooleanType SetImageGray(const Image *image,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType SetImageGray(Image *image,
ExceptionInfo *exception)
{
ImageType
type;
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (IsImageGray(image))
return(MagickTrue);
if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
return(MagickFalse);
type=IdentifyImageGray(image,exception);
if (type == UndefinedType)
return(MagickFalse);
image->colorspace=GRAYColorspace;
if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
return(MagickFalse);
image->type=type;
return(MagickTrue);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t I m a g e M o n o c h r o m e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetImageMonochrome() returns MagickTrue if all the pixels in the image have
% the same red, green, and blue intensities and the intensity is either
% 0 or QuantumRange and changes the type of the image to bi-level.
%
% The format of the SetImageMonochrome method is:
%
% MagickBooleanType SetImageMonochrome(Image *image,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType SetImageMonochrome(Image *image,
ExceptionInfo *exception)
{
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (image->type == BilevelType)
return(MagickTrue);
if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
return(MagickFalse);
if (IdentifyImageMonochrome(image,exception) == MagickFalse)
return(MagickFalse);
image->colorspace=GRAYColorspace;
if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
return(MagickFalse);
image->type=BilevelType;
return(MagickTrue);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
+2
View File
@@ -61,6 +61,8 @@ typedef enum
extern MagickExport MagickBooleanType
SetImageColorspace(Image *,const ColorspaceType,ExceptionInfo *),
SetImageGray(Image *,ExceptionInfo *),
SetImageMonochrome(Image *,ExceptionInfo *),
TransformImageColorspace(Image *,const ColorspaceType,ExceptionInfo *);
#if defined(__cplusplus) || defined(c_plusplus)
+170 -257
View File
@@ -605,6 +605,171 @@ static NodeInfo *GetNodeInfo(CubeInfo *cube_info,const size_t level)
return(node_info);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% I d e n t i f y P a l e t t e I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% IdentifyPaletteImage() returns MagickTrue if the image has 256 unique colors
% or less.
%
% The format of the IdentifyPaletteImage method is:
%
% MagickBooleanType IdentifyPaletteImage(const Image *image,
% ExceptionInfo *exception)
%
% A description of each parameter follows.
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType CheckImageColors(const Image *image,
ExceptionInfo *exception,size_t max_colors)
{
CacheView
*image_view;
CubeInfo
*cube_info;
PixelInfo
pixel,
target;
register const Quantum
*p;
register ssize_t
x;
register NodeInfo
*node_info;
register ssize_t
i;
size_t
id,
index,
level;
ssize_t
y;
if (image->storage_class == PseudoClass)
return((image->colors <= max_colors) ? MagickTrue : MagickFalse);
/*
Initialize color description tree.
*/
cube_info=GetCubeInfo();
if (cube_info == (CubeInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
return(MagickFalse);
}
GetPixelInfo(image,&pixel);
GetPixelInfo(image,&target);
image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
/*
Start at the root and proceed level by level.
*/
node_info=cube_info->root;
index=MaxTreeDepth-1;
for (level=1; level < MaxTreeDepth; level++)
{
GetPixelInfoPixel(image,p,&pixel);
id=ColorToNodeId(image,&pixel,index);
if (node_info->child[id] == (NodeInfo *) NULL)
{
node_info->child[id]=GetNodeInfo(cube_info,level);
if (node_info->child[id] == (NodeInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
image->filename);
break;
}
}
node_info=node_info->child[id];
index--;
}
if (level < MaxTreeDepth)
break;
for (i=0; i < (ssize_t) node_info->number_unique; i++)
{
target=node_info->list[i];
if (IsPixelInfoEquivalent(&pixel,&target) != MagickFalse)
break;
}
if (i < (ssize_t) node_info->number_unique)
node_info->list[i].count++;
else
{
/*
Add this unique color to the color list.
*/
if (node_info->number_unique == 0)
node_info->list=(PixelInfo *) AcquireMagickMemory(
sizeof(*node_info->list));
else
node_info->list=(PixelInfo *) ResizeQuantumMemory(node_info->list,
(size_t) (i+1),sizeof(*node_info->list));
if (node_info->list == (PixelInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
image->filename);
break;
}
node_info->list[i].red=(double) GetPixelRed(image,p);
node_info->list[i].green=(double) GetPixelGreen(image,p);
node_info->list[i].blue=(double) GetPixelBlue(image,p);
if (image->colorspace == CMYKColorspace)
node_info->list[i].black=(double) GetPixelBlack(image,p);
node_info->list[i].alpha=(double) GetPixelAlpha(image,p);
node_info->list[i].count=1;
node_info->number_unique++;
cube_info->colors++;
if (cube_info->colors > max_colors)
break;
}
p+=GetPixelChannels(image);
}
if (x < (ssize_t) image->columns)
break;
}
image_view=DestroyCacheView(image_view);
cube_info=DestroyCubeInfo(image,cube_info);
return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
}
MagickExport MagickBooleanType IdentifyPaletteImage(const Image *image,
ExceptionInfo *exception)
{
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
return(CheckImageColors(image,exception,256));
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
@@ -636,136 +801,11 @@ MagickExport MagickBooleanType IsHistogramImage(const Image *image,
{
#define MaximumUniqueColors 1024
CacheView
*image_view;
CubeInfo
*cube_info;
PixelInfo
pixel,
target;
register const Quantum
*p;
register ssize_t
x;
register NodeInfo
*node_info;
register ssize_t
i;
size_t
id,
index,
level;
ssize_t
y;
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if ((image->storage_class == PseudoClass) &&
(image->colors <= MaximumUniqueColors))
return(MagickTrue);
if (image->storage_class == PseudoClass)
return(MagickFalse);
/*
Initialize color description tree.
*/
cube_info=GetCubeInfo();
if (cube_info == (CubeInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
return(MagickFalse);
}
GetPixelInfo(image,&pixel);
GetPixelInfo(image,&target);
image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
/*
Start at the root and proceed level by level.
*/
node_info=cube_info->root;
index=MaxTreeDepth-1;
for (level=1; level < MaxTreeDepth; level++)
{
GetPixelInfoPixel(image,p,&pixel);
id=ColorToNodeId(image,&pixel,index);
if (node_info->child[id] == (NodeInfo *) NULL)
{
node_info->child[id]=GetNodeInfo(cube_info,level);
if (node_info->child[id] == (NodeInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
image->filename);
break;
}
}
node_info=node_info->child[id];
index--;
}
if (level < MaxTreeDepth)
break;
for (i=0; i < (ssize_t) node_info->number_unique; i++)
{
target=node_info->list[i];
if (IsPixelInfoEquivalent(&pixel,&target) != MagickFalse)
break;
}
if (i < (ssize_t) node_info->number_unique)
node_info->list[i].count++;
else
{
/*
Add this unique color to the color list.
*/
if (node_info->number_unique == 0)
node_info->list=(PixelInfo *) AcquireMagickMemory(
sizeof(*node_info->list));
else
node_info->list=(PixelInfo *) ResizeQuantumMemory(node_info->list,
(size_t) (i+1),sizeof(*node_info->list));
if (node_info->list == (PixelInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
image->filename);
break;
}
node_info->list[i].red=(double) GetPixelRed(image,p);
node_info->list[i].green=(double) GetPixelGreen(image,p);
node_info->list[i].blue=(double) GetPixelBlue(image,p);
if (image->colorspace == CMYKColorspace)
node_info->list[i].black=(double) GetPixelBlack(image,p);
node_info->list[i].alpha=(double) GetPixelAlpha(image,p);
node_info->list[i].count=1;
node_info->number_unique++;
cube_info->colors++;
if (cube_info->colors > MaximumUniqueColors)
break;
}
p+=GetPixelChannels(image);
}
if (x < (ssize_t) image->columns)
break;
}
image_view=DestroyCacheView(image_view);
cube_info=DestroyCubeInfo(image,cube_info);
return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
return(CheckImageColors(image,exception,MaximumUniqueColors));
}
/*
@@ -784,149 +824,22 @@ MagickExport MagickBooleanType IsHistogramImage(const Image *image,
%
% The format of the IsPaletteImage method is:
%
% MagickBooleanType IsPaletteImage(const Image *image,
% ExceptionInfo *exception)
% MagickBooleanType IsPaletteImage(const Image *image)
%
% A description of each parameter follows.
%
% o image: the image.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType IsPaletteImage(const Image *image,
ExceptionInfo *exception)
MagickExport MagickBooleanType IsPaletteImage(const Image *image)
{
CacheView
*image_view;
CubeInfo
*cube_info;
PixelInfo
pixel,
target;
register const Quantum
*p;
register ssize_t
x;
register NodeInfo
*node_info;
register ssize_t
i;
size_t
id,
index,
level;
ssize_t
y;
assert(image != (Image *) NULL);
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if ((image->storage_class == PseudoClass) && (image->colors <= 256))
return(MagickTrue);
if (image->storage_class == PseudoClass)
if (image->storage_class != PseudoClass)
return(MagickFalse);
/*
Initialize color description tree.
*/
cube_info=GetCubeInfo();
if (cube_info == (CubeInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
return(MagickFalse);
}
GetPixelInfo(image,&pixel);
GetPixelInfo(image,&target);
image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
/*
Start at the root and proceed level by level.
*/
node_info=cube_info->root;
index=MaxTreeDepth-1;
for (level=1; level < MaxTreeDepth; level++)
{
GetPixelInfoPixel(image,p,&pixel);
id=ColorToNodeId(image,&pixel,index);
if (node_info->child[id] == (NodeInfo *) NULL)
{
node_info->child[id]=GetNodeInfo(cube_info,level);
if (node_info->child[id] == (NodeInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
image->filename);
break;
}
}
node_info=node_info->child[id];
index--;
}
if (level < MaxTreeDepth)
break;
for (i=0; i < (ssize_t) node_info->number_unique; i++)
{
target=node_info->list[i];
if (IsPixelInfoEquivalent(&pixel,&target) != MagickFalse)
break;
}
if (i < (ssize_t) node_info->number_unique)
node_info->list[i].count++;
else
{
/*
Add this unique color to the color list.
*/
if (node_info->number_unique == 0)
node_info->list=(PixelInfo *) AcquireMagickMemory(
sizeof(*node_info->list));
else
node_info->list=(PixelInfo *) ResizeQuantumMemory(node_info->list,
(size_t) (i+1),sizeof(*node_info->list));
if (node_info->list == (PixelInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
image->filename);
break;
}
node_info->list[i]=pixel;
node_info->list[i].red=(double) GetPixelRed(image,p);
node_info->list[i].green=(double) GetPixelGreen(image,p);
node_info->list[i].blue=(double) GetPixelBlue(image,p);
if (image->colorspace == CMYKColorspace)
node_info->list[i].black=(double) GetPixelBlack(image,p);
node_info->list[i].alpha=(double) GetPixelAlpha(image,p);
node_info->list[i].count=1;
node_info->number_unique++;
cube_info->colors++;
if (cube_info->colors > 256)
break;
}
p+=GetPixelChannels(image);
}
if (x < (ssize_t) image->columns)
break;
}
image_view=DestroyCacheView(image_view);
cube_info=DestroyCubeInfo(image,cube_info);
return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
return((image->colors <= 256) ? MagickTrue : MagickFalse);
}
/*
+2 -1
View File
@@ -29,8 +29,9 @@ extern MagickExport Image
*UniqueImageColors(const Image *,ExceptionInfo *);
extern MagickExport MagickBooleanType
IdentifyPaletteImage(const Image *,ExceptionInfo *),
IsHistogramImage(const Image *,ExceptionInfo *),
IsPaletteImage(const Image *,ExceptionInfo *),
IsPaletteImage(const Image *),
MinMaxStretchImage(Image *,const double,const double,const double,
ExceptionInfo *);
+9 -9
View File
@@ -465,6 +465,7 @@ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
user_time;
ImageType
base_type,
type;
MagickBooleanType
@@ -489,6 +490,11 @@ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (file == (FILE *) NULL)
file=stdout;
colorspace=image->colorspace;
type=IdentifyImageType(image,exception);
if ((type == BilevelType) || (type == GrayscaleType) ||
(type == GrayscaleAlphaType))
colorspace=GRAYColorspace;
locate=GetImageArtifact(image,"identify:locate");
if (locate != (const char *) NULL)
{
@@ -513,9 +519,6 @@ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
channel_statistics=GetLocationStatistics(image,type,exception);
if (channel_statistics == (ChannelStatistics *) NULL)
return(MagickFalse);
colorspace=image->colorspace;
if (SetImageGray(image,exception) != MagickFalse)
colorspace=GRAYColorspace;
(void) FormatLocaleFile(file,"Channel %s locations:\n",locate);
switch (colorspace)
{
@@ -635,7 +638,6 @@ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
*/
p=GetVirtualPixels(image,0,0,1,1,exception);
ping=p == (const Quantum *) NULL ? MagickTrue : MagickFalse;
type=GetImageType(image,exception);
(void) SignatureImage(image,exception);
(void) FormatLocaleFile(file,"Image: %s\n",image->filename);
if (*image->magick_filename != '\0')
@@ -680,9 +682,10 @@ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
MagickResolutionOptions,(ssize_t) image->units));
(void) FormatLocaleFile(file," Type: %s\n",CommandOptionToMnemonic(
MagickTypeOptions,(ssize_t) type));
if (image->type != UndefinedType)
base_type=GetImageType(image);
if (type != base_type)
(void) FormatLocaleFile(file," Base type: %s\n",CommandOptionToMnemonic(
MagickTypeOptions,(ssize_t) image->type));
MagickTypeOptions,(ssize_t) base_type));
(void) FormatLocaleFile(file," Endianess: %s\n",CommandOptionToMnemonic(
MagickEndianOptions,(ssize_t) image->endian));
/*
@@ -694,7 +697,6 @@ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
channel_moments=(ChannelMoments *) NULL;
channel_phash=(ChannelPerceptualHash *) NULL;
channel_features=(ChannelFeatures *) NULL;
colorspace=image->colorspace;
scale=1.0;
if (ping == MagickFalse)
{
@@ -724,8 +726,6 @@ MagickExport MagickBooleanType IdentifyImage(Image *image,FILE *file,
(void) FormatLocaleFile(file," Depth: %.20g/%.20g-bit\n",(double)
image->depth,(double) depth);
(void) FormatLocaleFile(file," Channel depth:\n");
if (SetImageGray(image,exception) != MagickFalse)
colorspace=GRAYColorspace;
switch (colorspace)
{
case RGBColorspace:
+1 -1
View File
@@ -3004,7 +3004,7 @@ MagickExport const char *GetMagickProperty(ImageInfo *image_info,
{
WarnNoImageReturn("\"%%[%s]\"",property);
string=CommandOptionToMnemonic(MagickTypeOptions,(ssize_t)
GetImageType(image,exception));
IdentifyImageType(image,exception));
break;
}
break;
+1 -1
View File
@@ -1189,7 +1189,7 @@ MagickExport MagickBooleanType CompressImageColormap(Image *image,
assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (IsPaletteImage(image,exception) == MagickFalse)
if (image->storage_class != PseudoClass)
return(MagickFalse);
GetQuantizeInfo(&quantize_info);
quantize_info.number_colors=image->colors;
+47 -6
View File
@@ -5635,10 +5635,6 @@ WandExport size_t MagickGetImageTicksPerSecond(MagickWand *wand)
% Palette PaletteMatte TrueColor
% TrueColorMatte ColorSeparation ColorSeparationMatte
%
% To ensure the image type matches its potential, use MagickSetImageType():
%
% (void) MagickSetImageType(wand,MagickGetImageType(wand));
%
% The format of the MagickGetImageType method is:
%
% ImageType MagickGetImageType(MagickWand *wand)
@@ -5660,7 +5656,7 @@ WandExport ImageType MagickGetImageType(MagickWand *wand)
"ContainsNoImages","`%s'",wand->name);
return(UndefinedType);
}
return(GetImageType(wand->images,wand->exception));
return(GetImageType(wand->images));
}
/*
@@ -6060,7 +6056,52 @@ WandExport char *MagickIdentifyImage(MagickWand *wand)
(void) RelinquishUniqueFileResource(filename);
return(description);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% M a g i c k I d e n t i f y I m a g e T y p e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% MagickIdentifyImageType() gets the potential image type:
%
% Bilevel Grayscale GrayscaleMatte
% Palette PaletteMatte TrueColor
% TrueColorMatte ColorSeparation ColorSeparationMatte
%
% To ensure the image type matches its potential, use MagickSetImageType():
%
% (void) MagickSetImageType(wand,MagickIdentifyImageType(wand));
%
% The format of the MagickIdentifyImageType method is:
%
% ImageType MagickIdentifyImageType(MagickWand *wand)
%
% A description of each parameter follows:
%
% o wand: the magick wand.
%
*/
WandExport ImageType MagickIdentifyImageType(MagickWand *wand)
{
assert(wand != (MagickWand *) NULL);
assert(wand->signature == MagickWandSignature);
if (IfMagickTrue(wand->debug))
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
if (wand->images == (Image *) NULL)
{
(void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
"ContainsNoImages","`%s'",wand->name);
return(UndefinedType);
}
return(IdentifyImageType(wand->images,wand->exception));
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
+2 -1
View File
@@ -68,7 +68,8 @@ extern WandExport Image
*GetImageFromMagickWand(const MagickWand *);
extern WandExport ImageType
MagickGetImageType(MagickWand *);
MagickGetImageType(MagickWand *),
MagickIdentifyImageType(MagickWand *);
extern WandExport InterlaceType
MagickGetImageInterlaceScheme(MagickWand *);
+2 -2
View File
@@ -429,8 +429,8 @@ static MagickBooleanType WriteEPTImage(const ImageInfo *image_info,Image *image,
EPT preview requires that the image is colormapped.
*/
GetQuantizeInfo(&quantize_info);
quantize_info.dither_method=IsPaletteImage(write_image,exception) ==
MagickFalse ? RiemersmaDitherMethod : NoDitherMethod;
quantize_info.dither_method=IdentifyPaletteImage(write_image,
exception) == MagickFalse ? RiemersmaDitherMethod : NoDitherMethod;
(void) QuantizeImage(&quantize_info,write_image,exception);
}
write_info->compression=NoCompression;
+9 -9
View File
@@ -697,6 +697,7 @@ static MagickBooleanType EncodeImageAttributes(Image *image,FILE *file,
user_time;
ImageType
base_type,
type;
MagickBooleanType
@@ -728,7 +729,6 @@ static MagickBooleanType EncodeImageAttributes(Image *image,FILE *file,
p=GetVirtualPixels(image,0,0,1,1,exception);
ping=p == (const Quantum *) NULL ? MagickTrue : MagickFalse;
(void) ping;
type=GetImageType(image,exception);
(void) SignatureImage(image,exception);
JsonFormatLocaleFile(file,"{\n \"image\": {\n \"name\": %s,\n",
image->filename);
@@ -776,11 +776,17 @@ static MagickBooleanType EncodeImageAttributes(Image *image,FILE *file,
}
JsonFormatLocaleFile(file," \"units\": %s,\n",CommandOptionToMnemonic(
MagickResolutionOptions,(ssize_t) image->units));
colorspace=image->colorspace;
type=IdentifyImageType(image,exception);
if ((type == BilevelType) || (type == GrayscaleType) ||
(type == GrayscaleAlphaType))
colorspace=GRAYColorspace;
JsonFormatLocaleFile(file," \"type\": %s,\n",CommandOptionToMnemonic(
MagickTypeOptions,(ssize_t) type));
if (image->type != UndefinedType)
base_type=GetImageType(image);
if (type != base_type)
JsonFormatLocaleFile(file," \"baseType\": %s,\n",
CommandOptionToMnemonic(MagickTypeOptions,(ssize_t) image->type));
CommandOptionToMnemonic(MagickTypeOptions,(ssize_t) base_type));
JsonFormatLocaleFile(file," \"endianess\": %s,\n",
CommandOptionToMnemonic(MagickEndianOptions,(ssize_t) image->endian));
locate=GetImageArtifact(image,"identify:locate");
@@ -811,9 +817,6 @@ static MagickBooleanType EncodeImageAttributes(Image *image,FILE *file,
channel_statistics=GetLocationStatistics(image,type,exception);
if (channel_statistics == (ChannelStatistics *) NULL)
return(MagickFalse);
colorspace=image->colorspace;
if (SetImageGray(image,exception) != MagickFalse)
colorspace=GRAYColorspace;
(void) FormatLocaleFile(file," \"channel%s\": {\n",locate);
if (image->alpha_trait != UndefinedPixelTrait)
(void) PrintChannelLocations(file,image,AlphaPixelChannel,"Alpha",
@@ -864,7 +867,6 @@ static MagickBooleanType EncodeImageAttributes(Image *image,FILE *file,
channel_moments=(ChannelMoments *) NULL;
channel_phash=(ChannelPerceptualHash *) NULL;
channel_features=(ChannelFeatures *) NULL;
colorspace=image->colorspace;
scale=1;
channel_statistics=GetImageStatistics(image,exception);
if (channel_statistics == (ChannelStatistics *) NULL)
@@ -890,8 +892,6 @@ static MagickBooleanType EncodeImageAttributes(Image *image,FILE *file,
(void) FormatLocaleFile(file," \"baseDepth\": %.20g,\n",(double)
image->depth);
(void) FormatLocaleFile(file," \"channelDepth\": {\n");
if (SetImageGray(image,exception) != MagickFalse)
colorspace=GRAYColorspace;
if (image->alpha_trait != UndefinedPixelTrait)
(void) FormatLocaleFile(file," \"alpha\": %.20g,\n",(double)
channel_statistics[AlphaPixelChannel].depth);
+1 -1
View File
@@ -380,7 +380,7 @@ static MagickBooleanType WriteMAPImage(const ImageInfo *image_info,Image *image,
/*
Allocate colormap.
*/
if (IsPaletteImage(image,exception) == MagickFalse)
if (IsPaletteImage(image) == MagickFalse)
(void) SetImageType(image,PaletteType,exception);
depth=GetImageQuantumDepth(image,MagickTrue);
packet_size=(size_t) (depth/8);
+1 -1
View File
@@ -804,7 +804,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
{
if (flags & PALM_HAS_COLORMAP_FLAG) /* Write out colormap */
{
quantize_info->dither_method=IsPaletteImage(image,exception)
quantize_info->dither_method=IdentifyPaletteImage(image,exception)
== MagickFalse ? RiemersmaDitherMethod : NoDitherMethod;
quantize_info->number_colors=image->colors;
(void) QuantizeImage(quantize_info,image,exception);
+1 -2
View File
@@ -759,8 +759,7 @@ static MagickBooleanType WritePDBImage(const ImageInfo *image_info,Image *image,
if (status == MagickFalse)
return(status);
(void) TransformImageColorspace(image,sRGBColorspace,exception);
if ((image->colors <= 2) ||
(GetImageType(image,exception ) == BilevelType)) {
if (SetImageMonochrome(image,exception) != MagickFalse) {
bits_per_pixel=1;
} else if (image->colors <= 4) {
bits_per_pixel=2;
+2 -1
View File
@@ -3444,7 +3444,8 @@ static MagickBooleanType TraceSVGImage(Image *image,ExceptionInfo *exception)
*/
fitting_options=at_fitting_opts_new();
output_options=at_output_opts_new();
type=GetImageType(image,exception);
(void) SetImageGray(image,exception);
type=GetImageType(image);
number_planes=3;
if ((type == BilevelType) || (type == GrayscaleType))
number_planes=1;