/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d G R A D I E N T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadGRADIENTImage creates a gradient image and initializes it to % the color range as specified by the filename. It allocates the memory % necessary for the new Image structure and returns a pointer to the new % image. % % The format of the ReadGRADIENTImage method is: % % Image *ReadGRADIENTImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadGRADIENTImage(const ImageInfo *image_info, ExceptionInfo *exception) { char colorname[MaxTextExtent]; MagickBooleanType icc_color, status; MagickPixelPacket start_pixel, stop_pixel; PixelPacket start_color, stop_color; Image *image; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); (void) SetImageOpacity(image,(Quantum) TransparentOpacity); (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); (void) CopyMagickString(colorname,image_info->filename,MaxTextExtent); (void) sscanf(image_info->filename,"%[^-]",colorname); icc_color=MagickFalse; if (LocaleCompare(colorname,"icc") == 0) { (void) ConcatenateMagickString(colorname,"-",MaxTextExtent); (void) sscanf(image_info->filename,"%*[^-]-%[^-]",colorname+4); icc_color=MagickTrue; } if (QueryColorDatabase(colorname,&start_color,exception) == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } (void) QueryMagickColor(colorname,&start_pixel,exception); (void) CopyMagickString(colorname,"white",MaxTextExtent); if (GetPixelLuma(image,&start_color) > (QuantumRange/2)) (void) CopyMagickString(colorname,"black",MaxTextExtent); if (icc_color == MagickFalse) (void) sscanf(image_info->filename,"%*[^-]-%s",colorname); else (void) sscanf(image_info->filename,"%*[^-]-%*[^-]-%s",colorname); if (QueryColorDatabase(colorname,&stop_color,exception) == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } (void) QueryMagickColor(colorname,&stop_pixel,exception); (void) SetImageColorspace(image,start_pixel.colorspace); status=GradientImage(image,LocaleCompare(image_info->magick,"GRADIENT") == 0 ? LinearGradient : RadialGradient,PadSpread,&start_color,&stop_color); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if ((start_pixel.matte == MagickFalse) && (stop_pixel.matte == MagickFalse)) (void) SetImageAlphaChannel(image,DeactivateAlphaChannel); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S e t I m a g e A l p h a C h a n n e l % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SetImageAlphaChannel() activates, deactivates, resets, or sets the alpha % channel. % % The format of the SetImageAlphaChannel method is: % % MagickBooleanType SetImageAlphaChannel(Image *image, % const AlphaChannelType alpha_type) % % A description of each parameter follows: % % o image: the image. % % o alpha_type: The alpha channel type: ActivateAlphaChannel, % CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel, % OpaqueAlphaChannel, ResetAlphaChannel, SetAlphaChannel, % ShapeAlphaChannel, and TransparentAlphaChannel. % */ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, const AlphaChannelType alpha_type) { MagickBooleanType status; assert(image != (Image *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(image->signature == MagickSignature); status=MagickTrue; switch (alpha_type) { case ActivateAlphaChannel: { image->matte=MagickTrue; break; } case BackgroundAlphaChannel: { CacheView *image_view; ExceptionInfo *exception; IndexPacket index; MagickBooleanType status; MagickPixelPacket background; PixelPacket pixel; ssize_t y; /* Set transparent pixels to background color. */ if (image->matte == MagickFalse) break; if (SetImageStorageClass(image,DirectClass) == MagickFalse) break; GetMagickPixelPacket(image,&background); SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *) NULL,&background); if (image->colorspace == CMYKColorspace) ConvertRGBToCMYK(&background); index=0; SetPixelPacket(image,&background,&pixel,&index); status=MagickTrue; exception=(&image->exception); image_view=AcquireAuthenticCacheView(image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(status) \ magick_threads(image,image,image->rows,1) #endif for (y=0; y < (ssize_t) image->rows; y++) { register IndexPacket *restrict indexes; register PixelPacket *restrict q; register ssize_t x; if (status == MagickFalse) continue; q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, exception); if (q == (PixelPacket *) NULL) { status=MagickFalse; continue; } for (x=0; x < (ssize_t) image->columns; x++) { if (q->opacity == TransparentOpacity) { SetPixelRed(q,pixel.red); SetPixelGreen(q,pixel.green); SetPixelBlue(q,pixel.blue); } q++; } if (image->colorspace == CMYKColorspace) { indexes=GetCacheViewAuthenticIndexQueue(image_view); for (x=0; x < (ssize_t) image->columns; x++) SetPixelIndex(indexes+x,index); } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) status=MagickFalse; } image_view=DestroyCacheView(image_view); return(status); } case CopyAlphaChannel: case ShapeAlphaChannel: { /* Special usage case for SeparateImageChannel(): copy grayscale color to the alpha channel. */ status=SeparateImageChannel(image,GrayChannels); image->matte=MagickTrue; /* make sure transparency is now on! */ if (alpha_type == ShapeAlphaChannel) { MagickPixelPacket background; /* Reset all color channels to background color. */ GetMagickPixelPacket(image,&background); SetMagickPixelPacket(image,&(image->background_color),(IndexPacket *) NULL,&background); (void) LevelColorsImage(image,&background,&background,MagickTrue); } break; } case DeactivateAlphaChannel: { image->matte=MagickFalse; break; } case ExtractAlphaChannel: { status=SeparateImageChannel(image,TrueAlphaChannel); image->matte=MagickFalse; break; } case RemoveAlphaChannel: case FlattenAlphaChannel: { CacheView *image_view; ExceptionInfo *exception; IndexPacket index; MagickBooleanType status; MagickPixelPacket background; PixelPacket pixel; ssize_t y; /* Flatten image pixels over the background pixels. */ if (image->matte == MagickFalse) break; if (SetImageStorageClass(image,DirectClass) == MagickFalse) break; GetMagickPixelPacket(image,&background); SetMagickPixelPacket(image,&image->background_color,(const IndexPacket *) NULL,&background); if (image->colorspace == CMYKColorspace) ConvertRGBToCMYK(&background); index=0; SetPixelPacket(image,&background,&pixel,&index); status=MagickTrue; exception=(&image->exception); image_view=AcquireAuthenticCacheView(image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(status) \ magick_threads(image,image,image->rows,1) #endif for (y=0; y < (ssize_t) image->rows; y++) { register IndexPacket *restrict indexes; register PixelPacket *restrict q; register ssize_t x; if (status == MagickFalse) continue; q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1, exception); if (q == (PixelPacket *) NULL) { status=MagickFalse; continue; } for (x=0; x < (ssize_t) image->columns; x++) { double gamma, opacity; gamma=1.0-QuantumScale*QuantumScale*q->opacity*pixel.opacity; opacity=(double) QuantumRange*(1.0-gamma); gamma=PerceptibleReciprocal(gamma); q->red=ClampToQuantum(gamma*MagickOver_((MagickRealType) q->red, (MagickRealType) q->opacity,(MagickRealType) pixel.red, (MagickRealType) pixel.opacity)); q->green=ClampToQuantum(gamma*MagickOver_((MagickRealType) q->green, (MagickRealType) q->opacity,(MagickRealType) pixel.green, (MagickRealType) pixel.opacity)); q->blue=ClampToQuantum(gamma*MagickOver_((MagickRealType) q->blue, (MagickRealType) q->opacity,(MagickRealType) pixel.blue, (MagickRealType) pixel.opacity)); q->opacity=ClampToQuantum(opacity); q++; } if (image->colorspace == CMYKColorspace) { indexes=GetCacheViewAuthenticIndexQueue(image_view); for (x=0; x < (ssize_t) image->columns; x++) SetPixelIndex(indexes+x,index); } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) status=MagickFalse; } image_view=DestroyCacheView(image_view); return(status); } case ResetAlphaChannel: /* deprecated */ case OpaqueAlphaChannel: { status=SetImageOpacity(image,OpaqueOpacity); break; } case SetAlphaChannel: { if (image->matte == MagickFalse) status=SetImageOpacity(image,OpaqueOpacity); break; } case TransparentAlphaChannel: { status=SetImageOpacity(image,TransparentOpacity); break; } case UndefinedAlphaChannel: break; } if (status == MagickFalse) return(status); return(SyncImagePixelCache(image,&image->exception)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e R G B I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteRGBImage() writes an image to a file in red, green, and blue % rasterfile format. % % The format of the WriteRGBImage method is: % % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % */ static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image) { long y; MagickBooleanType status; MagickOffsetType scene; QuantumInfo quantum_info; register const PixelPacket *p; size_t packet_size; unsigned char *pixels; /* Allocate memory for pixels. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); packet_size=(size_t) ((3*image->depth+7)/8); if ((LocaleCompare(image_info->magick,"RGBA") == 0) || (LocaleCompare(image_info->magick,"RGBO") == 0)) packet_size+=(image->depth+7)/8; pixels=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size* sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); if (image_info->interlace != PartitionInterlace) { /* Open output image file. */ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); } scene=0; do { /* Convert MIFF to RGB raster pixels. */ GetQuantumInfo(image_info,&quantum_info); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); if (LocaleCompare(image_info->magick,"RGBA") == 0) if (image->matte == MagickFalse) (void) SetImageOpacity(image,OpaqueOpacity); switch (image_info->interlace) { case NoInterlace: default: { /* No interlacing: RGBRGBRGBRGBRGBRGB... */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; if (LocaleCompare(image_info->magick,"RGBA") != 0) { (void) ImportQuantumPixels(image,&quantum_info,RGBQuantum,pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); } else { if (LocaleCompare(image_info->magick,"RGBA") == 0) (void) ImportQuantumPixels(image,&quantum_info,RGBAQuantum, pixels); else (void) ImportQuantumPixels(image,&quantum_info,RGBOQuantum, pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); } if (image->previous == (Image *) NULL) if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(SaveImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } break; } case LineInterlace: { /* Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB... */ packet_size=(image->depth+7)/8; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ImportQuantumPixels(image,&quantum_info,RedQuantum,pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); (void) ImportQuantumPixels(image,&quantum_info,GreenQuantum,pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); (void) ImportQuantumPixels(image,&quantum_info,BlueQuantum,pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); if (LocaleCompare(image_info->magick,"RGBA") == 0) { if (LocaleCompare(image_info->magick,"RGBA") == 0) (void) ImportQuantumPixels(image,&quantum_info,AlphaQuantum, pixels); else (void) ImportQuantumPixels(image,&quantum_info,OpacityQuantum, pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); } if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(SaveImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } break; } case PlaneInterlace: case PartitionInterlace: { /* Plane interlacing: RRRRRR...GGGGGG...BBBBBB... */ packet_size=(image->depth+7)/8; if (image_info->interlace == PartitionInterlace) { AppendImageFormat("R",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == MagickFalse) return(status); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ImportQuantumPixels(image,&quantum_info,RedQuantum,pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("G",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == MagickFalse) return(status); } if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(LoadImageTag,100,400, image->client_data); if (status == MagickFalse) break; } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ImportQuantumPixels(image,&quantum_info,GreenQuantum,pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("B",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == MagickFalse) return(status); } if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(LoadImageTag,200,400, image->client_data); if (status == MagickFalse) break; } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ImportQuantumPixels(image,&quantum_info,BlueQuantum,pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); } if (LocaleCompare(image_info->magick,"RGBA") == 0) { if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(LoadImageTag,300,400, image->client_data); if (status == MagickFalse) break; } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("A",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == MagickFalse) return(status); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; if (LocaleCompare(image_info->magick,"RGBA") == 0) (void) ImportQuantumPixels(image,&quantum_info,AlphaQuantum, pixels); else (void) ImportQuantumPixels(image,&quantum_info,OpacityQuantum, pixels); (void) WriteBlob(image,packet_size*image->columns,pixels); } } if (image_info->interlace == PartitionInterlace) (void) CopyMagickString(image->filename,image_info->filename, MaxTextExtent); if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(LoadImageTag,400,400, image->client_data); if (status == MagickFalse) break; } break; } } if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(SaveImagesTag,scene, GetImageListLength(image),image->client_data); if (status == MagickFalse) break; } scene++; } while (image_info->adjoin != MagickFalse); pixels=(unsigned char *) RelinquishMagickMemory(pixels); CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e C M Y K I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteCMYKImage writes an image to a file in red, green, and blue % rasterfile format. % % The format of the WriteCMYKImage method is: % % unsigned int WriteCMYKImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteCMYKImage return True if the image is written. % False is returned is there is a memory shortage or if the image file % fails to write. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o image: A pointer to an Image structure. % % */ static unsigned int WriteCMYKImage(const ImageInfo *image_info,Image *image) { int y; register const PixelPacket *p; unsigned char *pixels; unsigned int packet_size, quantum_size, scene, status; ExportPixelAreaOptions export_options; ExportPixelAreaInfo export_info; if (image->depth <= 8) quantum_size=8; else if (image->depth <= 16) quantum_size=16; else quantum_size=32; /* Allocate memory for pixels. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); packet_size=(quantum_size*4)/8; if (LocaleCompare(image_info->magick,"CMYKA") == 0) packet_size=(quantum_size*5)/8; pixels=MagickAllocateArray(unsigned char *,packet_size,image->columns); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); if (image_info->interlace != PartitionInterlace) { /* Open output image file. */ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } scene=0; do { /* Convert MIFF to CMYK raster pixels. */ (void) TransformColorspace(image,CMYKColorspace); if (LocaleCompare(image_info->magick,"CMYKA") == 0) if (!image->matte) SetImageOpacity(image,OpaqueOpacity); /* Initialize export options. */ ExportPixelAreaOptionsInit(&export_options); if (image->endian != UndefinedEndian) export_options.endian=image->endian; else if (image_info->endian != UndefinedEndian) export_options.endian=image_info->endian; if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image depth %u bits, Endian %s",quantum_size, EndianTypeToString(export_options.endian)); switch (image_info->interlace) { case NoInterlace: default: { /* No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK... */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; if (LocaleCompare(image_info->magick,"CMYKA") != 0) { (void) ExportImagePixelArea(image,CMYKQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } else { (void) ExportImagePixelArea(image,CMYKAQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; } break; } case LineInterlace: { /* Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK... */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,CyanQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); (void) ExportImagePixelArea(image,MagentaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); (void) ExportImagePixelArea(image,YellowQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); (void) ExportImagePixelArea(image,BlackQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); if (LocaleCompare(image_info->magick,"CMYKA") == 0) { (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; } break; } case PlaneInterlace: case PartitionInterlace: { /* Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK... */ if (image_info->interlace == PartitionInterlace) { AppendImageFormat("C",image->filename); status= OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,CyanQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("M",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } if (!MagickMonitorFormatted(100,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,MagentaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("Y",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } if (!MagickMonitorFormatted(200,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,YellowQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("K",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } if (!MagickMonitorFormatted(200,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,BlackQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (LocaleCompare(image_info->magick,"CMYKA") == 0) { if (!MagickMonitorFormatted(300,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("A",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } } if (image_info->interlace == PartitionInterlace) (void) strlcpy(image->filename,image_info->filename,MaxTextExtent); if (!MagickMonitorFormatted(400,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; break; } } if (image->next == (Image *) NULL) break; image=SyncNextImageInList(image); status=MagickMonitorFormatted(scene++,GetImageListLength(image), &image->exception,SaveImagesText, image->filename); if (status == False) break; } while (image_info->adjoin); MagickFreeMemory(pixels); if (image_info->adjoin) while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); return(True); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S h e a r I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ShearImage() creates a new image that is a shear_image copy of an existing % one. Shearing slides one edge of an image along the X or Y axis, creating % a parallelogram. An X direction shear slides an edge along the X axis, % while a Y direction shear slides an edge along the Y axis. The amount of % the shear is controlled by a shear angle. For X direction shears, x_shear % is measured relative to the Y axis, and similarly, for Y direction shears % y_shear is measured relative to the X axis. Empty triangles left over from % shearing the image are filled with the background color defined by member % 'background_color' of the image.. ShearImage() allocates the memory % necessary for the new Image structure and returns a pointer to the new image. % % ShearImage() is based on the paper "A Fast Algorithm for General Raster % Rotatation" by Alan W. Paeth. % % The format of the ShearImage method is: % % Image *ShearImage(const Image *image,const double x_shear, % const double y_shear,ExceptionInfo *exception) % % A description of each parameter follows. % % o image: the image. % % o x_shear, y_shear: Specifies the number of degrees to shear the image. % % o exception: Return any errors or warnings in this structure. % % */ MagickExport Image *ShearImage(const Image *image,const double x_shear, const double y_shear,ExceptionInfo *exception) { Image *integral_image, *shear_image; long x_offset, y_offset; PointInfo shear; RectangleInfo border_info; unsigned long y_width; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); if ((x_shear != 0.0) && (fmod(x_shear,90.0) == 0.0)) ThrowImageException(ImageError,"AngleIsDiscontinuous"); if ((y_shear != 0.0) && (fmod(y_shear,90.0) == 0.0)) ThrowImageException(ImageError,"AngleIsDiscontinuous"); /* Initialize shear angle. */ integral_image=CloneImage(image,0,0,MagickTrue,exception); if (integral_image == (Image *) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); shear.x=(-tan(DegreesToRadians(x_shear))); shear.y=tan(DegreesToRadians(y_shear)); if ((shear.x == 0.0) && (shear.y == 0.0)) return(integral_image); if (SetImageStorageClass(integral_image,DirectClass) == MagickFalse) { InheritException(exception,&integral_image->exception); integral_image=DestroyImage(integral_image); return(integral_image); } if (integral_image->matte == MagickFalse) (void) SetImageOpacity(integral_image,OpaqueOpacity); /* Compute image size. */ y_width=image->columns+(long) (fabs(shear.x)*image->rows+0.5); x_offset=(long) (image->columns+((fabs(shear.x)*image->rows)- image->columns)/2.0+0.5); y_offset=(long) (image->rows+((fabs(shear.y)*y_width+0.5)-image->rows)/2.0+ 0.5); /* Surround image with border. */ integral_image->border_color=integral_image->background_color; integral_image->compose=CopyCompositeOp; border_info.width=(unsigned long) x_offset; border_info.height=(unsigned long) y_offset; shear_image=BorderImage(integral_image,&border_info,exception); if (shear_image == (Image *) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); integral_image=DestroyImage(integral_image); /* Shear the image. */ if (shear_image->matte == MagickFalse) (void) SetImageOpacity(shear_image,OpaqueOpacity); XShearImage(shear_image,shear.x,image->columns,image->rows,x_offset, ((long) shear_image->rows-image->rows)/2); YShearImage(shear_image,shear.y,y_width,image->rows, ((long) shear_image->columns-y_width)/2,y_offset); CropToFitImage(&shear_image,shear.x,shear.y,(MagickRealType) image->columns, (MagickRealType) image->rows,MagickFalse,exception); shear_image->compose=image->compose; shear_image->page.width=0; shear_image->page.height=0; return(shear_image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R o t a t e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % RotateImage() creates a new image that is a rotated copy of an existing % one. Positive angles rotate counter-clockwise (right-hand rule), while % negative angles rotate clockwise. Rotated images are usually larger than % the originals and have 'empty' triangular corners. X axis. Empty % triangles left over from shearing the image are filled with the background % color defined by member 'background_color' of the image. RotateImage % allocates the memory necessary for the new Image structure and returns a % pointer to the new image. % % RotateImage() is based on the paper "A Fast Algorithm for General % Raster Rotatation" by Alan W. Paeth. RotateImage is adapted from a similar % method based on the Paeth paper written by Michael Halle of the Spatial % Imaging Group, MIT Media Lab. % % The format of the RotateImage method is: % % Image *RotateImage(const Image *image,const double degrees, % ExceptionInfo *exception) % % A description of each parameter follows. % % o image: the image. % % o degrees: Specifies the number of degrees to rotate the image. % % o exception: Return any errors or warnings in this structure. % % */ MagickExport Image *RotateImage(const Image *image,const double degrees, ExceptionInfo *exception) { Image *integral_image, *rotate_image; long x_offset, y_offset; MagickRealType angle; PointInfo shear; RectangleInfo border_info; unsigned long height, rotations, width, y_width; /* Adjust rotation angle. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); angle=degrees; while (angle < -45.0) angle+=360.0; for (rotations=0; angle > 45.0; rotations++) angle-=90.0; rotations%=4; /* Calculate shear equations. */ integral_image=IntegralRotateImage(image,rotations,exception); if (integral_image == (Image *) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); shear.x=(-tan((double) DegreesToRadians(angle)/2.0)); shear.y=sin((double) DegreesToRadians(angle)); if ((shear.x == 0.0) && (shear.y == 0.0)) return(integral_image); if (SetImageStorageClass(integral_image,DirectClass) == MagickFalse) { InheritException(exception,&integral_image->exception); integral_image=DestroyImage(integral_image); return(integral_image); } if (integral_image->matte == MagickFalse) (void) SetImageOpacity(integral_image,OpaqueOpacity); /* Compute image size. */ width=image->columns; height=image->rows; if ((rotations == 1) || (rotations == 3)) { width=image->rows; height=image->columns; } y_width=width+(long) (fabs(shear.x)*height+0.5); x_offset=(long) (width+((fabs(shear.y)*height+0.5)-width)/2.0+0.5); y_offset=(long) (height+((fabs(shear.y)*y_width+0.5)-height)/2.0+0.5); /* Surround image with a border. */ integral_image->border_color=integral_image->background_color; integral_image->compose=CopyCompositeOp; border_info.width=(unsigned long) x_offset; border_info.height=(unsigned long) y_offset; rotate_image=BorderImage(integral_image,&border_info,exception); integral_image=DestroyImage(integral_image); if (rotate_image == (Image *) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); /* Rotate the image. */ XShearImage(rotate_image,shear.x,width,height,x_offset, ((long) rotate_image->rows-height)/2); YShearImage(rotate_image,shear.y,y_width,height, ((long) rotate_image->columns-y_width)/2,y_offset); XShearImage(rotate_image,shear.x,y_width,rotate_image->rows, ((long) rotate_image->columns-y_width)/2,0); CropToFitImage(&rotate_image,shear.x,shear.y,(MagickRealType) width, (MagickRealType) height,MagickTrue,exception); rotate_image->compose=image->compose; rotate_image->page.width=0; rotate_image->page.height=0; return(rotate_image); }
static Image *ReadPlasmaImage(const ImageInfo *image_info, ExceptionInfo *exception) { #define PlasmaImageTag "Plasma/Image" Image *image; ImageInfo *read_info; long y; MagickBooleanType status; register long x; register PixelPacket *q; register unsigned long i; SegmentInfo segment_info; unsigned long depth, max_depth; /* Recursively apply plasma to the image. */ read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); (void) FormatMagickString(read_info->filename,MaxTextExtent, "gradient:%s",image_info->filename); image=ReadImage(read_info,exception); read_info=DestroyImageInfo(read_info); if (image == (Image *) NULL) return((Image *) NULL); image->storage_class=DirectClass; for (y=0; y < (long) image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { q->opacity=(Quantum) (QuantumRange/2); q++; } if (SyncImagePixels(image) == MagickFalse) break; } segment_info.x1=0; segment_info.y1=0; segment_info.x2=(double) image->columns-1; segment_info.y2=(double) image->rows-1; if (LocaleCompare(image_info->filename,"fractal") == 0) { /* Seed pixels before recursion. */ PlasmaPixel(image,segment_info.x1,segment_info.y1); PlasmaPixel(image,segment_info.x1,(segment_info.y1+segment_info.y2)/2); PlasmaPixel(image,segment_info.x1,segment_info.y2); PlasmaPixel(image,(segment_info.x1+segment_info.x2)/2,segment_info.y1); PlasmaPixel(image,(segment_info.x1+segment_info.x2)/2, (segment_info.y1+segment_info.y2)/2); PlasmaPixel(image,(segment_info.x1+segment_info.x2)/2,segment_info.y2); PlasmaPixel(image,segment_info.x2,segment_info.y1); PlasmaPixel(image,segment_info.x2,(segment_info.y1+segment_info.y2)/2); PlasmaPixel(image,segment_info.x2,segment_info.y2); } i=(unsigned long) MagickMax(image->columns,image->rows)/2; for (max_depth=0; i != 0; max_depth++) i>>=1; for (depth=1; ; depth++) { if (PlasmaImage(image,&segment_info,0,depth) != MagickFalse) break; if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick((MagickOffsetType) depth,max_depth) != MagickFalse)) { status=image->progress_monitor(PlasmaImageTag,(MagickOffsetType) depth, max_depth,image->client_data); if (status == MagickFalse) break; } } (void) SetImageOpacity(image,OpaqueOpacity); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P a i n t T r a n s p a r e n t I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PaintTransparentImage() changes the opacity value associated with any pixel % that matches color to the value defined by opacity. % % By default color must match a particular pixel color exactly. However, % in many cases two colors may differ by a small amount. Fuzz defines % how much tolerance is acceptable to consider two colors as the same. % For example, set fuzz to 10 and the color red at intensities of 100 and % 102 respectively are now interpreted as the same color. % % The format of the PaintTransparentImage method is: % % MagickBooleanType PaintTransparentImage(Image *image, % const MagickPixelPacket *target,const Quantum opacity) % % A description of each parameter follows: % % o image: The image. % % o target: The RGB value of the target color. % % o opacity: The replacement opacity value. % */ MagickExport MagickBooleanType PaintTransparentImage(Image *image, const MagickPixelPacket *target,const Quantum opacity) { #define PaintTransparentImageTag "Transparent/Image" long y; MagickBooleanType status; MagickPixelPacket pixel; register IndexPacket *indexes; register long x; register PixelPacket *q; /* Make image color transparent. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(target != (MagickPixelPacket *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); if (SetImageStorageClass(image,DirectClass) == MagickFalse) return(MagickFalse); if (image->matte == MagickFalse) (void) SetImageOpacity(image,OpaqueOpacity); GetMagickPixelPacket(image,&pixel); for (y=0; y < (long) image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=0; x < (long) image->columns; x++) { SetMagickPixelPacket(image,q,indexes+x,&pixel); if (IsMagickColorSimilar(&pixel,target) != MagickFalse) q->opacity=opacity; q++; } if (SyncImagePixels(image) == MagickFalse) break; if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(PaintTransparentImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P a i n t F l o o d f i l l I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PaintFloodfill() changes the color value of any pixel that matches % target and is an immediate neighbor. If the method FillToBorderMethod is % specified, the color value is changed for any neighbor pixel that does not % match the bordercolor member of image. % % By default target must match a particular pixel color exactly. % However, in many cases two colors may differ by a small amount. The % fuzz member of image defines how much tolerance is acceptable to % consider two colors as the same. For example, set fuzz to 10 and the % color red at intensities of 100 and 102 respectively are now % interpreted as the same color for the purposes of the floodfill. % % The format of the PaintFloodfillImage method is: % % MagickBooleanType PaintFloodfillImage(Image *image, % const ChannelType channel,const MagickPixelPacket target, % const long x_offset,const long y_offset,const DrawInfo *draw_info, % const PaintMethod method) % % A description of each parameter follows: % % o image: The image. % % o channel: The channel(s). % % o target: The RGB value of the target color. % % o x_offset,y_offset: The starting location of the operation. % % o draw_info: The draw info. % % o method: Choose either FloodfillMethod or FillToBorderMethod. % */ MagickExport MagickBooleanType PaintFloodfillImage(Image *image, const ChannelType channel,const MagickPixelPacket *target, const long x_offset,const long y_offset,const DrawInfo *draw_info, const PaintMethod method) { #define MaxStacksize (1UL << 15) #define PushSegmentStack(up,left,right,delta) \ { \ if (s >= (segment_stack+MaxStacksize)) \ ThrowBinaryException(DrawError,"SegmentStackOverflow",image->filename) \ else \ { \ if ((((up)+(delta)) >= 0) && (((up)+(delta)) < (long) image->rows)) \ { \ s->x1=(double) (left); \ s->y1=(double) (up); \ s->x2=(double) (right); \ s->y2=(double) (delta); \ s++; \ } \ } \ } Image *floodplane_image; long offset, start, x1, x2, y; MagickBooleanType skip; MagickPixelPacket fill, pixel; PixelPacket fill_color; register const PixelPacket *p; register IndexPacket *indexes; register long x; register PixelPacket *q; register SegmentInfo *s; SegmentInfo *segment_stack; /* Check boundary conditions. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(draw_info != (DrawInfo *) NULL); assert(draw_info->signature == MagickSignature); if ((x_offset < 0) || (x_offset >= (long) image->columns)) return(MagickFalse); if ((y_offset < 0) || (y_offset >= (long) image->rows)) return(MagickFalse); if (SetImageStorageClass(image,DirectClass) == MagickFalse) return(MagickFalse); if (image->matte == MagickFalse) (void) SetImageOpacity(image,OpaqueOpacity); /* Set floodfill state. */ floodplane_image=CloneImage(image,image->columns,image->rows,MagickTrue, &image->exception); if (floodplane_image == (Image *) NULL) return(MagickFalse); (void) SetImageOpacity(floodplane_image,OpaqueOpacity); segment_stack=(SegmentInfo *) AcquireQuantumMemory(MaxStacksize, sizeof(*segment_stack)); if (segment_stack == (SegmentInfo *) NULL) { floodplane_image=DestroyImage(floodplane_image); ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", image->filename); } /* Push initial segment on stack. */ x=x_offset; y=y_offset; start=0; s=segment_stack; PushSegmentStack(y,x,x,1); PushSegmentStack(y+1,x,x,-1); GetMagickPixelPacket(image,&fill); GetMagickPixelPacket(image,&pixel); while (s > segment_stack) { /* Pop segment off stack. */ s--; x1=(long) s->x1; x2=(long) s->x2; offset=(long) s->y2; y=(long) s->y1+offset; /* Recolor neighboring pixels. */ p=AcquireImagePixels(image,0,y,(unsigned long) (x1+1),1,&image->exception); q=GetImagePixels(floodplane_image,0,y,(unsigned long) (x1+1),1); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetIndexes(image); p+=x1; q+=x1; for (x=x1; x >= 0; x--) { if (q->opacity == (Quantum) TransparentOpacity) break; SetMagickPixelPacket(image,p,indexes+x,&pixel); if (method == FloodfillMethod) { if (IsMagickColorSimilar(&pixel,target) == MagickFalse) break; } else if (IsMagickColorSimilar(&pixel,target) != MagickFalse) break; q->opacity=(Quantum) TransparentOpacity; p--; q--; } if (SyncImagePixels(floodplane_image) == MagickFalse) break; skip=x >= x1 ? MagickTrue : MagickFalse; if (skip == MagickFalse) { start=x+1; if (start < x1) PushSegmentStack(y,start,x1-1,-offset); x=x1+1; } do { if (skip == MagickFalse) { if (x < (long) image->columns) { p=AcquireImagePixels(image,x,y,image->columns-x,1, &image->exception); q=GetImagePixels(floodplane_image,x,y,image->columns-x,1); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetIndexes(image); for ( ; x < (long) image->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) break; SetMagickPixelPacket(image,p,indexes+x,&pixel); if (method == FloodfillMethod) { if (IsMagickColorSimilar(&pixel,target) == MagickFalse) break; } else if (IsMagickColorSimilar(&pixel,target) != MagickFalse) break; q->opacity=(Quantum) TransparentOpacity; p++; q++; } if (SyncImagePixels(floodplane_image) == MagickFalse) break; } PushSegmentStack(y,start,x-1,offset); if (x > (x2+1)) PushSegmentStack(y,x2+1,x-1,-offset); } skip=MagickFalse; x++; if (x <= x2) { p=AcquireImagePixels(image,x,y,(unsigned long) (x2-x+1),1, &image->exception); q=GetImagePixels(floodplane_image,x,y,(unsigned long) (x2-x+1),1); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetIndexes(image); for ( ; x <= x2; x++) { if (q->opacity == (Quantum) TransparentOpacity) break; SetMagickPixelPacket(image,p,indexes+x,&pixel); if (method == FloodfillMethod) { if (IsMagickColorSimilar(&pixel,target) != MagickFalse) break; } else if (IsMagickColorSimilar(&pixel,target) == MagickFalse) break; p++; q++; } } start=x; } while (x <= x2); } for (y=0; y < (long) image->rows; y++) { /* Tile fill color onto floodplane. */ p=AcquireImagePixels(floodplane_image,0,y,image->columns,1, &image->exception); q=GetImagePixels(image,0,y,image->columns,1); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetIndexes(image); for (x=0; x < (long) image->columns; x++) { if (p->opacity != OpaqueOpacity) { fill_color=GetFillColor(draw_info,x,y); SetMagickPixelPacket(image,&fill_color,(IndexPacket *) NULL,&fill); if (image->colorspace == CMYKColorspace) ConvertRGBToCMYK(&fill); if ((channel & RedChannel) != 0) q->red=RoundToQuantum(fill.red); if ((channel & GreenChannel) != 0) q->green=RoundToQuantum(fill.green); if ((channel & BlueChannel) != 0) q->blue=RoundToQuantum(fill.blue); if ((channel & OpacityChannel) != 0) q->opacity=RoundToQuantum(fill.opacity); if (((channel & IndexChannel) != 0) && (image->colorspace == CMYKColorspace)) indexes[x]=RoundToQuantum(fill.index); } p++; q++; } if (SyncImagePixels(image) == MagickFalse) break; } segment_stack=(SegmentInfo *) RelinquishMagickMemory(segment_stack); floodplane_image=DestroyImage(floodplane_image); return(y == (long) image->rows ? MagickTrue : MagickFalse); }