static inline void WriteVIPSPixel(Image *image, const Quantum value) { if (image->depth == 16) (void) WriteBlobShort(image,ScaleQuantumToShort(value)); else (void) WriteBlobByte(image,ScaleQuantumToChar(value)); }
static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { const char *value; CINInfo cin; const StringInfo *profile; MagickBooleanType status; MagickOffsetType offset; QuantumInfo *quantum_info; QuantumType quantum_type; register const Quantum *p; register ssize_t i; size_t length; ssize_t count, y; struct tm local_time; time_t seconds; 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); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); if (image->colorspace != LogColorspace) (void) TransformImageColorspace(image,LogColorspace,exception); /* Write image information. */ (void) ResetMagickMemory(&cin,0,sizeof(cin)); offset=0; cin.file.magic=0x802A5FD7UL; offset+=WriteBlobLong(image,(unsigned int) cin.file.magic); cin.file.image_offset=0x800; offset+=WriteBlobLong(image,(unsigned int) cin.file.image_offset); cin.file.generic_length=0x400; offset+=WriteBlobLong(image,(unsigned int) cin.file.generic_length); cin.file.industry_length=0x400; offset+=WriteBlobLong(image,(unsigned int) cin.file.industry_length); cin.file.user_length=0x00; profile=GetImageProfile(image,"dpx:user.data"); if (profile != (StringInfo *) NULL) { cin.file.user_length+=(size_t) GetStringInfoLength(profile); cin.file.user_length=(((cin.file.user_length+0x2000-1)/0x2000)*0x2000); } offset+=WriteBlobLong(image,(unsigned int) cin.file.user_length); cin.file.file_size=4*image->columns*image->rows+0x2000; offset+=WriteBlobLong(image,(unsigned int) cin.file.file_size); (void) CopyMagickString(cin.file.version,"V4.5",sizeof(cin.file.version)); offset+=WriteBlob(image,sizeof(cin.file.version),(unsigned char *) cin.file.version); value=GetCINProperty(image_info,image,"dpx:file.filename",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.file.filename,value,sizeof(cin.file.filename)); else (void) CopyMagickString(cin.file.filename,image->filename, sizeof(cin.file.filename)); offset+=WriteBlob(image,sizeof(cin.file.filename),(unsigned char *) cin.file.filename); seconds=time((time_t *) NULL); #if defined(MAGICKCORE_HAVE_LOCALTIME_R) (void) localtime_r(&seconds,&local_time); #else (void) memcpy(&local_time,localtime(&seconds),sizeof(local_time)); #endif (void) strftime(cin.file.create_date,sizeof(cin.file.create_date),"%Y:%m:%d", &local_time); offset+=WriteBlob(image,sizeof(cin.file.create_date),(unsigned char *) cin.file.create_date); (void) strftime(cin.file.create_time,sizeof(cin.file.create_time), "%H:%M:%S%Z",&local_time); offset+=WriteBlob(image,sizeof(cin.file.create_time),(unsigned char *) cin.file.create_time); offset+=WriteBlob(image,sizeof(cin.file.reserve),(unsigned char *) cin.file.reserve); cin.image.orientation=0x00; offset+=WriteBlobByte(image,cin.image.orientation); cin.image.number_channels=3; offset+=WriteBlobByte(image,cin.image.number_channels); offset+=WriteBlob(image,sizeof(cin.image.reserve1),(unsigned char *) cin.image.reserve1); for (i=0; i < 8; i++) { cin.image.channel[i].designator[0]=0; /* universal metric */ offset+=WriteBlobByte(image,cin.image.channel[0].designator[0]); cin.image.channel[i].designator[1]=(unsigned char) (i > 3 ? 0 : i+1); /* channel color */; offset+=WriteBlobByte(image,cin.image.channel[1].designator[0]); cin.image.channel[i].bits_per_pixel=(unsigned char) image->depth; offset+=WriteBlobByte(image,cin.image.channel[0].bits_per_pixel); offset+=WriteBlobByte(image,cin.image.channel[0].reserve); cin.image.channel[i].pixels_per_line=image->columns; offset+=WriteBlobLong(image,(unsigned int) cin.image.channel[0].pixels_per_line); cin.image.channel[i].lines_per_image=image->rows; offset+=WriteBlobLong(image,(unsigned int) cin.image.channel[0].lines_per_image); cin.image.channel[i].min_data=0; offset+=WriteBlobFloat(image,cin.image.channel[0].min_data); cin.image.channel[i].min_quantity=0.0; offset+=WriteBlobFloat(image,cin.image.channel[0].min_quantity); cin.image.channel[i].max_data=(float) ((MagickOffsetType) GetQuantumRange(image->depth)); offset+=WriteBlobFloat(image,cin.image.channel[0].max_data); cin.image.channel[i].max_quantity=2.048f; offset+=WriteBlobFloat(image,cin.image.channel[0].max_quantity); } offset+=WriteBlobFloat(image,image->chromaticity.white_point.x); offset+=WriteBlobFloat(image,image->chromaticity.white_point.y); offset+=WriteBlobFloat(image,image->chromaticity.red_primary.x); offset+=WriteBlobFloat(image,image->chromaticity.red_primary.y); offset+=WriteBlobFloat(image,image->chromaticity.green_primary.x); offset+=WriteBlobFloat(image,image->chromaticity.green_primary.y); offset+=WriteBlobFloat(image,image->chromaticity.blue_primary.x); offset+=WriteBlobFloat(image,image->chromaticity.blue_primary.y); value=GetCINProperty(image_info,image,"dpx:image.label",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.image.label,value,sizeof(cin.image.label)); offset+=WriteBlob(image,sizeof(cin.image.label),(unsigned char *) cin.image.label); offset+=WriteBlob(image,sizeof(cin.image.reserve),(unsigned char *) cin.image.reserve); /* Write data format information. */ cin.data_format.interleave=0; /* pixel interleave (rgbrgbr...) */ offset+=WriteBlobByte(image,cin.data_format.interleave); cin.data_format.packing=5; /* packing ssize_tword (32bit) boundaries */ offset+=WriteBlobByte(image,cin.data_format.packing); cin.data_format.sign=0; /* unsigned data */ offset+=WriteBlobByte(image,cin.data_format.sign); cin.data_format.sense=0; /* image sense: positive image */ offset+=WriteBlobByte(image,cin.data_format.sense); cin.data_format.line_pad=0; offset+=WriteBlobLong(image,(unsigned int) cin.data_format.line_pad); cin.data_format.channel_pad=0; offset+=WriteBlobLong(image,(unsigned int) cin.data_format.channel_pad); offset+=WriteBlob(image,sizeof(cin.data_format.reserve),(unsigned char *) cin.data_format.reserve); /* Write origination information. */ cin.origination.x_offset=0UL; value=GetCINProperty(image_info,image,"dpx:origination.x_offset",exception); if (value != (const char *) NULL) cin.origination.x_offset=(ssize_t) StringToLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.origination.x_offset); cin.origination.y_offset=0UL; value=GetCINProperty(image_info,image,"dpx:origination.y_offset",exception); if (value != (const char *) NULL) cin.origination.y_offset=(ssize_t) StringToLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.origination.y_offset); value=GetCINProperty(image_info,image,"dpx:origination.filename",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.filename,value, sizeof(cin.origination.filename)); else (void) CopyMagickString(cin.origination.filename,image->filename, sizeof(cin.origination.filename)); offset+=WriteBlob(image,sizeof(cin.origination.filename),(unsigned char *) cin.origination.filename); seconds=time((time_t *) NULL); (void) strftime(cin.origination.create_date, sizeof(cin.origination.create_date),"%Y:%m:%d",&local_time); offset+=WriteBlob(image,sizeof(cin.origination.create_date),(unsigned char *) cin.origination.create_date); (void) strftime(cin.origination.create_time, sizeof(cin.origination.create_time),"%H:%M:%S%Z",&local_time); offset+=WriteBlob(image,sizeof(cin.origination.create_time),(unsigned char *) cin.origination.create_time); value=GetCINProperty(image_info,image,"dpx:origination.device",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.device,value, sizeof(cin.origination.device)); offset+=WriteBlob(image,sizeof(cin.origination.device),(unsigned char *) cin.origination.device); value=GetCINProperty(image_info,image,"dpx:origination.model",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.model,value, sizeof(cin.origination.model)); offset+=WriteBlob(image,sizeof(cin.origination.model),(unsigned char *) cin.origination.model); value=GetCINProperty(image_info,image,"dpx:origination.serial",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.origination.serial,value, sizeof(cin.origination.serial)); offset+=WriteBlob(image,sizeof(cin.origination.serial),(unsigned char *) cin.origination.serial); cin.origination.x_pitch=0.0f; value=GetCINProperty(image_info,image,"dpx:origination.x_pitch",exception); if (value != (const char *) NULL) cin.origination.x_pitch=StringToDouble(value,(char **) NULL); offset+=WriteBlobFloat(image,cin.origination.x_pitch); cin.origination.y_pitch=0.0f; value=GetCINProperty(image_info,image,"dpx:origination.y_pitch",exception); if (value != (const char *) NULL) cin.origination.y_pitch=StringToDouble(value,(char **) NULL); offset+=WriteBlobFloat(image,cin.origination.y_pitch); cin.origination.gamma=image->gamma; offset+=WriteBlobFloat(image,cin.origination.gamma); offset+=WriteBlob(image,sizeof(cin.origination.reserve),(unsigned char *) cin.origination.reserve); /* Image film information. */ cin.film.id=0; value=GetCINProperty(image_info,image,"dpx:film.id",exception); if (value != (const char *) NULL) cin.film.id=(char) StringToLong(value); offset+=WriteBlobByte(image,(unsigned char) cin.film.id); cin.film.type=0; value=GetCINProperty(image_info,image,"dpx:film.type",exception); if (value != (const char *) NULL) cin.film.type=(char) StringToLong(value); offset+=WriteBlobByte(image,(unsigned char) cin.film.type); cin.film.offset=0; value=GetCINProperty(image_info,image,"dpx:film.offset",exception); if (value != (const char *) NULL) cin.film.offset=(char) StringToLong(value); offset+=WriteBlobByte(image,(unsigned char) cin.film.offset); offset+=WriteBlobByte(image,(unsigned char) cin.film.reserve1); cin.film.prefix=0UL; value=GetCINProperty(image_info,image,"dpx:film.prefix",exception); if (value != (const char *) NULL) cin.film.prefix=StringToUnsignedLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.film.prefix); cin.film.count=0UL; value=GetCINProperty(image_info,image,"dpx:film.count",exception); if (value != (const char *) NULL) cin.film.count=StringToUnsignedLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.film.count); value=GetCINProperty(image_info,image,"dpx:film.format",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.film.format,value,sizeof(cin.film.format)); offset+=WriteBlob(image,sizeof(cin.film.format),(unsigned char *) cin.film.format); cin.film.frame_position=0UL; value=GetCINProperty(image_info,image,"dpx:film.frame_position",exception); if (value != (const char *) NULL) cin.film.frame_position=StringToUnsignedLong(value); offset+=WriteBlobLong(image,(unsigned int) cin.film.frame_position); cin.film.frame_rate=0.0f; value=GetCINProperty(image_info,image,"dpx:film.frame_rate",exception); if (value != (const char *) NULL) cin.film.frame_rate=StringToDouble(value,(char **) NULL); offset+=WriteBlobFloat(image,cin.film.frame_rate); value=GetCINProperty(image_info,image,"dpx:film.frame_id",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.film.frame_id,value,sizeof(cin.film.frame_id)); offset+=WriteBlob(image,sizeof(cin.film.frame_id),(unsigned char *) cin.film.frame_id); value=GetCINProperty(image_info,image,"dpx:film.slate_info",exception); if (value != (const char *) NULL) (void) CopyMagickString(cin.film.slate_info,value, sizeof(cin.film.slate_info)); offset+=WriteBlob(image,sizeof(cin.film.slate_info),(unsigned char *) cin.film.slate_info); offset+=WriteBlob(image,sizeof(cin.film.reserve),(unsigned char *) cin.film.reserve); if (profile != (StringInfo *) NULL) offset+=WriteBlob(image,GetStringInfoLength(profile), GetStringInfoDatum(profile)); while (offset < (MagickOffsetType) cin.file.image_offset) offset+=WriteBlobByte(image,0x00); /* Convert pixel packets to CIN raster image. */ quantum_info=AcquireQuantumInfo(image_info,image); if (quantum_info == (QuantumInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); quantum_info->quantum=32; quantum_info->pack=MagickFalse; quantum_type=RGBQuantum; pixels=GetQuantumPixels(quantum_info); length=GetBytesPerRow(image->columns,3,image->depth,MagickTrue); if (0) { quantum_type=GrayQuantum; length=GetBytesPerRow(image->columns,1,image->depth,MagickTrue); } for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, quantum_type,pixels,exception); 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); (void) CloseBlob(image); return(status); }
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 R G F I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteRGFImage() writes an image to a file in the X bitmap format. % % The format of the WriteRGFImage method is: % % MagickBooleanType WriteRGFImage(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 WriteRGFImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { MagickBooleanType status; register const Quantum *p; register ssize_t x; size_t bit, byte; ssize_t y; /* 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); if((image->columns > 255L) || (image->rows > 255L)) ThrowWriterException(ImageError,"Dimensions must be less than 255x255"); /* Write header (just the image dimensions) */ (void) WriteBlobByte(image,image->columns & 0xff); (void) WriteBlobByte(image,image->rows & 0xff); /* Convert MIFF to bit pixels. */ (void) SetImageType(image,BilevelType,exception); x=0; y=0; for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; bit=0; byte=0; for (x=0; x < (ssize_t) image->columns; x++) { byte>>=1; if (GetPixelLuma(image,p) < (QuantumRange/2.0)) byte|=0x80; bit++; if (bit == 8) { /* Write a bitmap byte to the image file. */ (void) WriteBlobByte(image,(unsigned char) byte); bit=0; byte=0; } p+=GetPixelChannels(image); } if (bit != 0) { byte >>= 8 - bit; (void) WriteBlobByte(image,(unsigned char) byte); } status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; }
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 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); }
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); }
static MagickBooleanType WriteWBMPImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { MagickBooleanType status; register const Quantum *p; register ssize_t x; ssize_t y; unsigned char bit, byte; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); (void) TransformImageColorspace(image,sRGBColorspace,exception); /* Convert image to a bi-level image. */ (void) SetImageType(image,BilevelType,exception); (void) WriteBlobMSBShort(image,0); WBMPWriteInteger(image,image->columns); WBMPWriteInteger(image,image->rows); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; bit=0; byte=0; for (x=0; x < (ssize_t) image->columns; x++) { if (GetPixelLuma(image,p) >= (QuantumRange/2.0)) byte|=0x1 << (7-bit); bit++; if (bit == 8) { (void) WriteBlobByte(image,byte); bit=0; byte=0; } p+=GetPixelChannels(image); } if (bit != 0) (void) WriteBlobByte(image,byte); status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e O T B I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteOTBImage() writes an image to a file in the On-the-air Bitmap % (level 0) image format. % % The format of the WriteOTBImage method is: % % MagickBooleanType WriteOTBImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: The image info. % % o image: The image. % % */ static MagickBooleanType WriteOTBImage(const ImageInfo *image_info,Image *image) { #define SetBit(a,i,set) \ a=(unsigned char) ((set) ? (a) | (1L << (i)) : (a) & ~(1L << (i))) long y; MagickBooleanType status; register const PixelPacket *p; register IndexPacket *indexes; register long x; unsigned char bit, byte, info; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image_info->colorspace == UndefinedColorspace) (void) SetImageColorspace(image,RGBColorspace); /* Convert image to a bi-level image. */ (void) SetImageType(image,BilevelType); info=0; if ((image->columns >= 256) || (image->rows >= 256)) SetBit(info,4,1); (void) WriteBlobByte(image,info); if ((image->columns >= 256) || (image->rows >= 256)) { (void) WriteBlobMSBShort(image,(unsigned short) image->columns); (void) WriteBlobMSBShort(image,(unsigned short) image->rows); } else { (void) WriteBlobByte(image,(unsigned char) image->columns); (void) WriteBlobByte(image,(unsigned char) image->rows); } (void) WriteBlobByte(image,1); /* depth */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); bit=0; byte=0; for (x=0; x < (long) image->columns; x++) { if (PixelIntensity(p) < ((Quantum) QuantumRange/2.0)) byte|=0x1 << (7-bit); bit++; if (bit == 8) { (void) WriteBlobByte(image,byte); bit=0; byte=0; } } if (bit != 0) (void) WriteBlobByte(image,byte); if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(SaveImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } CloseBlob(image); return(MagickTrue); }
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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e H T M L I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteHTMLImage() writes an image in the HTML encoded image format. % % The format of the WriteHTMLImage method is: % % MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % */ static MagickBooleanType WriteHTMLImage(const ImageInfo *image_info, Image *image) { char basename[MaxTextExtent], buffer[MaxTextExtent], filename[MaxTextExtent], mapname[MaxTextExtent], url[MaxTextExtent]; Image *next; ImageInfo *write_info; MagickBooleanType status; RectangleInfo geometry; register char *p; /* Open image. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) CloseBlob(image); if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace); *url='\0'; if ((LocaleCompare(image_info->magick,"FTP") == 0) || (LocaleCompare(image_info->magick,"HTTP") == 0)) { /* Extract URL base from filename. */ p=strrchr(image->filename,'/'); if (p != (char *) NULL) { p++; (void) CopyMagickString(url,image_info->magick,MaxTextExtent); (void) ConcatenateMagickString(url,":",MaxTextExtent); url[strlen(url)+p-image->filename]='\0'; (void) ConcatenateMagickString(url,image->filename, p-image->filename+2); (void) CopyMagickString(image->filename,p,MaxTextExtent); } } /* Refer to image map file. */ (void) CopyMagickString(filename,image->filename,MaxTextExtent); AppendImageFormat("map",filename); GetPathComponent(filename,BasePath,basename); (void) CopyMagickString(mapname,basename,MaxTextExtent); (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); (void) CopyMagickString(filename,image->filename,MaxTextExtent); write_info=CloneImageInfo(image_info); write_info->adjoin=MagickTrue; status=MagickTrue; if (LocaleCompare(image_info->magick,"SHTML") != 0) { const char *value; /* Open output image file. */ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); /* Write the HTML image file. */ (void) WriteBlobString(image,"<?xml version=\"1.0\" " "encoding=\"US-ASCII\"?>\n"); (void) WriteBlobString(image,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML " "1.0 Strict//EN\" " "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"); (void) WriteBlobString(image,"<html>\n"); (void) WriteBlobString(image,"<head>\n"); value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) FormatLocaleString(buffer,MaxTextExtent,"<title>%s</title>\n", value); else { GetPathComponent(filename,BasePath,basename); (void) FormatLocaleString(buffer,MaxTextExtent, "<title>%s</title>\n",basename); } (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"</head>\n"); (void) WriteBlobString(image,"<body style=\"text-align: center;\">\n"); (void) FormatLocaleString(buffer,MaxTextExtent,"<h1>%s</h1>\n", image->filename); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"<div>\n"); (void) CopyMagickString(filename,image->filename,MaxTextExtent); AppendImageFormat("png",filename); (void) FormatLocaleString(buffer,MaxTextExtent,"<img usemap=\"#%s\" " "src=\"%s\" style=\"border: 0;\" alt=\"Image map\" />\n",mapname, filename); (void) WriteBlobString(image,buffer); /* Determine the size and location of each image tile. */ SetGeometry(image,&geometry); if (image->montage != (char *) NULL) (void) ParseAbsoluteGeometry(image->montage,&geometry); /* Write an image map. */ (void) FormatLocaleString(buffer,MaxTextExtent, "<map id=\"%s\" name=\"%s\">\n",mapname,mapname); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent," <area href=\"%s",url); (void) WriteBlobString(image,buffer); if (image->directory == (char *) NULL) { (void) FormatLocaleString(buffer,MaxTextExtent, "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n", image->filename,(double) geometry.width-1,(double) geometry.height- 1); (void) WriteBlobString(image,buffer); } else for (p=image->directory; *p != '\0'; p++) if (*p != '\n') (void) WriteBlobByte(image,(unsigned char) *p); else { (void) FormatLocaleString(buffer,MaxTextExtent,"\" shape=" "\"rect\" coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n", (double) geometry.x,(double) geometry.y,(double) (geometry.x+ geometry.width-1),(double) (geometry.y+geometry.height-1)); (void) WriteBlobString(image,buffer); if (*(p+1) != '\0') { (void) FormatLocaleString(buffer,MaxTextExtent, " <area href=%s\"",url); (void) WriteBlobString(image,buffer); } geometry.x+=(ssize_t) geometry.width; if ((geometry.x+4) >= (ssize_t) image->columns) { geometry.x=0; geometry.y+=(ssize_t) geometry.height; } } (void) WriteBlobString(image,"</map>\n"); (void) CopyMagickString(filename,image->filename,MaxTextExtent); (void) WriteBlobString(image,"</div>\n"); (void) WriteBlobString(image,"</body>\n"); (void) WriteBlobString(image,"</html>\n"); (void) CloseBlob(image); /* Write the image as PNG. */ (void) CopyMagickString(image->filename,filename,MaxTextExtent); AppendImageFormat("png",image->filename); next=GetNextImageInList(image); image->next=NewImageList(); (void) CopyMagickString(image->magick,"PNG",MaxTextExtent); (void) WriteImage(write_info,image); image->next=next; /* Determine image map filename. */ GetPathComponent(image->filename,BasePath,filename); (void) ConcatenateMagickString(filename,"_map.shtml",MaxTextExtent); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } /* Open image map. */ status=OpenBlob(write_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); write_info=DestroyImageInfo(write_info); /* Determine the size and location of each image tile. */ SetGeometry(image,&geometry); if (image->montage != (char *) NULL) (void) ParseAbsoluteGeometry(image->montage,&geometry); /* Write an image map. */ (void) FormatLocaleString(buffer,MaxTextExtent, "<map id=\"%s\" name=\"%s\">\n",mapname,mapname); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent," <area href=\"%s",url); (void) WriteBlobString(image,buffer); if (image->directory == (char *) NULL) { (void) FormatLocaleString(buffer,MaxTextExtent, "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n", image->filename,(double) geometry.width-1,(double) geometry.height-1); (void) WriteBlobString(image,buffer); } else for (p=image->directory; *p != '\0'; p++) if (*p != '\n') (void) WriteBlobByte(image,(unsigned char) *p); else { (void) FormatLocaleString(buffer,MaxTextExtent,"\" shape=\"rect\"" " coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n", (double) geometry.x,(double) geometry.y,geometry.x+(double) geometry.width-1,geometry.y+(double) geometry.height-1); (void) WriteBlobString(image,buffer); if (*(p+1) != '\0') { (void) FormatLocaleString(buffer,MaxTextExtent, " <area href=%s\"",url); (void) WriteBlobString(image,buffer); } geometry.x+=(ssize_t) geometry.width; if ((geometry.x+4) >= (ssize_t) image->columns) { geometry.x=0; geometry.y+=(ssize_t) geometry.height; } } (void) WriteBlobString(image,"</map>\n"); (void) CloseBlob(image); (void) CopyMagickString(image->filename,filename,MaxTextExtent); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e O T B I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteOTBImage() writes an image to a file in the On-the-air Bitmap % (level 0) image format. % % The format of the WriteOTBImage method is: % % MagickBooleanType WriteOTBImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % */ static MagickBooleanType WriteOTBImage(const ImageInfo *image_info,Image *image) { #define SetBit(a,i,set) \ a=(unsigned char) ((set) ? (a) | (1L << (i)) : (a) & ~(1L << (i))) MagickBooleanType status; register const PixelPacket *p; register ssize_t x; ssize_t y; unsigned char bit, byte, info; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); (void) TransformImageColorspace(image,sRGBColorspace); /* Convert image to a bi-level image. */ (void) SetImageType(image,BilevelType); info=0; if ((image->columns >= 256) || (image->rows >= 256)) SetBit(info,4,1); (void) WriteBlobByte(image,info); if ((image->columns >= 256) || (image->rows >= 256)) { (void) WriteBlobMSBShort(image,(unsigned short) image->columns); (void) WriteBlobMSBShort(image,(unsigned short) image->rows); } else { (void) WriteBlobByte(image,(unsigned char) image->columns); (void) WriteBlobByte(image,(unsigned char) image->rows); } (void) WriteBlobByte(image,1); /* depth */ for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; bit=0; byte=0; for (x=0; x < (ssize_t) image->columns; x++) { if (GetPixelLuma(image,p) < (QuantumRange/2.0)) byte|=0x1 << (7-bit); bit++; if (bit == 8) { (void) WriteBlobByte(image,byte); bit=0; byte=0; } p++; } if (bit != 0) (void) WriteBlobByte(image,byte); if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e M P C I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteMPCImage() writes an Magick Persistent Cache image to a file. % % The format of the WriteMPCImage method is: % % MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows: % % o image_info: the image info. % % o image: the image. % */ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent], cache_filename[MaxTextExtent]; const char *property, *value; MagickBooleanType status; MagickOffsetType offset, scene; register long i; unsigned long depth; /* Open persistent cache. */ 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) CopyMagickString(cache_filename,image->filename,MaxTextExtent); AppendImageFormat("cache",cache_filename); scene=0; offset=0; do { /* Write persistent cache meta-information. */ depth=GetImageQuantumDepth(image,MagickTrue); if ((image->storage_class == PseudoClass) && (image->colors > (1UL << depth))) image->storage_class=DirectClass; (void) WriteBlobString(image,"id=MagickCache\n"); (void) FormatMagickString(buffer,MaxTextExtent,"quantum-depth=%d\n", MAGICKCORE_QUANTUM_DEPTH); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "class=%s colors=%lu matte=%s\n",MagickOptionToMnemonic( MagickClassOptions,image->storage_class),image->colors, MagickOptionToMnemonic(MagickBooleanOptions,(long) image->matte)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "columns=%lu rows=%lu depth=%lu\n",image->columns,image->rows, image->depth); (void) WriteBlobString(image,buffer); if (image->type != UndefinedType) { (void) FormatMagickString(buffer,MaxTextExtent,"type=%s\n", MagickOptionToMnemonic(MagickTypeOptions,image->type)); (void) WriteBlobString(image,buffer); } if (image->colorspace != UndefinedColorspace) { (void) FormatMagickString(buffer,MaxTextExtent,"colorspace=%s\n", MagickOptionToMnemonic(MagickColorspaceOptions,image->colorspace)); (void) WriteBlobString(image,buffer); } if (image->endian != UndefinedEndian) { (void) FormatMagickString(buffer,MaxTextExtent,"endian=%s\n", MagickOptionToMnemonic(MagickEndianOptions,image->endian)); (void) WriteBlobString(image,buffer); } if (image->compression != UndefinedCompression) { (void) FormatMagickString(buffer,MaxTextExtent, "compression=%s quality=%lu\n",MagickOptionToMnemonic( MagickCompressOptions,image->compression),image->quality); (void) WriteBlobString(image,buffer); } if (image->units != UndefinedResolution) { (void) FormatMagickString(buffer,MaxTextExtent,"units=%s\n", MagickOptionToMnemonic(MagickResolutionOptions,image->units)); (void) WriteBlobString(image,buffer); } if ((image->x_resolution != 0) || (image->y_resolution != 0)) { (void) FormatMagickString(buffer,MaxTextExtent, "resolution=%gx%g\n",image->x_resolution,image->y_resolution); (void) WriteBlobString(image,buffer); } if ((image->page.width != 0) || (image->page.height != 0)) { (void) FormatMagickString(buffer,MaxTextExtent,"page=%lux%lu%+ld%+ld\n", image->page.width,image->page.height,image->page.x,image->page.y); (void) WriteBlobString(image,buffer); } else if ((image->page.x != 0) || (image->page.y != 0)) { (void) FormatMagickString(buffer,MaxTextExtent,"page=%+ld%+ld\n", image->page.x,image->page.y); (void) WriteBlobString(image,buffer); } if ((image->page.x != 0) || (image->page.y != 0)) { (void) FormatMagickString(buffer,MaxTextExtent,"tile-offset=%+ld%+ld\n", image->tile_offset.x,image->tile_offset.y); (void) WriteBlobString(image,buffer); } if ((GetNextImageInList(image) != (Image *) NULL) || (GetPreviousImageInList(image) != (Image *) NULL)) { if (image->scene == 0) (void) FormatMagickString(buffer,MaxTextExtent, "iterations=%lu delay=%lu ticks-per-second=%lu\n", image->iterations,image->delay,image->ticks_per_second); else (void) FormatMagickString(buffer,MaxTextExtent, "scene=%lu iterations=%lu delay=%lu ticks-per-second=%lu\n", image->scene,image->iterations,image->delay, image->ticks_per_second); (void) WriteBlobString(image,buffer); } else { if (image->scene != 0) { (void) FormatMagickString(buffer,MaxTextExtent,"scene=%lu\n", image->scene); (void) WriteBlobString(image,buffer); } if (image->iterations != 0) { (void) FormatMagickString(buffer,MaxTextExtent,"iterations=%lu\n", image->iterations); (void) WriteBlobString(image,buffer); } if (image->delay != 0) { (void) FormatMagickString(buffer,MaxTextExtent,"delay=%lu\n", image->delay); (void) WriteBlobString(image,buffer); } if (image->ticks_per_second != UndefinedTicksPerSecond) { (void) FormatMagickString(buffer,MaxTextExtent, "ticks-per-second=%lu\n",image->ticks_per_second); (void) WriteBlobString(image,buffer); } } if (image->gravity != UndefinedGravity) { (void) FormatMagickString(buffer,MaxTextExtent,"gravity=%s\n", MagickOptionToMnemonic(MagickGravityOptions,image->gravity)); (void) WriteBlobString(image,buffer); } if (image->dispose != UndefinedDispose) { (void) FormatMagickString(buffer,MaxTextExtent,"dispose=%s\n", MagickOptionToMnemonic(MagickDisposeOptions,image->dispose)); (void) WriteBlobString(image,buffer); } if (image->rendering_intent != UndefinedIntent) { (void) FormatMagickString(buffer,MaxTextExtent, "rendering-intent=%s\n", MagickOptionToMnemonic(MagickIntentOptions,image->rendering_intent)); (void) WriteBlobString(image,buffer); } if (image->gamma != 0.0) { (void) FormatMagickString(buffer,MaxTextExtent,"gamma=%g\n", image->gamma); (void) WriteBlobString(image,buffer); } if (image->chromaticity.white_point.x != 0.0) { /* Note chomaticity points. */ (void) FormatMagickString(buffer,MaxTextExtent,"red-primary=" "%g,%g green-primary=%g,%g blue-primary=%g,%g\n", image->chromaticity.red_primary.x,image->chromaticity.red_primary.y, image->chromaticity.green_primary.x, image->chromaticity.green_primary.y, image->chromaticity.blue_primary.x, image->chromaticity.blue_primary.y); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "white-point=%g,%g\n",image->chromaticity.white_point.x, image->chromaticity.white_point.y); (void) WriteBlobString(image,buffer); } if (image->orientation != UndefinedOrientation) { (void) FormatMagickString(buffer,MaxTextExtent, "orientation=%s\n",MagickOptionToMnemonic(MagickOrientationOptions, image->orientation)); (void) WriteBlobString(image,buffer); } if (image->profiles != (void *) NULL) { const char *name; const StringInfo *profile; /* Generic profile. */ ResetImageProfileIterator(image); for (name=GetNextImageProfile(image); name != (const char *) NULL; ) { profile=GetImageProfile(image,name); if (profile != (StringInfo *) NULL) { (void) FormatMagickString(buffer,MaxTextExtent,"profile:%s=%lu\n", name,(unsigned long) GetStringInfoLength(profile)); (void) WriteBlobString(image,buffer); } name=GetNextImageProfile(image); } } if (image->montage != (char *) NULL) { (void) FormatMagickString(buffer,MaxTextExtent,"montage=%s\n", image->montage); (void) WriteBlobString(image,buffer); } ResetImagePropertyIterator(image); property=GetNextImageProperty(image); while (property != (const char *) NULL) { (void) FormatMagickString(buffer,MaxTextExtent,"%s=",property); (void) WriteBlobString(image,buffer); value=GetImageProperty(image,property); if (value != (const char *) NULL) { for (i=0; i < (long) strlen(value); i++) if (isspace((int) ((unsigned char) value[i])) != 0) break; if (i <= (long) strlen(value)) (void) WriteBlobByte(image,'{'); (void) WriteBlob(image,strlen(value),(unsigned char *) value); if (i <= (long) strlen(value)) (void) WriteBlobByte(image,'}'); } (void) WriteBlobByte(image,'\n'); property=GetNextImageProperty(image); } ResetImageArtifactIterator(image); (void) WriteBlobString(image,"\f\n:\032"); if (image->montage != (char *) NULL) { /* Write montage tile directory. */ if (image->directory != (char *) NULL) (void) WriteBlobString(image,image->directory); (void) WriteBlobByte(image,'\0'); } if (image->profiles != 0) { const char *name; const StringInfo *profile; /* Write image profiles. */ ResetImageProfileIterator(image); name=GetNextImageProfile(image); while (name != (const char *) NULL) { profile=GetImageProfile(image,name); (void) WriteBlob(image,GetStringInfoLength(profile), GetStringInfoDatum(profile)); name=GetNextImageProfile(image); } } if (image->storage_class == PseudoClass) { size_t packet_size; unsigned char *colormap, *q; /* Allocate colormap. */ packet_size=(size_t) (3UL*depth/8UL); colormap=(unsigned char *) AcquireQuantumMemory(image->colors, packet_size*sizeof(*colormap)); if (colormap == (unsigned char *) NULL) return(MagickFalse); /* Write colormap to file. */ q=colormap; for (i=0; i < (long) image->colors; i++) { switch (depth) { default: ThrowWriterException(CorruptImageError,"ImageDepthNotSupported"); case 32: { unsigned long pixel; pixel=ScaleQuantumToLong(image->colormap[i].red); q=PopLongPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToLong(image->colormap[i].green); q=PopLongPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToLong(image->colormap[i].blue); q=PopLongPixel(MSBEndian,pixel,q); } case 16: { unsigned short pixel; pixel=ScaleQuantumToShort(image->colormap[i].red); q=PopShortPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToShort(image->colormap[i].green); q=PopShortPixel(MSBEndian,pixel,q); pixel=ScaleQuantumToShort(image->colormap[i].blue); q=PopShortPixel(MSBEndian,pixel,q); break; } case 8: { unsigned char pixel; pixel=(unsigned char) ScaleQuantumToChar(image->colormap[i].red); q=PopCharPixel(pixel,q); pixel=(unsigned char) ScaleQuantumToChar( image->colormap[i].green); q=PopCharPixel(pixel,q); pixel=(unsigned char) ScaleQuantumToChar(image->colormap[i].blue); q=PopCharPixel(pixel,q); break; } } } (void) WriteBlob(image,packet_size*image->colors,colormap); colormap=(unsigned char *) RelinquishMagickMemory(colormap); } /* Initialize persistent pixel cache. */ status=PersistPixelCache(image,cache_filename,MagickFalse,&offset, &image->exception); if (status == MagickFalse) ThrowWriterException(CacheError,"UnableToPersistPixelCache"); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(SaveImagesTag,scene, GetImageListLength(image),image->client_data); if (status == MagickFalse) break; } scene++; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(status); }
static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image) { static const char *PostscriptProlog[]= { "/ByteStreamDecodeFilter", "{", " /z exch def", " /r exch def", " /c exch def", " z "PS3_NoCompression" eq { /ASCII85Decode filter } if", " z "PS3_FaxCompression" eq", " {", " <<", " /K "CCITTParam, " /Columns c", " /Rows r", " >>", " /CCITTFaxDecode filter", " } if", " z "PS3_JPEGCompression" eq { /DCTDecode filter } if", " z "PS3_LZWCompression" eq { /LZWDecode filter } if", " z "PS3_RLECompression" eq { /RunLengthDecode filter } if", " z "PS3_ZipCompression" eq { /FlateDecode filter } if", "} bind def", "", "/DirectClassImageDict", "{", " colorspace "PS3_RGBColorspace" eq", " {", " /DeviceRGB setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /DataSource pixel_stream", " /MultipleDataSources false", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " /Decode [0 1 0 1 0 1]", " >>", " }", " {", " /DeviceCMYK setcolorspace", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 8", " /DataSource pixel_stream", " /MultipleDataSources false", " /ImageMatrix [columns 0 0 rows neg 0 rows]", " /Decode", " compression "PS3_JPEGCompression" eq", " { [1 0 1 0 1 0 1 0] }", " { [0 1 0 1 0 1 0 1] }", " ifelse", " >>", " }", " ifelse", "} bind def", "", "/PseudoClassImageDict", "{", " % Colors in colormap image.", " currentfile buffer readline pop", " token pop /colors exch def pop", " colors 0 eq", " {", " % Depth of grayscale image.", " 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]", " /DataSource pixel_stream", " >>", " }", " {", " % RGB colormap.", " /colormap colors 3 mul string def", " compression "PS3_NoCompression" eq", " { currentfile /ASCII85Decode filter colormap readstring pop pop }", " { currentfile colormap readstring pop pop }", " ifelse", " [ /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]", " /DataSource pixel_stream", " >>", " }", " ifelse", "} bind def", "", "/NonMaskedImageDict", "{", " class "PS3_PseudoClass" eq", " { PseudoClassImageDict }", " { DirectClassImageDict }", " ifelse", "} bind def", "", "/MaskedImageDict", "{", " <<", " /ImageType 3", " /InterleaveType 3", " /DataDict NonMaskedImageDict", " /MaskDict", " <<", " /ImageType 1", " /Width columns", " /Height rows", " /BitsPerComponent 1", " /DataSource mask_stream", " /MultipleDataSources false", " /ImageMatrix [ columns 0 0 rows neg 0 rows]", " /Decode [ 0 1 ]", " >>", " >>", "} bind def", "", "/ClipImage", "{} def", "", "/DisplayImage", "{", " /buffer 512 string def", " % Translation.", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " x y translate", " % Image size and font size.", " 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", (char *) NULL }, *PostscriptEpilog[]= { " x y scale", " % Clipping path.", " currentfile buffer readline pop", " token pop /clipped exch def pop", " % Showpage.", " currentfile buffer readline pop", " token pop /sp exch def pop", " % Image pixel size.", " currentfile buffer readline pop", " token pop /columns exch def", " token pop /rows exch def pop", " % Colorspace (RGB/CMYK).", " currentfile buffer readline pop", " token pop /colorspace exch def pop", " % Transparency.", " currentfile buffer readline pop", " token pop /alpha exch def pop", " % Stencil mask?", " currentfile buffer readline pop", " token pop /stencil exch def pop", " % Image class (direct/pseudo).", " currentfile buffer readline pop", " token pop /class exch def pop", " % Compression type.", " currentfile buffer readline pop", " token pop /compression exch def pop", " % Clip and render.", " /pixel_stream currentfile columns rows compression ByteStreamDecodeFilter def", " clipped { ClipImage } if", " alpha stencil not and", " { MaskedImageDict mask_stream resetfile }", " { NonMaskedImageDict }", " ifelse", " stencil { 0 setgray imagemask } { image } ifelse", " sp { showpage } if", "} bind def", (char *) NULL }; char buffer[MaxTextExtent], date[MaxTextExtent], **labels, page_geometry[MaxTextExtent]; CompressionType compression; const char *option, **q, *value; double pointsize; GeometryInfo geometry_info; long j; MagickBooleanType status; MagickOffsetType offset, scene, start, stop; MagickStatusType flags; PointInfo delta, resolution, scale; RectangleInfo geometry, media_info, page_info; register long i; SegmentInfo bounds; size_t length; time_t timer; unsigned char *pixels; unsigned long page, pixel, text_size; /* 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(MagickFalse); compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; switch (compression) { case FaxCompression: case Group4Compression: { if ((IsMonochromeImage(image,&image->exception) == MagickFalse) || (image->matte != MagickFalse)) compression=RLECompression; break; } #if !defined(MAGICKCORE_JPEG_DELEGATE) case JPEGCompression: { compression=RLECompression; (void) ThrowMagickException(&image->exception,GetMagickModule(), MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JPEG)", image->filename); break; } #endif #if !defined(MAGICKCORE_ZLIB_DELEGATE) case ZipCompression: { compression=RLECompression; (void) ThrowMagickException(&image->exception,GetMagickModule(), MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (ZLIB)", image->filename); break; } #endif default: break; } (void) ResetMagickMemory(&bounds,0,sizeof(bounds)); page=0; 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*=2.54; resolution.y*=2.54; } SetGeometry(image,&geometry); (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu", image->columns,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) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu%+ld%+ld", image->page.width,image->page.height,image->page.x,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=(unsigned long) (scale.x+0.5); scale.y=(double) (geometry.height*delta.y)/resolution.y; geometry.height=(unsigned long) (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=(long) (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=(unsigned long) (MultilineCensus(value)*pointsize+12); page++; if (page == 1) { /* Postscript header on the first page. */ if (LocaleCompare(image_info->magick,"PS3") == 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) FormatMagickString(buffer,MaxTextExtent, "%%%%Creator: ImageMagick %s\n",MagickLibVersionText); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Title: %s\n", image->filename); (void) WriteBlobString(image,buffer); timer=time((time_t *) NULL); (void) FormatMagickTime(timer,MaxTextExtent,date); (void) FormatMagickString(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+scale.x; bounds.y2=(double) geometry.y+scale.y+text_size; if ((image_info->adjoin != MagickFalse) && (GetNextImageInList(image) != (Image *) NULL)) { (void) WriteBlobString(image,"%%BoundingBox: (atend)\n"); (void) WriteBlobString(image,"%%HiResBoundingBox: (atend)\n"); } else { (void) FormatMagickString(buffer,MaxTextExtent, "%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5), floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,bounds.y1, bounds.x2,bounds.y2); (void) WriteBlobString(image,buffer); if (image->colorspace == CMYKColorspace) (void) WriteBlobString(image, "%%DocumentProcessColors: Cyan Magenta Yellow Black\n"); else if (IsGrayImage(image,&image->exception) != MagickFalse) (void) WriteBlobString(image, "%%DocumentProcessColors: Black\n"); } /* Font resources */ value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image, "%%DocumentNeededResources: font Helvetica\n"); (void) WriteBlobString(image,"%%LanguageLevel: 3\n"); /* Pages, orientation and order. */ if (LocaleCompare(image_info->magick,"PS3") != 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) FormatMagickString(buffer,MaxTextExtent,"%%%%Pages: %lu\n", (unsigned long) GetImageListLength(image)); (void) WriteBlobString(image,buffer); } (void) WriteBlobString(image,"%%EndComments\n"); /* The static postscript procedures prolog. */ (void)WriteBlobString(image,"%%BeginProlog\n"); for (q=PostscriptProlog; *q; q++) { (void) WriteBlobString(image,*q); (void) WriteBlobByte(image,'\n'); } /* One label line for each line in label string. */ value=GetImageProperty(image,"label"); if (value != (const char *) NULL) { (void) WriteBlobString(image,"\n %% Labels.\n /Helvetica " " findfont pointsize scalefont setfont\n"); for (i=(long) MultilineCensus(value)-1; i >= 0; i--) { (void) WriteBlobString(image, " currentfile buffer readline pop token pop\n"); (void) FormatMagickString(buffer,MaxTextExtent, " 0 y %g add moveto show pop\n",i*pointsize+12); (void) WriteBlobString(image,buffer); } } /* The static postscript procedures epilog. */ for (q=PostscriptEpilog; *q; q++) { (void) WriteBlobString(image,*q); (void) WriteBlobByte(image,'\n'); } (void)WriteBlobString(image,"%%EndProlog\n"); } (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Page: 1 %lu\n",page); (void) WriteBlobString(image,buffer); /* Page bounding box. */ (void) FormatMagickString(buffer,MaxTextExtent, "%%%%PageBoundingBox: %ld %ld %ld %ld\n",geometry.x,geometry.y,geometry.x+ (long) geometry.width,geometry.y+(long) (geometry.height+text_size)); (void) WriteBlobString(image,buffer); /* Page process colors if not RGB. */ if (image->colorspace == CMYKColorspace) (void) WriteBlobString(image, "%%PageProcessColors: Cyan Magenta Yellow Black\n"); else if (IsGrayImage(image,&image->exception) != MagickFalse) (void) WriteBlobString(image,"%%PageProcessColors: Black\n"); /* Adjust document bounding box to bound page bounding box. */ 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+scale.x) > bounds.x2) bounds.x2=(double) geometry.x+scale.x; if ((double) (geometry.y+scale.y+text_size) > bounds.y2) bounds.y2=(double) geometry.y+scale.y+text_size; /* Page font resource if there's a label. */ value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) WriteBlobString(image,"%%PageResources: font Helvetica\n"); /* PS clipping path from Photoshop clipping path. */ if ((image->clip_mask == (Image *) NULL) || (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) != 0)) (void) WriteBlobString(image,"/ClipImage {} def\n"); else { const char *value; value=GetImageProperty(image,image->clip_mask->magick_filename); if (value == (const char *) NULL) return(MagickFalse); (void) WriteBlobString(image,value); (void) WriteBlobByte(image,'\n'); } /* Push a dictionary for our own def's if this an EPS. */ if (LocaleCompare(image_info->magick,"PS3") != 0) (void) WriteBlobString(image,"userdict begin\n"); /* Image mask. */ if ((image->matte != MagickFalse) && (WritePS3MaskImage(image_info,image,compression) == MagickFalse)) { (void) CloseBlob(image); return(MagickFalse); } /* Remember position of BeginData comment so we can update it. */ start=TellBlob(image); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",0L, compression == NoCompression ? "ASCII" : "BINARY"); (void) WriteBlobString(image,buffer); stop=TellBlob(image); (void) WriteBlobString(image,"DisplayImage\n"); /* Translate, scale, and font point size. */ (void) FormatMagickString(buffer,MaxTextExtent,"%ld %ld\n%g %g\n%f\n", geometry.x,geometry.y,scale.x,scale.y,pointsize); (void) WriteBlobString(image,buffer); /* Output labels. */ 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++) { if (compression != NoCompression) { for (j=0; labels[i][j] != '\0'; j++) (void) WriteBlobByte(image,(unsigned char) labels[i][j]); (void) WriteBlobByte(image,'\n'); } else { (void) WriteBlobString(image,"<~"); Ascii85Initialize(image); for (j=0; labels[i][j] != '\0'; j++) Ascii85Encode(image,(unsigned char) labels[i][j]); Ascii85Flush(image); } labels[i]=DestroyString(labels[i]); } labels=(char **) RelinquishMagickMemory(labels); } /* Photoshop clipping path active? */ if ((image->clip_mask != (Image *) NULL) && (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) == 0)) (void) WriteBlobString(image,"true\n"); else (void) WriteBlobString(image,"false\n"); /* Showpage for non-EPS. */ (void) WriteBlobString(image, LocaleCompare(image_info->magick,"PS3") == 0 ? "true\n" : "false\n"); /* Image columns, rows, and color space. */ (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n%s\n", image->columns,image->rows,image->colorspace == CMYKColorspace ? PS3_CMYKColorspace : PS3_RGBColorspace); (void) WriteBlobString(image,buffer); /* Masked image? */ (void) WriteBlobString(image,image->matte != MagickFalse ? "true\n" : "false\n"); /* Render with imagemask operator? */ option=GetImageOption(image_info,"ps3:imagemask"); (void) WriteBlobString(image,((option != (const char *) NULL) && (IsMonochromeImage(image,&image->exception) != MagickFalse)) ? "true\n" : "false\n"); /* Output pixel data. */ pixels=(unsigned char *) NULL; length=0; if ((image_info->type != TrueColorType) && (image_info->type != TrueColorMatteType) && (image_info->type != ColorSeparationType) && (image_info->type != ColorSeparationMatteType) && (image->colorspace != CMYKColorspace) && ((IsGrayImage(image,&image->exception) != MagickFalse) || (IsMonochromeImage(image,&image->exception) != MagickFalse))) { /* Gray images. */ (void) WriteBlobString(image,PS3_PseudoClass"\n"); switch (compression) { case NoCompression: default: { (void) WriteBlobString(image,PS3_NoCompression"\n"); break; } case FaxCompression: case Group4Compression: { (void) WriteBlobString(image,PS3_FaxCompression"\n"); break; } case JPEGCompression: { (void) WriteBlobString(image,PS3_JPEGCompression"\n"); break; } case LZWCompression: { (void) WriteBlobString(image,PS3_LZWCompression"\n"); break; } case RLECompression: { (void) WriteBlobString(image,PS3_RLECompression"\n"); break; } case ZipCompression: { (void) WriteBlobString(image,PS3_ZipCompression"\n"); break; } } /* Number of colors -- 0 for single component non-color mapped data. */ (void) WriteBlobString(image,"0\n"); /* 1 bit or 8 bit components? */ (void) FormatMagickString(buffer,MaxTextExtent,"%d\n", IsMonochromeImage(image,&image->exception) != MagickFalse ? 1 : 8); (void) WriteBlobString(image,buffer); /* Image data. */ if (compression == JPEGCompression) status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); else if ((compression == FaxCompression) || (compression == Group4Compression)) { if (LocaleCompare(CCITTParam,"0") == 0) status=HuffmanEncodeImage(image_info,image,image); else status=Huffman2DEncodeImage(image_info,image,image); } else { status=SerializeImageChannel(image_info,image,&pixels,&length); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } switch (compression) { case NoCompression: default: { Ascii85Initialize(image); for (i=0; i < (long) length; i++) Ascii85Encode(image,pixels[i]); Ascii85Flush(image); status=MagickTrue; break; } case LZWCompression: { status=LZWEncodeImage(image,length,pixels); break; } case RLECompression: { status=PackbitsEncodeImage(image,length,pixels); break; } case ZipCompression: { status=ZLIBEncodeImage(image,length,pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); } } else if ((image->storage_class == DirectClass) || (image->colors > 256) || (compression == JPEGCompression)) { /* Truecolor image. */ (void) WriteBlobString(image,PS3_DirectClass"\n"); switch (compression) { case NoCompression: default: { (void) WriteBlobString(image,PS3_NoCompression"\n"); break; } case RLECompression: { (void) WriteBlobString(image,PS3_RLECompression"\n"); break; } case JPEGCompression: { (void) WriteBlobString(image,PS3_JPEGCompression"\n"); break; } case LZWCompression: { (void) WriteBlobString(image,PS3_LZWCompression"\n"); break; } case ZipCompression: { (void) WriteBlobString(image,PS3_ZipCompression"\n"); break; } } /* Image data. */ if (compression == JPEGCompression) status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); else { /* Stream based compressions. */ status=SerializeImage(image_info,image,&pixels,&length); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } switch (compression) { case NoCompression: default: { Ascii85Initialize(image); for (i=0; i < (long) length; i++) Ascii85Encode(image,pixels[i]); Ascii85Flush(image); status=MagickTrue; break; } case RLECompression: { status=PackbitsEncodeImage(image,length,pixels); break; } case LZWCompression: { status=LZWEncodeImage(image,length,pixels); break; } case ZipCompression: { status=ZLIBEncodeImage(image,length,pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); } } else { /* Colormapped images. */ (void) WriteBlobString(image,PS3_PseudoClass"\n"); switch (compression) { case NoCompression: default: { (void) WriteBlobString(image,PS3_NoCompression"\n"); break; } case JPEGCompression: { (void) WriteBlobString(image,PS3_JPEGCompression"\n"); break; } case RLECompression: { (void) WriteBlobString(image,PS3_RLECompression"\n"); break; } case LZWCompression: { (void) WriteBlobString(image,PS3_LZWCompression"\n"); break; } case ZipCompression: { (void) WriteBlobString(image,PS3_ZipCompression"\n"); break; } } /* Number of colors in color map. */ (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n", image->colors); (void) WriteBlobString(image,buffer); /* Color map - uncompressed. */ if ((compression != NoCompression) && (compression != UndefinedCompression)) { for (i=0; i < (long) image->colors; i++) { pixel=ScaleQuantumToChar(image->colormap[i].red); (void) WriteBlobByte(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].green); (void) WriteBlobByte(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].blue); (void) WriteBlobByte(image,(unsigned char) pixel); } } else { Ascii85Initialize(image); for (i=0; i < (long) image->colors; i++) { pixel=ScaleQuantumToChar(image->colormap[i].red); Ascii85Encode(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].green); Ascii85Encode(image,(unsigned char) pixel); pixel=ScaleQuantumToChar(image->colormap[i].blue); Ascii85Encode(image,(unsigned char) pixel); } Ascii85Flush(image); } status=SerializeImageIndexes(image_info,image,&pixels,&length); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } switch (compression) { case NoCompression: default: { Ascii85Initialize(image); for (i=0; i < (long) length; i++) Ascii85Encode(image,pixels[i]); Ascii85Flush(image); status=MagickTrue; break; } case JPEGCompression: { status=InjectImageBlob(image_info,image,image,"jpeg", &image->exception); break; } case RLECompression: { status=PackbitsEncodeImage(image,length,pixels); break; } case LZWCompression: { status=LZWEncodeImage(image,length,pixels); break; } case ZipCompression: { status=ZLIBEncodeImage(image,length,pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); } (void) WriteBlobByte(image,'\n'); if (status == MagickFalse) { (void) CloseBlob(image); return(MagickFalse); } /* Update BeginData now that we know the data size. */ length=(size_t) (TellBlob(image)-stop); stop=TellBlob(image); offset=SeekBlob(image,start,SEEK_SET); if (offset < 0) ThrowWriterException(CorruptImageError,"ImproperImageHeader"); (void) FormatMagickString(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"); /* End private dictionary if this an EPS. */ if (LocaleCompare(image_info->magick,"PS3") != 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) FormatMagickString(buffer,MaxTextExtent, "%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5), floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5)); (void) WriteBlobString(image,buffer); (void) FormatMagickString(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); }
static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info, Image *image,const CompressionType compression) { char buffer[MaxTextExtent]; Image *mask_image; MagickBooleanType status; MagickOffsetType offset, start, stop; register long i; size_t length; unsigned char *pixels; assert(image_info != (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(image->matte != MagickFalse); status=MagickTrue; /* Note BeginData DSC comment for update later. */ start=TellBlob(image); (void) FormatMagickString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",0L, compression == NoCompression ? "ASCII" : "BINARY"); (void) WriteBlobString(image,buffer); stop=TellBlob(image); /* Only lossless compressions for the mask. */ switch (compression) { case NoCompression: default: { (void) FormatMagickString(buffer,MaxTextExtent, "currentfile %lu %lu "PS3_NoCompression" ByteStreamDecodeFilter\n", image->columns,image->rows); break; } case FaxCompression: case Group4Compression: { (void) FormatMagickString(buffer,MaxTextExtent, "currentfile %lu %lu "PS3_FaxCompression" ByteStreamDecodeFilter\n", image->columns,image->rows); break; } case LZWCompression: { (void) FormatMagickString(buffer,MaxTextExtent, "currentfile %lu %lu "PS3_LZWCompression" ByteStreamDecodeFilter\n", image->columns,image->rows); break; } case RLECompression: { (void) FormatMagickString(buffer,MaxTextExtent, "currentfile %lu %lu "PS3_RLECompression" ByteStreamDecodeFilter\n", image->columns,image->rows); break; } case ZipCompression: { (void) FormatMagickString(buffer,MaxTextExtent, "currentfile %lu %lu "PS3_ZipCompression" ByteStreamDecodeFilter\n", image->columns,image->rows); break; } } (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"/ReusableStreamDecode filter\n"); mask_image=CloneImage(image,0,0,MagickTrue,&image->exception); if (mask_image == (Image *) NULL) ThrowWriterException(CoderError,image->exception.reason); status=SeparateImageChannel(mask_image,OpacityChannel); if (status == MagickFalse) { mask_image=DestroyImage(mask_image); return(MagickFalse); } (void) SetImageType(mask_image,BilevelType); (void) SetImageType(mask_image,PaletteType); mask_image->matte=MagickFalse; pixels=(unsigned char *) NULL; length=0; switch (compression) { case NoCompression: default: { status=SerializeImageChannel(image_info,mask_image,&pixels,&length); if (status == MagickFalse) break; Ascii85Initialize(image); for (i=0; i < (long) length; i++) Ascii85Encode(image,pixels[i]); Ascii85Flush(image); pixels=(unsigned char *) RelinquishMagickMemory(pixels); break; } case FaxCompression: case Group4Compression: { if ((compression == FaxCompression) || (LocaleCompare(CCITTParam,"0") == 0)) status=HuffmanEncodeImage(image_info,image,mask_image); else status=Huffman2DEncodeImage(image_info,image,mask_image); break; } case LZWCompression: { status=SerializeImageChannel(image_info,mask_image,&pixels,&length); if (status == MagickFalse) break; status=LZWEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); break; } case RLECompression: { status=SerializeImageChannel(image_info,mask_image,&pixels,&length); if (status == MagickFalse) break; status=PackbitsEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); break; } case ZipCompression: { status=SerializeImageChannel(image_info,mask_image,&pixels,&length); if (status == MagickFalse) break; status=ZLIBEncodeImage(image,length,pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); break; } } mask_image=DestroyImage(mask_image); (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) FormatMagickString(buffer,MaxTextExtent, "%%%%BeginData:%13ld %s Bytes\n",(long) length, compression == NoCompression ? "ASCII" : "BINARY"); (void) WriteBlobString(image,buffer); offset=SeekBlob(image,stop,SEEK_SET); if (offset < 0) ThrowWriterException(CorruptImageError,"ImproperImageHeader"); (void) WriteBlobString(image,"%%EndData\n"); (void) WriteBlobString(image, "/mask_stream exch def\n"); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e P C L I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WritePCLImage writes an image in the Page Control Language encoded % image format. % % The format of the WritePCLImage method is: % % unsigned int WritePCLImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WritePCLImage 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 WritePCLImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent]; long sans, y; register const PixelPacket *p; register const IndexPacket *indexes; register long i, x; register unsigned char *q; unsigned char *pixels, *last_row_pixels, *output_row; unsigned int status; long zero_rows; unsigned long bytes_to_write, scene, density, bytes_per_line; unsigned char bits_per_pixel; ImageCharacteristics characteristics; PCL_CompressionType compression, last_row_compression; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); (void) GetGeometry("75x75",&sans,&sans,&density,&density); if (image_info->density != (char *) NULL) (void) GetGeometry(image_info->density,&sans,&sans,&density,&density); scene = 0; output_row = (unsigned char *) NULL; last_row_pixels = (unsigned char *) NULL; do { /* Ensure that image is in an RGB space. */ (void) TransformColorspace(image,RGBColorspace); /* Analyze image to be written. */ if (!GetImageCharacteristics(image,&characteristics, (OptimizeType == image_info->type), &image->exception)) { CloseBlob(image); return MagickFail; } /* Initialize the printer */ (void) WriteBlobString(image,"\033E"); /* printer reset */ (void) WriteBlobString(image,"\033*r3F"); /* set presentation mode */ /* define columns and rows in image */ FormatString(buffer,"\033*r%lus%luT",image->columns,image->rows); (void) WriteBlobString(image,buffer); FormatString(buffer,"\033*t%luR",density); /* set resolution */ (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"\033&l0E"); /* top margin 0 */ /* Determine output type and initialize further accordingly */ if (image->storage_class == DirectClass) { /* Full color */ 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 if (characteristics.monochrome) { /* Use default printer monochrome setup - NB white = 0, black = 1 */ bits_per_pixel=1; } else { /* PseudoClass */ 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 (implicit) */ (void) WriteBlobByte(image,8); /* bits per green component (implicit) */ (void) WriteBlobByte(image,8); /* bits per blue component (implicit) */ /* Write colormap to file. */ for (i=0; i < (long)(image->colors); i++) { FormatString(buffer,"\033*v%da%db%dc%ldI", ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue), i); WriteBlobString(image,buffer); } /* Initialize rest of palette with empty entries */ for ( ; i < (1L << bits_per_pixel); i++) { FormatString(buffer,"\033*v%luI",i); /* set index to current component values */ (void) WriteBlobString(image,buffer); } } /* Start raster image */ if ((AccessDefinition(image_info,"pcl","fit-to-page") != NULL) || (AccessDefinition(image_info,"pcl","fit_to_page") != NULL)) (void) WriteBlobString(image,"\033*r3A"); /* start raster graphics with scaling */ else (void) WriteBlobString(image,"\033*r1A"); /* start raster graphics */ (void) WriteBlobString(image,"\033*b0Y"); /* set y offset */ /* Assign row buffer */ bytes_per_line=(image->columns*bits_per_pixel+7)/8; pixels=MagickAllocateMemory(unsigned char *,bytes_per_line); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); /* Set up for compression if desired */ last_row_compression = PCL_UndefinedCompression; if (image_info->compression != NoCompression) { MagickFreeMemory(last_row_pixels); last_row_pixels=MagickAllocateMemory(unsigned char *,bytes_per_line); if (last_row_pixels == (unsigned char *) NULL) { MagickFreeMemory(pixels); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); } MagickFreeMemory(output_row); output_row=MagickAllocateMemory(unsigned char *,bytes_per_line); if (output_row == (unsigned char *) NULL) { MagickFreeMemory(pixels); MagickFreeMemory(last_row_pixels); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); } memset(last_row_pixels,0,bytes_per_line); } /* Convert MIFF to PCL raster pixels. */ zero_rows=0; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; q=pixels; if (characteristics.monochrome) { register unsigned char bit, byte; int blk_ind; /* Monochrome row */ blk_ind = ((image->colormap == NULL) || (image->colormap[0].red == 0)) ? 0 : 1; indexes=AccessImmutableIndexes(image); bit=0; byte=0; for (x=0; x < (long) image->columns; x++) { byte<<=1; if (indexes[x] == blk_ind) byte |= 1; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } } if (bit != 0) *q++=byte << (8-bit); } else if (bits_per_pixel == 8) { /* 8 bit PseudoClass row */ indexes=AccessImmutableIndexes(image); for (x=0; x < (long) image->columns; x++) { *q++=indexes[x]; } } else if ((bits_per_pixel == 24) || (bits_per_pixel == 32)) { /* DirectClass/RGB row */ for (x=0; x < (long) image->columns; x++) { *q++=ScaleQuantumToChar(p->red); *q++=ScaleQuantumToChar(p->green); *q++=ScaleQuantumToChar(p->blue); p++; } } if (image_info->compression == NoCompression) { FormatString(buffer,"\033*b%luW",bytes_per_line); /* send row */ (void) WriteBlobString(image,buffer); (void) WriteBlob(image,bytes_per_line,pixels); } else { compression=PCL_ChooseCompression(bytes_per_line,pixels,last_row_pixels); if (compression == PCL_ZeroRowCompression) { zero_rows++; } else { /* Skip any omitted zero rows now */ if (zero_rows > 0) { i = 32767; do { if (zero_rows < i) i=zero_rows; FormatString(buffer,"\033*b%ldY",i); /* Y Offset */ (void) WriteBlobString(image,buffer); zero_rows -= i; } while (zero_rows > 0); } switch (compression) { case PCL_DeltaCompression: { if (compression != last_row_compression) { FormatString(buffer,"\033*b3M"); /* delta compression */ (void) WriteBlobString(image,buffer); last_row_compression=compression; } bytes_to_write=PCL_DeltaCompress(bytes_per_line,pixels, last_row_pixels,output_row); FormatString(buffer,"\033*b%luW",bytes_to_write); (void) WriteBlobString(image,buffer); WriteBlob(image,bytes_to_write,output_row); break; } case PCL_TiffRLECompression: { if (compression != last_row_compression) { FormatString(buffer,"\033*b2M"); /* Tiff RLE compression */ (void) WriteBlobString(image,buffer); last_row_compression=compression; } bytes_to_write=PCL_TiffRLECompress(bytes_per_line,pixels,output_row); FormatString(buffer,"\033*b%luW",bytes_to_write); (void) WriteBlobString(image,buffer); WriteBlob(image,bytes_to_write,output_row); break; } case PCL_RLECompression: { if (compression != last_row_compression) { FormatString(buffer,"\033*b1M"); /* RLE compression */ (void) WriteBlobString(image,buffer); last_row_compression=compression; } bytes_to_write=PCL_RLECompress(bytes_per_line,pixels,output_row); FormatString(buffer,"\033*b%luW",bytes_to_write); (void) WriteBlobString(image,buffer); WriteBlob(image,bytes_to_write,output_row); break; } case PCL_RepeatedRowCompression: { compression=PCL_DeltaCompression; if (compression != last_row_compression) { FormatString(buffer,"\033*b3M"); /* delta row compression */ (void) WriteBlobString(image,buffer); last_row_compression=compression; } FormatString(buffer,"\033*b0W"); /* no data -> replicate row */ (void) WriteBlobString(image,buffer); break; } case PCL_NoCompression: { if (compression != last_row_compression) { FormatString(buffer,"\033*b0M"); /* no compression */ (void) WriteBlobString(image,buffer); last_row_compression=compression; } FormatString(buffer,"\033*b%luW",bytes_per_line); /* send row */ (void) WriteBlobString(image,buffer); (void) WriteBlob(image,bytes_per_line,pixels); break; } case PCL_ZeroRowCompression: { break; } case PCL_UndefinedCompression: { break; } } } /* Swap row with last row */ q=last_row_pixels; last_row_pixels=pixels; pixels=q; } if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; } (void) WriteBlobString(image,"\033*rB"); /* end graphics */ MagickFreeMemory(pixels); MagickFreeMemory(last_row_pixels); MagickFreeMemory(output_row); if (image->next == (Image *) NULL) break; image=SyncNextImageInList(image); if ((status &= MagickMonitorFormatted(scene++, GetImageListLength(image), &image->exception, SaveImagesText, image->filename)) == MagickFail) break; } while (image_info->adjoin);