/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e V I C A R I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteVICARImage writes an image in the VICAR rasterfile format. % Vicar files contain a text header, followed by one or more planes of binary % grayscale image data. Vicar files are designed to allow many planes to be % stacked together to form image cubes. This method only writes a single % grayscale plane. % % Method WriteVICARImage was written contributed by % [email protected]. % % The format of the WriteVICARImage method is: % % unsigned int WriteVICARImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteVICARImage 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 WriteVICARImage(const ImageInfo *image_info,Image *image) { char header[MaxTextExtent]; int y; unsigned char *scanline; unsigned int status; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); (void) TransformColorspace(image,RGBColorspace); /* Write header. */ (void) memset(header,' ',MaxTextExtent); FormatString(header,"LBLSIZE=%u FORMAT='BYTE' TYPE='IMAGE' BUFSIZE=20000 " "DIM=2 EOL=0 RECSIZE=%lu ORG='BSQ' NL=%lu NS=%lu NB=1 N1=0 N2=0 N3=0 N4=0 " "NBB=0 NLB=0 TASK='GraphicsMagick'",MaxTextExtent,image->columns,image->rows, image->columns); (void) WriteBlob(image,MaxTextExtent,header); /* Allocate memory for scanline. */ scanline=MagickAllocateMemory(unsigned char *,image->columns); if (scanline == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); /* Write VICAR scanline. */ for (y=0; y < (long) image->rows; y++) { if (!AcquireImagePixels(image,0,y,image->columns,1,&image->exception)) break; (void) ExportImagePixelArea(image,GrayQuantum,8,scanline,0,0); (void) WriteBlob(image,image->columns,scanline); 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; } MagickFreeMemory(scanline); CloseBlob(image); return(True); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e M A T T E I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function WriteMATTEImage writes an image of matte bytes to a file. It % consists of data from the matte component of the image [0..255]. % % The format of the WriteMATTEImage method is: % % unsigned int WriteMATTEImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Function WriteMATTEImage 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 WriteMATTEImage(const ImageInfo *image_info,Image *image) { Image *matte_image; long y; register const PixelPacket *p; register long x; register PixelPacket *q; unsigned int status; if (!image->matte) ThrowWriterException(CoderError,ImageDoesNotHaveAMatteChannel,image); matte_image= CloneImage(image,image->columns,image->rows,True,&image->exception); if (matte_image == (Image *) NULL) return(False); (void) (void) SetImageType(matte_image,TrueColorType); /* Convert image to matte pixels. */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); q=SetImagePixels(matte_image,0,y,matte_image->columns,1); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (long) image->columns; x++) { q->red=p->opacity; q->green=p->opacity; q->blue=p->opacity; q->opacity=OpaqueOpacity; p++; q++; } if (!SyncImagePixels(matte_image)) break; 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; } (void) FormatString(matte_image->filename,"MIFF:%.1024s",image->filename); status=WriteImage(image_info,matte_image); DestroyImage(matte_image); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e A R T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function WriteARTImage writes an ART image to a file. % % The format of the WriteARTImage method is: % % unsigned int WriteARTImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Function WriteARTImage 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 WriteARTImage(const ImageInfo *image_info,Image *image) { long y; unsigned dummy = 0; long DataSize; const PixelPacket *q; unsigned int status; unsigned char Padding; int logging; unsigned char *pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ART"); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); DataSize = (long)((image->columns+7) / 8); Padding = (unsigned char)((-DataSize) & 0x01); pixels=MagickAllocateMemory(unsigned char *,(size_t) (DataSize)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); /* Write ART hader. */ (void) WriteBlobLSBShort(image,0); (void) WriteBlobLSBShort(image,image->columns); (void) WriteBlobLSBShort(image,0); (void) WriteBlobLSBShort(image,image->rows); /* Store image data. */ for(y=0; y<(long)image->rows; y++) { q = AcquireImagePixels(image,0,y,image->columns,1,&image->exception); (void)ExportImagePixelArea(image,GrayQuantum,1,pixels,0,0); (void)WriteBlob(image,DataSize,pixels); (void)WriteBlob(image,Padding,(char *)&dummy); } status=True; CloseBlob(image); MagickFreeMemory(pixels); if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return ART"); return(status); }
ARUint8* loadImage(char* filename, int* xsize, int* ysize) { ARUint8 *dptr; Image *image; MagickWand* magick_wand; magick_wand=NewMagickWand(); if( magick_wand == NULL) { fprintf(stderr, "bad magickwand\n"); } MagickBooleanType status=MagickReadImage(magick_wand,filename); if (status == MagickFalse) { //fprintf(stderr, "%s can't be read\n", filename); //exit(1); //return; //(1); ThrowWandException(magick_wand); } image = GetImageFromMagickWand(magick_wand); //ContrastImage(image,MagickTrue); //EnhanceImage(image,&image->exception); int index; *xsize = image->columns; *ysize = image->rows; dptr = malloc(sizeof(ARUint8) * 3 * image->rows * *xsize); int y; index = 0; for (y=0; y < (long) image->rows; y++) { const PixelPacket *p = AcquireImagePixels(image,0,y,*xsize,1,&image->exception); if (p == (const PixelPacket *) NULL) break; int x; for (x=0; x < (long) *xsize; x++) { /// convert to ARUint8 dptr /// probably a faster way to give the data straight over /// in BGR format dptr[index*3+2] = p->red/256; dptr[index*3+1] = p->green/256; dptr[index*3] = p->blue/256; //fprintf(stderr,"%d, %d, %d\t%d\t%d\n", x, y, p->red/256, p->green/256, p->blue/256); p++; index++; } } DestroyMagickWand(magick_wand); return dptr; }
bool ScImgDataLoader_GMagick::readCMYK(Image *input, RawImage *output, int width, int height) { /* Mapping: red: cyan green: magenta blue: yellow opacity: black index: alpha */ //Copied from GraphicsMagick header and modified #define GetCyanSample(p) (p.red) #define GetMagentaSample(p) (p.green) #define GetYellowSample(p) (p.blue) #define GetCMYKBlackSample(p) (p.opacity) #define GetAlphaSample(p) (p) bool hasAlpha = input->matte; if (!output->create(width, height, hasAlpha ? 5 : 4)) return false; ExceptionInfo exception; GetExceptionInfo(&exception); const PixelPacket *pixels = AcquireImagePixels(input, 0, 0, width, height, &exception); if (exception.severity != UndefinedException) CatchException(&exception); if (!pixels) { qCritical() << QObject::tr("Could not get pixel data!"); return false; } const IndexPacket *alpha = 0; if (hasAlpha) { alpha = AccessImmutableIndexes(input); if (!alpha) { qCritical() << QObject::tr("Could not get alpha channel data!"); return false; } } unsigned char *buffer = output->bits(); if (!buffer) { qCritical() << QObject::tr("Could not allocate output buffer!"); return false; } int i; for (i = 0; i < width*height; i++) { *buffer++ = ScaleQuantumToChar(GetCyanSample(pixels[i])); *buffer++ = ScaleQuantumToChar(GetMagentaSample(pixels[i])); *buffer++ = ScaleQuantumToChar(GetYellowSample(pixels[i])); *buffer++ = ScaleQuantumToChar(GetCMYKBlackSample(pixels[i])); if (hasAlpha) { *buffer++ = 255 - ScaleQuantumToChar(GetAlphaSample(alpha[i])); } } return true; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t I m a g e T o t a l I n k D e n s i t y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetImageTotalInkDensity() returns the toal ink density for a CMYK image. % Total nk Density (TID) is determined by adding the CMYK values in the % darkest shadow area in an image. % % The format of the GetImageTotalInkDensity method is: % % double GetImageTotalInkDensity(const Image *image) % % A description of each parameter follows: % % o image: The image. % */ MagickExport double GetImageTotalInkDensity(Image *image) { double density, total_ink_density; long y; register const PixelPacket *p; register IndexPacket *indexes; register long x; assert(image != (Image *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(image->signature == MagickSignature); if (image->colorspace != CMYKColorspace) { (void) ThrowMagickException(&image->exception,GetMagickModule(), ImageError,"ColorSeparatedImageRequired","`%s'",image->filename); return(0.0); } total_ink_density=0.0; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=0; x < (long) image->columns; x++) { density=(double) p->red+p->green+p->blue+indexes[x]; if (density > total_ink_density) total_ink_density=density; p++; } } return(total_ink_density); }
bool ScImgDataLoader_GMagick::readRGB(Image *input, QImage *output, int width, int height) { bool hasAlpha = input->matte; ExceptionInfo exception; GetExceptionInfo(&exception); const PixelPacket *pixels = AcquireImagePixels(input, 0, 0, width, height, &exception); if (exception.severity != UndefinedException) CatchException(&exception); if (!pixels) { qCritical() << QObject::tr("Could not get pixel data!"); return false; } unsigned char *buffer = output->bits(); if (!buffer) { qCritical() << QObject::tr("Could not allocate output buffer!"); return false; } QRgb *s = (QRgb*)(output->scanLine(0)); int i; for (i = 0; i < width*height; i++) { unsigned char b = ScaleQuantumToChar(pixels[i].blue); unsigned char g = ScaleQuantumToChar(pixels[i].green); unsigned char r = ScaleQuantumToChar(pixels[i].red); unsigned char a; if (hasAlpha) a = 255 - ScaleQuantumToChar(pixels[i].opacity); else a = 255; *s = qRgba(r, g, b, a); s++; } return true; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e V I C A R I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteVICARImage() writes an image in the VICAR rasterfile format. % Vicar files contain a text header, followed by one or more planes of binary % grayscale image data. Vicar files are designed to allow many planes to be % stacked together to form image cubes. This method only writes a single % grayscale plane. % % WriteVICARImage was written contributed by % [email protected]. % % The format of the WriteVICARImage method is: % % MagickBooleanType WriteVICARImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % */ static MagickBooleanType WriteVICARImage(const ImageInfo *image_info, Image *image) { char header[MaxTextExtent]; int y; MagickBooleanType status; QuantumInfo quantum_info; register const PixelPacket *p; unsigned char *scanline; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); /* Write header. */ (void) ResetMagickMemory(header,' ',MaxTextExtent); (void) FormatMagickString(header,MaxTextExtent, "LBLSIZE=%lu FORMAT='BYTE' TYPE='IMAGE' BUFSIZE=20000 DIM=2 EOL=0 " "RECSIZE=%lu ORG='BSQ' NL=%lu NS=%lu NB=1 N1=0 N2=0 N3=0 N4=0 NBB=0 " "NLB=0 TASK='ImageMagick'",(unsigned long) MaxTextExtent,image->columns, image->rows,image->columns); (void) WriteBlob(image,MaxTextExtent,(unsigned char *) header); /* Allocate memory for scanline. */ scanline=(unsigned char *) AcquireQuantumMemory(image->columns, sizeof(*scanline)); if (scanline == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Write VICAR scanline. */ GetQuantumInfo(image_info,&quantum_info); image->depth=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,GrayQuantum,scanline); (void) WriteBlob(image,image->columns,scanline); 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; } } scanline=(unsigned char *) RelinquishMagickMemory(scanline); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + I n t e g r a l R o t a t e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % IntegralRotateImage() rotates the image an integral of 90 degrees. It % allocates the memory necessary for the new Image structure and returns a % pointer to the rotated image. % % The format of the IntegralRotateImage method is: % % Image *IntegralRotateImage(const Image *image,unsigned long rotations, % ExceptionInfo *exception) % % A description of each parameter follows. % % o image: the image. % % o rotations: Specifies the number of 90 degree rotations. % % */ static Image *IntegralRotateImage(const Image *image,unsigned long rotations, ExceptionInfo *exception) { #define TileHeight 128 #define TileWidth 128 #define RotateImageTag "Rotate/Image" Image *rotate_image; long tile_x, tile_y, y; MagickBooleanType status; MagickPixelPacket pixel; RectangleInfo page; register IndexPacket *indexes, *rotate_indexes; register const PixelPacket *p, *tile_pixels; register long x; register PixelPacket *q; unsigned long tile_width, tile_height; /* Initialize rotated image attributes. */ assert(image != (Image *) NULL); page=image->page; rotations%=4; if ((rotations == 1) || (rotations == 3)) rotate_image=CloneImage(image,image->rows,image->columns,MagickTrue, exception); else rotate_image=CloneImage(image,image->columns,image->rows,MagickTrue, exception); if (rotate_image == (Image *) NULL) return((Image *) NULL); /* Integral rotate the image. */ GetMagickPixelPacket(image,&pixel); switch (rotations) { case 0: { /* Rotate 0 degrees. */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,exception); q=SetImagePixels(rotate_image,0,y,rotate_image->columns,1); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetIndexes(image); rotate_indexes=GetIndexes(rotate_image); for (x=0; x < (long) image->columns; x++) { SetMagickPixelPacket(image,p,indexes+x,&pixel); SetPixelPacket(rotate_image,&pixel,q,rotate_indexes+x); p++; q++; } if (SyncImagePixels(rotate_image) == MagickFalse) break; if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(RotateImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } break; } case 1: { /* Rotate 90 degrees. */ for (tile_y=0; tile_y < (long) image->rows; tile_y+=TileHeight) { for (tile_x=0; tile_x < (long) image->columns; tile_x+=TileWidth) { tile_width=TileWidth; if ((tile_x+TileWidth) > (long) image->columns) tile_width=1UL*(TileWidth-(tile_x+TileWidth-image->columns)); tile_height=TileHeight; if ((tile_y+TileHeight) > (long) image->rows) tile_height=1UL*(TileHeight-(tile_y+TileHeight-image->rows)); tile_pixels=AcquireImagePixels(image,tile_x,tile_y,tile_width, tile_height,exception); if (tile_pixels == (const PixelPacket *) NULL) break; for (y=0; y < (long) tile_width; y++) { q=SetImagePixels(rotate_image,(long) rotate_image->columns-(tile_y+ tile_height),tile_x+y,tile_height,1); if (q == (PixelPacket *) NULL) break; rotate_indexes=GetIndexes(rotate_image); p=tile_pixels+(tile_height-1)*tile_width+y; indexes=GetIndexes(image)+(tile_height-1)*tile_width+y; for (x=0; x < (long) tile_height; x++) { SetMagickPixelPacket(image,p,indexes,&pixel); SetPixelPacket(rotate_image,&pixel,q,rotate_indexes+x); p-=tile_width; indexes-=tile_width; q++; } if (SyncImagePixels(rotate_image) == MagickFalse) break; } } if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(tile_y,image->rows) != MagickFalse)) { status=image->progress_monitor(RotateImageTag,tile_y,image->rows, image->client_data); if (status == MagickFalse) break; } } Swap(page.width,page.height); Swap(page.x,page.y); if (page.width != 0) page.x=(long) (page.width-rotate_image->columns-page.x); break; } case 2: { /* Rotate 180 degrees. */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,exception); q=SetImagePixels(rotate_image,0,(long) (image->rows-y-1), image->columns,1); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; q+=image->columns; indexes=GetIndexes(image); rotate_indexes=GetIndexes(rotate_image); for (x=0; x < (long) image->columns; x++) { q--; SetMagickPixelPacket(image,p,indexes+x,&pixel); SetPixelPacket(rotate_image,&pixel,q,rotate_indexes+(image->columns- x-1)); p++; } if (SyncImagePixels(rotate_image) == MagickFalse) break; if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(RotateImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } if (page.width != 0) page.x=(long) (page.width-rotate_image->columns-page.x); if (page.height != 0) page.y=(long) (page.height-rotate_image->rows-page.y); break; } case 3: { /* Rotate 270 degrees. */ for (tile_y=0; tile_y < (long) image->rows; tile_y+=TileHeight) { for (tile_x=0; tile_x < (long) image->columns; tile_x+=TileWidth) { tile_width=TileWidth; if ((tile_x+TileWidth) > (long) image->columns) tile_width=1UL*(TileWidth-(tile_x+TileWidth-image->columns)); tile_height=TileHeight; if ((tile_y+TileHeight) > (long) image->rows) tile_height=1UL*(TileHeight-(tile_y+TileHeight-image->rows)); tile_pixels=AcquireImagePixels(image,tile_x,tile_y,tile_width, tile_height,exception); if (tile_pixels == (const PixelPacket *) NULL) break; for (y=0; y < (long) tile_width; y++) { q=SetImagePixels(rotate_image,tile_y,(long) rotate_image->rows- (tile_x+tile_width)+y,tile_height,1); if (q == (PixelPacket *) NULL) break; rotate_indexes=GetIndexes(rotate_image); p=tile_pixels+(tile_width-1)-y; indexes=GetIndexes(image)+(tile_width-1)-y; for (x=0; x < (long) tile_height; x++) { SetMagickPixelPacket(image,p,indexes,&pixel); SetPixelPacket(rotate_image,&pixel,q,rotate_indexes+x); p+=tile_width; indexes+=tile_width; q++; } if (SyncImagePixels(rotate_image) == MagickFalse) break; } } if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(tile_y,image->rows) != MagickFalse)) { status=image->progress_monitor(RotateImageTag,tile_y,image->rows, image->client_data); if (status == MagickFalse) break; } } Swap(page.width,page.height); Swap(page.x,page.y); if (page.height != 0) page.y=(long) (page.height-rotate_image->rows-page.y); break; } } rotate_image->page=page; return(rotate_image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P i x e l I t e r a t e T r i p l e M o d i f y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PixelIterateTripleModify() iterates through pixel regions of three images % and invokes a user-provided callback function (of type % PixelIteratorTripleModifyCallback) for each row of pixels. The first two % images are read-only, while the third image is read-write for update. % Access of the first two images is done lock-step using the same coordinates. % This is useful to support operations such as image differencing. % % The format of the PixelIterateTripleModify method is: % % MagickPassFail PixelIterateTripleModify( % PixelIteratorTripleModifyCallback call_back, % const PixelIteratorOptions *options, % const char *description, % void *mutable_data, % const void *immutable_data, % const unsigned long columns, % const unsigned long rows, % const Image *source1_image, % const Image *source2_image, % const long source_x, % const long source_y, % Image *update_image, % const long update_x, % const long update_y, % ExceptionInfo *exception) % % A description of each parameter follows: % % o call_back: A user-provided C callback function which reads from % a region of source pixels and updates a region of destination pixels. % % o options: Pixel iterator execution options (may be NULL). % % o description: textual description of operation being performed. % % o mutable_data: User-provided mutable context data. % % o immutable_data: User-provided immutable context data. % % o columns: Width of pixel region % % o rows: Height of pixel region % % o source1_image: The address of the constant source 1 Image. % % o source2_image: The address of the constant source 2 Image. % % o source_x: The horizontal ordinate of the top left corner of the source regions. % % o source_y: The vertical ordinate of the top left corner of the source regions. % % o update_image: The address of the update Image. % % o update_x: The horizontal ordinate of the top left corner of the update region. % % o update_y: The vertical ordinate of the top left corner of the update region. % % o exception: If an error is reported, this argument is updated with the reason. % */ static MagickPassFail PixelIterateTripleImplementation(PixelIteratorTripleModifyCallback call_back, const PixelIteratorOptions *options, const char *description, void *mutable_data, const void *immutable_data, const unsigned long columns, const unsigned long rows, const Image *source1_image, const Image *source2_image, const long source_x, const long source_y, Image *update_image, const long update_x, const long update_y, ExceptionInfo *exception, MagickBool set) { MagickPassFail status = MagickPass; register long row; unsigned long row_count=0; int max_threads; max_threads=omp_get_max_threads(); (void) SetRegionThreads(max_threads,options,columns,rows); #if defined(HAVE_OPENMP) # pragma omp parallel for schedule(static,1) shared(row_count, status) #endif for (row=0; row < (long) rows; row++) { MagickBool thread_status; const PixelPacket *source1_pixels, *source2_pixels; const IndexPacket *source1_indexes, *source2_indexes; PixelPacket *update_pixels; IndexPacket *update_indexes; long source_row, update_row; thread_status=status; if (thread_status == MagickFail) continue; source_row=source_y+row; update_row=update_y+row; /* First image (read only). */ source1_pixels=AcquireImagePixels(source1_image, source_x, source_row, columns, 1, exception); if (!source1_pixels) thread_status=MagickFail; source1_indexes=AccessImmutableIndexes(source1_image); /* Second image (read only). */ source2_pixels=AcquireImagePixels(source2_image, source_x, source_row, columns, 1, exception); if (!source2_pixels) thread_status=MagickFail; source2_indexes=AccessImmutableIndexes(source2_image); /* Third image (read/write). */ if (set) update_pixels=SetImagePixelsEx(update_image, update_x, update_row, columns, 1, exception); else update_pixels=GetImagePixelsEx(update_image, update_x, update_row, columns, 1, exception); if (!update_pixels) { thread_status=MagickFail; CopyException(exception,&update_image->exception); } update_indexes=AccessMutableIndexes(update_image); if (thread_status != MagickFail) status=(call_back)(mutable_data,immutable_data, source1_image,source1_pixels,source1_indexes, source2_image,source2_pixels,source2_indexes, update_image,update_pixels,update_indexes, columns,exception); if (!SyncImagePixelsEx(update_image,exception)) thread_status=MagickFail; #if defined(HAVE_OPENMP) # pragma omp critical (GM_PixelIterateTripleImplementation) #endif { row_count++; if (QuantumTick(row_count,rows)) if (!MagickMonitorFormatted(row_count,rows,exception,description, source1_image->filename, source2_image->filename, update_image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } omp_set_num_threads(max_threads); return (status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P i x e l I t e r a t e D u a l R e a d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PixelIterateDualRead() iterates through pixel regions of two images and % invokes a user-provided callback function (of type % PixelIteratorDualReadCallback) for each row of pixels. This is useful to % support operations such as image comparison. % % The format of the PixelIterateDualModify method is: % % MagickPassFail PixelIterateDualRead( % PixelIteratorDualReadCallback call_back, % const PixelIteratorOptions *options, % const char *description, % void *mutable_data, % const void *immutable_data, % const unsigned long columns, % const unsigned long rows, % const Image *first_image, % const long first_x, % const long first_y, % const Image *second_image, % const long second_x, % const long second_y, % ExceptionInfo *exception); % % A description of each parameter follows: % % o call_back: A user-provided C callback function which is passed the % address of pixels from each image. % % o options: Pixel iterator execution options (may be NULL). % % o description: textual description of operation being performed. % % o mutable_data: User-provided mutable context data. % % o immutable_data: User-provided immutable context data. % % o columns: Width of pixel region % % o rows: Height of pixel region % % o first_image: The address of the first Image. % % o first_x: The horizontal ordinate of the top left corner of the first region. % % o first_y: The vertical ordinate of the top left corner of the first region. % % o second_image: The address of the second Image. % % o second_x: The horizontal ordinate of the top left corner of the second region. % % o second_y: The vertical ordinate of the top left corner of the second region. % % o exception: If an error is reported, this argument is updated with the reason. % */ MagickExport MagickPassFail PixelIterateDualRead(PixelIteratorDualReadCallback call_back, const PixelIteratorOptions *options, const char *description, void *mutable_data, const void *immutable_data, const unsigned long columns, const unsigned long rows, const Image *first_image, const long first_x, const long first_y, const Image *second_image, const long second_x, const long second_y, ExceptionInfo *exception) { MagickPassFail status = MagickPass; register long row; unsigned long row_count=0; int max_threads; max_threads=omp_get_max_threads(); (void) SetRegionThreads(max_threads,options,columns,rows); #if defined(HAVE_OPENMP) # pragma omp parallel for schedule(static,1) shared(row_count, status) #endif for (row=0; row < (long) rows; row++) { MagickBool thread_status; long first_row, second_row; const PixelPacket *first_pixels, *second_pixels; const IndexPacket *first_indexes, *second_indexes; thread_status=status; if (thread_status == MagickFail) continue; first_row=first_y+row; second_row=second_y+row; first_pixels=AcquireImagePixels(first_image, first_x, first_row, columns, 1, exception); if (!first_pixels) thread_status=MagickFail; first_indexes=AccessImmutableIndexes(first_image); second_pixels=AcquireImagePixels(second_image, second_x, second_row, columns, 1, exception); if (!second_pixels) thread_status=MagickFail; second_indexes=AccessImmutableIndexes(second_image); if (thread_status != MagickFail) thread_status=(call_back)(mutable_data,immutable_data, first_image,first_pixels,first_indexes, second_image,second_pixels,second_indexes, columns, exception); #if defined(HAVE_OPENMP) # pragma omp critical (GM_PixelIterateDualRead) #endif { row_count++; if (QuantumTick(row_count,rows)) if (!MagickMonitorFormatted(row_count,rows,exception, description,first_image->filename, second_image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } omp_set_num_threads(max_threads); return (status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P i x e l I t e r a t e M o n o R e a d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % PixelIterateMonoRead() iterates through a region of an image and invokes a % user-provided callback function (of type PixelRowIteratorMonoReadCallback) % for a row of pixels. This is useful to support simple operations such as % statistics computation. % % The format of the PixelIterateMonoRead method is: % % MagickPassFail PixelIterateMonoRead( % PixelIteratorMonoReadCallback call_back, % const PixelIteratorOptions *options, % const char *description, % void *mutable_data, % const void *immutable_data, % const long x, % const long y, % const unsigned long columns, % const unsigned long rows, % const Image *image, % ExceptionInfo *exception) % % A description of each parameter follows: % % o call_back: A user-provided C callback function which is passed the % address of pixels from each image. % % o options: Pixel iterator execution options (may be NULL). % % o description: textual description of operation being performed. % % o mutable_data: User-provided mutable context data. % % o immutable_data: User-provided immutable context data. % % o x: The horizontal ordinate of the top left corner of the region. % % o y: The vertical ordinate of the top left corner of the region. % % o columns: Width of pixel region % % o rows: Height of pixel region % % o image: The address of the Image. % % o exception: If an error is reported, this argument is updated with the reason. % */ MagickExport MagickPassFail PixelIterateMonoRead(PixelIteratorMonoReadCallback call_back, const PixelIteratorOptions *options, const char *description, void *mutable_data, const void *immutable_data, const long x, const long y, const unsigned long columns, const unsigned long rows, const Image *image, ExceptionInfo *exception) { MagickPassFail status = MagickPass; register long row; unsigned long row_count=0; int max_threads=1; max_threads=omp_get_max_threads(); (void) SetRegionThreads(max_threads,options,columns,rows); #if defined(HAVE_OPENMP) # pragma omp parallel for schedule(static,1) shared(row_count, status) #endif for (row=y; row < (long) (y+rows); row++) { MagickPassFail thread_status; const PixelPacket *pixels; const IndexPacket *indexes; thread_status=status; if (thread_status == MagickFail) continue; pixels=AcquireImagePixels(image,x, row, columns, 1, exception); if (!pixels) thread_status=MagickFail; indexes=AccessImmutableIndexes(image); if (thread_status != MagickFail) thread_status=(call_back)(mutable_data,immutable_data,image,pixels,indexes,columns,exception); #if defined(HAVE_OPENMP) # pragma omp critical (GM_PixelIterateMonoRead) #endif { row_count++; if (QuantumTick(row_count,rows)) if (!MagickMonitorFormatted(row_count,rows,exception, description,image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } omp_set_num_threads(max_threads); return (status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e O T B I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteOTBImage() writes an image to a file in the On-the-air Bitmap % (level 0) image format. % % The format of the WriteOTBImage method is: % % MagickBooleanType WriteOTBImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % % */ static MagickBooleanType WriteOTBImage(const ImageInfo *image_info,Image *image) { #define SetBit(a,i,set) \ a=(unsigned char) ((set) ? (a) | (1L << (i)) : (a) & ~(1L << (i))) long y; MagickBooleanType status; register const PixelPacket *p; register IndexPacket *indexes; register long x; unsigned char bit, byte, info; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); /* Convert image to a bi-level image. */ (void) SetImageType(image,BilevelType); info=0; if ((image->columns >= 256) || (image->rows >= 256)) SetBit(info,4,1); (void) WriteBlobByte(image,info); if ((image->columns >= 256) || (image->rows >= 256)) { (void) WriteBlobMSBShort(image,(unsigned short) image->columns); (void) WriteBlobMSBShort(image,(unsigned short) image->rows); } else { (void) WriteBlobByte(image,(unsigned char) image->columns); (void) WriteBlobByte(image,(unsigned char) image->rows); } (void) WriteBlobByte(image,1); /* depth */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); bit=0; byte=0; for (x=0; x < (long) image->columns; x++) { if (PixelIntensity(p) < ((Quantum) QuantumRange/2.0)) byte|=0x1 << (7-bit); bit++; if (bit == 8) { (void) WriteBlobByte(image,byte); bit=0; byte=0; } } if (bit != 0) (void) WriteBlobByte(image,byte); 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; } } CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e G R A Y I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteGRAYImage() writes an image to a file as gray scale intensity % values. % % The format of the WriteGRAYImage method is: % % MagickBooleanType WriteGRAYImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % */ static MagickBooleanType WriteGRAYImage(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; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); /* Convert image to gray scale PseudoColor class. */ scene=0; do { /* Allocate memory for pixels. */ GetQuantumInfo(image_info,&quantum_info); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); packet_size=(size_t) (image->depth+7)/8; pixels=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size* sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert MIFF to GRAY raster pixels. */ 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,GrayQuantum,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; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); 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); CloseBlob(image); return(MagickTrue); }
CAMLprim value magick_loader(value input) { CAMLparam1(input); CAMLlocal2(pixel_matrix, res); Image *image_bloc; int image_type_code; int components; GLenum format; ExceptionInfo exception; GetExceptionInfo(&exception); { if (IsMagickInstantiated() == MagickFalse) { InitializeMagick(getenv("PWD")); } { ImageInfo *image_info; image_info = CloneImageInfo((ImageInfo *) NULL); switch (Tag_val(input)) { /* given a filename of an image */ case 0: (void) strcpy(image_info->filename, String_val(Field(input,0))); image_bloc = ReadImage(image_info, &exception); break; /* given the image data in a buffer */ case 1: image_bloc = BlobToImage( image_info, (void *)String_val(Field(input,0)), caml_string_length(Field(input,0)), &exception); break; } DestroyImageInfo(image_info); } if (exception.severity != UndefinedException) { if (image_bloc != (Image *) NULL) { DestroyImage(image_bloc); } DestroyExceptionInfo(&exception); caml_failwith( exception.reason ); /* @TODO exception.description */ } if (image_bloc == (Image *) NULL) { DestroyExceptionInfo(&exception); caml_failwith("read image failed"); } } { ImageType image_type; image_type = GetImageType( image_bloc, &exception ); if (exception.severity != UndefinedException) caml_failwith( exception.reason ); image_type_code = Val_ImageType(image_type, &components); if ( image_type_code == 11 ) caml_failwith("getting image type failed"); } { unsigned long x, y; unsigned long columns, rows; PixelPacket pixel; columns = image_bloc->columns; rows = image_bloc->rows; const PixelPacket * pixel_packet_array; pixel_packet_array = AcquireImagePixels( image_bloc, 0, 0, columns, rows, &exception ); if (exception.severity != UndefinedException) { caml_failwith(exception.reason); } { unsigned char *image; long ndx; long dims[3]; dims[0] = columns; dims[1] = rows; dims[2] = components; pixel_matrix = alloc_bigarray(BIGARRAY_UINT8 | BIGARRAY_C_LAYOUT, 3, NULL, dims); image = Data_bigarray_val(pixel_matrix); for (x=0; x < columns; ++x) { for (y=0; y < rows; ++y) { pixel = pixel_packet_array[(columns * y) + x]; ndx = (columns * y * components) + (x * components); switch (components) { case 1: image[ndx + 0] = pixel.red / SCALE; break; case 2: image[ndx + 0] = pixel.red / SCALE; image[ndx + 1] = ( MaxMap - pixel.opacity ) / SCALE; break; case 3: image[ndx + 0] = pixel.red / SCALE; image[ndx + 1] = pixel.green / SCALE; image[ndx + 2] = pixel.blue / SCALE; break; case 4: image[ndx + 0] = pixel.red / SCALE; image[ndx + 1] = pixel.green / SCALE; image[ndx + 2] = pixel.blue / SCALE; image[ndx + 3] = ( MaxMap - pixel.opacity ) / SCALE; break; } } } } switch (components) { case 1: format = GL_LUMINANCE; break; case 2: format = GL_LUMINANCE_ALPHA; break; case 3: format = GL_RGB; break; case 4: format = GL_RGBA; break; } res = alloc_tuple(5); Store_field(res, 0, pixel_matrix ); Store_field(res, 1, Val_long(columns) ); Store_field(res, 2, Val_long(rows) ); Store_field(res, 3, Val_internal_format(components) ); Store_field(res, 4, Val_pixel_data_format(format) ); } DestroyExceptionInfo(&exception); DestroyImage(image_bloc); CAMLreturn(res); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e J P 2 I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteJP2Image writes an image in the JPEG 2000 image format. % % JP2 support originally written by Nathan Brown, [email protected] % % The format of the WriteJP2Image method is: % % MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteJP2Image return MagickTrue if the image is written. % MagickFalse 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 MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image) { char magick[MaxTextExtent], option_keyval[MaxTextExtent], *options = NULL; int format; long y; jas_image_cmptparm_t component_info; jas_image_t *jp2_image; jas_matrix_t *jp2_pixels; jas_stream_t *jp2_stream; register const PixelPacket *p; register int x; unsigned int rate_specified=False, status; int component, number_components; unsigned short *lut; ImageCharacteristics characteristics; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); /* Ensure that image is in RGB space. */ (void) TransformColorspace(image,RGBColorspace); /* Analyze image to be written. */ if (!GetImageCharacteristics(image,&characteristics, (OptimizeType == image_info->type), &image->exception)) { CloseBlob(image); return MagickFail; } /* Obtain a JP2 stream. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowWriterException(DelegateError,UnableToManageJP2Stream,image); number_components=image->matte ? 4 : 3; if ((image_info->type != TrueColorType) && (characteristics.grayscale)) number_components=1; jp2_image=jas_image_create0(); if (jp2_image == (jas_image_t *) NULL) ThrowWriterException(DelegateError,UnableToCreateImage,image); for (component=0; component < number_components; component++) { (void) memset((void *)&component_info,0,sizeof(jas_image_cmptparm_t)); component_info.tlx=0; /* top left x ordinate */ component_info.tly=0; /* top left y ordinate */ component_info.hstep=1; /* horizontal pixels per step */ component_info.vstep=1; /* vertical pixels per step */ component_info.width=(unsigned int) image->columns; component_info.height=(unsigned int) image->rows; component_info.prec=(unsigned int) Max(2,Min(image->depth,16)); /* bits in range */ component_info.sgnd = false; /* range is signed value? */ if (jas_image_addcmpt(jp2_image, component,&component_info)) { jas_image_destroy(jp2_image); ThrowWriterException(DelegateError,UnableToCreateImageComponent,image); } } /* Allocate and compute LUT. */ { unsigned long i, max_value; double scale_to_component; lut=MagickAllocateArray(unsigned short *,MaxMap+1,sizeof(*lut)); if (lut == (unsigned short *) NULL) { jas_image_destroy(jp2_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); } max_value=MaxValueGivenBits(component_info.prec); scale_to_component=max_value/MaxRGBDouble; for(i=0; i <= MaxMap; i++) lut[i]=scale_to_component*i+0.5; } if (number_components == 1) { /* FIXME: If image has an attached ICC profile, then the profile should be transferred and the image colorspace set to JAS_CLRSPC_GENGRAY */ /* sRGB Grayscale */ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting SGRAY colorspace"); jas_image_setclrspc(jp2_image, JAS_CLRSPC_SGRAY); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting GRAY channel to channel 0"); jas_image_setcmpttype(jp2_image,0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); } else { /* FIXME: If image has an attached ICC profile, then the profile should be transferred and the image colorspace set to JAS_CLRSPC_GENRGB */ /* sRGB */ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting SRGB colorspace"); jas_image_setclrspc(jp2_image, JAS_CLRSPC_SRGB); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting RED channel to channel 0"); jas_image_setcmpttype(jp2_image,0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting GREEN channel to channel 1"); jas_image_setcmpttype(jp2_image,1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting BLUE channel to channel 2"); jas_image_setcmpttype(jp2_image,2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); if (number_components == 4 ) { (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting OPACITY channel to channel 3"); jas_image_setcmpttype(jp2_image,3, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY)); } } /* Convert to JPEG 2000 pixels. */ jp2_pixels=jas_matrix_create(1,(unsigned int) image->columns); if (jp2_pixels == (jas_matrix_t *) NULL) { MagickFreeMemory(lut); jas_image_destroy(jp2_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,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; if (number_components == 1) { for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(PixelIntensityToQuantum(&p[x]))]); (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); } else { for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].red)]); (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].green)]); (void) jas_image_writecmpt(jp2_image,1,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].blue)]); (void) jas_image_writecmpt(jp2_image,2,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); if (number_components > 3) for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(MaxRGB-p[x].opacity)]); (void) jas_image_writecmpt(jp2_image,3,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_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; } (void) strlcpy(magick,image_info->magick,MaxTextExtent); /* J2C is an alias for JPC but Jasper only supports "JPC". */ if (LocaleCompare(magick,"j2c") == 0) (void) strlcpy(magick,"jpc",sizeof(magick)); LocaleLower(magick); format=jas_image_strtofmt(magick); /* Support passing Jasper options. */ { const char **option_name; static const char *jasper_options[] = { "imgareatlx", "imgareatly", "tilegrdtlx", "tilegrdtly", "tilewidth", "tileheight", "prcwidth", "prcheight", "cblkwidth", "cblkheight", "mode", "ilyrrates", "prg", "nomct", "numrlvls", "sop", "eph", "lazy", "rate", "termall", "segsym", "vcausal", "pterm", "resetprob", "numgbits", NULL }; for (option_name = jasper_options; *option_name != NULL; option_name++) { const char *value; if ((value=AccessDefinition(image_info,"jp2",*option_name)) != NULL) { if(LocaleCompare(*option_name,"rate") == 0) rate_specified=True; FormatString(option_keyval,"%s=%.1024s ",*option_name,value); ConcatenateString(&options,option_keyval); } } } /* Provide an emulation of IJG JPEG "quality" by default. */ if (rate_specified == False) { double rate=1.0; /* A rough approximation to JPEG v1 quality using JPEG-2000. Default "quality" 75 results in a request for 16:1 compression, which results in image sizes approximating that of JPEG v1. */ if ((image_info->quality < 99.5) && (image->rows*image->columns > 2500)) { double header_size, current_size, target_size, d; d=115-image_info->quality; /* Best number is 110-115 */ rate=100.0/(d*d); header_size=550.0; /* Base file size. */ header_size+=(number_components-1)*142; /* Additional components */ /* FIXME: Need to account for any ICC profiles here */ current_size=(double)((image->rows*image->columns*image->depth)/8)* number_components; target_size=(current_size*rate)+header_size; rate=target_size/current_size; } FormatString(option_keyval,"%s=%g ","rate",rate); ConcatenateString(&options,option_keyval); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Compression rate: %g (%3.2f:1)",rate,1.0/rate); } if (options) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Jasper options: \"%s\"", options); (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Encoding image"); status=jas_image_encode(jp2_image,jp2_stream,format,options); (void) jas_stream_close(jp2_stream); MagickFreeMemory(options); MagickFreeMemory(lut); jas_matrix_destroy(jp2_pixels); jas_image_destroy(jp2_image); if (status) ThrowWriterException(DelegateError,UnableToEncodeImageFile,image); return(True); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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 M A P I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteMAPImage() writes an image to a file as red, green, and blue % colormap bytes followed by the colormap indexes. % % The format of the WriteMAPImage method is: % % MagickBooleanType WriteMAPImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % % */ static MagickBooleanType WriteMAPImage(const ImageInfo *image_info,Image *image) { long y; MagickBooleanType status; register IndexPacket *indexes; register const PixelPacket *p; register long i, x; register unsigned char *q; size_t packet_size; unsigned char *colormap, *pixels; unsigned long depth; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); /* Allocate colormap. */ if (IsPaletteImage(image,&image->exception) == MagickFalse) (void) SetImageType(image,PaletteType); depth=GetImageQuantumDepth(image,MagickTrue); packet_size=(size_t) (depth/8); pixels=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size* sizeof(*pixels)); packet_size=(size_t) (image->colors > 256 ? 6UL : 3UL); colormap=(unsigned char *) AcquireQuantumMemory(image->colors,packet_size* sizeof(*colormap)); if ((pixels == (unsigned char *) NULL) || (colormap == (unsigned char *) NULL)) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Write colormap to file. */ q=colormap; if (image->depth <= 8) for (i=0; i < (long) image->colors; i++) { *q++=(unsigned char) image->colormap[i].red; *q++=(unsigned char) image->colormap[i].green; *q++=(unsigned char) image->colormap[i].blue; } else for (i=0; i < (long) image->colors; i++) { *q++=(unsigned char) ((unsigned long) image->colormap[i].red >> 8); *q++=(unsigned char) image->colormap[i].red; *q++=(unsigned char) ((unsigned long) image->colormap[i].green >> 8); *q++=(unsigned char) image->colormap[i].green; *q++=(unsigned char) ((unsigned long) image->colormap[i].blue >> 8); *q++=(unsigned char) image->colormap[i].blue; } (void) WriteBlob(image,packet_size*image->colors,colormap); colormap=(unsigned char *) RelinquishMagickMemory(colormap); /* Write image pixels to file. */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); q=pixels; for (x=0; x < (long) image->columns; x++) { if (image->colors > 256) *q++=(unsigned char) ((unsigned long) indexes[x] >> 8); *q++=(unsigned char) indexes[x]; } (void) WriteBlob(image,(size_t) (q-pixels),pixels); } pixels=(unsigned char *) RelinquishMagickMemory(pixels); CloseBlob(image); return(status); }
void ImageProcessorDlg::Impl::test(ViewPane& view) { #if 0 CImageDecoderPtr d= photos_[0]->GetDecoder(); Dib bmp; CSize size(500,500); if (d->DecodeImg(bmp, size, false) != IS_OK) return; size = CSize(bmp.GetWidth(), bmp.GetHeight()); ExceptionInfo exc; GetExceptionInfo(&exc); Image* img= ConstituteImage(bmp.GetWidth(), bmp.GetHeight(), "RGB", CharPixel, bmp.GetBuffer(), &exc); if (img) { double radius= 10.0; double sigma= 1.0; double amount= 1.0; double threshold= 0.01; // Image* sharp= UnsharpMaskImage(img, radius, sigma, amount, threshold, &exc); int w= size.cy * 16 / 9; Image* sharp= LiquidRescaleImage(img, w, size.cy, 1.0, 0.0, &exc); if (sharp) { //ImageInfo ii; //GetImageInfo(&ii); //strcpy(sharp->filename, "c:\\sharp.img"); size.cx = sharp->columns; size.cy = sharp->rows; const PixelPacket* pix= AcquireImagePixels(sharp, 0, 0, size.cx, size.cy, &exc); Dib b(size.cx, size.cy, 24); for (int y= size.cy - 1; y >= 0; --y) { BYTE* line= b.LineBuffer(y); for (int x= 0; x < size.cx; ++x) { line[0] = pix->red; line[1] = pix->green; line[2] = pix->blue; line += 3; pix++; } } b.Swap(bmp); DestroyImage(sharp); } DestroyImage(img); } view.DisplayBitmap(bmp); bmp.Save(L"c:\\resized.bmp"); #endif }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % C r o p I m a g e T o H B i t m a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CropImageToHBITMAP() extracts a specified region of the image and returns % it as a Windows HBITMAP. While the same functionality can be accomplished by % invoking CropImage() followed by ImageToHBITMAP(), this method is more % efficient since it copies pixels directly to the HBITMAP. % % The format of the CropImageToHBITMAP method is: % % HBITMAP CropImageToHBITMAP(Image* image,const RectangleInfo *geometry, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image: The image. % % o geometry: Define the region of the image to crop with members % x, y, width, and height. % % o exception: Return any errors or warnings in this structure. % */ MagickExport void *CropImageToHBITMAP(Image *image, const RectangleInfo *geometry,ExceptionInfo *exception) { #define CropImageTag "Crop/Image" long y; MagickBooleanType status; RectangleInfo page; register const PixelPacket *p; BITMAP bitmap; HBITMAP bitmapH; HANDLE bitmap_bitsH; register RGBQUAD *q; RGBQUAD *bitmap_bits; /* Check crop geometry. */ assert(image != (const Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(geometry != (const RectangleInfo *) NULL); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); if (((geometry->x+(long) geometry->width) < 0) || ((geometry->y+(long) geometry->height) < 0) || (geometry->x >= (long) image->columns) || (geometry->y >= (long) image->rows)) ThrowImageException(OptionError,"GeometryDoesNotContainImage"); page=(*geometry); if ((page.x+(long) page.width) > (long) image->columns) page.width=image->columns-page.x; if ((page.y+(long) page.height) > (long) image->rows) page.height=image->rows-page.y; if (page.x < 0) { page.width+=page.x; page.x=0; } if (page.y < 0) { page.height+=page.y; page.y=0; } if ((page.width == 0) || (page.height == 0)) ThrowImageException(OptionError,"GeometryDimensionsAreZero"); /* Initialize crop image attributes. */ bitmap.bmType = 0; bitmap.bmWidth = page.width; bitmap.bmHeight = page.height; bitmap.bmWidthBytes = bitmap.bmWidth * 4; bitmap.bmPlanes = 1; bitmap.bmBitsPixel = 32; bitmap.bmBits = NULL; bitmap_bitsH = (HANDLE) GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, page.width*page.height*bitmap.bmBitsPixel); if (bitmap_bitsH == NULL) return(NULL); bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH); if ( bitmap.bmBits == NULL ) bitmap.bmBits = bitmap_bits; if (image->colorspace != RGBColorspace) SetImageColorspace(image,RGBColorspace); /* Extract crop image. */ q=bitmap_bits; for (y=0; y < (long) page.height; y++) { p=AcquireImagePixels(image,page.x,page.y+y,page.width,1,exception); if (p == (const PixelPacket *) NULL) break; #if MAGICKCORE_QUANTUM_DEPTH == 8 /* Form of PixelPacket is identical to RGBQUAD when MAGICKCORE_QUANTUM_DEPTH==8 */ CopyMagickMemory((void*)q,(const void*)p,page.width*sizeof(PixelPacket)); q += page.width; #else /* 16 or 32 bit Quantum */ { long x; /* Transfer pixels, scaling to Quantum */ for( x=page.width ; x> 0 ; x-- ) { q->rgbRed = ScaleQuantumToChar(p->red); q->rgbGreen = ScaleQuantumToChar(p->green); q->rgbBlue = ScaleQuantumToChar(p->blue); q->rgbReserved = 0; ++q; ++p; } } #endif if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,page.height) != MagickFalse)) { status=image->progress_monitor(CropImageTag,y,page.height, image->client_data); if (status == MagickFalse) break; } } if (y < (long) page.height) { GlobalUnlock((HGLOBAL) bitmap_bitsH); GlobalFree((HGLOBAL) bitmap_bitsH); return((void *) NULL); } bitmap.bmBits = bitmap_bits; bitmapH = CreateBitmapIndirect( &bitmap ); GlobalUnlock((HGLOBAL) bitmap_bitsH); return((void *) bitmapH); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % I m a g e T o H B i t m a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ImageToHBITMAP() creates a Windows HBITMAP from an image. % % The format of the ImageToHBITMAP method is: % % HBITMAP ImageToHBITMAP(Image *image) % % A description of each parameter follows: % % o image: the image to convert. % */ MagickExport void *ImageToHBITMAP(Image *image) { BITMAP bitmap; HANDLE bitmap_bitsH; HBITMAP bitmapH; long y; register long x; register const PixelPacket *p; register RGBQUAD *q; RGBQUAD *bitmap_bits; size_t length; (void) ResetMagickMemory(&bitmap,0,sizeof(bitmap)); bitmap.bmType=0; bitmap.bmWidth=image->columns; bitmap.bmHeight=image->rows; bitmap.bmWidthBytes=4*bitmap.bmWidth; bitmap.bmPlanes=1; bitmap.bmBitsPixel=32; bitmap.bmBits=NULL; length=bitmap.bmWidthBytes*bitmap.bmHeight; bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,length); if (bitmap_bitsH == NULL) { char *message; message=GetExceptionMessage(errno); (void) ThrowMagickException(&image->exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",message); message=DestroyString(message); return(NULL); } bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH); q=bitmap_bits; if (bitmap.bmBits == NULL) bitmap.bmBits=bitmap_bits; (void) SetImageColorspace(image,RGBColorspace); for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { q->rgbRed=ScaleQuantumToChar(p->red); q->rgbGreen=ScaleQuantumToChar(p->green); q->rgbBlue=ScaleQuantumToChar(p->blue); q->rgbReserved=0; p++; q++; } } bitmap.bmBits=bitmap_bits; bitmapH=CreateBitmapIndirect(&bitmap); if (bitmapH == NULL) { char *message; message=GetExceptionMessage(errno); (void) ThrowMagickException(&image->exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",message); message=DestroyString(message); } GlobalUnlock((HGLOBAL) bitmap_bitsH); GlobalFree((HGLOBAL) bitmap_bitsH); return((void *) bitmapH); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e C I P I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone % image format. % % The format of the WriteCIPImage method is: % % MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % % */ static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent]; const ImageAttribute *attribute; long y; MagickBooleanType status; register const PixelPacket *p; register long i, x; unsigned char byte; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n"); attribute=GetImageAttribute(image,"Label"); if (attribute != (const ImageAttribute *) NULL) (void) FormatMagickString(buffer,MaxTextExtent,"<Title>%s</Title>\n", attribute->value); else { char basename[MaxTextExtent]; GetPathComponent(image->filename,BasePath,basename); (void) FormatMagickString(buffer,MaxTextExtent,"<Title>%s</Title>\n", basename); } (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<LocationX>%ld</LocationX>\n", image->page.x); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<LocationY>%ld</LocationY>\n", image->page.y); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<Width>%lu</Width>\n", image->columns+(image->columns % 2)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<Height>%lu</Height>\n", image->rows); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"<Depth>2</Depth>\n"); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<Data>"); (void) SetImageColorspace(image,RGBColorspace); for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < ((long) image->columns-3); x+=4) { byte=(unsigned char) (((4*PixelIntensityToQuantum(p+3)/QuantumRange) & 0x03) << 6) | (((4*PixelIntensityToQuantum(p+2)/QuantumRange) & 0x03) << 4) | (((4*PixelIntensityToQuantum(p+1)/QuantumRange) & 0x03) << 2) | (((4*PixelIntensityToQuantum(p+0)/QuantumRange) & 0x03) << 0); (void) FormatMagickString(buffer,MaxTextExtent,"%02x",byte); (void) WriteBlobString(image,buffer); p+=4; } if ((image->columns % 4) != 0) { i=(long) image->columns % 4; byte=(unsigned char) ((((4*PixelIntensityToQuantum(p+Min(i,3))/QuantumRange) & 0x03) << 6) | (((4*PixelIntensityToQuantum(p+Min(i,2))/QuantumRange) & 0x03) << 4) | (((4*PixelIntensityToQuantum(p+Min(i,1))/QuantumRange) & 0x03) << 2) | (((4*PixelIntensityToQuantum(p+Min(i,0))/QuantumRange) & 0x03) << 0)); (void) FormatMagickString(buffer,MaxTextExtent,"%02x",~byte); (void) WriteBlobString(image,buffer); } 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; } } (void) WriteBlobString(image,"</Data>\n"); (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n"); CloseBlob(image); return(MagickTrue); }
unsigned long *HalfImage(unsigned long *image,int colums,int rows) { #define Minify(weight) \ total.red+=(weight)*(r->red); \ total.green+=(weight)*(r->green); \ total.blue+=(weight)*(r->blue); \ total.opacity+=(weight)*(r->opacity); \ r++; unsigned long *minify_image; long y; /* Initialize minified image. */ minify_image= image; /* Reduce each row. */ { unsigned long row_count=0,zero=0; float red,green,blue,opacity; zero=0; for (y=0; y < (long) minify_image->rows; y++) { DoublePixelPacket total; register const PixelPacket *p, *r; register long x; register PixelPacket *q; MagickBool thread_status; p=AcquireImagePixels(image,-2,2*(y-1),image->columns+4,4,exception); q=SetImagePixelsEx(minify_image,0,y,minify_image->columns,1,exception); for (x=0; x < columns/2; x++) { /* Compute weighted average of target pixel color components. */ total=zero; r=p; Minify(3.0); Minify(7.0); Minify(7.0); Minify(3.0); r=p+(image->columns+4); Minify(7.0); Minify(15.0); Minify(15.0); Minify(7.0); r=p+2*(image->columns+4); Minify(7.0); Minify(15.0); Minify(15.0); Minify(7.0); r=p+3*(image->columns+4); Minify(3.0); Minify(7.0); Minify(7.0); Minify(3.0); q->red=(Quantum) (total.red/128.0+0.5); q->green=(Quantum) (total.green/128.0+0.5); q->blue=(Quantum) (total.blue/128.0+0.5); q->opacity=(Quantum) (total.opacity/128.0+0.5); p+=2; q++; } if (!SyncImagePixelsEx(minify_image,exception)) thread_status=MagickFail; #if defined(HAVE_OPENMP) # pragma omp critical (GM_MinifyImage) #endif { row_count++; if (QuantumTick(row_count,image->rows)) if (!MagickMonitorFormatted(row_count,image->rows,exception, MinifyImageText,image->filename)) thread_status=MagickFail; if (thread_status == MagickFail) status=MagickFail; } } } minify_image->is_grayscale=image->is_grayscale; return(minify_image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e M G K I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteMGKImage() writes an image to a file in red, green, and blue % MGK rasterfile format. % % The format of the WriteMGKImage method is: % % MagickBooleanType WriteMGKImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteMGKImage(const ImageInfo *image_info, Image *image) { char buffer[MaxTextExtent]; MagickBooleanType status; MagickOffsetType scene; register const PixelPacket *p; register ssize_t x; register unsigned char *q; ssize_t y; unsigned char *pixels; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); scene=0; do { /* Allocate memory for pixels. */ if (image->colorspace != RGBColorspace) (void) SetImageColorspace(image,RGBColorspace); pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->columns, 3UL*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Initialize raster file header. */ (void) WriteBlobString(image,"id=mgk\n"); (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n",image->columns, image->rows); (void) WriteBlobString(image,buffer); for (y=0; y < (ssize_t) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; q=pixels; for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(GetRedSample(p)); *q++=ScaleQuantumToChar(GetGreenSample(p)); *q++=ScaleQuantumToChar(GetBlueSample(p)); p++; } (void) WriteBlob(image,(size_t) (q-pixels),pixels); if ((image->previous == (Image *) NULL) && (SetImageProgress(image,SaveImageTag,y,image->rows) == MagickFalse)) break; } pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene, GetImageListLength(image)); if (status == MagickFalse) break; scene++; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
static MagickBooleanType WriteJBIGImage(const ImageInfo *image_info, Image *image) { double version; long y; MagickBooleanType status; MagickOffsetType scene; register const PixelPacket *p; register IndexPacket *indexes; register long x; register unsigned char *q; struct jbg_enc_state jbig_info; unsigned char bit, byte, *pixels; unsigned long number_packets; /* Open image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); version=strtod(JBG_VERSION,(char **) NULL); scene=0; do { /* Allocate pixel data. */ if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); number_packets=(image->columns+7)/8; pixels=(unsigned char *) AcquireQuantumMemory(number_packets, image->rows*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert pixels to a bitmap. */ (void) SetImageType(image,BilevelType); q=pixels; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); bit=0; byte=0; for (x=0; x < (long) image->columns; x++) { byte<<=1; if (PixelIntensity(p) < (QuantumRange/2.0)) byte|=0x01; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } p++; } if (bit != 0) *q++=byte << (8-bit); 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; } } /* Initialize JBIG info structure. */ jbg_enc_init(&jbig_info,image->columns,image->rows,1,&pixels, (void (*)(unsigned char *,size_t,void *)) JBIGEncode,image); if (image_info->scene != 0) jbg_enc_layers(&jbig_info,(int) image_info->scene); else { long sans_offset; unsigned long x_resolution, y_resolution; x_resolution=640; y_resolution=480; sans_offset=0; if (image_info->density != (char *) NULL) { GeometryInfo geometry_info; MagickStatusType flags; flags=ParseGeometry(image_info->density,&geometry_info); x_resolution=geometry_info.rho; y_resolution=geometry_info.sigma; if ((flags & SigmaValue) == 0) y_resolution=x_resolution; } if (image->units == PixelsPerCentimeterResolution) { x_resolution*=2.54; y_resolution*=2.54; } (void) jbg_enc_lrlmax(&jbig_info,x_resolution,y_resolution); } (void) jbg_enc_lrange(&jbig_info,-1,-1); jbg_enc_options(&jbig_info,JBG_ILEAVE | JBG_SMID,JBG_TPDON | JBG_TPBON | JBG_DPON,version < 1.6 ? -1 : 0,-1,-1); /* Write JBIG image. */ jbg_enc_out(&jbig_info); jbg_enc_free(&jbig_info); pixels=(unsigned char *) RelinquishMagickMemory(pixels); 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); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e A V S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteAVSImage() writes an image to a file in AVS X image format. % % The format of the WriteAVSImage method is: % % MagickBooleanType WriteAVSImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % */ static MagickBooleanType WriteAVSImage(const ImageInfo *image_info,Image *image) { MagickBooleanType status; MagickOffsetType scene; register const PixelPacket *p; register long x, y; register unsigned char *q; unsigned char *pixels; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); scene=0; do { /* Write AVS header. */ if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); (void) WriteBlobMSBLong(image,image->columns); (void) WriteBlobMSBLong(image,image->rows); /* Allocate memory for pixels. */ pixels=(unsigned char *) AcquireMagickMemory((size_t) image->columns* 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert MIFF to AVS raster pixels. */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (PixelPacket *) NULL) break; q=pixels; for (x=0; x < (long) image->columns; x++) { *q++=ScaleQuantumToChar((Quantum) (QuantumRange- (image->matte != MagickFalse ? p->opacity : OpaqueOpacity))); *q++=ScaleQuantumToChar(p->red); *q++=ScaleQuantumToChar(p->green); *q++=ScaleQuantumToChar(p->blue); p++; } (void) WriteBlob(image,(size_t) (q-pixels),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; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); 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); 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e P I C O N I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedure WritePICONImage() writes an image to a file in the Personal Icon % format. % % The format of the WritePICONImage method is: % % MagickBooleanType WritePICONImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WritePICONImage(const ImageInfo *image_info, Image *image) { #define ColormapExtent 155 #define GraymapExtent 95 #define PiconGeometry "48x48>" static unsigned char Colormap[]= { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x06, 0x00, 0x05, 0x00, 0xf4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x4f, 0x4f, 0x70, 0x80, 0x90, 0x7e, 0x7e, 0x7e, 0xdc, 0xdc, 0xdc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x1e, 0x90, 0xff, 0x87, 0xce, 0xeb, 0xe6, 0xe6, 0xfa, 0x00, 0xff, 0xff, 0x80, 0x00, 0x80, 0xb2, 0x22, 0x22, 0x2e, 0x8b, 0x57, 0x32, 0xcd, 0x32, 0x00, 0xff, 0x00, 0x98, 0xfb, 0x98, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x63, 0x47, 0xff, 0xa5, 0x00, 0xff, 0xd7, 0x00, 0xff, 0xff, 0x00, 0xee, 0x82, 0xee, 0xa0, 0x52, 0x2d, 0xcd, 0x85, 0x3f, 0xd2, 0xb4, 0x8c, 0xf5, 0xde, 0xb3, 0xff, 0xfa, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x05, 0x18, 0x20, 0x10, 0x08, 0x03, 0x51, 0x18, 0x07, 0x92, 0x28, 0x0b, 0xd3, 0x38, 0x0f, 0x14, 0x49, 0x13, 0x55, 0x59, 0x17, 0x96, 0x69, 0x1b, 0xd7, 0x85, 0x00, 0x3b, }, Graymap[]= { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x04, 0x00, 0x04, 0x00, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x21, 0x21, 0x21, 0x33, 0x33, 0x33, 0x45, 0x45, 0x45, 0x54, 0x54, 0x54, 0x66, 0x66, 0x66, 0x78, 0x78, 0x78, 0x87, 0x87, 0x87, 0x99, 0x99, 0x99, 0xab, 0xab, 0xab, 0xba, 0xba, 0xba, 0xcc, 0xcc, 0xcc, 0xde, 0xde, 0xde, 0xed, 0xed, 0xed, 0xff, 0xff, 0xff, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x0c, 0x10, 0x04, 0x31, 0x48, 0x31, 0x07, 0x25, 0xb5, 0x58, 0x73, 0x4f, 0x04, 0x00, 0x3b, }; #define MaxCixels 92 static const char Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk" "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; char buffer[MaxTextExtent], basename[MaxTextExtent], name[MaxTextExtent], symbol[MaxTextExtent]; Image *picon, *map; ImageInfo *blob_info; long j, k, y; MagickBooleanType status, transparent; MagickPixelPacket pixel; RectangleInfo geometry; register const PixelPacket *p; register IndexPacket *indexes; register long i, x; register PixelPacket *q; unsigned long characters_per_pixel, colors; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); SetGeometry(image,&geometry); (void) ParseMetaGeometry(PiconGeometry,&geometry.x,&geometry.y, &geometry.width,&geometry.height); picon=ResizeImage(image,geometry.width,geometry.height,TriangleFilter,1.0, &image->exception); blob_info=CloneImageInfo(image_info); (void) AcquireUniqueFilename(blob_info->filename); if ((image_info->type != TrueColorType) && (IsGrayImage(image,&image->exception) != MagickFalse)) map=BlobToImage(blob_info,Graymap,GraymapExtent,&image->exception); else map=BlobToImage(blob_info,Colormap,ColormapExtent,&image->exception); (void) RelinquishUniqueFileResource(blob_info->filename); blob_info=DestroyImageInfo(blob_info); if ((picon == (Image *) NULL) || (map == (Image *) NULL)) return(MagickFalse); status=MapImage(picon,map,image_info->dither); map=DestroyImage(map); transparent=MagickFalse; if (picon->storage_class == PseudoClass) { CompressImageColormap(picon); if (picon->matte != MagickFalse) transparent=MagickTrue; } else { /* Convert DirectClass to PseudoClass picon. */ if (picon->matte != MagickFalse) { /* Map all the transparent pixels. */ for (y=0; y < (long) picon->rows; y++) { q=GetImagePixels(picon,0,y,picon->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) picon->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) transparent=MagickTrue; else q->opacity=OpaqueOpacity; q++; } if (SyncImagePixels(picon) == MagickFalse) break; } } (void) SetImageType(picon,PaletteType); } colors=picon->colors; if (transparent != MagickFalse) { colors++; picon->colormap=(PixelPacket *) ResizeQuantumMemory((void **) picon->colormap,(size_t) colors,sizeof(*picon->colormap)); if (picon->colormap == (PixelPacket *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationError"); for (y=0; y < (long) picon->rows; y++) { q=GetImagePixels(picon,0,y,picon->columns,1); if (q == (PixelPacket *) NULL) break; indexes=GetIndexes(picon); for (x=0; x < (long) picon->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) indexes[x]=(IndexPacket) picon->colors; q++; } if (SyncImagePixels(picon) == MagickFalse) break; } } /* Compute the character per pixel. */ characters_per_pixel=1; for (k=MaxCixels; (long) colors > k; k*=MaxCixels) characters_per_pixel++; /* XPM header. */ (void) WriteBlobString(image,"/* XPM */\n"); GetPathComponent(picon->filename,BasePath,basename); (void) FormatMagickString(buffer,MaxTextExtent, "static char *%s[] = {\n",basename); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n"); (void) FormatMagickString(buffer,MaxTextExtent,"\"%lu %lu %lu %ld\",\n", picon->columns,picon->rows,colors,characters_per_pixel); (void) WriteBlobString(image,buffer); GetMagickPixelPacket(image,&pixel); for (i=0; i < (long) colors; i++) { /* Define XPM color. */ SetMagickPixelPacket(image,picon->colormap+i,(IndexPacket *) NULL,&pixel); pixel.colorspace=RGBColorspace; pixel.depth=8; pixel.opacity=(MagickRealType) OpaqueOpacity; (void) QueryMagickColorname(image,&pixel,XPMCompliance,MagickFalse,name, &image->exception); if (LocaleNCompare(name,"rgb",3) == 0) (void) QueryMagickColorname(image,&pixel,XPMCompliance,MagickTrue,name, &image->exception); if (transparent != MagickFalse) { if (i == (long) (colors-1)) (void) CopyMagickString(name,"grey75",MaxTextExtent); } /* Write XPM color. */ k=i % MaxCixels; symbol[0]=Cixel[k]; for (j=1; j < (long) characters_per_pixel; j++) { k=((i-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) FormatMagickString(buffer,MaxTextExtent,"\"%s c %s\",\n", symbol,name); (void) WriteBlobString(image,buffer); } /* Define XPM pixels. */ (void) WriteBlobString(image,"/* pixels */\n"); for (y=0; y < (long) picon->rows; y++) { p=AcquireImagePixels(picon,0,y,picon->columns,1,&picon->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(picon); (void) WriteBlobString(image,"\""); for (x=0; x < (long) picon->columns; x++) { k=((long) indexes[x] % MaxCixels); symbol[0]=Cixel[k]; for (j=1; j < (long) characters_per_pixel; j++) { k=(((int) indexes[x]-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) CopyMagickString(buffer,symbol,MaxTextExtent); (void) WriteBlobString(image,buffer); } (void) FormatMagickString(buffer,MaxTextExtent,"\"%s\n", y == (long) (picon->rows-1) ? "" : ","); (void) WriteBlobString(image,buffer); if (QuantumTick(y,picon->rows) != MagickFalse) if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,picon->rows) != MagickFalse)) { status=image->progress_monitor(SaveImageTag,y,picon->rows, image->client_data); if (status == MagickFalse) break; } } picon=DestroyImage(picon); (void) WriteBlobString(image,"};\n"); (void) CloseBlob(image); return(MagickTrue); }
MagickExport MagickPixelPacket IInterpolateColor(const Image *image, const double x_offset,const double y_offset,ExceptionInfo *exception) { MagickPixelPacket pixel, pixels[4]; MagickRealType alpha[4], gamma; PointInfo delta; register const PixelPacket *p; register IndexPacket *indexes; register long i; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); GetMagickPixelPacket(image,&pixel); p=AcquireImagePixels(image,(long) x_offset,(long) y_offset,2,2,exception); if (p == (const PixelPacket *) NULL) return(pixel); indexes=GetIndexes(image); for (i=0; i < 4L; i++) { alpha[i]=1.0; if (image->matte != MagickFalse) alpha[i]=((MagickRealType) QuantumRange-p->opacity)/QuantumRange; GetMagickPixelPacket(image,pixels+i); SetMagickPixelPacket(p,indexes+i,pixels+i); pixels[i].red*=alpha[i]; pixels[i].green*=alpha[i]; pixels[i].blue*=alpha[i]; if (image->colorspace == CMYKColorspace) pixels[i].index*=alpha[i]; p++; } delta.x=x_offset-(long) x_offset; delta.y=y_offset-(long) y_offset; gamma=(alpha[0]+(alpha[2]-alpha[0])*delta.y+(alpha[1]-alpha[0])*delta.x+ (alpha[0]+alpha[3]-alpha[2]-alpha[1])*delta.x*delta.y); gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma); pixel.red=gamma*(pixels[0].red+(pixels[2].red-pixels[0].red)*delta.y+ (pixels[1].red-pixels[0].red)*delta.x+(pixels[0].red+pixels[3].red- pixels[2].red-pixels[1].red)*delta.x*delta.y); pixel.green=gamma*(pixels[0].green+(pixels[2].green-pixels[0].green)* delta.y+(pixels[1].green-pixels[0].green)*delta.x+(pixels[0].green+ pixels[3].green-pixels[2].green-pixels[1].green)*delta.x*delta.y); pixel.blue=gamma*(pixels[0].blue+(pixels[2].blue-pixels[0].blue)*delta.y+ (pixels[1].blue-pixels[0].blue)*delta.x+(pixels[0].blue+pixels[3].blue- pixels[2].blue-pixels[1].blue)*delta.x*delta.y); if (image->matte != MagickFalse) pixel.opacity=(pixels[0].opacity+(pixels[2].opacity-pixels[0].opacity)* delta.y+(pixels[1].opacity-pixels[0].opacity)*delta.x+(pixels[0].opacity+ pixels[3].opacity-pixels[2].opacity-pixels[1].opacity)*delta.x*delta.y); if (image->colorspace == CMYKColorspace) pixel.index=gamma*(pixels[0].index+(pixels[2].index-pixels[0].index)* delta.y+(pixels[1].index-pixels[0].index)*delta.x+(pixels[0].index+ pixels[3].index-pixels[2].index-pixels[1].index)*delta.x*delta.y); return(pixel); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e X P M I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedure WriteXPMImage() writes an image to a file in the X pixmap format. % % The format of the WriteXPMImage method is: % % MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % */ static MagickBooleanType WriteXPMImage(const ImageInfo *image_info,Image *image) { #define MaxCixels 92 static const char Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk" "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; char buffer[MaxTextExtent], basename[MaxTextExtent], name[MaxTextExtent], symbol[MaxTextExtent]; long j, k, opacity, y; MagickBooleanType status; MagickPixelPacket pixel; register const PixelPacket *p; register IndexPacket *indexes; register long i, x; unsigned long characters_per_pixel; /* Open output image file. */ 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); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); opacity=(-1); if (image->matte == MagickFalse) { if ((image->storage_class == DirectClass) || (image->colors > 256)) (void) SetImageType(image,PaletteType); } else { MagickRealType alpha, beta; /* Identify transparent colormap index. */ if ((image->storage_class == DirectClass) || (image->colors > 256)) (void) SetImageType(image,PaletteBilevelMatteType); for (i=0; i < (long) image->colors; i++) if (image->colormap[i].opacity != OpaqueOpacity) { if (opacity < 0) { opacity=i; continue; } alpha=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[i].opacity; beta=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[opacity].opacity; if (alpha < beta) opacity=i; } if (opacity == -1) { (void) SetImageType(image,PaletteBilevelMatteType); for (i=0; i < (long) image->colors; i++) if (image->colormap[i].opacity != OpaqueOpacity) { if (opacity < 0) { opacity=i; continue; } alpha=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[i].opacity; beta=(Quantum) TransparentOpacity-(MagickRealType) image->colormap[opacity].opacity; if (alpha < beta) opacity=i; } } if (opacity >= 0) { image->colormap[opacity].red=image->transparent_color.red; image->colormap[opacity].green=image->transparent_color.green; image->colormap[opacity].blue=image->transparent_color.blue; } } /* Compute the character per pixel. */ characters_per_pixel=1; for (k=MaxCixels; (long) image->colors > k; k*=MaxCixels) characters_per_pixel++; /* XPM header. */ (void) WriteBlobString(image,"/* XPM */\n"); GetPathComponent(image->filename,BasePath,basename); if (isalnum((int) ((unsigned char) *basename)) == 0) { (void) FormatMagickString(buffer,MaxTextExtent,"xpm_%s",basename); (void) CopyMagickString(basename,buffer,MaxTextExtent); } for (i=0; basename[i] != '\0'; i++) if (isalpha((int) ((unsigned char) basename[i])) == 0) basename[i]='_'; (void) FormatMagickString(buffer,MaxTextExtent, "static char *%s[] = {\n",basename); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n"); (void) FormatMagickString(buffer,MaxTextExtent,"\"%lu %lu %lu %ld\",\n", image->columns,image->rows,image->colors,characters_per_pixel); (void) WriteBlobString(image,buffer); GetMagickPixelPacket(image,&pixel); for (i=0; i < (long) image->colors; i++) { /* Define XPM color. */ SetMagickPixelPacket(image,image->colormap+i,(IndexPacket *) NULL,&pixel); pixel.colorspace=RGBColorspace; pixel.depth=8; pixel.opacity=(MagickRealType) OpaqueOpacity; (void) QueryMagickColorname(image,&pixel,XPMCompliance,MagickFalse,name, &image->exception); if (LocaleNCompare(name,"rgb",3) == 0) (void) QueryMagickColorname(image,&pixel,XPMCompliance,MagickTrue,name, &image->exception); if (i == opacity) (void) CopyMagickString(name,"None",MaxTextExtent); /* Write XPM color. */ k=i % MaxCixels; symbol[0]=Cixel[k]; for (j=1; j < (long) characters_per_pixel; j++) { k=((i-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) FormatMagickString(buffer,MaxTextExtent,"\"%s c %s\",\n",symbol, name); (void) WriteBlobString(image,buffer); } /* Define XPM pixels. */ (void) WriteBlobString(image,"/* pixels */\n"); for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); (void) WriteBlobString(image,"\""); for (x=0; x < (long) image->columns; x++) { k=((long) indexes[x] % MaxCixels); symbol[0]=Cixel[k]; for (j=1; j < (long) characters_per_pixel; j++) { k=(((int) indexes[x]-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) CopyMagickString(buffer,symbol,MaxTextExtent); (void) WriteBlobString(image,buffer); } (void) FormatMagickString(buffer,MaxTextExtent,"\"%s\n", (y == (long) (image->rows-1) ? "" : ",")); (void) WriteBlobString(image,buffer); if (QuantumTick(y,image->rows) != MagickFalse) 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; } } (void) WriteBlobString(image,"};\n"); (void) CloseBlob(image); return(MagickTrue); }