bool ScImgDataLoader_GMagick::readCMYK(Image *input, RawImage *output, int width, int height) { /* Mapping: red: cyan green: magenta blue: yellow opacity: black index: alpha */ //Copied from GraphicsMagick header and modified #define GetCyanSample(p) (p.red) #define GetMagentaSample(p) (p.green) #define GetYellowSample(p) (p.blue) #define GetCMYKBlackSample(p) (p.opacity) #define GetAlphaSample(p) (p) bool hasAlpha = input->matte; if (!output->create(width, height, hasAlpha ? 5 : 4)) return false; ExceptionInfo exception; GetExceptionInfo(&exception); const PixelPacket *pixels = AcquireImagePixels(input, 0, 0, width, height, &exception); if (exception.severity != UndefinedException) CatchException(&exception); if (!pixels) { qCritical() << QObject::tr("Could not get pixel data!"); return false; } const IndexPacket *alpha = 0; if (hasAlpha) { alpha = AccessImmutableIndexes(input); if (!alpha) { qCritical() << QObject::tr("Could not get alpha channel data!"); return false; } } unsigned char *buffer = output->bits(); if (!buffer) { qCritical() << QObject::tr("Could not allocate output buffer!"); return false; } int i; for (i = 0; i < width*height; i++) { *buffer++ = ScaleQuantumToChar(GetCyanSample(pixels[i])); *buffer++ = ScaleQuantumToChar(GetMagentaSample(pixels[i])); *buffer++ = ScaleQuantumToChar(GetYellowSample(pixels[i])); *buffer++ = ScaleQuantumToChar(GetCMYKBlackSample(pixels[i])); if (hasAlpha) { *buffer++ = 255 - ScaleQuantumToChar(GetAlphaSample(alpha[i])); } } return true; }
static inline void WriteVIPSPixel(Image *image, const Quantum value) { if (image->depth == 16) (void) WriteBlobShort(image,ScaleQuantumToShort(value)); else (void) WriteBlobByte(image,ScaleQuantumToChar(value)); }
/** * flogo_convert_image: Converts a single ImageMagick RGB image into a format * usable by transcode. * * Parameters: tcvhandle: Opaque libtcvideo handle * src: An ImageMagick handle (the source image) * dst: A pointer to the output buffer * ifmt: The output format (see aclib/imgconvert.h) * do_rgbswap: zero for no swap, nonzero to swap red and blue * pixel positions * Return value: 1 on success, 0 on failure * Preconditions: tcvhandle != null, was returned by a call to tcv_init() * src is a valid ImageMagick RGB image handle * dst buffer is large enough to hold the result of the * requested conversion * Postconditions: dst get overwritten with the result of the conversion */ static int flogo_convert_image(TCVHandle tcvhandle, Image *src, uint8_t *dst, ImageFormat ifmt, int do_rgbswap) { PixelPacket *pixel_packet; uint8_t *dst_ptr = dst; int row, col; int height = src->rows; int width = src->columns; int ret; unsigned long r_off, g_off, b_off; if (!do_rgbswap) { r_off = 0; b_off = 2; } else { r_off = 2; b_off = 0; } g_off = 1; pixel_packet = GetImagePixels(src, 0, 0, width, height); for (row = 0; row < height; row++) { for (col = 0; col < width; col++) { *(dst_ptr + r_off) = (uint8_t)ScaleQuantumToChar(pixel_packet->red); *(dst_ptr + g_off) = (uint8_t)ScaleQuantumToChar(pixel_packet->green); *(dst_ptr + b_off) = (uint8_t)ScaleQuantumToChar(pixel_packet->blue); dst_ptr += 3; pixel_packet++; } } ret = tcv_convert(tcvhandle, dst, dst, width, height, IMG_RGB24, ifmt); if (ret == 0) { tc_log_error(MOD_NAME, "RGB->YUV conversion failed"); return 0; } return 1; }
INLINE int aprox_image_pixels(const Image *image, GifColorType *colors, int color_count, PixelCache *cache, GifPixelType *out) { int width = image->columns; int height = image->rows; ExceptionInfo ex; int ii; int jj; register const PixelPacket *p = ACQUIRE_IMAGE_PIXELS(image, 0, 0, width, height, &ex); if (!p) { return 0; } int end = width * height; for (ii = 0; ii < end; ii++, p++) { GifByteType r = ScaleQuantumToChar(p->red); GifByteType g = ScaleQuantumToChar(p->green); GifByteType b = ScaleQuantumToChar(p->blue); uint32_t key = (r << 16) + (g << 8) + b; if (!pixel_cache_get(cache, key, &out[ii])) { int min_delta = 3 * (NCOLORS * NCOLORS); int min_pos = 0; GifColorType *c = colors; for (jj = 0; jj < color_count; jj++, c++) { int rd = c->Red - r; int gd = c->Green - g; int bd = c->Blue - b; int delta = (rd * rd) + (gd * gd) + (bd * bd); if (delta < min_delta) { min_delta = delta; min_pos = jj; if (min_delta == 0) { break; } } } out[ii] = min_pos; pixel_cache_set(cache, key, min_pos); } } return 1; }
void calculate_image_histogram_in_rect(const Image *image, const RectangleInfo *rect, unsigned int histogram[], int o) { register long y; register long x; register const PixelPacket *p; ExceptionInfo ex; long sx; long sy; unsigned int width; unsigned int height; if (o > 0) { memset(histogram, 0, sizeof(unsigned int) * HISTOGRAM_SIZE); } if (rect && rect->width > 0 && rect->height > 0) { sx = rect->x; sy = rect->y; width = rect->width; height = rect->height; } else { sx = 0; sy = 0; width = image->columns; height = image->rows; } unsigned int ey = sy + height; int total = 0; for(y = sy; y < ey; ++y) { p = ACQUIRE_IMAGE_PIXELS(image, sx, y, width, 1, &ex); if (!p) { continue; } total += width; for (x=0; x < width; x++, p++) { histogram[ScaleQuantumToChar(p->red)] += o; histogram[ScaleQuantumToChar(p->green) + 256] += o; histogram[ScaleQuantumToChar(p->blue) + 512] += o; } } }
INLINE int acquire_image_pixels(const Image *image, GifByteType *red, GifByteType *green, GifByteType *blue) { register long y; register long x; register const PixelPacket *p; ExceptionInfo ex; int width = image->columns; int height = image->rows; int ii = 0; for(y = 0; y < height; ++y) { p = ACQUIRE_IMAGE_PIXELS(image, 0, y, width, 1, &ex); if (!p) { return 0; } for (x = 0; x < width; x++, ii++, p++) { red[ii] = ScaleQuantumToChar(p->red); green[ii] = ScaleQuantumToChar(p->green); blue[ii] = ScaleQuantumToChar(p->blue); } } return 1; }
static int render_logo_rgb(LogoPrivateData *pd, const WorkItem *W, TCFrameVideo *frame) { int row, col; unsigned long r_off = 0, g_off = 1, b_off = 2; float img_coeff, vid_coeff; /* Note: GraphicsMagick defines opacity = 0 as fully visible, and * opacity = MaxRGB as fully transparent. */ Quantum opacity; uint8_t *video_buf = NULL; PixelPacket *pixels = GetImagePixels(pd->images, 0, 0, pd->images->columns, pd->images->rows); if (pd->rgbswap) { r_off = 2; b_off = 0; } for (row = 0; row < pd->magick.image->rows; row++) { video_buf = frame->video_buf + 3 * ((row + pd->posy) * pd->vob->ex_v_width + pd->posx); for (col = 0; col < pd->magick.image->columns; col++) { opacity = pixels->opacity; if (W->do_fade) opacity += (Quantum)((MaxRGB - opacity) * W->fade_coeff); if (opacity == 0) { *(video_buf + r_off) = ScaleQuantumToChar(pixels->red); *(video_buf + g_off) = ScaleQuantumToChar(pixels->green); *(video_buf + b_off) = ScaleQuantumToChar(pixels->blue); } else if (opacity < MaxRGB) { uint8_t opacity_byte = ScaleQuantumToChar(opacity); img_coeff = pd->img_coeff_lookup[opacity_byte]; vid_coeff = pd->vid_coeff_lookup[opacity_byte]; *(video_buf + r_off) = (uint8_t)((*(video_buf + r_off)) * vid_coeff) + (uint8_t)(ScaleQuantumToChar(pixels->red) * img_coeff); *(video_buf + g_off) = (uint8_t)((*(video_buf + g_off)) * vid_coeff) + (uint8_t)(ScaleQuantumToChar(pixels->green) * img_coeff); *(video_buf + b_off) = (uint8_t)((*(video_buf + b_off)) * vid_coeff) + (uint8_t)(ScaleQuantumToChar(pixels->blue) * img_coeff); } video_buf += 3; pixels++; } } return TC_OK; }
bool ScImgDataLoader_GMagick::readRGB(Image *input, QImage *output, int width, int height) { bool hasAlpha = input->matte; ExceptionInfo exception; GetExceptionInfo(&exception); const PixelPacket *pixels = AcquireImagePixels(input, 0, 0, width, height, &exception); if (exception.severity != UndefinedException) CatchException(&exception); if (!pixels) { qCritical() << QObject::tr("Could not get pixel data!"); return false; } unsigned char *buffer = output->bits(); if (!buffer) { qCritical() << QObject::tr("Could not allocate output buffer!"); return false; } QRgb *s = (QRgb*)(output->scanLine(0)); int i; for (i = 0; i < width*height; i++) { unsigned char b = ScaleQuantumToChar(pixels[i].blue); unsigned char g = ScaleQuantumToChar(pixels[i].green); unsigned char r = ScaleQuantumToChar(pixels[i].red); unsigned char a; if (hasAlpha) a = 255 - ScaleQuantumToChar(pixels[i].opacity); else a = 255; *s = qRgba(r, g, b, a); s++; } return true; }
static MagickBooleanType recolor(WandView *view, const ssize_t y, const int id, void *context){ RectangleInfo extent; MagickPixelPacket pixel; PixelWand **pixels; register ssize_t x; register float t; extent = GetWandViewExtent(view); pixels = GetWandViewPixels(view); for (x = 0; x < (ssize_t) (extent.width - extent.x); x++){ PixelGetMagickColor(pixels[x], &pixel); t = ScaleQuantumToChar(pixel.red); pixel.red = get_color(t, 0); pixel.green = get_color(t, 1); pixel.blue = get_color(t, 2); PixelSetMagickColor(pixels[x], &pixel); } return(MagickTrue); }
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 S I X E L I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteSIXELImage() writes an image to a file in the X pixmap format. % % The format of the WriteSIXELImage method is: % % MagickBooleanType WriteSIXELImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteSIXELImage(const ImageInfo *image_info,Image *image) { ExceptionInfo *exception; MagickBooleanType status; register const IndexPacket *indexes; register ssize_t i, x; ssize_t opacity, y; sixel_output_t *output; unsigned char sixel_palette[256 * 3], *sixel_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); exception=(&image->exception); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace); opacity=(-1); if (image->matte == MagickFalse) { if ((image->storage_class == DirectClass) || (image->colors > 256)) (void) SetImageType(image,PaletteType); } else { MagickRealType alpha, beta; /* Identify transparent colormap index. */ if ((image->storage_class == DirectClass) || (image->colors > 256)) (void) SetImageType(image,PaletteBilevelMatteType); for (i=0; i < (ssize_t) image->colors; i++) if (image->colormap[i].opacity != OpaqueOpacity) { if (opacity < 0) { opacity=i; continue; } alpha=(MagickRealType) image->colormap[i].opacity; beta=(MagickRealType) image->colormap[opacity].opacity; if (alpha > beta) opacity=i; } if (opacity == -1) { (void) SetImageType(image,PaletteBilevelMatteType); for (i=0; i < (ssize_t) image->colors; i++) if (image->colormap[i].opacity != OpaqueOpacity) { if (opacity < 0) { opacity=i; continue; } alpha=(MagickRealType) image->colormap[i].opacity; beta=(MagickRealType) image->colormap[opacity].opacity; if (alpha > beta) opacity=i; } } if (opacity >= 0) { image->colormap[opacity].red=image->transparent_color.red; image->colormap[opacity].green=image->transparent_color.green; image->colormap[opacity].blue=image->transparent_color.blue; } } /* SIXEL header. */ for (i=0; i < (ssize_t) image->colors; i++) { sixel_palette[i * 3 + 0] = ScaleQuantumToChar(image->colormap[i].red); sixel_palette[i * 3 + 1] = ScaleQuantumToChar(image->colormap[i].green); sixel_palette[i * 3 + 2] = ScaleQuantumToChar(image->colormap[i].blue); } /* Define SIXEL pixels. */ output = sixel_output_create(image); sixel_pixels =(unsigned char *) AcquireQuantumMemory(image->columns * image->rows,1); for (y=0; y < (ssize_t) image->rows; y++) { (void) GetVirtualPixels(image,0,y,image->columns,1,exception); indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) sixel_pixels[y * image->columns + x] = (unsigned char) ((ssize_t) GetPixelIndex(indexes + x)); } status = sixel_encode_impl(sixel_pixels, image->columns, image->rows, sixel_palette, image->colors, -1, output); sixel_pixels =(unsigned char *) RelinquishMagickMemory(sixel_pixels); output = (sixel_output_t *) RelinquishMagickMemory(output); (void) CloseBlob(image); return(status); }
static Image *ReadEMFImage(const ImageInfo *image_info, ExceptionInfo *exception) { Gdiplus::Bitmap *bitmap; Gdiplus::BitmapData bitmap_data; Gdiplus::GdiplusStartupInput startup_input; Gdiplus::Graphics *graphics; Gdiplus::Image *source; Gdiplus::Rect rect; GeometryInfo geometry_info; Image *image; MagickStatusType flags; register Quantum *q; register ssize_t x; ssize_t y; ULONG_PTR token; unsigned char *p; wchar_t fileName[MagickPathExtent]; 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); image=AcquireImage(image_info,exception); if (Gdiplus::GdiplusStartup(&token,&startup_input,NULL) != Gdiplus::Status::Ok) ThrowReaderException(CoderError, "GdiplusStartupFailed"); MultiByteToWideChar(CP_UTF8,0,image->filename,-1,fileName,MagickPathExtent); source=Gdiplus::Image::FromFile(fileName); if (source == (Gdiplus::Image *) NULL) { Gdiplus::GdiplusShutdown(token); ThrowReaderException(FileOpenError,"UnableToOpenFile"); } image->resolution.x=source->GetHorizontalResolution(); image->resolution.y=source->GetVerticalResolution(); image->columns=(size_t) source->GetWidth(); image->rows=(size_t) source->GetHeight(); if (image_info->density != (char *) NULL) { flags=ParseGeometry(image_info->density,&geometry_info); image->resolution.x=geometry_info.rho; image->resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->resolution.y=image->resolution.x; if ((image->resolution.x > 0.0) && (image->resolution.y > 0.0)) { image->columns=(size_t) floor((Gdiplus::REAL) source->GetWidth() / source->GetHorizontalResolution() * image->resolution.x + 0.5); image->rows=(size_t)floor((Gdiplus::REAL) source->GetHeight() / source->GetVerticalResolution() * image->resolution.y + 0.5); } } bitmap=new Gdiplus::Bitmap((INT) image->columns,(INT) image->rows, PixelFormat32bppARGB); graphics=Gdiplus::Graphics::FromImage(bitmap); graphics->SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic); graphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); graphics->SetTextRenderingHint(Gdiplus::TextRenderingHintClearTypeGridFit); graphics->Clear(Gdiplus::Color((BYTE) ScaleQuantumToChar( image->background_color.alpha),(BYTE) ScaleQuantumToChar( image->background_color.red),(BYTE) ScaleQuantumToChar( image->background_color.green),(BYTE) ScaleQuantumToChar( image->background_color.blue))); graphics->DrawImage(source,0,0,(INT) image->columns,(INT) image->rows); delete graphics; delete source; rect=Gdiplus::Rect(0,0,(INT) image->columns,(INT) image->rows); if (bitmap->LockBits(&rect,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB, &bitmap_data) != Gdiplus::Ok) { delete bitmap; Gdiplus::GdiplusShutdown(token); ThrowReaderException(FileOpenError,"UnableToReadImageData"); } image->alpha_trait=BlendPixelTrait; for (y=0; y < (ssize_t) image->rows; y++) { p=(unsigned char *) bitmap_data.Scan0+(y*abs(bitmap_data.Stride)); if (bitmap_data.Stride < 0) q=GetAuthenticPixels(image,0,image->rows-y-1,image->columns,1,exception); else q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelBlue(image,ScaleCharToQuantum(*p++),q); SetPixelGreen(image,ScaleCharToQuantum(*p++),q); SetPixelRed(image,ScaleCharToQuantum(*p++),q); SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } bitmap->UnlockBits(&bitmap_data); delete bitmap; Gdiplus::GdiplusShutdown(token); return(image); }
static Image *ReadEMFImage(const ImageInfo *image_info, ExceptionInfo *exception) { BITMAPINFO DIBinfo; HBITMAP hBitmap, hOldBitmap; HDC hDC; HENHMETAFILE hemf; Image *image; long height, width, y; RECT rect; register long 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=(unsigned long) ((height/1000.0/CENTIMETERS_INCH)* y_resolution+0.5); image->columns=(unsigned long) ((width/1000.0/CENTIMETERS_INCH)* x_resolution+0.5); } if (image_info->size != (char *) NULL) { long 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; long 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=(unsigned long) ((image->columns* image->x_resolution)+0.5); if (image->y_resolution != 0.0) image->rows=(unsigned long) ((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=(unsigned long) (((image->columns* image->x_resolution)/DefaultResolution)+0.5); if (image->y_resolution != 0.0) image->rows=(unsigned long) (((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=image->columns; DIBinfo.bmiHeader.biHeight=(-1)*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 < (long) image->rows; y++) { for (x=0; x < (long) 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=image->columns; rect.bottom=image->rows; /* Convert metafile pixels. */ PlayEnhMetaFile(hDC,hemf,&rect); 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); q->opacity=OpaqueOpacity; pBits++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } DeleteEnhMetaFile(hemf); SelectObject(hDC,hOldBitmap); DeleteDC(hDC); DeleteObject(hBitmap); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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 (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) SetImageColorspace(image,sRGBColorspace); /* Extract crop image. */ q=bitmap_bits; for (y=0; y < (ssize_t) page.height; y++) { register ssize_t x; p=GetVirtualPixels(image,page.x,page.y+y,page.width,1,exception); if (p == (const PixelPacket *) NULL) break; /* Transfer pixels, scaling to Quantum */ for( x=(ssize_t) page.width ; x> 0 ; x-- ) { q->rgbRed = ScaleQuantumToChar(GetPixelRed(p)); q->rgbGreen = ScaleQuantumToChar(GetPixelGreen(p)); q->rgbBlue = ScaleQuantumToChar(GetPixelBlue(p)); q->rgbReserved = 0; p++; q++; } 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e A V S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteAVSImage() writes an image to a file in AVS X image format. % % The format of the WriteAVSImage method is: % % MagickBooleanType WriteAVSImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % */ static MagickBooleanType WriteAVSImage(const ImageInfo *image_info,Image *image) { MagickBooleanType status; MagickOffsetType scene; register const PixelPacket *p; register long x, y; register unsigned char *q; unsigned char *pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); scene=0; do { /* Write AVS header. */ if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); (void) WriteBlobMSBLong(image,image->columns); (void) WriteBlobMSBLong(image,image->rows); /* Allocate memory for pixels. */ pixels=(unsigned char *) AcquireMagickMemory((size_t) image->columns* 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert MIFF to AVS raster pixels. */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (PixelPacket *) NULL) break; q=pixels; for (x=0; x < (long) image->columns; x++) { *q++=ScaleQuantumToChar((Quantum) (QuantumRange- (image->matte != MagickFalse ? p->opacity : OpaqueOpacity))); *q++=ScaleQuantumToChar(p->red); *q++=ScaleQuantumToChar(p->green); *q++=ScaleQuantumToChar(p->blue); p++; } (void) WriteBlob(image,(size_t) (q-pixels),pixels); if (image->previous == (Image *) NULL) if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(SaveImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(SaveImagesTag,scene, GetImageListLength(image),image->client_data); if (status == MagickFalse) break; } scene++; } while (image_info->adjoin != MagickFalse); CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e n e r a t e D i f f e r e n t i a l N o i s e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GenerateDifferentialNoise() generates differentual noise. % % The format of the GenerateDifferentialNoise method is: % % double GenerateDifferentialNoise(RandomInfo *random_info, % const Quantum pixel,const NoiseType noise_type, % const MagickRealType attenuate) % % A description of each parameter follows: % % o random_info: the random info. % % o pixel: noise is relative to this pixel value. % % o noise_type: the type of noise. % % o attenuate: attenuate the noise. % */ MagickExport double GenerateDifferentialNoise(RandomInfo *random_info, const Quantum pixel,const NoiseType noise_type,const MagickRealType attenuate) { #define NoiseEpsilon (attenuate*1.0e-5) #define SigmaUniform (attenuate*4.0) #define SigmaGaussian (attenuate*4.0) #define SigmaImpulse (attenuate*0.10) #define SigmaLaplacian (attenuate*10.0) #define SigmaMultiplicativeGaussian (attenuate*1.0) #define SigmaPoisson (attenuate*0.05) #define TauGaussian (attenuate*20.0) double alpha, beta, noise, sigma; alpha=GetPseudoRandomValue(random_info); switch (noise_type) { case UniformNoise: default: { noise=(double) pixel+ScaleCharToQuantum((unsigned char) (SigmaUniform*(alpha))); break; } case GaussianNoise: { double tau; if (alpha == 0.0) alpha=1.0; beta=GetPseudoRandomValue(random_info); sigma=sqrt(-2.0*log(alpha))*cos(2.0*MagickPI*beta); tau=sqrt(-2.0*log(alpha))*sin(2.0*MagickPI*beta); noise=(double) pixel+sqrt((double) pixel)*SigmaGaussian*sigma+ TauGaussian*tau; break; } case MultiplicativeGaussianNoise: { if (alpha <= NoiseEpsilon) sigma=(double) QuantumRange; else sigma=sqrt(-2.0*log(alpha)); beta=GetPseudoRandomValue(random_info); noise=(double) pixel+pixel*SigmaMultiplicativeGaussian*sigma/2.0* cos((2.0*MagickPI*beta)); break; } case ImpulseNoise: { if (alpha < (SigmaImpulse/2.0)) noise=0.0; else if (alpha >= (1.0-(SigmaImpulse/2.0))) noise=(double) QuantumRange; else noise=(double) pixel; break; } case LaplacianNoise: { if (alpha <= 0.5) { if (alpha <= NoiseEpsilon) noise=(double) pixel-(double) QuantumRange; else noise=(double) pixel+ScaleCharToQuantum((unsigned char) (SigmaLaplacian*log((2.0*alpha))+0.5)); break; } beta=1.0-alpha; if (beta <= (0.5*NoiseEpsilon)) noise=(double) (pixel+QuantumRange); else noise=(double) pixel-ScaleCharToQuantum((unsigned char) (SigmaLaplacian*log((2.0*beta))+0.5)); break; } case PoissonNoise: { double poisson; register long i; poisson=exp(-SigmaPoisson*ScaleQuantumToChar(pixel)); for (i=0; alpha > poisson; i++) { beta=GetPseudoRandomValue(random_info); alpha*=beta; } noise=(double) ScaleCharToQuantum((unsigned char) (i/SigmaPoisson)); break; } case RandomNoise: { noise=(double) QuantumRange*GetPseudoRandomValue(random_info); break; } } return(noise); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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 (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace); 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(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(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 int render_logo_yuv(LogoPrivateData *pd, const WorkItem *W, TCFrameVideo *frame) { unsigned long vid_size = pd->vob->ex_v_width * pd->vob->ex_v_height; unsigned long img_size = pd->images->columns * pd->images->rows; uint8_t *img_pixel_Y, *img_pixel_U, *img_pixel_V; uint8_t *vid_pixel_Y, *vid_pixel_U, *vid_pixel_V; float img_coeff, vid_coeff; /* Note: GraphicsMagick defines opacity = 0 as fully visible, and * opacity = MaxRGB as fully transparent. */ Quantum opacity; int row, col; PixelPacket *pixels = GetImagePixels(pd->images, 0, 0, pd->images->columns, pd->images->rows); /* FIXME: yet another independent reimplementation of * the YUV planes pointer assignement. */ img_pixel_Y = pd->yuv[pd->cur_seq]; img_pixel_U = img_pixel_Y + img_size; img_pixel_V = img_pixel_U + img_size/4; for (row = 0; row < pd->images->rows; row++) { vid_pixel_Y = frame->video_buf + (row + pd->posy)*pd->vob->ex_v_width + pd->posx; vid_pixel_U = frame->video_buf + vid_size + (row/2 + pd->posy/2)*(pd->vob->ex_v_width/2) + pd->posx/2; vid_pixel_V = vid_pixel_U + vid_size/4; for (col = 0; col < pd->images->columns; col++) { int do_UV_pixels = (pd->grayout == 0 && !(row % 2) && !(col % 2)) ? 1 : 0; opacity = pixels->opacity; if (W->do_fade) opacity += (Quantum)((MaxRGB - opacity) * W->fade_coeff); if (opacity == 0) { *vid_pixel_Y = *img_pixel_Y; if (do_UV_pixels) { *vid_pixel_U = *img_pixel_U; *vid_pixel_V = *img_pixel_V; } } else if (opacity < MaxRGB) { unsigned char opacity_byte = ScaleQuantumToChar(opacity); img_coeff = pd->img_coeff_lookup[opacity_byte]; vid_coeff = pd->vid_coeff_lookup[opacity_byte]; *vid_pixel_Y = (uint8_t)(*vid_pixel_Y * vid_coeff) + (uint8_t)(*img_pixel_Y * img_coeff); if (do_UV_pixels) { *vid_pixel_U = (uint8_t)(*vid_pixel_U * vid_coeff) + (uint8_t)(*img_pixel_U * img_coeff); *vid_pixel_V = (uint8_t)(*vid_pixel_V * vid_coeff) + (uint8_t)(*img_pixel_V * img_coeff); } } vid_pixel_Y++; img_pixel_Y++; if (do_UV_pixels) { vid_pixel_U++; img_pixel_U++; vid_pixel_V++; img_pixel_V++; } pixels++; } } return TC_OK; }
int tc_filter(frame_list_t *ptr_, char *options) { vframe_list_t *ptr = (vframe_list_t *)ptr_; int instance = ptr->filter_id; Image *pattern, *resized, *orig = 0; ImageInfo *image_info; PixelPacket *pixel_packet; pixelsMask *pixel_last; ExceptionInfo exception_info; if(ptr->tag & TC_FILTER_GET_CONFIG) { char buf[128]; optstr_filter_desc(options, MOD_NAME, MOD_CAP, MOD_VERSION, MOD_AUTHOR, "VRYMO", "1"); tc_snprintf(buf, 128, "/dev/null"); optstr_param(options, "pattern", "Pattern image file path", "%s", buf); tc_snprintf(buf, 128, "results.dat"); optstr_param(options, "results", "Results file path" , "%s", buf); tc_snprintf(buf, 128, "%f", compare[instance]->delta); optstr_param(options, "delta", "Delta error", "%f",buf,"0.0", "100.0"); return 0; } //---------------------------------- // // filter init // //---------------------------------- if(ptr->tag & TC_FILTER_INIT) { unsigned int t,r,index; pixelsMask *temp; compare[instance] = tc_malloc(sizeof(compareData)); if(compare[instance] == NULL) return (-1); compare[instance]->vob = tc_get_vob(); if(compare[instance]->vob ==NULL) return(-1); compare[instance]->delta=DELTA_COLOR; compare[instance]->step=1; compare[instance]->width=0; compare[instance]->height=0; compare[instance]->frames = 0; compare[instance]->pixel_mask = NULL; pixel_last = NULL; compare[instance]->width = compare[instance]->vob->ex_v_width; compare[instance]->height = compare[instance]->vob->ex_v_height; if (options != NULL) { char pattern_name[PATH_MAX]; char results_name[PATH_MAX]; memset(pattern_name,0,PATH_MAX); memset(results_name,0,PATH_MAX); if(verbose) tc_log_info(MOD_NAME, "options=%s", options); optstr_get(options, "pattern", "%[^:]", pattern_name); optstr_get(options, "results", "%[^:]", results_name); optstr_get(options, "delta", "%f", &compare[instance]->delta); if (verbose > 1) { tc_log_info(MOD_NAME, "Compare Image Settings:"); tc_log_info(MOD_NAME, " pattern = %s\n", pattern_name); tc_log_info(MOD_NAME, " results = %s\n", results_name); tc_log_info(MOD_NAME, " delta = %f\n", compare[instance]->delta); } if (strlen(results_name) == 0) { // Ponemos el nombre del fichero al original con extension dat strlcpy(results_name, "/tmp/compare.dat", sizeof(results_name)); } if (!(compare[instance]->results = fopen(results_name, "w"))) { tc_log_perror(MOD_NAME, "could not open file for writing"); } InitializeMagick(""); if (verbose > 1) tc_log_info(MOD_NAME, "Magick Initialized successfully"); GetExceptionInfo(&exception_info); image_info = CloneImageInfo ((ImageInfo *) NULL); strlcpy(image_info->filename, pattern_name, MaxTextExtent); if (verbose > 1) tc_log_info(MOD_NAME, "Trying to open image"); orig = ReadImage(image_info, &exception_info); if (orig == (Image *) NULL) { MagickWarning(exception_info.severity, exception_info.reason, exception_info.description); strlcpy(pattern_name, "/dev/null", sizeof(pattern_name)); }else{ if (verbose > 1) tc_log_info(MOD_NAME, "Image loaded successfully"); } } else{ tc_log_perror(MOD_NAME, "Not image provided"); } if (options != NULL) if (optstr_lookup (options, "help")) { help_optstr(); } fprintf(compare[instance]->results,"#fps:%f\n",compare[instance]->vob->fps); if (orig != NULL){ // Flip and resize if (compare[instance]->vob->im_v_codec == CODEC_YUV) TransformRGBImage(orig,YCbCrColorspace); if (verbose > 1) tc_log_info(MOD_NAME, "Resizing the Image"); resized = ResizeImage(orig, compare[instance]->width, compare[instance]->height, GaussianFilter, 1, &exception_info); if (verbose > 1) tc_log_info(MOD_NAME, "Flipping the Image"); pattern = FlipImage(resized, &exception_info); if (pattern == (Image *) NULL) { MagickError (exception_info.severity, exception_info.reason, exception_info.description); } // Filling the matrix with the pixels values not // alpha if (verbose > 1) tc_log_info(MOD_NAME, "GetImagePixels"); pixel_packet = GetImagePixels(pattern,0,0, pattern->columns, pattern->rows); if (verbose > 1) tc_log_info(MOD_NAME, "Filling the Image matrix"); for (t = 0; t < pattern->rows; t++) for (r = 0; r < pattern->columns; r++){ index = t*pattern->columns + r; if (pixel_packet[index].opacity == 0){ temp=tc_malloc(sizeof(struct pixelsMask)); temp->row=t; temp->col=r; temp->r = (uint8_t)ScaleQuantumToChar(pixel_packet[index].red); temp->g = (uint8_t)ScaleQuantumToChar(pixel_packet[index].green); temp->b = (uint8_t)ScaleQuantumToChar(pixel_packet[index].blue); temp->next=NULL; if (pixel_last == NULL){ pixel_last = temp; compare[instance]->pixel_mask = temp; }else{ pixel_last->next = temp; pixel_last = temp; } } } if (verbose) tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); } return(0); } //---------------------------------- // // filter close // //---------------------------------- if(ptr->tag & TC_FILTER_CLOSE) { if (compare[instance] != NULL) { fclose(compare[instance]->results); free(compare[instance]); } DestroyMagick(); compare[instance]=NULL; return(0); } /* filter close */ //---------------------------------- // // filter frame routine // //---------------------------------- // tag variable indicates, if we are called before // transcodes internal video/audio frame processing routines // or after and determines video/audio context if((ptr->tag & TC_POST_M_PROCESS) && (ptr->tag & TC_VIDEO)) { // For now I only support RGB color space pixelsMask *item = NULL; double sr,sg,sb; double avg_dr,avg_dg,avg_db; if (compare[instance]->vob->im_v_codec == CODEC_RGB){ int r,g,b,c; double width_long; if (compare[instance]->pixel_mask != NULL) { item = compare[instance]->pixel_mask; c = 0; sr = 0.0; sg = 0.0; sb = 0.0; width_long = compare[instance]->width*3; while(item){ r = item->row*width_long + item->col*3; g = item->row*width_long + item->col*3 + 1; b = item->row*width_long + item->col*3 + 2; // diff between points // Interchange RGB values if necesary sr = sr + (double)abs((unsigned char)ptr->video_buf[r] - item->r); sg = sg + (double)abs((unsigned char)ptr->video_buf[g] - item->g); sb = sb + (double)abs((unsigned char)ptr->video_buf[b] - item->b); item = item->next; c++; } avg_dr = sr/(double)c; avg_dg = sg/(double)c; avg_db = sb/(double)c; if ((avg_dr < compare[instance]->delta) && (avg_dg < compare[instance]->delta) && (avg_db < compare[instance]->delta)) fprintf(compare[instance]->results,"1"); else fprintf(compare[instance]->results,"n"); fflush(compare[instance]->results); } compare[instance]->frames++; return(0); }else{ // The colospace is YUV // FIXME: Doesn't works, I need to code all this part // again int Y,Cr,Cb,c; if (compare[instance]->pixel_mask != NULL) { item = compare[instance]->pixel_mask; c = 0; sr = 0.0; sg = 0.0; sb = 0.0; while(item){ Y = item->row*compare[instance]->width + item->col; Cb = compare[instance]->height*compare[instance]->width + (int)((item->row*compare[instance]->width + item->col)/4); Cr = compare[instance]->height*compare[instance]->width + (int)((compare[instance]->height*compare[instance]->width)/4) + (int)((item->row*compare[instance]->width + item->col)/4); // diff between points // Interchange RGB values if necesary sr = sr + (double)abs((unsigned char)ptr->video_buf[Y] - item->r); sg = sg + (double)abs((unsigned char)ptr->video_buf[Cb] - item->g); sb = sb + (double)abs((unsigned char)ptr->video_buf[Cr] - item->b); item = item->next; c++; } avg_dr = sr/(double)c; avg_dg = sg/(double)c; avg_db = sb/(double)c; if ((avg_dr < compare[instance]->delta) && (avg_dg < compare[instance]->delta) && (avg_db < compare[instance]->delta)) fprintf(compare[instance]->results,"1"); else fprintf(compare[instance]->results,"n"); } compare[instance]->frames++; return(0); } } return(0); }
MagickExport Image *OilPaintImage(const Image *image,const double radius, const double sigma,ExceptionInfo *exception) { #define NumberPaintBins 256 #define OilPaintImageTag "OilPaint/Image" CacheView *image_view, *paint_view; Image *linear_image, *paint_image; MagickBooleanType status; MagickOffsetType progress; size_t **histograms, width; ssize_t center, y; /* Initialize painted image attributes. */ assert(image != (const Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); width=GetOptimalKernelWidth2D(radius,sigma); linear_image=CloneImage(image,0,0,MagickTrue,exception); paint_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception); if ((linear_image == (Image *) NULL) || (paint_image == (Image *) NULL)) { if (linear_image != (Image *) NULL) linear_image=DestroyImage(linear_image); if (paint_image != (Image *) NULL) linear_image=DestroyImage(paint_image); return((Image *) NULL); } if (SetImageStorageClass(paint_image,DirectClass,exception) == MagickFalse) { linear_image=DestroyImage(linear_image); paint_image=DestroyImage(paint_image); return((Image *) NULL); } histograms=AcquireHistogramThreadSet(NumberPaintBins); if (histograms == (size_t **) NULL) { linear_image=DestroyImage(linear_image); paint_image=DestroyImage(paint_image); ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); } /* Oil paint image. */ status=MagickTrue; progress=0; center=(ssize_t) GetPixelChannels(linear_image)*(linear_image->columns+width)* (width/2L)+GetPixelChannels(linear_image)*(width/2L); image_view=AcquireVirtualCacheView(linear_image,exception); paint_view=AcquireAuthenticCacheView(paint_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(progress,status) \ magick_threads(linear_image,paint_image,linear_image->rows,1) #endif for (y=0; y < (ssize_t) linear_image->rows; y++) { register const Quantum *restrict p; register Quantum *restrict q; register size_t *histogram; register ssize_t x; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,-((ssize_t) width/2L),y-(ssize_t) (width/2L),linear_image->columns+width,width,exception); q=QueueCacheViewAuthenticPixels(paint_view,0,y,paint_image->columns,1, exception); if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) { status=MagickFalse; continue; } histogram=histograms[GetOpenMPThreadId()]; for (x=0; x < (ssize_t) linear_image->columns; x++) { register ssize_t i, u; size_t count; ssize_t j, k, n, v; /* Assign most frequent color. */ k=0; j=0; count=0; (void) ResetMagickMemory(histogram,0,NumberPaintBins* sizeof(*histogram)); for (v=0; v < (ssize_t) width; v++) { for (u=0; u < (ssize_t) width; u++) { n=(ssize_t) ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity( linear_image,p+GetPixelChannels(linear_image)*(u+k)))); histogram[n]++; if (histogram[n] > count) { j=k+u; count=histogram[n]; } } k+=(ssize_t) (linear_image->columns+width); } for (i=0; i < (ssize_t) GetPixelChannels(linear_image); i++) { PixelChannel channel=GetPixelChannelChannel(linear_image,i); PixelTrait traits=GetPixelChannelTraits(linear_image,channel); PixelTrait paint_traits=GetPixelChannelTraits(paint_image,channel); if ((traits == UndefinedPixelTrait) || (paint_traits == UndefinedPixelTrait)) continue; if (((paint_traits & CopyPixelTrait) != 0) || (GetPixelReadMask(linear_image,p) == 0)) { SetPixelChannel(paint_image,channel,p[center+i],q); continue; } SetPixelChannel(paint_image,channel,p[j*GetPixelChannels(linear_image)+ i],q); } p+=GetPixelChannels(linear_image); q+=GetPixelChannels(paint_image); } if (SyncCacheViewAuthenticPixels(paint_view,exception) == MagickFalse) status=MagickFalse; if (linear_image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_OilPaintImage) #endif proceed=SetImageProgress(linear_image,OilPaintImageTag,progress++, linear_image->rows); if (proceed == MagickFalse) status=MagickFalse; } } paint_view=DestroyCacheView(paint_view); image_view=DestroyCacheView(image_view); histograms=DestroyHistogramThreadSet(histograms); linear_image=DestroyImage(linear_image); if (status == MagickFalse) paint_image=DestroyImage(paint_image); return(paint_image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e H I S T O G R A M I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteHISTOGRAMImage writes an image to a file in Histogram format. % The image shows a histogram of the color (or gray) values in the image. The % image consists of three overlaid histograms: a red one for the red channel, % a green one for the green channel, and a blue one for the blue channel. The % image comment contains a list of unique pixel values and the number of times % each occurs in the image. % % This method is strongly based on a similar one written by % [email protected] which in turn is based on ppmhistmap of netpbm. % % The format of the WriteHISTOGRAMImage method is: % % unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o status: Method WriteHISTOGRAMImage return True if the image is written. % False is returned is there is a memory shortage or if the image file % fails to write. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o image: A pointer to an Image structure. % % */ static unsigned int WriteHISTOGRAMImage(const ImageInfo *image_info, Image *image) { #define HistogramDensity "256x200" char filename[MaxTextExtent]; double scale; FILE *file; Image *histogram_image; long *blue, *green, maximum, *red; long y; RectangleInfo geometry; register const PixelPacket *p; register long x; register PixelPacket *q, *r; unsigned int status; unsigned long length; /* Allocate histogram image. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); (void) SetImageDepth(image,image->depth); SetGeometry(image,&geometry); if (image_info->density == (char *) NULL) (void) GetMagickGeometry(HistogramDensity,&geometry.x,&geometry.y, &geometry.width,&geometry.height); else (void) GetMagickGeometry(image_info->density,&geometry.x,&geometry.y, &geometry.width,&geometry.height); histogram_image=CloneImage(image,geometry.width,geometry.height,True, &image->exception); if (histogram_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); (void) SetImageType(histogram_image,TrueColorType); /* Allocate histogram count arrays. */ length=Max(ScaleQuantumToChar(MaxRGB)+1,histogram_image->columns); red=MagickAllocateMemory(long *,length*sizeof(long)); green=MagickAllocateMemory(long *,length*sizeof(long)); blue=MagickAllocateMemory(long *,length*sizeof(long)); if ((red == (long *) NULL) || (green == (long *) NULL) || (blue == (long *) NULL)) { DestroyImage(histogram_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image) }
static MagickBooleanType WriteSGIImage(const ImageInfo *image_info,Image *image) { CompressionType compression; const char *value; MagickBooleanType status; MagickOffsetType scene; MagickSizeType number_pixels; MemoryInfo *pixel_info; SGIInfo iris_info; register const PixelPacket *p; register ssize_t i, x; register unsigned char *q; ssize_t y, z; unsigned char *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. */ (void) TransformImageColorspace(image,sRGBColorspace); (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) && (SetImageGray(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(QuantumRange) : 1UL*ScaleQuantumToShort(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"); pixel_info=AcquireVirtualMemory((size_t) number_pixels,4* iris_info.bytes_per_pixel*sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info); /* 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 *) pixels; q+=((iris_info.rows-1)-y)*(4*iris_info.columns)+4*x; *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); *q++=ScaleQuantumToChar(GetPixelAlpha(p)); p++; } else for (x=0; x < (ssize_t) image->columns; x++) { register unsigned short *q; q=(unsigned short *) pixels; q+=((iris_info.rows-1)-y)*(4*iris_info.columns)+4*x; *q++=ScaleQuantumToShort(GetPixelRed(p)); *q++=ScaleQuantumToShort(GetPixelGreen(p)); *q++=ScaleQuantumToShort(GetPixelBlue(p)); *q++=ScaleQuantumToShort(GetPixelAlpha(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 *) 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 *) pixels; q+=y*(4*iris_info.columns)+4*x+z; (void) WriteBlobMSBShort(image,*q); } } } break; } default: { MemoryInfo *packet_info; size_t length, number_packets, *runlength; ssize_t offset, *offsets; /* Convert SGI uncompressed pixels. */ offsets=(ssize_t *) AcquireQuantumMemory(iris_info.rows, iris_info.depth*sizeof(*offsets)); runlength=(size_t *) AcquireQuantumMemory(iris_info.rows, iris_info.depth*sizeof(*runlength)); packet_info=AcquireVirtualMemory((2*(size_t) iris_info.columns+10)* image->rows,4*sizeof(*packets)); if ((offsets == (ssize_t *) NULL) || (runlength == (size_t *) NULL) || (packet_info == (MemoryInfo *) NULL)) { if (offsets != (ssize_t *) NULL) offsets=(ssize_t *) RelinquishMagickMemory(offsets); if (runlength != (size_t *) NULL) runlength=(size_t *) RelinquishMagickMemory(runlength); if (packet_info != (MemoryInfo *) NULL) packet_info=RelinquishVirtualMemory(packet_info); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } packets=(unsigned char *) GetVirtualMemoryBlob(packet_info); offset=512+4*2*((ssize_t) iris_info.rows*iris_info.depth); number_packets=0; q=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. */ offsets=(ssize_t *) RelinquishMagickMemory(offsets); runlength=(size_t *) RelinquishMagickMemory(runlength); packet_info=RelinquishVirtualMemory(packet_info); break; } } pixel_info=RelinquishVirtualMemory(pixel_info); 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, ExceptionInfo *exception) { char buffer[MaxTextExtent]; const char *option; MagickBooleanType status; MagickOffsetType scene; register const Quantum *p; register ssize_t i, x; register unsigned char *q; size_t density, length, one, packets; ssize_t y; unsigned char bits_per_pixel, *compress_pixels, *pixels, *previous_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); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); density=75; if (image_info->density != (char *) NULL) { GeometryInfo geometry; (void) ParseGeometry(image_info->density,&geometry); density=(size_t) geometry.rho; } scene=0; one=1; do { if (IsRGBColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,RGBColorspace,exception); /* Initialize the printer. */ (void) WriteBlobString(image,"\033E"); /* printer reset */ (void) WriteBlobString(image,"\033*r3F"); /* set presentation mode */ (void) FormatLocaleString(buffer,MaxTextExtent,"\033*r%.20gs%.20gT", (double) image->columns,(double) image->rows); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*t%.20gR",(double) density); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"\033&l0E"); /* top margin 0 */ if (IsImageMonochrome(image,exception) != MagickFalse) { /* Monochrome image: use default printer monochrome setup. */ bits_per_pixel=1; } 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 < (ssize_t) image->colors; i++) { (void) FormatLocaleString(buffer,MaxTextExtent, "\033*v%da%db%dc%.20gI", ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue),(double) i); (void) WriteBlobString(image,buffer); } for (one=1; i < (ssize_t) (one << bits_per_pixel); i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*v%.20gI", (double) 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+1,sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(pixels,0,(length+1)*sizeof(*pixels)); compress_pixels=(unsigned char *) NULL; previous_pixels=(unsigned char *) NULL; switch (image->compression) { case NoCompression: { (void) FormatLocaleString(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) ResetMagickMemory(compress_pixels,0,(length+256)* sizeof(*compress_pixels)); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b2M"); (void) WriteBlobString(image,buffer); break; } default: { compress_pixels=(unsigned char *) AcquireQuantumMemory(3*length+256, sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) ResetMagickMemory(compress_pixels,0,(3*length+256)* sizeof(*compress_pixels)); previous_pixels=(unsigned char *) AcquireQuantumMemory(length+1, 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) ResetMagickMemory(previous_pixels,0,(length+1)* sizeof(*previous_pixels)); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b3M"); (void) WriteBlobString(image,buffer); break; } } for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; q=pixels; switch (bits_per_pixel) { case 1: { register unsigned char bit, byte; /* Monochrome image. */ bit=0; byte=0; for (x=0; x < (ssize_t) image->columns; x++) { byte<<=1; if (GetPixelIntensity(image,p) < ((MagickRealType) QuantumRange/2.0)) byte|=0x01; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } p+=GetPixelChannels(image); } if (bit != 0) *q++=byte << (8-bit); break; } case 8: { /* Colormapped image. */ for (x=0; x < (ssize_t) image->columns; x++) { *q++=(unsigned char) GetPixelIndex(image,p); p+=GetPixelChannels(image); } break; } case 24: case 32: { /* Truecolor image. */ for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(GetPixelRed(image,p)); *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); p+=GetPixelChannels(image); } break; } } switch (image->compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) length); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,length,pixels); break; } case RLECompression: { packets=PCLPackbitsCompressImage(length,pixels,compress_pixels); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) packets); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,packets,compress_pixels); break; } default: { if (y == 0) for (i=0; i < (ssize_t) length; i++) previous_pixels[i]=(~pixels[i]); packets=PCLDeltaCompressImage(length,previous_pixels,pixels, compress_pixels); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteHRZImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { Image *hrz_image; MagickBooleanType status; register const Quantum *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 == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); hrz_image=ResizeImage(image,256,240,image->filter,exception); if (hrz_image == (Image *) NULL) return(MagickFalse); (void) TransformImageColorspace(hrz_image,sRGBColorspace,exception); /* 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,exception); if (p == (const Quantum *) NULL) break; q=pixels; for (x=0; x < (ssize_t) hrz_image->columns; x++) { *q++=ScaleQuantumToChar(GetPixelRed(hrz_image,p)/4); *q++=ScaleQuantumToChar(GetPixelGreen(hrz_image,p)/4); *q++=ScaleQuantumToChar(GetPixelBlue(hrz_image,p)/4); p+=GetPixelChannels(hrz_image); } 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 H I S T O G R A M I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteHISTOGRAMImage() writes an image to a file in Histogram format. % The image shows a histogram of the color (or gray) values in the image. The % image consists of three overlaid histograms: a red one for the red channel, % a green one for the green channel, and a blue one for the blue channel. The % image comment contains a list of unique pixel values and the number of times % each occurs in the image. % % This method is strongly based on a similar one written by % [email protected] which in turn is based on ppmhistmap of netpbm. % % The format of the WriteHISTOGRAMImage method is: % % MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteHISTOGRAMImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { #define HistogramDensity "256x200" char filename[MagickPathExtent]; const char *option; Image *histogram_image; ImageInfo *write_info; MagickBooleanType status; PixelInfo *histogram; double maximum, scale; RectangleInfo geometry; register const Quantum *p; register Quantum *q, *r; register ssize_t x; size_t length; ssize_t y; /* Allocate histogram image. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); 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, exception); if (histogram_image == (Image *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) SetImageStorageClass(histogram_image,DirectClass,exception); /* Allocate histogram count arrays. */ length=MagickMax((size_t) ScaleQuantumToChar(QuantumRange)+1UL, histogram_image->columns); histogram=(PixelInfo *) AcquireQuantumMemory(length,sizeof(*histogram)); if (histogram == (PixelInfo *) NULL) { histogram_image=DestroyImage(histogram_image); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } /* Initialize histogram count arrays. */ (void) ResetMagickMemory(histogram,0,length*sizeof(*histogram)); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) histogram[ScaleQuantumToChar(GetPixelRed(image,p))].red++; if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) histogram[ScaleQuantumToChar(GetPixelGreen(image,p))].green++; if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) histogram[ScaleQuantumToChar(GetPixelBlue(image,p))].blue++; p+=GetPixelChannels(image); } } maximum=histogram[0].red; for (x=0; x < (ssize_t) histogram_image->columns; x++) { if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) && (maximum < histogram[x].red)) maximum=histogram[x].red; if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) && (maximum < histogram[x].green)) maximum=histogram[x].green; if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) && (maximum < histogram[x].blue)) maximum=histogram[x].blue; } scale=0.0; if (fabs(maximum) >= MagickEpsilon) scale=(double) histogram_image->rows/maximum; /* Initialize histogram image. */ (void) QueryColorCompliance("#000000",AllCompliance, &histogram_image->background_color,exception); (void) SetImageBackgroundColor(histogram_image,exception); for (x=0; x < (ssize_t) histogram_image->columns; x++) { q=GetAuthenticPixels(histogram_image,x,0,1,histogram_image->rows,exception); if (q == (Quantum *) NULL) break; if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) { y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].red-0.5); r=q+y*GetPixelChannels(histogram_image); for ( ; y < (ssize_t) histogram_image->rows; y++) { SetPixelRed(histogram_image,QuantumRange,r); r+=GetPixelChannels(histogram_image); } } if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) { y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].green-0.5); r=q+y*GetPixelChannels(histogram_image); for ( ; y < (ssize_t) histogram_image->rows; y++) { SetPixelGreen(histogram_image,QuantumRange,r); r+=GetPixelChannels(histogram_image); } } if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) { y=(ssize_t) ceil(histogram_image->rows-scale*histogram[x].blue-0.5); r=q+y*GetPixelChannels(histogram_image); for ( ; y < (ssize_t) histogram_image->rows; y++) { SetPixelBlue(histogram_image,QuantumRange,r); r+=GetPixelChannels(histogram_image); } } if (SyncAuthenticPixels(histogram_image,exception) == MagickFalse) break; status=SetImageProgress(image,SaveImageTag,y,histogram_image->rows); if (status == MagickFalse) break; } histogram=(PixelInfo *) RelinquishMagickMemory(histogram); option=GetImageOption(image_info,"histogram:unique-colors"); if ((option == (const char *) NULL) || (IsStringTrue(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,exception); (void) fclose(file); property=FileToString(filename,~0UL,exception); if (property != (char *) NULL) { (void) SetImageProperty(histogram_image,"comment",property, exception); property=DestroyString(property); } } (void) RelinquishUniqueFileResource(filename); } /* Write Histogram image. */ (void) CopyMagickString(histogram_image->filename,image_info->filename, MagickPathExtent); write_info=CloneImageInfo(image_info); *write_info->magick='\0'; (void) SetImageInfo(write_info,1,exception); if ((*write_info->magick == '\0') || (LocaleCompare(write_info->magick,"HISTOGRAM") == 0)) (void) FormatLocaleString(histogram_image->filename,MagickPathExtent, "miff:%s",write_info->filename); histogram_image->blob=DetachBlob(histogram_image->blob); histogram_image->blob=CloneBlobInfo(image->blob); status=WriteImage(write_info,histogram_image,exception); image->blob=DetachBlob(image->blob); image->blob=CloneBlobInfo(histogram_image->blob); histogram_image=DestroyImage(histogram_image); write_info=DestroyImageInfo(write_info); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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; MagickBooleanType status; MagickOffsetType scene; register const PixelPacket *p, *s; register ssize_t x; size_t height, quantum, width; ssize_t horizontal_factor, vertical_factor, y; 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); quantum=(size_t) (image->depth <= 8 ? 1 : 2); 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=(ssize_t) geometry_info.rho; vertical_factor=(ssize_t) 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=(size_t) (quantum == 1 ? 8 : 16); 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 < (ssize_t) 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 < (ssize_t) yuv_image->columns; x++) { if (quantum == 1) { (void) WriteBlobByte(image,ScaleQuantumToChar( GetPixelGreen(s))); (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelRed(p))); p++; (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelBlue(s))); (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelRed(p))); } else { (void) WriteBlobByte(image,ScaleQuantumToChar( GetPixelGreen(s))); (void) WriteBlobShort(image,ScaleQuantumToShort( GetPixelRed(p))); p++; (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelBlue(s))); (void) WriteBlobShort(image,ScaleQuantumToShort( GetPixelRed(p))); } p++; s++; x++; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } yuv_image=DestroyImage(yuv_image); } else { /* Initialize Y channel. */ for (y=0; y < (ssize_t) 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 < (ssize_t) yuv_image->columns; x++) { if (quantum == 1) (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelRed(p))); else (void) WriteBlobShort(image,ScaleQuantumToShort(GetPixelRed(p))); p++; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) 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 < (ssize_t) 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 < (ssize_t) chroma_image->columns; x++) { if (quantum == 1) (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelGreen(p))); else (void) WriteBlobShort(image,ScaleQuantumToShort( GetPixelGreen(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 < (ssize_t) 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 < (ssize_t) chroma_image->columns; x++) { if (quantum == 1) (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelBlue(p))); else (void) WriteBlobShort(image,ScaleQuantumToShort(GetPixelBlue(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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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,Exceptioninfo *exception) % % A description of each parameter follows: % % o image: the image to convert. % */ MagickExport void *ImageToHBITMAP(Image *image,ExceptionInfo *exception) { BITMAP bitmap; 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(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",message); message=DestroyString(message); return(NULL); } bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH); q=bitmap_bits; if (bitmap.bmBits == NULL) bitmap.bmBits=bitmap_bits; (void) SetImageColorspace(image,sRGBColorspace); 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(GetPixelRed(p)); q->rgbGreen=ScaleQuantumToChar(GetPixelGreen(p)); q->rgbBlue=ScaleQuantumToChar(GetPixelBlue(p)); q->rgbReserved=0; p++; q++; } } bitmap.bmBits=bitmap_bits; bitmapH=CreateBitmapIndirect(&bitmap); if (bitmapH == NULL) { char *message; message=GetExceptionMessage(errno); (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",message); message=DestroyString(message); } GlobalUnlock((HGLOBAL) bitmap_bitsH); GlobalFree((HGLOBAL) bitmap_bitsH); return((void *) bitmapH); }
static MagickBooleanType WritePS2Image(const ImageInfo *image_info,Image *image) { static const char *PostscriptProlog[]= { "%%%%BeginProlog", "%%", "%% Display a color image. The image is displayed in color on", "%% Postscript viewers or printers that support color, otherwise", "%% it is displayed as grayscale.", "%%", "/DirectClassImage", "{", " %%", " %% Display a DirectClass image.", " %%", " colorspace 0 eq", " {", " /DeviceRGB setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [0 1 0 1 0 1]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " }", " {", " /DeviceCMYK setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [1 0 1 0 1 0 1 0]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " } ifelse", "} bind def", "", "/PseudoClassImage", "{", " %%", " %% Display a PseudoClass image.", " %%", " %% Parameters:", " %% colors: number of colors in the colormap.", " %%", " currentfile buffer readline pop", " token pop /colors exch def pop", " colors 0 eq", " {", " %%", " %% Image is grayscale.", " %%", " currentfile buffer readline pop", " token pop /bits exch def pop", " /DeviceGray setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent bits", " /Decode [0 1]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " {", " /DataSource pixel_stream %s", " <<", " /K "CCITTParam, " /Columns columns", " /Rows rows", " >> /CCITTFaxDecode filter", " } ifelse", " >> image", " }", " {", " %%", " %% Parameters:", " %% colormap: red, green, blue color packets.", " %%", " /colormap colors 3 mul string def", " currentfile colormap readhexstring pop pop", " currentfile buffer readline pop", " [ /Indexed /DeviceRGB colors 1 sub colormap ] setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /Decode [0 255]", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " compression 0 gt", " { /DataSource pixel_stream %s }", " { /DataSource pixel_stream %s } ifelse", " >> image", " } ifelse", "} bind def", "", "/DisplayImage", "{", " %%", " %% Display a DirectClass or PseudoClass image.", " %%", " %% Parameters:", " %% x & y translation.", " %% x & y scale.", " %% label pointsize.", " %% image label.", " %% image columns & rows.", " %% class: 0-DirectClass or 1-PseudoClass.", " %% colorspace: 0-RGB or 1-CMYK.", " %% compression: 0-RLECompression or 1-NoCompression.", " %% hex color packets.", " %%", " gsave", " /buffer 512 string def", " /pixel_stream currentfile def", "", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " x y translate", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " currentfile buffer readline pop", " token pop /pointsize exch def pop", " /Helvetica findfont pointsize scalefont setfont", (char *) NULL }, *PostscriptEpilog[]= { " x y scale", " currentfile buffer readline pop", " token pop /columns exch def", " token pop /rows exch def pop", " currentfile buffer readline pop", " token pop /class exch def pop", " currentfile buffer readline pop", " token pop /colorspace exch def pop", " currentfile buffer readline pop", " token pop /compression exch def pop", " class 0 gt { PseudoClassImage } { DirectClassImage } ifelse", (char *) NULL }; char buffer[MaxTextExtent], date[MaxTextExtent], page_geometry[MaxTextExtent], **labels; CompressionType compression; const char **q, *value; double pointsize; GeometryInfo geometry_info; MagickOffsetType scene, start, stop; MagickBooleanType progress, status; MagickOffsetType offset; MagickSizeType number_pixels; MagickStatusType flags; PointInfo delta, resolution, scale; RectangleInfo geometry, media_info, page_info; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t x; register ssize_t i; SegmentInfo bounds; size_t length, page, text_size; ssize_t j, y; time_t timer; 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); compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; switch (compression) { #if !defined(MAGICKCORE_JPEG_DELEGATE) case JPEGCompression: { compression=RLECompression; (void) ThrowMagickException(&image->exception,GetMagickModule(), MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JPEG)", image->filename); break; } #endif default: break; } (void) ResetMagickMemory(&bounds,0,sizeof(bounds)); page=1; scene=0; do { /* Scale relative to dots-per-inch. */ delta.x=DefaultResolution; delta.y=DefaultResolution; resolution.x=image->x_resolution; resolution.y=image->y_resolution; if ((resolution.x == 0.0) || (resolution.y == 0.0)) { flags=ParseGeometry(PSDensityGeometry,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image_info->density != (char *) NULL) { flags=ParseGeometry(image_info->density,&geometry_info); resolution.x=geometry_info.rho; resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) resolution.y=resolution.x; } if (image->units == PixelsPerCentimeterResolution) { resolution.x=(size_t) (100.0*2.54*resolution.x+0.5)/100.0; resolution.y=(size_t) (100.0*2.54*resolution.y+0.5)/100.0; } SetGeometry(image,&geometry); (void) FormatLocaleString(page_geometry,MaxTextExtent,"%.20gx%.20g", (double) image->columns,(double) image->rows); if (image_info->page != (char *) NULL) (void) CopyMagickString(page_geometry,image_info->page,MaxTextExtent); else if ((image->page.width != 0) && (image->page.height != 0)) (void) FormatLocaleString(page_geometry,MaxTextExtent, "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,(double) image->page.height,(double) image->page.x,(double) image->page.y); else if ((image->gravity != UndefinedGravity) && (LocaleCompare(image_info->magick,"PS") == 0)) (void) CopyMagickString(page_geometry,PSPageGeometry,MaxTextExtent); (void) ConcatenateMagickString(page_geometry,">",MaxTextExtent); (void) ParseMetaGeometry(page_geometry,&geometry.x,&geometry.y, &geometry.width,&geometry.height); scale.x=(double) (geometry.width*delta.x)/resolution.x; geometry.width=(size_t) floor(scale.x+0.5); scale.y=(double) (geometry.height*delta.y)/resolution.y; geometry.height=(size_t) floor(scale.y+0.5); (void) ParseAbsoluteGeometry(page_geometry,&media_info); (void) ParseGravityGeometry(image,page_geometry,&page_info, &image->exception); if (image->gravity != UndefinedGravity) { geometry.x=(-page_info.x); geometry.y=(ssize_t) (media_info.height+page_info.y-image->rows); } pointsize=12.0; if (image_info->pointsize != 0.0) pointsize=image_info->pointsize; text_size=0; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) text_size=(size_t) (MultilineCensus(value)*pointsize+12); if (page == 1) { /* Output Postscript header. */ if (LocaleCompare(image_info->magick,"PS2") == 0) (void) CopyMagickString(buffer,"%!PS-Adobe-3.0\n",MaxTextExtent); else (void) CopyMagickString(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n", MaxTextExtent); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"%%Creator: (ImageMagick)\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Title: (%s)\n", image->filename); (void) WriteBlobString(image,buffer); timer=time((time_t *) NULL); (void) FormatMagickTime(timer,MaxTextExtent,date); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%CreationDate: (%s)\n",date); (void) WriteBlobString(image,buffer); bounds.x1=(double) geometry.x; bounds.y1=(double) geometry.y; bounds.x2=(double) geometry.x+geometry.width; bounds.y2=(double) geometry.y+geometry.height+text_size; if ((image_info->adjoin != MagickFalse) && (GetNextImageInList(image) != (Image *) NULL)) (void) CopyMagickString(buffer,"%%BoundingBox: (atend)\n", MaxTextExtent); else { (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BoundingBox: %.20g %.20g %.20g %.20g\n",ceil(bounds.x1-0.5), ceil(bounds.y1-0.5),floor(bounds.x2+0.5),floor(bounds.y2+0.5)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1, bounds.y1,bounds.x2,bounds.y2); } (void) WriteBlobString(image,buffer); value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image, "%%DocumentNeededResources: font Helvetica\n"); (void) WriteBlobString(image,"%%LanguageLevel: 2\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"%%Pages: 1\n"); else { (void) WriteBlobString(image,"%%Orientation: Portrait\n"); (void) WriteBlobString(image,"%%PageOrder: Ascend\n"); if (image_info->adjoin == MagickFalse) (void) CopyMagickString(buffer,"%%Pages: 1\n",MaxTextExtent); else (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%Pages: %.20g\n",(double) GetImageListLength(image)); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EndComments\n"); (void) WriteBlobString(image,"\n%%BeginDefaults\n"); (void) WriteBlobString(image,"%%EndDefaults\n\n"); /* Output Postscript commands. */ for (q=PostscriptProlog; *q; q++) { switch (compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/ASCII85Decode filter"); break; } case JPEGCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/DCTDecode filter"); break; } case LZWCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/LZWDecode filter"); break; } case FaxCompression: case Group4Compression: { (void) FormatLocaleString(buffer,MaxTextExtent,*q," "); break; } default: { (void) FormatLocaleString(buffer,MaxTextExtent,*q, "/RunLengthDecode filter"); break; } } (void) WriteBlobString(image,buffer); (void) WriteBlobByte(image,'\n'); } value=GetImageProperty(image,"label"); if (value != (const char *) NULL) for (j=(ssize_t) MultilineCensus(value)-1; j >= 0; j--) { (void) WriteBlobString(image," /label 512 string def\n"); (void) WriteBlobString(image," currentfile label readline pop\n"); (void) FormatLocaleString(buffer,MaxTextExtent, " 0 y %g add moveto label show pop\n",j*pointsize+12); (void) WriteBlobString(image,buffer); } for (q=PostscriptEpilog; *q; q++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%s\n",*q); (void) WriteBlobString(image,buffer); } if (LocaleCompare(image_info->magick,"PS2") == 0) (void) WriteBlobString(image," showpage\n"); (void) WriteBlobString(image,"} bind def\n"); (void) WriteBlobString(image,"%%EndProlog\n"); } (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Page: 1 %.20g\n", (double) page++); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%PageBoundingBox: %.20g %.20g %.20g %.20g\n",(double) geometry.x, (double) geometry.y,geometry.x+(double) geometry.width,geometry.y+(double) (geometry.height+text_size)); (void) WriteBlobString(image,buffer); if ((double) geometry.x < bounds.x1) bounds.x1=(double) geometry.x; if ((double) geometry.y < bounds.y1) bounds.y1=(double) geometry.y; if ((double) (geometry.x+geometry.width-1) > bounds.x2) bounds.x2=(double) geometry.x+geometry.width-1; if ((double) (geometry.y+(geometry.height+text_size)-1) > bounds.y2) bounds.y2=(double) geometry.y+(geometry.height+text_size)-1; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image,"%%PageResources: font Times-Roman\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"userdict begin\n"); start=TellBlob(image); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",0L, compression == NoCompression ? "ASCII" : "Binary"); (void) WriteBlobString(image,buffer); stop=TellBlob(image); (void) WriteBlobString(image,"DisplayImage\n"); /* Output image data. */ (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n%g %g\n%g\n", (double) geometry.x,(double) geometry.y,scale.x,scale.y,pointsize); (void) WriteBlobString(image,buffer); labels=(char **) NULL; value=GetImageProperty(image,"label"); if (value != (const char *) NULL) labels=StringToList(value); if (labels != (char **) NULL) { for (i=0; labels[i] != (char *) NULL; i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%s \n", labels[i]); (void) WriteBlobString(image,buffer); labels[i]=DestroyString(labels[i]); } labels=(char **) RelinquishMagickMemory(labels); } number_pixels=(MagickSizeType) image->columns*image->rows; if (number_pixels != (MagickSizeType) ((size_t) number_pixels)) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); if ((compression == FaxCompression) || (compression == Group4Compression) || ((image_info->type != TrueColorType) && (IsGrayImage(image,&image->exception) != MagickFalse))) { (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) ((compression != FaxCompression) && (compression != Group4Compression))); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"0\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (compression == FaxCompression) || (compression == Group4Compression) ? 1 : 8); (void) WriteBlobString(image,buffer); switch (compression) { case FaxCompression: case Group4Compression: { if (LocaleCompare(CCITTParam,"0") == 0) { (void) HuffmanEncodeImage(image_info,image,image); break; } (void) Huffman2DEncodeImage(image_info,image,image); break; } case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); if (status == MagickFalse) ThrowWriterException(CoderError,image->exception.reason); break; } case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Dump Runlength encoded pixels. */ q=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; for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p)); p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case NoCompression: { /* Dump uncompressed PseudoColor packets. */ Ascii85Initialize(image); 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; for (x=0; x < (ssize_t) image->columns; x++) { Ascii85Encode(image,ScaleQuantumToChar( PixelIntensityToQuantum(p))); p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } else if ((image->storage_class == DirectClass) || (image->colors > 256) || (compression == JPEGCompression) || (image->matte != MagickFalse)) { (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n0\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); switch (compression) { case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); if (status == MagickFalse) ThrowWriterException(CoderError,image->exception.reason); break; } case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); /* Dump Packbit encoded pixels. */ q=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; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { if ((image->matte != MagickFalse) && (GetPixelOpacity(p) == (Quantum) TransparentOpacity)) { *q++=ScaleQuantumToChar((Quantum) QuantumRange); *q++=ScaleQuantumToChar((Quantum) QuantumRange); *q++=ScaleQuantumToChar((Quantum) QuantumRange); } else if (image->colorspace != CMYKColorspace) { *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); } else { *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); *q++=ScaleQuantumToChar(GetPixelIndex( indexes+x)); } p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } pixels=(unsigned char *) RelinquishMagickMemory(pixels); break; } case NoCompression: { /* Dump uncompressed DirectColor packets. */ Ascii85Initialize(image); 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; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { if ((image->matte != MagickFalse) && (GetPixelOpacity(p) == (Quantum) TransparentOpacity)) { Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); } else if (image->colorspace != CMYKColorspace) { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(p))); } else { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelIndex(indexes+x))); } p++; } progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } else { /* Dump number of colors and colormap. */ (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",(double) image->colors); (void) WriteBlobString(image,buffer); for (i=0; i < (ssize_t) image->colors; i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"%02X%02X%02X\n", ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue)); (void) WriteBlobString(image,buffer); } switch (compression) { case RLECompression: default: { register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); /* Dump Runlength encoded pixels. */ q=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; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) *q++=(unsigned char) GetPixelIndex(indexes+x); progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } length=(size_t) (q-pixels); if (compression == LZWCompression) status=LZWEncodeImage(image,length,pixels); else status=PackbitsEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case NoCompression: { /* Dump uncompressed PseudoColor packets. */ Ascii85Initialize(image); 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; indexes=GetVirtualIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) Ascii85Encode(image,(unsigned char) GetPixelIndex( indexes+x)); progress=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows); if (progress == MagickFalse) break; } Ascii85Flush(image); break; } } } (void) WriteBlobByte(image,'\n'); length=(size_t) (TellBlob(image)-stop); stop=TellBlob(image); offset=SeekBlob(image,start,SEEK_SET); if (offset < 0) ThrowWriterException(CorruptImageError,"ImproperImageHeader"); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",(long) length, compression == NoCompression ? "ASCII" : "Binary"); (void) WriteBlobString(image,buffer); offset=SeekBlob(image,stop,SEEK_SET); (void) WriteBlobString(image,"%%EndData\n"); if (LocaleCompare(image_info->magick,"PS2") != 0) (void) WriteBlobString(image,"end\n"); (void) WriteBlobString(image,"%%PageTrailer\n"); 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,"%%Trailer\n"); if (page > 1) { (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%BoundingBox: %.20g %.20g %.20g %.20g\n",ceil(bounds.x1-0.5), ceil(bounds.y1-0.5),floor(bounds.x2+0.5),floor(bounds.y2+0.5)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,bounds.y1, bounds.x2,bounds.y2); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EOF\n"); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e A V S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteAVSImage() writes an image to a file in AVS X image format. % % The format of the WriteAVSImage method is: % % MagickBooleanType WriteAVSImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteAVSImage(const ImageInfo *image_info,Image *image) { MagickBooleanType status; MagickOffsetType scene; register const PixelPacket *restrict p; register ssize_t x; register unsigned char *restrict q; ssize_t count, 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 { /* Write AVS header. */ if (image->colorspace != RGBColorspace) (void) TransformImageColorspace(image,RGBColorspace); (void) WriteBlobMSBLong(image,(unsigned int) image->columns); (void) WriteBlobMSBLong(image,(unsigned int) image->rows); /* Allocate memory for pixels. */ pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->columns, 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert MIFF to AVS raster pixels. */ for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (PixelPacket *) NULL) break; q=pixels; for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar((Quantum) (QuantumRange-(image->matte != MagickFalse ? GetPixelOpacity(p) : OpaqueOpacity))); *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); p++; } count=WriteBlob(image,(size_t) (q-pixels),pixels); if (count != (ssize_t) (q-pixels)) break; 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; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
MagickExport Image *OilPaintImage(const Image *image,const double radius, ExceptionInfo *exception) { #define NumberPaintBins 256 #define OilPaintImageTag "OilPaint/Image" CacheView *image_view, *paint_view; Image *paint_image; MagickBooleanType status; MagickOffsetType progress; size_t **restrict histograms, width; ssize_t y; /* Initialize painted image attributes. */ assert(image != (const Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); width=GetOptimalKernelWidth2D(radius,0.5); paint_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception); if (paint_image == (Image *) NULL) return((Image *) NULL); if (SetImageStorageClass(paint_image,DirectClass) == MagickFalse) { InheritException(exception,&paint_image->exception); paint_image=DestroyImage(paint_image); return((Image *) NULL); } histograms=AcquireHistogramThreadSet(NumberPaintBins); if (histograms == (size_t **) NULL) { paint_image=DestroyImage(paint_image); ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); } /* Oil paint image. */ status=MagickTrue; progress=0; image_view=AcquireVirtualCacheView(image,exception); paint_view=AcquireAuthenticCacheView(paint_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(progress,status) \ IsConcurrentDos(image->columns,image->rows,64) #endif for (y=0; y < (ssize_t) image->rows; y++) { register const IndexPacket *restrict indexes; register const PixelPacket *restrict p; register IndexPacket *restrict paint_indexes; register ssize_t x; register PixelPacket *restrict q; register size_t *histogram; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,-((ssize_t) width/2L),y-(ssize_t) (width/2L),image->columns+width,width,exception); q=QueueCacheViewAuthenticPixels(paint_view,0,y,paint_image->columns,1, exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) { status=MagickFalse; continue; } indexes=GetCacheViewVirtualIndexQueue(image_view); paint_indexes=GetCacheViewAuthenticIndexQueue(paint_view); histogram=histograms[GetOpenMPThreadId()]; for (x=0; x < (ssize_t) image->columns; x++) { register ssize_t i, u; size_t count; ssize_t j, k, v; /* Assign most frequent color. */ i=0; j=0; count=0; (void) ResetMagickMemory(histogram,0,NumberPaintBins*sizeof(*histogram)); for (v=0; v < (ssize_t) width; v++) { for (u=0; u < (ssize_t) width; u++) { k=(ssize_t) ScaleQuantumToChar(PixelIntensityToQuantum(p+u+i)); histogram[k]++; if (histogram[k] > count) { j=i+u; count=histogram[k]; } } i+=(ssize_t) (image->columns+width); } *q=(*(p+j)); if (image->colorspace == CMYKColorspace) SetPixelIndex(paint_indexes+x,GetPixelIndex( indexes+x+j)); p++; q++; } if (SyncCacheViewAuthenticPixels(paint_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_OilPaintImage) #endif proceed=SetImageProgress(image,OilPaintImageTag,progress++,image->rows); if (proceed == MagickFalse) status=MagickFalse; } } paint_view=DestroyCacheView(paint_view); image_view=DestroyCacheView(image_view); histograms=DestroyHistogramThreadSet(histograms); if (status == MagickFalse) paint_image=DestroyImage(paint_image); return(paint_image); }