/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e P I C O N I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WritePICONImage() writes an image to a file in the Personal Icon format. % % The format of the WritePICONImage method is: % % MagickBooleanType WritePICONImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WritePICONImage(const ImageInfo *image_info, Image *image) { #define ColormapExtent 155 #define GraymapExtent 95 #define PiconGeometry "48x48>" static unsigned char Colormap[]= { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x06, 0x00, 0x05, 0x00, 0xf4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x4f, 0x4f, 0x70, 0x80, 0x90, 0x7e, 0x7e, 0x7e, 0xdc, 0xdc, 0xdc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0xff, 0x1e, 0x90, 0xff, 0x87, 0xce, 0xeb, 0xe6, 0xe6, 0xfa, 0x00, 0xff, 0xff, 0x80, 0x00, 0x80, 0xb2, 0x22, 0x22, 0x2e, 0x8b, 0x57, 0x32, 0xcd, 0x32, 0x00, 0xff, 0x00, 0x98, 0xfb, 0x98, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x63, 0x47, 0xff, 0xa5, 0x00, 0xff, 0xd7, 0x00, 0xff, 0xff, 0x00, 0xee, 0x82, 0xee, 0xa0, 0x52, 0x2d, 0xcd, 0x85, 0x3f, 0xd2, 0xb4, 0x8c, 0xf5, 0xde, 0xb3, 0xff, 0xfa, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x05, 0x18, 0x20, 0x10, 0x08, 0x03, 0x51, 0x18, 0x07, 0x92, 0x28, 0x0b, 0xd3, 0x38, 0x0f, 0x14, 0x49, 0x13, 0x55, 0x59, 0x17, 0x96, 0x69, 0x1b, 0xd7, 0x85, 0x00, 0x3b, }, Graymap[]= { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x04, 0x00, 0x04, 0x00, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x21, 0x21, 0x21, 0x33, 0x33, 0x33, 0x45, 0x45, 0x45, 0x54, 0x54, 0x54, 0x66, 0x66, 0x66, 0x78, 0x78, 0x78, 0x87, 0x87, 0x87, 0x99, 0x99, 0x99, 0xab, 0xab, 0xab, 0xba, 0xba, 0xba, 0xcc, 0xcc, 0xcc, 0xde, 0xde, 0xde, 0xed, 0xed, 0xed, 0xff, 0xff, 0xff, 0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x0c, 0x10, 0x04, 0x31, 0x48, 0x31, 0x07, 0x25, 0xb5, 0x58, 0x73, 0x4f, 0x04, 0x00, 0x3b, }; #define MaxCixels 92 static const char Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk" "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; char buffer[MaxTextExtent], basename[MaxTextExtent], name[MaxTextExtent], symbol[MaxTextExtent]; ExceptionInfo *exception; Image *affinity_image, *picon; ImageInfo *blob_info; MagickBooleanType status, transparent; MagickPixelPacket pixel; QuantizeInfo *quantize_info; RectangleInfo geometry; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t i, x; register PixelPacket *q; size_t characters_per_pixel, colors; ssize_t j, k, y; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) TransformImageColorspace(image,sRGBColorspace); SetGeometry(image,&geometry); (void) ParseMetaGeometry(PiconGeometry,&geometry.x,&geometry.y, &geometry.width,&geometry.height); picon=ResizeImage(image,geometry.width,geometry.height,TriangleFilter,1.0, &image->exception); blob_info=CloneImageInfo(image_info); (void) AcquireUniqueFilename(blob_info->filename); if ((image_info->type != TrueColorType) && (SetImageGray(image,&image->exception) != MagickFalse)) affinity_image=BlobToImage(blob_info,Graymap,GraymapExtent, &image->exception); else affinity_image=BlobToImage(blob_info,Colormap,ColormapExtent, &image->exception); (void) RelinquishUniqueFileResource(blob_info->filename); blob_info=DestroyImageInfo(blob_info); if ((picon == (Image *) NULL) || (affinity_image == (Image *) NULL)) return(MagickFalse); quantize_info=AcquireQuantizeInfo(image_info); status=RemapImage(quantize_info,picon,affinity_image); quantize_info=DestroyQuantizeInfo(quantize_info); affinity_image=DestroyImage(affinity_image); transparent=MagickFalse; exception=(&image->exception); if (picon->storage_class == PseudoClass) { (void) CompressImageColormap(picon); if (picon->matte != MagickFalse) transparent=MagickTrue; } else { /* Convert DirectClass to PseudoClass picon. */ if (picon->matte != MagickFalse) { /* Map all the transparent pixels. */ for (y=0; y < (ssize_t) picon->rows; y++) { q=GetAuthenticPixels(picon,0,y,picon->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) picon->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) transparent=MagickTrue; else SetPixelOpacity(q,OpaqueOpacity); q++; } if (SyncAuthenticPixels(picon,exception) == MagickFalse) break; } } (void) SetImageType(picon,PaletteType); } colors=picon->colors; if (transparent != MagickFalse) { register IndexPacket *indexes; colors++; picon->colormap=(PixelPacket *) ResizeQuantumMemory((void **) picon->colormap,(size_t) colors,sizeof(*picon->colormap)); if (picon->colormap == (PixelPacket *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationError"); for (y=0; y < (ssize_t) picon->rows; y++) { q=GetAuthenticPixels(picon,0,y,picon->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(picon); for (x=0; x < (ssize_t) picon->columns; x++) { if (q->opacity == (Quantum) TransparentOpacity) SetPixelIndex(indexes+x,picon->colors); q++; } if (SyncAuthenticPixels(picon,exception) == MagickFalse) break; } } /* Compute the character per pixel. */ characters_per_pixel=1; for (k=MaxCixels; (ssize_t) colors > k; k*=MaxCixels) characters_per_pixel++; /* XPM header. */ (void) WriteBlobString(image,"/* XPM */\n"); GetPathComponent(picon->filename,BasePath,basename); (void) FormatLocaleString(buffer,MaxTextExtent, "static char *%s[] = {\n",basename); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"/* columns rows colors chars-per-pixel */\n"); (void) FormatLocaleString(buffer,MaxTextExtent, "\"%.20g %.20g %.20g %.20g\",\n",(double) picon->columns,(double) picon->rows,(double) colors,(double) characters_per_pixel); (void) WriteBlobString(image,buffer); GetMagickPixelPacket(image,&pixel); for (i=0; i < (ssize_t) colors; i++) { /* Define XPM color. */ SetMagickPixelPacket(image,picon->colormap+i,(IndexPacket *) NULL,&pixel); pixel.colorspace=sRGBColorspace; pixel.depth=8; pixel.opacity=(MagickRealType) OpaqueOpacity; (void) QueryMagickColorname(image,&pixel,XPMCompliance,name, &image->exception); if (transparent != MagickFalse) { if (i == (ssize_t) (colors-1)) (void) CopyMagickString(name,"grey75",MaxTextExtent); } /* Write XPM color. */ k=i % MaxCixels; symbol[0]=Cixel[k]; for (j=1; j < (ssize_t) characters_per_pixel; j++) { k=((i-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) FormatLocaleString(buffer,MaxTextExtent,"\"%s c %s\",\n", symbol,name); (void) WriteBlobString(image,buffer); } /* Define XPM pixels. */ (void) WriteBlobString(image,"/* pixels */\n"); for (y=0; y < (ssize_t) picon->rows; y++) { p=GetVirtualPixels(picon,0,y,picon->columns,1,&picon->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetVirtualIndexQueue(picon); (void) WriteBlobString(image,"\""); for (x=0; x < (ssize_t) picon->columns; x++) { k=((ssize_t) GetPixelIndex(indexes+x) % MaxCixels); symbol[0]=Cixel[k]; for (j=1; j < (ssize_t) characters_per_pixel; j++) { k=(((int) GetPixelIndex(indexes+x)-k)/MaxCixels) % MaxCixels; symbol[j]=Cixel[k]; } symbol[j]='\0'; (void) CopyMagickString(buffer,symbol,MaxTextExtent); (void) WriteBlobString(image,buffer); } (void) FormatLocaleString(buffer,MaxTextExtent,"\"%s\n", y == (ssize_t) (picon->rows-1) ? "" : ","); (void) WriteBlobString(image,buffer); status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, picon->rows); if (status == MagickFalse) break; } picon=DestroyImage(picon); (void) WriteBlobString(image,"};\n"); (void) CloseBlob(image); return(MagickTrue); }
static MagickBooleanType WriteVIPSImage(const ImageInfo *image_info, Image *image) { const char *metadata; MagickBooleanType status; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t x; ssize_t y; unsigned int channels; assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image->endian == LSBEndian) (void) WriteBlobLSBLong(image,VIPS_MAGIC_LSB); else (void) WriteBlobLSBLong(image,VIPS_MAGIC_MSB); (void) WriteBlobLong(image,(unsigned int) image->columns); (void) WriteBlobLong(image,(unsigned int) image->rows); (void) SetImageStorageClass(image,DirectClass); channels=image->matte ? 4 : 3; if (SetImageGray(image,&image->exception) != MagickFalse) channels=image->matte ? 2 : 1; else if (image->colorspace == CMYKColorspace) channels=image->matte ? 5 : 4; (void) WriteBlobLong(image,channels); (void) WriteBlobLong(image,0); if (image->depth == 16) (void) WriteBlobLong(image,(unsigned int) VIPSBandFormatUSHORT); else { image->depth=8; (void) WriteBlobLong(image,(unsigned int) VIPSBandFormatUCHAR); } (void) WriteBlobLong(image,VIPSCodingNONE); switch(image->colorspace) { case CMYKColorspace: (void) WriteBlobLong(image,VIPSTypeCMYK); break; case GRAYColorspace: if (image->depth == 16) (void) WriteBlobLong(image, VIPSTypeGREY16); else (void) WriteBlobLong(image, VIPSTypeB_W); break; case RGBColorspace: if (image->depth == 16) (void) WriteBlobLong(image, VIPSTypeRGB16); else (void) WriteBlobLong(image, VIPSTypeRGB); break; default: case sRGBColorspace: (void) SetImageColorspace(image,sRGBColorspace); (void) WriteBlobLong(image,VIPSTypesRGB); break; } if (image->units == PixelsPerCentimeterResolution) { (void) WriteBlobFloat(image,(image->x_resolution / 10)); (void) WriteBlobFloat(image,(image->y_resolution / 10)); } else if (image->units == PixelsPerInchResolution) { (void) WriteBlobFloat(image,(image->x_resolution / 25.4)); (void) WriteBlobFloat(image,(image->y_resolution / 25.4)); } else { (void) WriteBlobLong(image,0); (void) WriteBlobLong(image,0); } /* Legacy, Offsets, Future */ for (y=0; y < 24; y++) (void) WriteBlobByte(image,0); 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++) { WriteVIPSPixel(image,GetPixelRed(p)); if (channels == 2) WriteVIPSPixel(image,GetPixelAlpha(p)); else { WriteVIPSPixel(image,GetPixelGreen(p)); WriteVIPSPixel(image,GetPixelBlue(p)); if (channels >= 4) { if (image->colorspace == CMYKColorspace) WriteVIPSPixel(image,GetPixelIndex(indexes+x)); else WriteVIPSPixel(image,GetPixelAlpha(p)); } else if (channels == 5) { WriteVIPSPixel(image,GetPixelIndex(indexes+x)); WriteVIPSPixel(image,GetPixelAlpha(p)); } } p++; } } metadata=GetImageProperty(image,"vips:metadata"); if (metadata != (const char*) NULL) WriteBlobString(image,metadata); (void) CloseBlob(image); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e F I T S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteFITSImage() writes a Flexible Image Transport System image to a % file as gray scale intensities [0..255]. % % The format of the WriteFITSImage method is: % % MagickBooleanType WriteFITSImage(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 WriteFITSImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { char header[FITSBlocksize], *fits_info; MagickBooleanType status; QuantumInfo *quantum_info; register const Quantum *p; size_t length; ssize_t count, offset, y; 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); (void) TransformImageColorspace(image,sRGBColorspace,exception); /* Allocate image memory. */ fits_info=(char *) AcquireQuantumMemory(FITSBlocksize,sizeof(*fits_info)); if (fits_info == (char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(fits_info,' ',FITSBlocksize*sizeof(*fits_info)); /* Initialize image header. */ image->depth=GetImageQuantumDepth(image,MagickFalse); image->endian=MSBEndian; quantum_info=AcquireQuantumInfo(image_info,image); if (quantum_info == (QuantumInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); offset=0; (void) FormatLocaleString(header,FITSBlocksize, "SIMPLE = T"); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatLocaleString(header,FITSBlocksize,"BITPIX = %10ld", (long) ((quantum_info->format == FloatingPointQuantumFormat ? -1 : 1)* image->depth)); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatLocaleString(header,FITSBlocksize,"NAXIS = %10lu", SetImageGray(image,exception) != MagickFalse ? 2UL : 3UL); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatLocaleString(header,FITSBlocksize,"NAXIS1 = %10lu", (unsigned long) image->columns); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatLocaleString(header,FITSBlocksize,"NAXIS2 = %10lu", (unsigned long) image->rows); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; if (SetImageGray(image,exception) == MagickFalse) { (void) FormatLocaleString(header,FITSBlocksize, "NAXIS3 = %10lu",3UL); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; } (void) FormatLocaleString(header,FITSBlocksize,"BSCALE = %E",1.0); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatLocaleString(header,FITSBlocksize,"BZERO = %E", image->depth > 8 ? GetFITSPixelRange(image->depth)/2.0 : 0.0); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatLocaleString(header,FITSBlocksize,"DATAMAX = %E", 1.0*((MagickOffsetType) GetQuantumRange(image->depth))); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatLocaleString(header,FITSBlocksize,"DATAMIN = %E",0.0); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; if (image->endian == LSBEndian) { (void) FormatLocaleString(header,FITSBlocksize,"XENDIAN = 'SMALL'"); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; } (void) FormatLocaleString(header,FITSBlocksize,"HISTORY %.72s", GetMagickVersion((size_t *) NULL)); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) strncpy(header,"END",FITSBlocksize); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) WriteBlob(image,FITSBlocksize,(unsigned char *) fits_info); /* Convert image to fits scale PseudoColor class. */ pixels=(unsigned char *) GetQuantumPixels(quantum_info); if (SetImageGray(image,exception) != MagickFalse) { length=GetQuantumExtent(image,quantum_info,GrayQuantum); for (y=(ssize_t) image->rows-1; y >= 0; y--) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, GrayQuantum,pixels,exception); if (image->depth == 16) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); if (((image->depth == 32) || (image->depth == 64)) && (quantum_info->format != FloatingPointQuantumFormat)) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); count=WriteBlob(image,length,pixels); if (count != (ssize_t) length) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } else { length=GetQuantumExtent(image,quantum_info,RedQuantum); for (y=(ssize_t) image->rows-1; y >= 0; y--) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, RedQuantum,pixels,exception); if (image->depth == 16) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); if (((image->depth == 32) || (image->depth == 64)) && (quantum_info->format != FloatingPointQuantumFormat)) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); count=WriteBlob(image,length,pixels); if (count != (ssize_t) length) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } length=GetQuantumExtent(image,quantum_info,GreenQuantum); for (y=(ssize_t) image->rows-1; y >= 0; y--) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, GreenQuantum,pixels,exception); if (image->depth == 16) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); if (((image->depth == 32) || (image->depth == 64)) && (quantum_info->format != FloatingPointQuantumFormat)) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); count=WriteBlob(image,length,pixels); if (count != (ssize_t) length) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } length=GetQuantumExtent(image,quantum_info,BlueQuantum); for (y=(ssize_t) image->rows-1; y >= 0; y--) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, BlueQuantum,pixels,exception); if (image->depth == 16) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); if (((image->depth == 32) || (image->depth == 64)) && (quantum_info->format != FloatingPointQuantumFormat)) SetFITSUnsignedPixels(image->columns,image->depth,image->endian, pixels); count=WriteBlob(image,length,pixels); if (count != (ssize_t) length) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } quantum_info=DestroyQuantumInfo(quantum_info); length=(size_t) (FITSBlocksize-TellBlob(image) % FITSBlocksize); if (length != 0) { (void) ResetMagickMemory(fits_info,0,length*sizeof(*fits_info)); (void) WriteBlob(image,length,(unsigned char *) fits_info); } fits_info=DestroyString(fits_info); (void) CloseBlob(image); return(MagickTrue); }
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 WritePS2Image(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { static const char *const 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", (const char *) NULL }, *const 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", " grestore", (const char *) NULL }; char buffer[MagickPathExtent], date[MagickPathExtent], page_geometry[MagickPathExtent], **labels; CompressionType compression; const char *const *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 Quantum *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 == 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); 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(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->resolution.x; resolution.y=image->resolution.y; 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,MagickPathExtent,"%.20gx%.20g", (double) image->columns,(double) image->rows); if (image_info->page != (char *) NULL) (void) CopyMagickString(page_geometry,image_info->page,MagickPathExtent); else if ((image->page.width != 0) && (image->page.height != 0)) (void) FormatLocaleString(page_geometry,MagickPathExtent, "%.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,MagickPathExtent); (void) ConcatenateMagickString(page_geometry,">",MagickPathExtent); (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,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",exception); 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",MagickPathExtent); else (void) CopyMagickString(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n", MagickPathExtent); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"%%Creator: (ImageMagick)\n"); (void) FormatLocaleString(buffer,MagickPathExtent,"%%%%Title: (%s)\n", image->filename); (void) WriteBlobString(image,buffer); timer=time((time_t *) NULL); (void) FormatMagickTime(timer,MagickPathExtent,date); (void) FormatLocaleString(buffer,MagickPathExtent, "%%%%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", MagickPathExtent); else { (void) FormatLocaleString(buffer,MagickPathExtent, "%%%%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,MagickPathExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1, bounds.y1,bounds.x2,bounds.y2); } (void) WriteBlobString(image,buffer); value=GetImageProperty(image,"label",exception); 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",MagickPathExtent); else (void) FormatLocaleString(buffer,MagickPathExtent, "%%%%Pages: %.20g\n",(double) GetImageListLength(image)); (void) WriteBlobString(image,buffer); } if (image->colorspace == CMYKColorspace) (void) WriteBlobString(image, "%%DocumentProcessColors: Cyan Magenta Yellow Black\n"); (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,MagickPathExtent,*q, "/ASCII85Decode filter"); break; } case JPEGCompression: { (void) FormatLocaleString(buffer,MagickPathExtent,*q, "/DCTDecode filter"); break; } case LZWCompression: { (void) FormatLocaleString(buffer,MagickPathExtent,*q, "/LZWDecode filter"); break; } case FaxCompression: case Group4Compression: { (void) FormatLocaleString(buffer,MagickPathExtent,*q," "); break; } default: { (void) FormatLocaleString(buffer,MagickPathExtent,*q, "/RunLengthDecode filter"); break; } } (void) WriteBlobString(image,buffer); (void) WriteBlobByte(image,'\n'); } value=GetImageProperty(image,"label",exception); 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,MagickPathExtent, " 0 y %g add moveto label show pop\n",j*pointsize+12); (void) WriteBlobString(image,buffer); } for (q=PostscriptEpilog; *q; q++) { (void) FormatLocaleString(buffer,MagickPathExtent,"%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,MagickPathExtent,"%%%%Page: 1 %.20g\n", (double) page++); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent, "%%%%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",exception); 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,MagickPathExtent, "%%%%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,MagickPathExtent,"%.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",exception); if (value != (const char *) NULL) labels=StringToList(value); if (labels != (char **) NULL) { for (i=0; labels[i] != (char *) NULL; i++) { (void) FormatLocaleString(buffer,MagickPathExtent,"%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) && (SetImageGray(image,exception) != MagickFalse))) { (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"%d\n", (int) ((compression != FaxCompression) && (compression != Group4Compression))); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"0\n"); (void) FormatLocaleString(buffer,MagickPathExtent,"%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,exception); break; } (void) Huffman2DEncodeImage(image_info,image,image,exception); break; } case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg",exception); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case RLECompression: default: { MemoryInfo *pixel_info; register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixel_info=AcquireVirtualMemory(length,sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info); /* Dump runlength encoded pixels. */ q=pixels; 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++) { *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelLuma(image,p))); p+=GetPixelChannels(image); } 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,exception); else status=PackbitsEncodeImage(image,length,pixels,exception); pixel_info=RelinquishVirtualMemory(pixel_info); 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,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { Ascii85Encode(image,ScaleQuantumToChar(ClampToQuantum( GetPixelLuma(image,p)))); p+=GetPixelChannels(image); } 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->alpha_trait != UndefinedPixelTrait)) { (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g %.20g\n0\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); switch (compression) { case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg",exception); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } break; } case RLECompression: default: { MemoryInfo *pixel_info; register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixel_info=AcquireVirtualMemory(length,4*sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info); /* Dump runlength encoded pixels. */ q=pixels; 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 ((image->alpha_trait != UndefinedPixelTrait) && (GetPixelAlpha(image,p) == (Quantum) TransparentAlpha)) { *q++=ScaleQuantumToChar(QuantumRange); *q++=ScaleQuantumToChar(QuantumRange); *q++=ScaleQuantumToChar(QuantumRange); } else if (image->colorspace != CMYKColorspace) { *q++=ScaleQuantumToChar(GetPixelRed(image,p)); *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); } else { *q++=ScaleQuantumToChar(GetPixelRed(image,p)); *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); *q++=ScaleQuantumToChar(GetPixelBlack(image,p)); } p+=GetPixelChannels(image); } 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,exception); else status=PackbitsEncodeImage(image,length,pixels,exception); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } pixel_info=RelinquishVirtualMemory(pixel_info); 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,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { if ((image->alpha_trait != UndefinedPixelTrait) && (GetPixelAlpha(image,p) == (Quantum) TransparentAlpha)) { Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); Ascii85Encode(image,ScaleQuantumToChar((Quantum) QuantumRange)); } else if (image->colorspace != CMYKColorspace) { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(image,p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(image,p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(image,p))); } else { Ascii85Encode(image,ScaleQuantumToChar( GetPixelRed(image,p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelGreen(image,p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlue(image,p))); Ascii85Encode(image,ScaleQuantumToChar( GetPixelBlack(image,p))); } p+=GetPixelChannels(image); } 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,MagickPathExtent,"%.20g %.20g\n1\n%d\n", (double) image->columns,(double) image->rows,(int) (image->colorspace == CMYKColorspace)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"%d\n", (int) (compression == NoCompression)); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g\n",(double) image->colors); (void) WriteBlobString(image,buffer); for (i=0; i < (ssize_t) image->colors; i++) { (void) FormatLocaleString(buffer,MagickPathExtent,"%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: { MemoryInfo *pixel_info; register unsigned char *q; /* Allocate pixel array. */ length=(size_t) number_pixels; pixel_info=AcquireVirtualMemory(length,sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed"); pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info); /* Dump runlength encoded pixels. */ q=pixels; 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++) { *q++=(unsigned char) GetPixelIndex(image,p); p+=GetPixelChannels(image); } 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,exception); else status=PackbitsEncodeImage(image,length,pixels,exception); pixel_info=RelinquishVirtualMemory(pixel_info); 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,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { Ascii85Encode(image,(unsigned char) GetPixelIndex(image,p)); p+=GetPixelChannels(image); } 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,MagickPathExtent, "%%%%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,MagickPathExtent, "%%%%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,MagickPathExtent, "%%%%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); }