/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % a n a l y z e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % analyzeImage() computes the brightness and saturation mean, standard % deviation, kurtosis and skewness and stores these values as attributes % of the image. % % The format of the analyzeImage method is: % % size_t analyzeImage(Image *images,const int argc, % char **argv,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the address of a structure of type Image. % % o argc: Specifies a pointer to an integer describing the number of % elements in the argument vector. % % o argv: Specifies a pointer to a text array containing the command line % arguments. % % o exception: return any errors or warnings in this structure. % */ ModuleExport size_t analyzeImage(Image **images,const int argc, const char **argv,ExceptionInfo *exception) { char text[MaxTextExtent]; double area, brightness, brightness_mean, brightness_standard_deviation, brightness_kurtosis, brightness_skewness, brightness_sum_x, brightness_sum_x2, brightness_sum_x3, brightness_sum_x4, hue, saturation, saturation_mean, saturation_standard_deviation, saturation_kurtosis, saturation_skewness, saturation_sum_x, saturation_sum_x2, saturation_sum_x3, saturation_sum_x4; Image *image; assert(images != (Image **) NULL); assert(*images != (Image *) NULL); assert((*images)->signature == MagickSignature); (void) argc; (void) argv; image=(*images); for ( ; image != (Image *) NULL; image=GetNextImageInList(image)) { CacheView *image_view; MagickBooleanType status; ssize_t y; brightness_sum_x=0.0; brightness_sum_x2=0.0; brightness_sum_x3=0.0; brightness_sum_x4=0.0; brightness_mean=0.0; brightness_standard_deviation=0.0; brightness_kurtosis=0.0; brightness_skewness=0.0; saturation_sum_x=0.0; saturation_sum_x2=0.0; saturation_sum_x3=0.0; saturation_sum_x4=0.0; saturation_mean=0.0; saturation_standard_deviation=0.0; saturation_kurtosis=0.0; saturation_skewness=0.0; area=0.0; status=MagickTrue; image_view=AcquireCacheView(image); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(status) #endif for (y=0; y < (ssize_t) image->rows; y++) { register const PixelPacket *p; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception); if (p == (const PixelPacket *) NULL) { status=MagickFalse; continue; } for (x=0; x < (ssize_t) image->columns; x++) { ConvertRGBToHSB(GetRedPixelComponent(p),GetGreenPixelComponent(p), GetBluePixelComponent(p),&hue,&saturation,&brightness); brightness*=QuantumRange; brightness_sum_x+=brightness; brightness_sum_x2+=brightness*brightness; brightness_sum_x3+=brightness*brightness*brightness; brightness_sum_x4+=brightness*brightness*brightness*brightness; saturation*=QuantumRange; saturation_sum_x+=saturation; saturation_sum_x2+=saturation*saturation; saturation_sum_x3+=saturation*saturation*saturation; saturation_sum_x4+=saturation*saturation*saturation*saturation; area++; p++; } } image_view=DestroyCacheView(image_view); if (area <= 0.0) break; brightness_mean=brightness_sum_x/area; (void) FormatMagickString(text,MaxTextExtent,"%g",brightness_mean); (void) SetImageProperty(image,"filter:brightness:mean",text); brightness_standard_deviation=sqrt(brightness_sum_x2/area-(brightness_sum_x/ area*brightness_sum_x/area)); (void) FormatMagickString(text,MaxTextExtent,"%g", brightness_standard_deviation); (void) SetImageProperty(image,"filter:brightness:standard-deviation",text); if (brightness_standard_deviation != 0) brightness_kurtosis=(brightness_sum_x4/area-4.0*brightness_mean* brightness_sum_x3/area+6.0*brightness_mean*brightness_mean* brightness_sum_x2/area-3.0*brightness_mean*brightness_mean* brightness_mean*brightness_mean)/(brightness_standard_deviation* brightness_standard_deviation*brightness_standard_deviation* brightness_standard_deviation)-3.0; (void) FormatMagickString(text,MaxTextExtent,"%g",brightness_kurtosis); (void) SetImageProperty(image,"filter:brightness:kurtosis",text); if (brightness_standard_deviation != 0) brightness_skewness=(brightness_sum_x3/area-3.0*brightness_mean* brightness_sum_x2/area+2.0*brightness_mean*brightness_mean* brightness_mean)/(brightness_standard_deviation* brightness_standard_deviation*brightness_standard_deviation); (void) FormatMagickString(text,MaxTextExtent,"%g",brightness_skewness); (void) SetImageProperty(image,"filter:brightness:skewness",text); saturation_mean=saturation_sum_x/area; (void) FormatMagickString(text,MaxTextExtent,"%g",saturation_mean); (void) SetImageProperty(image,"filter:saturation:mean",text); saturation_standard_deviation=sqrt(saturation_sum_x2/area-(saturation_sum_x/ area*saturation_sum_x/area)); (void) FormatMagickString(text,MaxTextExtent,"%g", saturation_standard_deviation); (void) SetImageProperty(image,"filter:saturation:standard-deviation",text); if (saturation_standard_deviation != 0) saturation_kurtosis=(saturation_sum_x4/area-4.0*saturation_mean* saturation_sum_x3/area+6.0*saturation_mean*saturation_mean* saturation_sum_x2/area-3.0*saturation_mean*saturation_mean* saturation_mean*saturation_mean)/(saturation_standard_deviation* saturation_standard_deviation*saturation_standard_deviation* saturation_standard_deviation)-3.0; (void) FormatMagickString(text,MaxTextExtent,"%g",saturation_kurtosis); (void) SetImageProperty(image,"filter:saturation:kurtosis",text); if (saturation_standard_deviation != 0) saturation_skewness=(saturation_sum_x3/area-3.0*saturation_mean* saturation_sum_x2/area+2.0*saturation_mean*saturation_mean* saturation_mean)/(saturation_standard_deviation* saturation_standard_deviation*saturation_standard_deviation); (void) FormatMagickString(text,MaxTextExtent,"%g",saturation_skewness); (void) SetImageProperty(image,"filter:saturation:skewness",text); } return(MagickImageFilterSignature); }
static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info, Image *image) { int webp_status; MagickBooleanType status; register const PixelPacket *__restrict__ p; register ssize_t x; register unsigned char *__restrict__ q; ssize_t y; unsigned char *pixels; WebPConfig configure; WebPPicture picture; WebPAuxStats statistics; /* 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 (WebPPictureInit(&picture) == 0) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); picture.writer=WebPWriter; picture.custom_ptr=(void *) image; picture.stats=(&statistics); picture.width=(int) image->columns; picture.height=(int) image->rows; if (image->quality != UndefinedCompressionQuality) configure.quality=(float) image->quality; if (WebPConfigInit(&configure) == 0) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Future: set custom configuration parameters here. */ if (WebPValidateConfig(&configure) == 0) ThrowWriterException(ResourceLimitError,"UnableToEncodeImageFile"); /* Allocate memory for pixels. */ pixels=(unsigned char *) AcquireQuantumMemory(image->columns, (image->matte != MagickFalse ? 4 : 3)*image->rows*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert image to WebP raster pixels. */ q=pixels; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(GetRedPixelComponent(p)); *q++=ScaleQuantumToChar(GetGreenPixelComponent(p)); *q++=ScaleQuantumToChar(GetBluePixelComponent(p)); if (image->matte != MagickFalse) *q++=ScaleQuantumToChar((Quantum) (QuantumRange- (image->matte != MagickFalse ? GetOpacityPixelComponent(p) : OpaqueOpacity))); p++; } status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } if (image->matte == MagickFalse) webp_status=WebPPictureImportRGB(&picture,pixels,3*picture.width); else webp_status=WebPPictureImportRGBA(&picture,pixels,4*picture.width); pixels=(unsigned char *) RelinquishMagickMemory(pixels); webp_status=WebPEncode(&configure,&picture); (void) CloseBlob(image); return(webp_status == 0 ? MagickFalse : MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e M T V I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteMTVImage() writes an image to a file in red, green, and blue MTV % rasterfile format. % % The format of the WriteMTVImage method is: % % MagickBooleanType WriteMTVImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteMTVImage(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) TransformImageColorspace(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) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n",(double) image->columns,(double) image->rows); (void) WriteBlobString(image,buffer); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(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(GetRedPixelComponent(p)); *q++=ScaleQuantumToChar(GetGreenPixelComponent(p)); *q++=ScaleQuantumToChar(GetBluePixelComponent(p)); p++; } (void) WriteBlob(image,(size_t) (q-pixels),pixels); if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == 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 ForwardFourierTransform(FourierInfo *fourier_info, const Image *image,double *magnitude,double *phase,ExceptionInfo *exception) { CacheView *image_view; double n, *source; fftw_complex *fourier; fftw_plan fftw_r2c_plan; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t i, x; ssize_t y; /* Generate the forward Fourier transform. */ source=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->width*sizeof(*source)); if (source == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(MagickFalse); } ResetMagickMemory(source,0,fourier_info->height*fourier_info->width* sizeof(*source)); i=0L; image_view=AcquireCacheView(image); for (y=0L; y < (ssize_t) fourier_info->height; y++) { p=GetCacheViewVirtualPixels(image_view,0L,y,fourier_info->width,1UL, exception); if (p == (const PixelPacket *) NULL) break; indexes=GetCacheViewVirtualIndexQueue(image_view); for (x=0L; x < (ssize_t) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { source[i]=QuantumScale*GetRedPixelComponent(p); break; } case GreenChannel: { source[i]=QuantumScale*GetGreenPixelComponent(p); break; } case BlueChannel: { source[i]=QuantumScale*GetBluePixelComponent(p); break; } case OpacityChannel: { source[i]=QuantumScale*GetOpacityPixelComponent(p); break; } case IndexChannel: { source[i]=QuantumScale*indexes[x]; break; } case GrayChannels: { source[i]=QuantumScale*GetGrayPixelComponent(p); break; } } i++; p++; } } image_view=DestroyCacheView(image_view); fourier=(fftw_complex *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->center*sizeof(*fourier)); if (fourier == (fftw_complex *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); source=(double *) RelinquishMagickMemory(source); return(MagickFalse); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_ForwardFourierTransform) #endif fftw_r2c_plan=fftw_plan_dft_r2c_2d(fourier_info->width,fourier_info->width, source,fourier,FFTW_ESTIMATE); fftw_execute(fftw_r2c_plan); fftw_destroy_plan(fftw_r2c_plan); source=(double *) RelinquishMagickMemory(source); /* Normalize Fourier transform. */ n=(double) fourier_info->width*(double) fourier_info->width; i=0L; for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { #if defined(MAGICKCORE_HAVE_COMPLEX_H) fourier[i]/=n; #else fourier[i][0]/=n; fourier[i][1]/=n; #endif i++; } /* Generate magnitude and phase (or real and imaginary). */ i=0L; if (fourier_info->modulus != MagickFalse) for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { magnitude[i]=cabs(fourier[i]); phase[i]=carg(fourier[i]); i++; } else for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { magnitude[i]=creal(fourier[i]); phase[i]=cimag(fourier[i]); i++; } fourier=(fftw_complex *) RelinquishMagickMemory(fourier); return(MagickTrue); }
static MagickBooleanType InverseFourier(FourierInfo *fourier_info, const Image *magnitude_image,const Image *phase_image,fftw_complex *fourier, ExceptionInfo *exception) { CacheView *magnitude_view, *phase_view; double *magnitude, *phase, *magnitude_source, *phase_source; MagickBooleanType status; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t i, x; ssize_t y; /* Inverse fourier - read image and break down into a double array. */ magnitude_source=(double *) AcquireQuantumMemory((size_t) fourier_info->height,fourier_info->width*sizeof(*magnitude_source)); if (magnitude_source == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", magnitude_image->filename); return(MagickFalse); } phase_source=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->width*sizeof(*phase_source)); if (phase_source == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", magnitude_image->filename); magnitude_source=(double *) RelinquishMagickMemory(magnitude_source); return(MagickFalse); } i=0L; magnitude_view=AcquireCacheView(magnitude_image); for (y=0L; y < (ssize_t) fourier_info->height; y++) { p=GetCacheViewVirtualPixels(magnitude_view,0L,y,fourier_info->width,1UL, exception); if (p == (const PixelPacket *) NULL) break; indexes=GetCacheViewAuthenticIndexQueue(magnitude_view); for (x=0L; x < (ssize_t) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { magnitude_source[i]=QuantumScale*GetRedPixelComponent(p); break; } case GreenChannel: { magnitude_source[i]=QuantumScale*GetGreenPixelComponent(p); break; } case BlueChannel: { magnitude_source[i]=QuantumScale*GetBluePixelComponent(p); break; } case OpacityChannel: { magnitude_source[i]=QuantumScale*GetOpacityPixelComponent(p); break; } case IndexChannel: { magnitude_source[i]=QuantumScale*indexes[x]; break; } case GrayChannels: { magnitude_source[i]=QuantumScale*GetGrayPixelComponent(p); break; } } i++; p++; } } i=0L; phase_view=AcquireCacheView(phase_image); for (y=0L; y < (ssize_t) fourier_info->height; y++) { p=GetCacheViewVirtualPixels(phase_view,0,y,fourier_info->width,1, exception); if (p == (const PixelPacket *) NULL) break; indexes=GetCacheViewAuthenticIndexQueue(phase_view); for (x=0L; x < (ssize_t) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { phase_source[i]=QuantumScale*GetRedPixelComponent(p); break; } case GreenChannel: { phase_source[i]=QuantumScale*GetGreenPixelComponent(p); break; } case BlueChannel: { phase_source[i]=QuantumScale*GetBluePixelComponent(p); break; } case OpacityChannel: { phase_source[i]=QuantumScale*GetOpacityPixelComponent(p); break; } case IndexChannel: { phase_source[i]=QuantumScale*indexes[x]; break; } case GrayChannels: { phase_source[i]=QuantumScale*GetGrayPixelComponent(p); break; } } i++; p++; } } if (fourier_info->modulus != MagickFalse) { i=0L; for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->width; x++) { phase_source[i]-=0.5; phase_source[i]*=(2.0*MagickPI); i++; } } magnitude_view=DestroyCacheView(magnitude_view); phase_view=DestroyCacheView(phase_view); magnitude=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->center*sizeof(*magnitude)); if (magnitude == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", magnitude_image->filename); magnitude_source=(double *) RelinquishMagickMemory(magnitude_source); phase_source=(double *) RelinquishMagickMemory(phase_source); return(MagickFalse); } status=InverseQuadrantSwap(fourier_info->width,fourier_info->height, magnitude_source,magnitude); magnitude_source=(double *) RelinquishMagickMemory(magnitude_source); phase=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->width*sizeof(*phase)); if (phase == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", magnitude_image->filename); phase_source=(double *) RelinquishMagickMemory(phase_source); return(MagickFalse); } CorrectPhaseLHS(fourier_info->width,fourier_info->width,phase_source); if (status != MagickFalse) status=InverseQuadrantSwap(fourier_info->width,fourier_info->height, phase_source,phase); phase_source=(double *) RelinquishMagickMemory(phase_source); /* Merge two sets. */ i=0L; if (fourier_info->modulus != MagickFalse) for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { #if defined(MAGICKCORE_HAVE_COMPLEX_H) fourier[i]=magnitude[i]*cos(phase[i])+I*magnitude[i]*sin(phase[i]); #else fourier[i][0]=magnitude[i]*cos(phase[i]); fourier[i][1]=magnitude[i]*sin(phase[i]); #endif i++; } else for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { #if defined(MAGICKCORE_HAVE_COMPLEX_H) fourier[i]=magnitude[i]+I*phase[i]; #else fourier[i][0]=magnitude[i]; fourier[i][1]=phase[i]; #endif i++; } phase=(double *) RelinquishMagickMemory(phase); magnitude=(double *) RelinquishMagickMemory(magnitude); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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" BITMAP bitmap; HBITMAP bitmapH; HANDLE bitmap_bitsH; MagickBooleanType proceed; RectangleInfo page; register const PixelPacket *p; register RGBQUAD *q; RGBQUAD *bitmap_bits; ssize_t y; /* 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+(ssize_t) geometry->width) < 0) || ((geometry->y+(ssize_t) geometry->height) < 0) || (geometry->x >= (ssize_t) image->columns) || (geometry->y >= (ssize_t) image->rows)) ThrowImageException(OptionError,"GeometryDoesNotContainImage"); page=(*geometry); if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns) page.width=image->columns-page.x; if ((page.y+(ssize_t) page.height) > (ssize_t) 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 = (LONG) page.width; bitmap.bmHeight = (LONG) 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) TransformImageColorspace(image,RGBColorspace); /* Extract crop image. */ q=bitmap_bits; for (y=0; y < (ssize_t) page.height; y++) { p=GetVirtualPixels(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 */ { ssize_t x; /* Transfer pixels, scaling to Quantum */ for( x=(ssize_t) page.width ; x> 0 ; x-- ) { q->rgbRed = ScaleQuantumToChar(GetRedPixelComponent(p)); q->rgbGreen = ScaleQuantumToChar(GetGreenPixelComponent(p)); q->rgbBlue = ScaleQuantumToChar(GetBluePixelComponent(p)); q->rgbReserved = 0; ++q; ++p; } } #endif proceed=SetImageProgress(image,CropImageTag,y,page.height); if (proceed == MagickFalse) break; } if (y < (ssize_t) page.height) { GlobalUnlock((HGLOBAL) bitmap_bitsH); GlobalFree((HGLOBAL) bitmap_bitsH); return((void *) NULL); } bitmap.bmBits=bitmap_bits; bitmapH=CreateBitmapIndirect(&bitmap); GlobalUnlock((HGLOBAL) bitmap_bitsH); GlobalFree((HGLOBAL) bitmap_bitsH); return((void *) bitmapH); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d R A W I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadRAWImage() reads an image of raw samples and returns it. It allocates % the memory necessary for the new Image structure and returns a pointer to % the new image. % % The format of the ReadRAWImage method is: % % Image *ReadRAWImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadRAWImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *canvas_image, *image; ssize_t y; MagickBooleanType status; MagickOffsetType scene; QuantumInfo *quantum_info; QuantumType quantum_type; size_t length; ssize_t count; unsigned char *pixels; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if (DiscardBlobBytes(image,image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); /* Create virtual canvas to support cropping (i.e. image.gray[100x100+10+20]). */ canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse, exception); (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod); quantum_type=GrayQuantum; quantum_info=AcquireQuantumInfo(image_info,canvas_image); if (quantum_info == (QuantumInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); pixels=GetQuantumPixels(quantum_info); if (image_info->number_scenes != 0) while (image->scene < image_info->scene) { /* Skip to next image. */ image->scene++; length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); for (y=0; y < (ssize_t) image->rows; y++) { count=ReadBlob(image,length,pixels); if (count != (ssize_t) length) break; } } scene=0; count=0; length=0; do { /* Read pixels to virtual canvas image then push to image. */ if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); count=ReadBlob(image,length,pixels); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { register const PixelPacket *restrict p; register ssize_t x; register PixelPacket *restrict q; if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,quantum_info, quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, image->columns,1,exception); q=QueueAuthenticPixels(image,0,y-image->extract_info.y,image->columns, 1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetRedPixelComponent(q,GetRedPixelComponent(p)); SetGreenPixelComponent(q,GetGreenPixelComponent(p)); SetBluePixelComponent(q,GetBluePixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } count=ReadBlob(image,length,pixels); } SetQuantumImageType(image,quantum_type); /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (count == (ssize_t) length) { /* Allocate next image structure. */ AcquireNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=SetImageProgress(image,LoadImagesTag,TellBlob(image), GetBlobSize(image)); if (status == MagickFalse) break; } scene++; } while (count == (ssize_t) length); quantum_info=DestroyQuantumInfo(quantum_info); InheritException(&image->exception,&canvas_image->exception); canvas_image=DestroyImage(canvas_image); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d Y C b C r I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadYCBCRImage() reads an image of raw YCbCr or YCbCrA samples and returns % it. It allocates the memory necessary for the new Image structure and % returns a pointer to the new image. % % The format of the ReadYCBCRImage method is: % % Image *ReadYCBCRImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadYCBCRImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *canvas_image, *image; ssize_t y; MagickBooleanType status; MagickOffsetType scene; QuantumInfo *quantum_info; QuantumType quantum_type; register const PixelPacket *p; register ssize_t i, x; register PixelPacket *q; ssize_t count; size_t length; unsigned char *pixels; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); image->colorspace=YCbCrColorspace; if (image_info->interlace != PartitionInterlace) { status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if (DiscardBlobBytes(image,image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); } /* Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]). */ canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse, exception); (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod); quantum_info=AcquireQuantumInfo(image_info,canvas_image); if (quantum_info == (QuantumInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); pixels=GetQuantumPixels(quantum_info); quantum_type=RGBQuantum; if (LocaleCompare(image_info->magick,"YCbCrA") == 0) { quantum_type=RGBAQuantum; image->matte=MagickTrue; } if (image_info->number_scenes != 0) while (image->scene < image_info->scene) { /* Skip to next image. */ image->scene++; length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); for (y=0; y < (ssize_t) image->rows; y++) { count=ReadBlob(image,length,pixels); if (count != (ssize_t) length) break; } } count=0; length=0; scene=0; do { /* Read pixels to virtual canvas image then push to image. */ if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; image->colorspace=YCbCrColorspace; switch (image_info->interlace) { case NoInterlace: default: { /* No interlacing: YCbCrYCbCrYCbCrYCbCrYCbCrYCbCr... */ if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); count=ReadBlob(image,length,pixels); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=QueueAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetRedPixelComponent(q,GetRedPixelComponent(p)); SetGreenPixelComponent(q,GetGreenPixelComponent(p)); SetBluePixelComponent(q,GetBluePixelComponent(p)); if (image->matte != MagickFalse) SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } count=ReadBlob(image,length,pixels); } break; } case LineInterlace: { static QuantumType quantum_types[4] = { RedQuantum, GreenQuantum, BlueQuantum, OpacityQuantum }; /* Line interlacing: YYY...CbCbCb...CrCrCr...YYY...CbCbCb...CrCrCr... */ if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); count=ReadBlob(image,length,pixels); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { for (i=0; i < (image->matte != MagickFalse ? 4 : 3); i++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } quantum_type=quantum_types[i]; q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x, 0,canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { switch (quantum_type) { case RedQuantum: { SetRedPixelComponent(q,GetRedPixelComponent(p)); break; } case GreenQuantum: { SetGreenPixelComponent(q,GetGreenPixelComponent(p)); break; } case BlueQuantum: { SetBluePixelComponent(q,GetBluePixelComponent(p)); break; } case OpacityQuantum: { SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); break; } default: break; } p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } break; } case PlaneInterlace: { /* Plane interlacing: YYYYYY...CbCbCbCbCbCb...CrCrCrCrCrCr... */ if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); count=ReadBlob(image,length,pixels); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,RedQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetRedPixelComponent(q,GetRedPixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,1,5); if (status == MagickFalse) break; } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,GreenQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetGreenPixelComponent(q,GetGreenPixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,2,5); if (status == MagickFalse) break; } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetBluePixelComponent(q,GetBluePixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,3,5); if (status == MagickFalse) break; } if (image->matte != MagickFalse) { for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,AlphaQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image, canvas_image->extract_info.x,0,canvas_image->columns,1, exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,4,5); if (status == MagickFalse) break; } } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,5,5); if (status == MagickFalse) break; } break; } case PartitionInterlace: { /* Partition interlacing: YYYYYY..., CbCbCbCbCbCb..., CrCrCrCrCrCr... */ AppendImageFormat("Y",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } if (DiscardBlobBytes(image,image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,RedQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetRedPixelComponent(q,GetRedPixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,1,5); if (status == MagickFalse) break; } (void) CloseBlob(image); AppendImageFormat("Cb",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,GreenQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetGreenPixelComponent(q,GetGreenPixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,2,5); if (status == MagickFalse) break; } (void) CloseBlob(image); AppendImageFormat("Cr",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetBluePixelComponent(q,GetBluePixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,3,5); if (status == MagickFalse) break; } if (image->matte != MagickFalse) { (void) CloseBlob(image); AppendImageFormat("A",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image, canvas_image->extract_info.x,0,canvas_image->columns,1, exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,4,5); if (status == MagickFalse) break; } } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,5,5); if (status == MagickFalse) break; } break; } } SetQuantumImageType(image,quantum_type); /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (count == (ssize_t) length) { /* Allocate next image structure. */ AcquireNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=SetImageProgress(image,LoadImagesTag,TellBlob(image), GetBlobSize(image)); if (status == MagickFalse) break; } scene++; } while (count == (ssize_t) length); quantum_info=DestroyQuantumInfo(quantum_info); InheritException(&image->exception,&canvas_image->exception); canvas_image=DestroyImage(canvas_image); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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; ExceptionInfo *exception; HANDLE bitmap_bitsH; HBITMAP bitmapH; register ssize_t x; register const PixelPacket *p; register RGBQUAD *q; RGBQUAD *bitmap_bits; size_t length; ssize_t y; (void) ResetMagickMemory(&bitmap,0,sizeof(bitmap)); bitmap.bmType=0; bitmap.bmWidth=(LONG) image->columns; bitmap.bmHeight=(LONG) 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) TransformImageColorspace(image,RGBColorspace); exception=(&image->exception); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { q->rgbRed=ScaleQuantumToChar(GetRedPixelComponent(p)); q->rgbGreen=ScaleQuantumToChar(GetGreenPixelComponent(p)); q->rgbBlue=ScaleQuantumToChar(GetBluePixelComponent(p)); 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); }
static MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, Image *image) { #define HistogramDensity "256x200" ChannelType channel; char filename[MaxTextExtent]; const char *option; ExceptionInfo *exception; Image *histogram_image; ImageInfo *write_info; long y; MagickBooleanType status; MagickPixelPacket *histogram; MagickRealType maximum, scale; RectangleInfo geometry; register const PixelPacket *p; register long x; register PixelPacket *q, *r; size_t length; /* Allocate histogram image. */ 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_info->filename); SetGeometry(image,&geometry); if (image_info->density == (char *) NULL) (void) ParseAbsoluteGeometry(HistogramDensity,&geometry); else (void) ParseAbsoluteGeometry(image_info->density,&geometry); histogram_image=CloneImage(image,geometry.width,geometry.height,MagickTrue, &image->exception); if (histogram_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) SetImageStorageClass(histogram_image,DirectClass); /* Allocate histogram count arrays. */ length=MagickMax((size_t) ScaleQuantumToChar((Quantum) QuantumRange)+1UL, histogram_image->columns); histogram=(MagickPixelPacket *) AcquireQuantumMemory(length, sizeof(*histogram)); if (histogram == (MagickPixelPacket *) NULL) { histogram_image=DestroyImage(histogram_image); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } /* Initialize histogram count arrays. */ channel=image_info->channel; (void) ResetMagickMemory(histogram,0,length*sizeof(*histogram)); for (y=0; y < (long) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if ((channel & RedChannel) != 0) histogram[ScaleQuantumToChar(GetRedPixelComponent(p))].red++; if ((channel & GreenChannel) != 0) histogram[ScaleQuantumToChar(GetGreenPixelComponent(p))].green++; if ((channel & BlueChannel) != 0) histogram[ScaleQuantumToChar(GetBluePixelComponent(p))].blue++; p++; } } maximum=histogram[0].red; for (x=0; x < (long) histogram_image->columns; x++) { if (((channel & RedChannel) != 0) && (maximum < histogram[x].red)) maximum=histogram[x].red; if (((channel & GreenChannel) != 0) && (maximum < histogram[x].green)) maximum=histogram[x].green; if (((channel & BlueChannel) != 0) && (maximum < histogram[x].blue)) maximum=histogram[x].blue; } scale=(MagickRealType) histogram_image->rows/maximum; /* Initialize histogram image. */ exception=(&image->exception); (void) QueryColorDatabase("#000000",&histogram_image->background_color, &image->exception); (void) SetImageBackgroundColor(histogram_image); for (x=0; x < (long) histogram_image->columns; x++) { q=GetAuthenticPixels(histogram_image,x,0,1,histogram_image->rows,exception); if (q == (PixelPacket *) NULL) break; if ((channel & RedChannel) != 0) { y=(long) ceil(histogram_image->rows-scale*histogram[x].red-0.5); r=q+y; for ( ; y < (long) histogram_image->rows; y++) { r->red=(Quantum) QuantumRange; r++; } } if ((channel & GreenChannel) != 0) { y=(long) ceil(histogram_image->rows-scale*histogram[x].green-0.5); r=q+y; for ( ; y < (long) histogram_image->rows; y++) { r->green=(Quantum) QuantumRange; r++; } } if ((channel & BlueChannel) != 0) { y=(long) ceil(histogram_image->rows-scale*histogram[x].blue-0.5); r=q+y; for ( ; y < (long) histogram_image->rows; y++) { r->blue=(Quantum) QuantumRange; r++; } } if (SyncAuthenticPixels(histogram_image,exception) == MagickFalse) break; status=SetImageProgress(image,SaveImageTag,y,histogram_image->rows); if (status == MagickFalse) break; } /* Relinquish resources. */ histogram=(MagickPixelPacket *) RelinquishMagickMemory(histogram); option=GetImageOption(image_info,"histogram:unique-colors"); if ((option == (const char *) NULL) || (IsMagickTrue(option) != MagickFalse)) { FILE *file; int unique_file; /* Add a unique colors as an image comment. */ file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file != -1) && (file != (FILE *) NULL)) { char *property; (void) GetNumberColors(image,file,&image->exception); (void) fclose(file); property=FileToString(filename,~0UL,&image->exception); if (property != (char *) NULL) { (void) SetImageProperty(histogram_image,"comment",property); property=DestroyString(property); } } (void) RelinquishUniqueFileResource(filename); } /* Write Histogram image. */ (void) CopyMagickString(histogram_image->filename,image_info->filename, MaxTextExtent); write_info=CloneImageInfo(image_info); (void) SetImageInfo(write_info,1,&image->exception); if (LocaleCompare(write_info->magick,"HISTOGRAM") == 0) (void) FormatMagickString(histogram_image->filename,MaxTextExtent, "miff:%s",write_info->filename); status=WriteImage(write_info,histogram_image); histogram_image=DestroyImage(histogram_image); write_info=DestroyImageInfo(write_info); return(status); }
static MagickBooleanType WriteSGIImage(const ImageInfo *image_info,Image *image) { CompressionType compression; const char *value; ssize_t y, z; MagickBooleanType status; MagickOffsetType scene; MagickSizeType number_pixels; SGIInfo iris_info; register const PixelPacket *p; register ssize_t i, x; register unsigned char *q; unsigned char *iris_pixels, *packets; /* 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); if ((image->columns > 65535UL) || (image->rows > 65535UL)) ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit"); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); scene=0; do { /* Initialize SGI raster file header. */ if (image->colorspace != RGBColorspace) (void) TransformImageColorspace(image,RGBColorspace); (void) ResetMagickMemory(&iris_info,0,sizeof(iris_info)); iris_info.magic=0x01DA; compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; if (image->depth > 8) compression=NoCompression; if (compression == NoCompression) iris_info.storage=(unsigned char) 0x00; else iris_info.storage=(unsigned char) 0x01; iris_info.bytes_per_pixel=(unsigned char) (image->depth > 8 ? 2 : 1); iris_info.dimension=3; iris_info.columns=(unsigned short) image->columns; iris_info.rows=(unsigned short) image->rows; if (image->matte != MagickFalse) iris_info.depth=4; else { if ((image_info->type != TrueColorType) && (IsGrayImage(image,&image->exception) != MagickFalse)) { iris_info.dimension=2; iris_info.depth=1; } else iris_info.depth=3; } iris_info.minimum_value=0; iris_info.maximum_value=(size_t) (image->depth <= 8 ? 1UL*ScaleQuantumToChar((Quantum) QuantumRange) : 1UL*ScaleQuantumToShort((Quantum) QuantumRange)); /* Write SGI header. */ (void) WriteBlobMSBShort(image,iris_info.magic); (void) WriteBlobByte(image,iris_info.storage); (void) WriteBlobByte(image,iris_info.bytes_per_pixel); (void) WriteBlobMSBShort(image,iris_info.dimension); (void) WriteBlobMSBShort(image,iris_info.columns); (void) WriteBlobMSBShort(image,iris_info.rows); (void) WriteBlobMSBShort(image,iris_info.depth); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.minimum_value); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.maximum_value); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.sans); value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) CopyMagickString(iris_info.name,value,sizeof(iris_info.name)); (void) WriteBlob(image,sizeof(iris_info.name),(unsigned char *) iris_info.name); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.pixel_format); (void) WriteBlob(image,sizeof(iris_info.filler),iris_info.filler); /* Allocate SGI pixels. */ number_pixels=(MagickSizeType) image->columns*image->rows; if ((4*iris_info.bytes_per_pixel*number_pixels) != ((MagickSizeType) (size_t) (4*iris_info.bytes_per_pixel*number_pixels))) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); iris_pixels=(unsigned char *) AcquireQuantumMemory((size_t) number_pixels, 4*iris_info.bytes_per_pixel*sizeof(*iris_pixels)); if (iris_pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert image pixels to uncompressed SGI pixels. */ for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; if (image->depth <= 8) for (x=0; x < (ssize_t) image->columns; x++) { register unsigned char *q; q=(unsigned char *) iris_pixels; q+=((iris_info.rows-1)-y)*(4*iris_info.columns)+4*x; *q++=ScaleQuantumToChar(GetRedPixelComponent(p)); *q++=ScaleQuantumToChar(GetGreenPixelComponent(p)); *q++=ScaleQuantumToChar(GetBluePixelComponent(p)); *q++=ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p))); p++; } else for (x=0; x < (ssize_t) image->columns; x++) { register unsigned short *q; q=(unsigned short *) iris_pixels; q+=((iris_info.rows-1)-y)*(4*iris_info.columns)+4*x; *q++=ScaleQuantumToShort(GetRedPixelComponent(p)); *q++=ScaleQuantumToShort(GetGreenPixelComponent(p)); *q++=ScaleQuantumToShort(GetBluePixelComponent(p)); *q++=ScaleQuantumToShort((Quantum) (GetAlphaPixelComponent(p))); p++; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } switch (compression) { case NoCompression: { /* Write uncompressed SGI pixels. */ for (z=0; z < (ssize_t) iris_info.depth; z++) { for (y=0; y < (ssize_t) iris_info.rows; y++) { if (image->depth <= 8) for (x=0; x < (ssize_t) iris_info.columns; x++) { register unsigned char *q; q=(unsigned char *) iris_pixels; q+=y*(4*iris_info.columns)+4*x+z; (void) WriteBlobByte(image,*q); } else for (x=0; x < (ssize_t) iris_info.columns; x++) { register unsigned short *q; q=(unsigned short *) iris_pixels; q+=y*(4*iris_info.columns)+4*x+z; (void) WriteBlobMSBShort(image,*q); } } } break; } default: { ssize_t offset, *offsets; size_t length, number_packets; size_t *runlength; /* Convert SGI uncompressed pixels. */ offsets=(ssize_t *) AcquireQuantumMemory(iris_info.rows*iris_info.depth, sizeof(*offsets)); packets=(unsigned char *) AcquireQuantumMemory((2*(size_t) iris_info.columns+10)*image->rows,4*sizeof(*packets)); runlength=(size_t *) AcquireQuantumMemory(iris_info.rows, iris_info.depth*sizeof(*runlength)); if ((offsets == (ssize_t *) NULL) || (packets == (unsigned char *) NULL) || (runlength == (size_t *) NULL)) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); offset=512+4*2*((ssize_t) iris_info.rows*iris_info.depth); number_packets=0; q=iris_pixels; for (y=0; y < (ssize_t) iris_info.rows; y++) { for (z=0; z < (ssize_t) iris_info.depth; z++) { length=SGIEncode(q+z,(size_t) iris_info.columns,packets+ number_packets); number_packets+=length; offsets[y+z*iris_info.rows]=offset; runlength[y+z*iris_info.rows]=(size_t) length; offset+=(ssize_t) length; } q+=(iris_info.columns*4); } /* Write out line start and length tables and runlength-encoded pixels. */ for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) (void) WriteBlobMSBLong(image,(unsigned int) offsets[i]); for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) (void) WriteBlobMSBLong(image,(unsigned int) runlength[i]); (void) WriteBlob(image,number_packets,packets); /* Relinquish resources. */ runlength=(size_t *) RelinquishMagickMemory(runlength); packets=(unsigned char *) RelinquishMagickMemory(packets); offsets=(ssize_t *) RelinquishMagickMemory(offsets); break; } } iris_pixels=(unsigned char *) RelinquishMagickMemory(iris_pixels); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e H R Z I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteHRZImage() writes an image to a file in HRZ X image format. % % The format of the WriteHRZImage method is: % % MagickBooleanType WriteHRZImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteHRZImage(const ImageInfo *image_info,Image *image) { Image *hrz_image; MagickBooleanType status; register const PixelPacket *p; register ssize_t x, y; register unsigned char *q; ssize_t count; 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); hrz_image=ResizeImage(image,256,240,image->filter,image->blur, &image->exception); if (hrz_image == (Image *) NULL) return(MagickFalse); if (hrz_image->colorspace != RGBColorspace) (void) TransformImageColorspace(hrz_image,RGBColorspace); /* Allocate memory for pixels. */ pixels=(unsigned char *) AcquireQuantumMemory((size_t) hrz_image->columns, 3*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) { hrz_image=DestroyImage(hrz_image); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } /* Convert MIFF to HRZ raster pixels. */ for (y=0; y < (ssize_t) hrz_image->rows; y++) { p=GetVirtualPixels(hrz_image,0,y,hrz_image->columns,1,&image->exception); if (p == (PixelPacket *) NULL) break; q=pixels; for (x=0; x < (ssize_t) hrz_image->columns; x++) { *q++=ScaleQuantumToChar(GetRedPixelComponent(p))/4; *q++=ScaleQuantumToChar(GetGreenPixelComponent(p))/4; *q++=ScaleQuantumToChar(GetBluePixelComponent(p))/4; p++; } count=WriteBlob(image,(size_t) (q-pixels),pixels); if (count != (ssize_t) (q-pixels)) break; status=SetImageProgress(image,SaveImageTag,y,hrz_image->rows); if (status == MagickFalse) break; } pixels=(unsigned char *) RelinquishMagickMemory(pixels); hrz_image=DestroyImage(hrz_image); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e Y U V I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteYUVImage() writes an image to a file in the digital YUV % (CCIR 601 4:1:1, plane or partition interlaced, or 4:2:2 plane, partition % interlaced or noninterlaced) bytes and returns it. % % The format of the WriteYUVImage method is: % % MagickBooleanType WriteYUVImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteYUVImage(const ImageInfo *image_info,Image *image) { Image *chroma_image, *yuv_image; InterlaceType interlace; long horizontal_factor, vertical_factor, y; MagickBooleanType status; MagickOffsetType scene; register const PixelPacket *p, *s; register long x; unsigned long height, width; 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); interlace=image->interlace; horizontal_factor=2; vertical_factor=2; if (image_info->sampling_factor != (char *) NULL) { GeometryInfo geometry_info; MagickStatusType flags; flags=ParseGeometry(image_info->sampling_factor,&geometry_info); horizontal_factor=(long) geometry_info.rho; vertical_factor=(long) geometry_info.sigma; if ((flags & SigmaValue) == 0) vertical_factor=horizontal_factor; if ((horizontal_factor != 1) && (horizontal_factor != 2) && (vertical_factor != 1) && (vertical_factor != 2)) ThrowWriterException(CorruptImageError,"UnexpectedSamplingFactor"); } if ((interlace == UndefinedInterlace) || ((interlace == NoInterlace) && (vertical_factor == 2))) { interlace=NoInterlace; /* CCIR 4:2:2 */ if (vertical_factor == 2) interlace=PlaneInterlace; /* CCIR 4:1:1 */ } if (interlace != PartitionInterlace) { /* Open output image file. */ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); } else { AppendImageFormat("Y",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); } scene=0; do { /* Sample image to an even width and height, if necessary. */ image->depth=8; width=image->columns+(image->columns & (horizontal_factor-1)); height=image->rows+(image->rows & (vertical_factor-1)); yuv_image=ResizeImage(image,width,height,TriangleFilter,1.0, &image->exception); if (yuv_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,image->exception.reason); (void) TransformImageColorspace(yuv_image,YCbCrColorspace); /* Downsample image. */ chroma_image=ResizeImage(image,width/horizontal_factor, height/vertical_factor,TriangleFilter,1.0,&image->exception); if (chroma_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,image->exception.reason); (void) TransformImageColorspace(chroma_image,YCbCrColorspace); if (interlace == NoInterlace) { /* Write noninterlaced YUV. */ for (y=0; y < (long) yuv_image->rows; y++) { p=GetVirtualPixels(yuv_image,0,y,yuv_image->columns,1, &yuv_image->exception); if (p == (const PixelPacket *) NULL) break; s=GetVirtualPixels(chroma_image,0,y,chroma_image->columns,1, &chroma_image->exception); if (s == (const PixelPacket *) NULL) break; for (x=0; x < (long) yuv_image->columns; x++) { (void) WriteBlobByte(image,ScaleQuantumToChar(s->green)); (void) WriteBlobByte(image,ScaleQuantumToChar(GetRedPixelComponent(p))); p++; (void) WriteBlobByte(image,ScaleQuantumToChar(s->blue)); (void) WriteBlobByte(image,ScaleQuantumToChar(GetRedPixelComponent(p))); p++; s++; x++; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,y,image->rows); if (status == MagickFalse) break; } } yuv_image=DestroyImage(yuv_image); } else { /* Initialize Y channel. */ for (y=0; y < (long) yuv_image->rows; y++) { p=GetVirtualPixels(yuv_image,0,y,yuv_image->columns,1, &yuv_image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) yuv_image->columns; x++) { (void) WriteBlobByte(image,ScaleQuantumToChar(GetRedPixelComponent(p))); p++; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,y,image->rows); if (status == MagickFalse) break; } } yuv_image=DestroyImage(yuv_image); if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,1,3); if (status == MagickFalse) break; } /* Initialize U channel. */ if (interlace == PartitionInterlace) { (void) CloseBlob(image); AppendImageFormat("U",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == MagickFalse) return(status); } for (y=0; y < (long) chroma_image->rows; y++) { p=GetVirtualPixels(chroma_image,0,y,chroma_image->columns,1, &chroma_image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) chroma_image->columns; x++) { (void) WriteBlobByte(image,ScaleQuantumToChar(GetGreenPixelComponent(p))); p++; } } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,2,3); if (status == MagickFalse) break; } /* Initialize V channel. */ if (interlace == PartitionInterlace) { (void) CloseBlob(image); AppendImageFormat("V",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == MagickFalse) return(status); } for (y=0; y < (long) chroma_image->rows; y++) { p=GetVirtualPixels(chroma_image,0,y,chroma_image->columns,1, &chroma_image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) chroma_image->columns; x++) { (void) WriteBlobByte(image,ScaleQuantumToChar(GetBluePixelComponent(p))); p++; } } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,2,3); if (status == MagickFalse) break; } } chroma_image=DestroyImage(chroma_image); if (interlace == PartitionInterlace) (void) CopyMagickString(image->filename,image_info->filename, MaxTextExtent); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
static MagickBooleanType WritePCLImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent]; const char *option; long y; MagickBooleanType status; MagickOffsetType scene; register const IndexPacket *indexes; register const PixelPacket *p; register long i, x; register unsigned char *q; size_t length, packets; unsigned char bits_per_pixel, *compress_pixels, *pixels, *previous_pixels; unsigned long density; /* 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); density=75; if (image_info->density != (char *) NULL) { GeometryInfo geometry; (void) ParseGeometry(image_info->density,&geometry); density=(unsigned long) geometry.rho; } scene=0; do { if (image->colorspace != RGBColorspace) (void) TransformImageColorspace(image,RGBColorspace); /* Initialize the printer. */ (void) WriteBlobString(image,"\033E"); /* printer reset */ (void) WriteBlobString(image,"\033*r3F"); /* set presentation mode */ (void) FormatMagickString(buffer,MaxTextExtent,"\033*r%lus%luT", image->columns,image->rows); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"\033*t%ldR",density); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"\033&l0E"); /* top margin 0 */ if (IsMonochromeImage(image,&image->exception) != MagickFalse) { /* Monochrome image. */ bits_per_pixel=1; (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */ (void) WriteBlobByte(image,0); /* RGB */ (void) WriteBlobByte(image,1); /* indexed by pixel */ (void) WriteBlobByte(image,bits_per_pixel); /* bits per index */ (void) WriteBlobByte(image,8); /* bits per red component */ (void) WriteBlobByte(image,8); /* bits per green component */ (void) WriteBlobByte(image,8); /* bits per blue component */ (void) FormatMagickString(buffer,MaxTextExtent,"\033*v0a0b0c0I"); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"\033*v1a1b1c1I"); (void) WriteBlobString(image,buffer); } else if (image->storage_class == DirectClass) { /* DirectClass image. */ bits_per_pixel=24; (void) WriteBlobString(image,"\033*v6W"); /* set color mode */ (void) WriteBlobByte(image,0); /* RGB */ (void) WriteBlobByte(image,3); /* direct by pixel */ (void) WriteBlobByte(image,0); /* bits per index (ignored) */ (void) WriteBlobByte(image,8); /* bits per red component */ (void) WriteBlobByte(image,8); /* bits per green component */ (void) WriteBlobByte(image,8); /* bits per blue component */ } else { /* Colormapped image. */ bits_per_pixel=8; (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */ (void) WriteBlobByte(image,0); /* RGB */ (void) WriteBlobByte(image,1); /* indexed by pixel */ (void) WriteBlobByte(image,bits_per_pixel); /* bits per index */ (void) WriteBlobByte(image,8); /* bits per red component */ (void) WriteBlobByte(image,8); /* bits per green component */ (void) WriteBlobByte(image,8); /* bits per blue component */ for (i=0; i < (long) image->colors; i++) { (void) FormatMagickString(buffer,MaxTextExtent, "\033*v%da%db%dc%ldI",ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue),i); (void) WriteBlobString(image,buffer); } for ( ; i < (1L << bits_per_pixel); i++) { (void) FormatMagickString(buffer,MaxTextExtent,"\033*v%luI",i); (void) WriteBlobString(image,buffer); } } option=GetImageOption(image_info,"pcl:fit-to-page"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) (void) WriteBlobString(image,"\033*r3A"); else (void) WriteBlobString(image,"\033*r1A"); /* start raster graphics */ (void) WriteBlobString(image,"\033*b0Y"); /* set y offset */ length=(image->columns*bits_per_pixel+7)/8; pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); compress_pixels=(unsigned char *) NULL; previous_pixels=(unsigned char *) NULL; switch (image->compression) { case NoCompression: { (void) FormatMagickString(buffer,MaxTextExtent,"\033*b0M"); (void) WriteBlobString(image,buffer); break; } case RLECompression: { compress_pixels=(unsigned char *) AcquireQuantumMemory(length+256, sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) FormatMagickString(buffer,MaxTextExtent,"\033*b2M"); (void) WriteBlobString(image,buffer); break; } default: { compress_pixels=(unsigned char *) AcquireQuantumMemory(length+ (length >> 3),sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } previous_pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*previous_pixels)); if (previous_pixels == (unsigned char *) NULL) { compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) FormatMagickString(buffer,MaxTextExtent,"\033*b3M"); (void) WriteBlobString(image,buffer); break; } } for (y=0; y < (long) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); q=pixels; switch (bits_per_pixel) { case 1: { register unsigned char bit, byte; /* Monochrome image. */ bit=0; byte=0; for (x=0; x < (long) image->columns; x++) { byte<<=1; if (PixelIntensity(p) >= ((MagickRealType) QuantumRange/2.0)) byte|=0x01; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } p++; } if (bit != 0) *q++=byte << (8-bit); break; } case 8: { /* Colormapped image. */ for (x=0; x < (long) image->columns; x++) *q++=(unsigned char) indexes[x]; break; } case 24: case 32: { /* Truecolor image. */ for (x=0; x < (long) image->columns; x++) { *q++=ScaleQuantumToChar(GetRedPixelComponent(p)); *q++=ScaleQuantumToChar(GetGreenPixelComponent(p)); *q++=ScaleQuantumToChar(GetBluePixelComponent(p)); p++; } break; } } switch (image->compression) { case NoCompression: { (void) FormatMagickString(buffer,MaxTextExtent,"\033*b%luW", (unsigned long) length); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,length,pixels); break; } case RLECompression: { packets=PCLPackbitsCompressImage(length,pixels, compress_pixels); (void) FormatMagickString(buffer,MaxTextExtent,"\033*b%luW", (unsigned long) packets); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,packets,compress_pixels); break; } default: { if (y == 0) for (i=0; i < (long) length; i++) previous_pixels[i]=(~pixels[i]); packets=PCLDeltaCompressImage(length,previous_pixels,pixels, compress_pixels); (void) FormatMagickString(buffer,MaxTextExtent,"\033*b%luW", (unsigned long) packets); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,packets,compress_pixels); (void) CopyMagickMemory(previous_pixels,pixels,length* sizeof(*pixels)); break; } } } (void) WriteBlobString(image,"\033*rB"); /* end graphics */ switch (image->compression) { case NoCompression: break; case RLECompression: { compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); break; } default: { previous_pixels=(unsigned char *) RelinquishMagickMemory( previous_pixels); compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); 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; } while (image_info->adjoin != MagickFalse); (void) WriteBlobString(image,"\033E"); (void) CloseBlob(image); return(MagickTrue); }