/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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: % % MagickBooleanType WriteMATTEImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteMATTEImage(const ImageInfo *image_info, Image *image) { ExceptionInfo *exception; Image *matte_image; ssize_t y; MagickBooleanType status; register const PixelPacket *p; register ssize_t x; register PixelPacket *q; if (image->matte == MagickFalse) ThrowWriterException(CoderError,"ImageDoesNotHaveAAlphaChannel"); matte_image=CloneImage(image,image->columns,image->rows,MagickTrue, &image->exception); if (matte_image == (Image *) NULL) return(MagickFalse); (void) SetImageType(matte_image,TrueColorMatteType); matte_image->matte=MagickFalse; /* Convert image to matte pixels. */ exception=(&image->exception); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); q=QueueAuthenticPixels(matte_image,0,y,matte_image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { q->red=GetOpacityPixelComponent(p); q->green=GetOpacityPixelComponent(p); q->blue=GetOpacityPixelComponent(p); SetOpacityPixelComponent(q,OpaqueOpacity); p++; q++; } if (SyncAuthenticPixels(matte_image,exception) == MagickFalse) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } (void) FormatMagickString(matte_image->filename,MaxTextExtent, "MIFF:%s",image->filename); status=WriteImage(image_info,matte_image); matte_image=DestroyImage(matte_image); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d W E B P I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadWEBPImage() reads an image in the WebP image format. % % The format of the ReadWEBPImage method is: % % Image *ReadWEBPImage(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 *ReadWEBPImage(const ImageInfo *image_info, ExceptionInfo *exception) { int height, width; Image *image; MagickBooleanType status; register PixelPacket *q; register ssize_t x; register unsigned char *p; size_t length; ssize_t count, y; unsigned char *stream, *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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } length=(size_t) GetBlobSize(image); stream=(unsigned char *) AcquireQuantumMemory(length,sizeof(*stream)); if (stream == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,length,stream); if (count != (ssize_t) length) ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile"); pixels=(unsigned char *) WebPDecodeRGBA(stream,length,&width,&height); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); image->columns=(size_t) width; image->rows=(size_t) height; p=pixels; for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetRedPixelComponent(q,ScaleCharToQuantum(*p++)); SetGreenPixelComponent(q,ScaleCharToQuantum(*p++)); SetBluePixelComponent(q,ScaleCharToQuantum(*p++)); SetOpacityPixelComponent(q,(QuantumRange-ScaleCharToQuantum(*p++))); if (q->opacity != OpaqueOpacity) image->matte=MagickTrue; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } free(pixels); pixels=(unsigned char *) NULL; return(image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d M T V I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadMTVImage() reads a MTV image file 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 ReadMTVImage method is: % % Image *ReadMTVImage(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 *ReadMTVImage(const ImageInfo *image_info,ExceptionInfo *exception) { char buffer[MaxTextExtent]; Image *image; MagickBooleanType status; register ssize_t x; register PixelPacket *q; register unsigned char *p; ssize_t count, y; unsigned char *pixels; unsigned long columns, rows; /* 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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read MTV image. */ (void) ReadBlobString(image,buffer); count=(ssize_t) sscanf(buffer,"%lu %lu\n",&columns,&rows); if (count <= 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); do { /* Initialize image structure. */ image->columns=columns; image->rows=rows; image->depth=8; if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Convert MTV raster image to pixel packets. */ pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->columns, 3UL*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (y=0; y < (ssize_t) image->rows; y++) { count=(ssize_t) ReadBlob(image,(size_t) (3*image->columns),pixels); if (count != (ssize_t) (3*image->columns)) ThrowReaderException(CorruptImageError,"UnableToReadImageData"); p=pixels; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetRedPixelComponent(q,ScaleCharToQuantum(*p++)); SetGreenPixelComponent(q,ScaleCharToQuantum(*p++)); SetBluePixelComponent(q,ScaleCharToQuantum(*p++)); SetOpacityPixelComponent(q,OpaqueOpacity); q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (EOFBlob(image) != MagickFalse) { ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); break; } /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; *buffer='\0'; (void) ReadBlobString(image,buffer); count=(ssize_t) sscanf(buffer,"%lu %lu\n",&columns,&rows); if (count > 0) { /* 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; } } while (count > 0); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
MagickExport MagickBooleanType OpaquePaintImageChannel(Image *image, const ChannelType channel,const MagickPixelPacket *target, const MagickPixelPacket *fill,const MagickBooleanType invert) { #define OpaquePaintImageTag "Opaque/Image" CacheView *image_view; ExceptionInfo *exception; MagickBooleanType status; MagickOffsetType progress; MagickPixelPacket zero; ssize_t y; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(target != (MagickPixelPacket *) NULL); assert(fill != (MagickPixelPacket *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); if (SetImageStorageClass(image,DirectClass) == MagickFalse) return(MagickFalse); /* Make image color opaque. */ status=MagickTrue; progress=0; exception=(&image->exception); GetMagickPixelPacket(image,&zero); image_view=AcquireCacheView(image); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(dynamic,4) shared(progress,status) #endif for (y=0; y < (ssize_t) image->rows; y++) { MagickPixelPacket pixel; register IndexPacket *restrict indexes; register ssize_t x; register PixelPacket *restrict q; if (status == MagickFalse) continue; q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) { status=MagickFalse; continue; } indexes=GetCacheViewAuthenticIndexQueue(image_view); pixel=zero; for (x=0; x < (ssize_t) image->columns; x++) { SetMagickPixelPacket(image,q,indexes+x,&pixel); if (IsMagickColorSimilar(&pixel,target) != invert) { if ((channel & RedChannel) != 0) SetRedPixelComponent(q,ClampToQuantum(fill->red)); if ((channel & GreenChannel) != 0) SetGreenPixelComponent(q,ClampToQuantum(fill->green)); if ((channel & BlueChannel) != 0) SetBluePixelComponent(q,ClampToQuantum(fill->blue)); if ((channel & OpacityChannel) != 0) SetOpacityPixelComponent(q,ClampToQuantum(fill->opacity)); if (((channel & IndexChannel) != 0) && (image->colorspace == CMYKColorspace)) SetIndexPixelComponent(indexes+x,ClampToQuantum(fill->index)); } q++; } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_OpaquePaintImageChannel) #endif proceed=SetImageProgress(image,OpaquePaintImageTag,progress++, image->rows); if (proceed == MagickFalse) status=MagickFalse; } } image_view=DestroyCacheView(image_view); return(status); }
static Image *ReadCLIPBOARDImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; long y; register long x; register PixelPacket *q; 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); { HBITMAP bitmapH; HPALETTE hPal; OpenClipboard(NULL); bitmapH=(HBITMAP) GetClipboardData(CF_BITMAP); hPal=(HPALETTE) GetClipboardData(CF_PALETTE); CloseClipboard(); if ( bitmapH == NULL ) ThrowReaderException(CoderError,"NoBitmapOnClipboard"); { BITMAPINFO DIBinfo; BITMAP bitmap; HBITMAP hBitmap, hOldBitmap; HDC hDC, hMemDC; RGBQUAD *pBits, *ppBits; /* create an offscreen DC for the source */ hMemDC=CreateCompatibleDC(NULL); hOldBitmap=(HBITMAP) SelectObject(hMemDC,bitmapH); GetObject(bitmapH,sizeof(BITMAP),(LPSTR) &bitmap); if ((image->columns == 0) || (image->rows == 0)) { image->rows=bitmap.bmHeight; image->columns=bitmap.bmWidth; } /* Initialize the bitmap header info. */ (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO)); DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); DIBinfo.bmiHeader.biWidth=image->columns; DIBinfo.bmiHeader.biHeight=(-1)*image->rows; DIBinfo.bmiHeader.biPlanes=1; DIBinfo.bmiHeader.biBitCount=32; DIBinfo.bmiHeader.biCompression=BI_RGB; hDC=GetDC(NULL); if (hDC == 0) ThrowReaderException(CoderError,"UnableToCreateADC"); hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits, NULL,0); ReleaseDC(NULL,hDC); if (hBitmap == 0) ThrowReaderException(CoderError,"UnableToCreateBitmap"); /* create an offscreen DC */ hDC=CreateCompatibleDC(NULL); if (hDC == 0) { DeleteObject(hBitmap); ThrowReaderException(CoderError,"UnableToCreateADC"); } hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap); if (hOldBitmap == 0) { DeleteDC(hDC); DeleteObject(hBitmap); ThrowReaderException(CoderError,"UnableToCreateBitmap"); } if (hPal != NULL) { /* Kenichi Masuko says this needed */ SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); } /* bitblt from the memory to the DIB-based one */ BitBlt(hDC,0,0,image->columns,image->rows,hMemDC,0,0,SRCCOPY); /* finally copy the pixels! */ pBits=ppBits; for (y=0; y < (long) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { q->red=ScaleCharToQuantum(pBits->rgbRed); q->green=ScaleCharToQuantum(pBits->rgbGreen); q->blue=ScaleCharToQuantum(pBits->rgbBlue); SetOpacityPixelComponent(q,OpaqueOpacity); pBits++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } DeleteDC(hDC); DeleteObject(hBitmap); } } (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)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % F l o o d f i l l P a i n t I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FloodfillPaintImage() changes the color value of any pixel that matches % target and is an immediate neighbor. If the method FillToBorderMethod is % specified, the color value is changed for any neighbor pixel that does not % match the bordercolor member of image. % % By default target must match a particular pixel color exactly. % However, in many cases two colors may differ by a small amount. The % fuzz member of image defines how much tolerance is acceptable to % consider two colors as the same. For example, set fuzz to 10 and the % color red at intensities of 100 and 102 respectively are now % interpreted as the same color for the purposes of the floodfill. % % The format of the FloodfillPaintImage method is: % % MagickBooleanType FloodfillPaintImage(Image *image, % const ChannelType channel,const DrawInfo *draw_info, % const MagickPixelPacket target,const ssize_t x_offset, % const ssize_t y_offset,const MagickBooleanType invert) % % A description of each parameter follows: % % o image: the image. % % o channel: the channel(s). % % o draw_info: the draw info. % % o target: the RGB value of the target color. % % o x_offset,y_offset: the starting location of the operation. % % o invert: paint any pixel that does not match the target color. % */ MagickExport MagickBooleanType FloodfillPaintImage(Image *image, const ChannelType channel,const DrawInfo *draw_info, const MagickPixelPacket *target,const ssize_t x_offset,const ssize_t y_offset, const MagickBooleanType invert) { #define MaxStacksize (1UL << 15) #define PushSegmentStack(up,left,right,delta) \ { \ if (s >= (segment_stack+MaxStacksize)) \ ThrowBinaryException(DrawError,"SegmentStackOverflow",image->filename) \ else \ { \ if ((((up)+(delta)) >= 0) && (((up)+(delta)) < (ssize_t) image->rows)) \ { \ s->x1=(double) (left); \ s->y1=(double) (up); \ s->x2=(double) (right); \ s->y2=(double) (delta); \ s++; \ } \ } \ } CacheView *floodplane_view, *image_view; ExceptionInfo *exception; Image *floodplane_image; MagickBooleanType skip; MagickPixelPacket fill, pixel; PixelPacket fill_color; register SegmentInfo *s; SegmentInfo *segment_stack; ssize_t offset, start, x, x1, x2, y; /* Check boundary conditions. */ assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(draw_info != (DrawInfo *) NULL); assert(draw_info->signature == MagickSignature); if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns)) return(MagickFalse); if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows)) return(MagickFalse); if (SetImageStorageClass(image,DirectClass) == MagickFalse) return(MagickFalse); if (image->matte == MagickFalse) (void) SetImageAlphaChannel(image,OpaqueAlphaChannel); /* Set floodfill state. */ floodplane_image=CloneImage(image,0,0,MagickTrue,&image->exception); if (floodplane_image == (Image *) NULL) return(MagickFalse); (void) SetImageAlphaChannel(floodplane_image,OpaqueAlphaChannel); segment_stack=(SegmentInfo *) AcquireQuantumMemory(MaxStacksize, sizeof(*segment_stack)); if (segment_stack == (SegmentInfo *) NULL) { floodplane_image=DestroyImage(floodplane_image); ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", image->filename); } /* Push initial segment on stack. */ exception=(&image->exception); x=x_offset; y=y_offset; start=0; s=segment_stack; PushSegmentStack(y,x,x,1); PushSegmentStack(y+1,x,x,-1); GetMagickPixelPacket(image,&fill); GetMagickPixelPacket(image,&pixel); image_view=AcquireCacheView(image); floodplane_view=AcquireCacheView(floodplane_image); while (s > segment_stack) { register const IndexPacket *restrict indexes; register const PixelPacket *restrict p; register ssize_t x; register PixelPacket *restrict q; /* Pop segment off stack. */ s--; x1=(ssize_t) s->x1; x2=(ssize_t) s->x2; offset=(ssize_t) s->y2; y=(ssize_t) s->y1+offset; /* Recolor neighboring pixels. */ p=GetCacheViewVirtualPixels(image_view,0,y,(size_t) (x1+1),1,exception); q=GetCacheViewAuthenticPixels(floodplane_view,0,y,(size_t) (x1+1),1, exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetCacheViewVirtualIndexQueue(image_view); p+=x1; q+=x1; for (x=x1; x >= 0; x--) { if (q->opacity == (Quantum) TransparentOpacity) break; SetMagickPixelPacket(image,p,indexes+x,&pixel); if (IsMagickColorSimilar(&pixel,target) == invert) break; q->opacity=(Quantum) TransparentOpacity; p--; q--; } if (SyncCacheViewAuthenticPixels(floodplane_view,exception) == MagickFalse) break; skip=x >= x1 ? MagickTrue : MagickFalse; if (skip == MagickFalse) { start=x+1; if (start < x1) PushSegmentStack(y,start,x1-1,-offset); x=x1+1; } do { if (skip == MagickFalse) { if (x < (ssize_t) image->columns) { p=GetCacheViewVirtualPixels(image_view,x,y,image->columns-x,1, exception); q=GetCacheViewAuthenticPixels(floodplane_view,x,y, image->columns-x,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetCacheViewVirtualIndexQueue(image_view); for ( ; x < (ssize_t) image->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) break; SetMagickPixelPacket(image,p,indexes+x,&pixel); if (IsMagickColorSimilar(&pixel,target) == invert) break; q->opacity=(Quantum) TransparentOpacity; p++; q++; } if (SyncCacheViewAuthenticPixels(floodplane_view,exception) == MagickFalse) break; } PushSegmentStack(y,start,x-1,offset); if (x > (x2+1)) PushSegmentStack(y,x2+1,x-1,-offset); } skip=MagickFalse; x++; if (x <= x2) { p=GetCacheViewVirtualPixels(image_view,x,y,(size_t) (x2-x+1),1, exception); q=GetCacheViewAuthenticPixels(floodplane_view,x,y,(size_t) (x2-x+1),1, exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetCacheViewVirtualIndexQueue(image_view); for ( ; x <= x2; x++) { if (q->opacity == (Quantum) TransparentOpacity) break; SetMagickPixelPacket(image,p,indexes+x,&pixel); if (IsMagickColorSimilar(&pixel,target) != invert) break; p++; q++; } } start=x; } while (x <= x2); } for (y=0; y < (ssize_t) image->rows; y++) { register const PixelPacket *restrict p; register IndexPacket *restrict indexes; register ssize_t x; register PixelPacket *restrict q; /* Tile fill color onto floodplane. */ p=GetCacheViewVirtualPixels(floodplane_view,0,y,image->columns,1, exception); q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; indexes=GetCacheViewAuthenticIndexQueue(image_view); for (x=0; x < (ssize_t) image->columns; x++) { if (GetOpacityPixelComponent(p) != OpaqueOpacity) { (void) GetFillColor(draw_info,x,y,&fill_color); SetMagickPixelPacket(image,&fill_color,(IndexPacket *) NULL,&fill); if (image->colorspace == CMYKColorspace) ConvertRGBToCMYK(&fill); if ((channel & RedChannel) != 0) SetRedPixelComponent(q,ClampToQuantum(fill.red)); if ((channel & GreenChannel) != 0) SetGreenPixelComponent(q,ClampToQuantum(fill.green)); if ((channel & BlueChannel) != 0) SetBluePixelComponent(q,ClampToQuantum(fill.blue)); if ((channel & OpacityChannel) != 0) SetOpacityPixelComponent(q,ClampToQuantum(fill.opacity)); if (((channel & IndexChannel) != 0) && (image->colorspace == CMYKColorspace)) SetIndexPixelComponent(indexes+x,ClampToQuantum(fill.index)); } p++; q++; } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) break; } floodplane_view=DestroyCacheView(floodplane_view); image_view=DestroyCacheView(image_view); segment_stack=(SegmentInfo *) RelinquishMagickMemory(segment_stack); floodplane_image=DestroyImage(floodplane_image); return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse); }
static Image *ReadEMFImage(const ImageInfo *image_info, ExceptionInfo *exception) { BITMAPINFO DIBinfo; HBITMAP hBitmap, hOldBitmap; HDC hDC; HENHMETAFILE hemf; Image *image; ssize_t height, width, y; RECT rect; register ssize_t x; register PixelPacket *q; RGBQUAD *pBits, *ppBits; image=AcquireImage(image_info); hemf=ReadEnhMetaFile(image_info->filename,&width,&height); if (hemf == (HENHMETAFILE) NULL) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if ((image->columns == 0) || (image->rows == 0)) { double y_resolution, x_resolution; y_resolution=DefaultResolution; x_resolution=DefaultResolution; if (image->y_resolution > 0) { y_resolution=image->y_resolution; if (image->units == PixelsPerCentimeterResolution) y_resolution*=CENTIMETERS_INCH; } if (image->x_resolution > 0) { x_resolution=image->x_resolution; if (image->units == PixelsPerCentimeterResolution) x_resolution*=CENTIMETERS_INCH; } image->rows=(size_t) ((height/1000.0/CENTIMETERS_INCH)* y_resolution+0.5); image->columns=(size_t) ((width/1000.0/CENTIMETERS_INCH)* x_resolution+0.5); } if (image_info->size != (char *) NULL) { ssize_t x; image->columns=width; image->rows=height; x=0; y=0; (void) GetGeometry(image_info->size,&x,&y,&image->columns,&image->rows); } if (image_info->page != (char *) NULL) { char *geometry; ssize_t sans; register char *p; MagickStatusType flags; geometry=GetPageGeometry(image_info->page); p=strchr(geometry,'>'); if (p == (char *) NULL) { flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, &image->rows); if (image->x_resolution != 0.0) image->columns=(size_t) floor((image->columns* image->x_resolution)+0.5); if (image->y_resolution != 0.0) image->rows=(size_t) floor((image->rows*image->y_resolution)+ 0.5); } else { *p='\0'; flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, &image->rows); if (image->x_resolution != 0.0) image->columns=(size_t) floor(((image->columns* image->x_resolution)/DefaultResolution)+0.5); if (image->y_resolution != 0.0) image->rows=(size_t) floor(((image->rows* image->y_resolution)/DefaultResolution)+0.5); } geometry=DestroyString(geometry); } hDC=GetDC(NULL); if (hDC == (HDC) NULL) { DeleteEnhMetaFile(hemf); ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); } /* Initialize the bitmap header info. */ (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO)); DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); DIBinfo.bmiHeader.biWidth=(LONG) image->columns; DIBinfo.bmiHeader.biHeight=(-1)*(LONG) image->rows; DIBinfo.bmiHeader.biPlanes=1; DIBinfo.bmiHeader.biBitCount=32; DIBinfo.bmiHeader.biCompression=BI_RGB; hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits, NULL,0); ReleaseDC(NULL,hDC); if (hBitmap == (HBITMAP) NULL) { DeleteEnhMetaFile(hemf); ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); } hDC=CreateCompatibleDC(NULL); if (hDC == (HDC) NULL) { DeleteEnhMetaFile(hemf); DeleteObject(hBitmap); ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); } hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap); if (hOldBitmap == (HBITMAP) NULL) { DeleteEnhMetaFile(hemf); DeleteDC(hDC); DeleteObject(hBitmap); ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); } /* Initialize the bitmap to the image background color. */ pBits=ppBits; for (y=0; y < (ssize_t) image->rows; y++) { for (x=0; x < (ssize_t) image->columns; x++) { pBits->rgbRed=ScaleQuantumToChar(image->background_color.red); pBits->rgbGreen=ScaleQuantumToChar(image->background_color.green); pBits->rgbBlue=ScaleQuantumToChar(image->background_color.blue); pBits++; } } rect.top=0; rect.left=0; rect.right=(LONG) image->columns; rect.bottom=(LONG) image->rows; /* Convert metafile pixels. */ PlayEnhMetaFile(hDC,hemf,&rect); pBits=ppBits; for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { q->red=ScaleCharToQuantum(pBits->rgbRed); q->green=ScaleCharToQuantum(pBits->rgbGreen); q->blue=ScaleCharToQuantum(pBits->rgbBlue); SetOpacityPixelComponent(q,OpaqueOpacity); pBits++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } DeleteEnhMetaFile(hemf); SelectObject(hDC,hOldBitmap); DeleteDC(hDC); DeleteObject(hBitmap); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d H A L D I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadHALDImage() creates a Hald color lookup table image 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 ReadHALDImage method is: % % Image *ReadHALDImage(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 *ReadHALDImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; long y; MagickBooleanType status; size_t cube_size, level; CacheView *image_view; /* Create HALD color lookup table image. */ 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); level=0; if (*image_info->filename != '\0') level=StringToUnsignedLong(image_info->filename); if (level < 2) level=8; status=MagickTrue; cube_size=level*level; image->columns=(unsigned long) (level*cube_size); image->rows=(unsigned long) (level*cube_size); image_view=AcquireCacheView(image); #if defined(MAGICKCORE_OPENMP_SUPPORT) && (_OPENMP > 200505) #pragma omp parallel for shared(status) #endif for (y=0; y < (long) image->rows; y+=(long) level) { long blue, green, red; register PixelPacket *restrict q; if (status == MagickFalse) continue; q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns, (unsigned long) level,exception); if (q == (PixelPacket *) NULL) { status=MagickFalse; continue; } blue=y/(long) level; for (green=0; green < (long) cube_size; green++) { for (red=0; red < (long) cube_size; red++) { q->red=ClampToQuantum(QuantumRange*red/(cube_size-1.0)); q->green=ClampToQuantum(QuantumRange*green/(cube_size-1.0)); q->blue=ClampToQuantum(QuantumRange*blue/(cube_size-1.0)); SetOpacityPixelComponent(q,OpaqueOpacity); q++; } } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) status=MagickFalse; } image_view=DestroyCacheView(image_view); return(GetFirstImageInList(image)); }
static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; int bits, id, mask; MagickBooleanType status; MagickOffsetType offset, *page_table; PCXInfo pcx_info; register IndexPacket *indexes; register ssize_t x; register PixelPacket *q; register ssize_t i; register unsigned char *p, *r; size_t one, pcx_packets; ssize_t count, y; unsigned char packet, *pcx_colormap, *pcx_pixels, *scanline; /* 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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Determine if this a PCX file. */ page_table=(MagickOffsetType *) NULL; if (LocaleCompare(image_info->magick,"DCX") == 0) { size_t magic; /* Read the DCX page table. */ magic=ReadBlobLSBLong(image); if (magic != 987654321) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); page_table=(MagickOffsetType *) AcquireQuantumMemory(1024UL, sizeof(*page_table)); if (page_table == (MagickOffsetType *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (id=0; id < 1024; id++) { page_table[id]=(MagickOffsetType) ReadBlobLSBLong(image); if (page_table[id] == 0) break; } } if (page_table != (MagickOffsetType *) NULL) { offset=SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET); if (offset < 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); } pcx_colormap=(unsigned char *) NULL; count=ReadBlob(image,1,&pcx_info.identifier); for (id=1; id < 1024; id++) { /* Verify PCX identifier. */ pcx_info.version=(unsigned char) ReadBlobByte(image); if ((count == 0) || (pcx_info.identifier != 0x0a)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); pcx_info.encoding=(unsigned char) ReadBlobByte(image); pcx_info.bits_per_pixel=(unsigned char) ReadBlobByte(image); pcx_info.left=ReadBlobLSBShort(image); pcx_info.top=ReadBlobLSBShort(image); pcx_info.right=ReadBlobLSBShort(image); pcx_info.bottom=ReadBlobLSBShort(image); pcx_info.horizontal_resolution=ReadBlobLSBShort(image); pcx_info.vertical_resolution=ReadBlobLSBShort(image); /* Read PCX raster colormap. */ image->columns=(size_t) MagickAbsoluteValue((ssize_t) pcx_info.right- pcx_info.left)+1UL; image->rows=(size_t) MagickAbsoluteValue((ssize_t) pcx_info.bottom- pcx_info.top)+1UL; if ((image->columns == 0) || (image->rows == 0) || (pcx_info.bits_per_pixel == 0)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); image->depth=pcx_info.bits_per_pixel <= 8 ? 8U : MAGICKCORE_QUANTUM_DEPTH; image->units=PixelsPerInchResolution; image->x_resolution=(double) pcx_info.horizontal_resolution; image->y_resolution=(double) pcx_info.vertical_resolution; image->colors=16; pcx_colormap=(unsigned char *) AcquireQuantumMemory(256UL, 3*sizeof(*pcx_colormap)); if (pcx_colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,3*image->colors,pcx_colormap); pcx_info.reserved=(unsigned char) ReadBlobByte(image); pcx_info.planes=(unsigned char) ReadBlobByte(image); one=1; if ((pcx_info.bits_per_pixel != 8) || (pcx_info.planes == 1)) if ((pcx_info.version == 3) || (pcx_info.version == 5) || ((pcx_info.bits_per_pixel*pcx_info.planes) == 1)) image->colors=(size_t) MagickMin(one << (1UL* (pcx_info.bits_per_pixel*pcx_info.planes)),256UL); if (AcquireImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1)) image->storage_class=DirectClass; p=pcx_colormap; for (i=0; i < (ssize_t) image->colors; i++) { image->colormap[i].red=ScaleCharToQuantum(*p++); image->colormap[i].green=ScaleCharToQuantum(*p++); image->colormap[i].blue=ScaleCharToQuantum(*p++); } pcx_info.bytes_per_line=ReadBlobLSBShort(image); pcx_info.palette_info=ReadBlobLSBShort(image); for (i=0; i < 58; i++) (void) ReadBlobByte(image); if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Read image data. */ pcx_packets=(size_t) image->rows*pcx_info.bytes_per_line* pcx_info.planes; pcx_pixels=(unsigned char *) AcquireQuantumMemory(pcx_packets, sizeof(*pcx_pixels)); scanline=(unsigned char *) AcquireQuantumMemory(MagickMax(image->columns, pcx_info.bytes_per_line),MagickMax(8,pcx_info.planes)*sizeof(*scanline)); if ((pcx_pixels == (unsigned char *) NULL) || (scanline == (unsigned char *) NULL)) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); /* Uncompress image data. */ p=pcx_pixels; if (pcx_info.encoding == 0) while (pcx_packets != 0) { packet=(unsigned char) ReadBlobByte(image); if (EOFBlob(image) != MagickFalse) break; *p++=packet; pcx_packets--; } else while (pcx_packets != 0) { packet=(unsigned char) ReadBlobByte(image); if (EOFBlob(image) != MagickFalse) break; if ((packet & 0xc0) != 0xc0) { *p++=packet; pcx_packets--; continue; } count=(ssize_t) (packet & 0x3f); packet=(unsigned char) ReadBlobByte(image); if (EOFBlob(image) != MagickFalse) break; for ( ; count != 0; count--) { *p++=packet; pcx_packets--; if (pcx_packets == 0) break; } } if (image->storage_class == DirectClass) image->matte=pcx_info.planes > 3 ? MagickTrue : MagickFalse; else if ((pcx_info.version == 5) || ((pcx_info.bits_per_pixel*pcx_info.planes) == 1)) { /* Initialize image colormap. */ if (image->colors > 256) ThrowReaderException(CorruptImageError,"ColormapExceeds256Colors"); if ((pcx_info.bits_per_pixel*pcx_info.planes) == 1) { /* Monochrome colormap. */ image->colormap[0].red=(Quantum) 0; image->colormap[0].green=(Quantum) 0; image->colormap[0].blue=(Quantum) 0; image->colormap[1].red=(Quantum) QuantumRange; image->colormap[1].green=(Quantum) QuantumRange; image->colormap[1].blue=(Quantum) QuantumRange; } else if (image->colors > 16) { /* 256 color images have their color map at the end of the file. */ pcx_info.colormap_signature=(unsigned char) ReadBlobByte(image); count=ReadBlob(image,3*image->colors,pcx_colormap); p=pcx_colormap; for (i=0; i < (ssize_t) image->colors; i++) { image->colormap[i].red=ScaleCharToQuantum(*p++); image->colormap[i].green=ScaleCharToQuantum(*p++); image->colormap[i].blue=ScaleCharToQuantum(*p++); } } pcx_colormap=(unsigned char *) RelinquishMagickMemory(pcx_colormap); } /* Convert PCX raster image to pixel packets. */ for (y=0; y < (ssize_t) image->rows; y++) { p=pcx_pixels+(y*pcx_info.bytes_per_line*pcx_info.planes); q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); r=scanline; if (image->storage_class == DirectClass) for (i=0; i < pcx_info.planes; i++) { r=scanline+i; for (x=0; x < (ssize_t) pcx_info.bytes_per_line; x++) { switch (i) { case 0: { *r=(*p++); break; } case 1: { *r=(*p++); break; } case 2: { *r=(*p++); break; } case 3: default: { *r=(*p++); break; } } r+=pcx_info.planes; } } else if (pcx_info.planes > 1) { for (x=0; x < (ssize_t) image->columns; x++) *r++=0; for (i=0; i < pcx_info.planes; i++) { r=scanline; for (x=0; x < (ssize_t) pcx_info.bytes_per_line; x++) { bits=(*p++); for (mask=0x80; mask != 0; mask>>=1) { if (bits & mask) *r|=1 << i; r++; } } } } else switch (pcx_info.bits_per_pixel) { case 1: { register ssize_t bit; for (x=0; x < ((ssize_t) image->columns-7); x+=8) { for (bit=7; bit >= 0; bit--) *r++=(unsigned char) ((*p) & (0x01 << bit) ? 0x01 : 0x00); p++; } if ((image->columns % 8) != 0) { for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--) *r++=(unsigned char) ((*p) & (0x01 << bit) ? 0x01 : 0x00); p++; } break; } case 2: { for (x=0; x < ((ssize_t) image->columns-3); x+=4) { *r++=(*p >> 6) & 0x3; *r++=(*p >> 4) & 0x3; *r++=(*p >> 2) & 0x3; *r++=(*p) & 0x3; p++; } if ((image->columns % 4) != 0) { for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--) *r++=(unsigned char) ((*p >> (i*2)) & 0x03); p++; } break; } case 4: { for (x=0; x < ((ssize_t) image->columns-1); x+=2) { *r++=(*p >> 4) & 0xf; *r++=(*p) & 0xf; p++; } if ((image->columns % 2) != 0) *r++=(*p++ >> 4) & 0xf; break; } case 8: { (void) CopyMagickMemory(r,p,image->columns); break; } default: break; } /* Transfer image scanline. */ r=scanline; for (x=0; x < (ssize_t) image->columns; x++) { if (image->storage_class == PseudoClass) SetIndexPixelComponent(indexes+x,*r++); else { SetRedPixelComponent(q,ScaleCharToQuantum(*r++)); SetGreenPixelComponent(q,ScaleCharToQuantum(*r++)); SetBluePixelComponent(q,ScaleCharToQuantum(*r++)); if (image->matte != MagickFalse) SetOpacityPixelComponent(q,QuantumRange-ScaleCharToQuantum(*r++)); } q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } if (image->storage_class == PseudoClass) (void) SyncImage(image); scanline=(unsigned char *) RelinquishMagickMemory(scanline); if (pcx_colormap != (unsigned char *) NULL) pcx_colormap=(unsigned char *) RelinquishMagickMemory(pcx_colormap); pcx_pixels=(unsigned char *) RelinquishMagickMemory(pcx_pixels); if (EOFBlob(image) != MagickFalse) { ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); break; } /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (page_table == (MagickOffsetType *) NULL) break; if (page_table[id] == 0) break; offset=SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET); if (offset < 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); count=ReadBlob(image,1,&pcx_info.identifier); if ((count != 0) && (pcx_info.identifier == 0x0a)) { /* 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; } }
static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; MagickBooleanType status; MagickSizeType number_pixels; register IndexPacket *indexes; register PixelPacket *q; register ssize_t i, x; register unsigned char *p; SGIInfo iris_info; size_t bytes_per_pixel, quantum; ssize_t count, y, z; unsigned char *iris_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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read SGI raster header. */ iris_info.magic=ReadBlobMSBShort(image); do { /* Verify SGI identifier. */ if (iris_info.magic != 0x01DA) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); iris_info.storage=(unsigned char) ReadBlobByte(image); switch (iris_info.storage) { case 0x00: image->compression=NoCompression; break; case 0x01: image->compression=RLECompression; break; default: ThrowReaderException(CorruptImageError,"ImproperImageHeader"); } iris_info.bytes_per_pixel=(unsigned char) ReadBlobByte(image); if ((iris_info.bytes_per_pixel == 0) || (iris_info.bytes_per_pixel > 2)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); iris_info.dimension=ReadBlobMSBShort(image); iris_info.columns=ReadBlobMSBShort(image); iris_info.rows=ReadBlobMSBShort(image); iris_info.depth=ReadBlobMSBShort(image); if ((iris_info.depth == 0) || (iris_info.depth > 4)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); iris_info.minimum_value=ReadBlobMSBLong(image); iris_info.maximum_value=ReadBlobMSBLong(image); iris_info.sans=ReadBlobMSBLong(image); (void) ReadBlob(image,sizeof(iris_info.name),(unsigned char *) iris_info.name); iris_info.name[sizeof(iris_info.name)-1]='\0'; if (*iris_info.name != '\0') (void) SetImageProperty(image,"label",iris_info.name); iris_info.pixel_format=ReadBlobMSBLong(image); if (iris_info.pixel_format != 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); count=ReadBlob(image,sizeof(iris_info.filler),iris_info.filler); image->columns=iris_info.columns; image->rows=iris_info.rows; image->depth=(size_t) MagickMin(iris_info.depth,MAGICKCORE_QUANTUM_DEPTH); if (iris_info.pixel_format == 0) image->depth=(size_t) MagickMin((size_t) 8* iris_info.bytes_per_pixel,MAGICKCORE_QUANTUM_DEPTH); if (iris_info.depth < 3) { image->storage_class=PseudoClass; image->colors=iris_info.bytes_per_pixel > 1 ? 65535 : 256; } if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Allocate SGI pixels. */ bytes_per_pixel=(size_t) iris_info.bytes_per_pixel; number_pixels=(MagickSizeType) iris_info.columns*iris_info.rows; if ((4*bytes_per_pixel*number_pixels) != ((MagickSizeType) (size_t) (4*bytes_per_pixel*number_pixels))) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); iris_pixels=(unsigned char *) AcquireQuantumMemory(iris_info.columns, iris_info.rows*4*bytes_per_pixel*sizeof(*iris_pixels)); if (iris_pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if ((int) iris_info.storage != 0x01) { unsigned char *scanline; /* Read standard image format. */ scanline=(unsigned char *) AcquireQuantumMemory(iris_info.columns, bytes_per_pixel*sizeof(*scanline)); if (scanline == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (z=0; z < (ssize_t) iris_info.depth; z++) { p=iris_pixels+bytes_per_pixel*z; for (y=0; y < (ssize_t) iris_info.rows; y++) { count=ReadBlob(image,bytes_per_pixel*iris_info.columns,scanline); if (EOFBlob(image) != MagickFalse) break; if (bytes_per_pixel == 2) for (x=0; x < (ssize_t) iris_info.columns; x++) { *p=scanline[2*x]; *(p+1)=scanline[2*x+1]; p+=8; } else for (x=0; x < (ssize_t) iris_info.columns; x++) { *p=scanline[x]; p+=4; } } } scanline=(unsigned char *) RelinquishMagickMemory(scanline); } else { size_t *runlength; ssize_t offset, *offsets; unsigned char *packets; unsigned int data_order; /* Read runlength-encoded image format. */ offsets=(ssize_t *) AcquireQuantumMemory((size_t) iris_info.rows, iris_info.depth*sizeof(*offsets)); packets=(unsigned char *) AcquireQuantumMemory((size_t) iris_info.columns+10UL,4UL*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)) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) offsets[i]=(int) ReadBlobMSBLong(image); for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) { runlength[i]=ReadBlobMSBLong(image); if (runlength[i] > (4*(size_t) iris_info.columns+10)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); } /* Check data order. */ offset=0; data_order=0; for (y=0; ((y < (ssize_t) iris_info.rows) && (data_order == 0)); y++) for (z=0; ((z < (ssize_t) iris_info.depth) && (data_order == 0)); z++) { if (offsets[y+z*iris_info.rows] < offset) data_order=1; offset=offsets[y+z*iris_info.rows]; } offset=(ssize_t) TellBlob(image); if (data_order == 1) { for (z=0; z < (ssize_t) iris_info.depth; z++) { p=iris_pixels; for (y=0; y < (ssize_t) iris_info.rows; y++) { if (offset != offsets[y+z*iris_info.rows]) { offset=offsets[y+z*iris_info.rows]; offset=(ssize_t) SeekBlob(image,(ssize_t) offset,SEEK_SET); } count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows], packets); if (EOFBlob(image) != MagickFalse) break; offset+=(ssize_t) runlength[y+z*iris_info.rows]; status=SGIDecode(bytes_per_pixel,(ssize_t) (runlength[y+z*iris_info.rows]/bytes_per_pixel),packets, 1L*iris_info.columns,p+bytes_per_pixel*z); if (status == MagickFalse) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); p+=(iris_info.columns*4*bytes_per_pixel); } } } else { MagickOffsetType position; position=TellBlob(image); p=iris_pixels; for (y=0; y < (ssize_t) iris_info.rows; y++) { for (z=0; z < (ssize_t) iris_info.depth; z++) { if (offset != offsets[y+z*iris_info.rows]) { offset=offsets[y+z*iris_info.rows]; offset=(ssize_t) SeekBlob(image,(ssize_t) offset,SEEK_SET); } count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows], packets); if (EOFBlob(image) != MagickFalse) break; offset+=(ssize_t) runlength[y+z*iris_info.rows]; status=SGIDecode(bytes_per_pixel,(ssize_t) (runlength[y+z*iris_info.rows]/bytes_per_pixel),packets, 1L*iris_info.columns,p+bytes_per_pixel*z); if (status == MagickFalse) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); } p+=(iris_info.columns*4*bytes_per_pixel); } offset=(ssize_t) SeekBlob(image,position,SEEK_SET); } runlength=(size_t *) RelinquishMagickMemory(runlength); packets=(unsigned char *) RelinquishMagickMemory(packets); offsets=(ssize_t *) RelinquishMagickMemory(offsets); } /* Initialize image structure. */ image->matte=iris_info.depth == 4 ? MagickTrue : MagickFalse; image->columns=iris_info.columns; image->rows=iris_info.rows; /* Convert SGI raster image to pixel packets. */ if (image->storage_class == DirectClass) { /* Convert SGI image to DirectClass pixel packets. */ if (bytes_per_pixel == 2) { for (y=0; y < (ssize_t) image->rows; y++) { p=iris_pixels+(image->rows-y-1)*8*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { q->red=ScaleShortToQuantum((unsigned short) ((*(p+0) << 8) | (*(p+1)))); q->green=ScaleShortToQuantum((unsigned short) ((*(p+2) << 8) | (*(p+3)))); q->blue=ScaleShortToQuantum((unsigned short) ((*(p+4) << 8) | (*(p+5)))); SetOpacityPixelComponent(q,OpaqueOpacity); if (image->matte != MagickFalse) q->opacity=(Quantum) (QuantumRange-ScaleShortToQuantum( (unsigned short) ((*(p+6) << 8) | (*(p+7))))); p+=8; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,image->rows); if (status == MagickFalse) break; } } } else for (y=0; y < (ssize_t) image->rows; y++) { p=iris_pixels+(image->rows-y-1)*4*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { q->red=ScaleCharToQuantum(*p); q->green=ScaleCharToQuantum(*(p+1)); q->blue=ScaleCharToQuantum(*(p+2)); SetOpacityPixelComponent(q,OpaqueOpacity); if (image->matte != MagickFalse) q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*(p+3))); p+=4; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } } else { /* Create grayscale map. */ if (AcquireImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert SGI image to PseudoClass pixel packets. */ if (bytes_per_pixel == 2) { for (y=0; y < (ssize_t) image->rows; y++) { p=iris_pixels+(image->rows-y-1)*8*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { quantum=(*p << 8); quantum|=(*(p+1)); indexes[x]=(IndexPacket) quantum; p+=8; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,image->rows); if (status == MagickFalse) break; } } } else for (y=0; y < (ssize_t) image->rows; y++) { p=iris_pixels+(image->rows-y-1)*4*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { indexes[x]=(IndexPacket) (*p); p+=4; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } (void) SyncImage(image); } iris_pixels=(unsigned char *) RelinquishMagickMemory(iris_pixels); if (EOFBlob(image) != MagickFalse) { ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); break; } /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; iris_info.magic=ReadBlobMSBShort(image); if (iris_info.magic == 0x01DA) { /* 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; } } while (iris_info.magic == 0x01DA); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d H R Z I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadHRZImage() reads a Slow Scan TeleVision image file 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 ReadHRZImage method is: % % Image *ReadHRZImage(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 *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; ssize_t y; MagickBooleanType status; register ssize_t x; register PixelPacket *q; register unsigned char *p; 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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Convert HRZ raster image to pixel packets. */ image->columns=256; image->rows=240; image->depth=8; pixels=(unsigned char *) AcquireQuantumMemory(image->columns, 3*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); length=(size_t) (3*image->columns); for (y=0; y < (ssize_t) image->rows; y++) { count=ReadBlob(image,length,pixels); if ((size_t) count != length) ThrowReaderException(CorruptImageError,"UnableToReadImageData"); p=pixels; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { q->red=4*ScaleCharToQuantum(*p++); q->green=4*ScaleCharToQuantum(*p++); q->blue=4*ScaleCharToQuantum(*p++); SetOpacityPixelComponent(q,OpaqueOpacity); q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse) break; } pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (EOFBlob(image) != MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); (void) CloseBlob(image); return(GetFirstImageInList(image)); }