/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e V I C A R I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteVICARImage writes an image in the VICAR rasterfile format. % Vicar files contain a text header, followed by one or more planes of binary % grayscale image data. Vicar files are designed to allow many planes to be % stacked together to form image cubes. This method only writes a single % grayscale plane. % % Method WriteVICARImage was written contributed by % [email protected]. % % The format of the WriteVICARImage method is: % % unsigned int WriteVICARImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteVICARImage 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 WriteVICARImage(const ImageInfo *image_info,Image *image) { char header[MaxTextExtent]; int y; unsigned char *scanline; unsigned int status; /* 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) TransformColorspace(image,RGBColorspace); /* Write header. */ (void) memset(header,' ',MaxTextExtent); FormatString(header,"LBLSIZE=%u FORMAT='BYTE' TYPE='IMAGE' BUFSIZE=20000 " "DIM=2 EOL=0 RECSIZE=%lu ORG='BSQ' NL=%lu NS=%lu NB=1 N1=0 N2=0 N3=0 N4=0 " "NBB=0 NLB=0 TASK='GraphicsMagick'",MaxTextExtent,image->columns,image->rows, image->columns); (void) WriteBlob(image,MaxTextExtent,header); /* Allocate memory for scanline. */ scanline=MagickAllocateMemory(unsigned char *,image->columns); if (scanline == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); /* Write VICAR scanline. */ for (y=0; y < (long) image->rows; y++) { if (!AcquireImagePixels(image,0,y,image->columns,1,&image->exception)) break; (void) ExportImagePixelArea(image,GrayQuantum,8,scanline,0,0); (void) WriteBlob(image,image->columns,scanline); 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; } MagickFreeMemory(scanline); CloseBlob(image); return(True); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e F A X I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Procedure WriteFAXImage writes an image to a file in 1 dimensional Huffman % encoded format. % % The format of the WriteFAXImage method is: % % unsigned int WriteFAXImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteFAXImage 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 WriteFAXImage(const ImageInfo *image_info,Image *image) { ImageInfo *clone_info; unsigned int status; unsigned long scene; /* 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); clone_info=CloneImageInfo(image_info); (void) strcpy(clone_info->magick,"FAX"); scene=0; do { /* Convert MIFF to monochrome. */ (void) TransformColorspace(image,RGBColorspace); status=HuffmanEncodeImage(clone_info,image); if (image->next == (Image *) NULL) break; image=SyncNextImageInList(image); status=MagickMonitorFormatted(scene++,GetImageListLength(image), &image->exception,SaveImagesText, image->filename); if (status == False) break; } while (clone_info->adjoin); DestroyImageInfo(clone_info); if (image_info->adjoin) while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e C M Y K I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteCMYKImage writes an image to a file in red, green, and blue % rasterfile format. % % The format of the WriteCMYKImage method is: % % unsigned int WriteCMYKImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteCMYKImage 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 WriteCMYKImage(const ImageInfo *image_info,Image *image) { int y; register const PixelPacket *p; unsigned char *pixels; unsigned int packet_size, quantum_size, scene, status; ExportPixelAreaOptions export_options; ExportPixelAreaInfo export_info; if (image->depth <= 8) quantum_size=8; else if (image->depth <= 16) quantum_size=16; else quantum_size=32; /* Allocate memory for pixels. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); packet_size=(quantum_size*4)/8; if (LocaleCompare(image_info->magick,"CMYKA") == 0) packet_size=(quantum_size*5)/8; pixels=MagickAllocateArray(unsigned char *,packet_size,image->columns); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); if (image_info->interlace != PartitionInterlace) { /* Open output image file. */ status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } scene=0; do { /* Convert MIFF to CMYK raster pixels. */ (void) TransformColorspace(image,CMYKColorspace); if (LocaleCompare(image_info->magick,"CMYKA") == 0) if (!image->matte) SetImageOpacity(image,OpaqueOpacity); /* Initialize export options. */ ExportPixelAreaOptionsInit(&export_options); if (image->endian != UndefinedEndian) export_options.endian=image->endian; else if (image_info->endian != UndefinedEndian) export_options.endian=image_info->endian; if (image->logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Image depth %u bits, Endian %s",quantum_size, EndianTypeToString(export_options.endian)); switch (image_info->interlace) { case NoInterlace: default: { /* No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK... */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; if (LocaleCompare(image_info->magick,"CMYKA") != 0) { (void) ExportImagePixelArea(image,CMYKQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } else { (void) ExportImagePixelArea(image,CMYKAQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } 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; } break; } case LineInterlace: { /* Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK... */ for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,CyanQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); (void) ExportImagePixelArea(image,MagentaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); (void) ExportImagePixelArea(image,YellowQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); (void) ExportImagePixelArea(image,BlackQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); if (LocaleCompare(image_info->magick,"CMYKA") == 0) { (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; } break; } case PlaneInterlace: case PartitionInterlace: { /* Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK... */ if (image_info->interlace == PartitionInterlace) { AppendImageFormat("C",image->filename); status= OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,CyanQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("M",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } if (!MagickMonitorFormatted(100,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,MagentaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("Y",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } if (!MagickMonitorFormatted(200,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,YellowQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("K",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } if (!MagickMonitorFormatted(200,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,BlackQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } if (LocaleCompare(image_info->magick,"CMYKA") == 0) { if (!MagickMonitorFormatted(300,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("A",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode, &image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; (void) ExportImagePixelArea(image,AlphaQuantum,quantum_size,pixels, &export_options,&export_info); (void) WriteBlob(image,export_info.bytes_exported,pixels); } } if (image_info->interlace == PartitionInterlace) (void) strlcpy(image->filename,image_info->filename,MaxTextExtent); if (!MagickMonitorFormatted(400,400,&image->exception, SaveImageText,image->filename, image->columns,image->rows)) break; break; } } if (image->next == (Image *) NULL) break; image=SyncNextImageInList(image); status=MagickMonitorFormatted(scene++,GetImageListLength(image), &image->exception,SaveImagesText, image->filename); if (status == False) break; } while (image_info->adjoin); MagickFreeMemory(pixels); if (image_info->adjoin) while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); return(True); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e J P 2 I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteJP2Image writes an image in the JPEG 2000 image format. % % JP2 support originally written by Nathan Brown, [email protected] % % The format of the WriteJP2Image method is: % % MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteJP2Image return MagickTrue if the image is written. % MagickFalse 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 MagickPassFail WriteJP2Image(const ImageInfo *image_info,Image *image) { char magick[MaxTextExtent], option_keyval[MaxTextExtent], *options = NULL; int format; long y; jas_image_cmptparm_t component_info; jas_image_t *jp2_image; jas_matrix_t *jp2_pixels; jas_stream_t *jp2_stream; register const PixelPacket *p; register int x; unsigned int rate_specified=False, status; int component, number_components; unsigned short *lut; ImageCharacteristics characteristics; /* Open 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); /* Ensure that image is in 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; } /* Obtain a JP2 stream. */ jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowWriterException(DelegateError,UnableToManageJP2Stream,image); number_components=image->matte ? 4 : 3; if ((image_info->type != TrueColorType) && (characteristics.grayscale)) number_components=1; jp2_image=jas_image_create0(); if (jp2_image == (jas_image_t *) NULL) ThrowWriterException(DelegateError,UnableToCreateImage,image); for (component=0; component < number_components; component++) { (void) memset((void *)&component_info,0,sizeof(jas_image_cmptparm_t)); component_info.tlx=0; /* top left x ordinate */ component_info.tly=0; /* top left y ordinate */ component_info.hstep=1; /* horizontal pixels per step */ component_info.vstep=1; /* vertical pixels per step */ component_info.width=(unsigned int) image->columns; component_info.height=(unsigned int) image->rows; component_info.prec=(unsigned int) Max(2,Min(image->depth,16)); /* bits in range */ component_info.sgnd = false; /* range is signed value? */ if (jas_image_addcmpt(jp2_image, component,&component_info)) { jas_image_destroy(jp2_image); ThrowWriterException(DelegateError,UnableToCreateImageComponent,image); } } /* Allocate and compute LUT. */ { unsigned long i, max_value; double scale_to_component; lut=MagickAllocateArray(unsigned short *,MaxMap+1,sizeof(*lut)); if (lut == (unsigned short *) NULL) { jas_image_destroy(jp2_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); } max_value=MaxValueGivenBits(component_info.prec); scale_to_component=max_value/MaxRGBDouble; for(i=0; i <= MaxMap; i++) lut[i]=scale_to_component*i+0.5; } if (number_components == 1) { /* FIXME: If image has an attached ICC profile, then the profile should be transferred and the image colorspace set to JAS_CLRSPC_GENGRAY */ /* sRGB Grayscale */ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting SGRAY colorspace"); jas_image_setclrspc(jp2_image, JAS_CLRSPC_SGRAY); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting GRAY channel to channel 0"); jas_image_setcmpttype(jp2_image,0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); } else { /* FIXME: If image has an attached ICC profile, then the profile should be transferred and the image colorspace set to JAS_CLRSPC_GENRGB */ /* sRGB */ (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting SRGB colorspace"); jas_image_setclrspc(jp2_image, JAS_CLRSPC_SRGB); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting RED channel to channel 0"); jas_image_setcmpttype(jp2_image,0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting GREEN channel to channel 1"); jas_image_setcmpttype(jp2_image,1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting BLUE channel to channel 2"); jas_image_setcmpttype(jp2_image,2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); if (number_components == 4 ) { (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Setting OPACITY channel to channel 3"); jas_image_setcmpttype(jp2_image,3, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY)); } } /* Convert to JPEG 2000 pixels. */ jp2_pixels=jas_matrix_create(1,(unsigned int) image->columns); if (jp2_pixels == (jas_matrix_t *) NULL) { MagickFreeMemory(lut); jas_image_destroy(jp2_image); ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); } for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; if (number_components == 1) { for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(PixelIntensityToQuantum(&p[x]))]); (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); } else { for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].red)]); (void) jas_image_writecmpt(jp2_image,0,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].green)]); (void) jas_image_writecmpt(jp2_image,1,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(p[x].blue)]); (void) jas_image_writecmpt(jp2_image,2,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); if (number_components > 3) for (x=0; x < (long) image->columns; x++) jas_matrix_setv(jp2_pixels,x,lut[ScaleQuantumToMap(MaxRGB-p[x].opacity)]); (void) jas_image_writecmpt(jp2_image,3,0,(unsigned int) y, (unsigned int) image->columns,1,jp2_pixels); } 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) strlcpy(magick,image_info->magick,MaxTextExtent); /* J2C is an alias for JPC but Jasper only supports "JPC". */ if (LocaleCompare(magick,"j2c") == 0) (void) strlcpy(magick,"jpc",sizeof(magick)); LocaleLower(magick); format=jas_image_strtofmt(magick); /* Support passing Jasper options. */ { const char **option_name; static const char *jasper_options[] = { "imgareatlx", "imgareatly", "tilegrdtlx", "tilegrdtly", "tilewidth", "tileheight", "prcwidth", "prcheight", "cblkwidth", "cblkheight", "mode", "ilyrrates", "prg", "nomct", "numrlvls", "sop", "eph", "lazy", "rate", "termall", "segsym", "vcausal", "pterm", "resetprob", "numgbits", NULL }; for (option_name = jasper_options; *option_name != NULL; option_name++) { const char *value; if ((value=AccessDefinition(image_info,"jp2",*option_name)) != NULL) { if(LocaleCompare(*option_name,"rate") == 0) rate_specified=True; FormatString(option_keyval,"%s=%.1024s ",*option_name,value); ConcatenateString(&options,option_keyval); } } } /* Provide an emulation of IJG JPEG "quality" by default. */ if (rate_specified == False) { double rate=1.0; /* A rough approximation to JPEG v1 quality using JPEG-2000. Default "quality" 75 results in a request for 16:1 compression, which results in image sizes approximating that of JPEG v1. */ if ((image_info->quality < 99.5) && (image->rows*image->columns > 2500)) { double header_size, current_size, target_size, d; d=115-image_info->quality; /* Best number is 110-115 */ rate=100.0/(d*d); header_size=550.0; /* Base file size. */ header_size+=(number_components-1)*142; /* Additional components */ /* FIXME: Need to account for any ICC profiles here */ current_size=(double)((image->rows*image->columns*image->depth)/8)* number_components; target_size=(current_size*rate)+header_size; rate=target_size/current_size; } FormatString(option_keyval,"%s=%g ","rate",rate); ConcatenateString(&options,option_keyval); (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Compression rate: %g (%3.2f:1)",rate,1.0/rate); } if (options) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "Jasper options: \"%s\"", options); (void) LogMagickEvent(CoderEvent,GetMagickModule(),"Encoding image"); status=jas_image_encode(jp2_image,jp2_stream,format,options); (void) jas_stream_close(jp2_stream); MagickFreeMemory(options); MagickFreeMemory(lut); jas_matrix_destroy(jp2_pixels); jas_image_destroy(jp2_image); if (status) ThrowWriterException(DelegateError,UnableToEncodeImageFile,image); return(True); }
MagickExport MagickPassFail CdlImage(Image *image,const char *cdl) { char progress_message[MaxTextExtent]; CdlImageParameters_t param; PixelPacket *lut = (PixelPacket *) NULL; register long i; MagickPassFail status=MagickPass; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (cdl == (char *) NULL) return(MagickFail); param.redslope=1.0; param.redoffset=0.0; param.redpower=1.0; param.greenslope=1.0; param.greenoffset=0.0; param.greenpower=1.0; param.blueslope=1.0; param.blueoffset=0.0; param.bluepower=1.0; param.saturation=0.0; param.lut=(PixelPacket *) NULL; (void) sscanf(cdl, "%lf%*[,/]%lf%*[,/]%lf%*[:/]%lf%*[,/]%lf%*[,/]%lf%*" "[:/]%lf%*[,/]%lf%*[,/]%lf%*[:/]%lf", ¶m.redslope,¶m.redoffset,¶m.redpower, ¶m.greenslope,¶m.greenoffset,¶m.greenpower ,¶m.blueslope,¶m.blueoffset,¶m.bluepower, ¶m.saturation); param.redslope=AbsoluteValue(param.redslope); param.redpower=AbsoluteValue(param.redpower); param.greenslope=AbsoluteValue(param.greenslope); param.greenpower=AbsoluteValue(param.greenpower); param.blueslope=AbsoluteValue(param.blueslope); param.bluepower=AbsoluteValue(param.bluepower); FormatString(progress_message, "[%%s] cdl %g/%g/%g/%g/%g/%g/%g/%g/%g/%g image...", param.redslope,param.redoffset,param.redpower, param.greenslope,param.greenoffset,param.greenpower, param.blueslope,param.blueoffset,param.bluepower, param.saturation); if (!IsRGBCompatibleColorspace(image->colorspace)) TransformColorspace(image,RGBColorspace); /* Build a LUT if it is beneficial to do so. */ if ((MaxMap == MaxRGB) && (image->columns*image->rows > MaxMap*3)) { lut=MagickAllocateMemory(PixelPacket *,(MaxMap+1)*sizeof(PixelPacket)); if (lut != (PixelPacket *) NULL) { #if (MaxMap > 256) && defined(HAVE_OPENMP) # pragma omp parallel for schedule(guided) #endif for (i=0; i <= (long) MaxMap; i++) { lut[i].red=CdlQuantum((Quantum) i,param.redslope,param.redoffset, param.redpower,param.saturation); lut[i].green=CdlQuantum((Quantum) i,param.greenslope,param.greenoffset, param.greenpower,param.saturation); lut[i].blue=CdlQuantum((Quantum) i,param.blueslope,param.blueoffset, param.bluepower,param.saturation); } param.lut=lut; } }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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);
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e T X T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteTXTImage writes the pixel values as text numbers. % % The format of the WriteTXTImage method is: % % unsigned int WriteTXTImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteTXTImage 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 WriteTXTImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent], tuple[MaxTextExtent]; long y; register const PixelPacket *p; register long x; unsigned int status; unsigned long scene; /* 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,WriteBlobMode,&image->exception); if (status == False) ThrowWriterException(FileOpenError,UnableToOpenFile,image); scene=0; do { /* Convert MIFF to TXT raster pixels. */ unsigned int depth; (void) TransformColorspace(image,RGBColorspace); if (image->depth <= 8) depth=8; else if (image->depth <= 16) depth=16; else depth=32; for (y=0; y < (long) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { FormatString(buffer,"%ld,%ld: ",x,y); (void) WriteBlobString(image,buffer); GetColorTuple(p,depth,image->matte,MagickFalse,tuple); (void) strcat(tuple," "); (void) WriteBlobString(image,tuple); /* (void) QueryColorname(image,p,SVGCompliance,tuple,&image->exception); */ GetColorTuple(p,depth,image->matte,MagickTrue,tuple); (void) WriteBlobString(image,tuple); (void) WriteBlobString(image,"\n"); p++; } } if (image->next == (Image *) NULL) break; image=SyncNextImageInList(image); status=MagickMonitorFormatted(scene++,GetImageListLength(image), &image->exception,SaveImagesText, image->filename); if (status == False) break; } while (image_info->adjoin); if (image_info->adjoin) while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); return(True); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e M T V I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method WriteMTVImage writes an image to a file in red, green, and blue % MTV rasterfile format. % % The format of the WriteMTVImage method is: % % unsigned int WriteMTVImage(const ImageInfo *image_info,Image *image) % % A description of each parameter follows. % % o status: Method WriteMTVImage 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 WriteMTVImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent]; int y; register const PixelPacket *p; register long x; register unsigned char *q; unsigned char *pixels; unsigned int status; unsigned long scene; /* 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); scene=0; do { /* Allocate memory for pixels. */ (void) TransformColorspace(image,RGBColorspace); pixels=MagickAllocateMemory(unsigned char *, image->columns*sizeof(PixelPacket)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image); /* Initialize raster file header. */ FormatString(buffer,"%lu %lu\n",image->columns,image->rows); (void) WriteBlobString(image,buffer); 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; for (x=0; x < (long) image->columns; x++) { *q++=ScaleQuantumToChar(p->red); *q++=ScaleQuantumToChar(p->green); *q++=ScaleQuantumToChar(p->blue); p++; } (void) WriteBlob(image,q-pixels,(char *) pixels); 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; } MagickFreeMemory(pixels); if (image->next == (Image *) NULL) break; image=SyncNextImageInList(image); status=MagickMonitorFormatted(scene++,GetImageListLength(image), &image->exception,SaveImagesText, image->filename); if (status == False) break; } while (image_info->adjoin); if (image_info->adjoin) while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); return(True); }