/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P i x e l S y n c I t e r a t o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PixelSyncIterator() syncs the pixel iterator. % % The format of the PixelSyncIterator method is: % % MagickBooleanType PixelSyncIterator(PixelIterator *iterator) % % A description of each parameter follows: % % o iterator: the pixel iterator. % */ WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator) { IndexPacket *indexes; register long x; register PixelPacket *p; assert(iterator != (const PixelIterator *) NULL); assert(iterator->signature == WandSignature); if (iterator->debug != MagickFalse) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name); if (SetCacheViewStorageClass(iterator->view,DirectClass) == MagickFalse) return(MagickFalse); p=GetCacheViewPixels(iterator->view,iterator->region.x,iterator->region.y+ iterator->y,iterator->region.width,1); if (p == (PixelPacket *) NULL) { InheritException(iterator->exception,GetCacheViewException( iterator->view)); return(MagickFalse); } indexes=GetCacheViewIndexes(iterator->view); for (x=0; x < (long) iterator->region.width; x++) { PixelGetQuantumColor(iterator->pixel_wands[x],p); if (GetCacheViewColorspace(iterator->view) == CMYKColorspace) indexes[x]=PixelGetBlackQuantum(iterator->pixel_wands[x]); else if (GetCacheViewStorageClass(iterator->view) == PseudoClass) indexes[x]=PixelGetIndex(iterator->pixel_wands[x]); p++; } if (SyncCacheView(iterator->view) == MagickFalse) { InheritException(iterator->exception,GetCacheViewException( iterator->view)); return(MagickFalse); } return(MagickTrue); }
MagickExport Image *CompareImageChannels(Image *image, const Image *reconstruct_image,const ChannelType channel, const MetricType metric,double *distortion,ExceptionInfo *exception) { Image *difference_image; long y; MagickPixelPacket composite, red, source, white; MagickStatusType difference; register const IndexPacket *indexes, *reconstruct_indexes; register const PixelPacket *p, *q; register IndexPacket *difference_indexes; register long x; register PixelPacket *r; ViewInfo *difference_view, *image_view, *reconstruct_view; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(reconstruct_image != (const Image *) NULL); assert(reconstruct_image->signature == MagickSignature); assert(distortion != (double *) NULL); *distortion=0.0; if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); if ((reconstruct_image->columns != image->columns) || (reconstruct_image->rows != image->rows)) ThrowImageException(ImageError,"ImageSizeDiffers"); difference_image=CloneImage(image,image->columns,image->rows,MagickTrue, exception); if (difference_image == (Image *) NULL) return((Image *) NULL); if (SetImageStorageClass(difference_image,DirectClass) == MagickFalse) { InheritException(exception,&difference_image->exception); difference_image=DestroyImage(difference_image); return((Image *) NULL); } (void) QueryMagickColor("#f1001e",&red,exception); (void) QueryMagickColor("#ffffff",&white,exception); if (difference_image->colorspace == CMYKColorspace) { ConvertRGBToCMYK(&red); ConvertRGBToCMYK(&white); } /* Generate difference image. */ GetMagickPixelPacket(reconstruct_image,&source); GetMagickPixelPacket(difference_image,&composite); image_view=OpenCacheView(image); reconstruct_view=OpenCacheView(reconstruct_image); difference_view=OpenCacheView(difference_image); for (y=0; y < (long) image->rows; y++) { p=AcquireCacheViewPixels(image_view,0,y,image->columns,1,exception); q=AcquireCacheViewPixels(reconstruct_view,0,y,reconstruct_image->columns,1, exception); r=SetCacheView(difference_view,0,y,difference_image->columns,1); if ((p == (const PixelPacket *) NULL) || (q == (const PixelPacket *) NULL) || (r == (PixelPacket *) NULL)) break; indexes=AcquireCacheViewIndexes(image_view); reconstruct_indexes=AcquireCacheViewIndexes(reconstruct_view); difference_indexes=GetCacheViewIndexes(difference_view); for (x=0; x < (long) image->columns; x++) { difference=MagickFalse; if ((channel & RedChannel) != 0) if (p->red != q->red) difference=MagickTrue; if ((channel & GreenChannel) != 0) if (p->green != q->green) difference=MagickTrue; if ((channel & BlueChannel) != 0) if (p->blue != q->blue) difference=MagickTrue; if ((channel & OpacityChannel) != 0) if (p->opacity != q->opacity) difference=MagickTrue; if (((channel & IndexChannel) != 0) && (image->colorspace == CMYKColorspace) && (reconstruct_image->colorspace == CMYKColorspace)) if (indexes[x] != reconstruct_indexes[x]) difference=MagickTrue; SetMagickPixelPacket(reconstruct_image,q,reconstruct_indexes+x,&source); if (difference != MagickFalse) MagickPixelCompositeOver(&source,7.5*QuantumRange/10.0,&red, (MagickRealType) red.opacity,&composite); else MagickPixelCompositeOver(&source,7.5*QuantumRange/10.0,&white, (MagickRealType) white.opacity,&composite); SetPixelPacket(difference_image,&composite,r,difference_indexes+x); p++; q++; r++; } if (SyncCacheView(difference_view) == MagickFalse) break; } difference_view=CloseCacheView(difference_view); reconstruct_view=CloseCacheView(reconstruct_view); image_view=CloseCacheView(image_view); (void) GetImageChannelDistortion(image,reconstruct_image,channel,metric, distortion,exception); return(difference_image); }